have functions that change polyvox voxes return true if they changed anything, else false. added voxelCoordsToWorldCoords and worldCoordsToVoxelCoords

This commit is contained in:
Seth Alves 2015-08-15 15:18:25 -07:00
parent 09a9deabdb
commit 5ecdbaa19d
6 changed files with 128 additions and 60 deletions

View file

@ -7,10 +7,15 @@ function attemptVoxelChange(intersection) {
var success = false;
for (var i = 0; i < ids.length; i++) {
var id = ids[i];
// var voxelCoords = Entities.worldCoordsToVoxelCoords(id, intersection.intersection);
if (controlHeld) {
// hold control to erase a sphere
if (Entities.setVoxelSphere(id, intersection.intersection, 1.0, 0)) {
success = true;
for (var r = 1.0; r < 17.0; r++) {
if (Entities.setVoxelSphere(id, intersection.intersection, r, 0)) {
success = true;
break;
}
}
} else if (shiftHeld) {
// hold shift to set all voxels to 255
@ -19,8 +24,11 @@ function attemptVoxelChange(intersection) {
}
} else {
// no modifier key means to add a sphere
if (Entities.setVoxelSphere(id, intersection.intersection, 1.0, 255)) {
success = true;
for (var r = 1.0; r < 17.0; r++) {
if (Entities.setVoxelSphere(id, intersection.intersection, r, 255)) {
success = true;
break;
}
}
}
}

View file

@ -230,78 +230,88 @@ uint8_t RenderablePolyVoxEntityItem::getVoxel(int x, int y, int z) {
return _volData->getVoxelAt(x, y, z);
}
void RenderablePolyVoxEntityItem::setVoxelInternal(int x, int y, int z, uint8_t toValue) {
bool RenderablePolyVoxEntityItem::setVoxelInternal(int x, int y, int z, uint8_t toValue) {
// set a voxel without recompressing the voxel data
assert(_volData);
bool result = false;
if (!inUserBounds(_volData, _voxelSurfaceStyle, x, y, z)) {
return;
return false;
}
updateOnCount(x, y, z, toValue);
result = updateOnCount(x, y, z, toValue);
if (_voxelSurfaceStyle == SURFACE_EDGED_CUBIC || _voxelSurfaceStyle == SURFACE_EDGED_MARCHING_CUBES) {
_volData->setVoxelAt(x + 1, y + 1, z + 1, toValue);
} else {
_volData->setVoxelAt(x, y, z, toValue);
}
return result;
}
void RenderablePolyVoxEntityItem::setVoxel(int x, int y, int z, uint8_t toValue) {
bool RenderablePolyVoxEntityItem::setVoxel(int x, int y, int z, uint8_t toValue) {
if (_locked) {
return;
return false;
}
setVoxelInternal(x, y, z, toValue);
bool result = setVoxelInternal(x, y, z, toValue);
compressVolumeData();
return result;
}
void RenderablePolyVoxEntityItem::updateOnCount(int x, int y, int z, uint8_t toValue) {
bool RenderablePolyVoxEntityItem::updateOnCount(int x, int y, int z, uint8_t toValue) {
// keep _onCount up to date
if (!inUserBounds(_volData, _voxelSurfaceStyle, x, y, z)) {
return;
return false;
}
uint8_t uVoxelValue = getVoxel(x, y, z);
if (toValue != 0) {
if (uVoxelValue == 0) {
_onCount++;
return true;
}
} else {
// toValue == 0
if (uVoxelValue != 0) {
_onCount--;
assert(_onCount >= 0);
return true;
}
}
return false;
}
void RenderablePolyVoxEntityItem::setAll(uint8_t toValue) {
bool RenderablePolyVoxEntityItem::setAll(uint8_t toValue) {
bool result = false;
if (_locked) {
return;
return false;
}
for (int z = 0; z < _voxelVolumeSize.z; z++) {
for (int y = 0; y < _voxelVolumeSize.y; y++) {
for (int x = 0; x < _voxelVolumeSize.x; x++) {
setVoxelInternal(x, y, z, toValue);
result |= setVoxelInternal(x, y, z, toValue);
}
}
}
compressVolumeData();
return result;
}
void RenderablePolyVoxEntityItem::setVoxelInVolume(glm::vec3 position, uint8_t toValue) {
bool RenderablePolyVoxEntityItem::setVoxelInVolume(glm::vec3 position, uint8_t toValue) {
if (_locked) {
return;
return false;
}
// same as setVoxel but takes a vector rather than 3 floats.
setVoxel((int)position.x, (int)position.y, (int)position.z, toValue);
return setVoxel((int)position.x, (int)position.y, (int)position.z, toValue);
}
void RenderablePolyVoxEntityItem::setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue) {
bool RenderablePolyVoxEntityItem::setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue) {
bool result = false;
if (_locked) {
return;
return false;
}
// This three-level for loop iterates over every voxel in the volume
@ -314,22 +324,22 @@ 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);
setVoxelInternal(x, y, z, toValue);
result |= setVoxelInternal(x, y, z, toValue);
}
}
}
}
compressVolumeData();
return result;
}
void RenderablePolyVoxEntityItem::setSphere(glm::vec3 centerWorldCoords, float radiusWorldCoords, uint8_t toValue) {
bool RenderablePolyVoxEntityItem::setSphere(glm::vec3 centerWorldCoords, float radiusWorldCoords, uint8_t toValue) {
// glm::vec3 centerVoxelCoords = worldToVoxelCoordinates(centerWorldCoords);
glm::vec4 centerVoxelCoords = worldToVoxelMatrix() * glm::vec4(centerWorldCoords, 1.0f);
glm::vec3 scale = getDimensions() / _voxelVolumeSize; // meters / voxel-units
float scaleY = scale.y;
float radiusVoxelCoords = radiusWorldCoords / scaleY;
setSphereInVolume(glm::vec3(centerVoxelCoords), radiusVoxelCoords, toValue);
return setSphereInVolume(glm::vec3(centerVoxelCoords), radiusVoxelCoords, toValue);
}
class RaycastFunctor
@ -508,7 +518,6 @@ void RenderablePolyVoxEntityItem::decompressVolumeData() {
for (int y = 0; y < voxelYSize; y++) {
for (int x = 0; x < voxelXSize; x++) {
int uncompressedIndex = (z * voxelYSize * voxelXSize) + (y * voxelZSize) + x;
updateOnCount(x, y, z, uncompressedData[uncompressedIndex]);
setVoxelInternal(x, y, z, uncompressedData[uncompressedIndex]);
}
}
@ -845,3 +854,11 @@ namespace render {
}
}
}
glm::vec3 RenderablePolyVoxEntityItem::voxelCoordsToWorldCoords(glm::vec3 voxelCoords) {
return glm::vec3(voxelToWorldMatrix() * glm::vec4(voxelCoords, 1.0f));
}
glm::vec3 RenderablePolyVoxEntityItem::worldCoordsToVoxelCoords(glm::vec3 worldCoords) {
return glm::vec3(worldToVoxelMatrix() * glm::vec4(worldCoords, 1.0f));
}

View file

@ -54,9 +54,9 @@ public:
}
virtual uint8_t getVoxel(int x, int y, int z);
virtual void setVoxel(int x, int y, int z, uint8_t toValue);
virtual bool setVoxel(int x, int y, int z, uint8_t toValue);
void updateOnCount(int x, int y, int z, uint8_t new_value);
bool updateOnCount(int x, int y, int z, uint8_t new_value);
void render(RenderArgs* args);
virtual bool supportsDetailedRayIntersection() const { return true; }
@ -78,16 +78,16 @@ public:
virtual bool isReadyToComputeShape();
virtual void computeShapeInfo(ShapeInfo& info);
virtual glm::vec3 voxelCoordsToWorldCoords(glm::vec3 voxelCoords);
virtual glm::vec3 worldCoordsToVoxelCoords(glm::vec3 worldCoords);
// coords are in voxel-volume space
virtual void setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue);
virtual bool setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue);
virtual bool setVoxelInVolume(glm::vec3 position, uint8_t toValue);
// coords are in world-space
virtual void setSphere(glm::vec3 center, float radius, uint8_t toValue);
virtual void setAll(uint8_t toValue);
virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue);
virtual bool setSphere(glm::vec3 center, float radius, uint8_t toValue);
virtual bool setAll(uint8_t toValue);
virtual void setXTextureURL(QString xTextureURL);
virtual void setYTextureURL(QString yTextureURL);
@ -107,7 +107,7 @@ private:
// The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions
// may not match _voxelVolumeSize.
void setVoxelInternal(int x, int y, int z, uint8_t toValue);
bool setVoxelInternal(int x, int y, int z, uint8_t toValue);
void compressVolumeData();
void decompressVolumeData();

View file

@ -415,7 +415,7 @@ void RayToEntityIntersectionResultFromScriptValue(const QScriptValue& object, Ra
}
bool EntityScriptingInterface::setVoxels(QUuid entityID,
std::function<void(PolyVoxEntityItem&)> actor) {
std::function<bool(PolyVoxEntityItem&)> actor) {
if (!_entityTree) {
return false;
}
@ -435,7 +435,7 @@ bool EntityScriptingInterface::setVoxels(QUuid entityID,
auto polyVoxEntity = std::dynamic_pointer_cast<PolyVoxEntityItem>(entity);
_entityTree->lockForWrite();
actor(*polyVoxEntity);
bool result = actor(*polyVoxEntity);
entity->setLastEdited(now);
entity->setLastBroadcast(now);
_entityTree->unlock();
@ -448,42 +448,41 @@ bool EntityScriptingInterface::setVoxels(QUuid entityID,
properties.setLastEdited(now);
queueEntityMessage(PacketType::EntityEdit, entityID, properties);
return true;
return result;
}
bool EntityScriptingInterface::setPoints(QUuid entityID, std::function<bool(LineEntityItem&)> actor) {
if (!_entityTree) {
return false;
}
EntityItemPointer entity = static_cast<EntityItemPointer>(_entityTree->findEntityByEntityItemID(entityID));
if (!entity) {
qCDebug(entities) << "EntityScriptingInterface::setPoints no entity with ID" << entityID;
}
EntityTypes::EntityType entityType = entity->getType();
if (entityType != EntityTypes::Line) {
return false;
}
auto now = usecTimestampNow();
auto lineEntity = std::static_pointer_cast<LineEntityItem>(entity);
_entityTree->lockForWrite();
bool success = actor(*lineEntity);
entity->setLastEdited(now);
entity->setLastBroadcast(now);
_entityTree->unlock();
_entityTree->lockForRead();
EntityItemProperties properties = entity->getProperties();
_entityTree->unlock();
properties.setLinePointsDirty();
properties.setLastEdited(now);
queueEntityMessage(PacketType::EntityEdit, entityID, properties);
return success;
}
@ -491,19 +490,19 @@ bool EntityScriptingInterface::setPoints(QUuid entityID, std::function<bool(Line
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);
return 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);
return polyVoxEntity.setVoxelInVolume(position, value);
});
}
bool EntityScriptingInterface::setAllVoxels(QUuid entityID, int value) {
return setVoxels(entityID, [value](PolyVoxEntityItem& polyVoxEntity) {
polyVoxEntity.setAll(value);
return polyVoxEntity.setAll(value);
});
}
@ -512,16 +511,16 @@ bool EntityScriptingInterface::setAllPoints(QUuid entityID, const QVector<glm::v
if (!entity) {
qCDebug(entities) << "EntityScriptingInterface::setPoints no entity with ID" << entityID;
}
EntityTypes::EntityType entityType = entity->getType();
if (entityType == EntityTypes::Line) {
return setPoints(entityID, [points](LineEntityItem& lineEntity) -> bool
{
return (LineEntityItem*)lineEntity.setLinePoints(points);
});
}
return false;
}
@ -658,3 +657,43 @@ QVariantMap EntityScriptingInterface::getActionArguments(const QUuid& entityID,
});
return result;
}
glm::vec3 EntityScriptingInterface::voxelCoordsToWorldCoords(const QUuid& entityID, glm::vec3 voxelCoords) {
if (!_entityTree) {
return glm::vec3(0.0f);
}
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID);
if (!entity) {
qCDebug(entities) << "EntityScriptingInterface::voxelCoordsToWorldCoords no entity with ID" << entityID;
return glm::vec3(0.0f);
}
EntityTypes::EntityType entityType = entity->getType();
if (entityType != EntityTypes::PolyVox) {
return glm::vec3(0.0f);
}
auto polyVoxEntity = std::dynamic_pointer_cast<PolyVoxEntityItem>(entity);
return polyVoxEntity->voxelCoordsToWorldCoords(voxelCoords);
}
glm::vec3 EntityScriptingInterface::worldCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 worldCoords) {
if (!_entityTree) {
return glm::vec3(0.0f);
}
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID);
if (!entity) {
qCDebug(entities) << "EntityScriptingInterface::worldCoordsToVoxelCoords no entity with ID" << entityID;
return glm::vec3(0.0f);
}
EntityTypes::EntityType entityType = entity->getType();
if (entityType != EntityTypes::PolyVox) {
return glm::vec3(0.0f);
}
auto polyVoxEntity = std::dynamic_pointer_cast<PolyVoxEntityItem>(entity);
return polyVoxEntity->worldCoordsToVoxelCoords(worldCoords);
}

View file

@ -134,6 +134,9 @@ public slots:
Q_INVOKABLE QVector<QUuid> getActionIDs(const QUuid& entityID);
Q_INVOKABLE QVariantMap getActionArguments(const QUuid& entityID, const QUuid& actionID);
Q_INVOKABLE glm::vec3 voxelCoordsToWorldCoords(const QUuid& entityID, glm::vec3 voxelCoords);
Q_INVOKABLE glm::vec3 worldCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 worldCoords);
signals:
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
@ -162,7 +165,7 @@ signals:
private:
bool actionWorker(const QUuid& entityID, std::function<bool(EntitySimulation*, EntityItemPointer)> actor);
bool setVoxels(QUuid entityID, std::function<void(PolyVoxEntityItem&)> actor);
bool setVoxels(QUuid entityID, std::function<bool(PolyVoxEntityItem&)> actor);
bool setPoints(QUuid entityID, std::function<bool(LineEntityItem&)> actor);
void queueEntityMessage(PacketType::Value packetType, EntityItemID entityID, const EntityItemProperties& properties);

View file

@ -74,17 +74,18 @@ class PolyVoxEntityItem : public EntityItem {
static const PolyVoxSurfaceStyle DEFAULT_VOXEL_SURFACE_STYLE;
// coords are in voxel-volume space
virtual void setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue) {}
virtual bool setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue) { return false; }
virtual bool setVoxelInVolume(glm::vec3 position, uint8_t toValue) { return false; }
virtual glm::vec3 voxelCoordsToWorldCoords(glm::vec3 voxelCoords) { return glm::vec3(0.0f); }
virtual glm::vec3 worldCoordsToVoxelCoords(glm::vec3 worldCoords) { return glm::vec3(0.0f); }
// coords are in world-space
virtual void setSphere(glm::vec3 center, float radius, uint8_t toValue) {}
virtual void setAll(uint8_t toValue) {}
virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue) {}
virtual bool setSphere(glm::vec3 center, float radius, uint8_t toValue) { return false; }
virtual bool setAll(uint8_t toValue) { return false; }
virtual uint8_t getVoxel(int x, int y, int z) { return 0; }
virtual void setVoxel(int x, int y, int z, uint8_t toValue) {}
virtual bool setVoxel(int x, int y, int z, uint8_t toValue) { return false; }
static QByteArray makeEmptyVoxelData(quint16 voxelXSize = 16, quint16 voxelYSize = 16, quint16 voxelZSize = 16);