From 57726e6752eacbbfee906479be9e1c49d456fb6f Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 2 Sep 2014 15:10:53 +0300 Subject: Change volumetric example to show fictional terrain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I7cb3c59acef5364ff964da3e756d2db387b53308 Reviewed-by: Mika Salmela Reviewed-by: Tomi Korpipää --- .../datavisualization/volumetric/layer_ground.png | Bin 0 -> 63473 bytes .../datavisualization/volumetric/layer_magma.png | Bin 0 -> 17332 bytes .../datavisualization/volumetric/layer_water.png | Bin 0 -> 27124 bytes examples/datavisualization/volumetric/main.cpp | 10 +- .../datavisualization/volumetric/volumetric.cpp | 332 ++++++++++++++++++--- examples/datavisualization/volumetric/volumetric.h | 13 + .../datavisualization/volumetric/volumetric.pro | 2 + .../datavisualization/volumetric/volumetric.qrc | 7 + 8 files changed, 315 insertions(+), 49 deletions(-) create mode 100644 examples/datavisualization/volumetric/layer_ground.png create mode 100644 examples/datavisualization/volumetric/layer_magma.png create mode 100644 examples/datavisualization/volumetric/layer_water.png create mode 100644 examples/datavisualization/volumetric/volumetric.qrc (limited to 'examples/datavisualization/volumetric') diff --git a/examples/datavisualization/volumetric/layer_ground.png b/examples/datavisualization/volumetric/layer_ground.png new file mode 100644 index 00000000..3f96a122 Binary files /dev/null and b/examples/datavisualization/volumetric/layer_ground.png differ diff --git a/examples/datavisualization/volumetric/layer_magma.png b/examples/datavisualization/volumetric/layer_magma.png new file mode 100644 index 00000000..01434d35 Binary files /dev/null and b/examples/datavisualization/volumetric/layer_magma.png differ diff --git a/examples/datavisualization/volumetric/layer_water.png b/examples/datavisualization/volumetric/layer_water.png new file mode 100644 index 00000000..4d57563e Binary files /dev/null and b/examples/datavisualization/volumetric/layer_water.png differ diff --git a/examples/datavisualization/volumetric/main.cpp b/examples/datavisualization/volumetric/main.cpp index 68895b17..0acffe10 100644 --- a/examples/datavisualization/volumetric/main.cpp +++ b/examples/datavisualization/volumetric/main.cpp @@ -49,7 +49,7 @@ int main(int argc, char **argv) hLayout->addLayout(vLayout); hLayout->addLayout(vLayout2); - widget->setWindowTitle(QStringLiteral("Volumetric Object Example")); + widget->setWindowTitle(QStringLiteral("Volumetric object example - 3D terrain")); QCheckBox *sliceXCheckBox = new QCheckBox(widget); sliceXCheckBox->setText(QStringLiteral("Slice volume on X axis")); @@ -135,6 +135,10 @@ int main(int argc, char **argv) preserveOpacityCheckBox->setText(QStringLiteral("Preserve opacity")); preserveOpacityCheckBox->setChecked(true); + QCheckBox *transparentGroundCheckBox = new QCheckBox(widget); + transparentGroundCheckBox->setText(QStringLiteral("Transparent ground")); + transparentGroundCheckBox->setChecked(false); + QCheckBox *useHighDefShaderCheckBox = new QCheckBox(widget); useHighDefShaderCheckBox->setText(QStringLiteral("Use HD shader")); useHighDefShaderCheckBox->setChecked(true); @@ -155,6 +159,7 @@ int main(int argc, char **argv) vLayout2->addWidget(alphaMultiplierLabel); vLayout2->addWidget(alphaMultiplierSlider); vLayout2->addWidget(preserveOpacityCheckBox); + vLayout2->addWidget(transparentGroundCheckBox); vLayout2->addWidget(useHighDefShaderCheckBox, 1, Qt::AlignTop); VolumetricModifier *modifier = new VolumetricModifier(graph); @@ -164,6 +169,7 @@ int main(int argc, char **argv) modifier->setSliceSliders(sliceXSlider, sliceYSlider, sliceZSlider); modifier->setSliceLabels(sliceImageXLabel, sliceImageYLabel, sliceImageZLabel); modifier->setAlphaMultiplierLabel(alphaMultiplierLabel); + modifier->setTransparentGround(transparentGroundCheckBox->isChecked()); QObject::connect(fpsCheckBox, &QCheckBox::stateChanged, modifier, &VolumetricModifier::setFpsMeasurement); @@ -189,6 +195,8 @@ int main(int argc, char **argv) &VolumetricModifier::changeColorTable); QObject::connect(preserveOpacityCheckBox, &QCheckBox::stateChanged, modifier, &VolumetricModifier::setPreserveOpacity); + QObject::connect(transparentGroundCheckBox, &QCheckBox::stateChanged, modifier, + &VolumetricModifier::setTransparentGround); QObject::connect(useHighDefShaderCheckBox, &QCheckBox::stateChanged, modifier, &VolumetricModifier::setUseHighDefShader); QObject::connect(alphaMultiplierSlider, &QSlider::valueChanged, modifier, diff --git a/examples/datavisualization/volumetric/volumetric.cpp b/examples/datavisualization/volumetric/volumetric.cpp index 1de4b1b7..156e0bf4 100644 --- a/examples/datavisualization/volumetric/volumetric.cpp +++ b/examples/datavisualization/volumetric/volumetric.cpp @@ -34,7 +34,21 @@ const int lowDetailSize(128); const int mediumDetailSize(256); const int highDetailSize(512); const int colorTableSize(256); -const int cutOffColorIndex(15); +const int layerDataSize(512); +const int mineShaftDiameter(1); + +const int airColorIndex(254); +const int mineShaftColorIndex(255); +const int layerColorThickness(60); +const int magmaColorsMin(0); +const int magmaColorsMax(layerColorThickness); +const int aboveWaterGroundColorsMin(magmaColorsMax + 1); +const int aboveWaterGroundColorsMax(aboveWaterGroundColorsMin + layerColorThickness); +const int underWaterGroundColorsMin(aboveWaterGroundColorsMax + 1); +const int underWaterGroundColorsMax(underWaterGroundColorsMin + layerColorThickness); +const int waterColorsMin(underWaterGroundColorsMax + 1); +const int waterColorsMax(waterColorsMin + layerColorThickness); +const int terrainTransparency(12); VolumetricModifier::VolumetricModifier(Q3DScatter *scatter) : m_graph(scatter), @@ -49,9 +63,12 @@ VolumetricModifier::VolumetricModifier(Q3DScatter *scatter) m_highDetailData(0), m_mediumDetailIndex(0), m_highDetailIndex(0), + m_mediumDetailShaftIndex(0), + m_highDetailShaftIndex(0), m_sliceSliderX(0), m_sliceSliderY(0), m_sliceSliderZ(0), + m_usingPrimaryTable(true), m_sliceLabelX(0), m_sliceLabelY(0), m_sliceLabelZ(0) @@ -66,7 +83,14 @@ VolumetricModifier::VolumetricModifier(Q3DScatter *scatter) m_mediumDetailData = new QVector(mediumDetailSize * mediumDetailSize * mediumDetailSize / 2); m_highDetailData = new QVector(highDetailSize * highDetailSize * highDetailSize / 2); + initHeightMap(QStringLiteral(":/heightmaps/layer_ground.png"), m_groundLayer); + initHeightMap(QStringLiteral(":/heightmaps/layer_water.png"), m_waterLayer); + initHeightMap(QStringLiteral(":/heightmaps/layer_magma.png"), m_magmaLayer); + + initMineShaftArray(); + createVolume(lowDetailSize, 0, lowDetailSize, m_lowDetailData); + excavateMineShaft(lowDetailSize, 0, m_mineShaftArray.size(), m_lowDetailData); m_volumeItem = new QCustom3DVolume; m_volumeItem->setScaling(QVector3D(2.0f, 1.0f, 2.0f)); @@ -77,37 +101,47 @@ VolumetricModifier::VolumetricModifier(Q3DScatter *scatter) m_volumeItem->setTextureData(new QVector(*m_lowDetailData)); // Generate color tables. - // Both tables have a fully transparent colors to fill outer portions of the volume. - - // The primary color table. - // The top two layers are transparent. m_colorTable1.resize(colorTableSize); m_colorTable2.resize(colorTableSize); - for (int i = 1; i < colorTableSize; i++) { - if (i < cutOffColorIndex) - m_colorTable1[i] = qRgba(0, 0, 0, 0); - else if (i < 60) - m_colorTable1[i] = qRgba((i * 2) + 120, 0, 0, 15); - else if (i < 120) - m_colorTable1[i] = qRgba(0, ((i - 60) * 2) + 120, 0, 50); - else if (i < 180) - m_colorTable1[i] = qRgba(0, 0, ((i - 120) * 2) + 120, 255); - else - m_colorTable1[i] = qRgba(i, i, i, 255); + for (int i = 0; i < colorTableSize - 2; i++) { + if (i < magmaColorsMax) { + m_colorTable1[i] = qRgba(130 - (i * 2), 0, 0, 255); + } else if (i < aboveWaterGroundColorsMax) { + m_colorTable1[i] = qRgba(0, ((i - magmaColorsMax) * 2) + 120, 0, terrainTransparency); + } else if (i < underWaterGroundColorsMax) { + m_colorTable1[i] = qRgba(((i - aboveWaterGroundColorsMax) * 2) + 30, + ((i - aboveWaterGroundColorsMax) * 2) + 100, + ((i - aboveWaterGroundColorsMax) * 2) + 30, terrainTransparency); + } else if (i < waterColorsMax) { + m_colorTable1[i] = qRgba(0, 0, ((i - underWaterGroundColorsMax) * 2) + 120, + terrainTransparency); + } else { + m_colorTable1[i] = qRgba(0, 0, 0, 0); // Not used + } } - - // The alternate color table. - // The first visible layer is a thin opaque color, and rest of the volume uses a smooth - // transparent gradient. - for (int i = 1; i < colorTableSize; i++) { - if (i < cutOffColorIndex) - m_colorTable2[i] = qRgba(0, 0, 0, 0); - else if (i < cutOffColorIndex + 4) - m_colorTable2[i] = qRgba(75, 150, 0, 255); - else - m_colorTable2[i] = qRgba(i, 0, 255 - i, i); + m_colorTable1[airColorIndex] = qRgba(0, 0, 0, 0); + m_colorTable1[mineShaftColorIndex] = qRgba(50, 50, 50, 255); + + // The alternate color table just has gray gradients for all terrain except water + for (int i = 0; i < colorTableSize - 2; i++) { + if (i < magmaColorsMax) { + m_colorTable2[i] = qRgba(((i - aboveWaterGroundColorsMax) * 2), + ((i - aboveWaterGroundColorsMax) * 2), + ((i - aboveWaterGroundColorsMax) * 2), 255); + } else if (i < underWaterGroundColorsMax) { + m_colorTable2[i] = qRgba(((i - aboveWaterGroundColorsMax) * 2), + ((i - aboveWaterGroundColorsMax) * 2), + ((i - aboveWaterGroundColorsMax) * 2), terrainTransparency); + } else if (i < waterColorsMax) { + m_colorTable2[i] = qRgba(0, 0, ((i - underWaterGroundColorsMax) * 2) + 120, + terrainTransparency); + } else { + m_colorTable2[i] = qRgba(0, 0, 0, 0); // Not used + } } + m_colorTable2[airColorIndex] = qRgba(0, 0, 0, 0); + m_colorTable2[mineShaftColorIndex] = qRgba(255, 255, 0, 255); m_volumeItem->setColorTable(m_colorTable1); @@ -246,18 +280,26 @@ void VolumetricModifier::handleFpsChange(qreal fps) void VolumetricModifier::handleTimeout() { - if (m_mediumDetailIndex < mediumDetailSize) { - m_mediumDetailIndex = createVolume(mediumDetailSize, m_mediumDetailIndex, 4, - m_mediumDetailData); - if (m_mediumDetailIndex == mediumDetailSize) { + if (!m_mediumDetailRB->isEnabled()) { + if (m_mediumDetailIndex != mediumDetailSize) { + m_mediumDetailIndex = createVolume(mediumDetailSize, m_mediumDetailIndex, 4, + m_mediumDetailData); + } else if (m_mediumDetailShaftIndex != m_mineShaftArray.size()) { + m_mediumDetailShaftIndex = excavateMineShaft(mediumDetailSize, m_mediumDetailShaftIndex, + 1, m_mediumDetailData ); + } else { m_mediumDetailRB->setEnabled(true); QString label = QStringLiteral("Medium (%1x%2x%1)"); m_mediumDetailRB->setText(label.arg(mediumDetailSize).arg(mediumDetailSize / 2)); } - } else if (m_highDetailIndex < highDetailSize) { - m_highDetailIndex = createVolume(highDetailSize, m_highDetailIndex, 1, - m_highDetailData); - if (m_highDetailIndex == highDetailSize) { + } else if (!m_highDetailRB->isEnabled()) { + if (m_highDetailIndex != highDetailSize) { + m_highDetailIndex = createVolume(highDetailSize, m_highDetailIndex, 1, + m_highDetailData); + } else if (m_highDetailShaftIndex != m_mineShaftArray.size()) { + m_highDetailShaftIndex = excavateMineShaft(highDetailSize, m_highDetailShaftIndex, 1, + m_highDetailData); + } else { m_highDetailRB->setEnabled(true); QString label = QStringLiteral("High (%1x%2x%1)"); m_highDetailRB->setText(label.arg(highDetailSize).arg(highDetailSize / 2)); @@ -313,6 +355,11 @@ void VolumetricModifier::setSliceSliders(QSlider *sliderX, QSlider *sliderY, QSl m_sliceSliderX = sliderX; m_sliceSliderY = sliderY; m_sliceSliderZ = sliderZ; + + // Set sliders to interesting values + m_sliceSliderX->setValue(715); + m_sliceSliderY->setValue(612); + m_sliceSliderZ->setValue(715); } void VolumetricModifier::changeColorTable(int enabled) @@ -322,6 +369,8 @@ void VolumetricModifier::changeColorTable(int enabled) else m_volumeItem->setColorTable(m_colorTable1); + m_usingPrimaryTable = !enabled; + // Rerender image labels adjustSliceX(m_sliceSliderX->value()); adjustSliceY(m_sliceSliderY->value()); @@ -338,6 +387,25 @@ void VolumetricModifier::setPreserveOpacity(bool enabled) adjustSliceZ(m_sliceSliderZ->value()); } +void VolumetricModifier::setTransparentGround(bool enabled) +{ + int newAlpha = enabled ? terrainTransparency : 255; + for (int i = aboveWaterGroundColorsMin; i < underWaterGroundColorsMax; i++) { + QRgb oldColor1 = m_colorTable1.at(i); + QRgb oldColor2 = m_colorTable2.at(i); + m_colorTable1[i] = qRgba(qRed(oldColor1), qGreen(oldColor1), qBlue(oldColor1), newAlpha); + m_colorTable2[i] = qRgba(qRed(oldColor2), qGreen(oldColor2), qBlue(oldColor2), newAlpha); + } + if (m_usingPrimaryTable) + m_volumeItem->setColorTable(m_colorTable1); + else + m_volumeItem->setColorTable(m_colorTable2); + + adjustSliceX(m_sliceSliderX->value()); + adjustSliceY(m_sliceSliderY->value()); + adjustSliceZ(m_sliceSliderZ->value()); +} + void VolumetricModifier::setUseHighDefShader(bool enabled) { m_volumeItem->setUseHighDefShader(enabled); @@ -361,29 +429,65 @@ void VolumetricModifier::adjustAlphaMultiplier(int value) adjustSliceZ(m_sliceSliderZ->value()); } +void VolumetricModifier::initHeightMap(QString fileName, QVector &layerData) +{ + QImage heightImage(fileName); + + layerData.resize(layerDataSize * layerDataSize); + const uchar *bits = heightImage.bits(); + int index = 0; + QVector colorTable = heightImage.colorTable(); + for (int i = 0; i < layerDataSize; i++) { + for (int j = 0; j < layerDataSize; j++) { + layerData[index] = qRed(colorTable.at(bits[index])); + index++; + } + } +} + int VolumetricModifier::createVolume(int textureSize, int startIndex, int count, QVector *textureData) { - // Generate example texture data for an half-ellipsoid with a section missing. - // This can take a while if the dimensions are large, so we support incremental data generation. - - QVector3D midPoint(float(textureSize) / 2.0f, - float(textureSize) / 2.0f, - float(textureSize) / 2.0f); - + // Generate volume from layer data. int index = startIndex * textureSize * textureSize / 2.0f; int endIndex = startIndex + count; if (endIndex > textureSize) endIndex = textureSize; + QVector magmaHeights(textureSize); + QVector waterHeights(textureSize); + QVector groundHeights(textureSize); + float multiplier = float(layerDataSize) / float(textureSize); for (int i = startIndex; i < endIndex; i++) { + // Generate layer height arrays + for (int l = 0; l < textureSize; l++) { + int layerIndex = (int(i * multiplier) * layerDataSize + int(l * multiplier)); + magmaHeights[l] = int(m_magmaLayer.at(layerIndex)); + waterHeights[l] = int(m_waterLayer.at(layerIndex)); + groundHeights[l] = int(m_groundLayer.at(layerIndex)); + } for (int j = 0; j < textureSize / 2; j++) { for (int k = 0; k < textureSize; k++) { - int colorIndex = 0; - // Take a section out of the ellipsoid - if (i >= textureSize / 2 || j >= textureSize / 4 || k >= textureSize / 2) { - QVector3D distVec = QVector3D(float(k), float(j * 2), float(i)) - midPoint; - float adjLen = qMin(255.0f, (distVec.length() * 512.0f / float(textureSize))); - colorIndex = 255 - int(adjLen); + int colorIndex; + int height((layerDataSize - (j * 2 * multiplier)) / 2); + if (height < magmaHeights.at(k)) { + // Magma layer + colorIndex = int((float(height) / colorTableSize) + * float(layerColorThickness)) + magmaColorsMin; + } else if (height <= groundHeights.at(k) && height <= waterHeights.at(k)) { + // Ground layer below water + colorIndex = int((float(waterHeights.at(k) - height) / colorTableSize) + * float(layerColorThickness)) + underWaterGroundColorsMin; + } else if (height <= waterHeights.at(k)) { + // Water layer where water goes over ground + colorIndex = int((float(height - magmaHeights.at(k)) / colorTableSize) + * float(layerColorThickness)) + waterColorsMin; + } else if (height <= groundHeights.at(k)) { + // Ground above water + colorIndex = int((float(height - waterHeights.at(k)) / colorTableSize) + * float(layerColorThickness)) + aboveWaterGroundColorsMin; + } else { + // Rest is air + colorIndex = airColorIndex; } (*textureData)[index] = colorIndex; @@ -391,7 +495,139 @@ int VolumetricModifier::createVolume(int textureSize, int startIndex, int count, } } } + return endIndex; +} + +int VolumetricModifier::excavateMineShaft(int textureSize, int startIndex, int count, + QVector *textureData) +{ + int endIndex = startIndex + count; + if (endIndex > m_mineShaftArray.size()) + endIndex = m_mineShaftArray.size(); + int shaftSize = mineShaftDiameter * textureSize / lowDetailSize; + for (int i = startIndex; i < endIndex; i++) { + QVector3D shaftStart(m_mineShaftArray.at(i).first); + QVector3D shaftEnd(m_mineShaftArray.at(i).second); + int shaftLen = (shaftEnd - shaftStart).length() * lowDetailSize; + int dataX = shaftStart.x() * textureSize - (shaftSize / 2); + int dataY = (shaftStart.y() * textureSize - (shaftSize / 2)) / 2; + int dataZ = shaftStart.z() * textureSize - (shaftSize / 2); + int dataIndex = dataX + (dataY * textureSize) + dataZ * (textureSize * textureSize / 2); + if (shaftStart.x() != shaftEnd.x()) { + for (int j = 0; j <= shaftLen; j++) { + excavateMineBlock(textureSize, dataIndex, shaftSize, textureData); + dataIndex += shaftSize; + } + } else if (shaftStart.y() != shaftEnd.y()) { + shaftLen /= 2; // Vertical shafts are half as long + for (int j = 0; j <= shaftLen; j++) { + excavateMineBlock(textureSize, dataIndex, shaftSize, textureData); + dataIndex += textureSize * shaftSize; + } + } else { + for (int j = 0; j <= shaftLen; j++) { + excavateMineBlock(textureSize, dataIndex, shaftSize, textureData); + dataIndex += (textureSize * textureSize / 2) * shaftSize; + } + } + + } return endIndex; } +void VolumetricModifier::excavateMineBlock(int textureSize, int dataIndex, int size, + QVector *textureData) +{ + for (int k = 0; k < size; k++) { + int curIndex = dataIndex + (k * textureSize * textureSize / 2); + for (int l = 0; l < size; l++) { + curIndex = dataIndex + (k * textureSize * textureSize / 2) + + (l * textureSize); + for (int m = 0; m < size; m++) { + if (textureData->at(curIndex) != airColorIndex) + (*textureData)[curIndex] = mineShaftColorIndex; + curIndex++; + } + + } + } +} + +void VolumetricModifier::initMineShaftArray() +{ + m_mineShaftArray << QPair(QVector3D(0.7f, 0.1f, 0.7f), + QVector3D(0.7f, 0.8f, 0.7f)); + m_mineShaftArray << QPair(QVector3D(0.7f, 0.7f, 0.5f), + QVector3D(0.7f, 0.7f, 0.7f)); + + m_mineShaftArray << QPair(QVector3D(0.4f, 0.7f, 0.7f), + QVector3D(0.7f, 0.7f, 0.7f)); + m_mineShaftArray << QPair(QVector3D(0.4f, 0.7f, 0.7f), + QVector3D(0.4f, 0.7f, 0.8f)); + m_mineShaftArray << QPair(QVector3D(0.45f, 0.7f, 0.7f), + QVector3D(0.45f, 0.7f, 0.8f)); + m_mineShaftArray << QPair(QVector3D(0.5f, 0.7f, 0.7f), + QVector3D(0.5f, 0.7f, 0.8f)); + m_mineShaftArray << QPair(QVector3D(0.55f, 0.7f, 0.7f), + QVector3D(0.55f, 0.7f, 0.8f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.7f, 0.7f), + QVector3D(0.6f, 0.7f, 0.8f)); + m_mineShaftArray << QPair(QVector3D(0.65f, 0.7f, 0.7f), + QVector3D(0.65f, 0.7f, 0.8f)); + + m_mineShaftArray << QPair(QVector3D(0.5f, 0.6f, 0.7f), + QVector3D(0.7f, 0.6f, 0.7f)); + m_mineShaftArray << QPair(QVector3D(0.5f, 0.6f, 0.7f), + QVector3D(0.5f, 0.6f, 0.8f)); + m_mineShaftArray << QPair(QVector3D(0.55f, 0.6f, 0.7f), + QVector3D(0.55f, 0.6f, 0.8f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.6f, 0.7f), + QVector3D(0.6f, 0.6f, 0.8f)); + m_mineShaftArray << QPair(QVector3D(0.65f, 0.6f, 0.7f), + QVector3D(0.65f, 0.6f, 0.8f)); + + m_mineShaftArray << QPair(QVector3D(0.7f, 0.6f, 0.4f), + QVector3D(0.7f, 0.6f, 0.7f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.6f, 0.45f), + QVector3D(0.8f, 0.6f, 0.45f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.6f, 0.5f), + QVector3D(0.8f, 0.6f, 0.5f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.6f, 0.55f), + QVector3D(0.8f, 0.6f, 0.55f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.6f, 0.6f), + QVector3D(0.8f, 0.6f, 0.6f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.6f, 0.65f), + QVector3D(0.8f, 0.6f, 0.65f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.6f, 0.7f), + QVector3D(0.8f, 0.6f, 0.7f)); + + m_mineShaftArray << QPair(QVector3D(0.7f, 0.7f, 0.4f), + QVector3D(0.7f, 0.7f, 0.7f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.7f, 0.45f), + QVector3D(0.8f, 0.7f, 0.45f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.7f, 0.5f), + QVector3D(0.8f, 0.7f, 0.5f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.7f, 0.55f), + QVector3D(0.8f, 0.7f, 0.55f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.7f, 0.6f), + QVector3D(0.8f, 0.7f, 0.6f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.7f, 0.65f), + QVector3D(0.8f, 0.7f, 0.65f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.7f, 0.7f), + QVector3D(0.8f, 0.7f, 0.7f)); + + m_mineShaftArray << QPair(QVector3D(0.7f, 0.8f, 0.5f), + QVector3D(0.7f, 0.8f, 0.7f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.8f, 0.55f), + QVector3D(0.8f, 0.8f, 0.55f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.8f, 0.6f), + QVector3D(0.8f, 0.8f, 0.6f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.8f, 0.65f), + QVector3D(0.8f, 0.8f, 0.65f)); + m_mineShaftArray << QPair(QVector3D(0.6f, 0.8f, 0.7f), + QVector3D(0.8f, 0.8f, 0.7f)); + + m_mineShaftArray << QPair(QVector3D(0.7f, 0.1f, 0.4f), + QVector3D(0.7f, 0.7f, 0.4f)); +} diff --git a/examples/datavisualization/volumetric/volumetric.h b/examples/datavisualization/volumetric/volumetric.h index 83af4b3c..27b053e2 100644 --- a/examples/datavisualization/volumetric/volumetric.h +++ b/examples/datavisualization/volumetric/volumetric.h @@ -60,13 +60,19 @@ public slots: void setSliceSliders(QSlider *sliderX, QSlider *sliderY, QSlider *sliderZ); void changeColorTable(int enabled); void setPreserveOpacity(bool enabled); + void setTransparentGround(bool enabled); void setUseHighDefShader(bool enabled); void adjustAlphaMultiplier(int value); private: + void initHeightMap(QString fileName, QVector &layerData); + void initMineShaftArray(); int createVolume(int textureSize, int startIndex, int count, QVector *textureData); + int excavateMineShaft(int textureSize, int startIndex, int count, + QVector *textureData); + void excavateMineBlock(int textureSize, int dataIndex, int size, QVector *textureData); Q3DScatter *m_graph; QCustom3DVolume *m_volumeItem; @@ -82,15 +88,22 @@ private: QTimer m_timer; int m_mediumDetailIndex; int m_highDetailIndex; + int m_mediumDetailShaftIndex; + int m_highDetailShaftIndex; QSlider *m_sliceSliderX; QSlider *m_sliceSliderY; QSlider *m_sliceSliderZ; QVector m_colorTable1; QVector m_colorTable2; + bool m_usingPrimaryTable; QLabel *m_sliceLabelX; QLabel *m_sliceLabelY; QLabel *m_sliceLabelZ; QLabel *m_alphaMultiplierLabel; + QVector m_magmaLayer; + QVector m_waterLayer; + QVector m_groundLayer; + QVector > m_mineShaftArray; }; #endif diff --git a/examples/datavisualization/volumetric/volumetric.pro b/examples/datavisualization/volumetric/volumetric.pro index c5e31891..fa355692 100644 --- a/examples/datavisualization/volumetric/volumetric.pro +++ b/examples/datavisualization/volumetric/volumetric.pro @@ -13,3 +13,5 @@ QT += widgets OTHER_FILES += doc/src/* \ doc/images/* + +RESOURCES += volumetric.qrc diff --git a/examples/datavisualization/volumetric/volumetric.qrc b/examples/datavisualization/volumetric/volumetric.qrc new file mode 100644 index 00000000..920fd1d2 --- /dev/null +++ b/examples/datavisualization/volumetric/volumetric.qrc @@ -0,0 +1,7 @@ + + + layer_ground.png + layer_magma.png + layer_water.png + + -- cgit v1.2.3