more work on edge handling and resizing

This commit is contained in:
Seth Alves 2015-06-01 13:57:28 -07:00
parent 43a1519e29
commit d1bb6473d9
5 changed files with 58 additions and 52 deletions

View file

@ -53,8 +53,9 @@ RenderablePolyVoxEntityItem::~RenderablePolyVoxEntityItem() {
delete _volData;
}
bool inBounds(const PolyVox::SimpleVolume<uint8_t>* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle surfaceStyle,
bool inUserBounds(const PolyVox::SimpleVolume<uint8_t>* 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<uint8_t>* 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<uint8_t>* vol, PolyVoxEntityItem::Poly
return false;
}
bool inBounds(const PolyVox::SimpleVolume<uint8_t>* 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<uint8_t>* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle voxelSurfaceStyle) :
RaycastFunctor(PolyVox::SimpleVolume<uint8_t>* vol) :
_result(glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)),
_vol(vol),
_voxelSurfaceStyle(voxelSurfaceStyle) {
_vol(vol) {
}
bool operator()(PolyVox::SimpleVolume<unsigned char>::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<uint8_t>* _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.

View file

@ -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.

View file

@ -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<void(PolyVoxEntityItem&)> actor) {
if (!_entityTree) {
return false;
}
@ -415,7 +415,7 @@ bool EntityScriptingInterface::setVoxelSphere(QUuid entityID, const glm::vec3& c
PolyVoxEntityItem* polyVoxEntity = static_cast<PolyVoxEntityItem*>(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<EntityItemPointer>(_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<PolyVoxEntityItem*>(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);
});
}

View file

@ -21,6 +21,7 @@
#include <Octree.h>
#include <OctreeScriptingInterface.h>
#include <RegisteredMetaTypes.h>
#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<void(PolyVoxEntityItem&)> 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;

View file

@ -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) {}