From 244a8503eff8182240dce001719746785469204d Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Jan 2015 14:48:16 -0800 Subject: [PATCH 1/7] include damping in remote extrapolation model --- libraries/physics/src/ObjectMotionState.cpp | 16 ++++++++++------ libraries/physics/src/ObjectMotionState.h | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 4abe52a861..67763a98a9 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -123,9 +123,10 @@ bool ObjectMotionState::doesNotNeedToSendUpdate() const { const float FIXED_SUBSTEP = 1.0f / 60.0f; -bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame, float subStepRemainder) const { +bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame, float subStepRemainder) { assert(_body); float dt = (float)(simulationFrame - _sentFrame) * FIXED_SUBSTEP + subStepRemainder; + _sentFrame = simulationFrame; bool isActive = _body->isActive(); if (isActive) { @@ -156,28 +157,31 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame, float subStep // TODO: Andrew to reconcile Bullet and legacy damping coefficients. // compute position error - glm::vec3 extrapolatedPosition = _sentPosition + dt * (_sentVelocity + (0.5f * dt) * _sentAcceleration); + _sentVelocity += _sentAcceleration * dt; + _sentVelocity *= powf(1.0f - _linearDamping, dt); + _sentPosition += dt * _sentVelocity; btTransform worldTrans = _body->getWorldTransform(); glm::vec3 position = bulletToGLM(worldTrans.getOrigin()); - float dx2 = glm::distance2(position, extrapolatedPosition); + float dx2 = glm::distance2(position, _sentPosition); const float MAX_POSITION_ERROR_SQUARED = 0.001f; // 0.001 m^2 ~~> 0.03 m if (dx2 > MAX_POSITION_ERROR_SQUARED) { return true; } // compute rotation error + _sentAngularVelocity *= powf(1.0f - _angularDamping, dt); + float spin = glm::length(_sentAngularVelocity); - glm::quat extrapolatedRotation = _sentRotation; const float MIN_SPIN = 1.0e-4f; if (spin > MIN_SPIN) { glm::vec3 axis = _sentAngularVelocity / spin; - extrapolatedRotation = glm::angleAxis(dt * spin, axis) * _sentRotation; + _sentRotation = glm::normalize(glm::angleAxis(dt * spin, axis) * _sentRotation); } const float MIN_ROTATION_DOT = 0.98f; glm::quat actualRotation = bulletToGLM(worldTrans.getRotation()); - return (glm::dot(actualRotation, extrapolatedRotation) < MIN_ROTATION_DOT); + return (glm::dot(actualRotation, _sentRotation) < MIN_ROTATION_DOT); } #endif // USE_BULLET_PHYSICS diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 24a00609cf..c0d3d2cabf 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -84,7 +84,7 @@ public: void clearOutgoingPacketFlags(uint32_t flags) { _outgoingPacketFlags &= ~flags; } bool doesNotNeedToSendUpdate() const; - virtual bool shouldSendUpdate(uint32_t simulationFrame, float subStepRemainder) const; + virtual bool shouldSendUpdate(uint32_t simulationFrame, float subStepRemainder); virtual void sendUpdate(OctreeEditPacketSender* packetSender, uint32_t frame) = 0; virtual MotionType computeMotionType() const = 0; From 75a8faec860ca1c04fe8d8491d0fb977eb437941 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Jan 2015 15:02:18 -0800 Subject: [PATCH 2/7] purge support for voxels from PhysicsEngine --- libraries/physics/src/PhysicsEngine.cpp | 57 ----------------------- libraries/physics/src/PhysicsEngine.h | 13 ------ libraries/physics/src/PositionHashKey.cpp | 37 --------------- libraries/physics/src/PositionHashKey.h | 26 ----------- libraries/physics/src/VoxelObject.h | 31 ------------ 5 files changed, 164 deletions(-) delete mode 100644 libraries/physics/src/PositionHashKey.cpp delete mode 100644 libraries/physics/src/PositionHashKey.h delete mode 100644 libraries/physics/src/VoxelObject.h diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index f6700455a6..edff3f8291 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -24,7 +24,6 @@ PhysicsEngine::PhysicsEngine(const glm::vec3& offset) _constraintSolver(NULL), _dynamicsWorld(NULL), _originOffset(offset), - _voxels(), _entityPacketSender(NULL), _frameCount(0) { } @@ -221,62 +220,6 @@ void PhysicsEngine::stepSimulation() { _frameCount += (uint32_t)numSubSteps; } -bool PhysicsEngine::addVoxel(const glm::vec3& position, float scale) { - glm::vec3 halfExtents = glm::vec3(0.5f * scale); - glm::vec3 trueCenter = position + halfExtents; - PositionHashKey key(trueCenter); - VoxelObject* proxy = _voxels.find(key); - if (!proxy) { - // create a shape - ShapeInfo info; - info.setBox(halfExtents); - btCollisionShape* shape = _shapeManager.getShape(info); - - // NOTE: the shape creation will fail when the size of the voxel is out of range - if (shape) { - // create a collisionObject - btCollisionObject* object = new btCollisionObject(); - object->setCollisionShape(shape); - btTransform transform; - transform.setIdentity(); - // we shift the center into the simulation's frame - glm::vec3 shiftedCenter = (position - _originOffset) + halfExtents; - transform.setOrigin(btVector3(shiftedCenter.x, shiftedCenter.y, shiftedCenter.z)); - object->setWorldTransform(transform); - - // add to map and world - _voxels.insert(key, VoxelObject(trueCenter, object)); - _dynamicsWorld->addCollisionObject(object); - return true; - } - } - return false; -} - -bool PhysicsEngine::removeVoxel(const glm::vec3& position, float scale) { - glm::vec3 halfExtents = glm::vec3(0.5f * scale); - glm::vec3 trueCenter = position + halfExtents; - PositionHashKey key(trueCenter); - VoxelObject* proxy = _voxels.find(key); - if (proxy) { - // remove from world - assert(proxy->_object); - _dynamicsWorld->removeCollisionObject(proxy->_object); - - // release shape - ShapeInfo info; - info.setBox(halfExtents); - bool released = _shapeManager.releaseShape(info); - assert(released); - - // delete object and remove from voxel map - delete proxy->_object; - _voxels.remove(key); - return true; - } - return false; -} - // Bullet collision flags are as follows: // CF_STATIC_OBJECT= 1, // CF_KINEMATIC_OBJECT= 2, diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 5d506fced6..e93495e1d2 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -24,10 +24,8 @@ typedef unsigned int uint32_t; #include "BulletUtil.h" #include "EntityMotionState.h" -#include "PositionHashKey.h" #include "ShapeManager.h" #include "ThreadSafeDynamicsWorld.h" -#include "VoxelObject.h" const float HALF_SIMULATION_EXTENT = 512.0f; // meters @@ -56,16 +54,6 @@ public: /// \return position of simulation origin in domain-frame const glm::vec3& getOriginOffset() const { return _originOffset; } - /// \param position the minimum corner of the voxel - /// \param scale the length of the voxel side - /// \return true if Voxel added - bool addVoxel(const glm::vec3& position, float scale); - - /// \param position the minimum corner of the voxel - /// \param scale the length of the voxel side - /// \return true if Voxel removed - bool removeVoxel(const glm::vec3& position, float scale); - /// \param motionState pointer to Object's MotionState /// \return true if Object added bool addObject(ObjectMotionState* motionState); @@ -103,7 +91,6 @@ protected: private: glm::vec3 _originOffset; - btHashMap _voxels; // EntitySimulation stuff QSet _entityMotionStates; // all entities that we track diff --git a/libraries/physics/src/PositionHashKey.cpp b/libraries/physics/src/PositionHashKey.cpp deleted file mode 100644 index 91f8261fba..0000000000 --- a/libraries/physics/src/PositionHashKey.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// -// PositionHashKey.cpp -// libraries/physcis/src -// -// Created by Andrew Meadows 2014.11.05 -// 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 "PositionHashKey.h" - -// static -int computeHash(const glm::vec3& center) { - // NOTE: 0.49f is used to bump the float up almost half a millimeter - // so the cast to int produces a round() effect rather than a floor() - int hash = DoubleHashKey::hashFunction((int)(center.x * MILLIMETERS_PER_METER + copysignf(1.0f, center.x) * 0.49f), 0); - hash ^= DoubleHashKey::hashFunction((int)(center.y * MILLIMETERS_PER_METER + copysignf(1.0f, center.y) * 0.49f), 1); - return hash ^ DoubleHashKey::hashFunction((int)(center.z * MILLIMETERS_PER_METER + copysignf(1.0f, center.z) * 0.49f), 2); -} - -// static -int computeHash2(const glm::vec3& center) { - // NOTE: 0.49f is used to bump the float up almost half a millimeter - // so the cast to int produces a round() effect rather than a floor() - int hash = DoubleHashKey::hashFunction2((int)(center.x * MILLIMETERS_PER_METER + copysignf(1.0f, center.x) * 0.49f)); - hash ^= DoubleHashKey::hashFunction2((int)(center.y * MILLIMETERS_PER_METER + copysignf(1.0f, center.y) * 0.49f)); - return hash ^ DoubleHashKey::hashFunction2((int)(center.z * MILLIMETERS_PER_METER + copysignf(1.0f, center.z) * 0.49f)); -} - -PositionHashKey::PositionHashKey(glm::vec3 center) : DoubleHashKey() { - _hash = computeHash(center); - _hash2 = computeHash2(center); -} diff --git a/libraries/physics/src/PositionHashKey.h b/libraries/physics/src/PositionHashKey.h deleted file mode 100644 index 1065034fa8..0000000000 --- a/libraries/physics/src/PositionHashKey.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// PositionHashKey.h -// libraries/physcis/src -// -// Created by Andrew Meadows 2014.11.05 -// 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_PositionHashKey_h -#define hifi_PositionHashKey_h - -#include - -#include - -#include "DoubleHashKey.h" - -class PositionHashKey : public DoubleHashKey { -public: - PositionHashKey(glm::vec3 center); -}; - -#endif // hifi_PositionHashKey_h diff --git a/libraries/physics/src/VoxelObject.h b/libraries/physics/src/VoxelObject.h deleted file mode 100644 index 1372f761c7..0000000000 --- a/libraries/physics/src/VoxelObject.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// VoxelObject.h -// libraries/physcis/src -// -// Created by Andrew Meadows 2014.11.05 -// 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_VoxelObject_h -#define hifi_VoxelObject_h - -#ifdef USE_BULLET_PHYSICS - -#include -#include - -// VoxelObject is a simple wrapper for tracking a Voxel in a PhysicsEngine -class VoxelObject { -public: - VoxelObject(const glm::vec3& center, btCollisionObject* object) : _object(object), _center(center) { - assert(object != NULL); - } - btCollisionObject* _object; - glm::vec3 _center; -}; - -#endif // USE_BULLET_PHYSICS -#endif // hifi_VoxelObject_h From e2884c56f525682ed88f90b94fe6d0d15fd8305b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Jan 2015 15:16:03 -0800 Subject: [PATCH 3/7] only predict remote transform for moving objects --- libraries/physics/src/ObjectMotionState.cpp | 26 ++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 67763a98a9..c6563a2d63 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -157,9 +157,11 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame, float subStep // TODO: Andrew to reconcile Bullet and legacy damping coefficients. // compute position error - _sentVelocity += _sentAcceleration * dt; - _sentVelocity *= powf(1.0f - _linearDamping, dt); - _sentPosition += dt * _sentVelocity; + if (glm::length2(_sentVelocity) > 0.0f) { + _sentVelocity += _sentAcceleration * dt; + _sentVelocity *= powf(1.0f - _linearDamping, dt); + _sentPosition += dt * _sentVelocity; + } btTransform worldTrans = _body->getWorldTransform(); glm::vec3 position = bulletToGLM(worldTrans.getOrigin()); @@ -170,14 +172,16 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame, float subStep return true; } - // compute rotation error - _sentAngularVelocity *= powf(1.0f - _angularDamping, dt); - - float spin = glm::length(_sentAngularVelocity); - const float MIN_SPIN = 1.0e-4f; - if (spin > MIN_SPIN) { - glm::vec3 axis = _sentAngularVelocity / spin; - _sentRotation = glm::normalize(glm::angleAxis(dt * spin, axis) * _sentRotation); + if (glm::length2(_sentAngularVelocity) > 0.0f) { + // compute rotation error + _sentAngularVelocity *= powf(1.0f - _angularDamping, dt); + + float spin = glm::length(_sentAngularVelocity); + const float MIN_SPIN = 1.0e-4f; + if (spin > MIN_SPIN) { + glm::vec3 axis = _sentAngularVelocity / spin; + _sentRotation = glm::normalize(glm::angleAxis(dt * spin, axis) * _sentRotation); + } } const float MIN_ROTATION_DOT = 0.98f; glm::quat actualRotation = bulletToGLM(worldTrans.getRotation()); From cf235705da79ab7a5897f2f1390d01f7869beff1 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Jan 2015 15:29:02 -0800 Subject: [PATCH 4/7] mention Bullet in BUILD.md dependencies --- BUILD.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD.md b/BUILD.md index 6613786903..d068d6d458 100644 --- a/BUILD.md +++ b/BUILD.md @@ -6,6 +6,7 @@ * [OpenSSL](https://www.openssl.org/related/binaries.html) ~> 1.0.1g * IMPORTANT: OpenSSL 1.0.1g is critical to avoid a security vulnerability. * [Intel Threading Building Blocks](https://www.threadingbuildingblocks.org/) ~> 4.3 +* [Bullet Physics Engine](http://bulletphysics.org) ~> 2.82 ### OS Specific Build Guides * [BUILD_OSX.md](BUILD_OSX.md) - additional instructions for OS X. From ec86f0bd508d191859de543264aa1a50f19447fa Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Jan 2015 17:30:50 -0800 Subject: [PATCH 5/7] fixing toyball.js to work under Bullet --- examples/toyball.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/toyball.js b/examples/toyball.js index 9b91d1f098..2cda1fa82a 100644 --- a/examples/toyball.js +++ b/examples/toyball.js @@ -29,7 +29,7 @@ var RIGHT_BUTTON_FWD = 11; var RIGHT_BUTTON_3 = 9; var BALL_RADIUS = 0.08; -var GRAVITY_STRENGTH = 0.5; +var GRAVITY_STRENGTH = 1.0; var HELD_COLOR = { red: 240, green: 0, blue: 0 }; var THROWN_COLOR = { red: 128, green: 0, blue: 0 }; @@ -136,7 +136,7 @@ function checkControllerSide(whichSide) { velocity: { x: 0, y: 0, z: 0}, gravity: { x: 0, y: 0, z: 0}, inHand: true, - radius: { x: BALL_RADIUS * 2, y: BALL_RADIUS * 2, z: BALL_RADIUS * 2 }, + dimensions: { x: BALL_RADIUS * 2, y: BALL_RADIUS * 2, z: BALL_RADIUS * 2 }, damping: 0.00001, color: HELD_COLOR, @@ -185,6 +185,7 @@ function checkControllerSide(whichSide) { velocity: { x: tipVelocity.x * THROWN_VELOCITY_SCALING, y: tipVelocity.y * THROWN_VELOCITY_SCALING, z: tipVelocity.z * THROWN_VELOCITY_SCALING } , + collisionsWillMove: true, inHand: false, color: THROWN_COLOR, lifetime: 10, From 0a8437a578ea7ebbabc0e82fdab70dcac342c852 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Jan 2015 17:31:23 -0800 Subject: [PATCH 6/7] increasing default restitution to 0.5 --- libraries/physics/src/ObjectMotionState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index c6563a2d63..f8f0712d5e 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -27,7 +27,7 @@ const float MAX_VOLUME = 1000000.0f; const float DEFAULT_FRICTION = 0.5f; const float MAX_FRICTION = 10.0f; -const float DEFAULT_RESTITUTION = 0.0f; +const float DEFAULT_RESTITUTION = 0.5f; // origin of physics simulation in world frame glm::vec3 _worldOffset(0.0f); From 278be3d31b6c0a3772510f61510653c5bc6621ff Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Jan 2015 18:13:50 -0800 Subject: [PATCH 7/7] remove use of "radius" property for entities use "dimensions" instead --- examples/twoFallingEntities.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/twoFallingEntities.js b/examples/twoFallingEntities.js index b4a1f18bad..2d71344e2c 100644 --- a/examples/twoFallingEntities.js +++ b/examples/twoFallingEntities.js @@ -4,21 +4,21 @@ // Creates a red 0.2 meter diameter ball right in front of your avatar that lives for 60 seconds // -var radius = 0.1; +var diameter = 0.2; var position = Vec3.sum(MyAvatar.position, Quat.getFront(MyAvatar.orientation)); var properties = { type: "Sphere", position: position, velocity: { x: 0, y: 0, z: 0}, gravity: { x: 0, y: -0.05, z: 0}, - radius: radius, + dimensions: { x: diameter, y: diameter, z: diameter }; damping: 0.00001, color: { red: 200, green: 0, blue: 0 }, lifetime: 60 }; var newEntity = Entities.addEntity(properties); -position.x -= radius * 1.0; +position.x -= 0.5 * diameter; properties.position = position; var newEntityTwo = Entities.addEntity(properties);