diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 1d58527427..efe284651a 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -1312,7 +1312,7 @@ void RenderablePolyVoxEntityItem::setMesh(model::MeshPointer mesh) { } _mesh = mesh; _meshDirty = true; - _meshInitialized = true; + _meshReady = true; neighborsNeedUpdate = _neighborsNeedUpdate; _neighborsNeedUpdate = false; }); @@ -1324,7 +1324,7 @@ void RenderablePolyVoxEntityItem::setMesh(model::MeshPointer mesh) { void RenderablePolyVoxEntityItem::computeShapeInfoWorker() { // this creates a collision-shape for the physics engine. The shape comes from // _volData for cubic extractors and from _mesh for marching-cube extractors - if (!_meshInitialized) { + if (!_meshReady) { return; } @@ -1601,15 +1601,22 @@ bool RenderablePolyVoxEntityItem::getMeshAsScriptValue(QScriptEngine *engine, QS MeshProxy* meshProxy = nullptr; glm::mat4 transform = voxelToLocalMatrix(); withReadLock([&] { - if (_meshInitialized) { + gpu::BufferView::Index numVertices = (gpu::BufferView::Index)_mesh->getNumVertices(); + if (!_meshReady) { + // we aren't ready to return a mesh. the caller will have to try again later. + success = false; + } else if (numVertices == 0) { + // we are ready, but there are no triangles in the mesh. + success = true; + } else { success = true; // the mesh will be in voxel-space. transform it into object-space meshProxy = new MeshProxy( _mesh->map([=](glm::vec3 position){ return glm::vec3(transform * glm::vec4(position, 1.0f)); }, [=](glm::vec3 normal){ return glm::vec3(transform * glm::vec4(normal, 0.0f)); }, - [](uint32_t index){ return index; })); + [&](uint32_t index){ return index; })); + result = meshToScriptValue(engine, meshProxy); } }); - result = meshToScriptValue(engine, meshProxy); return success; } diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index cf4672f068..e6467be987 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -142,7 +142,7 @@ public: uint8_t getVoxelInternal(int x, int y, int z) const; bool setVoxelInternal(int x, int y, int z, uint8_t toValue); - void setVolDataDirty() { withWriteLock([&] { _volDataDirty = true; }); } + void setVolDataDirty() { withWriteLock([&] { _volDataDirty = true; _meshReady = false; }); } // Transparent polyvox didn't seem to be working so disable for now bool isTransparent() override { return false; } @@ -157,7 +157,7 @@ private: model::MeshPointer _mesh; gpu::Stream::FormatPointer _vertexFormat; bool _meshDirty { true }; // does collision-shape need to be recomputed? - bool _meshInitialized { false }; + bool _meshReady { false }; NetworkTexturePointer _xTexture; NetworkTexturePointer _yTexture; diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 7ab0c3f7d9..88cc527164 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -934,11 +934,7 @@ void EntityScriptingInterface::voxelsToMesh(QUuid entityID, QScriptValue callbac QScriptValue mesh { false }; polyVoxWorker(entityID, [&](PolyVoxEntityItem& polyVoxEntity) mutable { - if (polyVoxEntity.getOnCount() == 0) { - success = true; - } else { - success = polyVoxEntity.getMeshAsScriptValue(callback.engine(), mesh); - } + success = polyVoxEntity.getMeshAsScriptValue(callback.engine(), mesh); return true; }); @@ -1578,3 +1574,20 @@ glm::mat4 EntityScriptingInterface::getEntityTransform(const QUuid& entityID) { } return result; } + +glm::mat4 EntityScriptingInterface::getEntityLocalTransform(const QUuid& entityID) { + glm::mat4 result; + if (_entityTree) { + _entityTree->withReadLock([&] { + EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(entityID)); + if (entity) { + glm::mat4 translation = glm::translate(entity->getLocalPosition()); + glm::mat4 rotation = glm::mat4_cast(entity->getLocalOrientation()); + glm::mat4 registration = glm::translate(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - + entity->getRegistrationPoint()); + result = translation * rotation * registration; + } + }); + } + return result; +} diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index fa727aaa7a..71758ba53f 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -304,6 +304,16 @@ public slots: */ Q_INVOKABLE glm::mat4 getEntityTransform(const QUuid& entityID); + + /**jsdoc + * Returns object to world transform, excluding scale + * + * @function Entities.getEntityLocalTransform + * @param {EntityID} entityID The ID of the entity whose local transform is to be returned + * @return {Mat4} Entity's object to parent transform, excluding scale + */ + Q_INVOKABLE glm::mat4 getEntityLocalTransform(const QUuid& entityID); + signals: void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); diff --git a/libraries/model/src/model/Geometry.cpp b/libraries/model/src/model/Geometry.cpp index 04b0db92d3..341015816e 100755 --- a/libraries/model/src/model/Geometry.cpp +++ b/libraries/model/src/model/Geometry.cpp @@ -228,7 +228,7 @@ void Mesh::forEach(std::function vertexFunc, // normal data const gpu::BufferView& normalsBufferView = getAttributeBuffer(attributeTypeNormal); - gpu::BufferView::Index numNormals = (gpu::BufferView::Index) normalsBufferView.getNumElements(); + gpu::BufferView::Index numNormals = (gpu::BufferView::Index)normalsBufferView.getNumElements(); for (gpu::BufferView::Index i = 0; i < numNormals; i ++) { normalFunc(normalsBufferView.get(i)); }