summaryrefslogtreecommitdiffstats
path: root/examples/datavisualization
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2014-09-02 15:10:53 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2014-09-03 09:12:19 +0300
commit57726e6752eacbbfee906479be9e1c49d456fb6f (patch)
tree7196bb1b37c1f0a552b2fbfa12463e78602dfb60 /examples/datavisualization
parent3c2d0623c74cc51d0c3b73e0b56b5f5052676ee4 (diff)
Change volumetric example to show fictional terrain
Change-Id: I7cb3c59acef5364ff964da3e756d2db387b53308 Reviewed-by: Mika Salmela <mika.salmela@digia.com> Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'examples/datavisualization')
-rw-r--r--examples/datavisualization/volumetric/layer_ground.pngbin0 -> 63473 bytes
-rw-r--r--examples/datavisualization/volumetric/layer_magma.pngbin0 -> 17332 bytes
-rw-r--r--examples/datavisualization/volumetric/layer_water.pngbin0 -> 27124 bytes
-rw-r--r--examples/datavisualization/volumetric/main.cpp10
-rw-r--r--examples/datavisualization/volumetric/volumetric.cpp332
-rw-r--r--examples/datavisualization/volumetric/volumetric.h13
-rw-r--r--examples/datavisualization/volumetric/volumetric.pro2
-rw-r--r--examples/datavisualization/volumetric/volumetric.qrc7
8 files changed, 315 insertions, 49 deletions
diff --git a/examples/datavisualization/volumetric/layer_ground.png b/examples/datavisualization/volumetric/layer_ground.png
new file mode 100644
index 00000000..3f96a122
--- /dev/null
+++ b/examples/datavisualization/volumetric/layer_ground.png
Binary files differ
diff --git a/examples/datavisualization/volumetric/layer_magma.png b/examples/datavisualization/volumetric/layer_magma.png
new file mode 100644
index 00000000..01434d35
--- /dev/null
+++ b/examples/datavisualization/volumetric/layer_magma.png
Binary files differ
diff --git a/examples/datavisualization/volumetric/layer_water.png b/examples/datavisualization/volumetric/layer_water.png
new file mode 100644
index 00000000..4d57563e
--- /dev/null
+++ b/examples/datavisualization/volumetric/layer_water.png
Binary files 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<uchar>(mediumDetailSize * mediumDetailSize * mediumDetailSize / 2);
m_highDetailData = new QVector<uchar>(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<uchar>(*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<uchar> &layerData)
+{
+ QImage heightImage(fileName);
+
+ layerData.resize(layerDataSize * layerDataSize);
+ const uchar *bits = heightImage.bits();
+ int index = 0;
+ QVector<QRgb> 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<uchar> *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<uchar> magmaHeights(textureSize);
+ QVector<uchar> waterHeights(textureSize);
+ QVector<uchar> 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<uchar> *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<uchar> *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, QVector3D>(QVector3D(0.7f, 0.1f, 0.7f),
+ QVector3D(0.7f, 0.8f, 0.7f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.7f, 0.7f, 0.5f),
+ QVector3D(0.7f, 0.7f, 0.7f));
+
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.4f, 0.7f, 0.7f),
+ QVector3D(0.7f, 0.7f, 0.7f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.4f, 0.7f, 0.7f),
+ QVector3D(0.4f, 0.7f, 0.8f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.45f, 0.7f, 0.7f),
+ QVector3D(0.45f, 0.7f, 0.8f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.5f, 0.7f, 0.7f),
+ QVector3D(0.5f, 0.7f, 0.8f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.55f, 0.7f, 0.7f),
+ QVector3D(0.55f, 0.7f, 0.8f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.7f, 0.7f),
+ QVector3D(0.6f, 0.7f, 0.8f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.65f, 0.7f, 0.7f),
+ QVector3D(0.65f, 0.7f, 0.8f));
+
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.5f, 0.6f, 0.7f),
+ QVector3D(0.7f, 0.6f, 0.7f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.5f, 0.6f, 0.7f),
+ QVector3D(0.5f, 0.6f, 0.8f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.55f, 0.6f, 0.7f),
+ QVector3D(0.55f, 0.6f, 0.8f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.6f, 0.7f),
+ QVector3D(0.6f, 0.6f, 0.8f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.65f, 0.6f, 0.7f),
+ QVector3D(0.65f, 0.6f, 0.8f));
+
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.7f, 0.6f, 0.4f),
+ QVector3D(0.7f, 0.6f, 0.7f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.6f, 0.45f),
+ QVector3D(0.8f, 0.6f, 0.45f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.6f, 0.5f),
+ QVector3D(0.8f, 0.6f, 0.5f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.6f, 0.55f),
+ QVector3D(0.8f, 0.6f, 0.55f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.6f, 0.6f),
+ QVector3D(0.8f, 0.6f, 0.6f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.6f, 0.65f),
+ QVector3D(0.8f, 0.6f, 0.65f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.6f, 0.7f),
+ QVector3D(0.8f, 0.6f, 0.7f));
+
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.7f, 0.7f, 0.4f),
+ QVector3D(0.7f, 0.7f, 0.7f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.7f, 0.45f),
+ QVector3D(0.8f, 0.7f, 0.45f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.7f, 0.5f),
+ QVector3D(0.8f, 0.7f, 0.5f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.7f, 0.55f),
+ QVector3D(0.8f, 0.7f, 0.55f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.7f, 0.6f),
+ QVector3D(0.8f, 0.7f, 0.6f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.7f, 0.65f),
+ QVector3D(0.8f, 0.7f, 0.65f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.7f, 0.7f),
+ QVector3D(0.8f, 0.7f, 0.7f));
+
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.7f, 0.8f, 0.5f),
+ QVector3D(0.7f, 0.8f, 0.7f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.8f, 0.55f),
+ QVector3D(0.8f, 0.8f, 0.55f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.8f, 0.6f),
+ QVector3D(0.8f, 0.8f, 0.6f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.8f, 0.65f),
+ QVector3D(0.8f, 0.8f, 0.65f));
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(QVector3D(0.6f, 0.8f, 0.7f),
+ QVector3D(0.8f, 0.8f, 0.7f));
+
+ m_mineShaftArray << QPair<QVector3D, QVector3D>(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<uchar> &layerData);
+ void initMineShaftArray();
int createVolume(int textureSize, int startIndex, int count,
QVector<uchar> *textureData);
+ int excavateMineShaft(int textureSize, int startIndex, int count,
+ QVector<uchar> *textureData);
+ void excavateMineBlock(int textureSize, int dataIndex, int size, QVector<uchar> *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<QRgb> m_colorTable1;
QVector<QRgb> m_colorTable2;
+ bool m_usingPrimaryTable;
QLabel *m_sliceLabelX;
QLabel *m_sliceLabelY;
QLabel *m_sliceLabelZ;
QLabel *m_alphaMultiplierLabel;
+ QVector<uchar> m_magmaLayer;
+ QVector<uchar> m_waterLayer;
+ QVector<uchar> m_groundLayer;
+ QVector<QPair<QVector3D, QVector3D> > 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 @@
+<RCC>
+ <qresource prefix="/heightmaps">
+ <file>layer_ground.png</file>
+ <file>layer_magma.png</file>
+ <file>layer_water.png</file>
+ </qresource>
+</RCC>