From c5a0dd72ec0f0f11ffebc8697659495c44d77b05 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 30 May 2015 18:13:57 -0700 Subject: [PATCH] keep track of number of non-zero voxels, use this information when deciding on shape-type --- .../src/RenderablePolyVoxEntityItem.cpp | 181 ++++++++++-------- .../src/RenderablePolyVoxEntityItem.h | 5 +- 2 files changed, 103 insertions(+), 83 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 4941acdf36..389a5eac4f 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -70,6 +70,7 @@ void RenderablePolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) PolyVox::Vector3DInt32 highCorner(_voxelVolumeSize[0] - 1, // -1 because these corners are inclusive _voxelVolumeSize[1] - 1, _voxelVolumeSize[2] - 1); + _onCount = 0; _volData = new PolyVox::SimpleVolume(PolyVox::Region(lowCorner, highCorner)); compressVolumeData(); @@ -117,12 +118,30 @@ glm::mat4 RenderablePolyVoxEntityItem::worldToVoxelMatrix() const { } +void RenderablePolyVoxEntityItem::updateOnCount(int x, int y, int z, uint8_t toValue) { + // keep _onCount up to date + uint8_t uVoxelValue = _volData->getVoxelAt(x, y, z); + if (toValue != 0) { + if (uVoxelValue == 0) { + _onCount++; + } + } else { + // toValue == 0 + if (uVoxelValue != 0) { + _onCount--; + assert(_onCount >= 0); + } + } +} + + void RenderablePolyVoxEntityItem::setAll(uint8_t toValue) { // XXX a volume that is all "on" has no mesh. make a different call for this nearly-all code: for (int z = 1; z < _volData->getDepth() - 1; z++) { for (int y = 1; y < _volData->getHeight() - 1; y++) { for (int x = 1; x < _volData->getWidth() - 1; x++) { - _volData->setVoxelAt(x, y, z, toValue); + updateOnCount(x, y, z, toValue); + _volData->setVoxelAt(x, y, z, toValue); } } } @@ -140,6 +159,7 @@ void RenderablePolyVoxEntityItem::setSphereInVolume(glm::vec3 center, float radi float fDistToCenter = glm::distance(pos, center); // If the current voxel is less than 'radius' units from the center then we make it solid. if (fDistToCenter <= radius) { + updateOnCount(x, y, z, toValue); _volData->setVoxelAt(x, y, z, toValue); } } @@ -361,6 +381,7 @@ void RenderablePolyVoxEntityItem::decompressVolumeData() { for (int y = 0; y < _volData->getHeight(); y++) { for (int x = 0; x < _volData->getWidth(); x++) { int uncompressedIndex = z * _volData->getHeight() * _volData->getWidth() + y * _volData->getWidth() + x; + updateOnCount(x, y, z, uncompressedData[uncompressedIndex]); _volData->setVoxelAt(x, y, z, uncompressedData[uncompressedIndex]); } } @@ -374,96 +395,92 @@ void RenderablePolyVoxEntityItem::decompressVolumeData() { getModel(); } +// virtual +ShapeType RenderablePolyVoxEntityItem::getShapeType() const { + if (_onCount > 0) { + return SHAPE_TYPE_COMPOUND; + } + return SHAPE_TYPE_NONE; +} + + bool RenderablePolyVoxEntityItem::isReadyToComputeShape() { - qDebug() << "RenderablePolyVoxEntityItem::isReadyToComputeShape" << (!_needsModelReload); - if (_needsModelReload) { - getModel(); + return false; } - for (int z = 0; z < _volData->getDepth(); z++) { - for (int y = 0; y < _volData->getHeight(); y++) { - for (int x = 0; x < _volData->getWidth(); x++) { - if (_volData->getVoxelAt(x, y, z) > 0) { - return true; - } - } - } - } - - return false; + qDebug() << "RenderablePolyVoxEntityItem::isReadyToComputeShape" << (!_needsModelReload); + return true; } void RenderablePolyVoxEntityItem::computeShapeInfo(ShapeInfo& info) { qDebug() << "RenderablePolyVoxEntityItem::computeShapeInfo"; ShapeType type = getShapeType(); if (type != SHAPE_TYPE_COMPOUND) { - qDebug() << "RenderablePolyVoxEntityItem::computeShapeInfo NOT COMPOUND"; - PolyVoxEntityItem::computeShapeInfo(info); - info.setParams(type, 0.5f * getDimensions()); - } else { - _points.clear(); - unsigned int i = 0; - - glm::mat4 wToM = voxelToLocalMatrix(); - - AABox box; - - for (int z = 0; z < _volData->getDepth(); z++) { - for (int y = 0; y < _volData->getHeight(); y++) { - for (int x = 0; x < _volData->getWidth(); x++) { - if (_volData->getVoxelAt(x, y, z) > 0) { - QVector pointsInPart; - - float offL = -0.5f; - float offH = 0.5f; - - // XXX I don't really understand why this make it line up. - // float offL = -1.0f; - // float offH = 0.0f; - - - glm::vec3 p000 = glm::vec3(wToM * glm::vec4(x + offL, y + offL, z + offL, 1.0f)); - glm::vec3 p001 = glm::vec3(wToM * glm::vec4(x + offL, y + offL, z + offH, 1.0f)); - glm::vec3 p010 = glm::vec3(wToM * glm::vec4(x + offL, y + offH, z + offL, 1.0f)); - glm::vec3 p011 = glm::vec3(wToM * glm::vec4(x + offL, y + offH, z + offH, 1.0f)); - glm::vec3 p100 = glm::vec3(wToM * glm::vec4(x + offH, y + offL, z + offL, 1.0f)); - glm::vec3 p101 = glm::vec3(wToM * glm::vec4(x + offH, y + offL, z + offH, 1.0f)); - glm::vec3 p110 = glm::vec3(wToM * glm::vec4(x + offH, y + offH, z + offL, 1.0f)); - glm::vec3 p111 = glm::vec3(wToM * glm::vec4(x + offH, y + offH, z + offH, 1.0f)); - - box += p000; - box += p001; - box += p010; - box += p011; - box += p100; - box += p101; - box += p110; - box += p111; - - pointsInPart << p000; - pointsInPart << p001; - pointsInPart << p010; - pointsInPart << p011; - pointsInPart << p100; - pointsInPart << p101; - pointsInPart << p110; - pointsInPart << p111; - - // add next convex hull - QVector newMeshPoints; - _points << newMeshPoints; - // add points to the new convex hull - _points[i++] << pointsInPart; - } - } - } - } - - - glm::vec3 collisionModelDimensions = box.getDimensions(); - QByteArray b64 = _voxelData.toBase64(); - info.setParams(type, collisionModelDimensions, QString(b64)); - info.setConvexHulls(_points); + EntityItem::computeShapeInfo(info); + return; } + + _points.clear(); + unsigned int i = 0; + + glm::mat4 wToM = voxelToLocalMatrix(); + + AABox box; + + for (int z = 0; z < _volData->getDepth(); z++) { + for (int y = 0; y < _volData->getHeight(); y++) { + for (int x = 0; x < _volData->getWidth(); x++) { + if (_volData->getVoxelAt(x, y, z) > 0) { + QVector pointsInPart; + + float offL = -0.5f; + float offH = 0.5f; + + glm::vec3 p000 = glm::vec3(wToM * glm::vec4(x + offL, y + offL, z + offL, 1.0f)); + glm::vec3 p001 = glm::vec3(wToM * glm::vec4(x + offL, y + offL, z + offH, 1.0f)); + glm::vec3 p010 = glm::vec3(wToM * glm::vec4(x + offL, y + offH, z + offL, 1.0f)); + glm::vec3 p011 = glm::vec3(wToM * glm::vec4(x + offL, y + offH, z + offH, 1.0f)); + glm::vec3 p100 = glm::vec3(wToM * glm::vec4(x + offH, y + offL, z + offL, 1.0f)); + glm::vec3 p101 = glm::vec3(wToM * glm::vec4(x + offH, y + offL, z + offH, 1.0f)); + glm::vec3 p110 = glm::vec3(wToM * glm::vec4(x + offH, y + offH, z + offL, 1.0f)); + glm::vec3 p111 = glm::vec3(wToM * glm::vec4(x + offH, y + offH, z + offH, 1.0f)); + + box += p000; + box += p001; + box += p010; + box += p011; + box += p100; + box += p101; + box += p110; + box += p111; + + pointsInPart << p000; + pointsInPart << p001; + pointsInPart << p010; + pointsInPart << p011; + pointsInPart << p100; + pointsInPart << p101; + pointsInPart << p110; + pointsInPart << p111; + + // add next convex hull + QVector newMeshPoints; + _points << newMeshPoints; + // add points to the new convex hull + _points[i++] << pointsInPart; + } + } + } + } + + if (_points.isEmpty()) { + EntityItem::computeShapeInfo(info); + return; + } + + glm::vec3 collisionModelDimensions = box.getDimensions(); + QByteArray b64 = _voxelData.toBase64(); + info.setParams(type, collisionModelDimensions, QString(b64)); + info.setConvexHulls(_points); } diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index b569d3d5b6..d659cc0e69 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -33,6 +33,7 @@ public: // _needsModelReload = true; } + void updateOnCount(int x, int y, int z, uint8_t new_value); void render(RenderArgs* args); virtual bool supportsDetailedRayIntersection() const { return true; } @@ -51,7 +52,7 @@ public: glm::mat4 voxelToLocalMatrix() const; glm::mat4 worldToVoxelMatrix() const; - + virtual ShapeType getShapeType() const; virtual bool isReadyToComputeShape(); virtual void computeShapeInfo(ShapeInfo& info); @@ -73,6 +74,8 @@ private: bool _needsModelReload = true; QVector> _points; // XXX + + int _onCount = 0; // how many non-zero voxels are in _volData };