From d86d69aeba4b72f69d2d0d3f626801bfa4ee0fb6 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 22 Oct 2015 15:36:03 -0700 Subject: [PATCH] keep track of children. use local position and orientation on the wire. --- assignment-client/src/avatars/AvatarMixer.cpp | 4 +-- .../src/entities/AssignmentParentFinder.cpp | 5 +-- interface/src/InterfaceParentFinder.cpp | 4 +-- libraries/avatars/src/AvatarData.cpp | 13 +++---- .../RenderableParticleEffectEntityItem.cpp | 3 +- .../src/RenderablePolyVoxEntityItem.cpp | 2 +- libraries/entities/src/EntityItem.cpp | 12 +++---- libraries/entities/src/EntityItem.h | 4 ++- libraries/shared/src/SpatiallyNestable.cpp | 34 ++++++++++++++++--- libraries/shared/src/SpatiallyNestable.h | 13 ++++--- 10 files changed, 61 insertions(+), 33 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 833b53b729..7124bb368c 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -155,7 +155,7 @@ void AvatarMixer::broadcastAvatarData() { ++_sumListeners; AvatarData& avatar = nodeData->getAvatar(); - glm::vec3 myPosition = avatar.getPosition(); + glm::vec3 myPosition = avatar.getLocalPosition(); // XXX should be world position // reset the internal state for correct random number distribution distribution.reset(); @@ -248,7 +248,7 @@ void AvatarMixer::broadcastAvatarData() { // The full rate distance is the distance at which EVERY update will be sent for this avatar // at twice the full rate distance, there will be a 50% chance of sending this avatar's update - glm::vec3 otherPosition = otherAvatar.getPosition(); + glm::vec3 otherPosition = otherAvatar.getLocalPosition(); // XXX should be world position float distanceToAvatar = glm::length(myPosition - otherPosition); // potentially update the max full rate distance for this frame diff --git a/assignment-client/src/entities/AssignmentParentFinder.cpp b/assignment-client/src/entities/AssignmentParentFinder.cpp index 6a66aa3f73..3e6fc2ed38 100644 --- a/assignment-client/src/entities/AssignmentParentFinder.cpp +++ b/assignment-client/src/entities/AssignmentParentFinder.cpp @@ -12,11 +12,8 @@ #include "AssignmentParentFinder.h" SpatiallyNestableWeakPointer AssignmentParentFinder::find(QUuid parentID) const { - assert(false); SpatiallyNestableWeakPointer parent; // search entities - _tree->withReadLock([&] { - parent = _tree->findEntityByEntityItemID(parentID); - }); + parent = _tree->findEntityByEntityItemID(parentID); return parent; } diff --git a/interface/src/InterfaceParentFinder.cpp b/interface/src/InterfaceParentFinder.cpp index f8604b15d3..1703ffc5d1 100644 --- a/interface/src/InterfaceParentFinder.cpp +++ b/interface/src/InterfaceParentFinder.cpp @@ -22,9 +22,7 @@ SpatiallyNestableWeakPointer InterfaceParentFinder::find(QUuid parentID) const { // search entities EntityTreeRenderer* treeRenderer = qApp->getEntities(); EntityTreePointer tree = treeRenderer->getTree(); - tree->withReadLock([&] { - parent = tree->findEntityByEntityItemID(parentID); - }); + parent = tree->findEntityByEntityItemID(parentID); if (!parent.expired()) { return parent; } diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 9a6c4b0180..fc9d9c75a7 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -174,14 +174,15 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { unsigned char* destinationBuffer = reinterpret_cast(avatarDataByteArray.data()); unsigned char* startPosition = destinationBuffer; - const glm::vec3& position = getPosition(); + const glm::vec3& position = getLocalPosition(); memcpy(destinationBuffer, &position, sizeof(position)); destinationBuffer += sizeof(position); // Body rotation - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, getBodyYaw()); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, getBodyPitch()); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, getBodyRoll()); + glm::vec3 bodyEulerAngles = glm::degrees(safeEulerAngles(getLocalOrientation())); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, bodyEulerAngles.y); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, bodyEulerAngles.x); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, bodyEulerAngles.z); // Body scale destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _targetScale); @@ -465,7 +466,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { } return maxAvailableSize; } - setPosition(position); + setLocalPosition(position); // rotation (NOTE: This needs to become a quaternion to save two bytes) float yaw, pitch, roll; @@ -483,7 +484,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { if (getBodyYaw() != yaw || getBodyPitch() != pitch || getBodyRoll() != roll) { _hasNewJointRotations = true; glm::vec3 eulerAngles(pitch, yaw, roll); - setOrientation(glm::quat(glm::radians(eulerAngles))); + setLocalOrientation(glm::quat(glm::radians(eulerAngles))); } // scale diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index a7bdffc020..a0bb582d58 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -134,7 +134,8 @@ bool RenderableParticleEffectEntityItem::addToScene(EntityItemPointer self, render::ScenePointer scene, render::PendingChanges& pendingChanges) { - auto particlePayload = std::shared_ptr(new ParticlePayload(shared_from_this())); + auto particlePayload = + std::shared_ptr(new ParticlePayload(getThisPointer())); particlePayload->setPipeline(_untexturedPipeline); _renderItemId = scene->allocateID(); auto renderData = ParticlePayload::Pointer(particlePayload); diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index fd5a9a6b4a..3ce3717dfb 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -547,7 +547,7 @@ bool RenderablePolyVoxEntityItem::addToScene(EntityItemPointer self, render::PendingChanges& pendingChanges) { _myItem = scene->allocateID(); - auto renderItem = std::make_shared(shared_from_this()); + auto renderItem = std::make_shared(getThisPointer()); auto renderData = PolyVoxPayload::Pointer(renderItem); auto renderPayload = std::make_shared(renderData); diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index c3c0204aee..f8e191cde1 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -242,7 +242,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet // PROP_CUSTOM_PROPERTIES_INCLUDED, APPEND_ENTITY_PROPERTY(PROP_SIMULATION_OWNER, _simulationOwner.toByteArray()); - APPEND_ENTITY_PROPERTY(PROP_POSITION, getPosition()); + APPEND_ENTITY_PROPERTY(PROP_POSITION, getLocalPosition()); APPEND_ENTITY_PROPERTY(PROP_ROTATION, getRotation()); APPEND_ENTITY_PROPERTY(PROP_VELOCITY, getVelocity()); APPEND_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, getAngularVelocity()); @@ -1038,7 +1038,7 @@ EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProper properties._type = getType(); COPY_ENTITY_PROPERTY_TO_PROPERTIES(simulationOwner, getSimulationOwner); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(position, getPosition); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(position, getLocalPosition); COPY_ENTITY_PROPERTY_TO_PROPERTIES(dimensions, getDimensions); // NOTE: radius is obsolete COPY_ENTITY_PROPERTY_TO_PROPERTIES(rotation, getRotation); COPY_ENTITY_PROPERTY_TO_PROPERTIES(density, getDensity); @@ -1078,7 +1078,7 @@ EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProper void EntityItem::getAllTerseUpdateProperties(EntityItemProperties& properties) const { // a TerseUpdate includes the transform and its derivatives - properties._position = getPosition(); + properties._position = getLocalPosition(); properties._velocity = _velocity; properties._rotation = getRotation(); properties._angularVelocity = _angularVelocity; @@ -1313,10 +1313,10 @@ void EntityItem::updatePosition(const glm::vec3& value) { if (shouldSuppressLocationEdits()) { return; } - auto delta = glm::distance(getPosition(), value); + auto delta = glm::distance(getLocalPosition(), value); if (delta > IGNORE_POSITION_DELTA) { _dirtyFlags |= Simulation::DIRTY_POSITION; - setPosition(value); + setLocalPosition(value); if (delta > ACTIVATION_POSITION_DELTA) { _dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION; } @@ -1685,7 +1685,7 @@ void EntityItem::deserializeActionsInternal() { action->locallyAddedButNotYetReceived = false; } else { auto actionFactory = DependencyManager::get(); - EntityItemPointer entity = shared_from_this(); + EntityItemPointer entity = getThisPointer(); EntityActionPointer action = actionFactory->factoryBA(entity, serializedAction); if (action) { entity->addActionInternal(simulation, action); diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 79fe438c39..7d6de20a5c 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -75,7 +75,7 @@ const float ACTIVATION_ANGULAR_VELOCITY_DELTA = 0.03f; /// EntityItem class this is the base class for all entity types. It handles the basic properties and functionality available /// to all other entity types. In particular: postion, size, rotation, age, lifetime, velocity, gravity. You can not instantiate /// one directly, instead you must only construct one of it's derived classes with additional features. -class EntityItem : public std::enable_shared_from_this, public SpatiallyNestable, public ReadWriteLockable { +class EntityItem : public SpatiallyNestable, public ReadWriteLockable { // These two classes manage lists of EntityItem pointers and must be able to cleanup pointers when an EntityItem is deleted. // To make the cleanup robust each EntityItem has backpointers to its manager classes (which are only ever set/cleared by // the managers themselves, hence they are fiends) whose NULL status can be used to determine which managers still need to @@ -89,6 +89,8 @@ public: EntityItem(const EntityItemID& entityItemID); virtual ~EntityItem(); + inline EntityItemPointer getThisPointer() { return std::static_pointer_cast(shared_from_this()); } + EntityItemID getEntityItemID() const { return EntityItemID(_id); } // methods for getting/setting all properties of an entity diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 870c96a784..b3723cf3b7 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -34,19 +34,43 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { if (parent && parent->getID() == _parentID) { // parent pointer is up-to-date + if (!_parentKnowsMe) { + parent->beParentOfChild(shared_from_this()); + _parentKnowsMe = true; + } return parent; } - if (parent && _parentID.isNull()) { - // we have a parent pointer but our _parentID is null + if (parent) { + // we have a parent pointer but our _parentID doesn't indicate this parent. + parent->forgetChild(shared_from_this()); + _parentKnowsMe = false; _parent.reset(); - return nullptr; } // we have a _parentID but no parent pointer, or our parent pointer is to the wrong thing QSharedPointer parentFinder = DependencyManager::get(); - _parent = parentFinder->find(_parentID); - return _parent.lock(); + _parent = parentFinder->find(_parentID); + parent = _parent.lock(); + if (parent) { + parent->beParentOfChild(shared_from_this()); + _parentKnowsMe = true; + } + return parent; +} + +void SpatiallyNestable::beParentOfChild(SpatiallyNestableConstPointer newChild) const { + _children[newChild->getID()] = newChild; +} + +void SpatiallyNestable::forgetChild(SpatiallyNestableConstPointer newChild) const { + _children.remove(newChild->getID()); +} + + +void SpatiallyNestable::setParentID(const QUuid& parentID) { + _parentID = parentID; + _parentKnowsMe = false; } const glm::vec3& SpatiallyNestable::getPosition() const { diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 930b096450..7ba5493340 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -20,9 +20,11 @@ class SpatiallyNestable; using SpatiallyNestableWeakPointer = std::weak_ptr; +using SpatiallyNestableWeakConstPointer = std::weak_ptr; using SpatiallyNestablePointer = std::shared_ptr; +using SpatiallyNestableConstPointer = std::shared_ptr; -class SpatiallyNestable { +class SpatiallyNestable : public std::enable_shared_from_this { public: SpatiallyNestable() : _transform() { } // XXX get rid of this one? @@ -33,7 +35,7 @@ public: virtual void setID(const QUuid& id) { _id = id; } virtual const QUuid& getParentID() const { return _parentID; } - virtual void setParentID(const QUuid& parentID) { _parentID = parentID; } + virtual void setParentID(const QUuid& parentID); virtual quint16 getParentJointIndex() const { return _parentJointIndex; } virtual void setParentJointIndex(quint16 parentJointIndex) { _parentJointIndex = parentJointIndex; } @@ -71,9 +73,11 @@ protected: QUuid _parentID; // what is this thing's transform relative to? quint16 _parentJointIndex; // which joint of the parent is this relative to? SpatiallyNestablePointer getParentPointer() const; - mutable SpatiallyNestableWeakPointer _parent; - QVector _children; + + virtual void beParentOfChild(SpatiallyNestableConstPointer newChild) const; + virtual void forgetChild(SpatiallyNestableConstPointer newChild) const; + mutable QHash _children; private: Transform _transform; // this is to be combined with parent's world-transform to produce this' world-transform. @@ -82,6 +86,7 @@ private: mutable glm::vec3 _absolutePositionCache; mutable glm::quat _absoluteRotationCache; mutable Transform _worldTransformCache; + mutable bool _parentKnowsMe = false; };