diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index a1ce826072..d08e677c48 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -355,7 +355,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_START, alphaStart); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_FINISH, alphaFinish); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ADDITIVE_BLENDING, additiveBlending); - + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_POSITION, localPosition); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ROTATION, localrotation); } // Models only @@ -473,6 +474,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_ID, parentID); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_JOINT_INDEX, parentJointIndex); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_POSITION, localPosition); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ROTATION, localRotation); + // FIXME - I don't think these properties are supported any more //COPY_PROPERTY_TO_QSCRIPTVALUE(glowLevel); //COPY_PROPERTY_TO_QSCRIPTVALUE(localRenderAlpha); @@ -598,6 +602,9 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(parentID, QUuid, setParentID); COPY_PROPERTY_FROM_QSCRIPTVALUE(parentJointIndex, quint16, setParentJointIndex); + COPY_PROPERTY_FROM_QSCRIPTVALUE(localPosition, glmVec3, setLocalPosition); + COPY_PROPERTY_FROM_QSCRIPTVALUE(localRotation, glmQuat, setLocalRotation); + _lastEdited = usecTimestampNow(); } diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 981c1503fe..bcb48a1903 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -192,6 +192,10 @@ public: DEFINE_PROPERTY_REF(PROP_PARENT_ID, ParentID, parentID, QUuid, UNKNOWN_ENTITY_ID); DEFINE_PROPERTY_REF(PROP_PARENT_JOINT_INDEX, ParentJointIndex, parentJointIndex, quint16, 0); + // these are used when bouncing location data into and out of scripts + DEFINE_PROPERTY_REF_WITH_SETTER(PROP_LOCAL_POSITION, LocalPosition, localPosition, glmVec3, ENTITY_ITEM_ZERO_VEC3); + DEFINE_PROPERTY_REF(PROP_LOCAL_ROTATION, LocalRotation, localRotation, glmQuat, ENTITY_ITEM_DEFAULT_ROTATION); + static QString getBackgroundModeString(BackgroundMode mode); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index fd1e448aed..3bca911a56 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -154,6 +154,9 @@ enum EntityPropertyList { PROP_PARENT_ID, PROP_PARENT_JOINT_INDEX, + PROP_LOCAL_POSITION, // only used to convert values to and from scripts + PROP_LOCAL_ROTATION, // only used to convert values to and from scripts + //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line PROP_AFTER_LAST_ITEM, diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index bc57f2c72c..8a8150d017 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -64,6 +64,54 @@ void EntityScriptingInterface::setEntityTree(EntityTreePointer elementTree) { } } +EntityItemProperties convertLocationToScriptSemantics(EntityItemProperties entitySideProperties) { + // In EntityTree code, properties.position and properties.rotation are relative to the parent. In javascript, + // they are in world-space. The local versions are put into localPosition and localRotation and position and + // rotation are converted from local to world space. + EntityItemProperties scriptSideProperties = entitySideProperties; + scriptSideProperties.setLocalPosition(entitySideProperties.getPosition()); + scriptSideProperties.setLocalRotation(entitySideProperties.getRotation()); + + glm::vec3 worldPosition = SpatiallyNestable::localToWorld(entitySideProperties.getPosition(), + entitySideProperties.getParentID(), + entitySideProperties.getParentJointIndex()); + glm::quat worldRotation = SpatiallyNestable::localToWorld(entitySideProperties.getRotation(), + entitySideProperties.getParentID(), + entitySideProperties.getParentJointIndex()); + scriptSideProperties.setPosition(worldPosition); + scriptSideProperties.setRotation(worldRotation); + + return scriptSideProperties; +} + + +EntityItemProperties convertLocationFromScriptSemantics(EntityItemProperties scriptSideProperties) { + // convert position and rotation properties from world-space to local, unless localPosition and localRotation + // are set. If they are set, they overwrite position and rotation. + EntityItemProperties entitySideProperties = scriptSideProperties; + + if (scriptSideProperties.localPositionChanged()) { + entitySideProperties.setPosition(scriptSideProperties.getLocalPosition()); + } else if (scriptSideProperties.positionChanged()) { + glm::vec3 localPosition = SpatiallyNestable::worldToLocal(entitySideProperties.getPosition(), + entitySideProperties.getParentID(), + entitySideProperties.getParentJointIndex()); + entitySideProperties.setPosition(localPosition); + } + + if (scriptSideProperties.localRotationChanged()) { + entitySideProperties.setRotation(scriptSideProperties.getLocalRotation()); + } else if (scriptSideProperties.rotationChanged()) { + glm::quat localRotation = SpatiallyNestable::worldToLocal(entitySideProperties.getRotation(), + entitySideProperties.getParentID(), + entitySideProperties.getParentJointIndex()); + entitySideProperties.setRotation(localRotation); + } + + return entitySideProperties; +} + + QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties) { EntityItemProperties propertiesWithSimID = properties; propertiesWithSimID.setDimensionsInitialized(properties.dimensionsChanged()); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 9aa89a6a9c..707fa37192 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -455,8 +455,9 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q EntityItemProperties properties; // explicitly set the properties that changed so that they will be packed - properties.setPosition(_entity->worldToLocal(_serverPosition)); - properties.setRotation(_entity->worldToLocal(_serverRotation)); + properties.setPosition(_entity->getLocalPosition()); + properties.setRotation(_entity->getLocalOrientation()); + properties.setVelocity(_serverVelocity); properties.setAcceleration(_serverAcceleration); properties.setAngularVelocity(_serverAngularVelocity); diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index d5e2104706..4469cfd3c3 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -94,24 +94,41 @@ void SpatiallyNestable::setParentID(const QUuid parentID) { } } -glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3 position) { - Transform parentTransform = getParentTransform(); +glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3 position, QUuid parentID, int parentJointIndex) { + QSharedPointer parentFinder = DependencyManager::get(); + auto parentWP = parentFinder->find(parentID); + auto parent = parentWP.lock(); + Transform parentTransform; + if (parent) { + parentTransform = parent->getTransform(parentJointIndex); + parentTransform.setScale(1.0f); + } + + Transform positionTransform; + positionTransform.setTranslation(position); Transform myWorldTransform; - _transformLock.withReadLock([&] { - Transform::mult(myWorldTransform, parentTransform, _transform); - }); + Transform::mult(myWorldTransform, parentTransform, positionTransform); + myWorldTransform.setTranslation(position); Transform result; Transform::inverseMult(result, parentTransform, myWorldTransform); return result.getTranslation(); } -glm::quat SpatiallyNestable::worldToLocal(const glm::quat orientation) { - Transform parentTransform = getParentTransform(); +glm::quat SpatiallyNestable::worldToLocal(const glm::quat orientation, QUuid parentID, int parentJointIndex) { + QSharedPointer parentFinder = DependencyManager::get(); + auto parentWP = parentFinder->find(parentID); + auto parent = parentWP.lock(); + Transform parentTransform; + if (parent) { + parentTransform = parent->getTransform(parentJointIndex); + parentTransform.setScale(1.0f); + } + + Transform orientationTransform; + orientationTransform.setRotation(orientation); Transform myWorldTransform; - _transformLock.withReadLock([&] { - Transform::mult(myWorldTransform, parentTransform, _transform); - }); + Transform::mult(myWorldTransform, parentTransform, orientationTransform); myWorldTransform.setRotation(orientation); Transform result; Transform::inverseMult(result, parentTransform, myWorldTransform); diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 5074779d8e..bbef61b93a 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -47,8 +47,8 @@ public: virtual quint16 getParentJointIndex() const { return _parentJointIndex; } virtual void setParentJointIndex(quint16 parentJointIndex) { _parentJointIndex = parentJointIndex; } - glm::vec3 worldToLocal(const glm::vec3 position); - glm::quat worldToLocal(const glm::quat orientation); + static glm::vec3 worldToLocal(const glm::vec3 position, QUuid parentID, int parentJointIndex); + static glm::quat worldToLocal(const glm::quat orientation, QUuid parentID, int parentJointIndex); static glm::vec3 localToWorld(const glm::vec3 position, QUuid parentID, int parentJointIndex); static glm::quat localToWorld(const glm::quat orientation, QUuid parentID, int parentJointIndex);