From 7369ca19e9874498da5e27776547c1d34530e5e3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 31 Aug 2015 18:01:15 -0700 Subject: [PATCH] allow setting cuboid voxel spaces. clean up some locking --- .../src/RenderablePolyVoxEntityItem.cpp | 59 +++++++++++++++---- .../src/RenderablePolyVoxEntityItem.h | 1 + .../entities/src/EntityScriptingInterface.cpp | 7 +++ .../entities/src/EntityScriptingInterface.h | 2 + libraries/entities/src/PolyVoxEntityItem.cpp | 18 ++++-- libraries/entities/src/PolyVoxEntityItem.h | 3 +- 6 files changed, 70 insertions(+), 20 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 7d7607860d..2a7b3fe299 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -201,6 +201,37 @@ bool RenderablePolyVoxEntityItem::setAll(uint8_t toValue) { } +bool RenderablePolyVoxEntityItem::setCuboid(const glm::vec3& lowPosition, const glm::vec3& cuboidSize, int toValue) { + bool result = false; + if (_locked) { + return result; + } + + int xLow = std::max(std::min((int)roundf(lowPosition.x), (int)roundf(_voxelVolumeSize.x) - 1), 0); + int yLow = std::max(std::min((int)roundf(lowPosition.y), (int)roundf(_voxelVolumeSize.y) - 1), 0); + int zLow = std::max(std::min((int)roundf(lowPosition.z), (int)roundf(_voxelVolumeSize.z) - 1), 0); + int xHigh = std::max(std::min(xLow + (int)roundf(cuboidSize.x), (int)roundf(_voxelVolumeSize.x)), xLow); + int yHigh = std::max(std::min(yLow + (int)roundf(cuboidSize.y), (int)roundf(_voxelVolumeSize.y)), yLow); + int zHigh = std::max(std::min(zLow + (int)roundf(cuboidSize.z), (int)roundf(_voxelVolumeSize.z)), zLow); + + _volDataLock.lockForWrite(); + _volDataDirty = true; + + for (int x = xLow; x < xHigh; x++) { + for (int y = yLow; y < yHigh; y++) { + for (int z = zLow; z < zHigh; z++) { + result |= setVoxelInternal(x, y, z, toValue); + } + } + } + _volDataLock.unlock(); + if (result) { + compressVolumeDataAndSendEditPacket(); + } + return result; +} + + bool RenderablePolyVoxEntityItem::setVoxelInVolume(glm::vec3 position, uint8_t toValue) { if (_locked) { @@ -408,9 +439,8 @@ bool RenderablePolyVoxEntityItem::isReadyToComputeShape() { } void RenderablePolyVoxEntityItem::computeShapeInfo(ShapeInfo& info) { - _shapeInfoLock.lockForRead(); + QReadLocker(&this->_shapeInfoLock); info = _shapeInfo; - _shapeInfoLock.unlock(); } void RenderablePolyVoxEntityItem::setXTextureURL(QString xTextureURL) { @@ -643,10 +673,8 @@ bool RenderablePolyVoxEntityItem::inUserBounds(const PolyVox::SimpleVolume_volDataLock); + return getVoxelInternal(x, y, z); } @@ -903,10 +931,10 @@ void RenderablePolyVoxEntityItem::copyUpperEdgesFromNeighbors() { if (currentXNeighbor) { auto polyVoxXNeighbor = std::dynamic_pointer_cast(currentXNeighbor); - if (polyVoxXNeighbor->_volData->getEnclosingRegion() == _volData->getEnclosingRegion()) { + if (polyVoxXNeighbor->getVoxelVolumeSize() == _voxelVolumeSize) { for (int y = 0; y < _volData->getHeight(); y++) { for (int z = 0; z < _volData->getDepth(); z++) { - uint8_t neighborValue = polyVoxXNeighbor->_volData->getVoxelAt(1, y, z); + uint8_t neighborValue = polyVoxXNeighbor->getVoxel(0, y, z); _volData->setVoxelAt(_volData->getWidth() - 1, y, z, neighborValue); } } @@ -915,10 +943,10 @@ void RenderablePolyVoxEntityItem::copyUpperEdgesFromNeighbors() { if (currentYNeighbor) { auto polyVoxYNeighbor = std::dynamic_pointer_cast(currentYNeighbor); - if (polyVoxYNeighbor->_volData->getEnclosingRegion() == _volData->getEnclosingRegion()) { + if (polyVoxYNeighbor->getVoxelVolumeSize() == _voxelVolumeSize) { for (int x = 0; x < _volData->getWidth(); x++) { for (int z = 0; z < _volData->getDepth(); z++) { - uint8_t neighborValue = polyVoxYNeighbor->_volData->getVoxelAt(x, 1, z); + uint8_t neighborValue = polyVoxYNeighbor->getVoxel(x, 0, z); _volData->setVoxelAt(x, _volData->getWidth() - 1, z, neighborValue); } } @@ -927,10 +955,10 @@ void RenderablePolyVoxEntityItem::copyUpperEdgesFromNeighbors() { if (currentZNeighbor) { auto polyVoxZNeighbor = std::dynamic_pointer_cast(currentZNeighbor); - if (polyVoxZNeighbor->_volData->getEnclosingRegion() == _volData->getEnclosingRegion()) { + if (polyVoxZNeighbor->getVoxelVolumeSize() == _voxelVolumeSize) { for (int x = 0; x < _volData->getWidth(); x++) { for (int y = 0; y < _volData->getHeight(); y++) { - uint8_t neighborValue = polyVoxZNeighbor->_volData->getVoxelAt(x, y, 1); + uint8_t neighborValue = polyVoxZNeighbor->getVoxel(x, y, 0); _volData->setVoxelAt(x, y, _volData->getDepth() - 1, neighborValue); } } @@ -951,12 +979,17 @@ void RenderablePolyVoxEntityItem::getMeshAsync() { model::MeshPointer mesh(new model::Mesh()); cacheNeighbors(); - copyUpperEdgesFromNeighbors(); // A mesh object to hold the result of surface extraction PolyVox::SurfaceMesh polyVoxMesh; _volDataLock.lockForRead(); + if (!_volData) { + _volDataLock.unlock(); + return; + } + copyUpperEdgesFromNeighbors(); + switch (_voxelSurfaceStyle) { case PolyVoxEntityItem::SURFACE_EDGED_MARCHING_CUBES: { PolyVox::MarchingCubesSurfaceExtractor> surfaceExtractor diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index fa203f5e4d..98d2b0665d 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -93,6 +93,7 @@ public: // coords are in world-space virtual bool setSphere(glm::vec3 center, float radius, uint8_t toValue); virtual bool setAll(uint8_t toValue); + virtual bool setCuboid(const glm::vec3& lowPosition, const glm::vec3& cuboidSize, int toValue); virtual void setXTextureURL(QString xTextureURL); virtual void setYTextureURL(QString yTextureURL); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index fee2055bd0..b337c05776 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -493,6 +493,13 @@ bool EntityScriptingInterface::setAllVoxels(QUuid entityID, int value) { }); } +bool EntityScriptingInterface::setVoxelsInCuboid(QUuid entityID, const glm::vec3& lowPosition, + const glm::vec3& cuboidSize, int value) { + return setVoxels(entityID, [lowPosition, cuboidSize, value](PolyVoxEntityItem& polyVoxEntity) { + return polyVoxEntity.setCuboid(lowPosition, cuboidSize, value); + }); +} + bool EntityScriptingInterface::setAllPoints(QUuid entityID, const QVector& points) { EntityItemPointer entity = static_cast(_entityTree->findEntityByEntityItemID(entityID)); if (!entity) { diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index a51ebfb61c..ff693e4585 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -122,6 +122,8 @@ public slots: Q_INVOKABLE bool setVoxelSphere(QUuid entityID, const glm::vec3& center, float radius, int value); Q_INVOKABLE bool setVoxel(QUuid entityID, const glm::vec3& position, int value); Q_INVOKABLE bool setAllVoxels(QUuid entityID, int value); + Q_INVOKABLE bool setVoxelsInCuboid(QUuid entityID, const glm::vec3& lowPosition, + const glm::vec3& cuboidSize, int value); Q_INVOKABLE bool setAllPoints(QUuid entityID, const QVector& points); Q_INVOKABLE bool appendPoint(QUuid entityID, const glm::vec3& point); diff --git a/libraries/entities/src/PolyVoxEntityItem.cpp b/libraries/entities/src/PolyVoxEntityItem.cpp index 0ce71a37ad..0da66e962b 100644 --- a/libraries/entities/src/PolyVoxEntityItem.cpp +++ b/libraries/entities/src/PolyVoxEntityItem.cpp @@ -12,6 +12,7 @@ #include #include +#include #include @@ -62,6 +63,8 @@ PolyVoxEntityItem::PolyVoxEntityItem(const EntityItemID& entityItemID, const Ent } void PolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) { + QWriteLocker(&this->_voxelDataLock); + assert((int)_voxelVolumeSize.x == _voxelVolumeSize.x); assert((int)_voxelVolumeSize.y == _voxelVolumeSize.y); assert((int)_voxelVolumeSize.z == _voxelVolumeSize.z); @@ -95,6 +98,12 @@ void PolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) { } } +const glm::vec3& PolyVoxEntityItem::getVoxelVolumeSize() const { + QWriteLocker locker(&this->_voxelDataLock); + return _voxelVolumeSize; +} + + EntityItemProperties PolyVoxEntityItem::getProperties() const { EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelVolumeSize, getVoxelVolumeSize); @@ -200,15 +209,12 @@ void PolyVoxEntityItem::debugDump() const { } void PolyVoxEntityItem::setVoxelData(QByteArray voxelData) { - _voxelDataLock.lockForWrite(); + QWriteLocker(&this->_voxelDataLock); _voxelData = voxelData; _voxelDataDirty = true; - _voxelDataLock.unlock(); } const QByteArray PolyVoxEntityItem::getVoxelData() const { - _voxelDataLock.lockForRead(); - auto result = _voxelData; - _voxelDataLock.unlock(); - return result; + QReadLocker(&this->_voxelDataLock); + return _voxelData; } diff --git a/libraries/entities/src/PolyVoxEntityItem.h b/libraries/entities/src/PolyVoxEntityItem.h index 886a9c37c7..55118f9017 100644 --- a/libraries/entities/src/PolyVoxEntityItem.h +++ b/libraries/entities/src/PolyVoxEntityItem.h @@ -50,7 +50,7 @@ class PolyVoxEntityItem : public EntityItem { virtual void debugDump() const; virtual void setVoxelVolumeSize(glm::vec3 voxelVolumeSize); - virtual const glm::vec3& getVoxelVolumeSize() const { return _voxelVolumeSize; } + virtual const glm::vec3& getVoxelVolumeSize() const; virtual void setVoxelData(QByteArray voxelData); virtual const QByteArray getVoxelData() const; @@ -85,6 +85,7 @@ class PolyVoxEntityItem : public EntityItem { // coords are in world-space virtual bool setSphere(glm::vec3 center, float radius, uint8_t toValue) { return false; } virtual bool setAll(uint8_t toValue) { return false; } + virtual bool setCuboid(const glm::vec3& lowPosition, const glm::vec3& cuboidSize, int value) { return false; } virtual uint8_t getVoxel(int x, int y, int z) { return 0; } virtual bool setVoxel(int x, int y, int z, uint8_t toValue) { return false; }