mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 05:37:22 +02:00
Merge pull request #4089 from AndrewMeadows/inertia
fix glitchy entity motion in Bullet simulation
This commit is contained in:
commit
284ee32b7b
10 changed files with 179 additions and 138 deletions
|
@ -35,25 +35,25 @@ void EntityItem::initFromEntityItemID(const EntityItemID& entityItemID) {
|
||||||
_created = UNKNOWN_CREATED_TIME;
|
_created = UNKNOWN_CREATED_TIME;
|
||||||
_changedOnServer = 0;
|
_changedOnServer = 0;
|
||||||
|
|
||||||
_position = glm::vec3(0,0,0);
|
_position = ENTITY_ITEM_ZERO_VEC3;
|
||||||
_dimensions = DEFAULT_DIMENSIONS;
|
_dimensions = ENTITY_ITEM_DEFAULT_DIMENSIONS;
|
||||||
_rotation = DEFAULT_ROTATION;
|
_rotation = ENTITY_ITEM_DEFAULT_ROTATION;
|
||||||
_glowLevel = DEFAULT_GLOW_LEVEL;
|
_glowLevel = ENTITY_ITEM_DEFAULT_GLOW_LEVEL;
|
||||||
_localRenderAlpha = DEFAULT_LOCAL_RENDER_ALPHA;
|
_localRenderAlpha = ENTITY_ITEM_DEFAULT_LOCAL_RENDER_ALPHA;
|
||||||
_mass = DEFAULT_MASS;
|
_mass = ENTITY_ITEM_DEFAULT_MASS;
|
||||||
_velocity = DEFAULT_VELOCITY;
|
_velocity = ENTITY_ITEM_DEFAULT_VELOCITY;
|
||||||
_gravity = DEFAULT_GRAVITY;
|
_gravity = ENTITY_ITEM_DEFAULT_GRAVITY;
|
||||||
_damping = DEFAULT_DAMPING;
|
_damping = ENTITY_ITEM_DEFAULT_DAMPING;
|
||||||
_lifetime = DEFAULT_LIFETIME;
|
_lifetime = ENTITY_ITEM_DEFAULT_LIFETIME;
|
||||||
_script = DEFAULT_SCRIPT;
|
_script = ENTITY_ITEM_DEFAULT_SCRIPT;
|
||||||
_registrationPoint = DEFAULT_REGISTRATION_POINT;
|
_registrationPoint = ENTITY_ITEM_DEFAULT_REGISTRATION_POINT;
|
||||||
_angularVelocity = DEFAULT_ANGULAR_VELOCITY;
|
_angularVelocity = ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY;
|
||||||
_angularDamping = DEFAULT_ANGULAR_DAMPING;
|
_angularDamping = ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING;
|
||||||
_visible = DEFAULT_VISIBLE;
|
_visible = ENTITY_ITEM_DEFAULT_VISIBLE;
|
||||||
_ignoreForCollisions = DEFAULT_IGNORE_FOR_COLLISIONS;
|
_ignoreForCollisions = ENTITY_ITEM_DEFAULT_IGNORE_FOR_COLLISIONS;
|
||||||
_collisionsWillMove = DEFAULT_COLLISIONS_WILL_MOVE;
|
_collisionsWillMove = ENTITY_ITEM_DEFAULT_COLLISIONS_WILL_MOVE;
|
||||||
_locked = DEFAULT_LOCKED;
|
_locked = ENTITY_ITEM_DEFAULT_LOCKED;
|
||||||
_userData = DEFAULT_USER_DATA;
|
_userData = ENTITY_ITEM_DEFAULT_USER_DATA;
|
||||||
|
|
||||||
recalculateCollisionShape();
|
recalculateCollisionShape();
|
||||||
}
|
}
|
||||||
|
@ -555,6 +555,8 @@ void EntityItem::adjustEditPacketForClockSkew(unsigned char* editPacketBuffer, s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float ENTITY_ITEM_EPSILON_VELOCITY_LENGTH = 0.001f / (float)TREE_SCALE;
|
||||||
|
|
||||||
// TODO: we probably want to change this to make "down" be the direction of the entity's gravity vector
|
// TODO: we probably want to change this to make "down" be the direction of the entity's gravity vector
|
||||||
// for now, this is always true DOWN even if entity has non-down gravity.
|
// for now, this is always true DOWN even if entity has non-down gravity.
|
||||||
// TODO: the old code had "&& _velocity.y >= -EPSILON && _velocity.y <= EPSILON" --- what was I thinking?
|
// TODO: the old code had "&& _velocity.y >= -EPSILON && _velocity.y <= EPSILON" --- what was I thinking?
|
||||||
|
@ -562,7 +564,7 @@ bool EntityItem::isRestingOnSurface() const {
|
||||||
glm::vec3 downwardVelocity = glm::vec3(0.0f, _velocity.y, 0.0f);
|
glm::vec3 downwardVelocity = glm::vec3(0.0f, _velocity.y, 0.0f);
|
||||||
|
|
||||||
return _position.y <= getDistanceToBottomOfEntity()
|
return _position.y <= getDistanceToBottomOfEntity()
|
||||||
&& (glm::length(downwardVelocity) <= EPSILON_VELOCITY_LENGTH)
|
&& (glm::length(downwardVelocity) <= ENTITY_ITEM_EPSILON_VELOCITY_LENGTH)
|
||||||
&& _gravity.y < 0.0f;
|
&& _gravity.y < 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -639,7 +641,7 @@ void EntityItem::simulate(const quint64& now) {
|
||||||
|
|
||||||
const float EPSILON_ANGULAR_VELOCITY_LENGTH = 0.1f; //
|
const float EPSILON_ANGULAR_VELOCITY_LENGTH = 0.1f; //
|
||||||
if (angularSpeed < EPSILON_ANGULAR_VELOCITY_LENGTH) {
|
if (angularSpeed < EPSILON_ANGULAR_VELOCITY_LENGTH) {
|
||||||
setAngularVelocity(NO_ANGULAR_VELOCITY);
|
setAngularVelocity(ENTITY_ITEM_ZERO_VEC3);
|
||||||
} else {
|
} else {
|
||||||
// NOTE: angularSpeed is currently in degrees/sec!!!
|
// NOTE: angularSpeed is currently in degrees/sec!!!
|
||||||
// TODO: Andrew to convert to radians/sec
|
// TODO: Andrew to convert to radians/sec
|
||||||
|
@ -668,7 +670,7 @@ void EntityItem::simulate(const quint64& now) {
|
||||||
qDebug() << " damping:" << _damping;
|
qDebug() << " damping:" << _damping;
|
||||||
qDebug() << " velocity AFTER dampingResistance:" << velocity;
|
qDebug() << " velocity AFTER dampingResistance:" << velocity;
|
||||||
qDebug() << " glm::length(velocity):" << glm::length(velocity);
|
qDebug() << " glm::length(velocity):" << glm::length(velocity);
|
||||||
qDebug() << " EPSILON_VELOCITY_LENGTH:" << EPSILON_VELOCITY_LENGTH;
|
qDebug() << " velocityEspilon :" << ENTITY_ITEM_EPSILON_VELOCITY_LENGTH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,8 +698,8 @@ void EntityItem::simulate(const quint64& now) {
|
||||||
|
|
||||||
#ifndef USE_BULLET_PHYSICS
|
#ifndef USE_BULLET_PHYSICS
|
||||||
// if we've slowed considerably, then just stop moving, but only if no BULLET
|
// if we've slowed considerably, then just stop moving, but only if no BULLET
|
||||||
if (glm::length(velocity) <= EPSILON_VELOCITY_LENGTH) {
|
if (glm::length(velocity) <= ENTITY_ITEM_EPSILON_VELOCITY_LENGTH) {
|
||||||
velocity = NO_VELOCITY;
|
velocity = ENTITY_ITEM_ZERO_VEC3;
|
||||||
}
|
}
|
||||||
#endif // !USE_BULLET_PHYSICS
|
#endif // !USE_BULLET_PHYSICS
|
||||||
|
|
||||||
|
@ -720,8 +722,8 @@ void EntityItem::simulate(const quint64& now) {
|
||||||
// When Bullet is available we assume that it will tell us when velocities go to zero...
|
// When Bullet is available we assume that it will tell us when velocities go to zero...
|
||||||
#else // !USE_BULLET_PHYSICS
|
#else // !USE_BULLET_PHYSICS
|
||||||
// ... otherwise we help things come to rest by clamping small velocities.
|
// ... otherwise we help things come to rest by clamping small velocities.
|
||||||
if (glm::length(velocity) <= EPSILON_VELOCITY_LENGTH) {
|
if (glm::length(velocity) <= ENTITY_ITEM_EPSILON_VELOCITY_LENGTH) {
|
||||||
velocity = NO_VELOCITY;
|
velocity = ENTITY_ITEM_ZERO_VEC3;
|
||||||
}
|
}
|
||||||
#endif // USE_BULLET_PHYSICS
|
#endif // USE_BULLET_PHYSICS
|
||||||
|
|
||||||
|
@ -909,7 +911,7 @@ AACube EntityItem::getMinimumAACube() const {
|
||||||
// _position represents the position of the registration point.
|
// _position represents the position of the registration point.
|
||||||
glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint;
|
glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint;
|
||||||
|
|
||||||
glm::vec3 unrotatedMinRelativeToEntity = glm::vec3(0.0f, 0.0f, 0.0f) - (_dimensions * _registrationPoint);
|
glm::vec3 unrotatedMinRelativeToEntity = - (_dimensions * _registrationPoint);
|
||||||
glm::vec3 unrotatedMaxRelativeToEntity = _dimensions * registrationRemainder;
|
glm::vec3 unrotatedMaxRelativeToEntity = _dimensions * registrationRemainder;
|
||||||
Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
|
Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
|
||||||
Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation());
|
Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation());
|
||||||
|
@ -934,7 +936,7 @@ AABox EntityItem::getAABox() const {
|
||||||
// _position represents the position of the registration point.
|
// _position represents the position of the registration point.
|
||||||
glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint;
|
glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint;
|
||||||
|
|
||||||
glm::vec3 unrotatedMinRelativeToEntity = glm::vec3(0.0f, 0.0f, 0.0f) - (_dimensions * _registrationPoint);
|
glm::vec3 unrotatedMinRelativeToEntity = - (_dimensions * _registrationPoint);
|
||||||
glm::vec3 unrotatedMaxRelativeToEntity = _dimensions * registrationRemainder;
|
glm::vec3 unrotatedMaxRelativeToEntity = _dimensions * registrationRemainder;
|
||||||
Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
|
Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
|
||||||
Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation());
|
Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation());
|
||||||
|
@ -998,7 +1000,7 @@ void EntityItem::recalculateCollisionShape() {
|
||||||
const float MIN_POSITION_DELTA = 0.0001f;
|
const float MIN_POSITION_DELTA = 0.0001f;
|
||||||
const float MIN_ALIGNMENT_DOT = 0.9999f;
|
const float MIN_ALIGNMENT_DOT = 0.9999f;
|
||||||
const float MIN_MASS_DELTA = 0.001f;
|
const float MIN_MASS_DELTA = 0.001f;
|
||||||
const float MIN_VELOCITY_DELTA = 0.025f;
|
const float MIN_VELOCITY_DELTA = 0.01f;
|
||||||
const float MIN_DAMPING_DELTA = 0.001f;
|
const float MIN_DAMPING_DELTA = 0.001f;
|
||||||
const float MIN_GRAVITY_DELTA = 0.001f;
|
const float MIN_GRAVITY_DELTA = 0.001f;
|
||||||
const float MIN_SPIN_DELTA = 0.0003f;
|
const float MIN_SPIN_DELTA = 0.0003f;
|
||||||
|
@ -1055,7 +1057,7 @@ void EntityItem::updateMass(float value) {
|
||||||
void EntityItem::updateVelocity(const glm::vec3& value) {
|
void EntityItem::updateVelocity(const glm::vec3& value) {
|
||||||
if (glm::distance(_velocity, value) * (float)TREE_SCALE > MIN_VELOCITY_DELTA) {
|
if (glm::distance(_velocity, value) * (float)TREE_SCALE > MIN_VELOCITY_DELTA) {
|
||||||
if (glm::length(value) * (float)TREE_SCALE < MIN_VELOCITY_DELTA) {
|
if (glm::length(value) * (float)TREE_SCALE < MIN_VELOCITY_DELTA) {
|
||||||
_velocity = glm::vec3(0.0f);
|
_velocity = ENTITY_ITEM_ZERO_VEC3;
|
||||||
} else {
|
} else {
|
||||||
_velocity = value;
|
_velocity = value;
|
||||||
}
|
}
|
||||||
|
@ -1067,7 +1069,7 @@ void EntityItem::updateVelocityInMeters(const glm::vec3& value) {
|
||||||
glm::vec3 velocity = value / (float) TREE_SCALE;
|
glm::vec3 velocity = value / (float) TREE_SCALE;
|
||||||
if (glm::distance(_velocity, velocity) * (float)TREE_SCALE > MIN_VELOCITY_DELTA) {
|
if (glm::distance(_velocity, velocity) * (float)TREE_SCALE > MIN_VELOCITY_DELTA) {
|
||||||
if (glm::length(value) < MIN_VELOCITY_DELTA) {
|
if (glm::length(value) < MIN_VELOCITY_DELTA) {
|
||||||
_velocity = glm::vec3(0.0f);
|
_velocity = ENTITY_ITEM_ZERO_VEC3;
|
||||||
} else {
|
} else {
|
||||||
_velocity = velocity;
|
_velocity = velocity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include "EntityItemID.h"
|
#include "EntityItemID.h"
|
||||||
#include "EntityItemProperties.h"
|
#include "EntityItemProperties.h"
|
||||||
|
#include "EntityItemPropertiesDefaults.h"
|
||||||
#include "EntityTypes.h"
|
#include "EntityTypes.h"
|
||||||
|
|
||||||
class EntityTree;
|
class EntityTree;
|
||||||
|
@ -35,30 +36,6 @@ class EntityTreeElementExtraEncodeData;
|
||||||
#define DONT_ALLOW_INSTANTIATION virtual void pureVirtualFunctionPlaceHolder() = 0;
|
#define DONT_ALLOW_INSTANTIATION virtual void pureVirtualFunctionPlaceHolder() = 0;
|
||||||
#define ALLOW_INSTANTIATION virtual void pureVirtualFunctionPlaceHolder() { };
|
#define ALLOW_INSTANTIATION virtual void pureVirtualFunctionPlaceHolder() { };
|
||||||
|
|
||||||
const glm::vec3 DEFAULT_DIMENSIONS = glm::vec3(0.1f) / (float)TREE_SCALE;
|
|
||||||
const glm::quat DEFAULT_ROTATION;
|
|
||||||
const float DEFAULT_GLOW_LEVEL = 0.0f;
|
|
||||||
const float DEFAULT_LOCAL_RENDER_ALPHA = 1.0f;
|
|
||||||
const float DEFAULT_MASS = 1.0f;
|
|
||||||
const glm::vec3 NO_VELOCITY= glm::vec3(0.0f);
|
|
||||||
const glm::vec3 DEFAULT_VELOCITY = NO_VELOCITY;
|
|
||||||
const float EPSILON_VELOCITY_LENGTH = 0.001f / (float)TREE_SCALE;
|
|
||||||
const glm::vec3 NO_GRAVITY = glm::vec3(0.0f);
|
|
||||||
const glm::vec3 DEFAULT_GRAVITY = NO_GRAVITY;
|
|
||||||
const glm::vec3 REGULAR_GRAVITY = glm::vec3(0, -9.8f / (float)TREE_SCALE, 0);
|
|
||||||
const float DEFAULT_DAMPING = 0.39347f; // approx timescale = 2.0 sec (see damping timescale formula in header)
|
|
||||||
const float IMMORTAL = -1.0f; /// special lifetime which means the entity lives for ever. default lifetime
|
|
||||||
const float DEFAULT_LIFETIME = IMMORTAL;
|
|
||||||
const QString DEFAULT_SCRIPT = QString("");
|
|
||||||
const glm::vec3 DEFAULT_REGISTRATION_POINT = glm::vec3(0.5f, 0.5f, 0.5f); // center
|
|
||||||
const glm::vec3 NO_ANGULAR_VELOCITY = glm::vec3(0.0f);
|
|
||||||
const glm::vec3 DEFAULT_ANGULAR_VELOCITY = NO_ANGULAR_VELOCITY;
|
|
||||||
const float DEFAULT_ANGULAR_DAMPING = 0.39347f; // approx timescale = 2.0 sec (see damping timescale formula in header)
|
|
||||||
const bool DEFAULT_VISIBLE = true;
|
|
||||||
const bool DEFAULT_IGNORE_FOR_COLLISIONS = false;
|
|
||||||
const bool DEFAULT_COLLISIONS_WILL_MOVE = false;
|
|
||||||
const bool DEFAULT_LOCKED = false;
|
|
||||||
const QString DEFAULT_USER_DATA = QString("");
|
|
||||||
|
|
||||||
/// EntityItem class this is the base class for all entity types. It handles the basic properties and functionality available
|
/// EntityItem class this is the base class for all entity types. It handles the basic properties and functionality available
|
||||||
/// to all other entity types. In particular: postion, size, rotation, age, lifetime, velocity, gravity. You can not instantiate
|
/// to all other entity types. In particular: postion, size, rotation, age, lifetime, velocity, gravity. You can not instantiate
|
||||||
|
@ -201,13 +178,13 @@ public:
|
||||||
glm::vec3 getVelocityInMeters() const { return _velocity * (float) TREE_SCALE; } /// get velocity in meters
|
glm::vec3 getVelocityInMeters() const { return _velocity * (float) TREE_SCALE; } /// get velocity in meters
|
||||||
void setVelocity(const glm::vec3& value) { _velocity = value; } /// velocity in domain scale units (0.0-1.0) per second
|
void setVelocity(const glm::vec3& value) { _velocity = value; } /// velocity in domain scale units (0.0-1.0) per second
|
||||||
void setVelocityInMeters(const glm::vec3& value) { _velocity = value / (float) TREE_SCALE; } /// velocity in meters
|
void setVelocityInMeters(const glm::vec3& value) { _velocity = value / (float) TREE_SCALE; } /// velocity in meters
|
||||||
bool hasVelocity() const { return _velocity != NO_VELOCITY; }
|
bool hasVelocity() const { return _velocity != ENTITY_ITEM_ZERO_VEC3; }
|
||||||
|
|
||||||
const glm::vec3& getGravity() const { return _gravity; } /// gravity in domain scale units (0.0-1.0) per second squared
|
const glm::vec3& getGravity() const { return _gravity; } /// gravity in domain scale units (0.0-1.0) per second squared
|
||||||
glm::vec3 getGravityInMeters() const { return _gravity * (float) TREE_SCALE; } /// get gravity in meters
|
glm::vec3 getGravityInMeters() const { return _gravity * (float) TREE_SCALE; } /// get gravity in meters
|
||||||
void setGravity(const glm::vec3& value) { _gravity = value; } /// gravity in domain scale units (0.0-1.0) per second squared
|
void setGravity(const glm::vec3& value) { _gravity = value; } /// gravity in domain scale units (0.0-1.0) per second squared
|
||||||
void setGravityInMeters(const glm::vec3& value) { _gravity = value / (float) TREE_SCALE; } /// gravity in meters
|
void setGravityInMeters(const glm::vec3& value) { _gravity = value / (float) TREE_SCALE; } /// gravity in meters
|
||||||
bool hasGravity() const { return _gravity != NO_GRAVITY; }
|
bool hasGravity() const { return _gravity != ENTITY_ITEM_ZERO_VEC3; }
|
||||||
|
|
||||||
// TODO: this should eventually be updated to support resting on collisions with other surfaces
|
// TODO: this should eventually be updated to support resting on collisions with other surfaces
|
||||||
bool isRestingOnSurface() const;
|
bool isRestingOnSurface() const;
|
||||||
|
@ -220,10 +197,10 @@ public:
|
||||||
void setLifetime(float value) { _lifetime = value; } /// set the lifetime in seconds for the entity
|
void setLifetime(float value) { _lifetime = value; } /// set the lifetime in seconds for the entity
|
||||||
|
|
||||||
/// is this entity immortal, in that it has no lifetime set, and will exist until manually deleted
|
/// is this entity immortal, in that it has no lifetime set, and will exist until manually deleted
|
||||||
bool isImmortal() const { return _lifetime == IMMORTAL; }
|
bool isImmortal() const { return _lifetime == ENTITY_ITEM_IMMORTAL_LIFETIME; }
|
||||||
|
|
||||||
/// is this entity mortal, in that it has a lifetime set, and will automatically be deleted when that lifetime expires
|
/// is this entity mortal, in that it has a lifetime set, and will automatically be deleted when that lifetime expires
|
||||||
bool isMortal() const { return _lifetime != IMMORTAL; }
|
bool isMortal() const { return _lifetime != ENTITY_ITEM_IMMORTAL_LIFETIME; }
|
||||||
|
|
||||||
/// age of this entity in seconds
|
/// age of this entity in seconds
|
||||||
float getAge() const { return (float)(usecTimestampNow() - _created) / (float)USECS_PER_SECOND; }
|
float getAge() const { return (float)(usecTimestampNow() - _created) / (float)USECS_PER_SECOND; }
|
||||||
|
@ -247,7 +224,7 @@ public:
|
||||||
|
|
||||||
const glm::vec3& getAngularVelocity() const { return _angularVelocity; }
|
const glm::vec3& getAngularVelocity() const { return _angularVelocity; }
|
||||||
void setAngularVelocity(const glm::vec3& value) { _angularVelocity = value; }
|
void setAngularVelocity(const glm::vec3& value) { _angularVelocity = value; }
|
||||||
bool hasAngularVelocity() const { return _angularVelocity != NO_ANGULAR_VELOCITY; }
|
bool hasAngularVelocity() const { return _angularVelocity != ENTITY_ITEM_ZERO_VEC3; }
|
||||||
|
|
||||||
float getAngularDamping() const { return _angularDamping; }
|
float getAngularDamping() const { return _angularDamping; }
|
||||||
void setAngularDamping(float value) { _angularDamping = value; }
|
void setAngularDamping(float value) { _angularDamping = value; }
|
||||||
|
|
|
@ -19,32 +19,34 @@
|
||||||
|
|
||||||
#include "EntityItem.h"
|
#include "EntityItem.h"
|
||||||
#include "EntityItemProperties.h"
|
#include "EntityItemProperties.h"
|
||||||
|
#include "EntityItemPropertiesDefaults.h"
|
||||||
#include "ModelEntityItem.h"
|
#include "ModelEntityItem.h"
|
||||||
#include "TextEntityItem.h"
|
#include "TextEntityItem.h"
|
||||||
|
|
||||||
|
|
||||||
EntityItemProperties::EntityItemProperties() :
|
EntityItemProperties::EntityItemProperties() :
|
||||||
|
|
||||||
CONSTRUCT_PROPERTY(visible, DEFAULT_VISIBLE),
|
CONSTRUCT_PROPERTY(visible, ENTITY_ITEM_DEFAULT_VISIBLE),
|
||||||
CONSTRUCT_PROPERTY(position, 0),
|
CONSTRUCT_PROPERTY(position, 0),
|
||||||
CONSTRUCT_PROPERTY(dimensions, DEFAULT_DIMENSIONS),
|
CONSTRUCT_PROPERTY(dimensions, ENTITY_ITEM_DEFAULT_DIMENSIONS),
|
||||||
CONSTRUCT_PROPERTY(rotation, DEFAULT_ROTATION),
|
CONSTRUCT_PROPERTY(rotation, ENTITY_ITEM_DEFAULT_ROTATION),
|
||||||
CONSTRUCT_PROPERTY(mass, DEFAULT_MASS),
|
CONSTRUCT_PROPERTY(mass, ENTITY_ITEM_DEFAULT_MASS),
|
||||||
CONSTRUCT_PROPERTY(velocity, DEFAULT_VELOCITY),
|
CONSTRUCT_PROPERTY(velocity, ENTITY_ITEM_DEFAULT_VELOCITY),
|
||||||
CONSTRUCT_PROPERTY(gravity, DEFAULT_GRAVITY),
|
CONSTRUCT_PROPERTY(gravity, ENTITY_ITEM_DEFAULT_GRAVITY),
|
||||||
CONSTRUCT_PROPERTY(damping, DEFAULT_DAMPING),
|
CONSTRUCT_PROPERTY(damping, ENTITY_ITEM_DEFAULT_DAMPING),
|
||||||
CONSTRUCT_PROPERTY(lifetime, DEFAULT_LIFETIME),
|
CONSTRUCT_PROPERTY(lifetime, ENTITY_ITEM_DEFAULT_LIFETIME),
|
||||||
CONSTRUCT_PROPERTY(script, DEFAULT_SCRIPT),
|
CONSTRUCT_PROPERTY(script, ENTITY_ITEM_DEFAULT_SCRIPT),
|
||||||
CONSTRUCT_PROPERTY(color, ),
|
CONSTRUCT_PROPERTY(color, ),
|
||||||
CONSTRUCT_PROPERTY(modelURL, ""),
|
CONSTRUCT_PROPERTY(modelURL, ""),
|
||||||
CONSTRUCT_PROPERTY(animationURL, ""),
|
CONSTRUCT_PROPERTY(animationURL, ""),
|
||||||
CONSTRUCT_PROPERTY(animationFPS, ModelEntityItem::DEFAULT_ANIMATION_FPS),
|
CONSTRUCT_PROPERTY(animationFPS, ModelEntityItem::DEFAULT_ANIMATION_FPS),
|
||||||
CONSTRUCT_PROPERTY(animationFrameIndex, ModelEntityItem::DEFAULT_ANIMATION_FRAME_INDEX),
|
CONSTRUCT_PROPERTY(animationFrameIndex, ModelEntityItem::DEFAULT_ANIMATION_FRAME_INDEX),
|
||||||
CONSTRUCT_PROPERTY(animationIsPlaying, ModelEntityItem::DEFAULT_ANIMATION_IS_PLAYING),
|
CONSTRUCT_PROPERTY(animationIsPlaying, ModelEntityItem::DEFAULT_ANIMATION_IS_PLAYING),
|
||||||
CONSTRUCT_PROPERTY(registrationPoint, DEFAULT_REGISTRATION_POINT),
|
CONSTRUCT_PROPERTY(registrationPoint, ENTITY_ITEM_DEFAULT_REGISTRATION_POINT),
|
||||||
CONSTRUCT_PROPERTY(angularVelocity, DEFAULT_ANGULAR_VELOCITY),
|
CONSTRUCT_PROPERTY(angularVelocity, ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY),
|
||||||
CONSTRUCT_PROPERTY(angularDamping, DEFAULT_ANGULAR_DAMPING),
|
CONSTRUCT_PROPERTY(angularDamping, ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING),
|
||||||
CONSTRUCT_PROPERTY(ignoreForCollisions, DEFAULT_IGNORE_FOR_COLLISIONS),
|
CONSTRUCT_PROPERTY(ignoreForCollisions, ENTITY_ITEM_DEFAULT_IGNORE_FOR_COLLISIONS),
|
||||||
CONSTRUCT_PROPERTY(collisionsWillMove, DEFAULT_COLLISIONS_WILL_MOVE),
|
CONSTRUCT_PROPERTY(collisionsWillMove, ENTITY_ITEM_DEFAULT_COLLISIONS_WILL_MOVE),
|
||||||
CONSTRUCT_PROPERTY(isSpotlight, false),
|
CONSTRUCT_PROPERTY(isSpotlight, false),
|
||||||
CONSTRUCT_PROPERTY(diffuseColor, ),
|
CONSTRUCT_PROPERTY(diffuseColor, ),
|
||||||
CONSTRUCT_PROPERTY(ambientColor, ),
|
CONSTRUCT_PROPERTY(ambientColor, ),
|
||||||
|
@ -54,10 +56,10 @@ EntityItemProperties::EntityItemProperties() :
|
||||||
CONSTRUCT_PROPERTY(quadraticAttenuation, 0.0f),
|
CONSTRUCT_PROPERTY(quadraticAttenuation, 0.0f),
|
||||||
CONSTRUCT_PROPERTY(exponent, 0.0f),
|
CONSTRUCT_PROPERTY(exponent, 0.0f),
|
||||||
CONSTRUCT_PROPERTY(cutoff, PI),
|
CONSTRUCT_PROPERTY(cutoff, PI),
|
||||||
CONSTRUCT_PROPERTY(locked, false),
|
CONSTRUCT_PROPERTY(locked, ENTITY_ITEM_DEFAULT_LOCKED),
|
||||||
CONSTRUCT_PROPERTY(textures, ""),
|
CONSTRUCT_PROPERTY(textures, ""),
|
||||||
CONSTRUCT_PROPERTY(animationSettings, ""),
|
CONSTRUCT_PROPERTY(animationSettings, ""),
|
||||||
CONSTRUCT_PROPERTY(userData, DEFAULT_USER_DATA),
|
CONSTRUCT_PROPERTY(userData, ENTITY_ITEM_DEFAULT_USER_DATA),
|
||||||
CONSTRUCT_PROPERTY(text, TextEntityItem::DEFAULT_TEXT),
|
CONSTRUCT_PROPERTY(text, TextEntityItem::DEFAULT_TEXT),
|
||||||
CONSTRUCT_PROPERTY(lineHeight, TextEntityItem::DEFAULT_LINE_HEIGHT),
|
CONSTRUCT_PROPERTY(lineHeight, TextEntityItem::DEFAULT_LINE_HEIGHT),
|
||||||
CONSTRUCT_PROPERTY(textColor, TextEntityItem::DEFAULT_TEXT_COLOR),
|
CONSTRUCT_PROPERTY(textColor, TextEntityItem::DEFAULT_TEXT_COLOR),
|
||||||
|
@ -858,7 +860,7 @@ AABox EntityItemProperties::getAABoxInMeters() const {
|
||||||
// _position represents the position of the registration point.
|
// _position represents the position of the registration point.
|
||||||
glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint;
|
glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint;
|
||||||
|
|
||||||
glm::vec3 unrotatedMinRelativeToEntity = glm::vec3(0.0f, 0.0f, 0.0f) - (_dimensions * _registrationPoint);
|
glm::vec3 unrotatedMinRelativeToEntity = - (_dimensions * _registrationPoint);
|
||||||
glm::vec3 unrotatedMaxRelativeToEntity = _dimensions * registrationRemainder;
|
glm::vec3 unrotatedMaxRelativeToEntity = _dimensions * registrationRemainder;
|
||||||
Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
|
Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
|
||||||
Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation());
|
Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation());
|
||||||
|
|
51
libraries/entities/src/EntityItemPropertiesDefaults.h
Normal file
51
libraries/entities/src/EntityItemPropertiesDefaults.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
//
|
||||||
|
// EntityItemPropertiesDefaults.h
|
||||||
|
// libraries/entities/src
|
||||||
|
//
|
||||||
|
// Created by Andrew Meadows on 2015.01.12
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_EntityItemPropertiesDefaults_h
|
||||||
|
#define hifi_EntityItemPropertiesDefaults_h
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
// There is a minor performance gain when comparing/copying an existing glm::vec3 rather than
|
||||||
|
// creating a new one on the stack so we declare the ZERO_VEC3 constant as an optimization.
|
||||||
|
const glm::vec3 ENTITY_ITEM_ZERO_VEC3(0.0f);
|
||||||
|
|
||||||
|
const glm::vec3 REGULAR_GRAVITY = glm::vec3(0, -9.8f / (float)TREE_SCALE, 0);
|
||||||
|
|
||||||
|
const bool ENTITY_ITEM_DEFAULT_LOCKED = false;
|
||||||
|
const QString ENTITY_ITEM_DEFAULT_USER_DATA = QString("");
|
||||||
|
|
||||||
|
const float ENTITY_ITEM_DEFAULT_LOCAL_RENDER_ALPHA = 1.0f;
|
||||||
|
const float ENTITY_ITEM_DEFAULT_GLOW_LEVEL = 0.0f;
|
||||||
|
const bool ENTITY_ITEM_DEFAULT_VISIBLE = true;
|
||||||
|
|
||||||
|
const QString ENTITY_ITEM_DEFAULT_SCRIPT = QString("");
|
||||||
|
const glm::vec3 ENTITY_ITEM_DEFAULT_REGISTRATION_POINT = glm::vec3(0.5f, 0.5f, 0.5f); // center
|
||||||
|
|
||||||
|
const float ENTITY_ITEM_IMMORTAL_LIFETIME = -1.0f; /// special lifetime which means the entity lives for ever
|
||||||
|
const float ENTITY_ITEM_DEFAULT_LIFETIME = ENTITY_ITEM_IMMORTAL_LIFETIME;
|
||||||
|
|
||||||
|
const glm::quat ENTITY_ITEM_DEFAULT_ROTATION;
|
||||||
|
const glm::vec3 ENTITY_ITEM_DEFAULT_DIMENSIONS = glm::vec3(0.1f) / (float)TREE_SCALE;
|
||||||
|
const float ENTITY_ITEM_DEFAULT_MASS = 1.0f;
|
||||||
|
|
||||||
|
const glm::vec3 ENTITY_ITEM_DEFAULT_VELOCITY = ENTITY_ITEM_ZERO_VEC3;
|
||||||
|
const glm::vec3 ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY = ENTITY_ITEM_ZERO_VEC3;
|
||||||
|
const glm::vec3 ENTITY_ITEM_DEFAULT_GRAVITY = ENTITY_ITEM_ZERO_VEC3;
|
||||||
|
const float ENTITY_ITEM_DEFAULT_DAMPING = 0.39347f; // approx timescale = 2.0 sec (see damping timescale formula in header)
|
||||||
|
const float ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING = 0.39347f; // approx timescale = 2.0 sec (see damping timescale formula in header)
|
||||||
|
|
||||||
|
const bool ENTITY_ITEM_DEFAULT_IGNORE_FOR_COLLISIONS = false;
|
||||||
|
const bool ENTITY_ITEM_DEFAULT_COLLISIONS_WILL_MOVE = false;
|
||||||
|
|
||||||
|
#endif // hifi_EntityItemPropertiesDefaults_h
|
|
@ -79,21 +79,59 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) {
|
||||||
}
|
}
|
||||||
#endif // USE_BULLET_PHYSICS
|
#endif // USE_BULLET_PHYSICS
|
||||||
|
|
||||||
void EntityMotionState::applyVelocities() const {
|
void EntityMotionState::updateObjectEasy(uint32_t flags, uint32_t frame) {
|
||||||
#ifdef USE_BULLET_PHYSICS
|
#ifdef USE_BULLET_PHYSICS
|
||||||
if (_body) {
|
if (flags & (EntityItem::DIRTY_POSITION | EntityItem::DIRTY_VELOCITY)) {
|
||||||
setVelocity(_entity->getVelocityInMeters());
|
if (flags & EntityItem::DIRTY_POSITION) {
|
||||||
// DANGER! EntityItem stores angularVelocity in degrees/sec!!!
|
_sentPosition = _entity->getPositionInMeters() - ObjectMotionState::getWorldOffset();
|
||||||
setAngularVelocity(glm::radians(_entity->getAngularVelocity()));
|
btTransform worldTrans;
|
||||||
_body->setActivationState(ACTIVE_TAG);
|
worldTrans.setOrigin(glmToBullet(_sentPosition));
|
||||||
}
|
|
||||||
#endif // USE_BULLET_PHYSICS
|
|
||||||
}
|
|
||||||
|
|
||||||
void EntityMotionState::applyGravity() const {
|
_sentRotation = _entity->getRotation();
|
||||||
|
worldTrans.setRotation(glmToBullet(_sentRotation));
|
||||||
|
|
||||||
|
_body->setWorldTransform(worldTrans);
|
||||||
|
}
|
||||||
|
if (flags & EntityItem::DIRTY_VELOCITY) {
|
||||||
|
updateObjectVelocities();
|
||||||
|
}
|
||||||
|
_sentFrame = frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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_MASS) {
|
||||||
|
float mass = getMass();
|
||||||
|
btVector3 inertia(0.0f, 0.0f, 0.0f);
|
||||||
|
_body->getCollisionShape()->calculateLocalInertia(mass, inertia);
|
||||||
|
_body->setMassProps(mass, inertia);
|
||||||
|
_body->updateInertiaTensor();
|
||||||
|
}
|
||||||
|
_body->activate();
|
||||||
|
#endif // USE_BULLET_PHYSICS
|
||||||
|
};
|
||||||
|
|
||||||
|
void EntityMotionState::updateObjectVelocities() {
|
||||||
#ifdef USE_BULLET_PHYSICS
|
#ifdef USE_BULLET_PHYSICS
|
||||||
if (_body) {
|
if (_body) {
|
||||||
setGravity(_entity->getGravityInMeters());
|
_sentVelocity = _entity->getVelocityInMeters();
|
||||||
|
setVelocity(_sentVelocity);
|
||||||
|
|
||||||
|
// DANGER! EntityItem stores angularVelocity in degrees/sec!!!
|
||||||
|
_sentAngularVelocity = glm::radians(_entity->getAngularVelocity());
|
||||||
|
setAngularVelocity(_sentAngularVelocity);
|
||||||
|
|
||||||
|
_sentAcceleration = _entity->getGravityInMeters();
|
||||||
|
setGravity(_sentAcceleration);
|
||||||
|
|
||||||
_body->setActivationState(ACTIVE_TAG);
|
_body->setActivationState(ACTIVE_TAG);
|
||||||
}
|
}
|
||||||
#endif // USE_BULLET_PHYSICS
|
#endif // USE_BULLET_PHYSICS
|
||||||
|
@ -123,7 +161,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
||||||
_sentAngularVelocity = bulletToGLM(_body->getAngularVelocity());
|
_sentAngularVelocity = bulletToGLM(_body->getAngularVelocity());
|
||||||
|
|
||||||
// if the speeds are very small we zero them out
|
// if the speeds are very small we zero them out
|
||||||
const float MINIMUM_EXTRAPOLATION_SPEED_SQUARED = 4.0e-6f; // 2mm/sec
|
const float MINIMUM_EXTRAPOLATION_SPEED_SQUARED = 1.0e-4f; // 1cm/sec
|
||||||
bool zeroSpeed = (glm::length2(_sentVelocity) < MINIMUM_EXTRAPOLATION_SPEED_SQUARED);
|
bool zeroSpeed = (glm::length2(_sentVelocity) < MINIMUM_EXTRAPOLATION_SPEED_SQUARED);
|
||||||
if (zeroSpeed) {
|
if (zeroSpeed) {
|
||||||
_sentVelocity = glm::vec3(0.0f);
|
_sentVelocity = glm::vec3(0.0f);
|
||||||
|
|
|
@ -54,8 +54,8 @@ public:
|
||||||
#endif // USE_BULLET_PHYSICS
|
#endif // USE_BULLET_PHYSICS
|
||||||
|
|
||||||
// these relay incoming values to the RigidBody
|
// these relay incoming values to the RigidBody
|
||||||
void applyVelocities() const;
|
void updateObjectEasy(uint32_t flags, uint32_t frame);
|
||||||
void applyGravity() const;
|
void updateObjectVelocities();
|
||||||
|
|
||||||
void computeShapeInfo(ShapeInfo& info);
|
void computeShapeInfo(ShapeInfo& info);
|
||||||
|
|
||||||
|
|
|
@ -123,9 +123,9 @@ bool ObjectMotionState::doesNotNeedToSendUpdate() const {
|
||||||
|
|
||||||
const float FIXED_SUBSTEP = 1.0f / 60.0f;
|
const float FIXED_SUBSTEP = 1.0f / 60.0f;
|
||||||
|
|
||||||
bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame, float subStepRemainder) {
|
bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame) {
|
||||||
assert(_body);
|
assert(_body);
|
||||||
float dt = (float)(simulationFrame - _sentFrame) * FIXED_SUBSTEP + subStepRemainder;
|
float dt = (float)(simulationFrame - _sentFrame) * FIXED_SUBSTEP;
|
||||||
_sentFrame = simulationFrame;
|
_sentFrame = simulationFrame;
|
||||||
bool isActive = _body->isActive();
|
bool isActive = _body->isActive();
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame, float subStep
|
||||||
}
|
}
|
||||||
const float MIN_ROTATION_DOT = 0.98f;
|
const float MIN_ROTATION_DOT = 0.98f;
|
||||||
glm::quat actualRotation = bulletToGLM(worldTrans.getRotation());
|
glm::quat actualRotation = bulletToGLM(worldTrans.getRotation());
|
||||||
return (glm::dot(actualRotation, _sentRotation) < MIN_ROTATION_DOT);
|
return (fabsf(glm::dot(actualRotation, _sentRotation)) < MIN_ROTATION_DOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USE_BULLET_PHYSICS
|
#endif // USE_BULLET_PHYSICS
|
||||||
|
|
|
@ -56,8 +56,9 @@ public:
|
||||||
ObjectMotionState();
|
ObjectMotionState();
|
||||||
~ObjectMotionState();
|
~ObjectMotionState();
|
||||||
|
|
||||||
virtual void applyVelocities() const = 0;
|
// An EASY update does not require the object to be removed and then reinserted into the PhysicsEngine
|
||||||
virtual void applyGravity() const = 0;
|
virtual void updateObjectEasy(uint32_t flags, uint32_t frame) = 0;
|
||||||
|
virtual void updateObjectVelocities() = 0;
|
||||||
|
|
||||||
virtual void computeShapeInfo(ShapeInfo& info) = 0;
|
virtual void computeShapeInfo(ShapeInfo& info) = 0;
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ public:
|
||||||
void clearOutgoingPacketFlags(uint32_t flags) { _outgoingPacketFlags &= ~flags; }
|
void clearOutgoingPacketFlags(uint32_t flags) { _outgoingPacketFlags &= ~flags; }
|
||||||
|
|
||||||
bool doesNotNeedToSendUpdate() const;
|
bool doesNotNeedToSendUpdate() const;
|
||||||
virtual bool shouldSendUpdate(uint32_t simulationFrame, float subStepRemainder);
|
virtual bool shouldSendUpdate(uint32_t simulationFrame);
|
||||||
virtual void sendUpdate(OctreeEditPacketSender* packetSender, uint32_t frame) = 0;
|
virtual void sendUpdate(OctreeEditPacketSender* packetSender, uint32_t frame) = 0;
|
||||||
|
|
||||||
virtual MotionType computeMotionType() const = 0;
|
virtual MotionType computeMotionType() const = 0;
|
||||||
|
|
|
@ -41,14 +41,12 @@ void PhysicsEngine::updateEntitiesInternal(const quint64& now) {
|
||||||
|
|
||||||
// this is step (4)
|
// this is step (4)
|
||||||
QSet<ObjectMotionState*>::iterator stateItr = _outgoingPackets.begin();
|
QSet<ObjectMotionState*>::iterator stateItr = _outgoingPackets.begin();
|
||||||
uint32_t frame = getFrameCount();
|
|
||||||
float subStepRemainder = getSubStepRemainder();
|
|
||||||
while (stateItr != _outgoingPackets.end()) {
|
while (stateItr != _outgoingPackets.end()) {
|
||||||
ObjectMotionState* state = *stateItr;
|
ObjectMotionState* state = *stateItr;
|
||||||
if (state->doesNotNeedToSendUpdate()) {
|
if (state->doesNotNeedToSendUpdate()) {
|
||||||
stateItr = _outgoingPackets.erase(stateItr);
|
stateItr = _outgoingPackets.erase(stateItr);
|
||||||
} else if (state->shouldSendUpdate(frame, subStepRemainder)) {
|
} else if (state->shouldSendUpdate(_frameCount)) {
|
||||||
state->sendUpdate(_entityPacketSender, frame);
|
state->sendUpdate(_entityPacketSender, _frameCount);
|
||||||
++stateItr;
|
++stateItr;
|
||||||
} else {
|
} else {
|
||||||
++stateItr;
|
++stateItr;
|
||||||
|
@ -140,7 +138,8 @@ void PhysicsEngine::relayIncomingChangesToSimulation() {
|
||||||
updateObjectHard(body, motionState, flags);
|
updateObjectHard(body, motionState, flags);
|
||||||
} else if (flags) {
|
} else if (flags) {
|
||||||
// an EASY update does NOT require that the body be pulled out of physics engine
|
// an EASY update does NOT require that the body be pulled out of physics engine
|
||||||
updateObjectEasy(body, motionState, flags);
|
// hence the MotionState has all the knowledge and authority to perform the update.
|
||||||
|
motionState->updateObjectEasy(flags, _frameCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,8 +268,12 @@ bool PhysicsEngine::addObject(ObjectMotionState* motionState) {
|
||||||
body = new btRigidBody(mass, motionState, shape, inertia);
|
body = new btRigidBody(mass, motionState, shape, inertia);
|
||||||
body->updateInertiaTensor();
|
body->updateInertiaTensor();
|
||||||
motionState->_body = body;
|
motionState->_body = body;
|
||||||
motionState->applyVelocities();
|
motionState->updateObjectVelocities();
|
||||||
motionState->applyGravity();
|
// 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 LINEAR_VELOCITY_THRESHOLD = 0.05f; // 5 cm/sec
|
||||||
|
const float ANGULAR_VELOCITY_THRESHOLD = 0.087266f; // ~5 deg/sec
|
||||||
|
body->setSleepingThresholds(LINEAR_VELOCITY_THRESHOLD, ANGULAR_VELOCITY_THRESHOLD);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MOTION_TYPE_STATIC:
|
case MOTION_TYPE_STATIC:
|
||||||
|
@ -334,7 +337,7 @@ void PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio
|
||||||
}
|
}
|
||||||
bool easyUpdate = flags & EASY_DIRTY_PHYSICS_FLAGS;
|
bool easyUpdate = flags & EASY_DIRTY_PHYSICS_FLAGS;
|
||||||
if (easyUpdate) {
|
if (easyUpdate) {
|
||||||
updateObjectEasy(body, motionState, flags);
|
motionState->updateObjectEasy(flags, _frameCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the motion parameters
|
// update the motion parameters
|
||||||
|
@ -385,31 +388,4 @@ void PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio
|
||||||
body->activate();
|
body->activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// private
|
|
||||||
void PhysicsEngine::updateObjectEasy(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags) {
|
|
||||||
if (flags & EntityItem::DIRTY_POSITION) {
|
|
||||||
btTransform transform;
|
|
||||||
motionState->getWorldTransform(transform);
|
|
||||||
body->setWorldTransform(transform);
|
|
||||||
}
|
|
||||||
if (flags & EntityItem::DIRTY_VELOCITY) {
|
|
||||||
motionState->applyVelocities();
|
|
||||||
motionState->applyGravity();
|
|
||||||
}
|
|
||||||
body->setRestitution(motionState->_restitution);
|
|
||||||
body->setFriction(motionState->_friction);
|
|
||||||
body->setDamping(motionState->_linearDamping, motionState->_angularDamping);
|
|
||||||
|
|
||||||
if (flags & EntityItem::DIRTY_MASS) {
|
|
||||||
float mass = motionState->getMass();
|
|
||||||
btVector3 inertia(0.0f, 0.0f, 0.0f);
|
|
||||||
body->getCollisionShape()->calculateLocalInertia(mass, inertia);
|
|
||||||
body->setMassProps(mass, inertia);
|
|
||||||
body->updateInertiaTensor();
|
|
||||||
}
|
|
||||||
body->activate();
|
|
||||||
|
|
||||||
// TODO: support collision groups
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // USE_BULLET_PHYSICS
|
#endif // USE_BULLET_PHYSICS
|
||||||
|
|
|
@ -71,12 +71,6 @@ public:
|
||||||
/// \return number of simulation frames the physics engine has taken
|
/// \return number of simulation frames the physics engine has taken
|
||||||
uint32_t getFrameCount() const { return _frameCount; }
|
uint32_t getFrameCount() const { return _frameCount; }
|
||||||
|
|
||||||
/// \return substep remainder used for Bullet MotionState extrapolation
|
|
||||||
// Bullet will extrapolate the positions provided to MotionState::setWorldTransform() in an effort to provide
|
|
||||||
// smoother visible motion when the render frame rate does not match that of the simulation loop. We provide
|
|
||||||
// access to this fraction for improved filtering of update packets to interested parties.
|
|
||||||
float getSubStepRemainder() { return _dynamicsWorld->getLocalTimeAccumulation(); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateObjectHard(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags);
|
void updateObjectHard(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags);
|
||||||
void updateObjectEasy(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags);
|
void updateObjectEasy(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags);
|
||||||
|
|
Loading…
Reference in a new issue