From 7977f4640dc53c8226dc6be969775acedee7c78b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 18 Oct 2015 07:27:22 -0700 Subject: [PATCH 01/51] new class: SpatiallyNestable --- libraries/shared/src/SpatiallyNestable.cpp | 37 +++++++++++++++++ libraries/shared/src/SpatiallyNestable.h | 47 ++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 libraries/shared/src/SpatiallyNestable.cpp create mode 100644 libraries/shared/src/SpatiallyNestable.h diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp new file mode 100644 index 0000000000..5e14f398ea --- /dev/null +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -0,0 +1,37 @@ +// +// SpatiallyNestable.cpp +// libraries/shared/src/ +// +// Created by Seth Alves on 2015-10-18 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "SpatiallyNestable.h" + +SpatiallyNestable::SpatiallyNestable() : + _transform() { +} + + +const glm::vec3& SpatiallyNestable::getPosition() const { + return _transform.getTranslation(); +} + +void SpatiallyNestable::setPosition(const glm::vec3& position) { + _transform.setTranslation(position); +} + +const glm::quat& SpatiallyNestable::getOrientation() const { + return _transform.getRotation(); +} + +void SpatiallyNestable::setOrientation(const glm::quat& orientation) { + _transform.setRotation(orientation); +} + +const Transform& SpatiallyNestable::getTransform() const { + return _transform; +} diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h new file mode 100644 index 0000000000..dd57f27477 --- /dev/null +++ b/libraries/shared/src/SpatiallyNestable.h @@ -0,0 +1,47 @@ +// +// SpatiallyNestable.h +// libraries/shared/src/ +// +// Created by Seth Alves on 2015-10-18 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_SpatiallyNestable_h +#define hifi_SpatiallyNestable_h + +#include + +#include "Transform.h" + + +class SpatiallyNestable; +typedef std::weak_ptr SpatiallyNestableWeakPointer; +typedef std::shared_ptr SpatiallyNestablePointer; + +class SpatiallyNestable { + +public: + SpatiallyNestable(); + virtual ~SpatiallyNestable() { } + + virtual const glm::vec3& getPosition() const; + virtual void setPosition(const glm::vec3& position); + virtual const glm::quat& getOrientation() const; + virtual void setOrientation(const glm::quat& orientation); + virtual const Transform& getTransform() const; + +protected: + Transform _transform; + + QUuid _parentID; // what is this thing's transform relative to? + int _parentJointIndex; // which joint of the parent is this relative to? + + SpatiallyNestableWeakPointer _parent; + QVector _children; +}; + + +#endif // hifi_SpatiallyNestable_h From 275e77d29e2a258eed2ea286398107bb983ed660 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 18 Oct 2015 07:51:00 -0700 Subject: [PATCH 02/51] remove old-style avatar referentials --- interface/src/Menu.cpp | 6 +- interface/src/avatar/Avatar.cpp | 28 ---- interface/src/avatar/ModelReferential.cpp | 192 ---------------------- interface/src/avatar/ModelReferential.h | 48 ------ interface/src/avatar/MyAvatar.cpp | 31 ---- interface/src/avatar/MyAvatar.h | 4 - libraries/avatars/src/AvatarData.cpp | 79 +++------ libraries/avatars/src/AvatarData.h | 10 +- libraries/avatars/src/Referential.cpp | 109 ------------ libraries/avatars/src/Referential.h | 73 -------- libraries/entities/src/EntityItem.cpp | 12 -- libraries/entities/src/EntityItem.h | 33 +--- 12 files changed, 31 insertions(+), 594 deletions(-) delete mode 100644 interface/src/avatar/ModelReferential.cpp delete mode 100644 interface/src/avatar/ModelReferential.h delete mode 100644 libraries/avatars/src/Referential.cpp delete mode 100644 libraries/avatars/src/Referential.h diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 008694717f..c6f5bace3a 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -369,9 +369,9 @@ Menu::Menu() { auto& atpMigrator = ATPAssetMigrator::getInstance(); atpMigrator.setDialogParent(this); - QAction* assetMigration = addActionToQMenuAndActionHash(assetDeveloperMenu, MenuOption::AssetMigration, - 0, &atpMigrator, - SLOT(loadEntityServerFile())); + /*QAction* assetMigration =*/ addActionToQMenuAndActionHash(assetDeveloperMenu, MenuOption::AssetMigration, + 0, &atpMigrator, + SLOT(loadEntityServerFile())); MenuWrapper* avatarDebugMenu = developerMenu->addMenu("Avatar"); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 9f4e7ee3cf..432149d907 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -38,7 +38,6 @@ #include "Hand.h" #include "Head.h" #include "Menu.h" -#include "ModelReferential.h" #include "Physics.h" #include "Recorder.h" #include "Util.h" @@ -150,30 +149,6 @@ float Avatar::getLODDistance() const { void Avatar::simulate(float deltaTime) { PerformanceTimer perfTimer("simulate"); - // update the avatar's position according to its referential - if (_referential) { - if (_referential->hasExtraData()) { - EntityTreePointer tree = qApp->getEntities()->getTree(); - switch (_referential->type()) { - case Referential::MODEL: - _referential = new ModelReferential(_referential, - tree, - this); - break; - case Referential::JOINT: - _referential = new JointReferential(_referential, - tree, - this); - break; - default: - qCDebug(interfaceapp) << "[WARNING] Avatar::simulate(): Unknown referential type."; - break; - } - } - - _referential->update(); - } - if (_scale != _targetScale) { setScale(_targetScale); } @@ -329,9 +304,6 @@ void Avatar::removeFromScene(AvatarSharedPointer self, std::shared_ptrupdate(); - } auto& batch = *renderArgs->_batch; diff --git a/interface/src/avatar/ModelReferential.cpp b/interface/src/avatar/ModelReferential.cpp deleted file mode 100644 index 18c5e36e7a..0000000000 --- a/interface/src/avatar/ModelReferential.cpp +++ /dev/null @@ -1,192 +0,0 @@ -// -// ModelReferential.cpp -// -// -// Created by Clement on 7/30/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include -#include -#include - -#include "InterfaceLogging.h" -#include "ModelReferential.h" - -ModelReferential::ModelReferential(Referential* referential, EntityTreePointer tree, AvatarData* avatar) : - Referential(MODEL, avatar), - _tree(tree) -{ - _translation = referential->getTranslation(); - _rotation = referential->getRotation(); - unpackExtraData(reinterpret_cast(referential->getExtraData().data()), - referential->getExtraData().size()); - - if (!isValid()) { - qCDebug(interfaceapp) << "ModelReferential::copyConstructor(): Not Valid"; - return; - } - - EntityItemPointer item = _tree->findEntityByID(_entityID); - if (item != NULL) { - _lastRefDimension = item->getDimensions(); - _refRotation = item->getRotation(); - _refPosition = item->getPosition(); - update(); - } -} - -ModelReferential::ModelReferential(const QUuid& entityID, EntityTreePointer tree, AvatarData* avatar) : - Referential(MODEL, avatar), - _entityID(entityID), - _tree(tree) -{ - EntityItemPointer item = _tree->findEntityByID(_entityID); - if (!isValid() || item == NULL) { - qCDebug(interfaceapp) << "ModelReferential::constructor(): Not Valid"; - _isValid = false; - return; - } - - _lastRefDimension = item->getDimensions(); - _refRotation = item->getRotation(); - _refPosition = item->getPosition(); - - glm::quat refInvRot = glm::inverse(_refRotation); - _rotation = refInvRot * _avatar->getOrientation(); - _translation = refInvRot * (avatar->getPosition() - _refPosition); -} - -void ModelReferential::update() { - EntityItemPointer item = _tree->findEntityByID(_entityID); - if (!isValid() || item == NULL || _avatar == NULL) { - return; - } - - bool somethingChanged = false; - if (item->getDimensions() != _lastRefDimension) { - glm::vec3 oldDimension = _lastRefDimension; - _lastRefDimension = item->getDimensions(); - _translation *= _lastRefDimension / oldDimension; - somethingChanged = true; - } - if (item->getRotation() != _refRotation) { - _refRotation = item->getRotation(); - _avatar->setOrientation(_refRotation * _rotation, true); - somethingChanged = true; - } - if (item->getPosition() != _refPosition || somethingChanged) { - _refPosition = item->getPosition(); - _avatar->setPosition(_refPosition + _refRotation * _translation, true); - } -} - -int ModelReferential::packExtraData(unsigned char* destinationBuffer) const { - QByteArray encodedEntityID = _entityID.toRfc4122(); - memcpy(destinationBuffer, encodedEntityID.constData(), encodedEntityID.size()); - return encodedEntityID.size(); -} - -int ModelReferential::unpackExtraData(const unsigned char *sourceBuffer, int size) { - QByteArray encodedEntityID((const char*)sourceBuffer, NUM_BYTES_RFC4122_UUID); - _entityID = QUuid::fromRfc4122(encodedEntityID); - return NUM_BYTES_RFC4122_UUID; -} - -JointReferential::JointReferential(Referential* referential, EntityTreePointer tree, AvatarData* avatar) : - ModelReferential(referential, tree, avatar) -{ - _type = JOINT; - if (!isValid()) { - qCDebug(interfaceapp) << "JointReferential::copyConstructor(): Not Valid"; - return; - } - - EntityItemPointer item = _tree->findEntityByID(_entityID); - const Model* model = getModel(item); - if (isValid() && model != NULL && _jointIndex < (uint32_t)(model->getJointStateCount())) { - _lastRefDimension = item->getDimensions(); - model->getJointRotationInWorldFrame(_jointIndex, _refRotation); - model->getJointPositionInWorldFrame(_jointIndex, _refPosition); - } - update(); -} - -JointReferential::JointReferential(uint32_t jointIndex, const QUuid& entityID, EntityTreePointer tree, AvatarData* avatar) : - ModelReferential(entityID, tree, avatar), - _jointIndex(jointIndex) -{ - _type = JOINT; - EntityItemPointer item = _tree->findEntityByID(_entityID); - const Model* model = getModel(item); - if (!isValid() || model == NULL || _jointIndex >= (uint32_t)(model->getJointStateCount())) { - qCDebug(interfaceapp) << "JointReferential::constructor(): Not Valid"; - _isValid = false; - return; - } - - _lastRefDimension = item->getDimensions(); - model->getJointRotationInWorldFrame(_jointIndex, _refRotation); - model->getJointPositionInWorldFrame(_jointIndex, _refPosition); - - glm::quat refInvRot = glm::inverse(_refRotation); - _rotation = refInvRot * _avatar->getOrientation(); - // BUG! _refPosition is in domain units, but avatar is in meters - _translation = refInvRot * (avatar->getPosition() - _refPosition); -} - -void JointReferential::update() { - EntityItemPointer item = _tree->findEntityByID(_entityID); - const Model* model = getModel(item); - if (!isValid() || model == NULL || _jointIndex >= (uint32_t)(model->getJointStateCount())) { - return; - } - - bool somethingChanged = false; - if (item->getDimensions() != _lastRefDimension) { - glm::vec3 oldDimension = _lastRefDimension; - _lastRefDimension = item->getDimensions(); - _translation *= _lastRefDimension / oldDimension; - somethingChanged = true; - } - if (item->getRotation() != _refRotation) { - model->getJointRotationInWorldFrame(_jointIndex, _refRotation); - _avatar->setOrientation(_refRotation * _rotation, true); - somethingChanged = true; - } - if (item->getPosition() != _refPosition || somethingChanged) { - model->getJointPositionInWorldFrame(_jointIndex, _refPosition); - _avatar->setPosition(_refPosition + _refRotation * _translation, true); - } -} - -const Model* JointReferential::getModel(EntityItemPointer item) { - EntityItemFBXService* fbxService = _tree->getFBXService(); - if (item != NULL && fbxService != NULL) { - return fbxService->getModelForEntityItem(item); - } - return NULL; -} - -int JointReferential::packExtraData(unsigned char* destinationBuffer) const { - unsigned char* startPosition = destinationBuffer; - destinationBuffer += ModelReferential::packExtraData(destinationBuffer); - - memcpy(destinationBuffer, &_jointIndex, sizeof(_jointIndex)); - destinationBuffer += sizeof(_jointIndex); - - return destinationBuffer - startPosition; -} - -int JointReferential::unpackExtraData(const unsigned char *sourceBuffer, int size) { - const unsigned char* startPosition = sourceBuffer; - sourceBuffer += ModelReferential::unpackExtraData(sourceBuffer, size); - - memcpy(&_jointIndex, sourceBuffer, sizeof(_jointIndex)); - sourceBuffer += sizeof(_jointIndex); - - return sourceBuffer - startPosition; -} diff --git a/interface/src/avatar/ModelReferential.h b/interface/src/avatar/ModelReferential.h deleted file mode 100644 index 810db4b8e5..0000000000 --- a/interface/src/avatar/ModelReferential.h +++ /dev/null @@ -1,48 +0,0 @@ -// -// ModelReferential.h -// -// -// Created by Clement on 7/30/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_ModelReferential_h -#define hifi_ModelReferential_h - -#include - -class EntityTree; -class Model; - -class ModelReferential : public Referential { -public: - ModelReferential(Referential* ref, EntityTreePointer tree, AvatarData* avatar); - ModelReferential(const QUuid& entityID, EntityTreePointer tree, AvatarData* avatar); - virtual void update(); - -protected: - virtual int packExtraData(unsigned char* destinationBuffer) const; - virtual int unpackExtraData(const unsigned char* sourceBuffer, int size); - - QUuid _entityID; - EntityTreePointer _tree; -}; - -class JointReferential : public ModelReferential { -public: - JointReferential(Referential* ref, EntityTreePointer tree, AvatarData* avatar); - JointReferential(uint32_t jointIndex, const QUuid& entityID, EntityTreePointer tree, AvatarData* avatar); - virtual void update(); - -protected: - const Model* getModel(EntityItemPointer item); - virtual int packExtraData(unsigned char* destinationBuffer) const; - virtual int unpackExtraData(const unsigned char* sourceBuffer, int size); - - uint32_t _jointIndex; -}; - -#endif // hifi_ModelReferential_h diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5920543dca..3f6a6a1e77 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -43,7 +43,6 @@ #include "AvatarManager.h" #include "Environment.h" #include "Menu.h" -#include "ModelReferential.h" #include "MyAvatar.h" #include "Physics.h" #include "Recorder.h" @@ -209,10 +208,6 @@ void MyAvatar::update(float deltaTime) { _goToPending = false; } - if (_referential) { - _referential->update(); - } - Head* head = getHead(); head->relaxLean(deltaTime); updateFromTrackers(deltaTime); @@ -540,32 +535,6 @@ void MyAvatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { } } -void MyAvatar::clearReferential() { - changeReferential(NULL); -} - -bool MyAvatar::setModelReferential(const QUuid& id) { - EntityTreePointer tree = qApp->getEntities()->getTree(); - changeReferential(new ModelReferential(id, tree, this)); - if (_referential->isValid()) { - return true; - } else { - changeReferential(NULL); - return false; - } -} - -bool MyAvatar::setJointReferential(const QUuid& id, int jointIndex) { - EntityTreePointer tree = qApp->getEntities()->getTree(); - changeReferential(new JointReferential(jointIndex, id, tree, this)); - if (!_referential->isValid()) { - return true; - } else { - changeReferential(NULL); - return false; - } -} - bool MyAvatar::isRecording() { if (!_recorder) { return false; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 7347419fee..0c3b415177 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -199,10 +199,6 @@ public slots: Q_INVOKABLE void updateMotionBehaviorFromMenu(); - void clearReferential(); - bool setModelReferential(const QUuid& id); - bool setJointReferential(const QUuid& id, int jointIndex); - bool isRecording(); qint64 recorderElapsed(); void startRecording(); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index a698c6f374..a4d506a748 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -40,7 +40,6 @@ AvatarData::AvatarData() : _sessionUUID(), _position(0.0f), _handPosition(0.0f), - _referential(NULL), _bodyYaw(-90.0f), _bodyPitch(0.0f), _bodyRoll(0.0f), @@ -68,7 +67,6 @@ AvatarData::AvatarData() : AvatarData::~AvatarData() { delete _headData; delete _handData; - delete _referential; } // We cannot have a file-level variable (const or otherwise) in the header if it uses PathUtils, because that references Application, which will not yet initialized. @@ -82,40 +80,29 @@ const QUrl& AvatarData::defaultFullAvatarModelUrl() { } const glm::vec3& AvatarData::getPosition() const { - if (_referential) { - _referential->update(); - } return _position; } -void AvatarData::setPosition(const glm::vec3 position, bool overideReferential) { - if (!_referential || overideReferential) { - _position = position; - } +void AvatarData::setPosition(const glm::vec3 position) { + _position = position; } glm::quat AvatarData::getOrientation() const { - if (_referential) { - _referential->update(); - } - return glm::quat(glm::radians(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll))); } -void AvatarData::setOrientation(const glm::quat& orientation, bool overideReferential) { - if (!_referential || overideReferential) { - glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(orientation)); - _bodyPitch = eulerAngles.x; - _bodyYaw = eulerAngles.y; - _bodyRoll = eulerAngles.z; - } +void AvatarData::setOrientation(const glm::quat& orientation) { + glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(orientation)); + _bodyPitch = eulerAngles.x; + _bodyYaw = eulerAngles.y; + _bodyRoll = eulerAngles.z; } // There are a number of possible strategies for this set of tools through endRender, below. void AvatarData::nextAttitude(glm::vec3 position, glm::quat orientation) { avatarLock.lock(); - setPosition(position, true); - setOrientation(orientation, true); + setPosition(position); + setOrientation(orientation); avatarLock.unlock(); } void AvatarData::startCapture() { @@ -145,31 +132,25 @@ void AvatarData::endRenderRun() { void AvatarData::startRender() { glm::vec3 pos = getPosition(); glm::quat rot = getOrientation(); - setPosition(_nextPosition, true); - setOrientation(_nextOrientation, true); + setPosition(_nextPosition); + setOrientation(_nextOrientation); updateAttitude(); _nextPosition = pos; _nextOrientation = rot; } void AvatarData::endRender() { - setPosition(_nextPosition, true); - setOrientation(_nextOrientation, true); + setPosition(_nextPosition); + setOrientation(_nextOrientation); updateAttitude(); _nextAllowed = true; } float AvatarData::getTargetScale() const { - if (_referential) { - _referential->update(); - } - return _targetScale; } void AvatarData::setTargetScale(float targetScale, bool overideReferential) { - if (!_referential || overideReferential) { - _targetScale = targetScale; - } + _targetScale = targetScale; } void AvatarData::setClampedTargetScale(float targetScale, bool overideReferential) { @@ -246,14 +227,14 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { setAtBit(bitItems, IS_EYE_TRACKER_CONNECTED); } // referential state - if (_referential != NULL && _referential->isValid()) { - setAtBit(bitItems, HAS_REFERENTIAL); + if (false) { + setAtBit(bitItems, HAS_REFERENTIAL); // XXX leaving this for later use } *destinationBuffer++ = bitItems; - // Add referential - if (_referential != NULL && _referential->isValid()) { - destinationBuffer += _referential->packReferential(destinationBuffer); + // XXX leaving this for later use + if (false) { + // destinationBuffer += _referential->packReferential(destinationBuffer); } // If it is connected, pack up the data @@ -572,21 +553,10 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { _headData->_isEyeTrackerConnected = oneAtBit(bitItems, IS_EYE_TRACKER_CONNECTED); bool hasReferential = oneAtBit(bitItems, HAS_REFERENTIAL); - // Referential + // XXX leaving this for later use Referential if (hasReferential) { - Referential* ref = new Referential(sourceBuffer, this); - if (_referential == NULL || - ref->version() != _referential->version()) { - changeReferential(ref); - } else { - delete ref; - } - _referential->update(); - } else if (_referential != NULL) { - changeReferential(NULL); } - if (_headData->_isFaceTrackerConnected) { float leftEyeBlink, rightEyeBlink, averageLoudness, browAudioLift; minPossibleSize += sizeof(leftEyeBlink) + sizeof(rightEyeBlink) + sizeof(averageLoudness) + sizeof(browAudioLift); @@ -779,10 +749,6 @@ int AvatarData::getReceiveRate() const { return lrint(1.0f / _averageBytesReceived.getEventDeltaAverage()); } -bool AvatarData::hasReferential() { - return _referential != NULL; -} - bool AvatarData::isPlaying() { return _player && _player->isPlaying(); } @@ -946,11 +912,6 @@ void AvatarData::stopPlaying() { } } -void AvatarData::changeReferential(Referential* ref) { - delete _referential; - _referential = ref; -} - void AvatarData::setJointData(int index, const glm::quat& rotation, const glm::vec3& translation) { if (index == -1) { return; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 3abd63bf63..8f5416e4fd 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -57,7 +57,6 @@ typedef unsigned long long quint64; #include "PathUtils.h" #include "Player.h" #include "Recorder.h" -#include "Referential.h" using AvatarSharedPointer = std::shared_ptr; using AvatarWeakPointer = std::weak_ptr; @@ -174,7 +173,7 @@ public: const QUuid& getSessionUUID() const { return _sessionUUID; } const glm::vec3& getPosition() const; - virtual void setPosition(const glm::vec3 position, bool overideReferential = false); + virtual void setPosition(const glm::vec3 position); glm::vec3 getHandPosition() const; void setHandPosition(const glm::vec3& handPosition); @@ -199,7 +198,7 @@ public: void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; } glm::quat getOrientation() const; - virtual void setOrientation(const glm::quat& orientation, bool overideReferential = false); + virtual void setOrientation(const glm::quat& orientation); void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time. void startCapture(); // start/end of the period in which the latest values are about to be captured for camera, etc. @@ -319,7 +318,6 @@ public: void setOwningAvatarMixer(const QWeakPointer& owningAvatarMixer) { _owningAvatarMixer = owningAvatarMixer; } const AABox& getLocalAABox() const { return _localAABox; } - const Referential* getReferential() const { return _referential; } int getUsecsSinceLastUpdate() const { return _averageBytesReceived.getUsecsSinceLastEvent(); } int getAverageBytesReceivedPerSecond() const; @@ -339,7 +337,6 @@ public slots: void setBillboardFromNetworkReply(); void setJointMappingsFromNetworkReply(); void setSessionUUID(const QUuid& sessionUUID) { _sessionUUID = sessionUUID; } - bool hasReferential(); bool isPlaying(); bool isPaused(); @@ -369,8 +366,6 @@ protected: glm::vec3 _position = START_LOCATION; glm::vec3 _handPosition; - Referential* _referential; - // Body rotation float _bodyYaw; // degrees float _bodyPitch; // degrees @@ -421,7 +416,6 @@ protected: /// Loads the joint indices, names from the FST file (if any) virtual void updateJointMappings(); - void changeReferential(Referential* ref); glm::vec3 _velocity; glm::vec3 _targetVelocity; diff --git a/libraries/avatars/src/Referential.cpp b/libraries/avatars/src/Referential.cpp deleted file mode 100644 index 0683580093..0000000000 --- a/libraries/avatars/src/Referential.cpp +++ /dev/null @@ -1,109 +0,0 @@ -// -// Referential.cpp -// -// -// Created by Clement on 7/30/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include - -#include "AvatarData.h" -#include "AvatarLogging.h" -#include "Referential.h" - -Referential::Referential(Type type, AvatarData* avatar) : - _type(type), - _version(0), - _isValid(true), - _avatar(avatar) -{ - if (_avatar == NULL) { - _isValid = false; - return; - } - if (_avatar->hasReferential()) { - _version = _avatar->getReferential()->version() + 1; - } -} - -Referential::Referential(const unsigned char*& sourceBuffer, AvatarData* avatar) : - _isValid(false), - _avatar(avatar) -{ - // Since we can't return how many byte have been read - // We take a reference to the pointer as argument and increment the pointer ouself. - sourceBuffer += unpackReferential(sourceBuffer); - // The actual unpacking to the right referential type happens in Avatar::simulate() - // If subclassed, make sure to add a case there to unpack the new referential type correctly -} - -Referential::~Referential() { -} - -int Referential::packReferential(unsigned char* destinationBuffer) const { - const unsigned char* startPosition = destinationBuffer; - destinationBuffer += pack(destinationBuffer); - - unsigned char* sizePosition = destinationBuffer++; // Save a spot for the extra data size - char size = packExtraData(destinationBuffer); - *sizePosition = size; // write extra data size in saved spot here - destinationBuffer += size; - return destinationBuffer - startPosition; -} - -int Referential::unpackReferential(const unsigned char* sourceBuffer) { - const unsigned char* startPosition = sourceBuffer; - sourceBuffer += unpack(sourceBuffer); - char expectedSize = *sourceBuffer++; - char bytesRead = unpackExtraData(sourceBuffer, expectedSize); - _isValid = (bytesRead == expectedSize); - if (!_isValid) { - // Will occur if the new instance unpacking is of the wrong type - qCDebug(avatars) << "[ERROR] Referential extra data overflow"; - } - sourceBuffer += expectedSize; - return sourceBuffer - startPosition; -} - -int Referential::pack(unsigned char* destinationBuffer) const { - unsigned char* startPosition = destinationBuffer; - *destinationBuffer++ = (unsigned char)_type; - memcpy(destinationBuffer, &_version, sizeof(_version)); - destinationBuffer += sizeof(_version); - - destinationBuffer += packFloatVec3ToSignedTwoByteFixed(destinationBuffer, _translation, 0); - destinationBuffer += packOrientationQuatToBytes(destinationBuffer, _rotation); - return destinationBuffer - startPosition; -} - -int Referential::unpack(const unsigned char* sourceBuffer) { - const unsigned char* startPosition = sourceBuffer; - _type = (Type)*sourceBuffer++; - if (_type < 0 || _type >= NUM_TYPES) { - _type = UNKNOWN; - } - memcpy(&_version, sourceBuffer, sizeof(_version)); - sourceBuffer += sizeof(_version); - - sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, _translation, 0); - sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, _rotation); - return sourceBuffer - startPosition; -} - -int Referential::packExtraData(unsigned char *destinationBuffer) const { - // Since we can't interpret that data, just store it in a buffer for later use. - memcpy(destinationBuffer, _extraDataBuffer.data(), _extraDataBuffer.size()); - return _extraDataBuffer.size(); -} - - -int Referential::unpackExtraData(const unsigned char* sourceBuffer, int size) { - _extraDataBuffer.clear(); - _extraDataBuffer.append(reinterpret_cast(sourceBuffer), size); - return size; -} - diff --git a/libraries/avatars/src/Referential.h b/libraries/avatars/src/Referential.h deleted file mode 100644 index 70edecda62..0000000000 --- a/libraries/avatars/src/Referential.h +++ /dev/null @@ -1,73 +0,0 @@ -// -// Referential.h -// -// -// Created by Clement on 7/30/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_Referential_h -#define hifi_Referential_h - -#include -#include - -class AvatarData; - -/// Stores and enforce the relative position of an avatar to a given referential (ie. model, joint, ...) -class Referential { -public: - enum Type { - UNKNOWN, - MODEL, - JOINT, - AVATAR, - - NUM_TYPES - }; - - Referential(const unsigned char*& sourceBuffer, AvatarData* avatar); - virtual ~Referential(); - - Type type() const { return _type; } - quint8 version() const { return _version; } - bool isValid() const { return _isValid; } - bool hasExtraData() const { return !_extraDataBuffer.isEmpty(); } - - glm::vec3 getTranslation() const { return _translation; } - glm::quat getRotation() const { return _rotation; } - QByteArray getExtraData() const { return _extraDataBuffer; } - - virtual void update() {} - int packReferential(unsigned char* destinationBuffer) const; - int unpackReferential(const unsigned char* sourceBuffer); - -protected: - Referential(Type type, AvatarData* avatar); - - // packs the base class data - int pack(unsigned char* destinationBuffer) const; - int unpack(const unsigned char* sourceBuffer); - // virtual functions that pack fthe extra data of subclasses (needs to be reimplemented in subclass) - virtual int packExtraData(unsigned char* destinationBuffer) const; - virtual int unpackExtraData(const unsigned char* sourceBuffer, int size); - - Type _type; - quint8 _version; - bool _isValid; - AvatarData* _avatar; - QByteArray _extraDataBuffer; - - glm::vec3 _refPosition; // position of object in world-frame - glm::quat _refRotation; // rotation of object in world-frame - glm::vec3 _lastRefDimension; // dimension of object when _translation was last computed - - glm::vec3 _translation; // offset of avatar in object local-frame - glm::quat _rotation; // rotation of avatar in object local-frame -}; - - -#endif // hifi_Referential_h diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 5b262b273b..d58c26e72c 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -46,7 +46,6 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) : _lastEditedFromRemoteInRemoteTime(0), _created(UNKNOWN_CREATED_TIME), _changedOnServer(0), - _transform(), _glowLevel(ENTITY_ITEM_DEFAULT_GLOW_LEVEL), _localRenderAlpha(ENTITY_ITEM_DEFAULT_LOCAL_RENDER_ALPHA), _density(ENTITY_ITEM_DEFAULT_DENSITY), @@ -1516,7 +1515,6 @@ bool EntityItem::addAction(EntitySimulation* simulation, EntityActionPointer act } bool EntityItem::addActionInternal(EntitySimulation* simulation, EntityActionPointer action) { - assertLocked(); assert(action); assert(simulation); auto actionOwnerEntity = action->getOwnerEntity().lock(); @@ -1570,7 +1568,6 @@ bool EntityItem::removeAction(EntitySimulation* simulation, const QUuid& actionI } bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulation* simulation) { - assertWriteLocked(); _previouslyDeletedActions.insert(actionID, usecTimestampNow()); if (_objectActions.contains(actionID)) { if (!simulation) { @@ -1615,7 +1612,6 @@ bool EntityItem::clearActions(EntitySimulation* simulation) { void EntityItem::deserializeActions() { - assertUnlocked(); withWriteLock([&] { deserializeActionsInternal(); }); @@ -1623,8 +1619,6 @@ void EntityItem::deserializeActions() { void EntityItem::deserializeActionsInternal() { - assertWriteLocked(); - quint64 now = usecTimestampNow(); if (!_element) { @@ -1704,7 +1698,6 @@ void EntityItem::deserializeActionsInternal() { } void EntityItem::checkWaitingToRemove(EntitySimulation* simulation) { - assertLocked(); foreach(QUuid actionID, _actionsToRemove) { removeActionInternal(actionID, simulation); } @@ -1712,14 +1705,12 @@ void EntityItem::checkWaitingToRemove(EntitySimulation* simulation) { } void EntityItem::setActionData(QByteArray actionData) { - assertUnlocked(); withWriteLock([&] { setActionDataInternal(actionData); }); } void EntityItem::setActionDataInternal(QByteArray actionData) { - assertWriteLocked(); if (_allActionsDataCache != actionData) { _allActionsDataCache = actionData; deserializeActionsInternal(); @@ -1728,8 +1719,6 @@ void EntityItem::setActionDataInternal(QByteArray actionData) { } void EntityItem::serializeActions(bool& success, QByteArray& result) const { - assertLocked(); - if (_objectActions.size() == 0) { success = true; result.clear(); @@ -1771,7 +1760,6 @@ const QByteArray EntityItem::getActionDataInternal() const { const QByteArray EntityItem::getActionData() const { QByteArray result; - assertUnlocked(); withReadLock([&] { result = getActionDataInternal(); }); diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index f438e3f28b..e85112d4ef 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "EntityItemID.h" #include "EntityItemPropertiesDefaults.h" @@ -71,31 +72,10 @@ const float ACTIVATION_ANGULAR_VELOCITY_DELTA = 0.03f; #define debugTimeOnly(T) qPrintable(QString("%1").arg(T, 16, 10)) #define debugTreeVector(V) V << "[" << V << " in meters ]" -//#if DEBUG -// #define assertLocked() assert(isLocked()) -//#else -// #define assertLocked() -//#endif -// -//#if DEBUG -// #define assertWriteLocked() assert(isWriteLocked()) -//#else -// #define assertWriteLocked() -//#endif -// -//#if DEBUG -// #define assertUnlocked() assert(isUnlocked()) -//#else -// #define assertUnlocked() -//#endif -#define assertLocked() -#define assertUnlocked() -#define assertWriteLocked() - /// 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 ReadWriteLockable { +class EntityItem : public std::enable_shared_from_this, 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 @@ -208,11 +188,11 @@ public: inline void setTransform(const Transform& transform) { _transform = transform; requiresRecalcBoxes(); } /// Position in meters (-TREE_SCALE - TREE_SCALE) - inline const glm::vec3& getPosition() const { return _transform.getTranslation(); } - inline void setPosition(const glm::vec3& value) { _transform.setTranslation(value); requiresRecalcBoxes(); } + virtual const glm::vec3& getPosition() const { return SpatiallyNestable::getPosition(); } + virtual void setPosition(const glm::vec3& value) { SpatiallyNestable::setPosition(value); requiresRecalcBoxes(); } - inline const glm::quat& getRotation() const { return _transform.getRotation(); } - inline void setRotation(const glm::quat& rotation) { _transform.setRotation(rotation); requiresRecalcBoxes(); } + virtual const glm::quat& getRotation() const { return SpatiallyNestable::getOrientation(); } + virtual void setRotation(const glm::quat& rotation) { SpatiallyNestable::setOrientation(rotation); requiresRecalcBoxes(); } inline void requiresRecalcBoxes() { _recalcAABox = true; _recalcMinAACube = true; _recalcMaxAACube = true; } @@ -428,7 +408,6 @@ protected: quint64 _created; quint64 _changedOnServer; - Transform _transform; mutable AABox _cachedAABox; mutable AACube _maxAACube; mutable AACube _minAACube; From 37923e81bbc26db526fd0fe59a7d39faffe18911 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 18 Oct 2015 08:18:10 -0700 Subject: [PATCH 03/51] make SpatiallyNestable::_transform private --- libraries/entities/src/EntityItem.cpp | 8 ++++---- libraries/entities/src/EntityItem.h | 5 ++--- libraries/shared/src/SpatiallyNestable.cpp | 12 ++++++++++++ libraries/shared/src/SpatiallyNestable.h | 18 +++++++++++++++--- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index d58c26e72c..3c3f7fd0f1 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -79,9 +79,9 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) : _simulated(false) { // explicitly set transform parts to set dirty flags used by batch rendering - _transform.setTranslation(ENTITY_ITEM_DEFAULT_POSITION); - _transform.setRotation(ENTITY_ITEM_DEFAULT_ROTATION); - _transform.setScale(ENTITY_ITEM_DEFAULT_DIMENSIONS); + setPosition(ENTITY_ITEM_DEFAULT_POSITION); + setRotation(ENTITY_ITEM_DEFAULT_ROTATION); + setScale(ENTITY_ITEM_DEFAULT_DIMENSIONS); quint64 now = usecTimestampNow(); _lastSimulated = now; _lastUpdated = now; @@ -1176,7 +1176,7 @@ void EntityItem::setDimensions(const glm::vec3& value) { if (value.x <= 0.0f || value.y <= 0.0f || value.z <= 0.0f) { return; } - _transform.setScale(value); + setScale(value); requiresRecalcBoxes(); } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index e85112d4ef..4d56b92171 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -184,8 +184,7 @@ public: const Transform getTransformToCenter() const; void setTranformToCenter(const Transform& transform); - inline const Transform& getTransform() const { return _transform; } - inline void setTransform(const Transform& transform) { _transform = transform; requiresRecalcBoxes(); } + virtual void setTransform(const Transform& transform) { SpatiallyNestable::setTransform(transform); requiresRecalcBoxes(); } /// Position in meters (-TREE_SCALE - TREE_SCALE) virtual const glm::vec3& getPosition() const { return SpatiallyNestable::getPosition(); } @@ -204,7 +203,7 @@ public: void setDescription(QString value) { _description = value; } /// Dimensions in meters (0.0 - TREE_SCALE) - inline const glm::vec3& getDimensions() const { return _transform.getScale(); } + inline const glm::vec3& getDimensions() const { return getScale(); } virtual void setDimensions(const glm::vec3& value); float getGlowLevel() const { return _glowLevel; } diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 5e14f398ea..a3e427caa8 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -35,3 +35,15 @@ void SpatiallyNestable::setOrientation(const glm::quat& orientation) { const Transform& SpatiallyNestable::getTransform() const { return _transform; } + +void SpatiallyNestable::setTransform(const Transform& transform) { + _transform = transform; +} + +const glm::vec3& SpatiallyNestable::getScale() const { + return _transform.getScale(); +} + +void SpatiallyNestable::setScale(const glm::vec3& scale) { + _transform.setScale(scale); +} diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index dd57f27477..294450a980 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -27,20 +27,32 @@ public: SpatiallyNestable(); virtual ~SpatiallyNestable() { } + // world frame + virtual const Transform& getTransform() const; + virtual void setTransform(const Transform& transform); + virtual const glm::vec3& getPosition() const; virtual void setPosition(const glm::vec3& position); + virtual const glm::quat& getOrientation() const; virtual void setOrientation(const glm::quat& orientation); - virtual const Transform& getTransform() const; + + virtual const glm::vec3& getScale() const; + virtual void setScale(const glm::vec3& scale); + + // model frame + // ... + protected: - Transform _transform; - QUuid _parentID; // what is this thing's transform relative to? int _parentJointIndex; // which joint of the parent is this relative to? SpatiallyNestableWeakPointer _parent; QVector _children; + +private: + Transform _transform; }; From a78f2a95777603a0764da4cc7bca92ba973d652c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 18 Oct 2015 09:48:46 -0700 Subject: [PATCH 04/51] have avatar make use of SpatiallyNestable --- interface/src/Application.cpp | 4 +- interface/src/avatar/Avatar.cpp | 74 +++++++++---------- interface/src/avatar/Avatar.h | 5 +- interface/src/avatar/AvatarManager.cpp | 2 +- interface/src/avatar/Hand.cpp | 2 +- interface/src/avatar/MyAvatar.cpp | 29 ++++---- interface/src/ui/ApplicationCompositor.cpp | 2 +- interface/src/ui/PreferencesDialog.cpp | 2 +- interface/src/ui/overlays/OverlaysPayload.cpp | 2 +- libraries/avatars/src/AvatarData.cpp | 70 +++++++++++------- libraries/avatars/src/AvatarData.h | 29 +++----- 11 files changed, 112 insertions(+), 109 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1b6be53876..9b5b83492c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1136,7 +1136,7 @@ void Application::paintGL() { * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)) * hmdRotation); glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getScale(), 0) + + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0) + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))) * hmdOffset); @@ -1144,7 +1144,7 @@ void Application::paintGL() { _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getScale(), 0) + + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0) + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); } diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 432149d907..92493ab23f 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -90,7 +90,6 @@ Avatar::Avatar(RigPointer rig) : _angularAcceleration(0.0f), _lastOrientation(), _leanScale(0.5f), - _scale(1.0f), _worldUpDirection(DEFAULT_UP_DIRECTION), _moving(false), _initialized(false), @@ -100,6 +99,7 @@ Avatar::Avatar(RigPointer rig) : // we may have been created in the network thread, but we live in the main thread moveToThread(qApp->thread()); + setAvatarScale(1.0f); // give the pointer to our head to inherited _headData variable from AvatarData _headData = static_cast(new Head(this)); _handData = static_cast(new Hand(this)); @@ -124,12 +124,12 @@ void Avatar::init() { glm::vec3 Avatar::getChestPosition() const { // for now, let's just assume that the "chest" is halfway between the root and the neck glm::vec3 neckPosition; - return _skeletonModel.getNeckPosition(neckPosition) ? (_position + neckPosition) * 0.5f : _position; + return _skeletonModel.getNeckPosition(neckPosition) ? (getPosition() + neckPosition) * 0.5f : getPosition(); } glm::vec3 Avatar::getNeckPosition() const { glm::vec3 neckPosition; - return _skeletonModel.getNeckPosition(neckPosition) ? neckPosition : _position; + return _skeletonModel.getNeckPosition(neckPosition) ? neckPosition : getPosition(); } @@ -143,14 +143,14 @@ AABox Avatar::getBounds() const { float Avatar::getLODDistance() const { return DependencyManager::get()->getAvatarLODDistanceMultiplier() * - glm::distance(qApp->getCamera()->getPosition(), _position) / _scale; + glm::distance(qApp->getCamera()->getPosition(), getPosition()) / getAvatarScale(); } void Avatar::simulate(float deltaTime) { PerformanceTimer perfTimer("simulate"); - if (_scale != _targetScale) { - setScale(_targetScale); + if (getAvatarScale() != _targetScale) { + setAvatarScale(_targetScale); } // update the billboard render flag @@ -165,7 +165,7 @@ void Avatar::simulate(float deltaTime) { // simple frustum check float boundingRadius = getBillboardSize(); - bool inViewFrustum = qApp->getViewFrustum()->sphereInFrustum(_position, boundingRadius) != + bool inViewFrustum = qApp->getViewFrustum()->sphereInFrustum(getPosition(), boundingRadius) != ViewFrustum::OUTSIDE; { @@ -189,11 +189,11 @@ void Avatar::simulate(float deltaTime) { } { PerformanceTimer perfTimer("head"); - glm::vec3 headPosition = _position; + glm::vec3 headPosition = getPosition(); _skeletonModel.getHeadPosition(headPosition); Head* head = getHead(); head->setPosition(headPosition); - head->setScale(_scale); + head->setScale(getAvatarScale()); head->simulate(deltaTime, false, _shouldRenderBillboard); } } @@ -226,7 +226,7 @@ bool Avatar::isLookingAtMe(AvatarSharedPointer avatar) { glm::vec3 theirLookAt = dynamic_pointer_cast(avatar)->getHead()->getLookAtPosition(); glm::vec3 myEyePosition = getHead()->getEyePosition(); - return glm::distance(theirLookAt, myEyePosition) <= (HEAD_SPHERE_RADIUS * getScale()); + return glm::distance(theirLookAt, myEyePosition) <= (HEAD_SPHERE_RADIUS * getAvatarScale()); } void Avatar::slamPosition(const glm::vec3& newPosition) { @@ -237,7 +237,7 @@ void Avatar::slamPosition(const glm::vec3& newPosition) { } void Avatar::applyPositionDelta(const glm::vec3& delta) { - _position += delta; + setPosition(getPosition() + delta); _positionDeltaAccumulator += delta; } @@ -307,7 +307,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { auto& batch = *renderArgs->_batch; - if (glm::distance(DependencyManager::get()->getMyAvatar()->getPosition(), _position) < 10.0f) { + if (glm::distance(DependencyManager::get()->getMyAvatar()->getPosition(), getPosition()) < 10.0f) { auto geometryCache = DependencyManager::get(); auto deferredLighting = DependencyManager::get(); @@ -405,7 +405,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { const float BASE_LIGHT_DISTANCE = 2.0f; const float LIGHT_EXPONENT = 1.0f; const float LIGHT_CUTOFF = glm::radians(80.0f); - float distance = BASE_LIGHT_DISTANCE * _scale; + float distance = BASE_LIGHT_DISTANCE * getAvatarScale(); glm::vec3 position = glm::mix(_skeletonModel.getTranslation(), getHead()->getFaceModel().getTranslation(), 0.9f); glm::quat orientation = getOrientation(); foreach (const AvatarManager::LocalLight& light, DependencyManager::get()->getLocalLights()) { @@ -435,7 +435,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { static const float INDICATOR_OFFSET = 0.22f; static const float INDICATOR_RADIUS = 0.03f; static const glm::vec4 LOOK_AT_INDICATOR_COLOR = { 0.8f, 0.0f, 0.0f, 0.75f }; - glm::vec3 position = glm::vec3(_position.x, getDisplayNamePosition().y + INDICATOR_OFFSET, _position.z); + glm::vec3 position = glm::vec3(getPosition().x, getDisplayNamePosition().y + INDICATOR_OFFSET, getPosition().z); Transform transform; transform.setTranslation(position); transform.postScale(INDICATOR_RADIUS); @@ -467,7 +467,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { } DependencyManager::get()->renderSolidSphereInstance(batch, - Transform(transform).postScale(eyeDiameter * _scale / 2.0f + RADIUS_INCREMENT), + Transform(transform).postScale(eyeDiameter * getAvatarScale() / 2.0f + RADIUS_INCREMENT), glm::vec4(LOOKING_AT_ME_COLOR, alpha)); position = getHead()->getRightEyePosition(); @@ -477,7 +477,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { eyeDiameter = DEFAULT_EYE_DIAMETER; } DependencyManager::get()->renderSolidSphereInstance(batch, - Transform(transform).postScale(eyeDiameter * _scale / 2.0f + RADIUS_INCREMENT), + Transform(transform).postScale(eyeDiameter * getAvatarScale() / 2.0f + RADIUS_INCREMENT), glm::vec4(LOOKING_AT_ME_COLOR, alpha)); } @@ -507,7 +507,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { Transform transform; - transform.setTranslation(_position); + transform.setTranslation(getPosition()); transform.setScale(height); transform.postScale(sphereRadius); DependencyManager::get()->renderSolidSphereInstance(batch, @@ -610,9 +610,9 @@ void Avatar::simulateAttachments(float deltaTime) { glm::quat jointRotation; if (_skeletonModel.getJointPositionInWorldFrame(jointIndex, jointPosition) && _skeletonModel.getJointCombinedRotation(jointIndex, jointRotation)) { - model->setTranslation(jointPosition + jointRotation * attachment.translation * _scale); + model->setTranslation(jointPosition + jointRotation * attachment.translation * getAvatarScale()); model->setRotation(jointRotation * attachment.rotation); - model->setScaleToFit(true, _scale * attachment.scale, true); // hack to force rescale + model->setScaleToFit(true, getAvatarScale() * attachment.scale, true); // hack to force rescale model->setSnapModelToCenter(false); // hack to force resnap model->setSnapModelToCenter(true); model->simulate(deltaTime); @@ -639,14 +639,14 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) { } // rotate about vertical to face the camera glm::quat rotation = getOrientation(); - glm::vec3 cameraVector = glm::inverse(rotation) * (qApp->getCamera()->getPosition() - _position); + glm::vec3 cameraVector = glm::inverse(rotation) * (qApp->getCamera()->getPosition() - getPosition()); rotation = rotation * glm::angleAxis(atan2f(-cameraVector.x, -cameraVector.z), glm::vec3(0.0f, 1.0f, 0.0f)); // compute the size from the billboard camera parameters and scale float size = getBillboardSize(); Transform transform; - transform.setTranslation(_position); + transform.setTranslation(getPosition()); transform.setRotation(rotation); transform.setScale(size); @@ -663,7 +663,7 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) { } float Avatar::getBillboardSize() const { - return _scale * BILLBOARD_DISTANCE * glm::tan(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f)); + return getAvatarScale() * BILLBOARD_DISTANCE * glm::tan(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f)); } #ifdef DEBUG @@ -700,7 +700,7 @@ glm::vec3 Avatar::getDisplayNamePosition() const { DEBUG_VALUE("_position =", _position); DEBUG_VALUE("billboardSize =", billboardSize); - namePosition = _position + bodyUpDirection * (billboardSize * HEAD_PROPORTION); + namePosition = getPosition() + bodyUpDirection * (billboardSize * HEAD_PROPORTION); } if (glm::any(glm::isnan(namePosition)) || glm::any(glm::isinf(namePosition))) { @@ -803,7 +803,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co } void Avatar::setSkeletonOffset(const glm::vec3& offset) { - const float MAX_OFFSET_LENGTH = _scale * 0.5f; + const float MAX_OFFSET_LENGTH = getAvatarScale() * 0.5f; float offsetLength = glm::length(offset); if (offsetLength > MAX_OFFSET_LENGTH) { _skeletonOffset = (MAX_OFFSET_LENGTH / offsetLength) * offset; @@ -816,7 +816,7 @@ glm::vec3 Avatar::getSkeletonPosition() const { // The avatar is rotated PI about the yAxis, so we have to correct for it // to get the skeleton offset contribution in the world-frame. const glm::quat FLIP = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); - return _position + getOrientation() * FLIP * _skeletonOffset; + return getPosition() + getOrientation() * FLIP * _skeletonOffset; } QVector Avatar::getJointRotations() const { @@ -941,7 +941,7 @@ void Avatar::setJointModelPositionAndOrientation(const QString& name, glm::vec3 void Avatar::scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const { //Scale a world space vector as if it was relative to the position - positionToScale = _position + _scale * (positionToScale - _position); + positionToScale = getPosition() + getAvatarScale() * (positionToScale - getPosition()); } void Avatar::setFaceModelURL(const QUrl& faceModelURL) { @@ -981,7 +981,7 @@ void Avatar::setAttachmentData(const QVector& attachmentData) { for (int i = 0; i < attachmentData.size(); i++) { _attachmentModels[i]->setURL(attachmentData.at(i).modelURL); _attachmentModels[i]->setSnapModelToCenter(true); - _attachmentModels[i]->setScaleToFit(true, _scale * _attachmentData.at(i).scale); + _attachmentModels[i]->setScaleToFit(true, getAvatarScale() * _attachmentData.at(i).scale); } } @@ -1000,12 +1000,12 @@ int Avatar::parseDataFromBuffer(const QByteArray& buffer) { } // change in position implies movement - glm::vec3 oldPosition = _position; + glm::vec3 oldPosition = getPosition(); int bytesRead = AvatarData::parseDataFromBuffer(buffer); const float MOVE_DISTANCE_THRESHOLD = 0.001f; - _moving = glm::distance(oldPosition, _position) > MOVE_DISTANCE_THRESHOLD; + _moving = glm::distance(oldPosition, getPosition()) > MOVE_DISTANCE_THRESHOLD; if (_moving && _motionState) { _motionState->addDirtyFlags(Simulation::DIRTY_POSITION); } @@ -1068,12 +1068,12 @@ void Avatar::renderJointConnectingCone(gpu::Batch& batch, glm::vec3 position1, g } } -void Avatar::setScale(float scale) { - _scale = scale; - - if (_targetScale * (1.0f - RESCALING_TOLERANCE) < _scale && - _scale < _targetScale * (1.0f + RESCALING_TOLERANCE)) { - _scale = _targetScale; +void Avatar::setAvatarScale(float scale) { + if (_targetScale * (1.0f - RESCALING_TOLERANCE) < scale && + scale < _targetScale * (1.0f + RESCALING_TOLERANCE)) { + setScale(glm::vec3(_targetScale)); + } else { + setScale(glm::vec3(scale)); } } @@ -1088,7 +1088,7 @@ float Avatar::getHeadHeight() const { // HACK: We have a really odd case when fading out for some models where this value explodes float result = extents.maximum.y - extents.minimum.y; - if (result >= 0.0f && result < 100.0f * _scale ) { + if (result >= 0.0f && result < 100.0f * getAvatarScale() ) { return result; } } @@ -1096,7 +1096,7 @@ float Avatar::getHeadHeight() const { extents = _skeletonModel.getMeshExtents(); glm::vec3 neckPosition; if (!extents.isEmpty() && extents.isValid() && _skeletonModel.getNeckPosition(neckPosition)) { - return extents.maximum.y / 2.0f - neckPosition.y + _position.y; + return extents.maximum.y / 2.0f - neckPosition.y + getPosition().y; } const float DEFAULT_HEAD_HEIGHT = 0.25f; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 9a46a145c2..2b7d27b2e3 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -103,7 +103,7 @@ public: const SkeletonModel& getSkeletonModel() const { return _skeletonModel; } const QVector& getAttachmentModels() const { return _attachmentModels; } glm::vec3 getChestPosition() const; - float getScale() const { return _scale; } + float getAvatarScale() const { return getScale().y; } const Head* getHead() const { return static_cast(_headData); } Head* getHead() { return static_cast(_headData); } Hand* getHand() { return static_cast(_handData); } @@ -207,7 +207,6 @@ protected: glm::quat _lastOrientation; float _leanScale; - float _scale; glm::vec3 _worldUpDirection; float _stringLength; bool _moving; ///< set when position is changing @@ -219,7 +218,7 @@ protected: glm::vec3 getBodyUpDirection() const { return getOrientation() * IDENTITY_UP; } glm::vec3 getBodyFrontDirection() const { return getOrientation() * IDENTITY_FRONT; } glm::quat computeRotationFromBodyToWorldUp(float proportion = 1.0f) const; - void setScale(float scale); + void setAvatarScale(float scale); void measureMotionDerivatives(float deltaTime); float getSkeletonHeight() const; diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 5f0ac435e0..f42cdc200b 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -151,7 +151,7 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { while (fadingIterator != _avatarFades.end()) { auto avatar = std::static_pointer_cast(*fadingIterator); avatar->startUpdate(); - avatar->setTargetScale(avatar->getScale() * SHRINK_RATE, true); + avatar->setTargetScale(avatar->getAvatarScale() * SHRINK_RATE, true); if (avatar->getTargetScale() < MIN_FADE_SCALE) { avatar->removeFromScene(*fadingIterator, scene, pendingChanges); fadingIterator = _avatarFades.erase(fadingIterator); diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 0eeb7222b6..a8d09aff69 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -43,7 +43,7 @@ void Hand::simulate(float deltaTime, bool isMine) { void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) { float avatarScale = 1.0f; if (_owningAvatar) { - avatarScale = _owningAvatar->getScale(); + avatarScale = _owningAvatar->getAvatarScale(); } const float alpha = 1.0f; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 3f6a6a1e77..8b9d89eeaa 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -129,11 +129,11 @@ QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) { CameraMode mode = qApp->getCamera()->getMode(); if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) { // fake the avatar position that is sent up to the AvatarMixer - glm::vec3 oldPosition = _position; - _position = getSkeletonPosition(); + glm::vec3 oldPosition = getPosition(); + setPosition(getSkeletonPosition()); QByteArray array = AvatarData::toByteArray(cullSmallChanges, sendAll); // copy the correct position back - _position = oldPosition; + setPosition(oldPosition); return array; } return AvatarData::toByteArray(cullSmallChanges, sendAll); @@ -228,9 +228,9 @@ void MyAvatar::simulate(float deltaTime) { _player->play(); } - if (_scale != _targetScale) { - float scale = (1.0f - SMOOTHING_RATIO) * _scale + SMOOTHING_RATIO * _targetScale; - setScale(scale); + if (getAvatarScale() != _targetScale) { + float scale = (1.0f - SMOOTHING_RATIO) * getAvatarScale() + SMOOTHING_RATIO * _targetScale; + setAvatarScale(scale); } { @@ -277,10 +277,10 @@ void MyAvatar::simulate(float deltaTime) { Head* head = getHead(); glm::vec3 headPosition; if (!_skeletonModel.getHeadPosition(headPosition)) { - headPosition = _position; + headPosition = getPosition(); } head->setPosition(headPosition); - head->setScale(_scale); + head->setScale(getAvatarScale()); head->simulate(deltaTime, true); } @@ -846,7 +846,7 @@ void MyAvatar::loadData() { _leanScale = loadSetting(settings, "leanScale", 0.05f); _targetScale = loadSetting(settings, "scale", 1.0f); - setScale(_scale); + setAvatarScale(getAvatarScale()); _animGraphUrl = settings.value("animGraphURL", "").toString(); _fullAvatarURLFromPreferences = settings.value("fullAvatarURL", AvatarData::defaultFullAvatarModelUrl()).toUrl(); @@ -992,7 +992,8 @@ void MyAvatar::updateLookAtTargetAvatar() { bool isCurrentTarget = avatar->getIsLookAtTarget(); float distanceTo = glm::length(avatar->getHead()->getEyePosition() - cameraPosition); avatar->setIsLookAtTarget(false); - if (!avatar->isMyAvatar() && avatar->isInitialized() && (distanceTo < GREATEST_LOOKING_AT_DISTANCE * getScale())) { + if (!avatar->isMyAvatar() && avatar->isInitialized() && + (distanceTo < GREATEST_LOOKING_AT_DISTANCE * getAvatarScale())) { float angleTo = glm::angle(lookForward, glm::normalize(avatar->getHead()->getEyePosition() - cameraPosition)); if (angleTo < (smallestAngleTo * (isCurrentTarget ? KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR : 1.0f))) { _lookAtTargetAvatar = avatarPointer; @@ -1228,7 +1229,7 @@ glm::vec3 MyAvatar::getSkeletonPosition() const { // The avatar is rotated PI about the yAxis, so we have to correct for it // to get the skeleton offset contribution in the world-frame. const glm::quat FLIP = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); - return _position + getOrientation() * FLIP * _skeletonOffset; + return getPosition() + getOrientation() * FLIP * _skeletonOffset; } return Avatar::getPosition(); } @@ -1464,7 +1465,7 @@ const float RENDER_HEAD_CUTOFF_DISTANCE = 0.50f; bool MyAvatar::cameraInsideHead() const { const Head* head = getHead(); const glm::vec3 cameraPosition = qApp->getCamera()->getPosition(); - return glm::length(cameraPosition - head->getEyePosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * _scale); + return glm::length(cameraPosition - head->getEyePosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * getAvatarScale()); } bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const { @@ -1618,11 +1619,11 @@ glm::vec3 MyAvatar::applyKeyboardMotor(float deltaTime, const glm::vec3& localVe if (isHovering) { // we're flying --> complex acceleration curve with high max speed float motorSpeed = glm::length(_keyboardMotorVelocity); - float finalMaxMotorSpeed = _scale * MAX_KEYBOARD_MOTOR_SPEED; + float finalMaxMotorSpeed = getAvatarScale() * MAX_KEYBOARD_MOTOR_SPEED; float speedGrowthTimescale = 2.0f; float speedIncreaseFactor = 1.8f; motorSpeed *= 1.0f + glm::clamp(deltaTime / speedGrowthTimescale , 0.0f, 1.0f) * speedIncreaseFactor; - const float maxBoostSpeed = _scale * MAX_BOOST_SPEED; + const float maxBoostSpeed = getAvatarScale() * MAX_BOOST_SPEED; if (motorSpeed < maxBoostSpeed) { // an active keyboard motor should never be slower than this float boostCoefficient = (maxBoostSpeed - motorSpeed) / maxBoostSpeed; diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index 4e5dd0da0c..c6164978ef 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -416,7 +416,7 @@ bool ApplicationCompositor::calculateRayUICollisionPoint(const glm::vec3& positi glm::vec3 relativeDirection = glm::normalize(inverseOrientation * direction); float t; - if (raySphereIntersect(relativeDirection, relativePosition, _oculusUIRadius * myAvatar->getScale(), &t)){ + if (raySphereIntersect(relativeDirection, relativePosition, _oculusUIRadius * myAvatar->getAvatarScale(), &t)){ result = position + direction * t; return true; } diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 4ba248c76c..3a222ce15a 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -189,7 +189,7 @@ void PreferencesDialog::loadPreferences() { ui.leanScaleSpin->setValue(myAvatar->getLeanScale()); - ui.avatarScaleSpin->setValue(myAvatar->getScale()); + ui.avatarScaleSpin->setValue(myAvatar->getAvatarScale()); ui.avatarAnimationEdit->setText(myAvatar->getAnimGraphUrl()); ui.maxOctreePPSSpin->setValue(qApp->getMaxOctreePacketsPerSecond()); diff --git a/interface/src/ui/overlays/OverlaysPayload.cpp b/interface/src/ui/overlays/OverlaysPayload.cpp index 02d432ea81..1b1c48c3ca 100644 --- a/interface/src/ui/overlays/OverlaysPayload.cpp +++ b/interface/src/ui/overlays/OverlaysPayload.cpp @@ -68,7 +68,7 @@ namespace render { glm::vec3 myAvatarPosition = avatar->getPosition(); float angle = glm::degrees(glm::angle(myAvatarRotation)); glm::vec3 axis = glm::axis(myAvatarRotation); - float myAvatarScale = avatar->getScale(); + float myAvatarScale = avatar->getAvatarScale(); Transform transform = Transform(); transform.setTranslation(myAvatarPosition); transform.setRotation(glm::angleAxis(angle, axis)); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index a4d506a748..6f4c89abe7 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -38,11 +38,7 @@ const glm::vec3 DEFAULT_LOCAL_AABOX_SCALE(1.0f); AvatarData::AvatarData() : _sessionUUID(), - _position(0.0f), _handPosition(0.0f), - _bodyYaw(-90.0f), - _bodyPitch(0.0f), - _bodyRoll(0.0f), _targetScale(1.0f), _handState(0), _keyState(NO_KEY_DOWN), @@ -61,7 +57,9 @@ AvatarData::AvatarData() : _targetVelocity(0.0f), _localAABox(DEFAULT_LOCAL_AABOX_CORNER, DEFAULT_LOCAL_AABOX_SCALE) { - + setBodyPitch(0.0f); + setBodyYaw(-90.0f); + setBodyRoll(0.0f); } AvatarData::~AvatarData() { @@ -79,23 +77,37 @@ const QUrl& AvatarData::defaultFullAvatarModelUrl() { return _defaultFullAvatarModelUrl; } -const glm::vec3& AvatarData::getPosition() const { - return _position; +float AvatarData::getBodyYaw() const { + glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); + return eulerAngles.y; } -void AvatarData::setPosition(const glm::vec3 position) { - _position = position; +void AvatarData::setBodyYaw(float bodyYaw) { + glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); + eulerAngles.y = bodyYaw; + setOrientation(glm::quat(glm::radians(eulerAngles))); } -glm::quat AvatarData::getOrientation() const { - return glm::quat(glm::radians(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll))); +float AvatarData::getBodyPitch() const { + glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); + return eulerAngles.x; } -void AvatarData::setOrientation(const glm::quat& orientation) { - glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(orientation)); - _bodyPitch = eulerAngles.x; - _bodyYaw = eulerAngles.y; - _bodyRoll = eulerAngles.z; +void AvatarData::setBodyPitch(float bodyPitch) { + glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); + eulerAngles.x = bodyPitch; + setOrientation(glm::quat(glm::radians(eulerAngles))); +} + +float AvatarData::getBodyRoll() const { + glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); + return eulerAngles.z; +} + +void AvatarData::setBodyRoll(float bodyRoll) { + glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); + eulerAngles.z = bodyRoll; + setOrientation(glm::quat(glm::radians(eulerAngles))); } // There are a number of possible strategies for this set of tools through endRender, below. @@ -162,12 +174,12 @@ void AvatarData::setClampedTargetScale(float targetScale, bool overideReferentia } glm::vec3 AvatarData::getHandPosition() const { - return getOrientation() * _handPosition + _position; + return getOrientation() * _handPosition + getPosition(); } void AvatarData::setHandPosition(const glm::vec3& handPosition) { // store relative to position/orientation - _handPosition = glm::inverse(getOrientation()) * (handPosition - _position); + _handPosition = glm::inverse(getOrientation()) * (handPosition - getPosition()); } QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { @@ -188,13 +200,14 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { unsigned char* destinationBuffer = reinterpret_cast(avatarDataByteArray.data()); unsigned char* startPosition = destinationBuffer; - memcpy(destinationBuffer, &_position, sizeof(_position)); - destinationBuffer += sizeof(_position); + const glm::vec3& position = getPosition(); + memcpy(destinationBuffer, &position, sizeof(position)); + destinationBuffer += sizeof(position); - // Body rotation (NOTE: This needs to become a quaternion to save two bytes) - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyYaw); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); + // Body rotation + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, getBodyYaw()); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, getBodyPitch()); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, getBodyRoll()); // Body scale destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _targetScale); @@ -487,11 +500,12 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { } return maxAvailableSize; } - if (_bodyYaw != yaw || _bodyPitch != pitch || _bodyRoll != roll) { + + // TODO is this safe? will the floats not exactly match? + if (getBodyYaw() != yaw || getBodyPitch() != pitch || getBodyRoll() != roll) { _hasNewJointRotations = true; - _bodyYaw = yaw; - _bodyPitch = pitch; - _bodyRoll = roll; + glm::vec3 eulerAngles(pitch, yaw, roll); + setOrientation(glm::quat(glm::radians(eulerAngles))); } // scale diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 8f5416e4fd..a7d216be6d 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -50,6 +50,7 @@ typedef unsigned long long quint64; #include #include #include +#include #include "AABox.h" #include "HandData.h" @@ -134,7 +135,7 @@ class QDataStream; class AttachmentData; class JointData; -class AvatarData : public QObject { +class AvatarData : public QObject, public SpatiallyNestable { Q_OBJECT Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition) @@ -172,9 +173,6 @@ public: const QUuid& getSessionUUID() const { return _sessionUUID; } - const glm::vec3& getPosition() const; - virtual void setPosition(const glm::vec3 position); - glm::vec3 getHandPosition() const; void setHandPosition(const glm::vec3& handPosition); @@ -189,16 +187,13 @@ public: /// \return number of bytes parsed virtual int parseDataFromBuffer(const QByteArray& buffer); - // Body Rotation (degrees) - float getBodyYaw() const { return _bodyYaw; } - void setBodyYaw(float bodyYaw) { _bodyYaw = bodyYaw; } - float getBodyPitch() const { return _bodyPitch; } - void setBodyPitch(float bodyPitch) { _bodyPitch = bodyPitch; } - float getBodyRoll() const { return _bodyRoll; } - void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; } - - glm::quat getOrientation() const; - virtual void setOrientation(const glm::quat& orientation); + // Body Rotation (degrees) + float getBodyYaw() const; + void setBodyYaw(float bodyYaw); + float getBodyPitch() const; + void setBodyPitch(float bodyPitch); + float getBodyRoll() const; + void setBodyRoll(float bodyRoll); void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time. void startCapture(); // start/end of the period in which the latest values are about to be captured for camera, etc. @@ -363,13 +358,7 @@ public slots: protected: QUuid _sessionUUID; - glm::vec3 _position = START_LOCATION; glm::vec3 _handPosition; - - // Body rotation - float _bodyYaw; // degrees - float _bodyPitch; // degrees - float _bodyRoll; // degrees glm::vec3 _nextPosition {}; glm::quat _nextOrientation {}; From bc99ef778cb16c94fb48875e30eb5940db6238ae Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 20 Oct 2015 12:04:29 -0700 Subject: [PATCH 05/51] change how render engine is told about model position changes --- interface/src/Application.cpp | 140 +++++++++--------- interface/src/avatar/Avatar.cpp | 44 +++--- interface/src/avatar/Avatar.h | 3 + interface/src/avatar/AvatarManager.cpp | 26 ++-- interface/src/avatar/AvatarUpdate.cpp | 10 +- libraries/avatars/src/AvatarData.cpp | 58 ++------ libraries/avatars/src/AvatarData.h | 22 +-- .../render-utils/src/MeshPartPayload.cpp | 22 ++- libraries/render-utils/src/MeshPartPayload.h | 10 +- libraries/render-utils/src/Model.cpp | 62 +++++--- libraries/render-utils/src/Model.h | 11 +- 11 files changed, 213 insertions(+), 195 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9b5b83492c..cab189e7a0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1086,75 +1086,77 @@ void Application::paintGL() { { PerformanceTimer perfTimer("CameraUpdates"); - auto myAvatar = getMyAvatar(); - - myAvatar->startCapture(); - if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); - Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); - cameraMenuChanged(); - } - - // The render mode is default or mirror if the camera is in mirror mode, assigned further below - renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; - - // Always use the default eye position, not the actual head eye position. - // Using the latter will cause the camera to wobble with idle animations, - // or with changes from the face tracker - if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { - if (isHMDMode()) { - mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setPosition(extractTranslation(camMat)); - _myCamera.setRotation(glm::quat_cast(camMat)); - } else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition()); - _myCamera.setRotation(myAvatar->getHead()->getCameraOrientation()); + myAvatar->withReadLock([&] { + if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, + myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); + Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, + !(myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); + cameraMenuChanged(); } - } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - if (isHMDMode()) { - auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setRotation(glm::normalize(glm::quat_cast(hmdWorldMat))); - auto worldBoomOffset = myAvatar->getOrientation() * (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f)); - _myCamera.setPosition(extractTranslation(hmdWorldMat) + worldBoomOffset); - } else { - _myCamera.setRotation(myAvatar->getHead()->getOrientation()); - if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + _myCamera.getRotation() - * (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); + + // The render mode is default or mirror if the camera is in mirror mode, assigned further below + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; + + // Always use the default eye position, not the actual head eye position. + // Using the latter will cause the camera to wobble with idle animations, + // or with changes from the face tracker + if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { + if (isHMDMode()) { + mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setPosition(extractTranslation(camMat)); + _myCamera.setRotation(glm::quat_cast(camMat)); } else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + myAvatar->getOrientation() - * (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); + _myCamera.setPosition(myAvatar->getDefaultEyePosition()); + _myCamera.setRotation(myAvatar->getHead()->getCameraOrientation()); } + } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + if (isHMDMode()) { + auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setRotation(glm::normalize(glm::quat_cast(hmdWorldMat))); + auto worldBoomOffset = myAvatar->getOrientation() * + (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f)); + _myCamera.setPosition(extractTranslation(hmdWorldMat) + worldBoomOffset); + } else { + _myCamera.setRotation(myAvatar->getHead()->getOrientation()); + if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + _myCamera.getRotation() * + (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); + } else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + myAvatar->getOrientation() * + (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); + } + } + } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { + if (isHMDMode()) { + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() + * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)) * hmdRotation); + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0) + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror + + (myAvatar->getOrientation() * + glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))) * hmdOffset); + } else { + _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() + * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0) + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + } + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; } - } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - if (isHMDMode()) { - glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() - * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)) * hmdRotation); - glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0) - + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror - + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))) * hmdOffset); - } else { - _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() - * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0) - + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + // Update camera position + if (!isHMDMode()) { + _myCamera.update(1.0f / _fps); } - renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; - } - // Update camera position - if (!isHMDMode()) { - _myCamera.update(1.0f / _fps); - } - myAvatar->endCapture(); + }); } // Primary rendering pass @@ -3386,9 +3388,9 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se // FIXME: This preRender call is temporary until we create a separate render::scene for the mirror rendering. // Then we can move this logic into the Avatar::simulate call. auto myAvatar = getMyAvatar(); - myAvatar->startRender(); - myAvatar->preRender(renderArgs); - myAvatar->endRender(); + myAvatar->withReadLock([&] { + myAvatar->preRender(renderArgs); + }); activeRenderingThread = QThread::currentThread(); @@ -3502,9 +3504,9 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se _renderEngine->setRenderContext(renderContext); // Before the deferred pass, let's try to use the render engine - myAvatar->startRenderRun(); - _renderEngine->run(); - myAvatar->endRenderRun(); + myAvatar->withReadLock([&] { + _renderEngine->run(); + }); auto engineRC = _renderEngine->getRenderContext(); sceneInterface->setEngineFeedOpaqueItems(engineRC->_numFeedOpaqueItems); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 92493ab23f..c70c1a5501 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -303,8 +303,6 @@ void Avatar::removeFromScene(AvatarSharedPointer self, std::shared_ptr_batch; if (glm::distance(DependencyManager::get()->getMyAvatar()->getPosition(), getPosition()) < 10.0f) { @@ -375,7 +373,6 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { } if (frustum->sphereInFrustum(getPosition(), boundingRadius) == ViewFrustum::OUTSIDE) { - endRender(); return; } @@ -529,7 +526,6 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { renderDisplayName(batch, frustum, textPosition); } } - endRender(); } glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { @@ -993,23 +989,25 @@ void Avatar::setBillboard(const QByteArray& billboard) { } int Avatar::parseDataFromBuffer(const QByteArray& buffer) { - startUpdate(); - if (!_initialized) { - // now that we have data for this Avatar we are go for init - init(); - } + int bytesRead; - // change in position implies movement - glm::vec3 oldPosition = getPosition(); + withWriteLock([&] { + if (!_initialized) { + // now that we have data for this Avatar we are go for init + init(); + } - int bytesRead = AvatarData::parseDataFromBuffer(buffer); + // change in position implies movement + glm::vec3 oldPosition = getPosition(); - const float MOVE_DISTANCE_THRESHOLD = 0.001f; - _moving = glm::distance(oldPosition, getPosition()) > MOVE_DISTANCE_THRESHOLD; - if (_moving && _motionState) { - _motionState->addDirtyFlags(Simulation::DIRTY_POSITION); - } - endUpdate(); + bytesRead = AvatarData::parseDataFromBuffer(buffer); + + const float MOVE_DISTANCE_THRESHOLD = 0.001f; + _moving = glm::distance(oldPosition, getPosition()) > MOVE_DISTANCE_THRESHOLD; + if (_moving && _motionState) { + _motionState->addDirtyFlags(Simulation::DIRTY_POSITION); + } + }); return bytesRead; } @@ -1201,3 +1199,13 @@ glm::quat Avatar::getRightPalmRotation() { getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightRotation); return rightRotation; } + +void Avatar::setPosition(const glm::vec3& position) { + AvatarData::setPosition(position); + updateAttitude(); +} + +void Avatar::setOrientation(const glm::quat& orientation) { + AvatarData::setOrientation(orientation); + updateAttitude(); +} diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 2b7d27b2e3..2366e79c5b 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -174,6 +174,9 @@ public: void setMotionState(AvatarMotionState* motionState) { _motionState = motionState; } AvatarMotionState* getMotionState() { return _motionState; } + virtual void setPosition(const glm::vec3& position); + virtual void setOrientation(const glm::quat& orientation); + public slots: glm::vec3 getLeftPalmPosition(); glm::vec3 getLeftPalmVelocity(); diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index f42cdc200b..16e136f9d1 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -129,9 +129,9 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { _avatarFades.push_back(avatarIterator.value()); avatarIterator = _avatarHash.erase(avatarIterator); } else { - avatar->startUpdate(); - avatar->simulate(deltaTime); - avatar->endUpdate(); + avatar->withWriteLock([&] { + avatar->simulate(deltaTime); + }); ++avatarIterator; } } @@ -150,16 +150,16 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { render::PendingChanges pendingChanges; while (fadingIterator != _avatarFades.end()) { auto avatar = std::static_pointer_cast(*fadingIterator); - avatar->startUpdate(); - avatar->setTargetScale(avatar->getAvatarScale() * SHRINK_RATE, true); - if (avatar->getTargetScale() < MIN_FADE_SCALE) { - avatar->removeFromScene(*fadingIterator, scene, pendingChanges); - fadingIterator = _avatarFades.erase(fadingIterator); - } else { - avatar->simulate(deltaTime); - ++fadingIterator; - } - avatar->endUpdate(); + avatar->withWriteLock([&] { + avatar->setTargetScale(avatar->getAvatarScale() * SHRINK_RATE, true); + if (avatar->getTargetScale() < MIN_FADE_SCALE) { + avatar->removeFromScene(*fadingIterator, scene, pendingChanges); + fadingIterator = _avatarFades.erase(fadingIterator); + } else { + avatar->simulate(deltaTime); + ++fadingIterator; + } + }); } scene->enqueuePendingChanges(pendingChanges); } diff --git a/interface/src/avatar/AvatarUpdate.cpp b/interface/src/avatar/AvatarUpdate.cpp index acdb251950..a32948f598 100644 --- a/interface/src/avatar/AvatarUpdate.cpp +++ b/interface/src/avatar/AvatarUpdate.cpp @@ -56,11 +56,11 @@ bool AvatarUpdate::process() { //gets current lookat data, removes missing avatars, etc. manager->updateOtherAvatars(deltaSeconds); - myAvatar->startUpdate(); - qApp->updateMyAvatarLookAtPosition(); - // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes - manager->updateMyAvatar(deltaSeconds); - myAvatar->endUpdate(); + myAvatar->withWriteLock([&] { + qApp->updateMyAvatarLookAtPosition(); + // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes + manager->updateMyAvatar(deltaSeconds); + }); if (!isThreaded()) { return true; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 6f4c89abe7..9b2967cf5d 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -110,51 +110,25 @@ void AvatarData::setBodyRoll(float bodyRoll) { setOrientation(glm::quat(glm::radians(eulerAngles))); } +void AvatarData::setPosition(const glm::vec3& position) { + withWriteLock([&] { + SpatiallyNestable::setPosition(position); + }); +} + +void AvatarData::setOrientation(const glm::quat& orientation) { + withWriteLock([&] { + SpatiallyNestable::setOrientation(orientation); + }); +} + // There are a number of possible strategies for this set of tools through endRender, below. void AvatarData::nextAttitude(glm::vec3 position, glm::quat orientation) { - avatarLock.lock(); - setPosition(position); - setOrientation(orientation); - avatarLock.unlock(); -} -void AvatarData::startCapture() { - avatarLock.lock(); - assert(_nextAllowed); - _nextAllowed = false; - _nextPosition = getPosition(); - _nextOrientation = getOrientation(); -} -void AvatarData::endCapture() { - avatarLock.unlock(); -} -void AvatarData::startUpdate() { - avatarLock.lock(); -} -void AvatarData::endUpdate() { - avatarLock.unlock(); -} -void AvatarData::startRenderRun() { - // I'd like to get rid of this and just (un)lock at (end-)startRender. - // But somehow that causes judder in rotations. - avatarLock.lock(); -} -void AvatarData::endRenderRun() { - avatarLock.unlock(); -} -void AvatarData::startRender() { - glm::vec3 pos = getPosition(); - glm::quat rot = getOrientation(); - setPosition(_nextPosition); - setOrientation(_nextOrientation); + withWriteLock([&] { + SpatiallyNestable::setPosition(position); + SpatiallyNestable::setOrientation(orientation); + }); updateAttitude(); - _nextPosition = pos; - _nextOrientation = rot; -} -void AvatarData::endRender() { - setPosition(_nextPosition); - setOrientation(_nextOrientation); - updateAttitude(); - _nextAllowed = true; } float AvatarData::getTargetScale() const { diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index a7d216be6d..9f8224caf8 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -44,13 +44,13 @@ typedef unsigned long long quint64; #include #include #include -#include #include #include #include #include #include +#include #include "AABox.h" #include "HandData.h" @@ -59,6 +59,7 @@ typedef unsigned long long quint64; #include "Player.h" #include "Recorder.h" + using AvatarSharedPointer = std::shared_ptr; using AvatarWeakPointer = std::weak_ptr; using AvatarHash = QHash; @@ -135,7 +136,7 @@ class QDataStream; class AttachmentData; class JointData; -class AvatarData : public QObject, public SpatiallyNestable { +class AvatarData : public QObject, public ReadWriteLockable, public SpatiallyNestable { Q_OBJECT Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition) @@ -195,15 +196,10 @@ public: float getBodyRoll() const; void setBodyRoll(float bodyRoll); + virtual void setPosition(const glm::vec3& position); + virtual void setOrientation(const glm::quat& orientation); + void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time. - void startCapture(); // start/end of the period in which the latest values are about to be captured for camera, etc. - void endCapture(); - void startUpdate(); // start/end of update iteration - void endUpdate(); - void startRender(); // start/end of rendering of this object - void startRenderRun(); // start/end of entire scene. - void endRenderRun(); - void endRender(); virtual void updateAttitude() {} // Tell skeleton mesh about changes glm::quat getHeadOrientation() const { return _headData->getOrientation(); } @@ -360,10 +356,6 @@ protected: QUuid _sessionUUID; glm::vec3 _handPosition; - glm::vec3 _nextPosition {}; - glm::quat _nextOrientation {}; - bool _nextAllowed {true}; - // Body scale float _targetScale; @@ -413,8 +405,6 @@ protected: SimpleMovingAverage _averageBytesReceived; - QMutex avatarLock; // Name is redundant, but it aids searches. - private: static QUrl _defaultFullAvatarModelUrl; // privatize the copy constructor and assignment operator so they cannot be called diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 80327b7e54..294bf015e0 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -39,9 +39,14 @@ namespace render { using namespace render; -MeshPartPayload::MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex) : - model(model), meshIndex(meshIndex), partIndex(partIndex), _shapeID(shapeIndex) -{ +MeshPartPayload::MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex, + glm::vec3 position, glm::quat orientation) : + model(model), + meshIndex(meshIndex), + partIndex(partIndex), + _shapeID(shapeIndex), + _modelPosition(position), + _modelOrientation(orientation) { initCache(); } @@ -66,6 +71,11 @@ void MeshPartPayload::initCache() { } +void MeshPartPayload::updateModelLocation(glm::vec3 position, glm::quat orientation) { + _modelPosition = position; + _modelOrientation = orientation; +} + render::ItemKey MeshPartPayload::getKey() const { ItemKey::Builder builder; builder.withTypeShape(); @@ -91,7 +101,7 @@ render::ItemKey MeshPartPayload::getKey() const { render::Item::Bound MeshPartPayload::getBound() const { // NOTE: we can't cache this bounds because we need to handle the case of a moving // entity or mesh part. - return model->getPartBounds(meshIndex, partIndex); + return model->getPartBounds(meshIndex, partIndex, _modelPosition, _modelOrientation); } void MeshPartPayload::drawCall(gpu::Batch& batch) const { @@ -222,7 +232,7 @@ void MeshPartPayload::bindTransform(gpu::Batch& batch, const ModelRender::Locati transform = Transform(state.clusterMatrices[0]); } } - transform.preTranslate(model->_translation); + transform.preTranslate(_modelPosition); batch.setModelTransform(transform); } @@ -247,7 +257,7 @@ void MeshPartPayload::render(RenderArgs* args) const { } // Back to model to update the cluster matrices right now - model->updateClusterMatrices(); + model->updateClusterMatrices(_modelPosition, _modelOrientation); const FBXMesh& mesh = geometry.meshes.at(meshIndex); diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index 51e577e7c7..b29d9510d1 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -24,7 +24,7 @@ class Model; class MeshPartPayload { public: - MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex); + MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex, glm::vec3 position, glm::quat orientation); typedef render::Payload Payload; typedef Payload::DataPointer Pointer; @@ -33,7 +33,11 @@ public: int meshIndex; int partIndex; int _shapeID; - + glm::vec3 _modelPosition; + glm::quat _modelOrientation; + + void updateModelLocation(glm::vec3 position, glm::quat orientation); + // Render Item interface render::ItemKey getKey() const; render::Item::Bound getBound() const; @@ -63,4 +67,4 @@ namespace render { template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args); } -#endif // hifi_MeshPartPayload_h \ No newline at end of file +#endif // hifi_MeshPartPayload_h diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 38f5ffdabe..9c3b8adc17 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -73,13 +73,16 @@ Model::~Model() { AbstractViewStateInterface* Model::_viewState = NULL; + void Model::setTranslation(const glm::vec3& translation) { _translation = translation; + enqueueLocationChange(); } - + void Model::setRotation(const glm::quat& rotation) { _rotation = rotation; -} + enqueueLocationChange(); +} void Model::setScale(const glm::vec3& scale) { setScaleInternal(scale); @@ -107,6 +110,20 @@ void Model::setOffset(const glm::vec3& offset) { _snappedToRegistrationPoint = false; } +void Model::enqueueLocationChange() { + render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); + + render::PendingChanges pendingChanges; + foreach (auto itemID, _renderItems.keys()) { + pendingChanges.updateItem(itemID, [=](MeshPartPayload& data) { + data.updateModelLocation(_translation, _rotation); + data.model->_needsUpdateClusterMatrices = true; + }); + } + + scene->enqueuePendingChanges(pendingChanges); +} + QVector Model::createJointStates(const FBXGeometry& geometry) { QVector jointStates; for (int i = 0; i < geometry.joints.size(); ++i) { @@ -378,7 +395,7 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) { _calculatedMeshPartBoxes.clear(); for (int i = 0; i < numberOfMeshes; i++) { const FBXMesh& mesh = geometry.meshes.at(i); - Extents scaledMeshExtents = calculateScaledOffsetExtents(mesh.meshExtents); + Extents scaledMeshExtents = calculateScaledOffsetExtents(mesh.meshExtents, _translation, _rotation); _calculatedMeshBoxes[i] = AABox(scaledMeshExtents); @@ -659,7 +676,8 @@ Extents Model::getUnscaledMeshExtents() const { return scaledExtents; } -Extents Model::calculateScaledOffsetExtents(const Extents& extents) const { +Extents Model::calculateScaledOffsetExtents(const Extents& extents, + glm::vec3 modelPosition, glm::quat modelOrientation) const { // we need to include any fst scaling, translation, and rotation, which is captured in the offset matrix glm::vec3 minimum = glm::vec3(_geometry->getFBXGeometry().offset * glm::vec4(extents.minimum, 1.0f)); glm::vec3 maximum = glm::vec3(_geometry->getFBXGeometry().offset * glm::vec4(extents.maximum, 1.0f)); @@ -667,17 +685,17 @@ Extents Model::calculateScaledOffsetExtents(const Extents& extents) const { Extents scaledOffsetExtents = { ((minimum + _offset) * _scale), ((maximum + _offset) * _scale) }; - Extents rotatedExtents = scaledOffsetExtents.getRotated(_rotation); + Extents rotatedExtents = scaledOffsetExtents.getRotated(modelOrientation); - Extents translatedExtents = { rotatedExtents.minimum + _translation, - rotatedExtents.maximum + _translation }; + Extents translatedExtents = { rotatedExtents.minimum + modelPosition, + rotatedExtents.maximum + modelPosition }; return translatedExtents; } /// Returns the world space equivalent of some box in model space. -AABox Model::calculateScaledOffsetAABox(const AABox& box) const { - return AABox(calculateScaledOffsetExtents(Extents(box))); +AABox Model::calculateScaledOffsetAABox(const AABox& box, glm::vec3 modelPosition, glm::quat modelOrientation) const { + return AABox(calculateScaledOffsetExtents(Extents(box), modelPosition, modelOrientation)); } glm::vec3 Model::calculateScaledOffsetPoint(const glm::vec3& point) const { @@ -971,7 +989,7 @@ void Model::simulateInternal(float deltaTime) { glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset; updateRig(deltaTime, parentTransform); } -void Model::updateClusterMatrices() { +void Model::updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrientation) { PerformanceTimer perfTimer("Model::updateClusterMatrices"); if (!_needsUpdateClusterMatrices) { @@ -985,7 +1003,7 @@ void Model::updateClusterMatrices() { glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); auto cauterizeMatrix = _rig->getJointTransform(geometry.neckJointIndex) * zeroScale; - glm::mat4 modelToWorld = glm::mat4_cast(_rotation); + glm::mat4 modelToWorld = glm::mat4_cast(modelOrientation); for (int i = 0; i < _meshStates.size(); i++) { MeshState& state = _meshStates[i]; const FBXMesh& mesh = geometry.meshes.at(i); @@ -1007,16 +1025,21 @@ void Model::updateClusterMatrices() { // Once computed the cluster matrices, update the buffer(s) if (mesh.clusters.size() > 1) { if (!state.clusterBuffer) { - state.clusterBuffer = std::make_shared(state.clusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.clusterMatrices.constData()); + state.clusterBuffer = std::make_shared(state.clusterMatrices.size() * sizeof(glm::mat4), + (const gpu::Byte*) state.clusterMatrices.constData()); } else { - state.clusterBuffer->setSubData(0, state.clusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.clusterMatrices.constData()); + state.clusterBuffer->setSubData(0, state.clusterMatrices.size() * sizeof(glm::mat4), + (const gpu::Byte*) state.clusterMatrices.constData()); } if (!_cauterizeBoneSet.empty() && (state.cauterizedClusterMatrices.size() > 1)) { if (!state.cauterizedClusterBuffer) { - state.cauterizedClusterBuffer = std::make_shared(state.cauterizedClusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.cauterizedClusterMatrices.constData()); + state.cauterizedClusterBuffer = + std::make_shared(state.cauterizedClusterMatrices.size() * sizeof(glm::mat4), + (const gpu::Byte*) state.cauterizedClusterMatrices.constData()); } else { - state.cauterizedClusterBuffer->setSubData(0, state.cauterizedClusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.cauterizedClusterMatrices.constData()); + state.cauterizedClusterBuffer->setSubData(0, state.cauterizedClusterMatrices.size() * sizeof(glm::mat4), + (const gpu::Byte*) state.cauterizedClusterMatrices.constData()); } } } @@ -1109,7 +1132,7 @@ void Model::deleteGeometry() { _blendedBlendshapeCoefficients.clear(); } -AABox Model::getPartBounds(int meshIndex, int partIndex) { +AABox Model::getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation) { if (!_geometry || !_geometry->isLoaded()) { return AABox(); @@ -1120,7 +1143,7 @@ AABox Model::getPartBounds(int meshIndex, int partIndex) { bool isSkinned = state.clusterMatrices.size() > 1; if (isSkinned) { // if we're skinned return the entire mesh extents because we can't know for sure our clusters don't move us - return calculateScaledOffsetAABox(_geometry->getFBXGeometry().meshExtents); + return calculateScaledOffsetAABox(_geometry->getFBXGeometry().meshExtents, modelPosition, modelOrientation); } } if (_geometry->getFBXGeometry().meshes.size() > meshIndex) { @@ -1138,7 +1161,7 @@ AABox Model::getPartBounds(int meshIndex, int partIndex) { // // If we not skinned use the bounds of the subMesh for all it's parts const FBXMesh& mesh = _geometry->getFBXGeometry().meshes.at(meshIndex); - return calculateScaledOffsetExtents(mesh.meshExtents); + return calculateScaledOffsetExtents(mesh.meshExtents, modelPosition, modelOrientation); } return AABox(); } @@ -1164,7 +1187,7 @@ void Model::segregateMeshGroups() { // Create the render payloads int totalParts = mesh.parts.size(); for (int partIndex = 0; partIndex < totalParts; partIndex++) { - _renderItemsSet << std::make_shared(this, i, partIndex, shapeID); + _renderItemsSet << std::make_shared(this, i, partIndex, shapeID, _translation, _rotation); shapeID++; } } @@ -1184,6 +1207,7 @@ bool Model::initWhenReady(render::ScenePointer scene) { _renderItems.insert(item, renderPayload); pendingChanges.resetItem(item, renderPayload); pendingChanges.updateItem(item, [&](MeshPartPayload& data) { + data.updateModelLocation(_translation, _rotation); data.model->_needsUpdateClusterMatrices = true; }); } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index e3a9ce9ac3..68468642da 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -86,7 +86,8 @@ public: bool isVisible() const { return _isVisible; } - AABox getPartBounds(int meshIndex, int partIndex); + void updateRenderItems(); + AABox getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation); bool maybeStartBlender(); @@ -109,7 +110,7 @@ public: bool getSnapModelToRegistrationPoint() { return _snapModelToRegistrationPoint; } virtual void simulate(float deltaTime, bool fullUpdate = true); - void updateClusterMatrices(); + void updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrientation); /// Returns a reference to the shared geometry. const QSharedPointer& getGeometry() const { return _geometry; } @@ -183,6 +184,8 @@ public: void setScale(const glm::vec3& scale); const glm::vec3& getScale() const { return _scale; } + void enqueueLocationChange(); + /// enables/disables scale to fit behavior, the model will be automatically scaled to the specified largest dimension bool getIsScaledToFit() const { return _scaledToFit; } /// is model scaled to fit const glm::vec3& getScaleToFitDimensions() const { return _scaleToFitDimensions; } /// the dimensions model is scaled to @@ -210,10 +213,10 @@ protected: Extents getUnscaledMeshExtents() const; /// Returns the scaled equivalent of some extents in model space. - Extents calculateScaledOffsetExtents(const Extents& extents) const; + Extents calculateScaledOffsetExtents(const Extents& extents, glm::vec3 modelPosition, glm::quat modelOrientation) const; /// Returns the world space equivalent of some box in model space. - AABox calculateScaledOffsetAABox(const AABox& box) const; + AABox calculateScaledOffsetAABox(const AABox& box, glm::vec3 modelPosition, glm::quat modelOrientation) const; /// Returns the scaled equivalent of a point in model space. glm::vec3 calculateScaledOffsetPoint(const glm::vec3& point) const; From 264b65813211eee445b936994494a406844ebd14 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 22 Oct 2015 11:05:48 -0700 Subject: [PATCH 06/51] hook up entities and avatars to SpatialParentFinder --- .../src/entities/AssignmentParentFinder.cpp | 22 +++++ .../src/entities/AssignmentParentFinder.h | 34 +++++++ .../src/entities/EntityServer.cpp | 5 + interface/src/Application.cpp | 4 + interface/src/InterfaceParentFinder.cpp | 35 +++++++ interface/src/InterfaceParentFinder.h | 27 ++++++ libraries/entities/src/EntityItem.cpp | 13 ++- libraries/entities/src/EntityItem.h | 4 - libraries/shared/src/SpatialParentFinder.h | 39 ++++++++ libraries/shared/src/SpatiallyNestable.cpp | 96 +++++++++++++++++-- libraries/shared/src/SpatiallyNestable.h | 37 +++++-- 11 files changed, 296 insertions(+), 20 deletions(-) create mode 100644 assignment-client/src/entities/AssignmentParentFinder.cpp create mode 100644 assignment-client/src/entities/AssignmentParentFinder.h create mode 100644 interface/src/InterfaceParentFinder.cpp create mode 100644 interface/src/InterfaceParentFinder.h create mode 100644 libraries/shared/src/SpatialParentFinder.h diff --git a/assignment-client/src/entities/AssignmentParentFinder.cpp b/assignment-client/src/entities/AssignmentParentFinder.cpp new file mode 100644 index 0000000000..6a66aa3f73 --- /dev/null +++ b/assignment-client/src/entities/AssignmentParentFinder.cpp @@ -0,0 +1,22 @@ +// +// AssignmentParentFinder.cpp +// assignment-client/src/ +// +// Created by Seth Alves on 2015-10-22 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "AssignmentParentFinder.h" + +SpatiallyNestableWeakPointer AssignmentParentFinder::find(QUuid parentID) const { + assert(false); + SpatiallyNestableWeakPointer parent; + // search entities + _tree->withReadLock([&] { + parent = _tree->findEntityByEntityItemID(parentID); + }); + return parent; +} diff --git a/assignment-client/src/entities/AssignmentParentFinder.h b/assignment-client/src/entities/AssignmentParentFinder.h new file mode 100644 index 0000000000..4d2e080443 --- /dev/null +++ b/assignment-client/src/entities/AssignmentParentFinder.h @@ -0,0 +1,34 @@ +// +// AssignmentParentFinder.h +// interface/src/ +// +// Created by Seth Alves on 2015-10-21 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_AssignmentParentFinder_h +#define hifi_AssignmentParentFinder_h + +#include +#include + +#include +#include + +// This interface is used to turn a QUuid into a pointer to a "parent" -- something that children can +// be spatially relative to. At this point, this means either an EntityItem or an Avatar. + +class AssignmentParentFinder : public SpatialParentFinder { +public: + AssignmentParentFinder(EntityTreePointer tree) : _tree(tree) { } + virtual ~AssignmentParentFinder() { } + virtual SpatiallyNestableWeakPointer find(QUuid parentID) const; + +protected: + EntityTreePointer _tree; +}; + +#endif // hifi_AssignmentParentFinder_h diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index f2a4c2664a..5c9b120a3a 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -16,6 +16,7 @@ #include "EntityServer.h" #include "EntityServerConsts.h" #include "EntityNodeData.h" +#include "AssignmentParentFinder.h" const char* MODEL_SERVER_NAME = "Entity"; const char* MODEL_SERVER_LOGGING_TARGET_NAME = "entity-server"; @@ -60,6 +61,10 @@ OctreePointer EntityServer::createTree() { tree->setSimulation(simpleSimulation); _entitySimulation = simpleSimulation; } + + DependencyManager::registerInheritance(); + DependencyManager::set(tree); + return tree; } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cab189e7a0..1a02cf912e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -136,6 +136,8 @@ #include "ui/Stats.h" #include "ui/UpdateDialog.h" #include "Util.h" +#include "InterfaceParentFinder.h" + // ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU // FIXME seems to be broken. @@ -286,6 +288,7 @@ bool setupEssentials(int& argc, char** argv) { DependencyManager::registerInheritance(); DependencyManager::registerInheritance(); DependencyManager::registerInheritance(); + DependencyManager::registerInheritance(); Setting::init(); @@ -327,6 +330,7 @@ bool setupEssentials(int& argc, char** argv) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); return true; } diff --git a/interface/src/InterfaceParentFinder.cpp b/interface/src/InterfaceParentFinder.cpp new file mode 100644 index 0000000000..f8604b15d3 --- /dev/null +++ b/interface/src/InterfaceParentFinder.cpp @@ -0,0 +1,35 @@ +// +// InterfaceParentFinder.cpp +// interface/src/ +// +// Created by Seth Alves on 2015-10-21 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include +#include +#include +#include + +#include "InterfaceParentFinder.h" + +SpatiallyNestableWeakPointer InterfaceParentFinder::find(QUuid parentID) const { + SpatiallyNestableWeakPointer parent; + + // search entities + EntityTreeRenderer* treeRenderer = qApp->getEntities(); + EntityTreePointer tree = treeRenderer->getTree(); + tree->withReadLock([&] { + parent = tree->findEntityByEntityItemID(parentID); + }); + if (!parent.expired()) { + return parent; + } + + // search avatars + QSharedPointer avatarManager = DependencyManager::get(); + return avatarManager->getAvatarBySessionID(parentID); +} diff --git a/interface/src/InterfaceParentFinder.h b/interface/src/InterfaceParentFinder.h new file mode 100644 index 0000000000..c8e8d4ed9f --- /dev/null +++ b/interface/src/InterfaceParentFinder.h @@ -0,0 +1,27 @@ +// +// InterfaceParentFinder.h +// interface/src/ +// +// Created by Seth Alves on 2015-10-21 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_InterfaceParentFinder_h +#define hifi_InterfaceParentFinder_h + +#include +#include + +#include + +class InterfaceParentFinder : public SpatialParentFinder { +public: + InterfaceParentFinder() { } + virtual ~InterfaceParentFinder() { } + virtual SpatiallyNestableWeakPointer find(QUuid parentID) const; +}; + +#endif // hifi_InterfaceParentFinder_h diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index c2e6a90ca8..0a47a004fd 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -37,8 +37,8 @@ int EntityItem::_maxActionsDataSize = 800; quint64 EntityItem::_rememberDeletedActionTime = 20 * USECS_PER_SECOND; EntityItem::EntityItem(const EntityItemID& entityItemID) : + SpatiallyNestable(entityItemID), _type(EntityTypes::Unknown), - _id(entityItemID), _lastSimulated(0), _lastUpdated(0), _lastEdited(0), @@ -1723,6 +1723,9 @@ void EntityItem::checkWaitingToRemove(EntitySimulation* simulation) { } void EntityItem::setActionData(QByteArray actionData) { + if (_id == QUuid("32147a6e-976d-44ea-8c33-056c820b4dbd")) { + qDebug() << "EntityItem::setActionData to " << actionData.size() << "bytes."; + } withWriteLock([&] { setActionDataInternal(actionData); }); @@ -1730,8 +1733,16 @@ void EntityItem::setActionData(QByteArray actionData) { void EntityItem::setActionDataInternal(QByteArray actionData) { if (_allActionsDataCache != actionData) { + if (_id == QUuid("32147a6e-976d-44ea-8c33-056c820b4dbd")) { + qDebug() << "EntityItem::setActionDataInternal to " << actionData.size() << "bytes."; + } + _allActionsDataCache = actionData; deserializeActionsInternal(); + } else { + if (_id == QUuid("32147a6e-976d-44ea-8c33-056c820b4dbd")) { + qDebug() << "EntityItem::setActionDataInternal NOT setting to " << actionData.size() << "bytes."; + } } checkWaitingToRemove(); } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 185d052bbd..79fe438c39 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -89,9 +89,6 @@ public: EntityItem(const EntityItemID& entityItemID); virtual ~EntityItem(); - // ID and EntityItemID related methods - const QUuid& getID() const { return _id; } - void setID(const QUuid& id) { _id = id; } EntityItemID getEntityItemID() const { return EntityItemID(_id); } // methods for getting/setting all properties of an entity @@ -399,7 +396,6 @@ protected: static bool _sendPhysicsUpdates; EntityTypes::EntityType _type; - QUuid _id; quint64 _lastSimulated; // last time this entity called simulate(), this includes velocity, angular velocity, // and physics changes quint64 _lastUpdated; // last time this entity called update(), this includes animations and non-physics changes diff --git a/libraries/shared/src/SpatialParentFinder.h b/libraries/shared/src/SpatialParentFinder.h new file mode 100644 index 0000000000..9cadbaf8ce --- /dev/null +++ b/libraries/shared/src/SpatialParentFinder.h @@ -0,0 +1,39 @@ +// +// SpatialParentFinder.h +// libraries/shared/src/ +// +// Created by Seth Alves on 2015-10-18 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_SpatialParentFinder_h +#define hifi_SpatialParentFinder_h + +#include + +#include "DependencyManager.h" + +class SpatiallyNestable; +using SpatiallyNestableWeakPointer = std::weak_ptr; +using SpatiallyNestablePointer = std::shared_ptr; +class SpatialParentFinder; +using SpatialParentFinderPointer = std::shared_ptr; +class SpatialParentFinder : public Dependency { + + + +// This interface is used to turn a QUuid into a pointer to a "parent" -- something that children can +// be spatially relative to. At this point, this means either an EntityItem or an Avatar. + + +public: + SpatialParentFinder() { } + virtual ~SpatialParentFinder() { } + + virtual SpatiallyNestableWeakPointer find(QUuid parentID) const = 0; +}; + +#endif // hifi_SpatialParentFinder_h diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index a3e427caa8..4cdf61061c 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -9,35 +9,84 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "DependencyManager.h" #include "SpatiallyNestable.h" -SpatiallyNestable::SpatiallyNestable() : - _transform() { +Transform SpatiallyNestable::getParentTransform() const { + Transform result; + SpatiallyNestablePointer parent = getParentPointer(); + if (parent) { + Transform parentTransform = parent->getTransform(); + result = parentTransform.setScale(1.0f); + } + return result; } +SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { + SpatiallyNestablePointer parent = _parent.lock(); + + if (!parent && _parentID.isNull()) { + // no parent + return nullptr; + } + + if (parent && parent->getID() == _parentID) { + // parent pointer is up-to-date + return parent; + } + + if (parent && _parentID.isNull()) { + // we have a parent pointer but our _parentID is null + _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(); +} const glm::vec3& SpatiallyNestable::getPosition() const { - return _transform.getTranslation(); + Transform parentTransformDescaled = getParentTransform(); + glm::mat4 parentMat; + parentTransformDescaled.getMatrix(parentMat); + glm::vec4 absPos = parentMat * glm::vec4(getLocalPosition(), 1.0f); + _absolutePositionCache = glm::vec3(absPos); + return _absolutePositionCache; } void SpatiallyNestable::setPosition(const glm::vec3& position) { - _transform.setTranslation(position); + Transform parentTransform = getParentTransform(); + Transform myWorldTransform; + Transform::mult(myWorldTransform, parentTransform, _transform); + myWorldTransform.setTranslation(position); + Transform::inverseMult(_transform, parentTransform, myWorldTransform); } const glm::quat& SpatiallyNestable::getOrientation() const { - return _transform.getRotation(); + Transform parentTransformDescaled = getParentTransform(); + _absoluteRotationCache = parentTransformDescaled.getRotation() * getLocalOrientation(); + return _absoluteRotationCache; } void SpatiallyNestable::setOrientation(const glm::quat& orientation) { - _transform.setRotation(orientation); + Transform parentTransform = getParentTransform(); + Transform myWorldTransform; + Transform::mult(myWorldTransform, parentTransform, _transform); + myWorldTransform.setRotation(orientation); + Transform::inverseMult(_transform, parentTransform, myWorldTransform); } const Transform& SpatiallyNestable::getTransform() const { - return _transform; + Transform parentTransform = getParentTransform(); + Transform::mult(_worldTransformCache, parentTransform, _transform); + return _worldTransformCache; } void SpatiallyNestable::setTransform(const Transform& transform) { - _transform = transform; + Transform parentTransform = getParentTransform(); + Transform::inverseMult(_transform, parentTransform, transform); } const glm::vec3& SpatiallyNestable::getScale() const { @@ -47,3 +96,34 @@ const glm::vec3& SpatiallyNestable::getScale() const { void SpatiallyNestable::setScale(const glm::vec3& scale) { _transform.setScale(scale); } + +const Transform& SpatiallyNestable::getLocalTransform() const { + return _transform; +} + +void SpatiallyNestable::setLocalTransform(const Transform& transform) { +} + +const glm::vec3& SpatiallyNestable::getLocalPosition() const { + return _transform.getTranslation(); +} + +void SpatiallyNestable::setLocalPosition(const glm::vec3& position) { + _transform.setTranslation(position); +} + +const glm::quat& SpatiallyNestable::getLocalOrientation() const { + return _transform.getRotation(); +} + +void SpatiallyNestable::setLocalOrientation(const glm::quat& orientation) { + _transform.setRotation(orientation); +} + +const glm::vec3& SpatiallyNestable::getLocalScale() const { + return _transform.getScale(); +} + +void SpatiallyNestable::setLocalScale(const glm::vec3& scale) { + _transform.setScale(scale); +} diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 294450a980..e3d3b8dc0d 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -15,22 +15,29 @@ #include #include "Transform.h" +#include "SpatialParentFinder.h" class SpatiallyNestable; -typedef std::weak_ptr SpatiallyNestableWeakPointer; -typedef std::shared_ptr SpatiallyNestablePointer; +using SpatiallyNestableWeakPointer = std::weak_ptr; +using SpatiallyNestablePointer = std::shared_ptr; class SpatiallyNestable { public: - SpatiallyNestable(); + SpatiallyNestable() : _transform() { } + SpatiallyNestable(QUuid id) : _id(id), _transform() { } virtual ~SpatiallyNestable() { } + const QUuid& getID() const { return _id; } + void setID(const QUuid& id) { _id = id; } + // world frame virtual const Transform& getTransform() const; virtual void setTransform(const Transform& transform); + Transform getParentTransform() const; + virtual const glm::vec3& getPosition() const; virtual void setPosition(const glm::vec3& position); @@ -40,19 +47,35 @@ public: virtual const glm::vec3& getScale() const; virtual void setScale(const glm::vec3& scale); - // model frame - // ... + // object's parent's frame + virtual const Transform& getLocalTransform() const; + virtual void setLocalTransform(const Transform& transform); + virtual const glm::vec3& getLocalPosition() const; + virtual void setLocalPosition(const glm::vec3& position); + + virtual const glm::quat& getLocalOrientation() const; + virtual void setLocalOrientation(const glm::quat& orientation); + + virtual const glm::vec3& getLocalScale() const; + virtual void setLocalScale(const glm::vec3& scale); protected: + QUuid _id; QUuid _parentID; // what is this thing's transform relative to? int _parentJointIndex; // which joint of the parent is this relative to? - SpatiallyNestableWeakPointer _parent; + mutable SpatiallyNestableWeakPointer _parent; QVector _children; private: - Transform _transform; + Transform _transform; // this is to be combined with parent's world-transform to produce this' world-transform. + SpatiallyNestablePointer getParentPointer() const; + + // these are so we can return by reference + mutable glm::vec3 _absolutePositionCache; + mutable glm::quat _absoluteRotationCache; + mutable Transform _worldTransformCache; }; From 778dc8dc15ddb1831d33c05350fbbc07c0bf62b9 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 22 Oct 2015 11:52:56 -0700 Subject: [PATCH 07/51] add parentID and parentJointIndex EntityItemProperties --- libraries/entities/src/EntityItem.cpp | 12 +++++++++++- libraries/entities/src/EntityItemProperties.cpp | 17 +++++++++++++++-- libraries/entities/src/EntityItemProperties.h | 5 +++++ .../entities/src/EntityItemPropertiesMacros.h | 2 ++ libraries/entities/src/EntityPropertyFlags.h | 3 +++ libraries/networking/src/udt/PacketHeaders.cpp | 3 ++- libraries/networking/src/udt/PacketHeaders.h | 1 + libraries/shared/src/SpatiallyNestable.cpp | 2 ++ libraries/shared/src/SpatiallyNestable.h | 16 +++++++++++----- 9 files changed, 52 insertions(+), 9 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 0a47a004fd..c3c0204aee 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -134,6 +134,8 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param requestedProperties += PROP_HREF; requestedProperties += PROP_DESCRIPTION; requestedProperties += PROP_ACTION_DATA; + requestedProperties += PROP_PARENT_ID; + requestedProperties += PROP_PARENT_JOINT_INDEX; return requestedProperties; } @@ -268,7 +270,8 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet APPEND_ENTITY_PROPERTY(PROP_HREF, getHref()); APPEND_ENTITY_PROPERTY(PROP_DESCRIPTION, getDescription()); APPEND_ENTITY_PROPERTY(PROP_ACTION_DATA, getActionData()); - + APPEND_ENTITY_PROPERTY(PROP_PARENT_ID, getParentID()); + APPEND_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, getParentJointIndex()); appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties, @@ -715,6 +718,9 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef overwriteLocalData = oldOverwrite; } + READ_ENTITY_PROPERTY(PROP_PARENT_ID, QUuid, setParentID); + READ_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, quint16, setParentJointIndex); + bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData, somethingChanged); @@ -1062,6 +1068,8 @@ EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProper COPY_ENTITY_PROPERTY_TO_PROPERTIES(href, getHref); COPY_ENTITY_PROPERTY_TO_PROPERTIES(description, getDescription); COPY_ENTITY_PROPERTY_TO_PROPERTIES(actionData, getActionData); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(parentID, getParentID); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(parentJointIndex, getParentJointIndex); properties._defaultSettings = false; @@ -1124,6 +1132,8 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(href, setHref); SET_ENTITY_PROPERTY_FROM_PROPERTIES(description, setDescription); SET_ENTITY_PROPERTY_FROM_PROPERTIES(actionData, setActionData); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(parentID, setParentID); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(parentJointIndex, setParentJointIndex); if (somethingChanged) { uint64_t now = usecTimestampNow(); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 19c8f779b4..6755149944 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -261,6 +261,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_X_P_NEIGHBOR_ID, xPNeighborID); CHECK_PROPERTY_CHANGE(PROP_Y_P_NEIGHBOR_ID, yPNeighborID); CHECK_PROPERTY_CHANGE(PROP_Z_P_NEIGHBOR_ID, zPNeighborID); + CHECK_PROPERTY_CHANGE(PROP_PARENT_ID, parentID); + CHECK_PROPERTY_CHANGE(PROP_PARENT_JOINT_INDEX, parentJointIndex); changedProperties += _animation.getChangedProperties(); changedProperties += _atmosphere.getChangedProperties(); @@ -467,6 +469,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(originalTextures, textureNamesList); // gettable, but not settable } + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_ID, parentID); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_JOINT_INDEX, parentJointIndex); + // FIXME - I don't think these properties are supported any more //COPY_PROPERTY_TO_QSCRIPTVALUE(glowLevel); //COPY_PROPERTY_TO_QSCRIPTVALUE(localRenderAlpha); @@ -591,6 +596,9 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(yPNeighborID, EntityItemID, setYPNeighborID); COPY_PROPERTY_FROM_QSCRIPTVALUE(zPNeighborID, EntityItemID, setZPNeighborID); + COPY_PROPERTY_FROM_QSCRIPTVALUE(parentID, QUuid, setParentID); + COPY_PROPERTY_FROM_QSCRIPTVALUE(parentJointIndex, quint16, setParentJointIndex); + _lastEdited = usecTimestampNow(); } @@ -906,7 +914,8 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_USER_DATA, properties.getUserData()); APPEND_ENTITY_PROPERTY(PROP_HREF, properties.getHref()); APPEND_ENTITY_PROPERTY(PROP_DESCRIPTION, properties.getDescription()); - + APPEND_ENTITY_PROPERTY(PROP_PARENT_ID, properties.getParentID()); + APPEND_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, properties.getParentJointIndex()); if (properties.getType() == EntityTypes::Web) { APPEND_ENTITY_PROPERTY(PROP_SOURCE_URL, properties.getSourceUrl()); @@ -1191,7 +1200,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_USER_DATA, QString, setUserData); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_HREF, QString, setHref); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DESCRIPTION, QString, setDescription); - + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARENT_ID, QUuid, setParentID); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARENT_JOINT_INDEX, quint16, setParentJointIndex); if (properties.getType() == EntityTypes::Web) { READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SOURCE_URL, QString, setSourceUrl); @@ -1446,6 +1456,9 @@ void EntityItemProperties::markAllChanged() { _xPNeighborIDChanged = true; _yPNeighborIDChanged = true; _zPNeighborIDChanged = true; + + _parentIDChanged = true; + _parentJointIndexChanged = true; } /// The maximum bounding cube for the entity, independent of it's rotation. diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 2227644484..1851e69dd2 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -191,6 +191,8 @@ public: DEFINE_PROPERTY_REF(PROP_X_P_NEIGHBOR_ID, XPNeighborID, xPNeighborID, EntityItemID, UNKNOWN_ENTITY_ID); DEFINE_PROPERTY_REF(PROP_Y_P_NEIGHBOR_ID, YPNeighborID, yPNeighborID, EntityItemID, UNKNOWN_ENTITY_ID); DEFINE_PROPERTY_REF(PROP_Z_P_NEIGHBOR_ID, ZPNeighborID, zPNeighborID, EntityItemID, UNKNOWN_ENTITY_ID); + DEFINE_PROPERTY_REF(PROP_PARENT_ID, ParentID, parentID, QUuid, UNKNOWN_ENTITY_ID); + DEFINE_PROPERTY_REF(PROP_PARENT_JOINT_INDEX, ParentJointIndex, parentJointIndex, quint16, 0); static QString getBackgroundModeString(BackgroundMode mode); @@ -389,6 +391,9 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, YPNeighborID, yPNeighborID, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ZPNeighborID, zPNeighborID, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParentID, parentID, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParentJointIndex, parentJointIndex, ""); + properties.getAnimation().debugDump(); properties.getAtmosphere().debugDump(); properties.getSkybox().debugDump(); diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index b3299b6fe6..ca6bbbbbb8 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -104,6 +104,7 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const glm::vec3& v) { return vec3toScriptValue(e, v); } inline QScriptValue convertScriptValue(QScriptEngine* e, float v) { return QScriptValue(v); } inline QScriptValue convertScriptValue(QScriptEngine* e, int v) { return QScriptValue(v); } +inline QScriptValue convertScriptValue(QScriptEngine* e, quint16 v) { return QScriptValue(v); } inline QScriptValue convertScriptValue(QScriptEngine* e, quint32 v) { return QScriptValue(v); } inline QScriptValue convertScriptValue(QScriptEngine* e, quint64 v) { return QScriptValue((qsreal)v); } inline QScriptValue convertScriptValue(QScriptEngine* e, const QString& v) { return QScriptValue(v); } @@ -179,6 +180,7 @@ inline quint32 quint32_convertFromScriptValue(const QScriptValue& v, bool& isVal // Use QString::toUInt() so that isValid is set to false if the number is outside the quint32 range. return v.toString().toUInt(&isValid); } +inline quint16 quint16_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); } inline uint16_t uint16_t_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); } inline int int_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); } inline bool bool_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return v.toVariant().toBool(); } diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index d70a5c9616..f0087b4803 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -149,6 +149,9 @@ enum EntityPropertyList { PROP_ANIMATION_HOLD, PROP_ANIMATION_START_AUTOMATICALLY, + PROP_PARENT_ID, + PROP_PARENT_JOINT_INDEX, + //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line PROP_AFTER_LAST_ITEM, diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 3c1d33deaf..ca2d03ca2b 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -38,9 +38,10 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: - return VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP; + return VERSION_ENTITIES_HAVE_PARENTS; case PacketType::AvatarData: case PacketType::BulkAvatarData: + return 17; default: return 16; } diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 3654d5b5fa..5f2cbf0193 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -143,5 +143,6 @@ const PacketVersion VERSION_ENTITIES_PROTOCOL_HEADER_SWAP = 43; const PacketVersion VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER = 44; const PacketVersion VERSION_ENTITIES_PROTOCOL_CHANNELS = 45; const PacketVersion VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP = 46; +const PacketVersion VERSION_ENTITIES_HAVE_PARENTS = 47; #endif // hifi_PacketHeaders_h diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 4cdf61061c..870c96a784 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -12,6 +12,8 @@ #include "DependencyManager.h" #include "SpatiallyNestable.h" +// TODO -- make use of parent joint index + Transform SpatiallyNestable::getParentTransform() const { Transform result; SpatiallyNestablePointer parent = getParentPointer(); diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index e3d3b8dc0d..c8bb7c2808 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -25,18 +25,24 @@ using SpatiallyNestablePointer = std::shared_ptr; class SpatiallyNestable { public: - SpatiallyNestable() : _transform() { } + SpatiallyNestable() : _transform() { } // XXX get rid of this one? SpatiallyNestable(QUuid id) : _id(id), _transform() { } virtual ~SpatiallyNestable() { } - const QUuid& getID() const { return _id; } - void setID(const QUuid& id) { _id = id; } + virtual const QUuid& getID() const { return _id; } + virtual void setID(const QUuid& id) { _id = id; } + + virtual const QUuid& getParentID() const { return _parentID; } + virtual void setParentID(const QUuid& parentID) { _parentID = parentID; } + + virtual quint16 getParentJointIndex() const { return _parentJointIndex; } + virtual void setParentJointIndex(quint16 parentJointIndex) { _parentJointIndex = parentJointIndex; } // world frame virtual const Transform& getTransform() const; virtual void setTransform(const Transform& transform); - Transform getParentTransform() const; + virtual Transform getParentTransform() const; virtual const glm::vec3& getPosition() const; virtual void setPosition(const glm::vec3& position); @@ -63,7 +69,7 @@ public: protected: QUuid _id; QUuid _parentID; // what is this thing's transform relative to? - int _parentJointIndex; // which joint of the parent is this relative to? + quint16 _parentJointIndex; // which joint of the parent is this relative to? mutable SpatiallyNestableWeakPointer _parent; QVector _children; From f6fe503c515d636bf4ddc0f66b58c111576a6e03 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 22 Oct 2015 13:44:04 -0700 Subject: [PATCH 08/51] pass avatar parent information through avatar-mixer --- interface/src/avatar/AvatarManager.cpp | 2 +- libraries/avatars/src/AvatarData.cpp | 29 ++++++++++++++++-------- libraries/avatars/src/AvatarData.h | 4 ++-- libraries/shared/src/SpatiallyNestable.h | 2 +- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 16e136f9d1..3d13ef5d02 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -151,7 +151,7 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { while (fadingIterator != _avatarFades.end()) { auto avatar = std::static_pointer_cast(*fadingIterator); avatar->withWriteLock([&] { - avatar->setTargetScale(avatar->getAvatarScale() * SHRINK_RATE, true); + avatar->setTargetScale(avatar->getAvatarScale() * SHRINK_RATE); if (avatar->getTargetScale() < MIN_FADE_SCALE) { avatar->removeFromScene(*fadingIterator, scene, pendingChanges); fadingIterator = _avatarFades.erase(fadingIterator); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 9b2967cf5d..9a6c4b0180 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -135,15 +135,15 @@ float AvatarData::getTargetScale() const { return _targetScale; } -void AvatarData::setTargetScale(float targetScale, bool overideReferential) { +void AvatarData::setTargetScale(float targetScale) { _targetScale = targetScale; } -void AvatarData::setClampedTargetScale(float targetScale, bool overideReferential) { +void AvatarData::setClampedTargetScale(float targetScale) { targetScale = glm::clamp(targetScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE); - setTargetScale(targetScale, overideReferential); + setTargetScale(targetScale); qCDebug(avatars) << "Changed scale to " << _targetScale; } @@ -214,14 +214,18 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { setAtBit(bitItems, IS_EYE_TRACKER_CONNECTED); } // referential state - if (false) { - setAtBit(bitItems, HAS_REFERENTIAL); // XXX leaving this for later use + SpatiallyNestablePointer parent = getParentPointer(); + if (parent) { + setAtBit(bitItems, HAS_REFERENTIAL); } *destinationBuffer++ = bitItems; - // XXX leaving this for later use - if (false) { - // destinationBuffer += _referential->packReferential(destinationBuffer); + if (parent) { + QByteArray referentialAsBytes = parent->getID().toRfc4122(); + memcpy(destinationBuffer, referentialAsBytes.data(), referentialAsBytes.size()); + destinationBuffer += referentialAsBytes.size(); + memcpy(destinationBuffer, &_parentJointIndex, sizeof(_parentJointIndex)); + destinationBuffer += sizeof(_parentJointIndex); } // If it is connected, pack up the data @@ -541,8 +545,15 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { _headData->_isEyeTrackerConnected = oneAtBit(bitItems, IS_EYE_TRACKER_CONNECTED); bool hasReferential = oneAtBit(bitItems, HAS_REFERENTIAL); - // XXX leaving this for later use Referential if (hasReferential) { + const int sizeOfPackedUuid = 16; + QByteArray referentialAsBytes((const char*)sourceBuffer, sizeOfPackedUuid); + _parentID = QUuid::fromRfc4122(referentialAsBytes); + sourceBuffer += sizeOfPackedUuid; + memcpy(&_parentJointIndex, sourceBuffer, sizeof(_parentJointIndex)); + sourceBuffer += sizeof(_parentJointIndex); + } else { + _parentID = QUuid(); } if (_headData->_isFaceTrackerConnected) { diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 9f8224caf8..4f826eafde 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -223,8 +223,8 @@ public: // Scale float getTargetScale() const; - void setTargetScale(float targetScale, bool overideReferential = false); - void setClampedTargetScale(float targetScale, bool overideReferential = false); + void setTargetScale(float targetScale); + void setClampedTargetScale(float targetScale); // Hand State Q_INVOKABLE void setHandState(char s) { _handState = s; } diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index c8bb7c2808..930b096450 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -70,13 +70,13 @@ protected: QUuid _id; 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; private: Transform _transform; // this is to be combined with parent's world-transform to produce this' world-transform. - SpatiallyNestablePointer getParentPointer() const; // these are so we can return by reference mutable glm::vec3 _absolutePositionCache; From d86d69aeba4b72f69d2d0d3f626801bfa4ee0fb6 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 22 Oct 2015 15:36:03 -0700 Subject: [PATCH 09/51] 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; }; From 7b08d047b19598784cfa03c67d67329a6351724a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 22 Oct 2015 16:59:56 -0700 Subject: [PATCH 10/51] when EntityTree::updateEntityWithElement is called on an entity, call it on all the children of that entity --- libraries/avatars/src/AvatarData.cpp | 2 +- libraries/avatars/src/AvatarData.h | 5 +- .../src/BoundingBoxRelatedProperties.cpp | 83 ++++++++++++++ .../src/BoundingBoxRelatedProperties.h | 30 ++++++ libraries/entities/src/EntityItem.cpp | 2 +- libraries/entities/src/EntityTree.cpp | 33 +++++- libraries/entities/src/EntityTypes.h | 4 +- .../entities/src/UpdateEntityOperator.cpp | 101 ++++-------------- libraries/entities/src/UpdateEntityOperator.h | 6 +- libraries/shared/src/SpatiallyNestable.cpp | 24 ++++- libraries/shared/src/SpatiallyNestable.h | 28 +++-- 11 files changed, 213 insertions(+), 105 deletions(-) create mode 100644 libraries/entities/src/BoundingBoxRelatedProperties.cpp create mode 100644 libraries/entities/src/BoundingBoxRelatedProperties.h diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index fc9d9c75a7..a1db573d8d 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -37,7 +37,7 @@ const glm::vec3 DEFAULT_LOCAL_AABOX_CORNER(-0.5f); const glm::vec3 DEFAULT_LOCAL_AABOX_SCALE(1.0f); AvatarData::AvatarData() : - _sessionUUID(), + SpatiallyNestable(NestableTypes::Avatar, QUuid()), _handPosition(0.0f), _targetScale(1.0f), _handState(0), diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 4f826eafde..8a0a9ac38a 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -172,7 +172,7 @@ public: virtual bool isMyAvatar() const { return false; } - const QUuid& getSessionUUID() const { return _sessionUUID; } + const QUuid& getSessionUUID() const { return getID(); } glm::vec3 getHandPosition() const; void setHandPosition(const glm::vec3& handPosition); @@ -327,7 +327,7 @@ public slots: void setBillboardFromNetworkReply(); void setJointMappingsFromNetworkReply(); - void setSessionUUID(const QUuid& sessionUUID) { _sessionUUID = sessionUUID; } + void setSessionUUID(const QUuid& sessionUUID) { setID(sessionUUID); } bool isPlaying(); bool isPaused(); @@ -353,7 +353,6 @@ public slots: void stopPlaying(); protected: - QUuid _sessionUUID; glm::vec3 _handPosition; // Body scale diff --git a/libraries/entities/src/BoundingBoxRelatedProperties.cpp b/libraries/entities/src/BoundingBoxRelatedProperties.cpp new file mode 100644 index 0000000000..e9ee302300 --- /dev/null +++ b/libraries/entities/src/BoundingBoxRelatedProperties.cpp @@ -0,0 +1,83 @@ +// +// BoundingBoxRelatedProperties.cpp +// libraries/entities/src +// +// Created by Seth Alves on 2015-9-24 +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "EntityItemProperties.h" +#include "BoundingBoxRelatedProperties.h" +#include "EntityTree.h" + +BoundingBoxRelatedProperties::BoundingBoxRelatedProperties(EntityItemPointer entity) : + position(entity->getPosition()), + rotation(entity->getRotation()), + registrationPoint(entity->getRegistrationPoint()), + dimensions(entity->getDimensions()), + parentID(entity->getParentID()) { +} + +BoundingBoxRelatedProperties::BoundingBoxRelatedProperties(EntityItemPointer entity, + const EntityItemProperties& propertiesWithUpdates) : + BoundingBoxRelatedProperties(entity) { + + if (propertiesWithUpdates.parentIDChanged()) { + parentID = propertiesWithUpdates.getParentID(); + } + + bool parentFound = false; + if (parentID != UNKNOWN_ENTITY_ID) { + EntityTreePointer tree = entity->getTree(); + EntityItemPointer parentZone = tree->findEntityByID(parentID); + if (parentZone) { + parentFound = true; + glm::vec3 localPosition = propertiesWithUpdates.containsPositionChange() ? + propertiesWithUpdates.getPosition() : + entity->getLocalPosition(); + + glm::quat localRotation = propertiesWithUpdates.rotationChanged() ? + propertiesWithUpdates.getRotation() : + entity->getLocalOrientation(); + + const Transform parentTransform = parentZone->getTransformToCenter(); + Transform parentDescaled(parentTransform.getRotation(), glm::vec3(1.0f), parentTransform.getTranslation()); + + Transform localTransform(localRotation, glm::vec3(1.0f), localPosition); + Transform result; + Transform::mult(result, parentDescaled, localTransform); + position = result.getTranslation(); + rotation = result.getRotation(); + } + } + + if (!parentFound) { + if (propertiesWithUpdates.containsPositionChange()) { + position = propertiesWithUpdates.getPosition(); + } + if (propertiesWithUpdates.rotationChanged()) { + rotation = propertiesWithUpdates.getRotation(); + } + } + + if (propertiesWithUpdates.registrationPointChanged()) { + registrationPoint = propertiesWithUpdates.getRegistrationPoint(); + } + + if (propertiesWithUpdates.dimensionsChanged()) { + dimensions = propertiesWithUpdates.getDimensions(); + } +} + +AACube BoundingBoxRelatedProperties::getMaximumAACube() const { + // see EntityItem::getMaximumAACube for comments which explain the following. + glm::vec3 scaledRegistrationPoint = (dimensions * registrationPoint); + glm::vec3 registrationRemainder = (dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - registrationPoint)); + glm::vec3 furthestExtentFromRegistration = glm::max(scaledRegistrationPoint, registrationRemainder); + float radius = glm::length(furthestExtentFromRegistration); + glm::vec3 minimumCorner = position - glm::vec3(radius, radius, radius); + return AACube(minimumCorner, radius * 2.0f); +} diff --git a/libraries/entities/src/BoundingBoxRelatedProperties.h b/libraries/entities/src/BoundingBoxRelatedProperties.h new file mode 100644 index 0000000000..811c885fd2 --- /dev/null +++ b/libraries/entities/src/BoundingBoxRelatedProperties.h @@ -0,0 +1,30 @@ +// +// BoundingBoxRelatedProperties.h +// libraries/entities/src +// +// Created by Seth Alves on 2015-9-24 +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "EntityItem.h" + +#ifndef hifi_BoundingBoxRelatedProperties_h +#define hifi_BoundingBoxRelatedProperties_h + +class BoundingBoxRelatedProperties { + public: + BoundingBoxRelatedProperties(EntityItemPointer entity); + BoundingBoxRelatedProperties(EntityItemPointer entity, const EntityItemProperties& propertiesWithUpdates); + AACube getMaximumAACube() const; + + glm::vec3 position; + glm::quat rotation; + glm::vec3 registrationPoint; + glm::vec3 dimensions; + EntityItemID parentID; +}; + +#endif // hifi_BoundingBoxRelatedProperties_h diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index f8e191cde1..46d5635fc5 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -37,7 +37,7 @@ int EntityItem::_maxActionsDataSize = 800; quint64 EntityItem::_rememberDeletedActionTime = 20 * USECS_PER_SECOND; EntityItem::EntityItem(const EntityItemID& entityItemID) : - SpatiallyNestable(entityItemID), + SpatiallyNestable(NestableTypes::Entity, entityItemID), _type(EntityTypes::Unknown), _lastSimulated(0), _lastUpdated(0), diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 24c13ae28e..257e3e0ed2 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -143,8 +143,11 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI if (!wantsLocked) { EntityItemProperties tempProperties; tempProperties.setLocked(wantsLocked); - UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, tempProperties); + + BoundingBoxRelatedProperties newBBRelProperties(entity, tempProperties); + UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, newBBRelProperties); recurseTreeWithOperator(&theOperator); + entity->setProperties(tempProperties); _isDirty = true; } } @@ -205,8 +208,34 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI quint64 entityScriptTimestampBefore = entity->getScriptTimestamp(); QString collisionSoundURLBefore = entity->getCollisionSoundURL(); uint32_t preFlags = entity->getDirtyFlags(); - UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, properties); + + BoundingBoxRelatedProperties newBBRelProperties(entity, properties); + UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, newBBRelProperties); recurseTreeWithOperator(&theOperator); + entity->setProperties(properties); + + // if the entity has children, run UpdateEntityOperator on them. If the children have children, recurse + QQueue toProcess; + foreach (SpatiallyNestablePointer child, entity->getChildren()) { + if (child && child->getNestableType() == NestableTypes::Entity) { + toProcess.enqueue(child); + } + } + + while (!toProcess.empty()) { + EntityItemPointer childEntity = std::static_pointer_cast(toProcess.dequeue()); + BoundingBoxRelatedProperties newChildBBRelProperties(childEntity); + UpdateEntityOperator theChildOperator(getThisPointer(), + childEntity->getElement(), + childEntity, newChildBBRelProperties); + recurseTreeWithOperator(&theChildOperator); + foreach (SpatiallyNestablePointer childChild, childEntity->getChildren()) { + if (childChild && childChild->getNestableType() == NestableTypes::Entity) { + toProcess.enqueue(childChild); + } + } + } + _isDirty = true; uint32_t newFlags = entity->getDirtyFlags() & ~preFlags; diff --git a/libraries/entities/src/EntityTypes.h b/libraries/entities/src/EntityTypes.h index 30b6edbc07..3536327d18 100644 --- a/libraries/entities/src/EntityTypes.h +++ b/libraries/entities/src/EntityTypes.h @@ -20,8 +20,8 @@ #include // for RenderArgs class EntityItem; -typedef std::shared_ptr EntityItemPointer; -typedef std::weak_ptr EntityItemWeakPointer; +using EntityItemPointer = std::shared_ptr; +using EntityItemWeakPointer = std::weak_ptr; inline uint qHash(const EntityItemPointer& a, uint seed) { return qHash(a.get(), seed); diff --git a/libraries/entities/src/UpdateEntityOperator.cpp b/libraries/entities/src/UpdateEntityOperator.cpp index 617663f48a..4acc386333 100644 --- a/libraries/entities/src/UpdateEntityOperator.cpp +++ b/libraries/entities/src/UpdateEntityOperator.cpp @@ -14,12 +14,12 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTreePointer tree, EntityTreeElementPointer containingElement, EntityItemPointer existingEntity, - const EntityItemProperties& properties) : + const BoundingBoxRelatedProperties& newProperties) : _tree(tree), _existingEntity(existingEntity), _containingElement(containingElement), _containingElementCube(containingElement->getAACube()), - _properties(properties), + _newProperties(newProperties), _entityItemID(existingEntity->getEntityItemID()), _foundOld(false), _foundNew(false), @@ -44,83 +44,32 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTreePointer tree, _oldEntityCube = _existingEntity->getMaximumAACube(); _oldEntityBox = _oldEntityCube.clamp((float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); // clamp to domain bounds - // If the old properties doesn't contain the properties required to calculate a bounding box, - // get them from the existing entity. Registration point is required to correctly calculate - // the bounding box. - if (!_properties.registrationPointChanged()) { - _properties.setRegistrationPoint(_existingEntity->getRegistrationPoint()); - } - - // If the new properties has position OR dimension changes, but not both, we need to - // get the old property value and set it in our properties in order for our bounds - // calculations to work. - if (_properties.containsPositionChange() && !_properties.containsDimensionsChange()) { - glm::vec3 oldDimensions= _existingEntity->getDimensions(); - _properties.setDimensions(oldDimensions); - - if (_wantDebug) { - qCDebug(entities) << " ** setting properties dimensions - had position change, no dimension change **"; - } - - } - if (!_properties.containsPositionChange() && _properties.containsDimensionsChange()) { - glm::vec3 oldPosition= _existingEntity->getPosition(); - _properties.setPosition(oldPosition); - - if (_wantDebug) { - qCDebug(entities) << " ** setting properties position - had dimensions change, no position change **"; - } - } - - // If our new properties don't have bounds details (no change to position, etc) or if this containing element would - // be the best fit for our new properties, then just do the new portion of the store pass, since the change path will + // If our new properties don't have bounds details (no change to position, etc) or if this containing element would + // be the best fit for our new properties, then just do the new portion of the store pass, since the change path will // be the same for both parts of the update - bool oldElementBestFit = _containingElement->bestFitBounds(_properties); - - // if we don't have bounds properties, then use our old clamped box to determine best fit - if (!_properties.containsBoundsProperties()) { - oldElementBestFit = _containingElement->bestFitBounds(_oldEntityBox); + bool oldElementBestFit = _containingElement->bestFitBounds(newProperties.getMaximumAACube()); - if (_wantDebug) { - qCDebug(entities) << " ** old Element best fit - no dimensions change, no position change **"; - } - - } - // For some reason we've seen a case where the original containing element isn't a best fit for the old properties // in this case we want to move it, even if the properties haven't changed. - if (!_properties.containsBoundsProperties() && !oldElementBestFit) { + if (!oldElementBestFit) { _newEntityCube = _oldEntityCube; _removeOld = true; // our properties are going to move us, so remember this for later processing if (_wantDebug) { qCDebug(entities) << " **** UNUSUAL CASE **** no changes, but not best fit... consider it a move.... **"; } - - - } else if (!_properties.containsBoundsProperties() || oldElementBestFit) { + } else { _foundOld = true; _newEntityCube = _oldEntityCube; _dontMove = true; if (_wantDebug) { - qCDebug(entities) << " **** TYPICAL NO MOVE CASE ****"; - qCDebug(entities) << " _properties.containsBoundsProperties():" << _properties.containsBoundsProperties(); - qCDebug(entities) << " oldElementBestFit:" << oldElementBestFit; - } - - } else { - _newEntityCube = _properties.getMaximumAACube(); - _removeOld = true; // our properties are going to move us, so remember this for later processing - - if (_wantDebug) { - qCDebug(entities) << " **** TYPICAL MOVE CASE ****"; + qCDebug(entities) << " **** TYPICAL NO MOVE CASE **** oldElementBestFit:" << oldElementBestFit; } } _newEntityBox = _newEntityCube.clamp((float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); // clamp to domain bounds - if (_wantDebug) { qCDebug(entities) << " _entityItemID:" << _entityItemID; qCDebug(entities) << " _containingElementCube:" << _containingElementCube; @@ -176,7 +125,7 @@ bool UpdateEntityOperator::subTreeContainsNewEntity(OctreeElementPointer element bool UpdateEntityOperator::preRecursion(OctreeElementPointer element) { EntityTreeElementPointer entityTreeElement = std::static_pointer_cast(element); - + // In Pre-recursion, we're generally deciding whether or not we want to recurse this // path of the tree. For this operation, we want to recurse the branch of the tree if // and of the following are true: @@ -185,7 +134,7 @@ bool UpdateEntityOperator::preRecursion(OctreeElementPointer element) { // // Note: it's often the case that the branch in question contains both the old entity // and the new entity. - + bool keepSearching = false; // assume we don't need to search any more bool subtreeContainsOld = subTreeContainsOldEntity(element); @@ -257,7 +206,8 @@ bool UpdateEntityOperator::preRecursion(OctreeElementPointer element) { qCDebug(entities) << " NEW TREE CASE...."; qCDebug(entities) << " entityTreeElement=" << entityTreeElement.get(); qCDebug(entities) << " _containingElement=" << _containingElement.get(); - qCDebug(entities) << " entityTreeElement->bestFitBounds(_newEntityBox)=" << entityTreeElement->bestFitBounds(_newEntityBox); + qCDebug(entities) << " entityTreeElement->bestFitBounds(_newEntityBox)=" + << entityTreeElement->bestFitBounds(_newEntityBox); } // If this element is the best fit for the new entity properties, then add/or update it @@ -270,16 +220,9 @@ bool UpdateEntityOperator::preRecursion(OctreeElementPointer element) { EntityTreeElementPointer oldElement = _existingEntity->getElement(); // if we are the existing containing element, then we can just do the update of the entity properties if (entityTreeElement == oldElement) { - if (_wantDebug) { qCDebug(entities) << " *** This is the same OLD ELEMENT ***"; } - - // set the entity properties and mark our element as changed. - _existingEntity->setProperties(_properties); - if (_wantDebug) { - qCDebug(entities) << " *** set properties ***"; - } } else { // otherwise, this is an add case. if (oldElement) { @@ -290,11 +233,6 @@ bool UpdateEntityOperator::preRecursion(OctreeElementPointer element) { } entityTreeElement->addEntityItem(_existingEntity); _tree->setContainingElement(_entityItemID, entityTreeElement); - - _existingEntity->setProperties(_properties); // still need to update the properties! - if (_wantDebug) { - qCDebug(entities) << " *** ADDING ENTITY to ELEMENT and MAP and SETTING PROPERTIES ***"; - } } _foundNew = true; // we found the new element _removeOld = false; // and it has already been removed from the old @@ -308,7 +246,6 @@ bool UpdateEntityOperator::preRecursion(OctreeElementPointer element) { qCDebug(entities) << "--------------------------------------------------"; } - return keepSearching; // if we haven't yet found it, keep looking } @@ -329,9 +266,9 @@ bool UpdateEntityOperator::postRecursion(OctreeElementPointer element) { } // It's not OK to prune if we have the potential of deleting the original containig element. - // because if we prune the containing element then new might end up reallocating the same memory later + // because if we prune the containing element then new might end up reallocating the same memory later // and that will confuse our logic. - // + // // it's ok to prune if: // 1) we're not removing the old // 2) we are removing the old, but this subtree doesn't contain the old @@ -340,17 +277,17 @@ bool UpdateEntityOperator::postRecursion(OctreeElementPointer element) { EntityTreeElementPointer entityTreeElement = std::static_pointer_cast(element); entityTreeElement->pruneChildren(); // take this opportunity to prune any empty leaves } - + return keepSearching; // if we haven't yet found it, keep looking } -OctreeElementPointer UpdateEntityOperator::possiblyCreateChildAt(OctreeElementPointer element, int childIndex) { +OctreeElementPointer UpdateEntityOperator::possiblyCreateChildAt(OctreeElementPointer element, int childIndex) { // If we're getting called, it's because there was no child element at this index while recursing. // We only care if this happens while still searching for the new entity location. - // Check to see if + // Check to see if if (!_foundNew) { float childElementScale = element->getScale() / 2.0f; // all of our children will be half our scale - + // Note: because the entity's bounds might have been clamped to the domain. We want to check if the // bounds of the clamped box would fit in our child elements. It may be the case that the actual // bounds of the element would hang outside of the child elements cells. @@ -365,5 +302,5 @@ OctreeElementPointer UpdateEntityOperator::possiblyCreateChildAt(OctreeElementPo } } } - return NULL; + return NULL; } diff --git a/libraries/entities/src/UpdateEntityOperator.h b/libraries/entities/src/UpdateEntityOperator.h index 46322997f7..aac442d415 100644 --- a/libraries/entities/src/UpdateEntityOperator.h +++ b/libraries/entities/src/UpdateEntityOperator.h @@ -12,6 +12,7 @@ #ifndef hifi_UpdateEntityOperator_h #define hifi_UpdateEntityOperator_h +#include "BoundingBoxRelatedProperties.h" #include "EntitiesLogging.h" #include "EntityItem.h" #include "EntityItemProperties.h" @@ -21,7 +22,8 @@ class UpdateEntityOperator : public RecurseOctreeOperator { public: UpdateEntityOperator(EntityTreePointer tree, EntityTreeElementPointer containingElement, - EntityItemPointer existingEntity, const EntityItemProperties& properties); + EntityItemPointer existingEntity, const BoundingBoxRelatedProperties& newProperties); + ~UpdateEntityOperator(); virtual bool preRecursion(OctreeElementPointer element); @@ -32,7 +34,7 @@ private: EntityItemPointer _existingEntity; EntityTreeElementPointer _containingElement; AACube _containingElementCube; // we temporarily store our cube here in case we need to delete the containing element - EntityItemProperties _properties; + BoundingBoxRelatedProperties _newProperties; EntityItemID _entityItemID; bool _foundOld; bool _foundNew; diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index b3723cf3b7..a813a37bfe 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -32,10 +32,13 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { return nullptr; } + SpatiallyNestableConstPointer constThisPointer = shared_from_this(); + SpatiallyNestablePointer thisPointer = std::const_pointer_cast(constThisPointer); // ermahgerd !!! + if (parent && parent->getID() == _parentID) { // parent pointer is up-to-date if (!_parentKnowsMe) { - parent->beParentOfChild(shared_from_this()); + parent->beParentOfChild(thisPointer); _parentKnowsMe = true; } return parent; @@ -43,7 +46,7 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { if (parent) { // we have a parent pointer but our _parentID doesn't indicate this parent. - parent->forgetChild(shared_from_this()); + parent->forgetChild(thisPointer); _parentKnowsMe = false; _parent.reset(); } @@ -53,17 +56,17 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { _parent = parentFinder->find(_parentID); parent = _parent.lock(); if (parent) { - parent->beParentOfChild(shared_from_this()); + parent->beParentOfChild(thisPointer); _parentKnowsMe = true; } return parent; } -void SpatiallyNestable::beParentOfChild(SpatiallyNestableConstPointer newChild) const { +void SpatiallyNestable::beParentOfChild(SpatiallyNestablePointer newChild) const { _children[newChild->getID()] = newChild; } -void SpatiallyNestable::forgetChild(SpatiallyNestableConstPointer newChild) const { +void SpatiallyNestable::forgetChild(SpatiallyNestablePointer newChild) const { _children.remove(newChild->getID()); } @@ -153,3 +156,14 @@ const glm::vec3& SpatiallyNestable::getLocalScale() const { void SpatiallyNestable::setLocalScale(const glm::vec3& scale) { _transform.setScale(scale); } + +QList SpatiallyNestable::getChildren() const { + QList children; + foreach (SpatiallyNestableWeakPointer childWP, _children.values()) { + SpatiallyNestablePointer child = childWP.lock(); + if (child) { + children << child; + } + } + return children; +} diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 7ba5493340..e0ee5bdb74 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -24,11 +24,21 @@ using SpatiallyNestableWeakConstPointer = std::weak_ptr using SpatiallyNestablePointer = std::shared_ptr; using SpatiallyNestableConstPointer = std::shared_ptr; -class SpatiallyNestable : public std::enable_shared_from_this { - +class NestableTypes { public: - SpatiallyNestable() : _transform() { } // XXX get rid of this one? - SpatiallyNestable(QUuid id) : _id(id), _transform() { } + using NestableType = enum NestableType_t { + Entity, + Avatar + }; +}; + +class SpatiallyNestable : public std::enable_shared_from_this { +public: + // SpatiallyNestable() : _transform() { } // XXX get rid of this one? + SpatiallyNestable(NestableTypes::NestableType nestableType, QUuid id) : + _nestableType(nestableType), + _id(id), + _transform() { } virtual ~SpatiallyNestable() { } virtual const QUuid& getID() const { return _id; } @@ -68,16 +78,20 @@ public: virtual const glm::vec3& getLocalScale() const; virtual void setLocalScale(const glm::vec3& scale); + QList getChildren() const; + NestableTypes::NestableType getNestableType() const { return _nestableType; } + protected: + NestableTypes::NestableType _nestableType; // EntityItem or an AvatarData QUuid _id; 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; - virtual void beParentOfChild(SpatiallyNestableConstPointer newChild) const; - virtual void forgetChild(SpatiallyNestableConstPointer newChild) const; - mutable QHash _children; + virtual void beParentOfChild(SpatiallyNestablePointer newChild) const; + virtual void forgetChild(SpatiallyNestablePointer newChild) const; + mutable QHash _children; private: Transform _transform; // this is to be combined with parent's world-transform to produce this' world-transform. From bf290c35be4ce5ff2c188d601785ad26ee27f24e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 23 Oct 2015 09:46:57 -0700 Subject: [PATCH 11/51] when an entity gets a physics flag set, set the same flag in any children --- libraries/entities/src/EntityItem.cpp | 47 +++++++++++++++++++++------ libraries/entities/src/EntityItem.h | 2 ++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 46d5635fc5..7c9f3139df 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1309,17 +1309,40 @@ void EntityItem::computeShapeInfo(ShapeInfo& info) { info.setParams(getShapeType(), 0.5f * getDimensions()); } +bool EntityItem::forSelfAndEachChildEntity(std::function actor) { + bool result = true; + QQueue toProcess; + toProcess.enqueue(shared_from_this()); + + while (!toProcess.empty()) { + EntityItemPointer entity = std::static_pointer_cast(toProcess.dequeue()); + + result &= actor(entity); + + foreach (SpatiallyNestablePointer child, entity->getChildren()) { + if (child && child->getNestableType() == NestableTypes::Entity) { + toProcess.enqueue(child); + } + } + } + + return result; +} + void EntityItem::updatePosition(const glm::vec3& value) { if (shouldSuppressLocationEdits()) { return; } auto delta = glm::distance(getLocalPosition(), value); if (delta > IGNORE_POSITION_DELTA) { - _dirtyFlags |= Simulation::DIRTY_POSITION; setLocalPosition(value); - if (delta > ACTIVATION_POSITION_DELTA) { - _dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION; - } + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + entity->_dirtyFlags |= Simulation::DIRTY_POSITION; + if (delta > ACTIVATION_POSITION_DELTA) { + entity->_dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION; + } + return true; + }); } } @@ -1342,12 +1365,16 @@ void EntityItem::updateRotation(const glm::quat& rotation) { setRotation(rotation); auto alignmentDot = glm::abs(glm::dot(getRotation(), rotation)); - if (alignmentDot < IGNORE_ALIGNMENT_DOT) { - _dirtyFlags |= Simulation::DIRTY_ROTATION; - } - if (alignmentDot < ACTIVATION_ALIGNMENT_DOT) { - _dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION; - } + + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + if (alignmentDot < IGNORE_ALIGNMENT_DOT) { + entity->_dirtyFlags |= Simulation::DIRTY_ROTATION; + } + if (alignmentDot < ACTIVATION_ALIGNMENT_DOT) { + entity->_dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION; + } + return true; + }); } } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 7d6de20a5c..6e03e52679 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -396,6 +396,8 @@ protected: const QByteArray getActionDataInternal() const; void setActionDataInternal(QByteArray actionData); + bool forSelfAndEachChildEntity(std::function actor); + static bool _sendPhysicsUpdates; EntityTypes::EntityType _type; quint64 _lastSimulated; // last time this entity called simulate(), this includes velocity, angular velocity, From 22af5b27abe9012e2d1cfa6fb6ef69b2377603fb Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 23 Oct 2015 12:55:48 -0700 Subject: [PATCH 12/51] avoid shared_from_this while constructing --- libraries/avatars/src/AvatarData.cpp | 1 + libraries/entities/src/EntityItem.cpp | 1 + libraries/shared/src/SpatiallyNestable.cpp | 5 +++++ libraries/shared/src/SpatiallyNestable.h | 2 ++ 4 files changed, 9 insertions(+) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index a1db573d8d..7f0f758b87 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -60,6 +60,7 @@ AvatarData::AvatarData() : setBodyPitch(0.0f); setBodyYaw(-90.0f); setBodyRoll(0.0f); + _constructing = false; } AvatarData::~AvatarData() { diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 7c9f3139df..fd4a4b298c 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -85,6 +85,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) : quint64 now = usecTimestampNow(); _lastSimulated = now; _lastUpdated = now; + _constructing = false; } EntityItem::~EntityItem() { diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index a813a37bfe..9d1220c214 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -32,6 +32,11 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { return nullptr; } + if (_constructing) { + // we can't use shared_from_this yet, so stop here. + return nullptr; + } + SpatiallyNestableConstPointer constThisPointer = shared_from_this(); SpatiallyNestablePointer thisPointer = std::const_pointer_cast(constThisPointer); // ermahgerd !!! diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index e0ee5bdb74..108da796a0 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -82,6 +82,8 @@ public: NestableTypes::NestableType getNestableType() const { return _nestableType; } protected: + bool _constructing = true; + NestableTypes::NestableType _nestableType; // EntityItem or an AvatarData QUuid _id; QUuid _parentID; // what is this thing's transform relative to? From 61269c3ce837b30cfcd389849832045a9d55e05f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 23 Oct 2015 13:52:50 -0700 Subject: [PATCH 13/51] fix up entity constructors so that setProperties isn't called during the constructor --- libraries/avatars/src/AvatarData.cpp | 1 - .../src/RenderableBoxEntityItem.cpp | 4 +++- .../src/RenderableBoxEntityItem.h | 5 +--- .../src/RenderableLightEntityItem.cpp | 4 +++- .../src/RenderableLightEntityItem.h | 5 +--- .../src/RenderableLineEntityItem.cpp | 4 +++- .../src/RenderableLineEntityItem.h | 5 ++-- .../src/RenderableModelEntityItem.cpp | 13 ++++++----- .../src/RenderableModelEntityItem.h | 2 +- .../RenderableParticleEffectEntityItem.cpp | 12 ++++++---- .../src/RenderableParticleEffectEntityItem.h | 2 +- .../src/RenderablePolyLineEntityItem.cpp | 10 ++++---- .../src/RenderablePolyLineEntityItem.h | 2 +- .../src/RenderablePolyVoxEntityItem.cpp | 9 ++++---- .../src/RenderablePolyVoxEntityItem.h | 3 +-- .../src/RenderableSphereEntityItem.cpp | 4 +++- .../src/RenderableSphereEntityItem.h | 5 +--- .../src/RenderableTextEntityItem.cpp | 4 +++- .../src/RenderableTextEntityItem.h | 5 +--- .../src/RenderableWebEntityItem.cpp | 8 ++++--- .../src/RenderableWebEntityItem.h | 3 +-- .../src/RenderableZoneEntityItem.cpp | 4 +++- .../src/RenderableZoneEntityItem.h | 8 +++---- libraries/entities/src/BoxEntityItem.cpp | 10 ++++---- libraries/entities/src/BoxEntityItem.h | 2 +- libraries/entities/src/EntityItem.cpp | 1 - libraries/entities/src/LightEntityItem.cpp | 13 ++++------- libraries/entities/src/LightEntityItem.h | 2 +- libraries/entities/src/LineEntityItem.cpp | 12 ++++------ libraries/entities/src/LineEntityItem.h | 2 +- libraries/entities/src/ModelEntityItem.cpp | 8 +++---- libraries/entities/src/ModelEntityItem.h | 2 +- .../entities/src/ParticleEffectEntityItem.cpp | 11 ++++----- .../entities/src/ParticleEffectEntityItem.h | 2 +- libraries/entities/src/PolyLineEntityItem.cpp | 23 +++++++++---------- libraries/entities/src/PolyLineEntityItem.h | 2 +- libraries/entities/src/PolyVoxEntityItem.cpp | 7 +++--- libraries/entities/src/PolyVoxEntityItem.h | 2 +- libraries/entities/src/SphereEntityItem.cpp | 10 ++++---- libraries/entities/src/SphereEntityItem.h | 2 +- libraries/entities/src/TextEntityItem.cpp | 9 ++++---- libraries/entities/src/TextEntityItem.h | 2 +- libraries/entities/src/WebEntityItem.cpp | 9 ++++---- libraries/entities/src/WebEntityItem.h | 2 +- libraries/entities/src/ZoneEntityItem.cpp | 10 ++++---- libraries/entities/src/ZoneEntityItem.h | 2 +- libraries/shared/src/SpatiallyNestable.cpp | 5 ---- libraries/shared/src/SpatiallyNestable.h | 2 -- 48 files changed, 127 insertions(+), 147 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 7f0f758b87..a1db573d8d 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -60,7 +60,6 @@ AvatarData::AvatarData() : setBodyPitch(0.0f); setBodyYaw(-90.0f); setBodyRoll(0.0f); - _constructing = false; } AvatarData::~AvatarData() { diff --git a/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp b/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp index 077f28350b..702b691342 100644 --- a/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp @@ -25,7 +25,9 @@ #include "../render-utils/simple_frag.h" EntityItemPointer RenderableBoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); + EntityItemPointer entity{ new RenderableBoxEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } void RenderableBoxEntityItem::setUserData(const QString& value) { diff --git a/libraries/entities-renderer/src/RenderableBoxEntityItem.h b/libraries/entities-renderer/src/RenderableBoxEntityItem.h index 838022c7d4..9addfd813a 100644 --- a/libraries/entities-renderer/src/RenderableBoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderableBoxEntityItem.h @@ -20,10 +20,7 @@ class RenderableBoxEntityItem : public BoxEntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - - RenderableBoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - BoxEntityItem(entityItemID, properties) - { } + RenderableBoxEntityItem(const EntityItemID& entityItemID) : BoxEntityItem(entityItemID) { } virtual void render(RenderArgs* args); virtual void setUserData(const QString& value); diff --git a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp index b0cc0462c6..5b8891d1f2 100644 --- a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp @@ -20,7 +20,9 @@ #include "RenderableLightEntityItem.h" EntityItemPointer RenderableLightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); + EntityItemPointer entity{ new RenderableLightEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } void RenderableLightEntityItem::render(RenderArgs* args) { diff --git a/libraries/entities-renderer/src/RenderableLightEntityItem.h b/libraries/entities-renderer/src/RenderableLightEntityItem.h index ecf24eaec7..aac1a4a998 100644 --- a/libraries/entities-renderer/src/RenderableLightEntityItem.h +++ b/libraries/entities-renderer/src/RenderableLightEntityItem.h @@ -18,10 +18,7 @@ class RenderableLightEntityItem : public LightEntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - - RenderableLightEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - LightEntityItem(entityItemID, properties) - { } + RenderableLightEntityItem(const EntityItemID& entityItemID) : LightEntityItem(entityItemID) { } virtual void render(RenderArgs* args); virtual bool supportsDetailedRayIntersection() const { return true; } diff --git a/libraries/entities-renderer/src/RenderableLineEntityItem.cpp b/libraries/entities-renderer/src/RenderableLineEntityItem.cpp index 3735690c33..1c9c50af55 100644 --- a/libraries/entities-renderer/src/RenderableLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableLineEntityItem.cpp @@ -20,7 +20,9 @@ #include "RenderableLineEntityItem.h" EntityItemPointer RenderableLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); + EntityItemPointer entity{ new RenderableLineEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } void RenderableLineEntityItem::updateGeometry() { diff --git a/libraries/entities-renderer/src/RenderableLineEntityItem.h b/libraries/entities-renderer/src/RenderableLineEntityItem.h index 09f98ca364..058cab2c4b 100644 --- a/libraries/entities-renderer/src/RenderableLineEntityItem.h +++ b/libraries/entities-renderer/src/RenderableLineEntityItem.h @@ -20,9 +20,8 @@ class RenderableLineEntityItem : public LineEntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - - RenderableLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - LineEntityItem(entityItemID, properties), + RenderableLineEntityItem(const EntityItemID& entityItemID) : + LineEntityItem(entityItemID), _lineVerticesID(GeometryCache::UNKNOWN_ID) { } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index e604bdb925..d2f16de936 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -24,13 +24,14 @@ #include "RenderableModelEntityItem.h" EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); + EntityItemPointer entity{ new RenderableModelEntityItem(entityID, properties.getDimensionsInitialized()) }; + entity->setProperties(properties); + return entity; } -RenderableModelEntityItem::RenderableModelEntityItem(const EntityItemID& entityItemID, - const EntityItemProperties& properties) : - ModelEntityItem(entityItemID, properties), - _dimensionsInitialized(properties.getDimensionsInitialized()) -{ + +RenderableModelEntityItem::RenderableModelEntityItem(const EntityItemID& entityItemID, bool dimensionsInitialized) : + ModelEntityItem(entityItemID), + _dimensionsInitialized(dimensionsInitialized) { } RenderableModelEntityItem::~RenderableModelEntityItem() { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 4dc1cced48..77c7f71ae9 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -25,7 +25,7 @@ class RenderableModelEntityItem : public ModelEntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - RenderableModelEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + RenderableModelEntityItem(const EntityItemID& entityItemID, bool dimensionsInitialized); virtual ~RenderableModelEntityItem(); diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index a0bb582d58..0ce6b49a5c 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -117,13 +117,15 @@ namespace render { gpu::PipelinePointer RenderableParticleEffectEntityItem::_texturedPipeline; gpu::PipelinePointer RenderableParticleEffectEntityItem::_untexturedPipeline; -EntityItemPointer RenderableParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); +EntityItemPointer RenderableParticleEffectEntityItem::factory(const EntityItemID& entityID, + const EntityItemProperties& properties) { + EntityItemPointer entity{ new RenderableParticleEffectEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } -RenderableParticleEffectEntityItem::RenderableParticleEffectEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - ParticleEffectEntityItem(entityItemID, properties) { - +RenderableParticleEffectEntityItem::RenderableParticleEffectEntityItem(const EntityItemID& entityItemID) : + ParticleEffectEntityItem(entityItemID) { // lazy creation of particle system pipeline if (!_untexturedPipeline && !_texturedPipeline) { createPipelines(); diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h index 5d69d19026..5ff6c3ff92 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h @@ -19,7 +19,7 @@ class RenderableParticleEffectEntityItem : public ParticleEffectEntityItem { friend class ParticlePayload; public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - RenderableParticleEffectEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + RenderableParticleEffectEntityItem(const EntityItemID& entityItemID); virtual void update(const quint64& now) override; diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index 572b24e99f..c5f5e9d55a 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -23,15 +23,15 @@ #include "paintStroke_frag.h" - EntityItemPointer RenderablePolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return EntityItemPointer(new RenderablePolyLineEntityItem(entityID, properties)); + EntityItemPointer entity{ new RenderablePolyLineEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } -RenderablePolyLineEntityItem::RenderablePolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : -PolyLineEntityItem(entityItemID, properties) { +RenderablePolyLineEntityItem::RenderablePolyLineEntityItem(const EntityItemID& entityItemID) : + PolyLineEntityItem(entityItemID) { _numVertices = 0; - } gpu::PipelinePointer RenderablePolyLineEntityItem::_pipeline; diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h index 59bf416d7a..f803e4c520 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h @@ -25,7 +25,7 @@ class RenderablePolyLineEntityItem : public PolyLineEntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); static void createPipeline(); - RenderablePolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + RenderablePolyLineEntityItem(const EntityItemID& entityItemID); virtual void render(RenderArgs* args); diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 3ce3717dfb..d9f1832339 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -49,12 +49,13 @@ gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipeline = nullptr; const float MARCHING_CUBE_COLLISION_HULL_OFFSET = 0.5; EntityItemPointer RenderablePolyVoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); + EntityItemPointer entity{ new RenderablePolyVoxEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } -RenderablePolyVoxEntityItem::RenderablePolyVoxEntityItem(const EntityItemID& entityItemID, - const EntityItemProperties& properties) : - PolyVoxEntityItem(entityItemID, properties), +RenderablePolyVoxEntityItem::RenderablePolyVoxEntityItem(const EntityItemID& entityItemID) : + PolyVoxEntityItem(entityItemID), _mesh(new model::Mesh()), _meshDirty(true), _xTexture(nullptr), diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index ef44ba5ab0..4068b09e13 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -45,8 +45,7 @@ namespace render { class RenderablePolyVoxEntityItem : public PolyVoxEntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - - RenderablePolyVoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + RenderablePolyVoxEntityItem(const EntityItemID& entityItemID); virtual ~RenderablePolyVoxEntityItem(); diff --git a/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp b/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp index 246cd2fea7..705a9a4d26 100644 --- a/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp @@ -30,7 +30,9 @@ static const float SPHERE_ENTITY_SCALE = 0.5f; EntityItemPointer RenderableSphereEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); + EntityItemPointer entity{ new RenderableSphereEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } void RenderableSphereEntityItem::setUserData(const QString& value) { diff --git a/libraries/entities-renderer/src/RenderableSphereEntityItem.h b/libraries/entities-renderer/src/RenderableSphereEntityItem.h index 293ae79029..737bee3134 100644 --- a/libraries/entities-renderer/src/RenderableSphereEntityItem.h +++ b/libraries/entities-renderer/src/RenderableSphereEntityItem.h @@ -20,10 +20,7 @@ class RenderableSphereEntityItem : public SphereEntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - - RenderableSphereEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - SphereEntityItem(entityItemID, properties) - { } + RenderableSphereEntityItem(const EntityItemID& entityItemID) : SphereEntityItem(entityItemID) { } virtual void render(RenderArgs* args); virtual void setUserData(const QString& value); diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index d87f89ba41..bdf3b5b97c 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -22,7 +22,9 @@ #include "GLMHelpers.h" EntityItemPointer RenderableTextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); + EntityItemPointer entity{ new RenderableTextEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } void RenderableTextEntityItem::render(RenderArgs* args) { diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.h b/libraries/entities-renderer/src/RenderableTextEntityItem.h index de1d745875..149df946f7 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.h +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.h @@ -22,10 +22,7 @@ const int FIXED_FONT_POINT_SIZE = 40; class RenderableTextEntityItem : public TextEntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - - RenderableTextEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - TextEntityItem(entityItemID, properties) - { } + RenderableTextEntityItem(const EntityItemID& entityItemID) : TextEntityItem(entityItemID) { } ~RenderableTextEntityItem() { delete _textRenderer; } virtual void render(RenderArgs* args); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 84707aca3b..943de1aa76 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -31,11 +31,13 @@ const float DPI = 30.47f; const float METERS_TO_INCHES = 39.3701f; EntityItemPointer RenderableWebEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); + EntityItemPointer entity{ new RenderableWebEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } -RenderableWebEntityItem::RenderableWebEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - WebEntityItem(entityItemID, properties) { +RenderableWebEntityItem::RenderableWebEntityItem(const EntityItemID& entityItemID) : + WebEntityItem(entityItemID) { qDebug() << "Created web entity " << getID(); } diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.h b/libraries/entities-renderer/src/RenderableWebEntityItem.h index 63418a890f..2266401b5d 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.h +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.h @@ -22,8 +22,7 @@ class QObject; class RenderableWebEntityItem : public WebEntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - - RenderableWebEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + RenderableWebEntityItem(const EntityItemID& entityItemID); ~RenderableWebEntityItem(); virtual void render(RenderArgs* args); diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index ff56bef46b..7dfefb9097 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -24,7 +24,9 @@ static const float SPHERE_ENTITY_SCALE = 0.5f; EntityItemPointer RenderableZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); + EntityItemPointer entity{ new RenderableZoneEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } template diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index 92de136df6..36555dbc45 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -21,10 +21,10 @@ class RenderableZoneEntityItem : public ZoneEntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - RenderableZoneEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - ZoneEntityItem(entityItemID, properties), - _model(NULL), - _needsInitialSimulation(true) + RenderableZoneEntityItem(const EntityItemID& entityItemID) : + ZoneEntityItem(entityItemID), + _model(NULL), + _needsInitialSimulation(true) { } virtual bool setProperties(const EntityItemProperties& properties); diff --git a/libraries/entities/src/BoxEntityItem.cpp b/libraries/entities/src/BoxEntityItem.cpp index 70d5ba0c4f..061c5b3854 100644 --- a/libraries/entities/src/BoxEntityItem.cpp +++ b/libraries/entities/src/BoxEntityItem.cpp @@ -21,15 +21,13 @@ #include "EntityTreeElement.h" EntityItemPointer BoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - EntityItemPointer result { new BoxEntityItem(entityID, properties) }; - return result; + EntityItemPointer entity { new BoxEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } -BoxEntityItem::BoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - EntityItem(entityItemID) -{ +BoxEntityItem::BoxEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) { _type = EntityTypes::Box; - setProperties(properties); } EntityItemProperties BoxEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { diff --git a/libraries/entities/src/BoxEntityItem.h b/libraries/entities/src/BoxEntityItem.h index 6c1b5b2312..351feb7e54 100644 --- a/libraries/entities/src/BoxEntityItem.h +++ b/libraries/entities/src/BoxEntityItem.h @@ -18,7 +18,7 @@ class BoxEntityItem : public EntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - BoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + BoxEntityItem(const EntityItemID& entityItemID); ALLOW_INSTANTIATION // This class can be instantiated diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index fd4a4b298c..7c9f3139df 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -85,7 +85,6 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) : quint64 now = usecTimestampNow(); _lastSimulated = now; _lastUpdated = now; - _constructing = false; } EntityItem::~EntityItem() { diff --git a/libraries/entities/src/LightEntityItem.cpp b/libraries/entities/src/LightEntityItem.cpp index fd3f674c5e..ac56fc9c1f 100644 --- a/libraries/entities/src/LightEntityItem.cpp +++ b/libraries/entities/src/LightEntityItem.cpp @@ -24,23 +24,20 @@ bool LightEntityItem::_lightsArePickable = false; EntityItemPointer LightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - EntityItemPointer result { new LightEntityItem(entityID, properties) }; - return result; + EntityItemPointer entity { new LightEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } // our non-pure virtual subclass for now... -LightEntityItem::LightEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - EntityItem(entityItemID) -{ +LightEntityItem::LightEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) { _type = EntityTypes::Light; - + // default property values _color[RED_INDEX] = _color[GREEN_INDEX] = _color[BLUE_INDEX] = 0; _intensity = 1.0f; _exponent = 0.0f; _cutoff = PI; - - setProperties(properties); } void LightEntityItem::setDimensions(const glm::vec3& value) { diff --git a/libraries/entities/src/LightEntityItem.h b/libraries/entities/src/LightEntityItem.h index 9f8d340852..103c462809 100644 --- a/libraries/entities/src/LightEntityItem.h +++ b/libraries/entities/src/LightEntityItem.h @@ -18,7 +18,7 @@ class LightEntityItem : public EntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - LightEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + LightEntityItem(const EntityItemID& entityItemID); ALLOW_INSTANTIATION // This class can be instantiated diff --git a/libraries/entities/src/LineEntityItem.cpp b/libraries/entities/src/LineEntityItem.cpp index e03d3a7a96..d48780845f 100644 --- a/libraries/entities/src/LineEntityItem.cpp +++ b/libraries/entities/src/LineEntityItem.cpp @@ -26,20 +26,18 @@ const int LineEntityItem::MAX_POINTS_PER_LINE = 70; EntityItemPointer LineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - EntityItemPointer result { new LineEntityItem(entityID, properties) }; - return result; + EntityItemPointer entity { new LineEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } -LineEntityItem::LineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - EntityItem(entityItemID) , +LineEntityItem::LineEntityItem(const EntityItemID& entityItemID) : + EntityItem(entityItemID), _lineWidth(DEFAULT_LINE_WIDTH), _pointsChanged(true), _points(QVector(0)) { _type = EntityTypes::Line; - setProperties(properties); - - } EntityItemProperties LineEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { diff --git a/libraries/entities/src/LineEntityItem.h b/libraries/entities/src/LineEntityItem.h index b20587637f..4d63562cf7 100644 --- a/libraries/entities/src/LineEntityItem.h +++ b/libraries/entities/src/LineEntityItem.h @@ -18,7 +18,7 @@ class LineEntityItem : public EntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - LineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + LineEntityItem(const EntityItemID& entityItemID); ALLOW_INSTANTIATION // This class can be instantiated diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index b4adde7467..eefe873b74 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -25,17 +25,17 @@ const QString ModelEntityItem::DEFAULT_MODEL_URL = QString(""); const QString ModelEntityItem::DEFAULT_COMPOUND_SHAPE_URL = QString(""); EntityItemPointer ModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); + EntityItemPointer entity { new ModelEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } -ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - EntityItem(entityItemID) +ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) { _animationProperties.associateWithAnimationLoop(&_animationLoop); _animationLoop.setResetOnRunning(false); _type = EntityTypes::Model; - setProperties(properties); _jointMappingCompleted = false; _lastKnownCurrentFrame = -1; _color[0] = _color[1] = _color[2] = 0; diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index e8ffcab3e7..8a49759921 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -21,7 +21,7 @@ class ModelEntityItem : public EntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - ModelEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + ModelEntityItem(const EntityItemID& entityItemID); ALLOW_INSTANTIATION // This class can be instantiated diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index ddd79375b3..1cd53c87f4 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -97,11 +97,13 @@ const QString ParticleEffectEntityItem::DEFAULT_TEXTURES = ""; EntityItemPointer ParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); + EntityItemPointer entity { new ParticleEffectEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } // our non-pure virtual subclass for now... -ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : +ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID), _lastSimulated(usecTimestampNow()), _particleLifetimes(DEFAULT_MAX_PARTICLES, 0.0f), @@ -121,12 +123,9 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _alphaMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _alphaFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _particleMaxBound(glm::vec3(1.0f, 1.0f, 1.0f)), - _particleMinBound(glm::vec3(-1.0f, -1.0f, -1.0f)) -{ - + _particleMinBound(glm::vec3(-1.0f, -1.0f, -1.0f)) { _type = EntityTypes::ParticleEffect; setColor(DEFAULT_COLOR); - setProperties(properties); } ParticleEffectEntityItem::~ParticleEffectEntityItem() { diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 029d65cfc0..be2204a321 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -20,7 +20,7 @@ public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - ParticleEffectEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + ParticleEffectEntityItem(const EntityItemID& entityItemID); virtual ~ParticleEffectEntityItem(); ALLOW_INSTANTIATION // This class can be instantiated diff --git a/libraries/entities/src/PolyLineEntityItem.cpp b/libraries/entities/src/PolyLineEntityItem.cpp index f1be431ce8..82ee0e1269 100644 --- a/libraries/entities/src/PolyLineEntityItem.cpp +++ b/libraries/entities/src/PolyLineEntityItem.cpp @@ -26,22 +26,21 @@ const int PolyLineEntityItem::MAX_POINTS_PER_LINE = 70; EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - EntityItemPointer result{ new PolyLineEntityItem(entityID, properties) }; - return result; + EntityItemPointer entity{ new PolyLineEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } -PolyLineEntityItem::PolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : -EntityItem(entityItemID), -_lineWidth(DEFAULT_LINE_WIDTH), -_pointsChanged(true), -_points(QVector(0.0f)), -_vertices(QVector(0.0f)), -_normals(QVector(0.0f)), -_strokeWidths(QVector(0.0f)) +PolyLineEntityItem::PolyLineEntityItem(const EntityItemID& entityItemID) : + EntityItem(entityItemID), + _lineWidth(DEFAULT_LINE_WIDTH), + _pointsChanged(true), + _points(QVector(0.0f)), + _vertices(QVector(0.0f)), + _normals(QVector(0.0f)), + _strokeWidths(QVector(0.0f)) { _type = EntityTypes::PolyLine; - _created = properties.getCreated(); - setProperties(properties); } EntityItemProperties PolyLineEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { diff --git a/libraries/entities/src/PolyLineEntityItem.h b/libraries/entities/src/PolyLineEntityItem.h index 86a1dfb6e0..9608bd9b44 100644 --- a/libraries/entities/src/PolyLineEntityItem.h +++ b/libraries/entities/src/PolyLineEntityItem.h @@ -18,7 +18,7 @@ class PolyLineEntityItem : public EntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - PolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + PolyLineEntityItem(const EntityItemID& entityItemID); ALLOW_INSTANTIATION // This class can be instantiated diff --git a/libraries/entities/src/PolyVoxEntityItem.cpp b/libraries/entities/src/PolyVoxEntityItem.cpp index 403d0bb1bc..9b85938a78 100644 --- a/libraries/entities/src/PolyVoxEntityItem.cpp +++ b/libraries/entities/src/PolyVoxEntityItem.cpp @@ -32,7 +32,9 @@ const QString PolyVoxEntityItem::DEFAULT_Y_TEXTURE_URL = QString(""); const QString PolyVoxEntityItem::DEFAULT_Z_TEXTURE_URL = QString(""); EntityItemPointer PolyVoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); + EntityItemPointer entity { new PolyVoxEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } QByteArray PolyVoxEntityItem::makeEmptyVoxelData(quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize) { @@ -49,7 +51,7 @@ QByteArray PolyVoxEntityItem::makeEmptyVoxelData(quint16 voxelXSize, quint16 vox return newVoxelData; } -PolyVoxEntityItem::PolyVoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : +PolyVoxEntityItem::PolyVoxEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID), _voxelVolumeSize(PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE), _voxelData(PolyVoxEntityItem::DEFAULT_VOXEL_DATA), @@ -59,7 +61,6 @@ PolyVoxEntityItem::PolyVoxEntityItem(const EntityItemID& entityItemID, const Ent _yTextureURL(PolyVoxEntityItem::DEFAULT_Y_TEXTURE_URL), _zTextureURL(PolyVoxEntityItem::DEFAULT_Z_TEXTURE_URL) { _type = EntityTypes::PolyVox; - setProperties(properties); } void PolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) { diff --git a/libraries/entities/src/PolyVoxEntityItem.h b/libraries/entities/src/PolyVoxEntityItem.h index 9070ad250f..13e541d298 100644 --- a/libraries/entities/src/PolyVoxEntityItem.h +++ b/libraries/entities/src/PolyVoxEntityItem.h @@ -18,7 +18,7 @@ class PolyVoxEntityItem : public EntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - PolyVoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + PolyVoxEntityItem(const EntityItemID& entityItemID); ALLOW_INSTANTIATION // This class can be instantiated diff --git a/libraries/entities/src/SphereEntityItem.cpp b/libraries/entities/src/SphereEntityItem.cpp index 26177f89de..841b70aa56 100644 --- a/libraries/entities/src/SphereEntityItem.cpp +++ b/libraries/entities/src/SphereEntityItem.cpp @@ -24,16 +24,14 @@ #include "SphereEntityItem.h" EntityItemPointer SphereEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - EntityItemPointer result { new SphereEntityItem(entityID, properties) }; - return result; + EntityItemPointer entity { new SphereEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } // our non-pure virtual subclass for now... -SphereEntityItem::SphereEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - EntityItem(entityItemID) -{ +SphereEntityItem::SphereEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) { _type = EntityTypes::Sphere; - setProperties(properties); _volumeMultiplier *= PI / 6.0f; } diff --git a/libraries/entities/src/SphereEntityItem.h b/libraries/entities/src/SphereEntityItem.h index e1e31d4839..941d5a167c 100644 --- a/libraries/entities/src/SphereEntityItem.h +++ b/libraries/entities/src/SphereEntityItem.h @@ -18,7 +18,7 @@ class SphereEntityItem : public EntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - SphereEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + SphereEntityItem(const EntityItemID& entityItemID); ALLOW_INSTANTIATION // This class can be instantiated diff --git a/libraries/entities/src/TextEntityItem.cpp b/libraries/entities/src/TextEntityItem.cpp index 49d3c13d80..893329d1ce 100644 --- a/libraries/entities/src/TextEntityItem.cpp +++ b/libraries/entities/src/TextEntityItem.cpp @@ -30,14 +30,13 @@ const xColor TextEntityItem::DEFAULT_BACKGROUND_COLOR = { 0, 0, 0}; const bool TextEntityItem::DEFAULT_FACE_CAMERA = false; EntityItemPointer TextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); + EntityItemPointer entity { new TextEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } -TextEntityItem::TextEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - EntityItem(entityItemID) -{ +TextEntityItem::TextEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) { _type = EntityTypes::Text; - setProperties(properties); } const float TEXT_ENTITY_ITEM_FIXED_DEPTH = 0.01f; diff --git a/libraries/entities/src/TextEntityItem.h b/libraries/entities/src/TextEntityItem.h index d205e9d01e..1caceee085 100644 --- a/libraries/entities/src/TextEntityItem.h +++ b/libraries/entities/src/TextEntityItem.h @@ -18,7 +18,7 @@ class TextEntityItem : public EntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - TextEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + TextEntityItem(const EntityItemID& entityItemID); ALLOW_INSTANTIATION // This class can be instantiated diff --git a/libraries/entities/src/WebEntityItem.cpp b/libraries/entities/src/WebEntityItem.cpp index 56f8357c8f..5f113f1de4 100644 --- a/libraries/entities/src/WebEntityItem.cpp +++ b/libraries/entities/src/WebEntityItem.cpp @@ -23,14 +23,13 @@ const QString WebEntityItem::DEFAULT_SOURCE_URL("http://www.google.com"); EntityItemPointer WebEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); + EntityItemPointer entity { new WebEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } -WebEntityItem::WebEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - EntityItem(entityItemID) -{ +WebEntityItem::WebEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) { _type = EntityTypes::Web; - setProperties(properties); } const float WEB_ENTITY_ITEM_FIXED_DEPTH = 0.01f; diff --git a/libraries/entities/src/WebEntityItem.h b/libraries/entities/src/WebEntityItem.h index 425d89de76..8e9d924cde 100644 --- a/libraries/entities/src/WebEntityItem.h +++ b/libraries/entities/src/WebEntityItem.h @@ -17,7 +17,7 @@ public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - WebEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + WebEntityItem(const EntityItemID& entityItemID); ALLOW_INSTANTIATION // This class can be instantiated diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index 3147af35e8..bc74c47e54 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -31,12 +31,12 @@ const ShapeType ZoneEntityItem::DEFAULT_SHAPE_TYPE = SHAPE_TYPE_BOX; const QString ZoneEntityItem::DEFAULT_COMPOUND_SHAPE_URL = ""; EntityItemPointer ZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return std::make_shared(entityID, properties); + EntityItemPointer entity { new ZoneEntityItem(entityID) }; + entity->setProperties(properties); + return entity; } -ZoneEntityItem::ZoneEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - EntityItem(entityItemID) -{ +ZoneEntityItem::ZoneEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) { _type = EntityTypes::Zone; _keyLightColor[RED_INDEX] = DEFAULT_KEYLIGHT_COLOR.red; @@ -50,8 +50,6 @@ ZoneEntityItem::ZoneEntityItem(const EntityItemID& entityItemID, const EntityIte _compoundShapeURL = DEFAULT_COMPOUND_SHAPE_URL; _backgroundMode = BACKGROUND_MODE_INHERIT; - - setProperties(properties); } diff --git a/libraries/entities/src/ZoneEntityItem.h b/libraries/entities/src/ZoneEntityItem.h index e7f2e03981..8a1f8022fc 100644 --- a/libraries/entities/src/ZoneEntityItem.h +++ b/libraries/entities/src/ZoneEntityItem.h @@ -24,7 +24,7 @@ class ZoneEntityItem : public EntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); - ZoneEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + ZoneEntityItem(const EntityItemID& entityItemID); ALLOW_INSTANTIATION // This class can be instantiated diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 9d1220c214..a813a37bfe 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -32,11 +32,6 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { return nullptr; } - if (_constructing) { - // we can't use shared_from_this yet, so stop here. - return nullptr; - } - SpatiallyNestableConstPointer constThisPointer = shared_from_this(); SpatiallyNestablePointer thisPointer = std::const_pointer_cast(constThisPointer); // ermahgerd !!! diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 108da796a0..e0ee5bdb74 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -82,8 +82,6 @@ public: NestableTypes::NestableType getNestableType() const { return _nestableType; } protected: - bool _constructing = true; - NestableTypes::NestableType _nestableType; // EntityItem or an AvatarData QUuid _id; QUuid _parentID; // what is this thing's transform relative to? From f3c61a823e1064d7bfec23f6f56a3605875fb617 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 23 Oct 2015 16:58:09 -0700 Subject: [PATCH 14/51] try harder to get children flags right when something moves. added worldToLocal methods --- libraries/entities/src/EntityItem.cpp | 99 ++++++++++++++------- libraries/entities/src/EntityItem.h | 21 ++--- libraries/physics/src/EntityMotionState.cpp | 4 +- libraries/shared/src/SpatiallyNestable.cpp | 31 +++++++ libraries/shared/src/SpatiallyNestable.h | 9 +- 5 files changed, 114 insertions(+), 50 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 7c9f3139df..2dee8a9d44 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -79,8 +79,6 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) : _simulated(false) { // explicitly set transform parts to set dirty flags used by batch rendering - setPosition(ENTITY_ITEM_DEFAULT_POSITION); - setRotation(ENTITY_ITEM_DEFAULT_ROTATION); setScale(ENTITY_ITEM_DEFAULT_DIMENSIONS); quint64 now = usecTimestampNow(); _lastSimulated = now; @@ -1309,24 +1307,19 @@ void EntityItem::computeShapeInfo(ShapeInfo& info) { info.setParams(getShapeType(), 0.5f * getDimensions()); } -bool EntityItem::forSelfAndEachChildEntity(std::function actor) { - bool result = true; +void EntityItem::forSelfAndEachChildEntity(std::function actor) { QQueue toProcess; toProcess.enqueue(shared_from_this()); while (!toProcess.empty()) { EntityItemPointer entity = std::static_pointer_cast(toProcess.dequeue()); - - result &= actor(entity); - + actor(entity); foreach (SpatiallyNestablePointer child, entity->getChildren()) { if (child && child->getNestableType() == NestableTypes::Entity) { toProcess.enqueue(child); } } } - - return result; } void EntityItem::updatePosition(const glm::vec3& value) { @@ -1336,16 +1329,76 @@ void EntityItem::updatePosition(const glm::vec3& value) { auto delta = glm::distance(getLocalPosition(), value); if (delta > IGNORE_POSITION_DELTA) { setLocalPosition(value); + if (delta > ACTIVATION_POSITION_DELTA) { + _dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION; + } forSelfAndEachChildEntity([&](EntityItemPointer entity) { entity->_dirtyFlags |= Simulation::DIRTY_POSITION; - if (delta > ACTIVATION_POSITION_DELTA) { - entity->_dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION; - } - return true; }); } } +void EntityItem::setTransform(const Transform& transform) { + SpatiallyNestable::setTransform(transform); + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + entity->requiresRecalcBoxes(); + }); +} + +void EntityItem::setLocalTransform(const Transform& transform) { + SpatiallyNestable::setLocalTransform(transform); + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + entity->requiresRecalcBoxes(); + }); +} + +void EntityItem::setPosition(const glm::vec3& position) { + SpatiallyNestable::setPosition(position); + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + entity->requiresRecalcBoxes(); + }); +} + +void EntityItem::setLocalPosition(const glm::vec3& position) { + SpatiallyNestable::setLocalPosition(position); + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + entity->requiresRecalcBoxes(); + }); +} + +void EntityItem::updateRotation(const glm::quat& rotation) { + if (shouldSuppressLocationEdits()) { + return; + } + if (getRotation() != rotation) { + auto alignmentDot = glm::abs(glm::dot(getRotation(), rotation)); + setRotation(rotation); + if (alignmentDot < ACTIVATION_ALIGNMENT_DOT) { + _dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION; + } + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + if (alignmentDot < IGNORE_ALIGNMENT_DOT) { + entity->_dirtyFlags |= Simulation::DIRTY_ROTATION; + } + entity->requiresRecalcBoxes(); + }); + } +} + +void EntityItem::setRotation(const glm::quat& orientation) { + SpatiallyNestable::setOrientation(orientation); + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + entity->requiresRecalcBoxes(); + }); +} + +void EntityItem::setLocalRotation(const glm::quat& orientation) { + SpatiallyNestable::setLocalOrientation(orientation); + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + entity->requiresRecalcBoxes(); + }); +} + void EntityItem::updateDimensions(const glm::vec3& value) { auto delta = glm::distance(getDimensions(), value); if (delta > IGNORE_DIMENSIONS_DELTA) { @@ -1357,26 +1410,6 @@ void EntityItem::updateDimensions(const glm::vec3& value) { } } -void EntityItem::updateRotation(const glm::quat& rotation) { - if (shouldSuppressLocationEdits()) { - return; - } - if (getRotation() != rotation) { - setRotation(rotation); - - auto alignmentDot = glm::abs(glm::dot(getRotation(), rotation)); - - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - if (alignmentDot < IGNORE_ALIGNMENT_DOT) { - entity->_dirtyFlags |= Simulation::DIRTY_ROTATION; - } - if (alignmentDot < ACTIVATION_ALIGNMENT_DOT) { - entity->_dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION; - } - return true; - }); - } -} void EntityItem::updateMass(float mass) { // Setting the mass actually changes the _density (at fixed volume), however diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 6e03e52679..ffcf24854d 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -183,15 +183,6 @@ public: const Transform getTransformToCenter() const; void setTranformToCenter(const Transform& transform); - virtual void setTransform(const Transform& transform) { SpatiallyNestable::setTransform(transform); requiresRecalcBoxes(); } - - /// Position in meters (-TREE_SCALE - TREE_SCALE) - virtual const glm::vec3& getPosition() const { return SpatiallyNestable::getPosition(); } - virtual void setPosition(const glm::vec3& value) { SpatiallyNestable::setPosition(value); requiresRecalcBoxes(); } - - virtual const glm::quat& getRotation() const { return SpatiallyNestable::getOrientation(); } - virtual void setRotation(const glm::quat& rotation) { SpatiallyNestable::setOrientation(rotation); requiresRecalcBoxes(); } - inline void requiresRecalcBoxes() { _recalcAABox = true; _recalcMinAACube = true; _recalcMaxAACube = true; } // Hyperlink related getters and setters @@ -330,6 +321,16 @@ public: /// return preferred shape type (actual physical shape may differ) virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; } + virtual void setTransform(const Transform& transform); + virtual void setLocalTransform(const Transform& transform); + // virtual const glm::vec3& getPosition() const { return SpatiallyNestable::getPosition(); } + virtual const glm::quat& getRotation() const { return SpatiallyNestable::getOrientation(); } + + virtual void setPosition(const glm::vec3& position); + virtual void setLocalPosition(const glm::vec3& position); + virtual void setRotation(const glm::quat& orientation); + virtual void setLocalRotation(const glm::quat& orientation); + // updateFoo() methods to be used when changes need to be accumulated in the _dirtyFlags void updatePosition(const glm::vec3& value); void updateDimensions(const glm::vec3& value); @@ -396,7 +397,7 @@ protected: const QByteArray getActionDataInternal() const; void setActionDataInternal(QByteArray actionData); - bool forSelfAndEachChildEntity(std::function actor); + void forSelfAndEachChildEntity(std::function actor); static bool _sendPhysicsUpdates; EntityTypes::EntityType _type; diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 6832b8daff..98d0bb245e 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -445,8 +445,8 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q EntityItemProperties properties; // explicitly set the properties that changed so that they will be packed - properties.setPosition(_serverPosition); - properties.setRotation(_serverRotation); + properties.setPosition(_entity->worldToLocal(_serverPosition)); + properties.setRotation(_entity->worldToLocal(_serverRotation)); properties.setVelocity(_serverVelocity); properties.setAcceleration(_serverAcceleration); properties.setAngularVelocity(_serverAngularVelocity); diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index a813a37bfe..300d9a5728 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -14,6 +14,16 @@ // TODO -- make use of parent joint index + +SpatiallyNestable::SpatiallyNestable(NestableTypes::NestableType nestableType, QUuid id) : + _nestableType(nestableType), + _id(id), + _transform() { + // set flags in _transform + _transform.setTranslation(glm::vec3(0.0f)); + _transform.setRotation(glm::quat()); +} + Transform SpatiallyNestable::getParentTransform() const { Transform result; SpatiallyNestablePointer parent = getParentPointer(); @@ -76,6 +86,26 @@ void SpatiallyNestable::setParentID(const QUuid& parentID) { _parentKnowsMe = false; } +glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position) { + Transform parentTransform = getParentTransform(); + Transform myWorldTransform; + Transform::mult(myWorldTransform, parentTransform, _transform); + myWorldTransform.setTranslation(position); + Transform result; + Transform::inverseMult(result, parentTransform, myWorldTransform); + return result.getTranslation(); +} + +glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation) { + Transform parentTransform = getParentTransform(); + Transform myWorldTransform; + Transform::mult(myWorldTransform, parentTransform, _transform); + myWorldTransform.setRotation(orientation); + Transform result; + Transform::inverseMult(result, parentTransform, myWorldTransform); + return result.getRotation(); +} + const glm::vec3& SpatiallyNestable::getPosition() const { Transform parentTransformDescaled = getParentTransform(); glm::mat4 parentMat; @@ -131,6 +161,7 @@ const Transform& SpatiallyNestable::getLocalTransform() const { } void SpatiallyNestable::setLocalTransform(const Transform& transform) { + _transform = transform; } const glm::vec3& SpatiallyNestable::getLocalPosition() const { diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index e0ee5bdb74..986a282891 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -34,11 +34,7 @@ public: class SpatiallyNestable : public std::enable_shared_from_this { public: - // SpatiallyNestable() : _transform() { } // XXX get rid of this one? - SpatiallyNestable(NestableTypes::NestableType nestableType, QUuid id) : - _nestableType(nestableType), - _id(id), - _transform() { } + SpatiallyNestable(NestableTypes::NestableType nestableType, QUuid id); virtual ~SpatiallyNestable() { } virtual const QUuid& getID() const { return _id; } @@ -50,6 +46,9 @@ 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); + // world frame virtual const Transform& getTransform() const; virtual void setTransform(const Transform& transform); From f60b1d9bd7c7f64fc9a23ca958667906c0d7d47a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 3 Nov 2015 13:50:35 -0800 Subject: [PATCH 15/51] unmangle merge --- libraries/entities/src/EntityItem.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index ba82bc230d..a4f4ed6512 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1861,7 +1861,6 @@ const QByteArray EntityItem::getActionDataInternal() const { const QByteArray EntityItem::getActionData() const { QByteArray result; - assertUnlocked(); if (_actionDataDirty) { withWriteLock([&] { From 60824a1fb013dc3a2eb839aef5272d8456a7b670 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 3 Nov 2015 16:07:28 -0800 Subject: [PATCH 16/51] back out some off-brand changes. add parentChanged call --- interface/src/Application.cpp | 142 ++++++++++----------- interface/src/avatar/Avatar.cpp | 32 ++--- interface/src/avatar/AvatarManager.cpp | 26 ++-- interface/src/avatar/AvatarUpdate.cpp | 11 +- libraries/avatars/src/AvatarData.cpp | 55 ++++++-- libraries/avatars/src/AvatarData.h | 18 ++- libraries/entities/src/EntityItem.cpp | 11 -- libraries/shared/src/SpatiallyNestable.cpp | 14 +- libraries/shared/src/SpatiallyNestable.h | 2 + 9 files changed, 178 insertions(+), 133 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e1ba4a8163..e9c2e0ccb1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1128,77 +1128,75 @@ void Application::paintGL() { { PerformanceTimer perfTimer("CameraUpdates"); + auto myAvatar = getMyAvatar(); - myAvatar->withReadLock([&] { - if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, - myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); - Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, - !(myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); - cameraMenuChanged(); - } + + myAvatar->startCapture(); + if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); + Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); + cameraMenuChanged(); + } - // The render mode is default or mirror if the camera is in mirror mode, assigned further below - renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; + // The render mode is default or mirror if the camera is in mirror mode, assigned further below + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; - // Always use the default eye position, not the actual head eye position. - // Using the latter will cause the camera to wobble with idle animations, - // or with changes from the face tracker - if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { - if (isHMDMode()) { - mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setPosition(extractTranslation(camMat)); - _myCamera.setRotation(glm::quat_cast(camMat)); - } else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition()); - _myCamera.setRotation(myAvatar->getHead()->getCameraOrientation()); - } - } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - if (isHMDMode()) { - auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setRotation(glm::normalize(glm::quat_cast(hmdWorldMat))); - auto worldBoomOffset = myAvatar->getOrientation() * - (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f)); - _myCamera.setPosition(extractTranslation(hmdWorldMat) + worldBoomOffset); - } else { - _myCamera.setRotation(myAvatar->getHead()->getOrientation()); - if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + _myCamera.getRotation() * - (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); - } else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + myAvatar->getOrientation() * - (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); - } - } - } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - if (isHMDMode()) { - glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() - * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)) * hmdRotation); - glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0) - + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror - + (myAvatar->getOrientation() * - glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))) * hmdOffset); - } else { - _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() - * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0) - + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); - } - renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; + // Always use the default eye position, not the actual head eye position. + // Using the latter will cause the camera to wobble with idle animations, + // or with changes from the face tracker + if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { + if (isHMDMode()) { + mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setPosition(extractTranslation(camMat)); + _myCamera.setRotation(glm::quat_cast(camMat)); + } else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition()); + _myCamera.setRotation(myAvatar->getHead()->getCameraOrientation()); } - // Update camera position - if (!isHMDMode()) { - _myCamera.update(1.0f / _fps); + } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + if (isHMDMode()) { + auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setRotation(glm::normalize(glm::quat_cast(hmdWorldMat))); + auto worldBoomOffset = myAvatar->getOrientation() * (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f)); + _myCamera.setPosition(extractTranslation(hmdWorldMat) + worldBoomOffset); + } else { + _myCamera.setRotation(myAvatar->getHead()->getOrientation()); + if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + _myCamera.getRotation() + * (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); + } else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + myAvatar->getOrientation() + * (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); + } } - }); + } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { + if (isHMDMode()) { + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() + * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)) * hmdRotation); + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0) + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))) * hmdOffset); + } else { + _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() + * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getAvatarScale(), 0) + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + } + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; + } + // Update camera position + if (!isHMDMode()) { + _myCamera.update(1.0f / _fps); + } + myAvatar->endCapture(); } // Primary rendering pass @@ -3454,9 +3452,9 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se // FIXME: This preRender call is temporary until we create a separate render::scene for the mirror rendering. // Then we can move this logic into the Avatar::simulate call. auto myAvatar = getMyAvatar(); - myAvatar->withReadLock([&] { - myAvatar->preRender(renderArgs); - }); + myAvatar->startRender(); + myAvatar->preRender(renderArgs); + myAvatar->endRender(); activeRenderingThread = QThread::currentThread(); @@ -3570,9 +3568,9 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se _renderEngine->setRenderContext(renderContext); // Before the deferred pass, let's try to use the render engine - myAvatar->withReadLock([&] { - _renderEngine->run(); - }); + myAvatar->startRenderRun(); + _renderEngine->run(); + myAvatar->endRenderRun(); auto engineRC = _renderEngine->getRenderContext(); sceneInterface->setEngineFeedOpaqueItems(engineRC->_numFeedOpaqueItems); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 4ffa1ffc7c..b6a6ae001d 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -377,6 +377,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { } if (frustum->sphereInFrustum(getPosition(), boundingRadius) == ViewFrustum::OUTSIDE) { + endRender(); return; } @@ -535,6 +536,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { renderDisplayName(batch, frustum, textPosition); } } + endRender(); } glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { @@ -1011,25 +1013,23 @@ void Avatar::setBillboard(const QByteArray& billboard) { } int Avatar::parseDataFromBuffer(const QByteArray& buffer) { - int bytesRead; + startUpdate(); + if (!_initialized) { + // now that we have data for this Avatar we are go for init + init(); + } - withWriteLock([&] { - if (!_initialized) { - // now that we have data for this Avatar we are go for init - init(); - } + // change in position implies movement + glm::vec3 oldPosition = getPosition(); - // change in position implies movement - glm::vec3 oldPosition = getPosition(); + int bytesRead = AvatarData::parseDataFromBuffer(buffer); - bytesRead = AvatarData::parseDataFromBuffer(buffer); - - const float MOVE_DISTANCE_THRESHOLD = 0.001f; - _moving = glm::distance(oldPosition, getPosition()) > MOVE_DISTANCE_THRESHOLD; - if (_moving && _motionState) { - _motionState->addDirtyFlags(Simulation::DIRTY_POSITION); - } - }); + const float MOVE_DISTANCE_THRESHOLD = 0.001f; + _moving = glm::distance(oldPosition, getPosition()) > MOVE_DISTANCE_THRESHOLD; + if (_moving && _motionState) { + _motionState->addDirtyFlags(Simulation::DIRTY_POSITION); + } + endUpdate(); return bytesRead; } diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index e9f4c63532..551891cbfa 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -133,9 +133,9 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { QWriteLocker locker(&_hashLock); avatarIterator = _avatarHash.erase(avatarIterator); } else { - avatar->withWriteLock([&] { - avatar->simulate(deltaTime); - }); + avatar->startUpdate(); + avatar->simulate(deltaTime); + avatar->endUpdate(); ++avatarIterator; } } @@ -154,16 +154,16 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { render::PendingChanges pendingChanges; while (fadingIterator != _avatarFades.end()) { auto avatar = std::static_pointer_cast(*fadingIterator); - avatar->withWriteLock([&] { - avatar->setTargetScale(avatar->getAvatarScale() * SHRINK_RATE); - if (avatar->getTargetScale() < MIN_FADE_SCALE) { - avatar->removeFromScene(*fadingIterator, scene, pendingChanges); - fadingIterator = _avatarFades.erase(fadingIterator); - } else { - avatar->simulate(deltaTime); - ++fadingIterator; - } - }); + avatar->startUpdate(); + avatar->setTargetScale(avatar->getAvatarScale() * SHRINK_RATE); + if (avatar->getTargetScale() < MIN_FADE_SCALE) { + avatar->removeFromScene(*fadingIterator, scene, pendingChanges); + fadingIterator = _avatarFades.erase(fadingIterator); + } else { + avatar->simulate(deltaTime); + ++fadingIterator; + } + avatar->endUpdate(); } scene->enqueuePendingChanges(pendingChanges); } diff --git a/interface/src/avatar/AvatarUpdate.cpp b/interface/src/avatar/AvatarUpdate.cpp index a32948f598..cae593ff85 100644 --- a/interface/src/avatar/AvatarUpdate.cpp +++ b/interface/src/avatar/AvatarUpdate.cpp @@ -56,11 +56,12 @@ bool AvatarUpdate::process() { //gets current lookat data, removes missing avatars, etc. manager->updateOtherAvatars(deltaSeconds); - myAvatar->withWriteLock([&] { - qApp->updateMyAvatarLookAtPosition(); - // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes - manager->updateMyAvatar(deltaSeconds); - }); + myAvatar->startUpdate(); + qApp->updateMyAvatarLookAtPosition(); + // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes + manager->updateMyAvatar(deltaSeconds); + myAvatar->endUpdate(); + if (!isThreaded()) { return true; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index a1db573d8d..a06b3448ea 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -111,25 +111,60 @@ void AvatarData::setBodyRoll(float bodyRoll) { } void AvatarData::setPosition(const glm::vec3& position) { - withWriteLock([&] { - SpatiallyNestable::setPosition(position); - }); + SpatiallyNestable::setPosition(position); } void AvatarData::setOrientation(const glm::quat& orientation) { - withWriteLock([&] { - SpatiallyNestable::setOrientation(orientation); - }); + SpatiallyNestable::setOrientation(orientation); } // There are a number of possible strategies for this set of tools through endRender, below. void AvatarData::nextAttitude(glm::vec3 position, glm::quat orientation) { - withWriteLock([&] { - SpatiallyNestable::setPosition(position); - SpatiallyNestable::setOrientation(orientation); - }); + avatarLock.lock(); + SpatiallyNestable::setPosition(position); + SpatiallyNestable::setOrientation(orientation); + avatarLock.unlock(); updateAttitude(); } +void AvatarData::startCapture() { + avatarLock.lock(); + assert(_nextAllowed); + _nextAllowed = false; + _nextPosition = getPosition(); + _nextOrientation = getOrientation(); +} +void AvatarData::endCapture() { + avatarLock.unlock(); +} +void AvatarData::startUpdate() { + avatarLock.lock(); +} +void AvatarData::endUpdate() { + avatarLock.unlock(); +} +void AvatarData::startRenderRun() { + // I'd like to get rid of this and just (un)lock at (end-)startRender. + // But somehow that causes judder in rotations. + avatarLock.lock(); +} +void AvatarData::endRenderRun() { + avatarLock.unlock(); +} +void AvatarData::startRender() { + glm::vec3 pos = getPosition(); + glm::quat rot = getOrientation(); + setPosition(_nextPosition); + setOrientation(_nextOrientation); + updateAttitude(); + _nextPosition = pos; + _nextOrientation = rot; +} +void AvatarData::endRender() { + setPosition(_nextPosition); + setOrientation(_nextOrientation); + updateAttitude(); + _nextAllowed = true; +} float AvatarData::getTargetScale() const { return _targetScale; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 8a0a9ac38a..2e3257554d 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -44,13 +44,13 @@ typedef unsigned long long quint64; #include #include #include +#include #include #include #include #include #include -#include #include "AABox.h" #include "HandData.h" @@ -136,7 +136,7 @@ class QDataStream; class AttachmentData; class JointData; -class AvatarData : public QObject, public ReadWriteLockable, public SpatiallyNestable { +class AvatarData : public QObject, public SpatiallyNestable { Q_OBJECT Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition) @@ -200,6 +200,14 @@ public: virtual void setOrientation(const glm::quat& orientation); void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time. + void startCapture(); // start/end of the period in which the latest values are about to be captured for camera, etc. + void endCapture(); + void startUpdate(); // start/end of update iteration + void endUpdate(); + void startRender(); // start/end of rendering of this object + void startRenderRun(); // start/end of entire scene. + void endRenderRun(); + void endRender(); virtual void updateAttitude() {} // Tell skeleton mesh about changes glm::quat getHeadOrientation() const { return _headData->getOrientation(); } @@ -355,6 +363,10 @@ public slots: protected: glm::vec3 _handPosition; + glm::vec3 _nextPosition {}; + glm::quat _nextOrientation {}; + bool _nextAllowed {true}; + // Body scale float _targetScale; @@ -404,6 +416,8 @@ protected: SimpleMovingAverage _averageBytesReceived; + QMutex avatarLock; // Name is redundant, but it aids searches. + private: static QUrl _defaultFullAvatarModelUrl; // privatize the copy constructor and assignment operator so they cannot be called diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index a4f4ed6512..0227aa23a1 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1795,9 +1795,6 @@ void EntityItem::checkWaitingToRemove(EntitySimulation* simulation) { } void EntityItem::setActionData(QByteArray actionData) { - if (_id == QUuid("32147a6e-976d-44ea-8c33-056c820b4dbd")) { - qDebug() << "EntityItem::setActionData to " << actionData.size() << "bytes."; - } withWriteLock([&] { setActionDataInternal(actionData); }); @@ -1805,16 +1802,8 @@ void EntityItem::setActionData(QByteArray actionData) { void EntityItem::setActionDataInternal(QByteArray actionData) { if (_allActionsDataCache != actionData) { - if (_id == QUuid("32147a6e-976d-44ea-8c33-056c820b4dbd")) { - qDebug() << "EntityItem::setActionDataInternal to " << actionData.size() << "bytes."; - } - _allActionsDataCache = actionData; deserializeActionsInternal(); - } else { - if (_id == QUuid("32147a6e-976d-44ea-8c33-056c820b4dbd")) { - qDebug() << "EntityItem::setActionDataInternal NOT setting to " << actionData.size() << "bytes."; - } } checkWaitingToRemove(); } diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 300d9a5728..f8b1d0dd54 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -61,7 +61,7 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { _parent.reset(); } - // we have a _parentID but no parent pointer, or our parent pointer is to the wrong thing + // we have a _parentID but no parent pointer, or our parent pointer was to the wrong thing QSharedPointer parentFinder = DependencyManager::get(); _parent = parentFinder->find(_parentID); parent = _parent.lock(); @@ -69,6 +69,11 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { parent->beParentOfChild(thisPointer); _parentKnowsMe = true; } + + if (parent || _parentID.isNull()) { + parentChanged(); + } + return parent; } @@ -80,10 +85,11 @@ void SpatiallyNestable::forgetChild(SpatiallyNestablePointer newChild) const { _children.remove(newChild->getID()); } - void SpatiallyNestable::setParentID(const QUuid& parentID) { - _parentID = parentID; - _parentKnowsMe = false; + if (_parentID != parentID) { + _parentID = parentID; + _parentKnowsMe = false; + } } glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position) { diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 986a282891..82e6c3d788 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -92,6 +92,8 @@ protected: virtual void forgetChild(SpatiallyNestablePointer newChild) const; mutable QHash _children; + virtual void parentChanged() const {} // called when parent pointer is updated + private: Transform _transform; // this is to be combined with parent's world-transform to produce this' world-transform. From fbaa86426c1359966f6308589c0f9ff91c8cf9e1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 3 Nov 2015 16:52:46 -0800 Subject: [PATCH 17/51] re-remove the _nextPosition stuff --- interface/src/avatar/AvatarUpdate.cpp | 1 - libraries/avatars/src/AvatarData.cpp | 13 ------------- libraries/avatars/src/AvatarData.h | 4 ---- 3 files changed, 18 deletions(-) diff --git a/interface/src/avatar/AvatarUpdate.cpp b/interface/src/avatar/AvatarUpdate.cpp index cae593ff85..acdb251950 100644 --- a/interface/src/avatar/AvatarUpdate.cpp +++ b/interface/src/avatar/AvatarUpdate.cpp @@ -62,7 +62,6 @@ bool AvatarUpdate::process() { manager->updateMyAvatar(deltaSeconds); myAvatar->endUpdate(); - if (!isThreaded()) { return true; } diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index a06b3448ea..63e20b55b5 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -128,10 +128,6 @@ void AvatarData::nextAttitude(glm::vec3 position, glm::quat orientation) { } void AvatarData::startCapture() { avatarLock.lock(); - assert(_nextAllowed); - _nextAllowed = false; - _nextPosition = getPosition(); - _nextOrientation = getOrientation(); } void AvatarData::endCapture() { avatarLock.unlock(); @@ -151,19 +147,10 @@ void AvatarData::endRenderRun() { avatarLock.unlock(); } void AvatarData::startRender() { - glm::vec3 pos = getPosition(); - glm::quat rot = getOrientation(); - setPosition(_nextPosition); - setOrientation(_nextOrientation); updateAttitude(); - _nextPosition = pos; - _nextOrientation = rot; } void AvatarData::endRender() { - setPosition(_nextPosition); - setOrientation(_nextOrientation); updateAttitude(); - _nextAllowed = true; } float AvatarData::getTargetScale() const { diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 2e3257554d..952017aa77 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -363,10 +363,6 @@ public slots: protected: glm::vec3 _handPosition; - glm::vec3 _nextPosition {}; - glm::quat _nextOrientation {}; - bool _nextAllowed {true}; - // Body scale float _targetScale; From 9b3708ea66a9ebd2cdf6e910039eb4b443776688 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 4 Nov 2015 09:27:57 -0800 Subject: [PATCH 18/51] use parentChanged to recalculate entity bounding boxes --- libraries/entities/src/EntityItem.cpp | 6 ++++++ libraries/entities/src/EntityItem.h | 1 + libraries/shared/src/SpatiallyNestable.cpp | 2 +- libraries/shared/src/SpatiallyNestable.h | 2 +- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 0227aa23a1..5394631459 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1324,6 +1324,12 @@ void EntityItem::forSelfAndEachChildEntity(std::functionrequiresRecalcBoxes(); + }); +} + void EntityItem::updatePosition(const glm::vec3& value) { if (shouldSuppressLocationEdits()) { return; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index ffcf24854d..6692886127 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -398,6 +398,7 @@ protected: void setActionDataInternal(QByteArray actionData); void forSelfAndEachChildEntity(std::function actor); + virtual void parentChanged(); static bool _sendPhysicsUpdates; EntityTypes::EntityType _type; diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index f8b1d0dd54..1d058b56df 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -71,7 +71,7 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { } if (parent || _parentID.isNull()) { - parentChanged(); + thisPointer->parentChanged(); } return parent; diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 82e6c3d788..6550eb721e 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -92,7 +92,7 @@ protected: virtual void forgetChild(SpatiallyNestablePointer newChild) const; mutable QHash _children; - virtual void parentChanged() const {} // called when parent pointer is updated + virtual void parentChanged() {} // called when parent pointer is updated private: Transform _transform; // this is to be combined with parent's world-transform to produce this' world-transform. From 3154b9d75f5e9762abb39b894240836caa182c40 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 4 Nov 2015 16:21:02 -0800 Subject: [PATCH 19/51] don't set release velocity --- examples/controllers/handControllerGrab.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 2d82896e26..4cce546840 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -895,9 +895,9 @@ function MyController(hand) { // the action will tend to quickly bring an object's velocity to zero. now that // the action is gone, set the objects velocity to something the holder might expect. - Entities.editEntity(this.grabbedEntity, { - velocity: this.grabbedVelocity - }); + // Entities.editEntity(this.grabbedEntity, { + // velocity: this.grabbedVelocity + // }); this.grabbedVelocity = ZERO_VEC; this.grabbedEntity = null; From 7cb8adb0905c92d2c8e4b3c1a8a847fd7896ffaa Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 4 Nov 2015 16:26:30 -0800 Subject: [PATCH 20/51] get rid of code that computes release velocity --- examples/controllers/handControllerGrab.js | 29 +--------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 4cce546840..e6381e8770 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -178,12 +178,11 @@ function MyController(hand) { this.actionID = null; // action this script created... this.grabbedEntity = null; // on this entity. - this.grabbedVelocity = ZERO_VEC; // rolling average of held object's velocity this.state = STATE_OFF; this.pointer = null; // entity-id of line object this.triggerValue = 0; // rolling average of trigger value this.rawTriggerValue = 0; - + this.offsetPosition = { x: 0.0, y: 0.0, z: 0.0 }; this.offsetRotation = { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }; @@ -587,7 +586,6 @@ function MyController(hand) { var deltaPosition = Vec3.subtract(newObjectPosition, this.currentObjectPosition); // meters var now = Date.now(); var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds - this.computeReleaseVelocity(deltaPosition, deltaTime, false); this.currentObjectPosition = newObjectPosition; this.currentObjectTime = now; @@ -707,7 +705,6 @@ function MyController(hand) { var deltaPosition = Vec3.subtract(handControllerPosition, this.currentHandControllerTipPosition); // meters var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds - this.computeReleaseVelocity(deltaPosition, deltaTime, true); this.currentHandControllerTipPosition = handControllerPosition; this.currentObjectTime = now; @@ -859,23 +856,6 @@ function MyController(hand) { Entities.callEntityMethod(entityID, "stopTouch"); }; - this.computeReleaseVelocity = function(deltaPosition, deltaTime, useMultiplier) { - if (deltaTime > 0.0 && !vec3equal(deltaPosition, ZERO_VEC)) { - var grabbedVelocity = Vec3.multiply(deltaPosition, 1.0 / deltaTime); - // don't update grabbedVelocity if the trigger is off. the smoothing of the trigger - // value would otherwise give the held object time to slow down. - if (this.triggerSqueezed()) { - this.grabbedVelocity = - Vec3.sum(Vec3.multiply(this.grabbedVelocity, (1.0 - NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)), - Vec3.multiply(grabbedVelocity, NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)); - } - - if (useMultiplier) { - this.grabbedVelocity = Vec3.multiply(this.grabbedVelocity, RELEASE_VELOCITY_MULTIPLIER); - } - } - }; - this.release = function() { if(this.hand !== disabledHand){ @@ -893,13 +873,6 @@ function MyController(hand) { this.deactivateEntity(this.grabbedEntity); - // the action will tend to quickly bring an object's velocity to zero. now that - // the action is gone, set the objects velocity to something the holder might expect. - // Entities.editEntity(this.grabbedEntity, { - // velocity: this.grabbedVelocity - // }); - - this.grabbedVelocity = ZERO_VEC; this.grabbedEntity = null; this.actionID = null; this.setState(STATE_OFF); From 4ffaa7db8e573ee941b4b60b9ec0217151eea852 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 4 Nov 2015 13:59:37 -0800 Subject: [PATCH 21/51] don't attempt to grab particles or zones --- examples/controllers/handControllerGrab.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index e6381e8770..b0721de119 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -451,6 +451,14 @@ function MyController(hand) { continue; } + if (propsForCandidate.type == 'ParticleEffect') { + continue; + } + + if (propsForCandidate.type == 'Zone') { + continue; + } + if (propsForCandidate.locked && !grabbableDataForCandidate.wantsTrigger) { continue; } From 0b1fa4f60f858bab217cf6bd90f739ca532561d3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 21 Nov 2015 08:21:10 -0800 Subject: [PATCH 22/51] add interface for getters for specific joints --- .../src/SceneScriptingInterface.h | 6 ++-- libraries/shared/src/SpatiallyNestable.cpp | 30 +++++++++++++++++++ libraries/shared/src/SpatiallyNestable.h | 10 +++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h index 95919d6c0c..16db9f78f4 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.h +++ b/libraries/script-engine/src/SceneScriptingInterface.h @@ -107,8 +107,8 @@ public: Q_INVOKABLE void setEngineMaxDrawnOverlay3DItems(int count) { _maxDrawnOverlay3DItems = count; } Q_INVOKABLE int getEngineMaxDrawnOverlay3DItems() { return _maxDrawnOverlay3DItems; } - Q_INVOKABLE void setEngineDisplayItemStatus(bool display) { _drawItemStatus = display; } - Q_INVOKABLE bool doEngineDisplayItemStatus() { return _drawItemStatus; } + Q_INVOKABLE void setEngineDisplayItemStatus(uint32_t display) { _drawItemStatus = display; } + Q_INVOKABLE uint32_t doEngineDisplayItemStatus() { return _drawItemStatus; } Q_INVOKABLE void setEngineDisplayHitEffect(bool display) { _drawHitEffect = display; } Q_INVOKABLE bool doEngineDisplayHitEffect() { return _drawHitEffect; } @@ -143,7 +143,7 @@ protected: int _maxDrawnTransparentItems = -1; int _maxDrawnOverlay3DItems = -1; - bool _drawItemStatus = false; + uint32_t _drawItemStatus = false; bool _drawHitEffect = false; diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 1d058b56df..bd7e244fb0 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -121,6 +121,12 @@ const glm::vec3& SpatiallyNestable::getPosition() const { return _absolutePositionCache; } +const glm::vec3& SpatiallyNestable::getPosition(int jointIndex) const { + getTransform(); // update _worldTransformCache + // XXX ... something with joints + return _absolutePositionCache; +} + void SpatiallyNestable::setPosition(const glm::vec3& position) { Transform parentTransform = getParentTransform(); Transform myWorldTransform; @@ -135,6 +141,11 @@ const glm::quat& SpatiallyNestable::getOrientation() const { return _absoluteRotationCache; } +const glm::quat& SpatiallyNestable::getOrientation(int jointIndex) const { + // XXX something with joints... + return getOrientation(); +} + void SpatiallyNestable::setOrientation(const glm::quat& orientation) { Transform parentTransform = getParentTransform(); Transform myWorldTransform; @@ -149,6 +160,12 @@ const Transform& SpatiallyNestable::getTransform() const { return _worldTransformCache; } +const Transform& SpatiallyNestable::getTransform(int jointIndex) const { + getTransform(); // update _worldTransformCache + // XXX ... something with joints + return _worldTransformCache; +} + void SpatiallyNestable::setTransform(const Transform& transform) { Transform parentTransform = getParentTransform(); Transform::inverseMult(_transform, parentTransform, transform); @@ -158,6 +175,11 @@ const glm::vec3& SpatiallyNestable::getScale() const { return _transform.getScale(); } +const glm::vec3& SpatiallyNestable::getScale(int jointIndex) const { + // XXX ... something with joints + return getScale(); +} + void SpatiallyNestable::setScale(const glm::vec3& scale) { _transform.setScale(scale); } @@ -204,3 +226,11 @@ QList SpatiallyNestable::getChildren() const { } return children; } + + +const Transform& SpatiallyNestable::getJointTransformInObjectFrame(int jointIndex) const { + _jointInObjectFrameCache.resize(jointIndex); + // XXX + _jointInObjectFrameCache[jointIndex] = Transform(); + return _jointInObjectFrameCache[jointIndex]; +} diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 6550eb721e..65f31c276a 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -59,11 +59,17 @@ public: virtual void setPosition(const glm::vec3& position); virtual const glm::quat& getOrientation() const; + virtual const glm::quat& getOrientation(int jointIndex) const; virtual void setOrientation(const glm::quat& orientation); virtual const glm::vec3& getScale() const; virtual void setScale(const glm::vec3& scale); + // get world location of a specific joint + virtual const Transform& getTransform(int jointIndex) const; + virtual const glm::vec3& getPosition(int jointIndex) const; + virtual const glm::vec3& getScale(int jointIndex) const; + // object's parent's frame virtual const Transform& getLocalTransform() const; virtual void setLocalTransform(const Transform& transform); @@ -80,6 +86,9 @@ public: QList getChildren() const; NestableTypes::NestableType getNestableType() const { return _nestableType; } + // this object's frame + virtual const Transform& getJointTransformInObjectFrame(int jointIndex) const; + protected: NestableTypes::NestableType _nestableType; // EntityItem or an AvatarData QUuid _id; @@ -102,6 +111,7 @@ private: mutable glm::quat _absoluteRotationCache; mutable Transform _worldTransformCache; mutable bool _parentKnowsMe = false; + mutable QVector _jointInObjectFrameCache; }; From 4646c0c1030b8c67ca4768d443fb39097a446067 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 21 Nov 2015 10:49:31 -0800 Subject: [PATCH 23/51] unmangle merge --- libraries/audio/src/AudioConstants.h | 2 +- libraries/avatars/src/AvatarData.cpp | 13 ------------- libraries/avatars/src/AvatarData.h | 1 - .../src/RenderableModelEntityItem.cpp | 4 ++-- .../src/RenderableParticleEffectEntityItem.cpp | 2 +- .../src/RenderablePolyVoxEntityItem.cpp | 2 +- .../src/RenderableZoneEntityItem.cpp | 4 ++-- libraries/entities/src/PolyLineEntityItem.cpp | 2 +- .../oculusLegacy/src/OculusLegacyDisplayPlugin.cpp | 5 ++++- 9 files changed, 12 insertions(+), 23 deletions(-) diff --git a/libraries/audio/src/AudioConstants.h b/libraries/audio/src/AudioConstants.h index e252a5354d..785060d364 100644 --- a/libraries/audio/src/AudioConstants.h +++ b/libraries/audio/src/AudioConstants.h @@ -35,4 +35,4 @@ namespace AudioConstants { } -#endif // hifi_AudioConstants_h \ No newline at end of file +#endif // hifi_AudioConstants_h diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 26f771f3bc..14985cdbf3 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -785,11 +785,6 @@ std::shared_ptr AvatarData::getRecordingBasis() const { return _recordingBasis; } -void AvatarData::changeReferential(Referential* ref) { - delete _referential; - _referential = ref; -} - void AvatarData::setRawJointData(QVector data) { if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "setRawJointData", Q_ARG(QVector, data)); @@ -1376,14 +1371,6 @@ void AvatarData::clearRecordingBasis() { _recordingBasis.reset(); } -Transform AvatarData::getTransform() const { - Transform result; - result.setRotation(getOrientation()); - result.setTranslation(getPosition()); - result.setScale(getTargetScale()); - return result; -} - static const QString JSON_AVATAR_BASIS = QStringLiteral("basisTransform"); static const QString JSON_AVATAR_RELATIVE = QStringLiteral("relativeTransform"); static const QString JSON_AVATAR_JOINT_ARRAY = QStringLiteral("jointArray"); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 26f9e38f99..7c5a967c97 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -334,7 +334,6 @@ public: bool shouldDie() const { return _owningAvatarMixer.isNull() || getUsecsSinceLastUpdate() > AVATAR_SILENCE_THRESHOLD_USECS; } - Transform getTransform() const; void clearRecordingBasis(); TransformPointer getRecordingBasis() const; void setRecordingBasis(TransformPointer recordingBasis = TransformPointer()); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index c58915d14f..0a67d73e81 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -193,7 +193,7 @@ bool RenderableModelEntityItem::addToScene(EntityItemPointer self, std::shared_p if (_model) { render::Item::Status::Getters statusGetters; - makeEntityItemStatusGetters(shared_from_this(), statusGetters); + makeEntityItemStatusGetters(getThisPointer(), statusGetters); // note: we don't care if the model fails to add items, we always added our meta item and therefore we return // true so that the system knows our meta item is in the scene! @@ -237,7 +237,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) { _model->removeFromScene(scene, pendingChanges); render::Item::Status::Getters statusGetters; - makeEntityItemStatusGetters(shared_from_this(), statusGetters); + makeEntityItemStatusGetters(getThisPointer(), statusGetters); _model->addToScene(scene, pendingChanges, statusGetters, _showCollisionHull); scene->enqueuePendingChanges(pendingChanges); diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index fa5d8c17f2..dca9c10849 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -143,7 +143,7 @@ bool RenderableParticleEffectEntityItem::addToScene(EntityItemPointer self, auto renderData = ParticlePayload::Pointer(particlePayload); auto renderPayload = render::PayloadPointer(new ParticlePayload::Payload(renderData)); render::Item::Status::Getters statusGetters; - makeEntityItemStatusGetters(shared_from_this(), statusGetters); + makeEntityItemStatusGetters(getThisPointer(), statusGetters); renderPayload->addStatusGetters(statusGetters); pendingChanges.resetItem(_renderItemId, renderPayload); _scene = scene; diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 5f14cee776..5363da772b 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -551,7 +551,7 @@ bool RenderablePolyVoxEntityItem::addToScene(EntityItemPointer self, auto renderPayload = std::make_shared(renderData); render::Item::Status::Getters statusGetters; - makeEntityItemStatusGetters(shared_from_this(), statusGetters); + makeEntityItemStatusGetters(getThisPointer(), statusGetters); renderPayload->addStatusGetters(statusGetters); pendingChanges.resetItem(_myItem, renderPayload); diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 205f2bc531..ca16b3aca1 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -117,7 +117,7 @@ void RenderableZoneEntityItem::render(RenderArgs* args) { render::PendingChanges pendingChanges; _model->removeFromScene(scene, pendingChanges); render::Item::Status::Getters statusGetters; - makeEntityItemStatusGetters(shared_from_this(), statusGetters); + makeEntityItemStatusGetters(getThisPointer(), statusGetters); _model->addToScene(scene, pendingChanges, false); scene->enqueuePendingChanges(pendingChanges); @@ -211,7 +211,7 @@ bool RenderableZoneEntityItem::addToScene(EntityItemPointer self, std::shared_pt auto renderPayload = std::make_shared(renderData); render::Item::Status::Getters statusGetters; - makeEntityItemStatusGetters(shared_from_this(), statusGetters); + makeEntityItemStatusGetters(getThisPointer(), statusGetters); renderPayload->addStatusGetters(statusGetters); pendingChanges.resetItem(_myMetaItem, renderPayload); diff --git a/libraries/entities/src/PolyLineEntityItem.cpp b/libraries/entities/src/PolyLineEntityItem.cpp index 22f27c5287..179705e5f5 100644 --- a/libraries/entities/src/PolyLineEntityItem.cpp +++ b/libraries/entities/src/PolyLineEntityItem.cpp @@ -31,7 +31,7 @@ EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, cons return entity; } -PolyLineEntityItem::PolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : +PolyLineEntityItem::PolyLineEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID), _lineWidth(DEFAULT_LINE_WIDTH), _pointsChanged(true), diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp index ddf251778f..3898d586ad 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp @@ -167,7 +167,10 @@ void OculusLegacyDisplayPlugin::activate() { } }); - ovrBool result = ovrHmd_ConfigureRendering(_hmd, &config.Config, distortionCaps, _eyeFovs, _eyeRenderDescs); + #ifndef QT_NO_DEBUG + ovrBool result = + #endif + ovrHmd_ConfigureRendering(_hmd, &config.Config, distortionCaps, _eyeFovs, _eyeRenderDescs); Q_ASSERT(result); } From a9669531ae324c90d34bd1caa3c9c931dccca893 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 21 Nov 2015 11:53:16 -0800 Subject: [PATCH 24/51] quiet a warning --- plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp index 3898d586ad..9d10d176e6 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp @@ -167,11 +167,11 @@ void OculusLegacyDisplayPlugin::activate() { } }); - #ifndef QT_NO_DEBUG + #ifndef NDEBUG ovrBool result = #endif ovrHmd_ConfigureRendering(_hmd, &config.Config, distortionCaps, _eyeFovs, _eyeRenderDescs); - Q_ASSERT(result); + assert(result); } void OculusLegacyDisplayPlugin::deactivate() { From abfc3e994a534ac82235be74cc95611faa8f663d Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 22 Nov 2015 07:18:12 -0800 Subject: [PATCH 25/51] AvatarData::toFrame expects a scaled transform --- libraries/avatars/src/AvatarData.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 14985cdbf3..cc75404748 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -1425,13 +1425,15 @@ QByteArray AvatarData::toFrame(const AvatarData& avatar) { } auto recordingBasis = avatar.getRecordingBasis(); + Transform avatarTransform = avatar.getTransform(); + avatarTransform.setScale(avatar.getTargetScale()); if (recordingBasis) { root[JSON_AVATAR_BASIS] = Transform::toJson(*recordingBasis); // Find the relative transform - auto relativeTransform = recordingBasis->relativeTransform(avatar.getTransform()); + auto relativeTransform = recordingBasis->relativeTransform(avatarTransform); root[JSON_AVATAR_RELATIVE] = Transform::toJson(relativeTransform); } else { - root[JSON_AVATAR_RELATIVE] = Transform::toJson(avatar.getTransform()); + root[JSON_AVATAR_RELATIVE] = Transform::toJson(avatarTransform); } // Skeleton pose From a0c1f9a1f9d8944fd33bb0f8f6d736cf0acd2666 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 22 Nov 2015 13:11:37 -0800 Subject: [PATCH 26/51] progress toward having things be children of specific joints rather than just of other objects --- libraries/entities/src/EntityItem.h | 4 +++ libraries/shared/src/SpatiallyNestable.cpp | 30 ++++++++++++++-------- libraries/shared/src/SpatiallyNestable.h | 3 +++ 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index e2368f92fd..8d47037f6b 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -403,6 +403,10 @@ public: QList getActionsOfType(EntityActionType typeToGet); + // these are in the frame of this object + virtual glm::quat getJointRotation(int index) const { return glm::quat(); } + virtual glm::vec3 getJointTranslation(int index) const { return glm::vec3(0.0f); } + protected: const QByteArray getActionDataInternal() const; diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index bd7e244fb0..87ef7565fb 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -12,8 +12,6 @@ #include "DependencyManager.h" #include "SpatiallyNestable.h" -// TODO -- make use of parent joint index - SpatiallyNestable::SpatiallyNestable(NestableTypes::NestableType nestableType, QUuid id) : _nestableType(nestableType), @@ -28,7 +26,7 @@ Transform SpatiallyNestable::getParentTransform() const { Transform result; SpatiallyNestablePointer parent = getParentPointer(); if (parent) { - Transform parentTransform = parent->getTransform(); + Transform parentTransform = parent->getTransform(_parentJointIndex); result = parentTransform.setScale(1.0f); } return result; @@ -123,8 +121,10 @@ const glm::vec3& SpatiallyNestable::getPosition() const { const glm::vec3& SpatiallyNestable::getPosition(int jointIndex) const { getTransform(); // update _worldTransformCache - // XXX ... something with joints - return _absolutePositionCache; + getJointTransformInObjectFrame(jointIndex); // update _jointInObjectFrameCache + _jointInWorldFrameCache.resize(jointIndex); + Transform::mult(_jointInWorldFrameCache[jointIndex], _worldTransformCache, _jointInObjectFrameCache[jointIndex]); + return _jointInWorldFrameCache[jointIndex].getTranslation(); } void SpatiallyNestable::setPosition(const glm::vec3& position) { @@ -142,8 +142,11 @@ const glm::quat& SpatiallyNestable::getOrientation() const { } const glm::quat& SpatiallyNestable::getOrientation(int jointIndex) const { - // XXX something with joints... - return getOrientation(); + getTransform(); // update _worldTransformCache + getJointTransformInObjectFrame(jointIndex); // update _jointInObjectFrameCache + _jointInWorldFrameCache.resize(jointIndex + 1); + Transform::mult(_jointInWorldFrameCache[jointIndex], _worldTransformCache, _jointInObjectFrameCache[jointIndex]); + return _jointInWorldFrameCache[jointIndex].getRotation(); } void SpatiallyNestable::setOrientation(const glm::quat& orientation) { @@ -162,8 +165,10 @@ const Transform& SpatiallyNestable::getTransform() const { const Transform& SpatiallyNestable::getTransform(int jointIndex) const { getTransform(); // update _worldTransformCache - // XXX ... something with joints - return _worldTransformCache; + getJointTransformInObjectFrame(jointIndex); // update _jointInObjectFrameCache + _jointInWorldFrameCache.resize(jointIndex + 1); + Transform::mult(_jointInWorldFrameCache[jointIndex], _worldTransformCache, _jointInObjectFrameCache[jointIndex]); + return _jointInWorldFrameCache[jointIndex]; } void SpatiallyNestable::setTransform(const Transform& transform) { @@ -229,8 +234,11 @@ QList SpatiallyNestable::getChildren() const { const Transform& SpatiallyNestable::getJointTransformInObjectFrame(int jointIndex) const { - _jointInObjectFrameCache.resize(jointIndex); - // XXX + _jointInObjectFrameCache.resize(jointIndex + 1); _jointInObjectFrameCache[jointIndex] = Transform(); + glm::vec3 position = getJointTranslation(jointIndex); + glm::quat orientation = getJointRotation(jointIndex); + _jointInObjectFrameCache[jointIndex].setRotation(orientation); + _jointInObjectFrameCache[jointIndex].setTranslation(position); return _jointInObjectFrameCache[jointIndex]; } diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 65f31c276a..30602d26b4 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -88,6 +88,8 @@ public: // this object's frame virtual const Transform& getJointTransformInObjectFrame(int jointIndex) const; + virtual glm::quat getJointRotation(int index) const = 0; + virtual glm::vec3 getJointTranslation(int index) const = 0; protected: NestableTypes::NestableType _nestableType; // EntityItem or an AvatarData @@ -112,6 +114,7 @@ private: mutable Transform _worldTransformCache; mutable bool _parentKnowsMe = false; mutable QVector _jointInObjectFrameCache; + mutable QVector _jointInWorldFrameCache; }; From a08bad8cbdb97b90dab7d4b8fd77675dbfbe3a62 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 23 Nov 2015 13:46:32 -0800 Subject: [PATCH 27/51] for models, relay getJointRotation and getJointTranslation to the model --- .../src/RenderableModelEntityItem.cpp | 20 +++++++++++++++++++ .../src/RenderableModelEntityItem.h | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 0a67d73e81..ce659acfa6 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -562,3 +562,23 @@ bool RenderableModelEntityItem::contains(const glm::vec3& point) const { return false; } + +glm::quat getJointRotation(int index) const { + if (_model) { + glm::quat result; + if (_model->getJointRotation(index, result)) { + return result; + } + } + return glm::quat(); +} + +glm::vec3 getJointTranslation(int index) const { + if (_model) { + glm::vec3 result; + if (_model->getJointTranslation(index, result)) { + return result; + } + } + return glm::vec3(0.0f); +} diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 34e2bacb47..2187c0edb3 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -67,6 +67,10 @@ public: virtual bool contains(const glm::vec3& point) const; + // these are in the frame of this object + virtual glm::quat getJointRotation(int index) const; + virtual glm::vec3 getJointTranslation(int index) const; + private: void remapTextures(); From ba30e016644a61c2d2a4a2b3697011303511bcf4 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 23 Nov 2015 14:12:49 -0800 Subject: [PATCH 28/51] include global position in avatar-mixer protocol so server knows where avatars are in world-space --- assignment-client/src/avatars/AvatarMixer.cpp | 4 ++-- interface/src/avatar/MyAvatar.cpp | 1 + libraries/avatars/src/AvatarData.cpp | 6 ++++++ libraries/avatars/src/AvatarData.h | 7 +++++++ .../entities-renderer/src/RenderableModelEntityItem.cpp | 4 ++-- 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index ae627caf00..174ba04311 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -157,7 +157,7 @@ void AvatarMixer::broadcastAvatarData() { ++_sumListeners; AvatarData& avatar = nodeData->getAvatar(); - glm::vec3 myPosition = avatar.getLocalPosition(); // XXX should be world position + glm::vec3 myPosition = avatar.getClientGlobalPosition(); // reset the internal state for correct random number distribution distribution.reset(); @@ -290,7 +290,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.getLocalPosition(); // XXX should be world position + glm::vec3 otherPosition = otherAvatar.getClientGlobalPosition(); float distanceToAvatar = glm::length(myPosition - otherPosition); // potentially update the max full rate distance for this frame diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 254d1c068f..9d3981f4a0 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -193,6 +193,7 @@ MyAvatar::~MyAvatar() { QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) { CameraMode mode = qApp->getCamera()->getMode(); + _globalPosition = getPosition(); if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) { // fake the avatar position that is sent up to the AvatarMixer glm::vec3 oldPosition = getPosition(); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index cc75404748..dfae86f132 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -210,6 +210,9 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { memcpy(destinationBuffer, &position, sizeof(position)); destinationBuffer += sizeof(position); + memcpy(destinationBuffer, &_globalPosition, sizeof(_globalPosition)); + destinationBuffer += sizeof(_globalPosition); + // Body rotation glm::vec3 bodyEulerAngles = glm::degrees(safeEulerAngles(getLocalOrientation())); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, bodyEulerAngles.y); @@ -492,6 +495,9 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { memcpy(&position, sourceBuffer, sizeof(position)); sourceBuffer += sizeof(position); + memcpy(&_globalPosition, sourceBuffer, sizeof(_globalPosition)); + sourceBuffer += sizeof(_globalPosition); + if (glm::isnan(position.x) || glm::isnan(position.y) || glm::isnan(position.z)) { if (shouldLogError(now)) { qCDebug(avatars) << "Discard nan AvatarData::position; displayName = '" << _displayName << "'"; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 7c5a967c97..5465c764f9 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -338,6 +338,8 @@ public: TransformPointer getRecordingBasis() const; void setRecordingBasis(TransformPointer recordingBasis = TransformPointer()); + glm::vec3 getClientGlobalPosition() { return _globalPosition; } + public slots: void sendAvatarDataPacket(); void sendIdentityPacket(); @@ -403,6 +405,11 @@ protected: // During playback, it holds the origin from which to play the relative positions in the clip TransformPointer _recordingBasis; + // _globalPosition is sent along with localPosition + parent because the avatar-mixer doesn't know + // where Entities are located. This is currently only used by the mixer to decide how often to send + // updates about one avatar to another. + glm::vec3 _globalPosition; + private: friend void avatarStateFromFrame(const QByteArray& frameData, AvatarData* _avatar); static QUrl _defaultFullAvatarModelUrl; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index ce659acfa6..ddacc78fd0 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -563,7 +563,7 @@ bool RenderableModelEntityItem::contains(const glm::vec3& point) const { return false; } -glm::quat getJointRotation(int index) const { +glm::quat RenderableModelEntityItem::getJointRotation(int index) const { if (_model) { glm::quat result; if (_model->getJointRotation(index, result)) { @@ -573,7 +573,7 @@ glm::quat getJointRotation(int index) const { return glm::quat(); } -glm::vec3 getJointTranslation(int index) const { +glm::vec3 RenderableModelEntityItem::getJointTranslation(int index) const { if (_model) { glm::vec3 result; if (_model->getJointTranslation(index, result)) { From 5fe41662d802ef852852a5db0d5c37cfefa0a837 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 23 Nov 2015 14:31:40 -0800 Subject: [PATCH 29/51] fix comment header paths --- assignment-client/src/entities/AssignmentParentFinder.cpp | 2 +- assignment-client/src/entities/AssignmentParentFinder.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/entities/AssignmentParentFinder.cpp b/assignment-client/src/entities/AssignmentParentFinder.cpp index 3e6fc2ed38..5fe4742b90 100644 --- a/assignment-client/src/entities/AssignmentParentFinder.cpp +++ b/assignment-client/src/entities/AssignmentParentFinder.cpp @@ -1,6 +1,6 @@ // // AssignmentParentFinder.cpp -// assignment-client/src/ +// assignment-client/src/entities // // Created by Seth Alves on 2015-10-22 // Copyright 2015 High Fidelity, Inc. diff --git a/assignment-client/src/entities/AssignmentParentFinder.h b/assignment-client/src/entities/AssignmentParentFinder.h index 4d2e080443..99fa58ffed 100644 --- a/assignment-client/src/entities/AssignmentParentFinder.h +++ b/assignment-client/src/entities/AssignmentParentFinder.h @@ -1,6 +1,6 @@ // // AssignmentParentFinder.h -// interface/src/ +// interface/src/entities // // Created by Seth Alves on 2015-10-21 // Copyright 2015 High Fidelity, Inc. From 7df984e7b207528477d04a3e6eab5477573668f2 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 26 Nov 2015 05:30:01 -0800 Subject: [PATCH 30/51] fix deadlock when setting parentID to null --- interface/src/InterfaceParentFinder.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/src/InterfaceParentFinder.cpp b/interface/src/InterfaceParentFinder.cpp index 1703ffc5d1..112bae5bb8 100644 --- a/interface/src/InterfaceParentFinder.cpp +++ b/interface/src/InterfaceParentFinder.cpp @@ -19,6 +19,10 @@ SpatiallyNestableWeakPointer InterfaceParentFinder::find(QUuid parentID) const { SpatiallyNestableWeakPointer parent; + if (parentID.isNull()) { + return parent; + } + // search entities EntityTreeRenderer* treeRenderer = qApp->getEntities(); EntityTreePointer tree = treeRenderer->getTree(); From 36e293608a009ec6b1d067f8351673c728e6e555 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 26 Nov 2015 05:31:52 -0800 Subject: [PATCH 31/51] more adding parentID to edit.js --- examples/html/entityProperties.html | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index bc6a6920d1..50fb205e3d 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -223,7 +223,9 @@ var elDimensionsZ = document.getElementById("property-dim-z"); var elResetToNaturalDimensions = document.getElementById("reset-to-natural-dimensions"); var elRescaleDimensionsPct = document.getElementById("dimension-rescale-pct"); - var elRescaleDimensionsButton = document.getElementById("dimension-rescale-button"); + var elRescaleDimensionsButton = document.getElementById("dimension-rescale-button"); + + var elParentID = document.getElementById("parent-id"); var elRegistrationX = document.getElementById("property-reg-x"); var elRegistrationY = document.getElementById("property-reg-y"); @@ -453,6 +455,8 @@ elDimensionsY.value = properties.dimensions.y.toFixed(2); elDimensionsZ.value = properties.dimensions.z.toFixed(2); + elParentID.value = properties.parentID; + elRegistrationX.value = properties.registrationPoint.x.toFixed(2); elRegistrationY.value = properties.registrationPoint.y.toFixed(2); elRegistrationZ.value = properties.registrationPoint.z.toFixed(2); @@ -666,6 +670,8 @@ elDimensionsY.addEventListener('change', dimensionsChangeFunction); elDimensionsZ.addEventListener('change', dimensionsChangeFunction); + elParentID.addEventListener('change', createEmitTextPropertyUpdateFunction('parentID)); + var registrationChangeFunction = createEmitVec3PropertyUpdateFunction( 'registrationPoint', elRegistrationX, elRegistrationY, elRegistrationZ); elRegistrationX.addEventListener('change', registrationChangeFunction); @@ -1055,6 +1061,13 @@ +
+ ParentID +
+ +
+
+
Registration
From 10cf85bad975090e01cb95da7edbf2b815af7c0f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 26 Nov 2015 07:02:53 -0800 Subject: [PATCH 32/51] fix some rotation handling in EntityItem, minimize diff vs master --- libraries/entities/src/EntityItem.cpp | 132 +++++++++++++------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index c0dd79d00e..d60df17d78 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -241,7 +241,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet APPEND_ENTITY_PROPERTY(PROP_SIMULATION_OWNER, _simulationOwner.toByteArray()); APPEND_ENTITY_PROPERTY(PROP_POSITION, getLocalPosition()); - APPEND_ENTITY_PROPERTY(PROP_ROTATION, getRotation()); + APPEND_ENTITY_PROPERTY(PROP_ROTATION, getLocalOrientation()); APPEND_ENTITY_PROPERTY(PROP_VELOCITY, getVelocity()); APPEND_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, getAngularVelocity()); APPEND_ENTITY_PROPERTY(PROP_ACCELERATION, getAcceleration()); @@ -1045,7 +1045,7 @@ EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProper COPY_ENTITY_PROPERTY_TO_PROPERTIES(simulationOwner, getSimulationOwner); 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(rotation, getLocalOrientation); COPY_ENTITY_PROPERTY_TO_PROPERTIES(density, getDensity); COPY_ENTITY_PROPERTY_TO_PROPERTIES(velocity, getVelocity); COPY_ENTITY_PROPERTY_TO_PROPERTIES(gravity, getGravity); @@ -1085,7 +1085,7 @@ void EntityItem::getAllTerseUpdateProperties(EntityItemProperties& properties) c // a TerseUpdate includes the transform and its derivatives properties._position = getLocalPosition(); properties._velocity = _velocity; - properties._rotation = getRotation(); + properties._rotation = getLocalOrientation(); properties._angularVelocity = _angularVelocity; properties._acceleration = _acceleration; @@ -1314,27 +1314,6 @@ void EntityItem::computeShapeInfo(ShapeInfo& info) { info.setParams(getShapeType(), 0.5f * getDimensions()); } -void EntityItem::forSelfAndEachChildEntity(std::function actor) { - QQueue toProcess; - toProcess.enqueue(shared_from_this()); - - while (!toProcess.empty()) { - EntityItemPointer entity = std::static_pointer_cast(toProcess.dequeue()); - actor(entity); - foreach (SpatiallyNestablePointer child, entity->getChildren()) { - if (child && child->getNestableType() == NestableTypes::Entity) { - toProcess.enqueue(child); - } - } - } -} - -void EntityItem::parentChanged() { - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); -} - void EntityItem::updatePosition(const glm::vec3& value) { if (shouldSuppressLocationEdits()) { return; @@ -1347,34 +1326,6 @@ void EntityItem::updatePosition(const glm::vec3& value) { } } -void EntityItem::setTransform(const Transform& transform) { - SpatiallyNestable::setTransform(transform); - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); -} - -void EntityItem::setLocalTransform(const Transform& transform) { - SpatiallyNestable::setLocalTransform(transform); - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); -} - -void EntityItem::setPosition(const glm::vec3& position) { - SpatiallyNestable::setPosition(position); - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); -} - -void EntityItem::setLocalPosition(const glm::vec3& position) { - SpatiallyNestable::setLocalPosition(position); - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); -} - void EntityItem::updateRotation(const glm::quat& rotation) { if (shouldSuppressLocationEdits()) { return; @@ -1390,20 +1341,6 @@ void EntityItem::updateRotation(const glm::quat& rotation) { } } -void EntityItem::setRotation(const glm::quat& orientation) { - SpatiallyNestable::setOrientation(orientation); - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); -} - -void EntityItem::setLocalRotation(const glm::quat& orientation) { - SpatiallyNestable::setLocalOrientation(orientation); - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); -} - void EntityItem::updateDimensions(const glm::vec3& value) { if (getDimensions() != value) { setDimensions(value); @@ -1901,3 +1838,66 @@ QList EntityItem::getActionsOfType(EntityActionType typeToG return result; } + +void EntityItem::forSelfAndEachChildEntity(std::function actor) { + QQueue toProcess; + toProcess.enqueue(shared_from_this()); + + while (!toProcess.empty()) { + EntityItemPointer entity = std::static_pointer_cast(toProcess.dequeue()); + actor(entity); + foreach (SpatiallyNestablePointer child, entity->getChildren()) { + if (child && child->getNestableType() == NestableTypes::Entity) { + toProcess.enqueue(child); + } + } + } +} + +void EntityItem::parentChanged() { + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + entity->requiresRecalcBoxes(); + }); +} + +void EntityItem::setTransform(const Transform& transform) { + SpatiallyNestable::setTransform(transform); + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + entity->requiresRecalcBoxes(); + }); +} + +void EntityItem::setLocalTransform(const Transform& transform) { + SpatiallyNestable::setLocalTransform(transform); + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + entity->requiresRecalcBoxes(); + }); +} + +void EntityItem::setPosition(const glm::vec3& position) { + SpatiallyNestable::setPosition(position); + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + entity->requiresRecalcBoxes(); + }); +} + +void EntityItem::setLocalPosition(const glm::vec3& position) { + SpatiallyNestable::setLocalPosition(position); + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + entity->requiresRecalcBoxes(); + }); +} + +void EntityItem::setRotation(const glm::quat& orientation) { + SpatiallyNestable::setOrientation(orientation); + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + entity->requiresRecalcBoxes(); + }); +} + +void EntityItem::setLocalRotation(const glm::quat& orientation) { + SpatiallyNestable::setLocalOrientation(orientation); + forSelfAndEachChildEntity([&](EntityItemPointer entity) { + entity->requiresRecalcBoxes(); + }); +} From 6062691c2a58f42486a1e28d975818582eb8e144 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 26 Nov 2015 07:04:27 -0800 Subject: [PATCH 33/51] minimize diff vs master --- libraries/entities/src/EntityItem.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index d60df17d78..24b0e7f977 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1326,6 +1326,13 @@ void EntityItem::updatePosition(const glm::vec3& value) { } } +void EntityItem::updateDimensions(const glm::vec3& value) { + if (getDimensions() != value) { + setDimensions(value); + _dirtyFlags |= (Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); + } +} + void EntityItem::updateRotation(const glm::quat& rotation) { if (shouldSuppressLocationEdits()) { return; @@ -1341,13 +1348,6 @@ void EntityItem::updateRotation(const glm::quat& rotation) { } } -void EntityItem::updateDimensions(const glm::vec3& value) { - if (getDimensions() != value) { - setDimensions(value); - _dirtyFlags |= (Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); - } -} - void EntityItem::updateMass(float mass) { // Setting the mass actually changes the _density (at fixed volume), however // we must protect the density range to help maintain stability of physics simulation From facf91faacf7cf6f9e5ec85ed2b91f4b7fcd8191 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 26 Nov 2015 07:13:43 -0800 Subject: [PATCH 34/51] minimize diff vs master --- libraries/avatars/src/AvatarData.cpp | 82 ++++++++++++++-------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index f7def48b9d..adfd10b2af 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -87,47 +87,6 @@ const QUrl& AvatarData::defaultFullAvatarModelUrl() { return _defaultFullAvatarModelUrl; } -float AvatarData::getBodyYaw() const { - glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); - return eulerAngles.y; -} - -void AvatarData::setBodyYaw(float bodyYaw) { - glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); - eulerAngles.y = bodyYaw; - setOrientation(glm::quat(glm::radians(eulerAngles))); -} - -float AvatarData::getBodyPitch() const { - glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); - return eulerAngles.x; -} - -void AvatarData::setBodyPitch(float bodyPitch) { - glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); - eulerAngles.x = bodyPitch; - setOrientation(glm::quat(glm::radians(eulerAngles))); -} - -float AvatarData::getBodyRoll() const { - glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); - return eulerAngles.z; -} - -void AvatarData::setBodyRoll(float bodyRoll) { - glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); - eulerAngles.z = bodyRoll; - setOrientation(glm::quat(glm::radians(eulerAngles))); -} - -void AvatarData::setPosition(const glm::vec3& position) { - SpatiallyNestable::setPosition(position); -} - -void AvatarData::setOrientation(const glm::quat& orientation) { - SpatiallyNestable::setOrientation(orientation); -} - // There are a number of possible strategies for this set of tools through endRender, below. void AvatarData::nextAttitude(glm::vec3 position, glm::quat orientation) { avatarLock.lock(); @@ -1616,3 +1575,44 @@ void AvatarData::fromFrame(const QByteArray& frameData, AvatarData& result) { #endif result.fromJson(doc.object()); } + +float AvatarData::getBodyYaw() const { + glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); + return eulerAngles.y; +} + +void AvatarData::setBodyYaw(float bodyYaw) { + glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); + eulerAngles.y = bodyYaw; + setOrientation(glm::quat(glm::radians(eulerAngles))); +} + +float AvatarData::getBodyPitch() const { + glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); + return eulerAngles.x; +} + +void AvatarData::setBodyPitch(float bodyPitch) { + glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); + eulerAngles.x = bodyPitch; + setOrientation(glm::quat(glm::radians(eulerAngles))); +} + +float AvatarData::getBodyRoll() const { + glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); + return eulerAngles.z; +} + +void AvatarData::setBodyRoll(float bodyRoll) { + glm::vec3 eulerAngles = glm::degrees(safeEulerAngles(getOrientation())); + eulerAngles.z = bodyRoll; + setOrientation(glm::quat(glm::radians(eulerAngles))); +} + +void AvatarData::setPosition(const glm::vec3& position) { + SpatiallyNestable::setPosition(position); +} + +void AvatarData::setOrientation(const glm::quat& orientation) { + SpatiallyNestable::setOrientation(orientation); +} From eb50c9de5f7b74966e0a07822c08db12ea620154 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 29 Nov 2015 10:16:56 -0800 Subject: [PATCH 35/51] aabox delivered to scripts in properties should be in world space --- libraries/entities/src/EntityItemProperties.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 8fa760930c..a1ce826072 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1491,10 +1491,12 @@ AABox EntityItemProperties::getAABox() const { glm::vec3 unrotatedMinRelativeToEntity = - (_dimensions * _registrationPoint); glm::vec3 unrotatedMaxRelativeToEntity = _dimensions * registrationRemainder; Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity }; - Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation()); + glm::quat worldRotation = SpatiallyNestable::localToWorld(getRotation(), _parentID, _parentJointIndex); + Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(worldRotation); // shift the extents to be relative to the position/registration point - rotatedExtentsRelativeToRegistrationPoint.shiftBy(_position); + glm::vec3 worldPosition = SpatiallyNestable::localToWorld(_position, _parentID, _parentJointIndex); + rotatedExtentsRelativeToRegistrationPoint.shiftBy(worldPosition); return AABox(rotatedExtentsRelativeToRegistrationPoint); } From 204c3d839e487775542ffa3adf1d1b4aa6fb9cf9 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 29 Nov 2015 10:17:21 -0800 Subject: [PATCH 36/51] added localToWorld calls, put locks around access to _children hashtable --- libraries/shared/src/SpatiallyNestable.cpp | 53 +++++++++++++++++++--- libraries/shared/src/SpatiallyNestable.h | 6 +++ 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 87ef7565fb..f5d05a77ad 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -76,11 +76,15 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { } void SpatiallyNestable::beParentOfChild(SpatiallyNestablePointer newChild) const { - _children[newChild->getID()] = newChild; + _childrenLock.withWriteLock([&] { + _children[newChild->getID()] = newChild; + }); } void SpatiallyNestable::forgetChild(SpatiallyNestablePointer newChild) const { - _children.remove(newChild->getID()); + _childrenLock.withWriteLock([&] { + _children.remove(newChild->getID()); + }); } void SpatiallyNestable::setParentID(const QUuid& parentID) { @@ -110,6 +114,39 @@ glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation) { return result.getRotation(); } +glm::vec3 SpatiallyNestable::localToWorld(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 result; + Transform::mult(result, parentTransform, positionTransform); + return result.getTranslation(); +} + +glm::quat SpatiallyNestable::localToWorld(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 result; + Transform::mult(result, parentTransform, orientationTransform); + return result.getRotation(); +} + + const glm::vec3& SpatiallyNestable::getPosition() const { Transform parentTransformDescaled = getParentTransform(); glm::mat4 parentMat; @@ -223,12 +260,14 @@ void SpatiallyNestable::setLocalScale(const glm::vec3& scale) { QList SpatiallyNestable::getChildren() const { QList children; - foreach (SpatiallyNestableWeakPointer childWP, _children.values()) { - SpatiallyNestablePointer child = childWP.lock(); - if (child) { - children << child; + _childrenLock.withReadLock([&] { + foreach (SpatiallyNestableWeakPointer childWP, _children.values()) { + SpatiallyNestablePointer child = childWP.lock(); + if (child) { + children << child; + } } - } + }); return children; } diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 30602d26b4..74d9cc9a95 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -16,6 +16,7 @@ #include "Transform.h" #include "SpatialParentFinder.h" +#include "shared/ReadWriteLockable.h" class SpatiallyNestable; @@ -49,6 +50,9 @@ public: glm::vec3 worldToLocal(const glm::vec3& position); glm::quat worldToLocal(const glm::quat& orientation); + static glm::vec3 localToWorld(const glm::vec3& position, QUuid parentID, int parentJointIndex); + static glm::quat localToWorld(const glm::quat& orientation, QUuid parentID, int parentJointIndex); + // world frame virtual const Transform& getTransform() const; virtual void setTransform(const Transform& transform); @@ -101,6 +105,8 @@ protected: virtual void beParentOfChild(SpatiallyNestablePointer newChild) const; virtual void forgetChild(SpatiallyNestablePointer newChild) const; + + mutable ReadWriteLockable _childrenLock; mutable QHash _children; virtual void parentChanged() {} // called when parent pointer is updated From cf39cac7fcfb24b38a47228ad8cc46d280d68970 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 29 Nov 2015 12:50:33 -0800 Subject: [PATCH 37/51] attempt to make SpatiallyNestable data access thread-safe --- interface/src/Application.cpp | 2 +- interface/src/Application.h | 2 +- interface/src/avatar/Avatar.cpp | 4 +- interface/src/avatar/Avatar.h | 4 +- libraries/avatars/src/AvatarData.cpp | 4 +- libraries/avatars/src/AvatarData.h | 4 +- .../src/RenderableModelEntityItem.cpp | 2 +- .../src/RenderableModelEntityItem.h | 2 +- libraries/entities/src/EntityItem.cpp | 38 ++-- libraries/entities/src/EntityItem.h | 20 +- libraries/entities/src/LightEntityItem.cpp | 2 +- libraries/entities/src/LightEntityItem.h | 2 +- libraries/entities/src/TextEntityItem.cpp | 2 +- libraries/entities/src/TextEntityItem.h | 2 +- libraries/entities/src/WebEntityItem.cpp | 2 +- libraries/entities/src/WebEntityItem.h | 2 +- .../src/AbstractViewStateInterface.h | 2 +- libraries/shared/src/SpatiallyNestable.cpp | 182 +++++++++++------- libraries/shared/src/SpatiallyNestable.h | 62 +++--- 19 files changed, 187 insertions(+), 153 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1088426fcc..f5781e727d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3329,7 +3329,7 @@ MyAvatar* Application::getMyAvatar() const { return DependencyManager::get()->getMyAvatar(); } -const glm::vec3& Application::getAvatarPosition() const { +const glm::vec3 Application::getAvatarPosition() const { return getMyAvatar()->getPosition(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 730158c689..0467926b47 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -185,7 +185,7 @@ public: virtual float getSizeScale() const; virtual int getBoundaryLevelAdjust() const; virtual PickRay computePickRay(float x, float y) const; - virtual const glm::vec3& getAvatarPosition() const; + virtual const glm::vec3 getAvatarPosition() const; virtual void overrideEnvironmentData(const EnvironmentData& newData) { _environment.override(newData); } virtual void endOverrideEnvironmentData() { _environment.endOverride(); } virtual qreal getDevicePixelRatio(); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 5aa6936fee..763d44274d 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -1212,12 +1212,12 @@ glm::quat Avatar::getRightPalmRotation() { return rightRotation; } -void Avatar::setPosition(const glm::vec3& position) { +void Avatar::setPosition(const glm::vec3 position) { AvatarData::setPosition(position); updateAttitude(); } -void Avatar::setOrientation(const glm::quat& orientation) { +void Avatar::setOrientation(const glm::quat orientation) { AvatarData::setOrientation(orientation); updateAttitude(); } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index c19efe032b..51768e4e71 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -161,8 +161,8 @@ public: void setMotionState(AvatarMotionState* motionState) { _motionState = motionState; } AvatarMotionState* getMotionState() { return _motionState; } - virtual void setPosition(const glm::vec3& position); - virtual void setOrientation(const glm::quat& orientation); + virtual void setPosition(const glm::vec3 position); + virtual void setOrientation(const glm::quat orientation); public slots: diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index adfd10b2af..ec363756f6 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -1609,10 +1609,10 @@ void AvatarData::setBodyRoll(float bodyRoll) { setOrientation(glm::quat(glm::radians(eulerAngles))); } -void AvatarData::setPosition(const glm::vec3& position) { +void AvatarData::setPosition(const glm::vec3 position) { SpatiallyNestable::setPosition(position); } -void AvatarData::setOrientation(const glm::quat& orientation) { +void AvatarData::setOrientation(const glm::quat orientation) { SpatiallyNestable::setOrientation(orientation); } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 9b684ec989..8db0ef5897 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -201,8 +201,8 @@ public: float getBodyRoll() const; void setBodyRoll(float bodyRoll); - virtual void setPosition(const glm::vec3& position); - virtual void setOrientation(const glm::quat& orientation); + virtual void setPosition(const glm::vec3 position); + virtual void setOrientation(const glm::quat orientation); void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time. void startCapture(); // start/end of the period in which the latest values are about to be captured for camera, etc. diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index bf3b2e7e95..393c0dc0dc 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -44,7 +44,7 @@ RenderableModelEntityItem::~RenderableModelEntityItem() { } } -void RenderableModelEntityItem::setDimensions(const glm::vec3& value) { +void RenderableModelEntityItem::setDimensions(const glm::vec3 value) { _dimensionsInitialized = true; ModelEntityItem::setDimensions(value); } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 2187c0edb3..b86692753c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -28,7 +28,7 @@ public: virtual ~RenderableModelEntityItem(); - virtual void setDimensions(const glm::vec3& value) override; + virtual void setDimensions(const glm::vec3 value) override; virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const; virtual bool setProperties(const EntityItemProperties& properties); diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 24b0e7f977..64b4fc5088 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1188,7 +1188,7 @@ const Transform EntityItem::getTransformToCenter() const { return result; } -void EntityItem::setDimensions(const glm::vec3& value) { +void EntityItem::setDimensions(const glm::vec3 value) { if (value.x <= 0.0f || value.y <= 0.0f || value.z <= 0.0f) { return; } @@ -1860,44 +1860,44 @@ void EntityItem::parentChanged() { }); } -void EntityItem::setTransform(const Transform& transform) { +void EntityItem::setTransform(const Transform transform) { SpatiallyNestable::setTransform(transform); forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); + entity->requiresRecalcBoxes(); + }); } -void EntityItem::setLocalTransform(const Transform& transform) { +void EntityItem::setLocalTransform(const Transform transform) { SpatiallyNestable::setLocalTransform(transform); forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); + entity->requiresRecalcBoxes(); + }); } -void EntityItem::setPosition(const glm::vec3& position) { +void EntityItem::setPosition(const glm::vec3 position) { SpatiallyNestable::setPosition(position); forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); + entity->requiresRecalcBoxes(); + }); } -void EntityItem::setLocalPosition(const glm::vec3& position) { +void EntityItem::setLocalPosition(const glm::vec3 position) { SpatiallyNestable::setLocalPosition(position); forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); + entity->requiresRecalcBoxes(); + }); } -void EntityItem::setRotation(const glm::quat& orientation) { +void EntityItem::setRotation(const glm::quat orientation) { SpatiallyNestable::setOrientation(orientation); forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); + entity->requiresRecalcBoxes(); + }); } -void EntityItem::setLocalRotation(const glm::quat& orientation) { +void EntityItem::setLocalRotation(const glm::quat orientation) { SpatiallyNestable::setLocalOrientation(orientation); forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); + entity->requiresRecalcBoxes(); + }); } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 855f9568f1..cd5f97bee2 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -196,8 +196,8 @@ public: void setDescription(QString value) { _description = value; } /// Dimensions in meters (0.0 - TREE_SCALE) - inline const glm::vec3& getDimensions() const { return getScale(); } - virtual void setDimensions(const glm::vec3& value); + inline const glm::vec3 getDimensions() const { return getScale(); } + virtual void setDimensions(const glm::vec3 value); float getGlowLevel() const { return _glowLevel; } void setGlowLevel(float glowLevel) { _glowLevel = glowLevel; } @@ -325,15 +325,15 @@ public: /// return preferred shape type (actual physical shape may differ) virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; } - virtual void setTransform(const Transform& transform); - virtual void setLocalTransform(const Transform& transform); - // virtual const glm::vec3& getPosition() const { return SpatiallyNestable::getPosition(); } - virtual const glm::quat& getRotation() const { return SpatiallyNestable::getOrientation(); } + virtual void setTransform(const Transform transform); + virtual void setLocalTransform(const Transform transform); + // virtual const glm::vec3 getPosition() const { return SpatiallyNestable::getPosition(); } + virtual const glm::quat getRotation() const { return SpatiallyNestable::getOrientation(); } - virtual void setPosition(const glm::vec3& position); - virtual void setLocalPosition(const glm::vec3& position); - virtual void setRotation(const glm::quat& orientation); - virtual void setLocalRotation(const glm::quat& orientation); + virtual void setPosition(const glm::vec3 position); + virtual void setLocalPosition(const glm::vec3 position); + virtual void setRotation(const glm::quat orientation); + virtual void setLocalRotation(const glm::quat orientation); // updateFoo() methods to be used when changes need to be accumulated in the _dirtyFlags void updatePosition(const glm::vec3& value); diff --git a/libraries/entities/src/LightEntityItem.cpp b/libraries/entities/src/LightEntityItem.cpp index ac56fc9c1f..af3110c000 100644 --- a/libraries/entities/src/LightEntityItem.cpp +++ b/libraries/entities/src/LightEntityItem.cpp @@ -40,7 +40,7 @@ LightEntityItem::LightEntityItem(const EntityItemID& entityItemID) : EntityItem( _cutoff = PI; } -void LightEntityItem::setDimensions(const glm::vec3& value) { +void LightEntityItem::setDimensions(const glm::vec3 value) { if (_isSpotlight) { // If we are a spotlight, treat the z value as our radius or length, and // recalculate the x/y dimensions to properly encapsulate the spotlight. diff --git a/libraries/entities/src/LightEntityItem.h b/libraries/entities/src/LightEntityItem.h index 103c462809..edb2ca7b3c 100644 --- a/libraries/entities/src/LightEntityItem.h +++ b/libraries/entities/src/LightEntityItem.h @@ -23,7 +23,7 @@ public: ALLOW_INSTANTIATION // This class can be instantiated /// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately - virtual void setDimensions(const glm::vec3& value); + virtual void setDimensions(const glm::vec3 value); // methods for getting/setting all properties of an entity virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const; diff --git a/libraries/entities/src/TextEntityItem.cpp b/libraries/entities/src/TextEntityItem.cpp index 893329d1ce..7d1cfb5c6b 100644 --- a/libraries/entities/src/TextEntityItem.cpp +++ b/libraries/entities/src/TextEntityItem.cpp @@ -41,7 +41,7 @@ TextEntityItem::TextEntityItem(const EntityItemID& entityItemID) : EntityItem(en const float TEXT_ENTITY_ITEM_FIXED_DEPTH = 0.01f; -void TextEntityItem::setDimensions(const glm::vec3& value) { +void TextEntityItem::setDimensions(const glm::vec3 value) { // NOTE: Text Entities always have a "depth" of 1cm. EntityItem::setDimensions(glm::vec3(value.x, value.y, TEXT_ENTITY_ITEM_FIXED_DEPTH)); } diff --git a/libraries/entities/src/TextEntityItem.h b/libraries/entities/src/TextEntityItem.h index 1caceee085..2080912d92 100644 --- a/libraries/entities/src/TextEntityItem.h +++ b/libraries/entities/src/TextEntityItem.h @@ -23,7 +23,7 @@ public: ALLOW_INSTANTIATION // This class can be instantiated /// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately - virtual void setDimensions(const glm::vec3& value); + virtual void setDimensions(const glm::vec3 value); virtual ShapeType getShapeType() const { return SHAPE_TYPE_BOX; } // methods for getting/setting all properties of an entity diff --git a/libraries/entities/src/WebEntityItem.cpp b/libraries/entities/src/WebEntityItem.cpp index 5f113f1de4..35189074bb 100644 --- a/libraries/entities/src/WebEntityItem.cpp +++ b/libraries/entities/src/WebEntityItem.cpp @@ -34,7 +34,7 @@ WebEntityItem::WebEntityItem(const EntityItemID& entityItemID) : EntityItem(enti const float WEB_ENTITY_ITEM_FIXED_DEPTH = 0.01f; -void WebEntityItem::setDimensions(const glm::vec3& value) { +void WebEntityItem::setDimensions(const glm::vec3 value) { // NOTE: Web Entities always have a "depth" of 1cm. EntityItem::setDimensions(glm::vec3(value.x, value.y, WEB_ENTITY_ITEM_FIXED_DEPTH)); } diff --git a/libraries/entities/src/WebEntityItem.h b/libraries/entities/src/WebEntityItem.h index 8e9d924cde..49ab009bb2 100644 --- a/libraries/entities/src/WebEntityItem.h +++ b/libraries/entities/src/WebEntityItem.h @@ -22,7 +22,7 @@ public: ALLOW_INSTANTIATION // This class can be instantiated /// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately - virtual void setDimensions(const glm::vec3& value); + virtual void setDimensions(const glm::vec3 value); virtual ShapeType getShapeType() const { return SHAPE_TYPE_BOX; } // methods for getting/setting all properties of an entity diff --git a/libraries/render-utils/src/AbstractViewStateInterface.h b/libraries/render-utils/src/AbstractViewStateInterface.h index b65289933c..2954c1fce4 100644 --- a/libraries/render-utils/src/AbstractViewStateInterface.h +++ b/libraries/render-utils/src/AbstractViewStateInterface.h @@ -45,7 +45,7 @@ public: virtual int getBoundaryLevelAdjust() const = 0; virtual PickRay computePickRay(float x, float y) const = 0; - virtual const glm::vec3& getAvatarPosition() const = 0; + virtual const glm::vec3 getAvatarPosition() const = 0; virtual void postLambdaEvent(std::function f) = 0; virtual qreal getDevicePixelRatio() = 0; diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index f5d05a77ad..d5e2104706 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -87,34 +87,38 @@ void SpatiallyNestable::forgetChild(SpatiallyNestablePointer newChild) const { }); } -void SpatiallyNestable::setParentID(const QUuid& parentID) { +void SpatiallyNestable::setParentID(const QUuid parentID) { if (_parentID != parentID) { _parentID = parentID; _parentKnowsMe = false; } } -glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position) { +glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3 position) { Transform parentTransform = getParentTransform(); Transform myWorldTransform; - Transform::mult(myWorldTransform, parentTransform, _transform); + _transformLock.withReadLock([&] { + Transform::mult(myWorldTransform, parentTransform, _transform); + }); myWorldTransform.setTranslation(position); Transform result; Transform::inverseMult(result, parentTransform, myWorldTransform); return result.getTranslation(); } -glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation) { +glm::quat SpatiallyNestable::worldToLocal(const glm::quat orientation) { Transform parentTransform = getParentTransform(); Transform myWorldTransform; - Transform::mult(myWorldTransform, parentTransform, _transform); + _transformLock.withReadLock([&] { + Transform::mult(myWorldTransform, parentTransform, _transform); + }); myWorldTransform.setRotation(orientation); Transform result; Transform::inverseMult(result, parentTransform, myWorldTransform); return result.getRotation(); } -glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position, QUuid parentID, int parentJointIndex) { +glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3 position, QUuid parentID, int parentJointIndex) { QSharedPointer parentFinder = DependencyManager::get(); auto parentWP = parentFinder->find(parentID); auto parent = parentWP.lock(); @@ -130,7 +134,7 @@ glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position, QUuid paren return result.getTranslation(); } -glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation, QUuid parentID, int parentJointIndex) { +glm::quat SpatiallyNestable::localToWorld(const glm::quat orientation, QUuid parentID, int parentJointIndex) { QSharedPointer parentFinder = DependencyManager::get(); auto parentWP = parentFinder->find(parentID); auto parent = parentWP.lock(); @@ -147,115 +151,152 @@ glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation, QUuid pa } -const glm::vec3& SpatiallyNestable::getPosition() const { +const glm::vec3 SpatiallyNestable::getPosition() const { Transform parentTransformDescaled = getParentTransform(); glm::mat4 parentMat; parentTransformDescaled.getMatrix(parentMat); glm::vec4 absPos = parentMat * glm::vec4(getLocalPosition(), 1.0f); - _absolutePositionCache = glm::vec3(absPos); - return _absolutePositionCache; + return glm::vec3(absPos); } -const glm::vec3& SpatiallyNestable::getPosition(int jointIndex) const { - getTransform(); // update _worldTransformCache - getJointTransformInObjectFrame(jointIndex); // update _jointInObjectFrameCache - _jointInWorldFrameCache.resize(jointIndex); - Transform::mult(_jointInWorldFrameCache[jointIndex], _worldTransformCache, _jointInObjectFrameCache[jointIndex]); - return _jointInWorldFrameCache[jointIndex].getTranslation(); +const glm::vec3 SpatiallyNestable::getPosition(int jointIndex) const { + Transform worldTransform = getTransform(); + Transform jointInObjectFrame = getJointTransformInObjectFrame(jointIndex); + Transform jointInWorldFrame; + Transform::mult(jointInWorldFrame, worldTransform, jointInObjectFrame); + return jointInWorldFrame.getTranslation(); } -void SpatiallyNestable::setPosition(const glm::vec3& position) { +void SpatiallyNestable::setPosition(const glm::vec3 position) { Transform parentTransform = getParentTransform(); Transform myWorldTransform; - Transform::mult(myWorldTransform, parentTransform, _transform); - myWorldTransform.setTranslation(position); - Transform::inverseMult(_transform, parentTransform, myWorldTransform); + _transformLock.withWriteLock([&] { + Transform::mult(myWorldTransform, parentTransform, _transform); + myWorldTransform.setTranslation(position); + Transform::inverseMult(_transform, parentTransform, myWorldTransform); + }); } -const glm::quat& SpatiallyNestable::getOrientation() const { +const glm::quat SpatiallyNestable::getOrientation() const { Transform parentTransformDescaled = getParentTransform(); - _absoluteRotationCache = parentTransformDescaled.getRotation() * getLocalOrientation(); - return _absoluteRotationCache; + return parentTransformDescaled.getRotation() * getLocalOrientation(); } -const glm::quat& SpatiallyNestable::getOrientation(int jointIndex) const { - getTransform(); // update _worldTransformCache - getJointTransformInObjectFrame(jointIndex); // update _jointInObjectFrameCache - _jointInWorldFrameCache.resize(jointIndex + 1); - Transform::mult(_jointInWorldFrameCache[jointIndex], _worldTransformCache, _jointInObjectFrameCache[jointIndex]); - return _jointInWorldFrameCache[jointIndex].getRotation(); +const glm::quat SpatiallyNestable::getOrientation(int jointIndex) const { + Transform worldTransform = getTransform(); + Transform jointInObjectFrame = getJointTransformInObjectFrame(jointIndex); + Transform jointInWorldFrame; + Transform::mult(jointInWorldFrame, worldTransform, jointInObjectFrame); + return jointInWorldFrame.getRotation(); } -void SpatiallyNestable::setOrientation(const glm::quat& orientation) { +void SpatiallyNestable::setOrientation(const glm::quat orientation) { Transform parentTransform = getParentTransform(); Transform myWorldTransform; - Transform::mult(myWorldTransform, parentTransform, _transform); - myWorldTransform.setRotation(orientation); - Transform::inverseMult(_transform, parentTransform, myWorldTransform); + _transformLock.withWriteLock([&] { + Transform::mult(myWorldTransform, parentTransform, _transform); + myWorldTransform.setRotation(orientation); + Transform::inverseMult(_transform, parentTransform, myWorldTransform); + }); } -const Transform& SpatiallyNestable::getTransform() const { +const Transform SpatiallyNestable::getTransform() const { Transform parentTransform = getParentTransform(); - Transform::mult(_worldTransformCache, parentTransform, _transform); - return _worldTransformCache; + Transform result; + _transformLock.withReadLock([&] { + Transform::mult(result, parentTransform, _transform); + }); + return result; } -const Transform& SpatiallyNestable::getTransform(int jointIndex) const { - getTransform(); // update _worldTransformCache - getJointTransformInObjectFrame(jointIndex); // update _jointInObjectFrameCache - _jointInWorldFrameCache.resize(jointIndex + 1); - Transform::mult(_jointInWorldFrameCache[jointIndex], _worldTransformCache, _jointInObjectFrameCache[jointIndex]); - return _jointInWorldFrameCache[jointIndex]; +const Transform SpatiallyNestable::getTransform(int jointIndex) const { + Transform worldTransform = getTransform(); + Transform jointInObjectFrame = getJointTransformInObjectFrame(jointIndex); + Transform jointInWorldFrame; + Transform::mult(jointInWorldFrame, worldTransform, jointInObjectFrame); + return jointInWorldFrame; } -void SpatiallyNestable::setTransform(const Transform& transform) { +void SpatiallyNestable::setTransform(const Transform transform) { Transform parentTransform = getParentTransform(); - Transform::inverseMult(_transform, parentTransform, transform); + _transformLock.withWriteLock([&] { + Transform::inverseMult(_transform, parentTransform, transform); + }); } -const glm::vec3& SpatiallyNestable::getScale() const { - return _transform.getScale(); +const glm::vec3 SpatiallyNestable::getScale() const { + glm::vec3 result; + _transformLock.withReadLock([&] { + result = _transform.getScale(); + }); + return result; } -const glm::vec3& SpatiallyNestable::getScale(int jointIndex) const { +const glm::vec3 SpatiallyNestable::getScale(int jointIndex) const { // XXX ... something with joints return getScale(); } -void SpatiallyNestable::setScale(const glm::vec3& scale) { - _transform.setScale(scale); +void SpatiallyNestable::setScale(const glm::vec3 scale) { + _transformLock.withWriteLock([&] { + _transform.setScale(scale); + }); } -const Transform& SpatiallyNestable::getLocalTransform() const { - return _transform; +const Transform SpatiallyNestable::getLocalTransform() const { + Transform result; + _transformLock.withReadLock([&] { + result =_transform; + }); + return result; } -void SpatiallyNestable::setLocalTransform(const Transform& transform) { - _transform = transform; +void SpatiallyNestable::setLocalTransform(const Transform transform) { + _transformLock.withWriteLock([&] { + _transform = transform; + }); } -const glm::vec3& SpatiallyNestable::getLocalPosition() const { - return _transform.getTranslation(); +const glm::vec3 SpatiallyNestable::getLocalPosition() const { + glm::vec3 result; + _transformLock.withReadLock([&] { + result = _transform.getTranslation(); + }); + return result; } -void SpatiallyNestable::setLocalPosition(const glm::vec3& position) { - _transform.setTranslation(position); +void SpatiallyNestable::setLocalPosition(const glm::vec3 position) { + _transformLock.withWriteLock([&] { + _transform.setTranslation(position); + }); } -const glm::quat& SpatiallyNestable::getLocalOrientation() const { - return _transform.getRotation(); +const glm::quat SpatiallyNestable::getLocalOrientation() const { + glm::quat result; + _transformLock.withReadLock([&] { + result = _transform.getRotation(); + }); + return result; } -void SpatiallyNestable::setLocalOrientation(const glm::quat& orientation) { - _transform.setRotation(orientation); +void SpatiallyNestable::setLocalOrientation(const glm::quat orientation) { + _transformLock.withWriteLock([&] { + _transform.setRotation(orientation); + }); } -const glm::vec3& SpatiallyNestable::getLocalScale() const { - return _transform.getScale(); +const glm::vec3 SpatiallyNestable::getLocalScale() const { + glm::vec3 result; + _transformLock.withReadLock([&] { + result = _transform.getScale(); + }); + return result; } -void SpatiallyNestable::setLocalScale(const glm::vec3& scale) { - _transform.setScale(scale); +void SpatiallyNestable::setLocalScale(const glm::vec3 scale) { + _transformLock.withWriteLock([&] { + _transform.setScale(scale); + }); } QList SpatiallyNestable::getChildren() const { @@ -272,12 +313,11 @@ QList SpatiallyNestable::getChildren() const { } -const Transform& SpatiallyNestable::getJointTransformInObjectFrame(int jointIndex) const { - _jointInObjectFrameCache.resize(jointIndex + 1); - _jointInObjectFrameCache[jointIndex] = Transform(); +const Transform SpatiallyNestable::getJointTransformInObjectFrame(int jointIndex) const { + Transform jointInObjectFrame; glm::vec3 position = getJointTranslation(jointIndex); glm::quat orientation = getJointRotation(jointIndex); - _jointInObjectFrameCache[jointIndex].setRotation(orientation); - _jointInObjectFrameCache[jointIndex].setTranslation(position); - return _jointInObjectFrameCache[jointIndex]; + jointInObjectFrame.setRotation(orientation); + jointInObjectFrame.setTranslation(position); + return jointInObjectFrame; } diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 74d9cc9a95..5074779d8e 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -41,57 +41,57 @@ public: virtual const QUuid& getID() const { return _id; } virtual void setID(const QUuid& id) { _id = id; } - virtual const QUuid& getParentID() const { return _parentID; } - virtual void setParentID(const QUuid& parentID); + virtual const QUuid getParentID() const { return _parentID; } + virtual void setParentID(const QUuid parentID); 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); + glm::vec3 worldToLocal(const glm::vec3 position); + glm::quat worldToLocal(const glm::quat orientation); - static glm::vec3 localToWorld(const glm::vec3& position, QUuid parentID, int parentJointIndex); - static glm::quat localToWorld(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); // world frame - virtual const Transform& getTransform() const; - virtual void setTransform(const Transform& transform); + virtual const Transform getTransform() const; + virtual void setTransform(const Transform transform); virtual Transform getParentTransform() const; - virtual const glm::vec3& getPosition() const; - virtual void setPosition(const glm::vec3& position); + virtual const glm::vec3 getPosition() const; + virtual void setPosition(const glm::vec3 position); - virtual const glm::quat& getOrientation() const; - virtual const glm::quat& getOrientation(int jointIndex) const; - virtual void setOrientation(const glm::quat& orientation); + virtual const glm::quat getOrientation() const; + virtual const glm::quat getOrientation(int jointIndex) const; + virtual void setOrientation(const glm::quat orientation); - virtual const glm::vec3& getScale() const; - virtual void setScale(const glm::vec3& scale); + virtual const glm::vec3 getScale() const; + virtual void setScale(const glm::vec3 scale); // get world location of a specific joint - virtual const Transform& getTransform(int jointIndex) const; - virtual const glm::vec3& getPosition(int jointIndex) const; - virtual const glm::vec3& getScale(int jointIndex) const; + virtual const Transform getTransform(int jointIndex) const; + virtual const glm::vec3 getPosition(int jointIndex) const; + virtual const glm::vec3 getScale(int jointIndex) const; // object's parent's frame - virtual const Transform& getLocalTransform() const; - virtual void setLocalTransform(const Transform& transform); + virtual const Transform getLocalTransform() const; + virtual void setLocalTransform(const Transform transform); - virtual const glm::vec3& getLocalPosition() const; - virtual void setLocalPosition(const glm::vec3& position); + virtual const glm::vec3 getLocalPosition() const; + virtual void setLocalPosition(const glm::vec3 position); - virtual const glm::quat& getLocalOrientation() const; - virtual void setLocalOrientation(const glm::quat& orientation); + virtual const glm::quat getLocalOrientation() const; + virtual void setLocalOrientation(const glm::quat orientation); - virtual const glm::vec3& getLocalScale() const; - virtual void setLocalScale(const glm::vec3& scale); + virtual const glm::vec3 getLocalScale() const; + virtual void setLocalScale(const glm::vec3 scale); QList getChildren() const; NestableTypes::NestableType getNestableType() const { return _nestableType; } // this object's frame - virtual const Transform& getJointTransformInObjectFrame(int jointIndex) const; + virtual const Transform getJointTransformInObjectFrame(int jointIndex) const; virtual glm::quat getJointRotation(int index) const = 0; virtual glm::vec3 getJointTranslation(int index) const = 0; @@ -112,15 +112,9 @@ protected: virtual void parentChanged() {} // called when parent pointer is updated private: + mutable ReadWriteLockable _transformLock; Transform _transform; // this is to be combined with parent's world-transform to produce this' world-transform. - - // these are so we can return by reference - mutable glm::vec3 _absolutePositionCache; - mutable glm::quat _absoluteRotationCache; - mutable Transform _worldTransformCache; mutable bool _parentKnowsMe = false; - mutable QVector _jointInObjectFrameCache; - mutable QVector _jointInWorldFrameCache; }; From bbc9d5d1317ad655aa9ff5c3209770537ad9d62a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 29 Nov 2015 13:04:45 -0800 Subject: [PATCH 38/51] add missing single-quote --- examples/html/entityProperties.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 50fb205e3d..9c1c37d2f6 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -670,7 +670,7 @@ elDimensionsY.addEventListener('change', dimensionsChangeFunction); elDimensionsZ.addEventListener('change', dimensionsChangeFunction); - elParentID.addEventListener('change', createEmitTextPropertyUpdateFunction('parentID)); + elParentID.addEventListener('change', createEmitTextPropertyUpdateFunction('parentID')); var registrationChangeFunction = createEmitVec3PropertyUpdateFunction( 'registrationPoint', elRegistrationX, elRegistrationY, elRegistrationZ); From 9548b0e138e0b9ec840c3fa4f8268655ff028420 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 29 Nov 2015 13:38:27 -0800 Subject: [PATCH 39/51] get parent-id field working --- examples/html/entityProperties.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 9c1c37d2f6..bef5c825c2 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -225,7 +225,7 @@ var elRescaleDimensionsPct = document.getElementById("dimension-rescale-pct"); var elRescaleDimensionsButton = document.getElementById("dimension-rescale-button"); - var elParentID = document.getElementById("parent-id"); + var elParentID = document.getElementById("property-parent-id"); var elRegistrationX = document.getElementById("property-reg-x"); var elRegistrationY = document.getElementById("property-reg-y"); From 4add3e2e91dadb14b786b1851ea2ce0c9927565a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 30 Nov 2015 09:41:15 -0800 Subject: [PATCH 40/51] rework worldToLocal, start on allowing scripts entity position/rotation to always be in world space --- .../entities/src/EntityItemProperties.cpp | 9 +++- libraries/entities/src/EntityItemProperties.h | 4 ++ libraries/entities/src/EntityPropertyFlags.h | 3 ++ .../entities/src/EntityScriptingInterface.cpp | 48 +++++++++++++++++++ libraries/physics/src/EntityMotionState.cpp | 5 +- libraries/shared/src/SpatiallyNestable.cpp | 37 ++++++++++---- libraries/shared/src/SpatiallyNestable.h | 4 +- 7 files changed, 95 insertions(+), 15 deletions(-) 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); From 4b87e0984806e7d2cb1eb1d4346defd4ddfe2c16 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 30 Nov 2015 13:23:55 -0800 Subject: [PATCH 41/51] clean up some unneeded consts. get edit.js closer to working on parented entities --- .../entities/src/EntityItemProperties.cpp | 8 ++-- libraries/entities/src/EntityItemProperties.h | 2 +- .../entities/src/EntityScriptingInterface.cpp | 16 ++++++-- libraries/shared/src/SpatialParentFinder.h | 2 - libraries/shared/src/SpatiallyNestable.cpp | 38 +++++++++---------- libraries/shared/src/SpatiallyNestable.h | 38 +++++++++---------- 6 files changed, 55 insertions(+), 49 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index d08e677c48..2ecb42a9ce 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -356,7 +356,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool 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); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ROTATION, localRotation); } // Models only @@ -1498,12 +1498,10 @@ AABox EntityItemProperties::getAABox() const { glm::vec3 unrotatedMinRelativeToEntity = - (_dimensions * _registrationPoint); glm::vec3 unrotatedMaxRelativeToEntity = _dimensions * registrationRemainder; Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity }; - glm::quat worldRotation = SpatiallyNestable::localToWorld(getRotation(), _parentID, _parentJointIndex); - Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(worldRotation); + Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(_rotation); // shift the extents to be relative to the position/registration point - glm::vec3 worldPosition = SpatiallyNestable::localToWorld(_position, _parentID, _parentJointIndex); - rotatedExtentsRelativeToRegistrationPoint.shiftBy(worldPosition); + rotatedExtentsRelativeToRegistrationPoint.shiftBy(_position); return AABox(rotatedExtentsRelativeToRegistrationPoint); } diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index bcb48a1903..6bb6b1914c 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -193,7 +193,7 @@ public: 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_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/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 8a8150d017..ca963aca6d 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -113,7 +113,7 @@ EntityItemProperties convertLocationFromScriptSemantics(EntityItemProperties scr QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties) { - EntityItemProperties propertiesWithSimID = properties; + EntityItemProperties propertiesWithSimID = convertLocationFromScriptSemantics(properties); propertiesWithSimID.setDimensionsInitialized(properties.dimensionsChanged()); EntityItemID id = EntityItemID(QUuid::createUuid()); @@ -159,6 +159,15 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit _entityTree->withReadLock([&] { EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(identity)); if (entity) { + if (desiredProperties.getHasProperty(PROP_POSITION) || + desiredProperties.getHasProperty(PROP_ROTATION) || + desiredProperties.getHasProperty(PROP_LOCAL_POSITION) || + desiredProperties.getHasProperty(PROP_LOCAL_ROTATION)) { + // if we are explicitly getting position or rotation, we need parent information to make sense of them. + desiredProperties.setHasProperty(PROP_PARENT_ID); + desiredProperties.setHasProperty(PROP_PARENT_JOINT_INDEX); + } + results = entity->getProperties(desiredProperties); // TODO: improve sitting points and naturalDimensions in the future, @@ -178,10 +187,11 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit }); } - return results; + return convertLocationToScriptSemantics(results); } -QUuid EntityScriptingInterface::editEntity(QUuid id, EntityItemProperties properties) { +QUuid EntityScriptingInterface::editEntity(QUuid id, EntityItemProperties scriptSideProperties) { + EntityItemProperties properties = convertLocationFromScriptSemantics(scriptSideProperties); EntityItemID entityID(id); // If we have a local entity tree set, then also update it. if (!_entityTree) { diff --git a/libraries/shared/src/SpatialParentFinder.h b/libraries/shared/src/SpatialParentFinder.h index 9cadbaf8ce..936d497eae 100644 --- a/libraries/shared/src/SpatialParentFinder.h +++ b/libraries/shared/src/SpatialParentFinder.h @@ -19,8 +19,6 @@ class SpatiallyNestable; using SpatiallyNestableWeakPointer = std::weak_ptr; using SpatiallyNestablePointer = std::shared_ptr; -class SpatialParentFinder; -using SpatialParentFinderPointer = std::shared_ptr; class SpatialParentFinder : public Dependency { diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 4469cfd3c3..31a0dd5647 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -94,7 +94,7 @@ void SpatiallyNestable::setParentID(const QUuid parentID) { } } -glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3 position, QUuid parentID, int parentJointIndex) { +glm::vec3 SpatiallyNestable::worldToLocal(glm::vec3 position, QUuid parentID, int parentJointIndex) { QSharedPointer parentFinder = DependencyManager::get(); auto parentWP = parentFinder->find(parentID); auto parent = parentWP.lock(); @@ -115,7 +115,7 @@ glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3 position, QUuid parent return result.getTranslation(); } -glm::quat SpatiallyNestable::worldToLocal(const glm::quat orientation, QUuid parentID, int parentJointIndex) { +glm::quat SpatiallyNestable::worldToLocal(glm::quat orientation, QUuid parentID, int parentJointIndex) { QSharedPointer parentFinder = DependencyManager::get(); auto parentWP = parentFinder->find(parentID); auto parent = parentWP.lock(); @@ -135,7 +135,7 @@ glm::quat SpatiallyNestable::worldToLocal(const glm::quat orientation, QUuid par return result.getRotation(); } -glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3 position, QUuid parentID, int parentJointIndex) { +glm::vec3 SpatiallyNestable::localToWorld(glm::vec3 position, QUuid parentID, int parentJointIndex) { QSharedPointer parentFinder = DependencyManager::get(); auto parentWP = parentFinder->find(parentID); auto parent = parentWP.lock(); @@ -151,7 +151,7 @@ glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3 position, QUuid parent return result.getTranslation(); } -glm::quat SpatiallyNestable::localToWorld(const glm::quat orientation, QUuid parentID, int parentJointIndex) { +glm::quat SpatiallyNestable::localToWorld(glm::quat orientation, QUuid parentID, int parentJointIndex) { QSharedPointer parentFinder = DependencyManager::get(); auto parentWP = parentFinder->find(parentID); auto parent = parentWP.lock(); @@ -168,7 +168,7 @@ glm::quat SpatiallyNestable::localToWorld(const glm::quat orientation, QUuid par } -const glm::vec3 SpatiallyNestable::getPosition() const { +glm::vec3 SpatiallyNestable::getPosition() const { Transform parentTransformDescaled = getParentTransform(); glm::mat4 parentMat; parentTransformDescaled.getMatrix(parentMat); @@ -176,7 +176,7 @@ const glm::vec3 SpatiallyNestable::getPosition() const { return glm::vec3(absPos); } -const glm::vec3 SpatiallyNestable::getPosition(int jointIndex) const { +glm::vec3 SpatiallyNestable::getPosition(int jointIndex) const { Transform worldTransform = getTransform(); Transform jointInObjectFrame = getJointTransformInObjectFrame(jointIndex); Transform jointInWorldFrame; @@ -184,7 +184,7 @@ const glm::vec3 SpatiallyNestable::getPosition(int jointIndex) const { return jointInWorldFrame.getTranslation(); } -void SpatiallyNestable::setPosition(const glm::vec3 position) { +void SpatiallyNestable::setPosition(glm::vec3 position) { Transform parentTransform = getParentTransform(); Transform myWorldTransform; _transformLock.withWriteLock([&] { @@ -194,12 +194,12 @@ void SpatiallyNestable::setPosition(const glm::vec3 position) { }); } -const glm::quat SpatiallyNestable::getOrientation() const { +glm::quat SpatiallyNestable::getOrientation() const { Transform parentTransformDescaled = getParentTransform(); return parentTransformDescaled.getRotation() * getLocalOrientation(); } -const glm::quat SpatiallyNestable::getOrientation(int jointIndex) const { +glm::quat SpatiallyNestable::getOrientation(int jointIndex) const { Transform worldTransform = getTransform(); Transform jointInObjectFrame = getJointTransformInObjectFrame(jointIndex); Transform jointInWorldFrame; @@ -207,7 +207,7 @@ const glm::quat SpatiallyNestable::getOrientation(int jointIndex) const { return jointInWorldFrame.getRotation(); } -void SpatiallyNestable::setOrientation(const glm::quat orientation) { +void SpatiallyNestable::setOrientation(glm::quat orientation) { Transform parentTransform = getParentTransform(); Transform myWorldTransform; _transformLock.withWriteLock([&] { @@ -241,7 +241,7 @@ void SpatiallyNestable::setTransform(const Transform transform) { }); } -const glm::vec3 SpatiallyNestable::getScale() const { +glm::vec3 SpatiallyNestable::getScale() const { glm::vec3 result; _transformLock.withReadLock([&] { result = _transform.getScale(); @@ -249,12 +249,12 @@ const glm::vec3 SpatiallyNestable::getScale() const { return result; } -const glm::vec3 SpatiallyNestable::getScale(int jointIndex) const { +glm::vec3 SpatiallyNestable::getScale(int jointIndex) const { // XXX ... something with joints return getScale(); } -void SpatiallyNestable::setScale(const glm::vec3 scale) { +void SpatiallyNestable::setScale(glm::vec3 scale) { _transformLock.withWriteLock([&] { _transform.setScale(scale); }); @@ -274,7 +274,7 @@ void SpatiallyNestable::setLocalTransform(const Transform transform) { }); } -const glm::vec3 SpatiallyNestable::getLocalPosition() const { +glm::vec3 SpatiallyNestable::getLocalPosition() const { glm::vec3 result; _transformLock.withReadLock([&] { result = _transform.getTranslation(); @@ -282,13 +282,13 @@ const glm::vec3 SpatiallyNestable::getLocalPosition() const { return result; } -void SpatiallyNestable::setLocalPosition(const glm::vec3 position) { +void SpatiallyNestable::setLocalPosition(glm::vec3 position) { _transformLock.withWriteLock([&] { _transform.setTranslation(position); }); } -const glm::quat SpatiallyNestable::getLocalOrientation() const { +glm::quat SpatiallyNestable::getLocalOrientation() const { glm::quat result; _transformLock.withReadLock([&] { result = _transform.getRotation(); @@ -296,13 +296,13 @@ const glm::quat SpatiallyNestable::getLocalOrientation() const { return result; } -void SpatiallyNestable::setLocalOrientation(const glm::quat orientation) { +void SpatiallyNestable::setLocalOrientation(glm::quat orientation) { _transformLock.withWriteLock([&] { _transform.setRotation(orientation); }); } -const glm::vec3 SpatiallyNestable::getLocalScale() const { +glm::vec3 SpatiallyNestable::getLocalScale() const { glm::vec3 result; _transformLock.withReadLock([&] { result = _transform.getScale(); @@ -310,7 +310,7 @@ const glm::vec3 SpatiallyNestable::getLocalScale() const { return result; } -void SpatiallyNestable::setLocalScale(const glm::vec3 scale) { +void SpatiallyNestable::setLocalScale(glm::vec3 scale) { _transformLock.withWriteLock([&] { _transform.setScale(scale); }); diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index bbef61b93a..962399d080 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -47,11 +47,11 @@ public: virtual quint16 getParentJointIndex() const { return _parentJointIndex; } virtual void setParentJointIndex(quint16 parentJointIndex) { _parentJointIndex = parentJointIndex; } - 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 worldToLocal(glm::vec3 position, QUuid parentID, int parentJointIndex); + static glm::quat worldToLocal(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); + static glm::vec3 localToWorld(glm::vec3 position, QUuid parentID, int parentJointIndex); + static glm::quat localToWorld(glm::quat orientation, QUuid parentID, int parentJointIndex); // world frame virtual const Transform getTransform() const; @@ -59,33 +59,33 @@ public: virtual Transform getParentTransform() const; - virtual const glm::vec3 getPosition() const; - virtual void setPosition(const glm::vec3 position); + virtual glm::vec3 getPosition() const; + virtual void setPosition(glm::vec3 position); - virtual const glm::quat getOrientation() const; - virtual const glm::quat getOrientation(int jointIndex) const; - virtual void setOrientation(const glm::quat orientation); + virtual glm::quat getOrientation() const; + virtual glm::quat getOrientation(int jointIndex) const; + virtual void setOrientation(glm::quat orientation); - virtual const glm::vec3 getScale() const; - virtual void setScale(const glm::vec3 scale); + virtual glm::vec3 getScale() const; + virtual void setScale(glm::vec3 scale); // get world location of a specific joint virtual const Transform getTransform(int jointIndex) const; - virtual const glm::vec3 getPosition(int jointIndex) const; - virtual const glm::vec3 getScale(int jointIndex) const; + virtual glm::vec3 getPosition(int jointIndex) const; + virtual glm::vec3 getScale(int jointIndex) const; // object's parent's frame virtual const Transform getLocalTransform() const; virtual void setLocalTransform(const Transform transform); - virtual const glm::vec3 getLocalPosition() const; - virtual void setLocalPosition(const glm::vec3 position); + virtual glm::vec3 getLocalPosition() const; + virtual void setLocalPosition(glm::vec3 position); - virtual const glm::quat getLocalOrientation() const; - virtual void setLocalOrientation(const glm::quat orientation); + virtual glm::quat getLocalOrientation() const; + virtual void setLocalOrientation(glm::quat orientation); - virtual const glm::vec3 getLocalScale() const; - virtual void setLocalScale(const glm::vec3 scale); + virtual glm::vec3 getLocalScale() const; + virtual void setLocalScale(glm::vec3 scale); QList getChildren() const; NestableTypes::NestableType getNestableType() const { return _nestableType; } From 941dfe5bd2dcb09f4a32878f0743432acc74be01 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 30 Nov 2015 13:30:47 -0800 Subject: [PATCH 42/51] initialize _parentJointIndex --- libraries/shared/src/SpatiallyNestable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 962399d080..8805e72af5 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -99,7 +99,7 @@ protected: NestableTypes::NestableType _nestableType; // EntityItem or an AvatarData QUuid _id; QUuid _parentID; // what is this thing's transform relative to? - quint16 _parentJointIndex; // which joint of the parent is this relative to? + quint16 _parentJointIndex { 0 }; // which joint of the parent is this relative to? SpatiallyNestablePointer getParentPointer() const; mutable SpatiallyNestableWeakPointer _parent; From 89b78986d5b219bec205348840aa6e43f6306645 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 30 Nov 2015 14:01:17 -0800 Subject: [PATCH 43/51] remove some more stray const --- interface/src/avatar/Avatar.h | 4 ++-- libraries/avatars/src/AvatarData.h | 4 ++-- libraries/entities/src/EntityItem.h | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 51768e4e71..60040fd493 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -161,8 +161,8 @@ public: void setMotionState(AvatarMotionState* motionState) { _motionState = motionState; } AvatarMotionState* getMotionState() { return _motionState; } - virtual void setPosition(const glm::vec3 position); - virtual void setOrientation(const glm::quat orientation); + virtual void setPosition(glm::vec3 position); + virtual void setOrientation(glm::quat orientation); public slots: diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 8db0ef5897..0cdc285021 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -201,8 +201,8 @@ public: float getBodyRoll() const; void setBodyRoll(float bodyRoll); - virtual void setPosition(const glm::vec3 position); - virtual void setOrientation(const glm::quat orientation); + virtual void setPosition(glm::vec3 position); + virtual void setOrientation(glm::quat orientation); void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time. void startCapture(); // start/end of the period in which the latest values are about to be captured for camera, etc. diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index cd5f97bee2..bccfccc628 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -330,10 +330,10 @@ public: // virtual const glm::vec3 getPosition() const { return SpatiallyNestable::getPosition(); } virtual const glm::quat getRotation() const { return SpatiallyNestable::getOrientation(); } - virtual void setPosition(const glm::vec3 position); - virtual void setLocalPosition(const glm::vec3 position); - virtual void setRotation(const glm::quat orientation); - virtual void setLocalRotation(const glm::quat orientation); + virtual void setPosition(glm::vec3 position); + virtual void setLocalPosition(glm::vec3 position); + virtual void setRotation(glm::quat orientation); + virtual void setLocalRotation(glm::quat orientation); // updateFoo() methods to be used when changes need to be accumulated in the _dirtyFlags void updatePosition(const glm::vec3& value); From 5c327edd5a8e1825e19a68a7cd5f81b3ca1cd0d4 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 30 Nov 2015 14:08:07 -0800 Subject: [PATCH 44/51] keep AvatarHashMap::findAvatar from creating bogus avatar entries. remove some more stray consts --- cmake/externals/quazip/CMakeLists.txt | 2 +- interface/src/Application.cpp | 2 +- interface/src/Application.h | 2 +- libraries/avatars/src/AvatarHashMap.cpp | 5 ++++- libraries/render-utils/src/AbstractViewStateInterface.h | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/cmake/externals/quazip/CMakeLists.txt b/cmake/externals/quazip/CMakeLists.txt index ddac942692..eadbecd2ad 100644 --- a/cmake/externals/quazip/CMakeLists.txt +++ b/cmake/externals/quazip/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_policy(SET CMP0046 OLD) include(ExternalProject) -string(REPLACE \\ / QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH}) +# string(REPLACE \\ / QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH}) ExternalProject_Add( ${EXTERNAL_NAME} URL http://s3-us-west-1.amazonaws.com/hifi-production/dependencies/quazip-0.6.2.zip diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0220d2b56c..1fff97c916 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3329,7 +3329,7 @@ MyAvatar* Application::getMyAvatar() const { return DependencyManager::get()->getMyAvatar(); } -const glm::vec3 Application::getAvatarPosition() const { +glm::vec3 Application::getAvatarPosition() const { return getMyAvatar()->getPosition(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 0467926b47..e615eeaeaa 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -185,7 +185,7 @@ public: virtual float getSizeScale() const; virtual int getBoundaryLevelAdjust() const; virtual PickRay computePickRay(float x, float y) const; - virtual const glm::vec3 getAvatarPosition() const; + virtual glm::vec3 getAvatarPosition() const; virtual void overrideEnvironmentData(const EnvironmentData& newData) { _environment.override(newData); } virtual void endOverrideEnvironmentData() { _environment.endOverride(); } virtual qreal getDevicePixelRatio(); diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index c195ab4c32..84fff8d114 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -65,7 +65,10 @@ AvatarSharedPointer AvatarHashMap::newOrExistingAvatar(const QUuid& sessionUUID, AvatarSharedPointer AvatarHashMap::findAvatar(const QUuid& sessionUUID) { QReadLocker locker(&_hashLock); - return _avatarHash.value(sessionUUID); + if (_avatarHash.contains(sessionUUID)) { + return _avatarHash.value(sessionUUID); + } + return nullptr; } void AvatarHashMap::processAvatarDataPacket(QSharedPointer packet, SharedNodePointer sendingNode) { diff --git a/libraries/render-utils/src/AbstractViewStateInterface.h b/libraries/render-utils/src/AbstractViewStateInterface.h index 2954c1fce4..39da33ee8f 100644 --- a/libraries/render-utils/src/AbstractViewStateInterface.h +++ b/libraries/render-utils/src/AbstractViewStateInterface.h @@ -45,7 +45,7 @@ public: virtual int getBoundaryLevelAdjust() const = 0; virtual PickRay computePickRay(float x, float y) const = 0; - virtual const glm::vec3 getAvatarPosition() const = 0; + virtual glm::vec3 getAvatarPosition() const = 0; virtual void postLambdaEvent(std::function f) = 0; virtual qreal getDevicePixelRatio() = 0; From aa383455f5967dfdcdf542fcf2fa29f4111f10ad Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 30 Nov 2015 14:09:19 -0800 Subject: [PATCH 45/51] oops --- cmake/externals/quazip/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/externals/quazip/CMakeLists.txt b/cmake/externals/quazip/CMakeLists.txt index eadbecd2ad..ddac942692 100644 --- a/cmake/externals/quazip/CMakeLists.txt +++ b/cmake/externals/quazip/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_policy(SET CMP0046 OLD) include(ExternalProject) -# string(REPLACE \\ / QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH}) +string(REPLACE \\ / QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH}) ExternalProject_Add( ${EXTERNAL_NAME} URL http://s3-us-west-1.amazonaws.com/hifi-production/dependencies/quazip-0.6.2.zip From 9b54924524783b3731c2a09f562705902f6ad2a5 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 30 Nov 2015 16:21:14 -0800 Subject: [PATCH 46/51] edit.js can now manipulate children without flipping the table --- .../entities/src/EntityItemProperties.cpp | 4 ++++ libraries/entities/src/EntityItemProperties.h | 2 ++ .../entities/src/EntityScriptingInterface.cpp | 23 ++++++++++++++++++- libraries/shared/src/SpatiallyNestable.cpp | 3 +++ libraries/shared/src/SpatiallyNestable.h | 2 +- 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 2ecb42a9ce..52f98be208 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1789,3 +1789,7 @@ QList EntityItemProperties::listChangedProperties() { return out; } + +bool EntityItemProperties::parentDependentPropertyChanged() { + return localPositionChanged() || positionChanged() || localRotationChanged() || rotationChanged(); +} diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 6bb6b1914c..11d29c5d57 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -83,6 +83,8 @@ public: { return (float)(usecTimestampNow() - getLastEdited()) / (float)USECS_PER_SECOND; } EntityPropertyFlags getChangedProperties() const; + bool parentDependentPropertyChanged(); // was there a changed in a property that requires parent info to interpret? + AACube getMaximumAACube() const; AABox getAABox() const; diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index ca963aca6d..39da57f3a8 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -201,10 +201,31 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, EntityItemProperties script bool updatedEntity = false; _entityTree->withWriteLock([&] { + if (scriptSideProperties.parentDependentPropertyChanged()) { + // if the script sets a location property but didn't include parent information, grab the needed + // properties from the entity. + bool recompute = false; + EntityItemPointer entity = nullptr; + if (!scriptSideProperties.parentIDChanged()) { + entity = _entityTree->findEntityByEntityItemID(entityID); + scriptSideProperties.setParentID(entity->getParentID()); + recompute = true; + } + if (!scriptSideProperties.parentJointIndexChanged()) { + if (!entity) { + entity = _entityTree->findEntityByEntityItemID(entityID); + } + scriptSideProperties.setParentJointIndex(entity->getParentJointIndex()); + recompute = true; + } + if (recompute) { + properties = convertLocationFromScriptSemantics(scriptSideProperties); + } + } + updatedEntity = _entityTree->updateEntity(entityID, properties); }); - if (!updatedEntity) { return QUuid(); } diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 31a0dd5647..9b2e809063 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -218,6 +218,7 @@ void SpatiallyNestable::setOrientation(glm::quat orientation) { } const Transform SpatiallyNestable::getTransform() const { + // return a world-space transform for this object's location Transform parentTransform = getParentTransform(); Transform result; _transformLock.withReadLock([&] { @@ -227,6 +228,8 @@ const Transform SpatiallyNestable::getTransform() const { } const Transform SpatiallyNestable::getTransform(int jointIndex) const { + // this returns the world-space transform for this object. It find its parent's transform (which may + // cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it. Transform worldTransform = getTransform(); Transform jointInObjectFrame = getJointTransformInObjectFrame(jointIndex); Transform jointInWorldFrame; diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 8805e72af5..6e0afa24a5 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -69,7 +69,7 @@ public: virtual glm::vec3 getScale() const; virtual void setScale(glm::vec3 scale); - // get world location of a specific joint + // get world-frame values for a specific joint virtual const Transform getTransform(int jointIndex) const; virtual glm::vec3 getPosition(int jointIndex) const; virtual glm::vec3 getScale(int jointIndex) const; From 3402585d1ac2b053c4708025765afe9d40c5eb26 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 30 Nov 2015 16:54:29 -0800 Subject: [PATCH 47/51] fix a crash from previous commit --- libraries/avatars/src/AvatarData.cpp | 12 +++++++-- .../entities/src/EntityScriptingInterface.cpp | 26 +++++++------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index ec363756f6..a7a3e74663 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -90,8 +90,10 @@ const QUrl& AvatarData::defaultFullAvatarModelUrl() { // There are a number of possible strategies for this set of tools through endRender, below. void AvatarData::nextAttitude(glm::vec3 position, glm::quat orientation) { avatarLock.lock(); - SpatiallyNestable::setPosition(position); - SpatiallyNestable::setOrientation(orientation); + Transform trans; + trans.setTranslation(position); + trans.setRotation(orientation); + SpatiallyNestable::setTransform(trans); avatarLock.unlock(); updateAttitude(); } @@ -478,6 +480,12 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { } // TODO is this safe? will the floats not exactly match? + // Andrew says: + // Yes, there is a possibility that the transmitted will not quite match the extracted despite being originally + // extracted from the exact same quaternion. I followed the code through and it appears the risk is that the + // avatar's SkeletonModel might fall into the CPU expensive part of Model::updateClusterMatrices() when otherwise it + // would not have required it. However, we know we can update many simultaneously animating avatars, and most + // avatars will be moving constantly anyway, so I don't think we need to worry. if (getBodyYaw() != yaw || getBodyPitch() != pitch || getBodyRoll() != roll) { _hasNewJointRotations = true; glm::vec3 eulerAngles(pitch, yaw, roll); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 39da57f3a8..9cb816be1f 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -191,7 +191,7 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit } QUuid EntityScriptingInterface::editEntity(QUuid id, EntityItemProperties scriptSideProperties) { - EntityItemProperties properties = convertLocationFromScriptSemantics(scriptSideProperties); + EntityItemProperties properties = scriptSideProperties; EntityItemID entityID(id); // If we have a local entity tree set, then also update it. if (!_entityTree) { @@ -204,25 +204,17 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, EntityItemProperties script if (scriptSideProperties.parentDependentPropertyChanged()) { // if the script sets a location property but didn't include parent information, grab the needed // properties from the entity. - bool recompute = false; - EntityItemPointer entity = nullptr; - if (!scriptSideProperties.parentIDChanged()) { - entity = _entityTree->findEntityByEntityItemID(entityID); - scriptSideProperties.setParentID(entity->getParentID()); - recompute = true; - } - if (!scriptSideProperties.parentJointIndexChanged()) { - if (!entity) { - entity = _entityTree->findEntityByEntityItemID(entityID); + if (!scriptSideProperties.parentIDChanged() || !scriptSideProperties.parentJointIndexChanged()) { + EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID); + if (entity && !scriptSideProperties.parentIDChanged()) { + properties.setParentID(entity->getParentID()); + } + if (entity && !scriptSideProperties.parentJointIndexChanged()) { + properties.setParentJointIndex(entity->getParentJointIndex()); } - scriptSideProperties.setParentJointIndex(entity->getParentJointIndex()); - recompute = true; - } - if (recompute) { - properties = convertLocationFromScriptSemantics(scriptSideProperties); } } - + properties = convertLocationFromScriptSemantics(properties); updatedEntity = _entityTree->updateEntity(entityID, properties); }); From f18fc84c2df8140cbe5afbe10437b4563549456d Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 2 Dec 2015 10:46:10 -0800 Subject: [PATCH 48/51] fix debug build --- interface/src/avatar/Avatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 4dff61cedc..83e2324080 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -725,7 +725,7 @@ glm::vec3 Avatar::getDisplayNamePosition() const { const float HEAD_PROPORTION = 0.75f; float billboardSize = getBillboardSize(); - DEBUG_VALUE("_position =", _position); + DEBUG_VALUE("_position =", getPosition()); DEBUG_VALUE("billboardSize =", billboardSize); namePosition = getPosition() + bodyUpDirection * (billboardSize * HEAD_PROPORTION); } From 2d804555dec92c105bea303d13630c8b3e3740a6 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 3 Dec 2015 08:59:15 -0800 Subject: [PATCH 49/51] minor cleanups --- libraries/shared/src/SpatiallyNestable.cpp | 37 ++++++++-------------- libraries/shared/src/SpatiallyNestable.h | 2 ++ 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 9b2e809063..688ed831e3 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -40,18 +40,17 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const { return nullptr; } - SpatiallyNestableConstPointer constThisPointer = shared_from_this(); - SpatiallyNestablePointer thisPointer = std::const_pointer_cast(constThisPointer); // ermahgerd !!! - if (parent && parent->getID() == _parentID) { // parent pointer is up-to-date if (!_parentKnowsMe) { - parent->beParentOfChild(thisPointer); + parent->beParentOfChild(getThisPointer()); _parentKnowsMe = true; } return parent; } + SpatiallyNestablePointer thisPointer = getThisPointer(); + if (parent) { // we have a parent pointer but our _parentID doesn't indicate this parent. parent->forgetChild(thisPointer); @@ -167,21 +166,12 @@ glm::quat SpatiallyNestable::localToWorld(glm::quat orientation, QUuid parentID, return result.getRotation(); } - glm::vec3 SpatiallyNestable::getPosition() const { - Transform parentTransformDescaled = getParentTransform(); - glm::mat4 parentMat; - parentTransformDescaled.getMatrix(parentMat); - glm::vec4 absPos = parentMat * glm::vec4(getLocalPosition(), 1.0f); - return glm::vec3(absPos); + return getTransform().getTranslation(); } glm::vec3 SpatiallyNestable::getPosition(int jointIndex) const { - Transform worldTransform = getTransform(); - Transform jointInObjectFrame = getJointTransformInObjectFrame(jointIndex); - Transform jointInWorldFrame; - Transform::mult(jointInWorldFrame, worldTransform, jointInObjectFrame); - return jointInWorldFrame.getTranslation(); + return getTransform(jointIndex).getTranslation(); } void SpatiallyNestable::setPosition(glm::vec3 position) { @@ -195,16 +185,11 @@ void SpatiallyNestable::setPosition(glm::vec3 position) { } glm::quat SpatiallyNestable::getOrientation() const { - Transform parentTransformDescaled = getParentTransform(); - return parentTransformDescaled.getRotation() * getLocalOrientation(); + return getTransform().getRotation(); } glm::quat SpatiallyNestable::getOrientation(int jointIndex) const { - Transform worldTransform = getTransform(); - Transform jointInObjectFrame = getJointTransformInObjectFrame(jointIndex); - Transform jointInWorldFrame; - Transform::mult(jointInWorldFrame, worldTransform, jointInObjectFrame); - return jointInWorldFrame.getRotation(); + return getTransform(jointIndex).getRotation(); } void SpatiallyNestable::setOrientation(glm::quat orientation) { @@ -228,7 +213,7 @@ const Transform SpatiallyNestable::getTransform() const { } const Transform SpatiallyNestable::getTransform(int jointIndex) const { - // this returns the world-space transform for this object. It find its parent's transform (which may + // this returns the world-space transform for this object. It finds its parent's transform (which may // cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it. Transform worldTransform = getTransform(); Transform jointInObjectFrame = getJointTransformInObjectFrame(jointIndex); @@ -341,3 +326,9 @@ const Transform SpatiallyNestable::getJointTransformInObjectFrame(int jointIndex jointInObjectFrame.setTranslation(position); return jointInObjectFrame; } + +SpatiallyNestablePointer SpatiallyNestable::getThisPointer() const { + SpatiallyNestableConstPointer constThisPointer = shared_from_this(); + SpatiallyNestablePointer thisPointer = std::const_pointer_cast(constThisPointer); // ermahgerd !!! + return thisPointer; +} diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 6e0afa24a5..b7c04e8563 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -95,6 +95,8 @@ public: virtual glm::quat getJointRotation(int index) const = 0; virtual glm::vec3 getJointTranslation(int index) const = 0; + SpatiallyNestablePointer getThisPointer() const; + protected: NestableTypes::NestableType _nestableType; // EntityItem or an AvatarData QUuid _id; From 6f79b381f96abf39682d985e1a67370e4dbef4cb Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 3 Dec 2015 11:00:06 -0800 Subject: [PATCH 50/51] working toward making children of avatar joints work --- libraries/entities/src/EntityItem.cpp | 77 +++------------------- libraries/entities/src/EntityItem.h | 15 ++--- libraries/shared/src/SpatiallyNestable.cpp | 41 +++++++++++- libraries/shared/src/SpatiallyNestable.h | 9 ++- 4 files changed, 59 insertions(+), 83 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index f169554a2c..e286275fed 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1319,9 +1319,6 @@ void EntityItem::updatePosition(const glm::vec3& value) { } if (getLocalPosition() != value) { setLocalPosition(value); - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->_dirtyFlags |= Simulation::DIRTY_POSITION; - }); } } @@ -1337,10 +1334,12 @@ void EntityItem::updateRotation(const glm::quat& rotation) { return; } if (getLocalOrientation() != rotation) { - setLocalRotation(rotation); - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->_dirtyFlags |= Simulation::DIRTY_ROTATION; - if (this->getID() != entity->getID()) { + setLocalOrientation(rotation); + _dirtyFlags |= Simulation::DIRTY_ROTATION; + forEachDescendant([&](SpatiallyNestablePointer object) { + if (object->getNestableType() == NestableTypes::Entity) { + EntityItemPointer entity = std::static_pointer_cast(object); + entity->_dirtyFlags |= Simulation::DIRTY_ROTATION; entity->_dirtyFlags |= Simulation::DIRTY_POSITION; } }); @@ -1838,65 +1837,7 @@ QList EntityItem::getActionsOfType(EntityActionType typeToG return result; } -void EntityItem::forSelfAndEachChildEntity(std::function actor) { - QQueue toProcess; - toProcess.enqueue(shared_from_this()); - - while (!toProcess.empty()) { - EntityItemPointer entity = std::static_pointer_cast(toProcess.dequeue()); - actor(entity); - foreach (SpatiallyNestablePointer child, entity->getChildren()) { - if (child && child->getNestableType() == NestableTypes::Entity) { - toProcess.enqueue(child); - } - } - } -} - -void EntityItem::parentChanged() { - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); -} - -void EntityItem::setTransform(const Transform transform) { - SpatiallyNestable::setTransform(transform); - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); -} - -void EntityItem::setLocalTransform(const Transform transform) { - SpatiallyNestable::setLocalTransform(transform); - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); -} - -void EntityItem::setPosition(const glm::vec3 position) { - SpatiallyNestable::setPosition(position); - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); -} - -void EntityItem::setLocalPosition(const glm::vec3 position) { - SpatiallyNestable::setLocalPosition(position); - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); -} - -void EntityItem::setRotation(const glm::quat orientation) { - SpatiallyNestable::setOrientation(orientation); - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); -} - -void EntityItem::setLocalRotation(const glm::quat orientation) { - SpatiallyNestable::setLocalOrientation(orientation); - forSelfAndEachChildEntity([&](EntityItemPointer entity) { - entity->requiresRecalcBoxes(); - }); +void EntityItem::locationChanged() { + requiresRecalcBoxes(); + SpatiallyNestable::locationChanged(); // tell all the children, also } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index cbaa152c7f..761208cb06 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -306,15 +306,9 @@ public: /// return preferred shape type (actual physical shape may differ) virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; } - virtual void setTransform(const Transform transform); - virtual void setLocalTransform(const Transform transform); - // virtual const glm::vec3 getPosition() const { return SpatiallyNestable::getPosition(); } - virtual const glm::quat getRotation() const { return SpatiallyNestable::getOrientation(); } - - virtual void setPosition(glm::vec3 position); - virtual void setLocalPosition(glm::vec3 position); - virtual void setRotation(glm::quat orientation); - virtual void setLocalRotation(glm::quat orientation); + // these are only needed because the names don't match + virtual const glm::quat getRotation() const { return getOrientation(); } + virtual void setRotation(glm::quat orientation) { setOrientation(orientation); } // updateFoo() methods to be used when changes need to be accumulated in the _dirtyFlags void updatePosition(const glm::vec3& value); @@ -393,8 +387,7 @@ protected: const QByteArray getActionDataInternal() const; void setActionDataInternal(QByteArray actionData); - void forSelfAndEachChildEntity(std::function actor); - virtual void parentChanged(); + virtual void locationChanged(); EntityTypes::EntityType _type; quint64 _lastSimulated; // last time this entity called simulate(), this includes velocity, angular velocity, // and physics changes diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 688ed831e3..a0280943de 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include "DependencyManager.h" #include "SpatiallyNestable.h" @@ -91,6 +93,7 @@ void SpatiallyNestable::setParentID(const QUuid parentID) { _parentID = parentID; _parentKnowsMe = false; } + parentChanged(); } glm::vec3 SpatiallyNestable::worldToLocal(glm::vec3 position, QUuid parentID, int parentJointIndex) { @@ -182,6 +185,7 @@ void SpatiallyNestable::setPosition(glm::vec3 position) { myWorldTransform.setTranslation(position); Transform::inverseMult(_transform, parentTransform, myWorldTransform); }); + locationChanged(); } glm::quat SpatiallyNestable::getOrientation() const { @@ -200,6 +204,7 @@ void SpatiallyNestable::setOrientation(glm::quat orientation) { myWorldTransform.setRotation(orientation); Transform::inverseMult(_transform, parentTransform, myWorldTransform); }); + locationChanged(); } const Transform SpatiallyNestable::getTransform() const { @@ -227,6 +232,7 @@ void SpatiallyNestable::setTransform(const Transform transform) { _transformLock.withWriteLock([&] { Transform::inverseMult(_transform, parentTransform, transform); }); + locationChanged(); } glm::vec3 SpatiallyNestable::getScale() const { @@ -246,6 +252,7 @@ void SpatiallyNestable::setScale(glm::vec3 scale) { _transformLock.withWriteLock([&] { _transform.setScale(scale); }); + dimensionsChanged(); } const Transform SpatiallyNestable::getLocalTransform() const { @@ -260,6 +267,7 @@ void SpatiallyNestable::setLocalTransform(const Transform transform) { _transformLock.withWriteLock([&] { _transform = transform; }); + locationChanged(); } glm::vec3 SpatiallyNestable::getLocalPosition() const { @@ -274,6 +282,7 @@ void SpatiallyNestable::setLocalPosition(glm::vec3 position) { _transformLock.withWriteLock([&] { _transform.setTranslation(position); }); + locationChanged(); } glm::quat SpatiallyNestable::getLocalOrientation() const { @@ -288,6 +297,7 @@ void SpatiallyNestable::setLocalOrientation(glm::quat orientation) { _transformLock.withWriteLock([&] { _transform.setRotation(orientation); }); + locationChanged(); } glm::vec3 SpatiallyNestable::getLocalScale() const { @@ -302,12 +312,13 @@ void SpatiallyNestable::setLocalScale(glm::vec3 scale) { _transformLock.withWriteLock([&] { _transform.setScale(scale); }); + dimensionsChanged(); } QList SpatiallyNestable::getChildren() const { QList children; _childrenLock.withReadLock([&] { - foreach (SpatiallyNestableWeakPointer childWP, _children.values()) { + foreach(SpatiallyNestableWeakPointer childWP, _children.values()) { SpatiallyNestablePointer child = childWP.lock(); if (child) { children << child; @@ -317,7 +328,6 @@ QList SpatiallyNestable::getChildren() const { return children; } - const Transform SpatiallyNestable::getJointTransformInObjectFrame(int jointIndex) const { Transform jointInObjectFrame; glm::vec3 position = getJointTranslation(jointIndex); @@ -332,3 +342,30 @@ SpatiallyNestablePointer SpatiallyNestable::getThisPointer() const { SpatiallyNestablePointer thisPointer = std::const_pointer_cast(constThisPointer); // ermahgerd !!! return thisPointer; } + +void SpatiallyNestable::forEachChild(std::function actor) { + foreach(SpatiallyNestablePointer child, getChildren()) { + actor(child); + } +} + +void SpatiallyNestable::forEachDescendant(std::function actor) { + QQueue toProcess; + foreach(SpatiallyNestablePointer child, getChildren()) { + toProcess.enqueue(child); + } + + while (!toProcess.empty()) { + SpatiallyNestablePointer object = toProcess.dequeue(); + actor(object); + foreach (SpatiallyNestablePointer child, object->getChildren()) { + toProcess.enqueue(child); + } + } +} + +void SpatiallyNestable::locationChanged() { + forEachChild([&](SpatiallyNestablePointer object) { + object->locationChanged(); + }); +} diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index b7c04e8563..f750860037 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -92,8 +92,8 @@ public: // this object's frame virtual const Transform getJointTransformInObjectFrame(int jointIndex) const; - virtual glm::quat getJointRotation(int index) const = 0; - virtual glm::vec3 getJointTranslation(int index) const = 0; + virtual glm::quat getJointRotation(int index) const { assert(false); } + virtual glm::vec3 getJointTranslation(int index) const { assert(false); } SpatiallyNestablePointer getThisPointer() const; @@ -112,6 +112,11 @@ protected: mutable QHash _children; virtual void parentChanged() {} // called when parent pointer is updated + virtual void locationChanged(); // called when a this object's location has changed + virtual void dimensionsChanged() {} // called when a this object's dimensions have changed + + void forEachChild(std::function actor); + void forEachDescendant(std::function actor); private: mutable ReadWriteLockable _transformLock; From e5b1cfa920d5a09b2e2b1375a0f797f4d21cf9a9 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 3 Dec 2015 11:15:04 -0800 Subject: [PATCH 51/51] fix windows build --- libraries/shared/src/SpatiallyNestable.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index f750860037..f3056d9a4f 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -92,8 +92,8 @@ public: // this object's frame virtual const Transform getJointTransformInObjectFrame(int jointIndex) const; - virtual glm::quat getJointRotation(int index) const { assert(false); } - virtual glm::vec3 getJointTranslation(int index) const { assert(false); } + virtual glm::quat getJointRotation(int index) const { assert(false); return glm::quat(); } + virtual glm::vec3 getJointTranslation(int index) const { assert(false); return glm::vec3(); } SpatiallyNestablePointer getThisPointer() const;