allow setting cuboid voxel spaces. clean up some locking

This commit is contained in:
Seth Alves 2015-08-31 18:01:15 -07:00
parent 6096c20db0
commit 7369ca19e9
6 changed files with 70 additions and 20 deletions

View file

@ -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) { bool RenderablePolyVoxEntityItem::setVoxelInVolume(glm::vec3 position, uint8_t toValue) {
if (_locked) { if (_locked) {
@ -408,9 +439,8 @@ bool RenderablePolyVoxEntityItem::isReadyToComputeShape() {
} }
void RenderablePolyVoxEntityItem::computeShapeInfo(ShapeInfo& info) { void RenderablePolyVoxEntityItem::computeShapeInfo(ShapeInfo& info) {
_shapeInfoLock.lockForRead(); QReadLocker(&this->_shapeInfoLock);
info = _shapeInfo; info = _shapeInfo;
_shapeInfoLock.unlock();
} }
void RenderablePolyVoxEntityItem::setXTextureURL(QString xTextureURL) { void RenderablePolyVoxEntityItem::setXTextureURL(QString xTextureURL) {
@ -643,10 +673,8 @@ bool RenderablePolyVoxEntityItem::inUserBounds(const PolyVox::SimpleVolume<uint8
uint8_t RenderablePolyVoxEntityItem::getVoxel(int x, int y, int z) { uint8_t RenderablePolyVoxEntityItem::getVoxel(int x, int y, int z) {
_volDataLock.lockForRead(); QReadLocker(&this->_volDataLock);
auto result = getVoxelInternal(x, y, z); return getVoxelInternal(x, y, z);
_volDataLock.unlock();
return result;
} }
@ -903,10 +931,10 @@ void RenderablePolyVoxEntityItem::copyUpperEdgesFromNeighbors() {
if (currentXNeighbor) { if (currentXNeighbor) {
auto polyVoxXNeighbor = std::dynamic_pointer_cast<RenderablePolyVoxEntityItem>(currentXNeighbor); auto polyVoxXNeighbor = std::dynamic_pointer_cast<RenderablePolyVoxEntityItem>(currentXNeighbor);
if (polyVoxXNeighbor->_volData->getEnclosingRegion() == _volData->getEnclosingRegion()) { if (polyVoxXNeighbor->getVoxelVolumeSize() == _voxelVolumeSize) {
for (int y = 0; y < _volData->getHeight(); y++) { for (int y = 0; y < _volData->getHeight(); y++) {
for (int z = 0; z < _volData->getDepth(); z++) { 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); _volData->setVoxelAt(_volData->getWidth() - 1, y, z, neighborValue);
} }
} }
@ -915,10 +943,10 @@ void RenderablePolyVoxEntityItem::copyUpperEdgesFromNeighbors() {
if (currentYNeighbor) { if (currentYNeighbor) {
auto polyVoxYNeighbor = std::dynamic_pointer_cast<RenderablePolyVoxEntityItem>(currentYNeighbor); auto polyVoxYNeighbor = std::dynamic_pointer_cast<RenderablePolyVoxEntityItem>(currentYNeighbor);
if (polyVoxYNeighbor->_volData->getEnclosingRegion() == _volData->getEnclosingRegion()) { if (polyVoxYNeighbor->getVoxelVolumeSize() == _voxelVolumeSize) {
for (int x = 0; x < _volData->getWidth(); x++) { for (int x = 0; x < _volData->getWidth(); x++) {
for (int z = 0; z < _volData->getDepth(); z++) { 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); _volData->setVoxelAt(x, _volData->getWidth() - 1, z, neighborValue);
} }
} }
@ -927,10 +955,10 @@ void RenderablePolyVoxEntityItem::copyUpperEdgesFromNeighbors() {
if (currentZNeighbor) { if (currentZNeighbor) {
auto polyVoxZNeighbor = std::dynamic_pointer_cast<RenderablePolyVoxEntityItem>(currentZNeighbor); auto polyVoxZNeighbor = std::dynamic_pointer_cast<RenderablePolyVoxEntityItem>(currentZNeighbor);
if (polyVoxZNeighbor->_volData->getEnclosingRegion() == _volData->getEnclosingRegion()) { if (polyVoxZNeighbor->getVoxelVolumeSize() == _voxelVolumeSize) {
for (int x = 0; x < _volData->getWidth(); x++) { for (int x = 0; x < _volData->getWidth(); x++) {
for (int y = 0; y < _volData->getHeight(); y++) { 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); _volData->setVoxelAt(x, y, _volData->getDepth() - 1, neighborValue);
} }
} }
@ -951,12 +979,17 @@ void RenderablePolyVoxEntityItem::getMeshAsync() {
model::MeshPointer mesh(new model::Mesh()); model::MeshPointer mesh(new model::Mesh());
cacheNeighbors(); cacheNeighbors();
copyUpperEdgesFromNeighbors();
// A mesh object to hold the result of surface extraction // A mesh object to hold the result of surface extraction
PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal> polyVoxMesh; PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal> polyVoxMesh;
_volDataLock.lockForRead(); _volDataLock.lockForRead();
if (!_volData) {
_volDataLock.unlock();
return;
}
copyUpperEdgesFromNeighbors();
switch (_voxelSurfaceStyle) { switch (_voxelSurfaceStyle) {
case PolyVoxEntityItem::SURFACE_EDGED_MARCHING_CUBES: { case PolyVoxEntityItem::SURFACE_EDGED_MARCHING_CUBES: {
PolyVox::MarchingCubesSurfaceExtractor<PolyVox::SimpleVolume<uint8_t>> surfaceExtractor PolyVox::MarchingCubesSurfaceExtractor<PolyVox::SimpleVolume<uint8_t>> surfaceExtractor

View file

@ -93,6 +93,7 @@ public:
// coords are in world-space // coords are in world-space
virtual bool setSphere(glm::vec3 center, float radius, uint8_t toValue); virtual bool setSphere(glm::vec3 center, float radius, uint8_t toValue);
virtual bool setAll(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 setXTextureURL(QString xTextureURL);
virtual void setYTextureURL(QString yTextureURL); virtual void setYTextureURL(QString yTextureURL);

View file

@ -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<glm::vec3>& points) { bool EntityScriptingInterface::setAllPoints(QUuid entityID, const QVector<glm::vec3>& points) {
EntityItemPointer entity = static_cast<EntityItemPointer>(_entityTree->findEntityByEntityItemID(entityID)); EntityItemPointer entity = static_cast<EntityItemPointer>(_entityTree->findEntityByEntityItemID(entityID));
if (!entity) { if (!entity) {

View file

@ -122,6 +122,8 @@ public slots:
Q_INVOKABLE bool setVoxelSphere(QUuid entityID, const glm::vec3& center, float radius, int value); 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 setVoxel(QUuid entityID, const glm::vec3& position, int value);
Q_INVOKABLE bool setAllVoxels(QUuid entityID, 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<glm::vec3>& points); Q_INVOKABLE bool setAllPoints(QUuid entityID, const QVector<glm::vec3>& points);
Q_INVOKABLE bool appendPoint(QUuid entityID, const glm::vec3& point); Q_INVOKABLE bool appendPoint(QUuid entityID, const glm::vec3& point);

View file

@ -12,6 +12,7 @@
#include <QByteArray> #include <QByteArray>
#include <QDebug> #include <QDebug>
#include <QWriteLocker>
#include <ByteCountCoding.h> #include <ByteCountCoding.h>
@ -62,6 +63,8 @@ PolyVoxEntityItem::PolyVoxEntityItem(const EntityItemID& entityItemID, const Ent
} }
void PolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) { void PolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) {
QWriteLocker(&this->_voxelDataLock);
assert((int)_voxelVolumeSize.x == _voxelVolumeSize.x); assert((int)_voxelVolumeSize.x == _voxelVolumeSize.x);
assert((int)_voxelVolumeSize.y == _voxelVolumeSize.y); assert((int)_voxelVolumeSize.y == _voxelVolumeSize.y);
assert((int)_voxelVolumeSize.z == _voxelVolumeSize.z); 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 PolyVoxEntityItem::getProperties() const {
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelVolumeSize, getVoxelVolumeSize); COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelVolumeSize, getVoxelVolumeSize);
@ -200,15 +209,12 @@ void PolyVoxEntityItem::debugDump() const {
} }
void PolyVoxEntityItem::setVoxelData(QByteArray voxelData) { void PolyVoxEntityItem::setVoxelData(QByteArray voxelData) {
_voxelDataLock.lockForWrite(); QWriteLocker(&this->_voxelDataLock);
_voxelData = voxelData; _voxelData = voxelData;
_voxelDataDirty = true; _voxelDataDirty = true;
_voxelDataLock.unlock();
} }
const QByteArray PolyVoxEntityItem::getVoxelData() const { const QByteArray PolyVoxEntityItem::getVoxelData() const {
_voxelDataLock.lockForRead(); QReadLocker(&this->_voxelDataLock);
auto result = _voxelData; return _voxelData;
_voxelDataLock.unlock();
return result;
} }

View file

@ -50,7 +50,7 @@ class PolyVoxEntityItem : public EntityItem {
virtual void debugDump() const; virtual void debugDump() const;
virtual void setVoxelVolumeSize(glm::vec3 voxelVolumeSize); 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 void setVoxelData(QByteArray voxelData);
virtual const QByteArray getVoxelData() const; virtual const QByteArray getVoxelData() const;
@ -85,6 +85,7 @@ class PolyVoxEntityItem : public EntityItem {
// coords are in world-space // coords are in world-space
virtual bool setSphere(glm::vec3 center, float radius, uint8_t toValue) { return false; } virtual bool setSphere(glm::vec3 center, float radius, uint8_t toValue) { return false; }
virtual bool setAll(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 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; } virtual bool setVoxel(int x, int y, int z, uint8_t toValue) { return false; }