From 0d3e78fdb819654f7fbd40ae88952942839e398f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 31 Dec 2014 16:29:55 -0800 Subject: [PATCH 1/6] modify extrapolation behavior when bullet enabled Allows Bullet to specify an object as "at rest" by setting velocity to zero. Also, moved velocity damping above position integration to get the same order of operations as Bullet. --- libraries/entities/CMakeLists.txt | 1 + libraries/entities/src/EntityItem.cpp | 61 +++++++++++++++++---------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/libraries/entities/CMakeLists.txt b/libraries/entities/CMakeLists.txt index 2da7745837..7589599548 100644 --- a/libraries/entities/CMakeLists.txt +++ b/libraries/entities/CMakeLists.txt @@ -4,6 +4,7 @@ set(TARGET_NAME entities) setup_hifi_library(Network Script) include_glm() +include_bullet() link_hifi_libraries(avatars shared octree gpu model fbx networking animation) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index d0b019467c..12b95c48d2 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -648,7 +648,8 @@ void EntityItem::simulate(const quint64& now) { glm::vec3 angularVelocity = glm::radians(getAngularVelocity()); float angularSpeed = glm::length(angularVelocity); - if (angularSpeed < EPSILON_VELOCITY_LENGTH) { + const float EPSILON_ANGULAR_VELOCITY_LENGTH = 0.0017453f; // ~0.1 degree/sec + if (angularSpeed < EPSILON_ANGULAR_VELOCITY_LENGTH) { setAngularVelocity(NO_ANGULAR_VELOCITY); } else { float angle = timeElapsed * angularSpeed; @@ -670,9 +671,31 @@ void EntityItem::simulate(const quint64& now) { } } +#ifdef USE_BULLET_PHYSICS + // When Bullet is available we assume that "zero velocity" means "at rest" + // because of collision conditions this simulation does not know about + // so we don't fall in for the non-zero gravity case here. + if (hasVelocity()) { +#else // !USE_BULLET_PHYSICS if (hasVelocity() || hasGravity()) { - glm::vec3 position = getPosition(); +#endif // USE_BULLET_PHYSICS + + // linear damping glm::vec3 velocity = getVelocity(); + float dampingTimescale = getDamping(); + if (dampingTimescale > 0.0f) { + float dampingFactor = glm::clamp(timeElapsed / dampingTimescale, 0.0f, 1.0f); + velocity *= (1.0f - dampingFactor); + if (wantDebug) { + qDebug() << " dampingTimescale:" << dampingTimescale; + qDebug() << " velocity AFTER dampingResistance:" << velocity; + qDebug() << " glm::length(velocity):" << glm::length(velocity); + qDebug() << " EPSILON_VELOCITY_LENGTH:" << EPSILON_VELOCITY_LENGTH; + } + } + + // integrate position forward + glm::vec3 position = getPosition(); glm::vec3 newPosition = position + (velocity * timeElapsed); if (wantDebug) { @@ -701,10 +724,10 @@ void EntityItem::simulate(const quint64& now) { position.y = getDistanceToBottomOfEntity(); } - // handle gravity.... + // apply gravity if (hasGravity()) { // handle resting on surface case, this is definitely a bit of a hack, and it only works on the - // "ground" plane of the domain, but for now it what we've got + // "ground" plane of the domain, but for now it's what we've got if (isRestingOnSurface()) { velocity.y = 0.0f; position.y = getDistanceToBottomOfEntity(); @@ -712,28 +735,15 @@ void EntityItem::simulate(const quint64& now) { velocity += getGravity() * timeElapsed; } } - - // handle damping for velocity - float dampingTimescale = getDamping(); - if (dampingTimescale > 0.0f) { - float dampingFactor = glm::clamp(timeElapsed / dampingTimescale, 0.0f, 1.0f); - velocity *= (1.0f - dampingFactor); - if (wantDebug) { - qDebug() << " dampingTimescale:" << dampingTimescale; - qDebug() << " newVelocity:" << velocity; - } - } - - if (wantDebug) { - qDebug() << " velocity AFTER dampingResistance:" << velocity; - qDebug() << " glm::length(velocity):" << glm::length(velocity); - qDebug() << " EPSILON_VELOCITY_LENGTH:" << EPSILON_VELOCITY_LENGTH; - } - // round velocity to zero if it's close enough... +#ifdef USE_BULLET_PHYSICS + // When Bullet is available we assume that it will tell us when velocities go to zero... +#else // !USE_BULLET_PHYSICS + // ... otherwise we help things come to rest by clamping small velocities. if (glm::length(velocity) <= EPSILON_VELOCITY_LENGTH) { velocity = NO_VELOCITY; } +#endif // USE_BULLET_PHYSICS // NOTE: the simulation should NOT set any DirtyFlags on this entity setPosition(position); // this will automatically recalculate our collision shape @@ -751,7 +761,13 @@ void EntityItem::simulate(const quint64& now) { } bool EntityItem::isMoving() const { +#ifdef USE_BULLET_PHYSICS + // When Bullet is available we assume that "zero velocity" means "at rest" + // because of collision conditions this simulation does not know about. + return hasVelocity() || hasAngularVelocity(); +#else // !USE_BULLET_PHYSICS return hasVelocity() || (hasGravity() && !isRestingOnSurface()) || hasAngularVelocity(); +#endif //USE_BULLET_PHYSICS } bool EntityItem::lifetimeHasExpired() const { @@ -1009,7 +1025,6 @@ const float MIN_GRAVITY_DELTA = 0.001f; const float MIN_SPIN_DELTA = 0.0003f; void EntityItem::updatePosition(const glm::vec3& value) { - glm::vec3 debugPosition = value * (float) TREE_SCALE; if (glm::distance(_position, value) * (float)TREE_SCALE > MIN_POSITION_DELTA) { _position = value; recalculateCollisionShape(); From 30200ef7eb03799410a396ed7ba9b1dfeca0257c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Jan 2015 09:17:46 -0800 Subject: [PATCH 2/6] add damping to ObjectMotionState --- libraries/physics/src/ObjectMotionState.cpp | 10 ++++++++++ libraries/physics/src/ObjectMotionState.h | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index ded2291229..4abe52a861 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -48,6 +48,8 @@ ObjectMotionState::ObjectMotionState() : _volume(DEFAULT_VOLUME), _friction(DEFAULT_FRICTION), _restitution(DEFAULT_RESTITUTION), + _linearDamping(0.0f), + _angularDamping(0.0f), _wasInWorld(false), _motionType(MOTION_TYPE_STATIC), _body(NULL), @@ -79,6 +81,14 @@ 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::setVolume(float volume) { _volume = btMax(btMin(fabsf(volume), MAX_VOLUME), MIN_VOLUME); } diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index ea9dcad0fc..24a00609cf 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -66,6 +66,8 @@ public: void setDensity(float density); void setFriction(float friction); void setRestitution(float restitution); + void setLinearDamping(float damping); + void setAngularDamping(float damping); void setVolume(float volume); float getMass() const { return _volume * _density; } @@ -93,6 +95,8 @@ protected: float _volume; float _friction; float _restitution; + float _linearDamping; + float _angularDamping; bool _wasInWorld; MotionType _motionType; From 3b7770f40555413bfa01f28a089de731ee54fbeb Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Jan 2015 11:23:01 -0800 Subject: [PATCH 3/6] change meaning of damping to agree with bullet 0 = no damping 1 = 100% damping The new formula is: velocity *= (1 - damping)^dt --- libraries/entities/src/EntityItem.cpp | 53 +++++++++++++++---------- libraries/entities/src/EntityItem.h | 16 +++++++- libraries/physics/src/PhysicsEngine.cpp | 2 + 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 5bdd755759..99c55740f7 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -29,7 +29,7 @@ const float EntityItem::DEFAULT_LOCAL_RENDER_ALPHA = 1.0f; const float EntityItem::DEFAULT_MASS = 1.0f; const float EntityItem::DEFAULT_LIFETIME = EntityItem::IMMORTAL; const QString EntityItem::DEFAULT_USER_DATA = QString(""); -const float EntityItem::DEFAULT_DAMPING = 2.0f; +const float EntityItem::DEFAULT_DAMPING = 0.39347f; // approx timescale = 2.0 sec (see damping timescale formula in header) const glm::vec3 EntityItem::NO_VELOCITY = glm::vec3(0, 0, 0); const float EntityItem::EPSILON_VELOCITY_LENGTH = (1.0f / 1000.0f) / (float)TREE_SCALE; // really small: 1mm/second const glm::vec3 EntityItem::DEFAULT_VELOCITY = EntityItem::NO_VELOCITY; @@ -647,7 +647,17 @@ void EntityItem::simulate(const quint64& now) { if (hasAngularVelocity()) { glm::quat rotation = getRotation(); + + // angular damping glm::vec3 angularVelocity = glm::radians(getAngularVelocity()); + if (_angularDamping > 0.0f) { + angularVelocity *= powf(1.0f - _angularDamping, timeElapsed); + if (wantDebug) { + qDebug() << " angularDamping :" << _angularDamping; + qDebug() << " newAngularVelocity:" << angularVelocity; + } + } + float angularSpeed = glm::length(angularVelocity); const float EPSILON_ANGULAR_VELOCITY_LENGTH = 0.0017453f; // ~0.1 degree/sec @@ -656,20 +666,8 @@ void EntityItem::simulate(const quint64& now) { } else { float angle = timeElapsed * angularSpeed; glm::quat dQ = glm::angleAxis(angle, glm::normalize(angularVelocity)); - rotation = dQ * rotation; + rotation = glm::normalize(dQ * rotation); setRotation(rotation); - - // handle damping for angular velocity - float dampingTimescale = getAngularDamping(); - if (dampingTimescale > 0.0f) { - float dampingFactor = glm::clamp(timeElapsed / dampingTimescale, 0.0f, 1.0f); - glm::vec3 newAngularVelocity = (1.0f - dampingFactor) * getAngularVelocity(); - setAngularVelocity(newAngularVelocity); - if (wantDebug) { - qDebug() << " dampingTimescale :" << dampingTimescale; - qDebug() << " newAngularVelocity:" << newAngularVelocity; - } - } } } @@ -684,12 +682,10 @@ void EntityItem::simulate(const quint64& now) { // linear damping glm::vec3 velocity = getVelocity(); - float dampingTimescale = getDamping(); - if (dampingTimescale > 0.0f) { - float dampingFactor = glm::clamp(timeElapsed / dampingTimescale, 0.0f, 1.0f); - velocity *= (1.0f - dampingFactor); + if (_damping > 0.0f) { + velocity *= powf(1.0f - _damping, timeElapsed); if (wantDebug) { - qDebug() << " dampingTimescale:" << dampingTimescale; + qDebug() << " damping:" << _damping; qDebug() << " velocity AFTER dampingResistance:" << velocity; qDebug() << " glm::length(velocity):" << glm::length(velocity); qDebug() << " EPSILON_VELOCITY_LENGTH:" << EPSILON_VELOCITY_LENGTH; @@ -822,12 +818,12 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(mass, updateMass); SET_ENTITY_PROPERTY_FROM_PROPERTIES(velocity, updateVelocityInMeters); SET_ENTITY_PROPERTY_FROM_PROPERTIES(gravity, updateGravityInMeters); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(damping, setDamping); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(damping, updateDamping); SET_ENTITY_PROPERTY_FROM_PROPERTIES(lifetime, updateLifetime); SET_ENTITY_PROPERTY_FROM_PROPERTIES(script, setScript); SET_ENTITY_PROPERTY_FROM_PROPERTIES(registrationPoint, setRegistrationPoint); SET_ENTITY_PROPERTY_FROM_PROPERTIES(angularVelocity, updateAngularVelocity); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(angularDamping, setAngularDamping); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(angularDamping, updateAngularDamping); SET_ENTITY_PROPERTY_FROM_PROPERTIES(glowLevel, setGlowLevel); SET_ENTITY_PROPERTY_FROM_PROPERTIES(localRenderAlpha, setLocalRenderAlpha); SET_ENTITY_PROPERTY_FROM_PROPERTIES(visible, setVisible); @@ -1023,6 +1019,7 @@ const float MIN_DIMENSION_DELTA = 0.0001f; const float MIN_ALIGNMENT_DOT = 0.9999f; const float MIN_MASS_DELTA = 0.001f; const float MIN_VELOCITY_DELTA = 0.025f; +const float MIN_DAMPING_DELTA = 0.001f; const float MIN_GRAVITY_DELTA = 0.001f; const float MIN_SPIN_DELTA = 0.0003f; @@ -1098,6 +1095,13 @@ void EntityItem::updateVelocityInMeters(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; + } +} + void EntityItem::updateGravity(const glm::vec3& value) { if (glm::distance(_gravity, value) * (float)TREE_SCALE > MIN_GRAVITY_DELTA) { _gravity = value; @@ -1120,6 +1124,13 @@ 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; + } +} + void EntityItem::updateIgnoreForCollisions(bool value) { if (_ignoreForCollisions != value) { _ignoreForCollisions = value; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 7acb55e8c3..5a1b162e4f 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -285,9 +285,11 @@ public: void updateMass(float value); void updateVelocity(const glm::vec3& value); void updateVelocityInMeters(const glm::vec3& value); + void updateDamping(float value); void updateGravity(const glm::vec3& value); void updateGravityInMeters(const glm::vec3& value); void updateAngularVelocity(const glm::vec3& value); + void updateAngularDamping(float value); void updateIgnoreForCollisions(bool value); void updateCollisionsWillMove(bool value); void updateLifetime(float value); @@ -325,17 +327,27 @@ protected: float _mass; glm::vec3 _velocity; glm::vec3 _gravity; - float _damping; // timescale + float _damping; float _lifetime; QString _script; glm::vec3 _registrationPoint; glm::vec3 _angularVelocity; - float _angularDamping; // timescale + float _angularDamping; bool _visible; bool _ignoreForCollisions; bool _collisionsWillMove; bool _locked; QString _userData; + + // NOTE: Damping is applied like this: v *= pow(1 - damping, dt) + // + // Hence the damping coefficient must range from 0 (no damping) to 1 (immediate stop). + // Each damping value relates to a corresponding exponential decay timescale as follows: + // + // timescale = -1 / ln(1 - damping) + // + // damping = 1 - exp(-1 / timescale) + // // NOTE: Radius support is obsolete, but these private helper functions are available for this class to // parse old data streams diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index a6317b4fcf..f6700455a6 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -327,6 +327,7 @@ bool PhysicsEngine::addObject(ObjectMotionState* motionState) { body->setFlags(BT_DISABLE_WORLD_GRAVITY); body->setRestitution(motionState->_restitution); body->setFriction(motionState->_friction); + body->setDamping(motionState->_linearDamping, motionState->_angularDamping); _dynamicsWorld->addRigidBody(body); return true; } @@ -438,6 +439,7 @@ void PhysicsEngine::updateObjectEasy(btRigidBody* body, ObjectMotionState* motio } body->setRestitution(motionState->_restitution); body->setFriction(motionState->_friction); + body->setDamping(motionState->_linearDamping, motionState->_angularDamping); if (flags & EntityItem::DIRTY_MASS) { float mass = motionState->getMass(); From 21b2d14956fa8efd88551a989584c1e8fb6c1f4a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Jan 2015 11:25:15 -0800 Subject: [PATCH 4/6] converting existing JS scripts to use new damping Old formula the scripts were using: v *= damping So a value of 0.999 was "little damping" and a value of 0.001 was "very strong damping", but now that is reversed. New formula: v *= (1 j- damping)^dt A damping value of 0.001 now means "very little damping" and a value of 0.999 means "very strong damping". --- examples/butterflies.js | 4 ++-- examples/cameraExample.js | 2 +- examples/frisbee.js | 6 +++--- examples/grenadeLauncher.js | 2 +- examples/gun.js | 2 +- examples/toyball.js | 2 +- examples/twoFallingEntities.js | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/butterflies.js b/examples/butterflies.js index edc33f7625..6eaa4ba66d 100644 --- a/examples/butterflies.js +++ b/examples/butterflies.js @@ -79,7 +79,7 @@ function addButterfly() { rotation: Quat.fromPitchYawRollDegrees(-80 + Math.random() * 20, Math.random() * 360.0, 0.0), velocity: { x: 0, y: 0, z: 0 }, gravity: { x: 0, y: GRAVITY, z: 0 }, - damping: 0.9999, + damping: 0.00001, dimensions: dimensions, color: color, animationURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/models/content/butterfly/butterfly.fbx", @@ -138,4 +138,4 @@ Script.scriptEnding.connect(function() { for (var i = 0; i < numButterflies; i++) { Entities.deleteEntity(butterflies[i]); } -}); \ No newline at end of file +}); diff --git a/examples/cameraExample.js b/examples/cameraExample.js index 4c02ce2f2e..85d35623b6 100644 --- a/examples/cameraExample.js +++ b/examples/cameraExample.js @@ -11,7 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var damping = 0.9; +var damping = 0.001; var yaw = 0.0; var pitch = 0.0; var roll = 0.0; diff --git a/examples/frisbee.js b/examples/frisbee.js index cf271f4f04..2d60827858 100644 --- a/examples/frisbee.js +++ b/examples/frisbee.js @@ -208,7 +208,7 @@ function checkControllerSide(hand) { gravity: { x: 0, y: 0, z: 0}, inHand: true, dimensions: { x: FRISBEE_RADIUS, y: FRISBEE_RADIUS / 5, z: FRISBEE_RADIUS }, - damping: 0.999, + damping: 0.00001, modelURL: modelUrl, modelScale: FRISBEE_MODEL_SCALE, modelRotation: hand.holdRotation(), @@ -235,7 +235,7 @@ function checkControllerSide(hand) { gravity: { x: 0, y: 0, z: 0}, inHand: true, dimensions: { x: FRISBEE_RADIUS, y: FRISBEE_RADIUS / 5, z: FRISBEE_RADIUS }, - damping: 0.999, + damping: 0.00001, modelURL: frisbeeURL(), modelScale: FRISBEE_MODEL_SCALE, modelRotation: hand.holdRotation(), @@ -444,4 +444,4 @@ Controller.mouseReleaseEvent.connect(mouseReleaseEvent); Menu.menuItemEvent.connect(menuItemEvent); Script.scriptEnding.connect(scriptEnding); Script.update.connect(checkController); -Script.update.connect(controlFrisbees); \ No newline at end of file +Script.update.connect(controlFrisbees); diff --git a/examples/grenadeLauncher.js b/examples/grenadeLauncher.js index 3907e41ea6..088e3aa43c 100644 --- a/examples/grenadeLauncher.js +++ b/examples/grenadeLauncher.js @@ -145,7 +145,7 @@ function shootTarget() { velocity: velocity, gravity: { x: 0, y: TARGET_GRAVITY, z: 0 }, lifetime: 1000.0, - damping: 0.99 }); + damping: 0.0001 }); // Record start time shotTime = new Date(); diff --git a/examples/gun.js b/examples/gun.js index 2386e61539..829ef68759 100644 --- a/examples/gun.js +++ b/examples/gun.js @@ -144,7 +144,7 @@ function shootTarget() { velocity: velocity, gravity: { x: 0, y: TARGET_GRAVITY, z: 0 }, lifetime: TARGET_LIFETIME, - damping: 0.99 }); + damping: 0.0001 }); // Record start time shotTime = new Date(); diff --git a/examples/toyball.js b/examples/toyball.js index e39ca9c8b4..9b91d1f098 100644 --- a/examples/toyball.js +++ b/examples/toyball.js @@ -137,7 +137,7 @@ function checkControllerSide(whichSide) { gravity: { x: 0, y: 0, z: 0}, inHand: true, radius: { x: BALL_RADIUS * 2, y: BALL_RADIUS * 2, z: BALL_RADIUS * 2 }, - damping: 0.999, + damping: 0.00001, color: HELD_COLOR, lifetime: 600 // 10 seconds - same as default, not needed but here as an example diff --git a/examples/twoFallingEntities.js b/examples/twoFallingEntities.js index 0d157b70c3..b4a1f18bad 100644 --- a/examples/twoFallingEntities.js +++ b/examples/twoFallingEntities.js @@ -12,7 +12,7 @@ var properties = { velocity: { x: 0, y: 0, z: 0}, gravity: { x: 0, y: -0.05, z: 0}, radius: radius, - damping: 0.999, + damping: 0.00001, color: { red: 200, green: 0, blue: 0 }, lifetime: 60 }; @@ -22,4 +22,4 @@ position.x -= radius * 1.0; properties.position = position; var newEntityTwo = Entities.addEntity(properties); -Script.stop(); // no need to run anymore \ No newline at end of file +Script.stop(); // no need to run anymore From bf6b8f9ca752068620323cd0922c1f4e464a1ae7 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Jan 2015 12:01:09 -0800 Subject: [PATCH 5/6] do not zero small velocities for non-bullet case --- libraries/entities/src/EntityItem.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 99c55740f7..05ef9cd101 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -714,10 +714,12 @@ void EntityItem::simulate(const quint64& now) { if (position.y <= getDistanceToBottomOfEntity()) { velocity = velocity * glm::vec3(1,-1,1); - // if we've slowed considerably, then just stop moving +#ifndef USE_BULLET_PHYSICS + // if we've slowed considerably, then just stop moving, but only if no BULLET if (glm::length(velocity) <= EPSILON_VELOCITY_LENGTH) { velocity = NO_VELOCITY; } +#endif // !USE_BULLET_PHYSICS position.y = getDistanceToBottomOfEntity(); } From 6fb4e1f622a85aba5c7f59227bbf5cb74cb53d02 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Jan 2015 12:23:55 -0800 Subject: [PATCH 6/6] oops, need to update angularVelocity after damping --- libraries/entities/src/EntityItem.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 05ef9cd101..f18d2ff75a 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -662,13 +662,14 @@ void EntityItem::simulate(const quint64& now) { const float EPSILON_ANGULAR_VELOCITY_LENGTH = 0.0017453f; // ~0.1 degree/sec if (angularSpeed < EPSILON_ANGULAR_VELOCITY_LENGTH) { - setAngularVelocity(NO_ANGULAR_VELOCITY); + angularVelocity = NO_ANGULAR_VELOCITY; } else { float angle = timeElapsed * angularSpeed; glm::quat dQ = glm::angleAxis(angle, glm::normalize(angularVelocity)); rotation = glm::normalize(dQ * rotation); setRotation(rotation); } + setAngularVelocity(angularVelocity); } #ifdef USE_BULLET_PHYSICS