From d1bb6473d9751f7f3c4b139306f4793e648d6ae7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 1 Jun 2015 13:57:28 -0700 Subject: [PATCH] more work on edge handling and resizing --- .../src/RenderablePolyVoxEntityItem.cpp | 47 ++++++++++------ .../src/RenderablePolyVoxEntityItem.h | 2 + .../entities/src/EntityScriptingInterface.cpp | 56 +++++++------------ .../entities/src/EntityScriptingInterface.h | 3 + libraries/entities/src/PolyVoxEntityItem.h | 2 + 5 files changed, 58 insertions(+), 52 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index c3b5033466..e190d8f8da 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -53,8 +53,9 @@ RenderablePolyVoxEntityItem::~RenderablePolyVoxEntityItem() { delete _volData; } -bool inBounds(const PolyVox::SimpleVolume* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle surfaceStyle, +bool inUserBounds(const PolyVox::SimpleVolume* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle surfaceStyle, int x, int y, int z) { + // x, y, z are in user voxel-coords, not adjusted-for-edge voxel-coords. switch (surfaceStyle) { case PolyVoxEntityItem::SURFACE_MARCHING_CUBES: case PolyVoxEntityItem::SURFACE_CUBIC: @@ -65,8 +66,8 @@ bool inBounds(const PolyVox::SimpleVolume* vol, PolyVoxEntityItem::Poly return true; case PolyVoxEntityItem::SURFACE_EDGED_CUBIC: - if (x < 1 || y < 1 || z < 1 || - x >= vol->getWidth() - 1 || y >= vol->getHeight() - 1 || z >= vol->getDepth() - 1) { + if (x < 0 || y < 0 || z < 0 || + x >= vol->getWidth() - 2 || y >= vol->getHeight() - 2 || z >= vol->getDepth() - 2) { return false; } return true; @@ -75,6 +76,17 @@ bool inBounds(const PolyVox::SimpleVolume* vol, PolyVoxEntityItem::Poly return false; } + +bool inBounds(const PolyVox::SimpleVolume* vol, int x, int y, int z) { + // x, y, z are in polyvox volume coords + if (x < 0 || y < 0 || z < 0 || + x >= vol->getWidth() || y >= vol->getHeight() || z >= vol->getDepth()) { + return false; + } + return true; +} + + void RenderablePolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) { if (_volData && voxelVolumeSize == _voxelVolumeSize) { return; @@ -195,7 +207,7 @@ glm::mat4 RenderablePolyVoxEntityItem::worldToVoxelMatrix() const { uint8_t RenderablePolyVoxEntityItem::getVoxel(int x, int y, int z) { assert(_volData); - if (!inBounds(_volData, _voxelSurfaceStyle, x, y, z)) { + if (!inUserBounds(_volData, _voxelSurfaceStyle, x, y, z)) { return 0; } @@ -211,7 +223,7 @@ uint8_t RenderablePolyVoxEntityItem::getVoxel(int x, int y, int z) { void RenderablePolyVoxEntityItem::setVoxel(int x, int y, int z, uint8_t toValue) { assert(_volData); - if (!inBounds(_volData, _voxelSurfaceStyle, x, y, z)) { + if (!inUserBounds(_volData, _voxelSurfaceStyle, x, y, z)) { return; } @@ -225,7 +237,7 @@ void RenderablePolyVoxEntityItem::setVoxel(int x, int y, int z, uint8_t toValue) void RenderablePolyVoxEntityItem::updateOnCount(int x, int y, int z, uint8_t toValue) { // keep _onCount up to date - if (!inBounds(_volData, _voxelSurfaceStyle, x, y, z)) { + if (!inUserBounds(_volData, _voxelSurfaceStyle, x, y, z)) { return; } @@ -243,7 +255,6 @@ void RenderablePolyVoxEntityItem::updateOnCount(int x, int y, int z, uint8_t toV } } - void RenderablePolyVoxEntityItem::setAll(uint8_t toValue) { for (int z = 0; z < _voxelVolumeSize.z; z++) { for (int y = 0; y < _voxelVolumeSize.y; y++) { @@ -256,6 +267,11 @@ void RenderablePolyVoxEntityItem::setAll(uint8_t toValue) { compressVolumeData(); } +void RenderablePolyVoxEntityItem::setVoxelInVolume(glm::vec3 position, uint8_t toValue) { + updateOnCount(position.x, position.y, position.z, toValue); + setVoxel(position.x, position.y, position.z, toValue); +} + void RenderablePolyVoxEntityItem::setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue) { // This three-level for loop iterates over every voxel in the volume for (int z = 0; z < _voxelVolumeSize.z; z++) { @@ -400,17 +416,17 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) { class RaycastFunctor { public: - RaycastFunctor(PolyVox::SimpleVolume* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle voxelSurfaceStyle) : + RaycastFunctor(PolyVox::SimpleVolume* vol) : _result(glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)), - _vol(vol), - _voxelSurfaceStyle(voxelSurfaceStyle) { + _vol(vol) { } bool operator()(PolyVox::SimpleVolume::Sampler& sampler) { int x = sampler.getPosition().getX(); int y = sampler.getPosition().getY(); int z = sampler.getPosition().getZ(); - if (!inBounds(_vol, _voxelSurfaceStyle, x, y, z)) { + + if (!inBounds(_vol, x, y, z)) { return true; } @@ -423,7 +439,6 @@ public: } glm::vec4 _result; const PolyVox::SimpleVolume* _vol = nullptr; - PolyVoxEntityItem::PolyVoxSurfaceStyle _voxelSurfaceStyle; }; bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& origin, @@ -452,13 +467,13 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o glm::vec4 originInVoxel = wtvMatrix * glm::vec4(origin, 1.0f); glm::vec4 farInVoxel = wtvMatrix * glm::vec4(farPoint, 1.0f); - PolyVox::Vector3DFloat start(originInVoxel.x, originInVoxel.y, originInVoxel.z); + PolyVox::Vector3DFloat startPoint(originInVoxel.x, originInVoxel.y, originInVoxel.z); // PolyVox::Vector3DFloat pvDirection(directionInVoxel.x, directionInVoxel.y, directionInVoxel.z); - PolyVox::Vector3DFloat far(farInVoxel.x, farInVoxel.y, farInVoxel.z); + PolyVox::Vector3DFloat endPoint(farInVoxel.x, farInVoxel.y, farInVoxel.z); PolyVox::RaycastResult raycastResult; - RaycastFunctor callback(_volData, _voxelSurfaceStyle); - raycastResult = PolyVox::raycastWithEndpoints(_volData, start, far, callback); + RaycastFunctor callback(_volData); + raycastResult = PolyVox::raycastWithEndpoints(_volData, startPoint, endPoint, callback); if (raycastResult == PolyVox::RaycastResults::Completed) { // the ray completed its path -- nothing was hit. diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index 86018b9fb2..c8f1b4a49d 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -69,6 +69,8 @@ public: virtual void setAll(uint8_t toValue); + virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue); + private: // The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions // may not match _voxelVolumeSize. diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 34c5199a0c..6866505d58 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -17,7 +17,6 @@ #include "ModelEntityItem.h" #include "ZoneEntityItem.h" #include "EntitiesLogging.h" -#include "PolyVoxEntityItem.h" EntityScriptingInterface::EntityScriptingInterface() : @@ -395,7 +394,8 @@ void RayToEntityIntersectionResultFromScriptValue(const QScriptValue& object, Ra } -bool EntityScriptingInterface::setVoxelSphere(QUuid entityID, const glm::vec3& center, float radius, int value) { +bool EntityScriptingInterface::setVoxels(QUuid entityID, + std::function actor) { if (!_entityTree) { return false; } @@ -415,7 +415,7 @@ bool EntityScriptingInterface::setVoxelSphere(QUuid entityID, const glm::vec3& c PolyVoxEntityItem* polyVoxEntity = static_cast(entity.get()); _entityTree->lockForWrite(); - polyVoxEntity->setSphere(center, radius, value); + actor(*polyVoxEntity); entity->setLastEdited(now); entity->setLastBroadcast(now); _entityTree->unlock(); @@ -432,38 +432,22 @@ bool EntityScriptingInterface::setVoxelSphere(QUuid entityID, const glm::vec3& c } +bool EntityScriptingInterface::setVoxelSphere(QUuid entityID, const glm::vec3& center, float radius, int value) { + return setVoxels(entityID, [center, radius, value](PolyVoxEntityItem& polyVoxEntity) { + polyVoxEntity.setSphere(center, radius, value); + }); +} + + +bool EntityScriptingInterface::setVoxel(QUuid entityID, const glm::vec3& position, int value) { + return setVoxels(entityID, [position, value](PolyVoxEntityItem& polyVoxEntity) { + polyVoxEntity.setVoxelInVolume(position, value); + }); +} + + bool EntityScriptingInterface::setAllVoxels(QUuid entityID, int value) { - if (!_entityTree) { - return false; - } - - EntityItemPointer entity = static_cast(_entityTree->findEntityByEntityItemID(entityID)); - if (!entity) { - qCDebug(entities) << "EntityScriptingInterface::setVoxelSphere no entity with ID" << entityID; - return false; - } - - EntityTypes::EntityType entityType = entity->getType(); - if (entityType != EntityTypes::PolyVox) { - return false; - } - - auto now = usecTimestampNow(); - - PolyVoxEntityItem* polyVoxEntity = static_cast(entity.get()); - _entityTree->lockForWrite(); - polyVoxEntity->setAll(value); - entity->setLastEdited(now); - entity->setLastBroadcast(now); - _entityTree->unlock(); - - _entityTree->lockForRead(); - EntityItemProperties properties = entity->getProperties(); - _entityTree->unlock(); - - properties.setVoxelDataDirty(); - properties.setLastEdited(now); - - queueEntityMessage(PacketTypeEntityEdit, entityID, properties); - return true; + return setVoxels(entityID, [value](PolyVoxEntityItem& polyVoxEntity) { + polyVoxEntity.setAll(value); + }); } diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 421875feef..7761effe2f 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -21,6 +21,7 @@ #include #include #include +#include "PolyVoxEntityItem.h" #include "EntityEditPacketSender.h" @@ -117,7 +118,9 @@ public slots: Q_INVOKABLE void setSendPhysicsUpdates(bool value); Q_INVOKABLE bool getSendPhysicsUpdates() const; + bool setVoxels(QUuid entityID, std::function actor); 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 void dumpTree() const; diff --git a/libraries/entities/src/PolyVoxEntityItem.h b/libraries/entities/src/PolyVoxEntityItem.h index 63bd4856d3..bf8214675b 100644 --- a/libraries/entities/src/PolyVoxEntityItem.h +++ b/libraries/entities/src/PolyVoxEntityItem.h @@ -81,6 +81,8 @@ class PolyVoxEntityItem : public EntityItem { virtual void setAll(uint8_t toValue) {} + virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue) {} + virtual uint8_t getVoxel(int x, int y, int z) { return 0; } virtual void setVoxel(int x, int y, int z, uint8_t toValue) {}