3
0
Fork 0
mirror of https://github.com/lubosz/overte.git synced 2025-04-26 22:15:53 +02:00

change meaning of damping to agree with bullet

0 = no damping
1 = 100% damping

The new formula is: velocity *= (1 - damping)^dt
This commit is contained in:
Andrew Meadows 2015-01-05 11:23:01 -08:00
parent d032eab0de
commit 3b7770f405
3 changed files with 48 additions and 23 deletions
libraries

View file

@ -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;

View file

@ -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

View file

@ -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();