mirror of
https://github.com/overte-org/overte.git
synced 2025-04-16 11:28:49 +02:00
have functions that change polyvox voxes return true if they changed anything, else false. added voxelCoordsToWorldCoords and worldCoordsToVoxelCoords
This commit is contained in:
parent
09a9deabdb
commit
5ecdbaa19d
6 changed files with 128 additions and 60 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue