From c4395e75bb40f2d208ad63201e1436732cef8c7c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 22 Apr 2015 11:20:38 -0700 Subject: [PATCH 01/12] cleanup and comments --- interface/src/avatar/AvatarManager.h | 2 +- libraries/physics/src/DynamicCharacterController.cpp | 8 ++++---- libraries/physics/src/PhysicsEngine.cpp | 1 + libraries/physics/src/PhysicsEngine.h | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 4912fabd33..1a833c5106 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -59,7 +59,7 @@ private: AvatarSharedPointer newSharedAvatar(); - // virtual override + // virtual overrides AvatarHash::iterator erase(const AvatarHash::iterator& iterator); QVector _avatarFades; diff --git a/libraries/physics/src/DynamicCharacterController.cpp b/libraries/physics/src/DynamicCharacterController.cpp index 46ff2e524e..f05dc11c5c 100644 --- a/libraries/physics/src/DynamicCharacterController.cpp +++ b/libraries/physics/src/DynamicCharacterController.cpp @@ -96,7 +96,7 @@ void DynamicCharacterController::preStep(btCollisionWorld* collisionWorld) { } } -void DynamicCharacterController::playerStep(btCollisionWorld* dynaWorld,btScalar dt) { +void DynamicCharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) { btVector3 actualVelocity = _rigidBody->getLinearVelocity(); btScalar actualSpeed = actualVelocity.length(); @@ -317,10 +317,10 @@ void DynamicCharacterController::updateShapeIfNecessary() { float mass = 1.0f; btVector3 inertia(1.0f, 1.0f, 1.0f); _rigidBody = new btRigidBody(mass, NULL, _shape, inertia); - _rigidBody->setSleepingThresholds (0.0f, 0.0f); - _rigidBody->setAngularFactor (0.0f); + _rigidBody->setSleepingThresholds(0.0f, 0.0f); + _rigidBody->setAngularFactor(0.0f); _rigidBody->setWorldTransform(btTransform(glmToBullet(_avatarData->getOrientation()), - glmToBullet(_avatarData->getPosition()))); + glmToBullet(_avatarData->getPosition()))); if (_isHovering) { _rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f)); } else { diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 45f3c97e30..75bab97d38 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -15,6 +15,7 @@ #include "ShapeInfoUtil.h" #include "PhysicsHelpers.h" #include "ThreadSafeDynamicsWorld.h" +#include "PhysicsLogging.h" static uint32_t _numSubsteps; diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 148261c6d2..af140f0f24 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -39,8 +39,8 @@ public: ContactKey(void* a, void* b) : _a(a), _b(b) {} bool operator<(const ContactKey& other) const { return _a < other._a || (_a == other._a && _b < other._b); } bool operator==(const ContactKey& other) const { return _a == other._a && _b == other._b; } - void* _a; - void* _b; + void* _a; // EntityMotionState pointer + void* _b; // EntityMotionState pointer }; typedef std::map ContactMap; From 79cb55eabc98bf611d16ae479dc35d18df56b7db Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 23 Apr 2015 15:09:57 -0700 Subject: [PATCH 02/12] rename setJointStates() --> initJointStates() --- interface/src/avatar/SkeletonModel.cpp | 5 +++-- interface/src/avatar/SkeletonModel.h | 2 +- libraries/render-utils/src/Model.cpp | 6 +++--- libraries/render-utils/src/Model.h | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index dc5427ab48..08e3ece331 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -40,13 +40,14 @@ SkeletonModel::SkeletonModel(Avatar* owningAvatar, QObject* parent) : _clampedFootPosition(0.0f), _headClipDistance(DEFAULT_NEAR_CLIP) { + assert(_owningAvatar); } SkeletonModel::~SkeletonModel() { } -void SkeletonModel::setJointStates(QVector states) { - Model::setJointStates(states); +void SkeletonModel::initJointStates(QVector states) { + Model::initJointStates(states); // Determine the default eye position for avatar scale = 1.0 int headJointIndex = _geometry->getFBXGeometry().headJointIndex; diff --git a/interface/src/avatar/SkeletonModel.h b/interface/src/avatar/SkeletonModel.h index 298d74fb7a..e28988326a 100644 --- a/interface/src/avatar/SkeletonModel.h +++ b/interface/src/avatar/SkeletonModel.h @@ -28,7 +28,7 @@ public: SkeletonModel(Avatar* owningAvatar, QObject* parent = NULL); ~SkeletonModel(); - void setJointStates(QVector states); + virtual void initJointStates(QVector states); void simulate(float deltaTime, bool fullUpdate = true); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 4bc69f1bea..78abd142bc 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -426,12 +426,12 @@ bool Model::updateGeometry() { _dilatedTextures.clear(); _geometry = geometry; _meshGroupsKnown = false; - setJointStates(newJointStates); + initJointStates(newJointStates); needToRebuild = true; } else if (_jointStates.isEmpty()) { const FBXGeometry& fbxGeometry = geometry->getFBXGeometry(); if (fbxGeometry.joints.size() > 0) { - setJointStates(createJointStates(fbxGeometry)); + initJointStates(createJointStates(fbxGeometry)); needToRebuild = true; } } else if (!geometry->isLoaded()) { @@ -469,7 +469,7 @@ bool Model::updateGeometry() { } // virtual -void Model::setJointStates(QVector states) { +void Model::initJointStates(QVector states) { _jointStates = states; initJointTransforms(); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 1559e73e61..b91d2116f8 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -244,7 +244,7 @@ protected: // returns 'true' if needs fullUpdate after geometry change bool updateGeometry(); - virtual void setJointStates(QVector states); + virtual void initJointStates(QVector states); void setScaleInternal(const glm::vec3& scale); void scaleToFit(); From f09a67af6c1dfc98d7328b2e8ac3add52e6e5914 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 24 Apr 2015 09:32:54 -0700 Subject: [PATCH 03/12] don't need temp variable --- libraries/physics/src/EntityMotionState.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index d1571fbcc5..64d1067668 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -189,9 +189,7 @@ float EntityMotionState::computeMass(const ShapeInfo& shapeInfo) const { } bool EntityMotionState::shouldSendUpdate(uint32_t simulationFrame) { - bool baseResult = this->ObjectMotionState::shouldSendUpdate(simulationFrame); - - if (!baseResult) { + if (!ObjectMotionState::shouldSendUpdate(simulationFrame)) { return false; } From 7cd9023e2339acd35b798ae6dba7a6c15f01122e Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 24 Apr 2015 09:34:19 -0700 Subject: [PATCH 04/12] build Avatar shape on SkeletonModel load --- interface/src/Application.cpp | 1 - interface/src/avatar/Avatar.cpp | 17 +++++++++++++++++ interface/src/avatar/Avatar.h | 4 ++++ interface/src/avatar/MyAvatar.cpp | 2 +- interface/src/avatar/MyAvatar.h | 3 ++- interface/src/avatar/SkeletonModel.cpp | 1 + 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 285bd11952..485f616a6c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4389,7 +4389,6 @@ void Application::checkSkeleton() { _myAvatar->useBodyURL(DEFAULT_BODY_MODEL_URL, "Default"); } else { - _myAvatar->updateCharacterController(); _physicsEngine.setCharacterController(_myAvatar->getCharacterController()); } } diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 63dd884bc6..b3439317d8 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -1058,3 +1058,20 @@ void Avatar::setShowDisplayName(bool showDisplayName) { } +// virtual +void Avatar::rebuildSkeletonBody() { + /* TODO: implement this and remove override from MyAvatar (when we have AvatarMotionStates working) + if (_motionState) { + // compute localAABox + const CapsuleShape& capsule = _skeletonModel.getBoundingShape(); + float radius = capsule.getRadius(); + float height = 2.0f * (capsule.getHalfHeight() + radius); + glm::vec3 corner(-radius, -0.5f * height, -radius); + corner += _skeletonModel.getBoundingShapeOffset(); + glm::vec3 scale(2.0f * radius, height, 2.0f * radius); + //_characterController.setLocalBoundingBox(corner, scale); + _motionState->setBoundingBox(corner, scale); + } + */ +} + diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 032fe25c7d..a358e7e58d 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -162,6 +162,8 @@ public: // (otherwise floating point error will cause problems at large positions). void applyPositionDelta(const glm::vec3& delta); + virtual void rebuildSkeletonBody(); + signals: void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision); @@ -228,6 +230,8 @@ private: static int _jointConesID; int _voiceSphereID; + + //AvatarMotionState* _motionState = nullptr; }; #endif // hifi_Avatar_h diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5adc818258..95f5e3fe9f 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1070,7 +1070,7 @@ glm::vec3 MyAvatar::getSkeletonPosition() const { return Avatar::getPosition(); } -void MyAvatar::updateCharacterController() { +void MyAvatar::rebuildSkeletonBody() { // compute localAABox const CapsuleShape& capsule = _skeletonModel.getBoundingShape(); float radius = capsule.getRadius(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 886d8ad590..4746a40099 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -138,7 +138,6 @@ public: virtual glm::vec3 getSkeletonPosition() const; void updateLocalAABox(); DynamicCharacterController* getCharacterController() { return &_characterController; } - void updateCharacterController(); void clearJointAnimationPriorities(); @@ -192,6 +191,8 @@ public slots: void stopRecording(); void saveRecording(QString filename); void loadLastRecording(); + + virtual void rebuildSkeletonBody(); signals: void transformChanged(); diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 08e3ece331..8c52c79ca0 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -84,6 +84,7 @@ void SkeletonModel::initJointStates(QVector states) { _headClipDistance = -(meshExtents.minimum.z / _scale.z - _defaultEyeModelPosition.z); _headClipDistance = std::max(_headClipDistance, DEFAULT_NEAR_CLIP); + _owningAvatar->rebuildSkeletonBody(); emit skeletonLoaded(); } From 3ecf959b3e514e1a21a51b958f33cdb66b763ece Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 24 Apr 2015 14:50:37 -0700 Subject: [PATCH 05/12] removed cached copies of damping and restitution --- libraries/entities/src/EntityItem.cpp | 15 ++++++++++-- libraries/entities/src/EntityItem.h | 6 ++++- libraries/physics/src/EntityMotionState.cpp | 20 ++++++++-------- libraries/physics/src/EntityMotionState.h | 1 + libraries/physics/src/ObjectMotionState.cpp | 26 +++------------------ libraries/physics/src/ObjectMotionState.h | 18 ++++---------- libraries/physics/src/PhysicsEngine.cpp | 5 ++-- 7 files changed, 38 insertions(+), 53 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index f968244ab3..54a00cdcb0 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -675,6 +675,17 @@ void EntityItem::setMass(float mass) { } } +const float DEFAULT_ENTITY_RESTITUTION = 0.5f; +const float DEFAULT_ENTITY_FRICTION = 0.5f; + +float EntityItem::getRestitution() const { + return DEFAULT_ENTITY_RESTITUTION; +} + +float EntityItem::getFriction() const { + return DEFAULT_ENTITY_FRICTION; +} + void EntityItem::simulate(const quint64& now) { if (_lastSimulated == 0) { _lastSimulated = now; @@ -1157,7 +1168,7 @@ void EntityItem::updateVelocity(const glm::vec3& value) { void EntityItem::updateDamping(float value) { if (fabsf(_damping - value) > MIN_DAMPING_DELTA) { _damping = glm::clamp(value, 0.0f, 1.0f); - _dirtyFlags |= EntityItem::DIRTY_VELOCITY; + _dirtyFlags |= EntityItem::DIRTY_MATERIAL; } } @@ -1188,7 +1199,7 @@ void EntityItem::updateAngularVelocity(const glm::vec3& value) { void EntityItem::updateAngularDamping(float value) { if (fabsf(_angularDamping - value) > MIN_DAMPING_DELTA) { _angularDamping = glm::clamp(value, 0.0f, 1.0f); - _dirtyFlags |= EntityItem::DIRTY_VELOCITY; + _dirtyFlags |= EntityItem::DIRTY_MATERIAL; } } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index fda8167564..d6f9a9506f 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -54,7 +54,8 @@ public: DIRTY_MOTION_TYPE = 0x0010, DIRTY_SHAPE = 0x0020, DIRTY_LIFETIME = 0x0040, - DIRTY_UPDATEABLE = 0x0080 + DIRTY_UPDATEABLE = 0x0080, + DIRTY_MATERIAL = 0x00100 }; DONT_ALLOW_INSTANTIATION // This class can not be instantiated directly @@ -188,6 +189,9 @@ public: float getDamping() const { return _damping; } void setDamping(float value) { _damping = value; } + float getRestitution() const; + float getFriction() const; + // lifetime related properties. float getLifetime() const { return _lifetime; } /// get the lifetime in seconds for the entity void setLifetime(float value) { _lifetime = value; } /// set the lifetime in seconds for the entity diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 64d1067668..f905b00ffa 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -143,15 +143,9 @@ void EntityMotionState::updateObjectEasy(uint32_t flags, uint32_t step) { _sentStep = step; } - // TODO: entity support for friction and restitution - //_restitution = _entity->getRestitution(); - _body->setRestitution(_restitution); - //_friction = _entity->getFriction(); - _body->setFriction(_friction); - - _linearDamping = _entity->getDamping(); - _angularDamping = _entity->getAngularDamping(); - _body->setDamping(_linearDamping, _angularDamping); + if (flags & EntityItem::DIRTY_MATERIAL) { + updateMaterialProperties(); + } if (flags & EntityItem::DIRTY_MASS) { float mass = _entity->computeMass(); @@ -161,7 +155,13 @@ void EntityMotionState::updateObjectEasy(uint32_t flags, uint32_t step) { _body->updateInertiaTensor(); } _body->activate(); -}; +} + +void EntityMotionState::updateMaterialProperties() { + _body->setRestitution(_entity->getRestitution()); + _body->setFriction(_entity->getFriction()); + _body->setDamping(fabsf(btMin(_entity->getDamping(), 1.0f)), fabsf(btMin(_entity->getAngularDamping(), 1.0f))); +} void EntityMotionState::updateObjectVelocities() { if (_body) { diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index 07f82aaa42..e8a96428a0 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -51,6 +51,7 @@ public: // these relay incoming values to the RigidBody virtual void updateObjectEasy(uint32_t flags, uint32_t step); + virtual void updateMaterialProperties(); virtual void updateObjectVelocities(); virtual void computeShapeInfo(ShapeInfo& shapeInfo); diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 3d8e578056..96257950ff 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -43,10 +43,6 @@ void ObjectMotionState::setSimulationStep(uint32_t step) { } ObjectMotionState::ObjectMotionState() : - _friction(DEFAULT_FRICTION), - _restitution(DEFAULT_RESTITUTION), - _linearDamping(0.0f), - _angularDamping(0.0f), _motionType(MOTION_TYPE_STATIC), _body(NULL), _sentMoving(false), @@ -80,7 +76,7 @@ void ObjectMotionState::measureAcceleration() { // Note: the integration equation for velocity uses damping: v1 = (v0 + a * dt) * (1 - D)^dt // hence the equation for acceleration is: a = (v1 / (1 - D)^dt - v0) / dt glm::vec3 velocity = bulletToGLM(_body->getLinearVelocity()); - _measuredAcceleration = (velocity / powf(1.0f - _linearDamping, dt) - _lastVelocity) * invDt; + _measuredAcceleration = (velocity / powf(1.0f - _body->getLinearDamping(), dt) - _lastVelocity) * invDt; _lastVelocity = velocity; } } @@ -90,22 +86,6 @@ void ObjectMotionState::resetMeasuredAcceleration() { _lastVelocity = bulletToGLM(_body->getLinearVelocity()); } -void ObjectMotionState::setFriction(float friction) { - _friction = btMax(btMin(fabsf(friction), MAX_FRICTION), 0.0f); -} - -void ObjectMotionState::setRestitution(float restitution) { - _restitution = btMax(btMin(fabsf(restitution), 1.0f), 0.0f); -} - -void ObjectMotionState::setLinearDamping(float damping) { - _linearDamping = btMax(btMin(fabsf(damping), 1.0f), 0.0f); -} - -void ObjectMotionState::setAngularDamping(float damping) { - _angularDamping = btMax(btMin(fabsf(damping), 1.0f), 0.0f); -} - void ObjectMotionState::setVelocity(const glm::vec3& velocity) const { _body->setLinearVelocity(glmToBullet(velocity)); } @@ -181,7 +161,7 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationStep) { // compute position error if (glm::length2(_sentVelocity) > 0.0f) { _sentVelocity += _sentAcceleration * dt; - _sentVelocity *= powf(1.0f - _linearDamping, dt); + _sentVelocity *= powf(1.0f - _body->getLinearDamping(), dt); _sentPosition += dt * _sentVelocity; } @@ -206,7 +186,7 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationStep) { if (glm::length2(_sentAngularVelocity) > 0.0f) { // compute rotation error - float attenuation = powf(1.0f - _angularDamping, dt); + float attenuation = powf(1.0f - _body->getAngularDamping(), dt); _sentAngularVelocity *= attenuation; // Bullet caps the effective rotation velocity inside its rotation integration step, therefore diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 9e0917a3ab..0f1d04d0bd 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -36,7 +36,7 @@ enum MotionStateType { // and re-added to the physics engine and "easy" which just updates the body properties. const uint32_t HARD_DIRTY_PHYSICS_FLAGS = (uint32_t)(EntityItem::DIRTY_MOTION_TYPE | EntityItem::DIRTY_SHAPE); const uint32_t EASY_DIRTY_PHYSICS_FLAGS = (uint32_t)(EntityItem::DIRTY_POSITION | EntityItem::DIRTY_VELOCITY | - EntityItem::DIRTY_MASS | EntityItem::DIRTY_COLLISION_GROUP); + EntityItem::DIRTY_MASS | EntityItem::DIRTY_COLLISION_GROUP | EntityItem::DIRTY_MATERIAL); // These are the set of incoming flags that the PhysicsEngine needs to hear about: const uint32_t DIRTY_PHYSICS_FLAGS = HARD_DIRTY_PHYSICS_FLAGS | EASY_DIRTY_PHYSICS_FLAGS; @@ -69,6 +69,7 @@ public: // An EASY update does not require the object to be removed and then reinserted into the PhysicsEngine virtual void updateObjectEasy(uint32_t flags, uint32_t frame) = 0; + virtual void updateMaterialProperties() = 0; virtual void updateObjectVelocities() = 0; MotionStateType getType() const { return _type; } @@ -77,11 +78,6 @@ public: virtual void computeShapeInfo(ShapeInfo& info) = 0; virtual float computeMass(const ShapeInfo& shapeInfo) const = 0; - void setFriction(float friction); - void setRestitution(float restitution); - void setLinearDamping(float damping); - void setAngularDamping(float damping); - void setVelocity(const glm::vec3& velocity) const; void setAngularVelocity(const glm::vec3& velocity) const; void setGravity(const glm::vec3& gravity) const; @@ -120,15 +116,9 @@ public: protected: void setRigidBody(btRigidBody* body); - MotionStateType _type = MOTION_STATE_TYPE_UNKNOWN; + MotionStateType _type = MOTION_STATE_TYPE_UNKNOWN; // type of MotionState - // TODO: move these materials properties outside of ObjectMotionState - float _friction; - float _restitution; - float _linearDamping; - float _angularDamping; - - MotionType _motionType; + MotionType _motionType; // type of motion: KINEMATIC, DYNAMIC, or STATIC btRigidBody* _body; diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 75bab97d38..00ac807808 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -527,9 +527,8 @@ void PhysicsEngine::addObject(const ShapeInfo& shapeInfo, btCollisionShape* shap } } body->setFlags(BT_DISABLE_WORLD_GRAVITY); - body->setRestitution(motionState->_restitution); - body->setFriction(motionState->_friction); - body->setDamping(motionState->_linearDamping, motionState->_angularDamping); + motionState->updateMaterialProperties(); + _dynamicsWorld->addRigidBody(body); motionState->resetMeasuredAcceleration(); } From 82e3c4c5879e3be0555d9c43667b5074cb7f03aa Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sat, 25 Apr 2015 16:26:15 -0700 Subject: [PATCH 06/12] Updating the build notes to refelect the new Qt version requirement --- BUILD.md | 10 +++++----- BUILD_OSX.md | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/BUILD.md b/BUILD.md index ed3fea5c5f..0de8d32b82 100644 --- a/BUILD.md +++ b/BUILD.md @@ -1,7 +1,7 @@ ###Dependencies * [cmake](http://www.cmake.org/cmake/resources/software.html) ~> 2.8.12.2 -* [Qt](http://qt-project.org/downloads) ~> 5.3.2 +* [Qt](http://www.qt.io/download-open-source) ~> 5.4.1 * [OpenSSL](https://www.openssl.org/related/binaries.html) ~> 1.0.1g * IMPORTANT: OpenSSL 1.0.1g is critical to avoid a security vulnerability. * [VHACD](https://github.com/virneo/v-hacd)(clone this repository)(Optional) @@ -37,12 +37,12 @@ Hifi uses CMake to generate build files and project files for your platform. ####Qt In order for CMake to find the Qt5 find modules, you will need to set an ENV variable pointing to your Qt installation. -For example, a Qt5 5.3.2 installation to /usr/local/qt5 would require that QT_CMAKE_PREFIX_PATH be set with the following command. This can either be entered directly into your shell session before you build or in your shell profile (e.g.: ~/.bash_profile, ~/.bashrc, ~/.zshrc - this depends on your shell and environment). +For example, a Qt5 5.4.1 installation to /usr/local/qt5 would require that QT_CMAKE_PREFIX_PATH be set with the following command. This can either be entered directly into your shell session before you build or in your shell profile (e.g.: ~/.bash_profile, ~/.bashrc, ~/.zshrc - this depends on your shell and environment). The path it needs to be set to will depend on where and how Qt5 was installed. e.g. - export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.3.2/clang_64/lib/cmake/ - export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.3.2/lib/cmake + export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.4.1/clang_64/lib/cmake/ + export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.4.1/lib/cmake export QT_CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake ####Generating build files @@ -57,7 +57,7 @@ Any variables that need to be set for CMake to find dependencies can be set as E For example, to pass the QT_CMAKE_PREFIX_PATH variable during build file generation: - cmake .. -DQT_CMAKE_PREFIX_PATH=/usr/local/qt/5.3.2/lib/cmake + cmake .. -DQT_CMAKE_PREFIX_PATH=/usr/local/qt/5.4.1/lib/cmake ####Finding Dependencies diff --git a/BUILD_OSX.md b/BUILD_OSX.md index c199fe4c73..2598507c90 100644 --- a/BUILD_OSX.md +++ b/BUILD_OSX.md @@ -10,7 +10,7 @@ Please read the [general build guide](BUILD.md) for information on dependencies We have a [homebrew formulas repository](https://github.com/highfidelity/homebrew-formulas) that you can use/tap to install some of the dependencies. In the code block above qt5 is installed from a formula in this repository. -*Our [qt5 homebrew formula](https://raw.github.com/highfidelity/homebrew-formulas/master/qt5.rb) is for a patched version of Qt 5.3.x stable that removes wireless network scanning that can reduce real-time audio performance. We recommended you use this formula to install Qt.* +*Our [qt5 homebrew formula](https://raw.github.com/highfidelity/homebrew-formulas/master/qt5.rb) is for a patched version of Qt 5.4.x stable that removes wireless network scanning that can reduce real-time audio performance. We recommended you use this formula to install Qt.* ###Xcode If Xcode is your editor of choice, you can ask CMake to generate Xcode project files instead of Unix Makefiles. From b760a033603fecff2d83288e2209cccd325a352d Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Sun, 26 Apr 2015 15:24:00 -0700 Subject: [PATCH 07/12] pass arguments by const reference --- libraries/entities/src/EntityItem.cpp | 4 ++-- libraries/entities/src/EntityItem.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 54a00cdcb0..1f4ef5d454 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -846,11 +846,11 @@ glm::mat4 EntityItem::getWorldToEntityMatrix() const { return glm::inverse(getEntityToWorldMatrix()); } -glm::vec3 EntityItem::entityToWorld(const glm::vec3 point) const { +glm::vec3 EntityItem::entityToWorld(const glm::vec3& point) const { return glm::vec3(getEntityToWorldMatrix() * glm::vec4(point, 1.0f)); } -glm::vec3 EntityItem::worldToEntity(const glm::vec3 point) const { +glm::vec3 EntityItem::worldToEntity(const glm::vec3& point) const { return glm::vec3(getWorldToEntityMatrix() * glm::vec4(point, 1.0f)); } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index d6f9a9506f..f666151e0d 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -174,7 +174,7 @@ public: float getDensity() const { return _density; } - const glm::vec3 getVelocity() const { return _velocity; } /// get velocity in meters + const glm::vec3& getVelocity() const { return _velocity; } /// get velocity in meters void setVelocity(const glm::vec3& value) { _velocity = value; } /// velocity in meters bool hasVelocity() const { return _velocity != ENTITY_ITEM_ZERO_VEC3; } @@ -182,7 +182,7 @@ public: void setGravity(const glm::vec3& value) { _gravity = value; } /// gravity in meters bool hasGravity() const { return _gravity != ENTITY_ITEM_ZERO_VEC3; } - const glm::vec3 getAcceleration() const { return _acceleration; } /// get acceleration in meters/second/second + const glm::vec3& getAcceleration() const { return _acceleration; } /// get acceleration in meters/second/second void setAcceleration(const glm::vec3& value) { _acceleration = value; } /// acceleration in meters/second/second bool hasAcceleration() const { return _acceleration != ENTITY_ITEM_ZERO_VEC3; } @@ -301,8 +301,8 @@ public: glm::mat4 getEntityToWorldMatrix() const; glm::mat4 getWorldToEntityMatrix() const; - glm::vec3 worldToEntity(const glm::vec3 point) const; - glm::vec3 entityToWorld(const glm::vec3 point) const; + glm::vec3 worldToEntity(const glm::vec3& point) const; + glm::vec3 entityToWorld(const glm::vec3& point) const; protected: From e3d29d74aff2d87335e36f0be8e44c5293d7eb08 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Sun, 26 Apr 2015 15:24:30 -0700 Subject: [PATCH 08/12] name changes and preparation for more cleanup --- libraries/physics/src/EntityMotionState.cpp | 46 +++++++++++---------- libraries/physics/src/EntityMotionState.h | 22 +++++++--- libraries/physics/src/ObjectMotionState.cpp | 24 +++++------ libraries/physics/src/ObjectMotionState.h | 37 ++++++++++++----- libraries/physics/src/PhysicsEngine.cpp | 26 ++++++------ 5 files changed, 91 insertions(+), 64 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index f905b00ffa..1015693213 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -50,7 +50,7 @@ EntityMotionState::~EntityMotionState() { _entity = NULL; } -MotionType EntityMotionState::computeMotionType() const { +MotionType EntityMotionState::computeObjectMotionType() const { if (_entity->getCollisionsWillMove()) { return MOTION_TYPE_DYNAMIC; } @@ -67,7 +67,7 @@ void EntityMotionState::stepKinematicSimulation(quint64 now) { // which is different from physical kinematic motion (inside getWorldTransform()) // which steps in physics simulation time. _entity->simulate(now); - // TODO: we can't use ObjectMotionState::measureAcceleration() here because the entity + // TODO: we can't use measureBodyAcceleration() here because the entity // has no RigidBody and the timestep is a little bit out of sync with the physics simulation anyway. // Hence we must manually measure kinematic velocity and acceleration. } @@ -100,7 +100,7 @@ void EntityMotionState::getWorldTransform(btTransform& worldTrans) const { // This callback is invoked by the physics simulation at the end of each simulation step... // iff the corresponding RigidBody is DYNAMIC and has moved. void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { - measureAcceleration(); + measureBodyAcceleration(); _entity->setPosition(bulletToGLM(worldTrans.getOrigin()) + ObjectMotionState::getWorldOffset()); _entity->setRotation(bulletToGLM(worldTrans.getRotation())); @@ -128,63 +128,65 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { void EntityMotionState::updateObjectEasy(uint32_t flags, uint32_t step) { if (flags & (EntityItem::DIRTY_POSITION | EntityItem::DIRTY_VELOCITY)) { if (flags & EntityItem::DIRTY_POSITION) { - _sentPosition = _entity->getPosition() - ObjectMotionState::getWorldOffset(); + _sentPosition = getObjectPosition() - ObjectMotionState::getWorldOffset(); btTransform worldTrans; worldTrans.setOrigin(glmToBullet(_sentPosition)); - _sentRotation = _entity->getRotation(); + _sentRotation = getObjectRotation(); worldTrans.setRotation(glmToBullet(_sentRotation)); _body->setWorldTransform(worldTrans); } if (flags & EntityItem::DIRTY_VELOCITY) { - updateObjectVelocities(); + updateBodyVelocities(); } _sentStep = step; + _body->activate(); } if (flags & EntityItem::DIRTY_MATERIAL) { - updateMaterialProperties(); + updateBodyMaterialProperties(); } if (flags & EntityItem::DIRTY_MASS) { - float mass = _entity->computeMass(); + ShapeInfo shapeInfo; + _entity->computeShapeInfo(shapeInfo); + float mass = computeObjectMass(shapeInfo); btVector3 inertia(0.0f, 0.0f, 0.0f); _body->getCollisionShape()->calculateLocalInertia(mass, inertia); _body->setMassProps(mass, inertia); _body->updateInertiaTensor(); } - _body->activate(); } -void EntityMotionState::updateMaterialProperties() { - _body->setRestitution(_entity->getRestitution()); - _body->setFriction(_entity->getFriction()); - _body->setDamping(fabsf(btMin(_entity->getDamping(), 1.0f)), fabsf(btMin(_entity->getAngularDamping(), 1.0f))); +void EntityMotionState::updateBodyMaterialProperties() { + _body->setRestitution(getObjectRestitution()); + _body->setFriction(getObjectFriction()); + _body->setDamping(fabsf(btMin(getObjectLinearDamping(), 1.0f)), fabsf(btMin(getObjectAngularDamping(), 1.0f))); } -void EntityMotionState::updateObjectVelocities() { +void EntityMotionState::updateBodyVelocities() { if (_body) { - _sentVelocity = _entity->getVelocity(); - setVelocity(_sentVelocity); + _sentVelocity = getObjectLinearVelocity(); + setBodyVelocity(_sentVelocity); - _sentAngularVelocity = _entity->getAngularVelocity(); - setAngularVelocity(_sentAngularVelocity); + _sentAngularVelocity = getObjectAngularVelocity(); + setBodyAngularVelocity(_sentAngularVelocity); - _sentGravity = _entity->getGravity(); - setGravity(_sentGravity); + _sentGravity = getObjectGravity(); + setBodyGravity(_sentGravity); _body->setActivationState(ACTIVE_TAG); } } -void EntityMotionState::computeShapeInfo(ShapeInfo& shapeInfo) { +void EntityMotionState::computeObjectShapeInfo(ShapeInfo& shapeInfo) { if (_entity->isReadyToComputeShape()) { _entity->computeShapeInfo(shapeInfo); } } -float EntityMotionState::computeMass(const ShapeInfo& shapeInfo) const { +float EntityMotionState::computeObjectMass(const ShapeInfo& shapeInfo) const { return _entity->computeMass(); } diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index e8a96428a0..7cdc3acbf7 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -31,12 +31,11 @@ public: static void setOutgoingEntityList(QSet* list); static void enqueueOutgoingEntity(EntityItem* entity); - EntityMotionState() = delete; // prevent compiler from making default ctor EntityMotionState(EntityItem* item); virtual ~EntityMotionState(); /// \return MOTION_TYPE_DYNAMIC or MOTION_TYPE_STATIC based on params set in EntityItem - virtual MotionType computeMotionType() const; + virtual MotionType computeObjectMotionType() const; virtual void updateKinematicState(uint32_t substep); virtual void stepKinematicSimulation(quint64 now); @@ -51,11 +50,11 @@ public: // these relay incoming values to the RigidBody virtual void updateObjectEasy(uint32_t flags, uint32_t step); - virtual void updateMaterialProperties(); - virtual void updateObjectVelocities(); + virtual void updateBodyMaterialProperties(); + virtual void updateBodyVelocities(); - virtual void computeShapeInfo(ShapeInfo& shapeInfo); - virtual float computeMass(const ShapeInfo& shapeInfo) const; + virtual void computeObjectShapeInfo(ShapeInfo& shapeInfo); + virtual float computeObjectMass(const ShapeInfo& shapeInfo) const; virtual bool shouldSendUpdate(uint32_t simulationFrame); virtual void sendUpdate(OctreeEditPacketSender* packetSender, uint32_t step); @@ -71,6 +70,17 @@ public: virtual void setShouldClaimSimulationOwnership(bool value) { _shouldClaimSimulationOwnership = value; } virtual bool getShouldClaimSimulationOwnership() { return _shouldClaimSimulationOwnership; } + virtual float getObjectRestitution() const { return _entity->getRestitution(); } + virtual float getObjectFriction() const { return _entity->getFriction(); } + virtual float getObjectLinearDamping() const { return _entity->getDamping(); } + virtual float getObjectAngularDamping() const { return _entity->getAngularDamping(); } + + virtual const glm::vec3& getObjectPosition() const { return _entity->getPosition(); } + virtual const glm::quat& getObjectRotation() const { return _entity->getRotation(); } + virtual const glm::vec3& getObjectLinearVelocity() const { return _entity->getVelocity(); } + virtual const glm::vec3& getObjectAngularVelocity() const { return _entity->getAngularVelocity(); } + virtual const glm::vec3& getObjectGravity() const { return _entity->getGravity(); } + protected: EntityItem* _entity; quint8 _accelerationNearlyGravityCount; diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 96257950ff..d8eb86f0b4 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -36,10 +36,10 @@ const glm::vec3& ObjectMotionState::getWorldOffset() { } // static -uint32_t _simulationStep = 0; -void ObjectMotionState::setSimulationStep(uint32_t step) { - assert(step > _simulationStep); - _simulationStep = step; +uint32_t _worldSimulationStep = 0; +void ObjectMotionState::setWorldSimulationStep(uint32_t step) { + assert(step > _worldSimulationStep); + _worldSimulationStep = step; } ObjectMotionState::ObjectMotionState() : @@ -65,13 +65,13 @@ ObjectMotionState::~ObjectMotionState() { assert(_body == NULL); } -void ObjectMotionState::measureAcceleration() { +void ObjectMotionState::measureBodyAcceleration() { // try to manually measure the true acceleration of the object - uint32_t numSubsteps = _simulationStep - _lastSimulationStep; + uint32_t numSubsteps = _worldSimulationStep - _lastSimulationStep; if (numSubsteps > 0) { float dt = ((float)numSubsteps * PHYSICS_ENGINE_FIXED_SUBSTEP); float invDt = 1.0f / dt; - _lastSimulationStep = _simulationStep; + _lastSimulationStep = _worldSimulationStep; // Note: the integration equation for velocity uses damping: v1 = (v0 + a * dt) * (1 - D)^dt // hence the equation for acceleration is: a = (v1 / (1 - D)^dt - v0) / dt @@ -81,20 +81,20 @@ void ObjectMotionState::measureAcceleration() { } } -void ObjectMotionState::resetMeasuredAcceleration() { - _lastSimulationStep = _simulationStep; +void ObjectMotionState::resetMeasuredBodyAcceleration() { + _lastSimulationStep = _worldSimulationStep; _lastVelocity = bulletToGLM(_body->getLinearVelocity()); } -void ObjectMotionState::setVelocity(const glm::vec3& velocity) const { +void ObjectMotionState::setBodyVelocity(const glm::vec3& velocity) const { _body->setLinearVelocity(glmToBullet(velocity)); } -void ObjectMotionState::setAngularVelocity(const glm::vec3& velocity) const { +void ObjectMotionState::setBodyAngularVelocity(const glm::vec3& velocity) const { _body->setAngularVelocity(glmToBullet(velocity)); } -void ObjectMotionState::setGravity(const glm::vec3& gravity) const { +void ObjectMotionState::setBodyGravity(const glm::vec3& gravity) const { _body->setGravity(glmToBullet(gravity)); } diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 0f1d04d0bd..049e3c6a37 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -59,28 +59,29 @@ public: static void setWorldOffset(const glm::vec3& offset); static const glm::vec3& getWorldOffset(); - static void setSimulationStep(uint32_t step); + // The WorldSimulationStep is a cached copy of number of SubSteps of the simulation, used for local time measurements. + static void setWorldSimulationStep(uint32_t step); ObjectMotionState(); ~ObjectMotionState(); - void measureAcceleration(); - void resetMeasuredAcceleration(); + void measureBodyAcceleration(); + void resetMeasuredBodyAcceleration(); // An EASY update does not require the object to be removed and then reinserted into the PhysicsEngine virtual void updateObjectEasy(uint32_t flags, uint32_t frame) = 0; - virtual void updateMaterialProperties() = 0; - virtual void updateObjectVelocities() = 0; + virtual void updateBodyMaterialProperties() = 0; + virtual void updateBodyVelocities() = 0; MotionStateType getType() const { return _type; } virtual MotionType getMotionType() const { return _motionType; } - virtual void computeShapeInfo(ShapeInfo& info) = 0; - virtual float computeMass(const ShapeInfo& shapeInfo) const = 0; + virtual void computeObjectShapeInfo(ShapeInfo& info) = 0; + virtual float computeObjectMass(const ShapeInfo& shapeInfo) const = 0; - void setVelocity(const glm::vec3& velocity) const; - void setAngularVelocity(const glm::vec3& velocity) const; - void setGravity(const glm::vec3& gravity) const; + void setBodyVelocity(const glm::vec3& velocity) const; + void setBodyAngularVelocity(const glm::vec3& velocity) const; + void setBodyGravity(const glm::vec3& gravity) const; void getVelocity(glm::vec3& velocityOut) const; void getAngularVelocity(glm::vec3& angularVelocityOut) const; @@ -93,7 +94,7 @@ public: virtual bool shouldSendUpdate(uint32_t simulationStep); virtual void sendUpdate(OctreeEditPacketSender* packetSender, uint32_t frame) = 0; - virtual MotionType computeMotionType() const = 0; + virtual MotionType computeObjectMotionType() const = 0; virtual void updateKinematicState(uint32_t substep) = 0; @@ -113,6 +114,20 @@ public: virtual void setShouldClaimSimulationOwnership(bool value) { } virtual bool getShouldClaimSimulationOwnership() { return false; } + // These pure virtual methods must be implemented for each MotionState type + // and make it possible to implement more complicated methods in this base class. + + virtual float getObjectRestitution() const = 0; + virtual float getObjectFriction() const = 0; + virtual float getObjectLinearDamping() const = 0; + virtual float getObjectAngularDamping() const = 0; + + virtual const glm::vec3& getObjectPosition() const = 0; + virtual const glm::quat& getObjectRotation() const = 0; + virtual const glm::vec3& getObjectLinearVelocity() const = 0; + virtual const glm::vec3& getObjectAngularVelocity() const = 0; + virtual const glm::vec3& getObjectGravity() const = 0; + protected: void setRigidBody(btRigidBody* body); diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 00ac807808..5422917aa7 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -196,7 +196,7 @@ void PhysicsEngine::relayIncomingChangesToSimulation() { motionState->updateObjectEasy(flags, _numSubsteps); } if (flags & (EntityItem::DIRTY_POSITION | EntityItem::DIRTY_VELOCITY)) { - motionState->resetMeasuredAcceleration(); + motionState->resetMeasuredBodyAcceleration(); } } else { // the only way we should ever get here (motionState exists but no body) is when the object @@ -206,7 +206,7 @@ void PhysicsEngine::relayIncomingChangesToSimulation() { // it is possible that the changes are such that the object can now be added to the physical simulation if (flags & EntityItem::DIRTY_SHAPE) { ShapeInfo shapeInfo; - motionState->computeShapeInfo(shapeInfo); + motionState->computeObjectShapeInfo(shapeInfo); btCollisionShape* shape = _shapeManager.getShape(shapeInfo); if (shape) { addObject(shapeInfo, shape, motionState); @@ -340,7 +340,7 @@ void PhysicsEngine::stepSimulation() { // lock on the tree before we re-lock ourselves. // // TODO: untangle these lock sequences. - ObjectMotionState::setSimulationStep(_numSubsteps); + ObjectMotionState::setWorldSimulationStep(_numSubsteps); _entityTree->lockForWrite(); lock(); _dynamicsWorld->synchronizeMotionStates(); @@ -485,7 +485,7 @@ void PhysicsEngine::addObject(const ShapeInfo& shapeInfo, btCollisionShape* shap btVector3 inertia(0.0f, 0.0f, 0.0f); float mass = 0.0f; btRigidBody* body = NULL; - switch(motionState->computeMotionType()) { + switch(motionState->computeObjectMotionType()) { case MOTION_TYPE_KINEMATIC: { body = new btRigidBody(mass, motionState, shape, inertia); body->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT); @@ -498,13 +498,13 @@ void PhysicsEngine::addObject(const ShapeInfo& shapeInfo, btCollisionShape* shap break; } case MOTION_TYPE_DYNAMIC: { - mass = motionState->computeMass(shapeInfo); + mass = motionState->computeObjectMass(shapeInfo); shape->calculateLocalInertia(mass, inertia); body = new btRigidBody(mass, motionState, shape, inertia); body->updateInertiaTensor(); motionState->setRigidBody(body); motionState->setKinematic(false, _numSubsteps); - motionState->updateObjectVelocities(); + motionState->updateBodyVelocities(); // NOTE: Bullet will deactivate any object whose velocity is below these thresholds for longer than 2 seconds. // (the 2 seconds is determined by: static btRigidBody::gDeactivationTime const float DYNAMIC_LINEAR_VELOCITY_THRESHOLD = 0.05f; // 5 cm/sec @@ -527,10 +527,10 @@ void PhysicsEngine::addObject(const ShapeInfo& shapeInfo, btCollisionShape* shap } } body->setFlags(BT_DISABLE_WORLD_GRAVITY); - motionState->updateMaterialProperties(); + motionState->updateBodyMaterialProperties(); _dynamicsWorld->addRigidBody(body); - motionState->resetMeasuredAcceleration(); + motionState->resetMeasuredBodyAcceleration(); } void PhysicsEngine::bump(EntityItem* bumpEntity) { @@ -597,7 +597,7 @@ void PhysicsEngine::removeObjectFromBullet(ObjectMotionState* motionState) { // private bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags) { - MotionType newType = motionState->computeMotionType(); + MotionType newType = motionState->computeObjectMotionType(); // pull body out of physics engine _dynamicsWorld->removeRigidBody(body); @@ -609,7 +609,7 @@ bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio // get new shape btCollisionShape* oldShape = body->getCollisionShape(); ShapeInfo shapeInfo; - motionState->computeShapeInfo(shapeInfo); + motionState->computeObjectShapeInfo(shapeInfo); btCollisionShape* newShape = _shapeManager.getShape(shapeInfo); if (!newShape) { // FAIL! we are unable to support these changes! @@ -628,7 +628,7 @@ bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio _shapeManager.releaseShape(oldShape); // compute mass properties - float mass = motionState->computeMass(shapeInfo); + float mass = motionState->computeObjectMass(shapeInfo); btVector3 inertia(0.0f, 0.0f, 0.0f); body->getCollisionShape()->calculateLocalInertia(mass, inertia); body->setMassProps(mass, inertia); @@ -663,8 +663,8 @@ bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio if (! (flags & EntityItem::DIRTY_MASS)) { // always update mass properties when going dynamic (unless it's already been done above) ShapeInfo shapeInfo; - motionState->computeShapeInfo(shapeInfo); - float mass = motionState->computeMass(shapeInfo); + motionState->computeObjectShapeInfo(shapeInfo); + float mass = motionState->computeObjectMass(shapeInfo); btVector3 inertia(0.0f, 0.0f, 0.0f); body->getCollisionShape()->calculateLocalInertia(mass, inertia); body->setMassProps(mass, inertia); From 31e57584229073de2296967b3b68601b05a36bd6 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 27 Apr 2015 13:04:59 -0700 Subject: [PATCH 09/12] namechange updateObjectEasy()-->updateBodyEasy() --- libraries/physics/src/EntityMotionState.cpp | 2 +- libraries/physics/src/EntityMotionState.h | 2 +- libraries/physics/src/ObjectMotionState.h | 3 ++- libraries/physics/src/PhysicsEngine.cpp | 10 +++++----- libraries/physics/src/PhysicsEngine.h | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 74096a3f45..a7245c32d4 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -138,7 +138,7 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { #endif } -void EntityMotionState::updateObjectEasy(uint32_t flags, uint32_t step) { +void EntityMotionState::updateBodyEasy(uint32_t flags, uint32_t step) { if (flags & (EntityItem::DIRTY_POSITION | EntityItem::DIRTY_VELOCITY | EntityItem::DIRTY_PHYSICS_NO_WAKE)) { if (flags & EntityItem::DIRTY_POSITION) { _sentPosition = getObjectPosition() - ObjectMotionState::getWorldOffset(); diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index b3323cafec..98d05a0420 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -49,7 +49,7 @@ public: virtual void setWorldTransform(const btTransform& worldTrans); // these relay incoming values to the RigidBody - virtual void updateObjectEasy(uint32_t flags, uint32_t step); + virtual void updateBodyEasy(uint32_t flags, uint32_t step); virtual void updateBodyMaterialProperties(); virtual void updateBodyVelocities(); diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 049e3c6a37..7c00eedd09 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -69,7 +69,8 @@ public: void resetMeasuredBodyAcceleration(); // An EASY update does not require the object to be removed and then reinserted into the PhysicsEngine - virtual void updateObjectEasy(uint32_t flags, uint32_t frame) = 0; + virtual void updateBodyEasy(uint32_t flags, uint32_t frame) = 0; + virtual void updateBodyMaterialProperties() = 0; virtual void updateBodyVelocities() = 0; diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 0f3d677017..603aef731c 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -173,9 +173,9 @@ void PhysicsEngine::relayIncomingChangesToSimulation() { if (flags & HARD_DIRTY_PHYSICS_FLAGS) { // a HARD update requires the body be pulled out of physics engine, changed, then reinserted // but it also handles all EASY changes - bool success = updateObjectHard(body, motionState, flags); + bool success = updateBodyHard(body, motionState, flags); if (!success) { - // NOTE: since updateObjectHard() failed we know that motionState has been removed + // NOTE: since updateBodyHard() failed we know that motionState has been removed // from simulation and body has been deleted. Depending on what else has changed // we might need to remove motionState altogether... if (flags & EntityItem::DIRTY_VELOCITY) { @@ -195,7 +195,7 @@ void PhysicsEngine::relayIncomingChangesToSimulation() { } else if (flags) { // an EASY update does NOT require that the body be pulled out of physics engine // hence the MotionState has all the knowledge and authority to perform the update. - motionState->updateObjectEasy(flags, _numSubsteps); + motionState->updateBodyEasy(flags, _numSubsteps); } if (flags & (EntityItem::DIRTY_POSITION | EntityItem::DIRTY_VELOCITY)) { motionState->resetMeasuredBodyAcceleration(); @@ -608,7 +608,7 @@ void PhysicsEngine::removeObjectFromBullet(ObjectMotionState* motionState) { } // private -bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags) { +bool PhysicsEngine::updateBodyHard(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags) { MotionType newType = motionState->computeObjectMotionType(); // pull body out of physics engine @@ -653,7 +653,7 @@ bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio } bool easyUpdate = flags & EASY_DIRTY_PHYSICS_FLAGS; if (easyUpdate) { - motionState->updateObjectEasy(flags, _numSubsteps); + motionState->updateBodyEasy(flags, _numSubsteps); } // update the motion parameters diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index a005c0f4f9..4f931d939a 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -100,7 +100,7 @@ private: void doOwnershipInfection(const btCollisionObject* objectA, const btCollisionObject* objectB); // return 'true' of update was successful - bool updateObjectHard(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags); + bool updateBodyHard(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags); void updateObjectEasy(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags); btClock _clock; From 62a421361ce243d654aec339366f0dd0751ec41b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 27 Apr 2015 16:58:34 -0700 Subject: [PATCH 10/12] fix crash in scripts using useAvatar methods --- interface/src/avatar/MyAvatar.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4e09f57267..cd7bedc19e 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -987,6 +987,13 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { } void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelName) { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "useFullAvatarURL", Qt::BlockingQueuedConnection, + Q_ARG(const QUrl&, fullAvatarURL), + Q_ARG(const QString&, modelName)); + return; + } + _useFullAvatar = true; if (_fullAvatarURLFromPreferences != fullAvatarURL) { @@ -1019,6 +1026,15 @@ void MyAvatar::useBodyURL(const QUrl& bodyURL, const QString& modelName) { } void MyAvatar::useHeadAndBodyURLs(const QUrl& headURL, const QUrl& bodyURL, const QString& headName, const QString& bodyName) { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "useFullAvatarURL", Qt::BlockingQueuedConnection, + Q_ARG(const QUrl&, headURL), + Q_ARG(const QUrl&, bodyURL), + Q_ARG(const QString&, headName), + Q_ARG(const QString&, bodyName)); + return; + } + _useFullAvatar = false; if (_headURLFromPreferences != headURL) { From 6f441e3490d3c43925b9faf071676e690d51e2f7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 27 Apr 2015 19:07:53 -0700 Subject: [PATCH 11/12] if our Node isn't allowed to create entities in this domain, don't try. --- .../entities/src/EntityScriptingInterface.cpp | 17 +++++++++++++---- libraries/entities/src/EntityTree.cpp | 8 ++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 04da26a1ff..1dbd67f3b2 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -16,6 +16,7 @@ #include "LightEntityItem.h" #include "ModelEntityItem.h" #include "ZoneEntityItem.h" +#include "EntitiesLogging.h" EntityScriptingInterface::EntityScriptingInterface() : @@ -78,19 +79,27 @@ EntityItemID EntityScriptingInterface::addEntity(const EntityItemProperties& pro EntityItemProperties propertiesWithSimID = properties; - EntityItemID id(NEW_ENTITY, creatorTokenID, false ); + EntityItemID id(NEW_ENTITY, creatorTokenID, false); // If we have a local entity tree set, then also update it. + bool success = true; if (_entityTree) { _entityTree->lockForWrite(); EntityItem* entity = _entityTree->addEntity(id, propertiesWithSimID); - // This Node is creating a new object. If it's in motion, set this Node as the simulator. - setSimId(propertiesWithSimID, entity); + if (entity) { + // This Node is creating a new object. If it's in motion, set this Node as the simulator. + setSimId(propertiesWithSimID, entity); + } else { + qCDebug(entities) << "script failed to add new Entity to local Octree"; + success = false; + } _entityTree->unlock(); } // queue the packet - queueEntityMessage(PacketTypeEntityAddOrEdit, id, propertiesWithSimID); + if (success) { + queueEntityMessage(PacketTypeEntityAddOrEdit, id, propertiesWithSimID); + } return id; } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index a63a7ef7c3..436339b3fe 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -192,6 +192,14 @@ bool EntityTree::updateEntityWithElement(EntityItem* entity, const EntityItemPro EntityItem* EntityTree::addEntity(const EntityItemID& entityID, const EntityItemProperties& properties) { EntityItem* result = NULL; + if (getIsClient()) { + // if our Node isn't allowed to create entities in this domain, don't try. + auto nodeList = DependencyManager::get(); + if (!nodeList->getThisNodeCanRez()) { + return NULL; + } + } + // NOTE: This method is used in the client and the server tree. In the client, it's possible to create EntityItems // that do not yet have known IDs. In the server tree however we don't want to have entities without known IDs. bool recordCreationTime = false; From 897e47e8e6946feb9883b1712c646d9ae8a10e39 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 27 Apr 2015 23:17:56 -0700 Subject: [PATCH 12/12] Removing debug hack to load resources from source folder --- libraries/shared/src/PathUtils.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/libraries/shared/src/PathUtils.cpp b/libraries/shared/src/PathUtils.cpp index 47e5659c60..84c8ae4939 100644 --- a/libraries/shared/src/PathUtils.cpp +++ b/libraries/shared/src/PathUtils.cpp @@ -19,19 +19,10 @@ QString& PathUtils::resourcesPath() { -#ifdef DEBUG - static QString staticResourcePath; - if (staticResourcePath.isEmpty()) { - QDir path(__FILE__); - path.cdUp(); - staticResourcePath = path.cleanPath(path.absoluteFilePath("../../../interface/resources/")) + "/"; - } -#else #ifdef Q_OS_MAC static QString staticResourcePath = QCoreApplication::applicationDirPath() + "/../Resources/"; #else static QString staticResourcePath = QCoreApplication::applicationDirPath() + "/resources/"; -#endif #endif return staticResourcePath;