mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 15:23:56 +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;
|
||||
_changedOnServer = 0;
|
||||
|
||||
_position = glm::vec3(0,0,0);
|
||||
_dimensions = DEFAULT_DIMENSIONS;
|
||||
_rotation = DEFAULT_ROTATION;
|
||||
_glowLevel = DEFAULT_GLOW_LEVEL;
|
||||
_localRenderAlpha = DEFAULT_LOCAL_RENDER_ALPHA;
|
||||
_mass = DEFAULT_MASS;
|
||||
_velocity = DEFAULT_VELOCITY;
|
||||
_gravity = DEFAULT_GRAVITY;
|
||||
_damping = DEFAULT_DAMPING;
|
||||
_lifetime = DEFAULT_LIFETIME;
|
||||
_script = DEFAULT_SCRIPT;
|
||||
_registrationPoint = DEFAULT_REGISTRATION_POINT;
|
||||
_angularVelocity = DEFAULT_ANGULAR_VELOCITY;
|
||||
_angularDamping = DEFAULT_ANGULAR_DAMPING;
|
||||
_visible = DEFAULT_VISIBLE;
|
||||
_ignoreForCollisions = DEFAULT_IGNORE_FOR_COLLISIONS;
|
||||
_collisionsWillMove = DEFAULT_COLLISIONS_WILL_MOVE;
|
||||
_locked = DEFAULT_LOCKED;
|
||||
_userData = DEFAULT_USER_DATA;
|
||||
_position = ENTITY_ITEM_ZERO_VEC3;
|
||||
_dimensions = ENTITY_ITEM_DEFAULT_DIMENSIONS;
|
||||
_rotation = ENTITY_ITEM_DEFAULT_ROTATION;
|
||||
_glowLevel = ENTITY_ITEM_DEFAULT_GLOW_LEVEL;
|
||||
_localRenderAlpha = ENTITY_ITEM_DEFAULT_LOCAL_RENDER_ALPHA;
|
||||
_mass = ENTITY_ITEM_DEFAULT_MASS;
|
||||
_velocity = ENTITY_ITEM_DEFAULT_VELOCITY;
|
||||
_gravity = ENTITY_ITEM_DEFAULT_GRAVITY;
|
||||
_damping = ENTITY_ITEM_DEFAULT_DAMPING;
|
||||
_lifetime = ENTITY_ITEM_DEFAULT_LIFETIME;
|
||||
_script = ENTITY_ITEM_DEFAULT_SCRIPT;
|
||||
_registrationPoint = ENTITY_ITEM_DEFAULT_REGISTRATION_POINT;
|
||||
_angularVelocity = ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY;
|
||||
_angularDamping = ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING;
|
||||
_visible = ENTITY_ITEM_DEFAULT_VISIBLE;
|
||||
_ignoreForCollisions = ENTITY_ITEM_DEFAULT_IGNORE_FOR_COLLISIONS;
|
||||
_collisionsWillMove = ENTITY_ITEM_DEFAULT_COLLISIONS_WILL_MOVE;
|
||||
_locked = ENTITY_ITEM_DEFAULT_LOCKED;
|
||||
_userData = ENTITY_ITEM_DEFAULT_USER_DATA;
|
||||
|
||||
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
|
||||
// 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?
|
||||
|
@ -562,7 +564,7 @@ bool EntityItem::isRestingOnSurface() const {
|
|||
glm::vec3 downwardVelocity = glm::vec3(0.0f, _velocity.y, 0.0f);
|
||||
|
||||
return _position.y <= getDistanceToBottomOfEntity()
|
||||
&& (glm::length(downwardVelocity) <= EPSILON_VELOCITY_LENGTH)
|
||||
&& (glm::length(downwardVelocity) <= ENTITY_ITEM_EPSILON_VELOCITY_LENGTH)
|
||||
&& _gravity.y < 0.0f;
|
||||
}
|
||||
|
||||
|
@ -639,7 +641,7 @@ void EntityItem::simulate(const quint64& now) {
|
|||
|
||||
const float EPSILON_ANGULAR_VELOCITY_LENGTH = 0.1f; //
|
||||
if (angularSpeed < EPSILON_ANGULAR_VELOCITY_LENGTH) {
|
||||
setAngularVelocity(NO_ANGULAR_VELOCITY);
|
||||
setAngularVelocity(ENTITY_ITEM_ZERO_VEC3);
|
||||
} else {
|
||||
// NOTE: angularSpeed is currently in degrees/sec!!!
|
||||
// TODO: Andrew to convert to radians/sec
|
||||
|
@ -668,7 +670,7 @@ void EntityItem::simulate(const quint64& now) {
|
|||
qDebug() << " damping:" << _damping;
|
||||
qDebug() << " velocity AFTER dampingResistance:" << 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
|
||||
// if we've slowed considerably, then just stop moving, but only if no BULLET
|
||||
if (glm::length(velocity) <= EPSILON_VELOCITY_LENGTH) {
|
||||
velocity = NO_VELOCITY;
|
||||
if (glm::length(velocity) <= ENTITY_ITEM_EPSILON_VELOCITY_LENGTH) {
|
||||
velocity = ENTITY_ITEM_ZERO_VEC3;
|
||||
}
|
||||
#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...
|
||||
#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;
|
||||
if (glm::length(velocity) <= ENTITY_ITEM_EPSILON_VELOCITY_LENGTH) {
|
||||
velocity = ENTITY_ITEM_ZERO_VEC3;
|
||||
}
|
||||
#endif // USE_BULLET_PHYSICS
|
||||
|
||||
|
@ -909,7 +911,7 @@ AACube EntityItem::getMinimumAACube() const {
|
|||
// _position represents the position of the registration point.
|
||||
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;
|
||||
Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
|
||||
Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation());
|
||||
|
@ -934,7 +936,7 @@ AABox EntityItem::getAABox() const {
|
|||
// _position represents the position of the registration point.
|
||||
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;
|
||||
Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
|
||||
Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation());
|
||||
|
@ -998,7 +1000,7 @@ void EntityItem::recalculateCollisionShape() {
|
|||
const float MIN_POSITION_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_VELOCITY_DELTA = 0.01f;
|
||||
const float MIN_DAMPING_DELTA = 0.001f;
|
||||
const float MIN_GRAVITY_DELTA = 0.001f;
|
||||
const float MIN_SPIN_DELTA = 0.0003f;
|
||||
|
@ -1055,7 +1057,7 @@ void EntityItem::updateMass(float value) {
|
|||
void EntityItem::updateVelocity(const glm::vec3& value) {
|
||||
if (glm::distance(_velocity, 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 {
|
||||
_velocity = value;
|
||||
}
|
||||
|
@ -1067,7 +1069,7 @@ void EntityItem::updateVelocityInMeters(const glm::vec3& value) {
|
|||
glm::vec3 velocity = value / (float) TREE_SCALE;
|
||||
if (glm::distance(_velocity, velocity) * (float)TREE_SCALE > MIN_VELOCITY_DELTA) {
|
||||
if (glm::length(value) < MIN_VELOCITY_DELTA) {
|
||||
_velocity = glm::vec3(0.0f);
|
||||
_velocity = ENTITY_ITEM_ZERO_VEC3;
|
||||
} else {
|
||||
_velocity = velocity;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "EntityItemID.h"
|
||||
#include "EntityItemProperties.h"
|
||||
#include "EntityItemPropertiesDefaults.h"
|
||||
#include "EntityTypes.h"
|
||||
|
||||
class EntityTree;
|
||||
|
@ -35,30 +36,6 @@ class EntityTreeElementExtraEncodeData;
|
|||
#define DONT_ALLOW_INSTANTIATION virtual void pureVirtualFunctionPlaceHolder() = 0;
|
||||
#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
|
||||
/// 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
|
||||
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
|
||||
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
|
||||
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 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
|
||||
bool isRestingOnSurface() const;
|
||||
|
@ -220,10 +197,10 @@ public:
|
|||
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
|
||||
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
|
||||
bool isMortal() const { return _lifetime != IMMORTAL; }
|
||||
bool isMortal() const { return _lifetime != ENTITY_ITEM_IMMORTAL_LIFETIME; }
|
||||
|
||||
/// age of this entity in seconds
|
||||
float getAge() const { return (float)(usecTimestampNow() - _created) / (float)USECS_PER_SECOND; }
|
||||
|
@ -247,7 +224,7 @@ public:
|
|||
|
||||
const glm::vec3& getAngularVelocity() const { return _angularVelocity; }
|
||||
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; }
|
||||
void setAngularDamping(float value) { _angularDamping = value; }
|
||||
|
|
|
@ -19,32 +19,34 @@
|
|||
|
||||
#include "EntityItem.h"
|
||||
#include "EntityItemProperties.h"
|
||||
#include "EntityItemPropertiesDefaults.h"
|
||||
#include "ModelEntityItem.h"
|
||||
#include "TextEntityItem.h"
|
||||
|
||||
|
||||
EntityItemProperties::EntityItemProperties() :
|
||||
|
||||
CONSTRUCT_PROPERTY(visible, DEFAULT_VISIBLE),
|
||||
CONSTRUCT_PROPERTY(visible, ENTITY_ITEM_DEFAULT_VISIBLE),
|
||||
CONSTRUCT_PROPERTY(position, 0),
|
||||
CONSTRUCT_PROPERTY(dimensions, DEFAULT_DIMENSIONS),
|
||||
CONSTRUCT_PROPERTY(rotation, DEFAULT_ROTATION),
|
||||
CONSTRUCT_PROPERTY(mass, DEFAULT_MASS),
|
||||
CONSTRUCT_PROPERTY(velocity, DEFAULT_VELOCITY),
|
||||
CONSTRUCT_PROPERTY(gravity, DEFAULT_GRAVITY),
|
||||
CONSTRUCT_PROPERTY(damping, DEFAULT_DAMPING),
|
||||
CONSTRUCT_PROPERTY(lifetime, DEFAULT_LIFETIME),
|
||||
CONSTRUCT_PROPERTY(script, DEFAULT_SCRIPT),
|
||||
CONSTRUCT_PROPERTY(dimensions, ENTITY_ITEM_DEFAULT_DIMENSIONS),
|
||||
CONSTRUCT_PROPERTY(rotation, ENTITY_ITEM_DEFAULT_ROTATION),
|
||||
CONSTRUCT_PROPERTY(mass, ENTITY_ITEM_DEFAULT_MASS),
|
||||
CONSTRUCT_PROPERTY(velocity, ENTITY_ITEM_DEFAULT_VELOCITY),
|
||||
CONSTRUCT_PROPERTY(gravity, ENTITY_ITEM_DEFAULT_GRAVITY),
|
||||
CONSTRUCT_PROPERTY(damping, ENTITY_ITEM_DEFAULT_DAMPING),
|
||||
CONSTRUCT_PROPERTY(lifetime, ENTITY_ITEM_DEFAULT_LIFETIME),
|
||||
CONSTRUCT_PROPERTY(script, ENTITY_ITEM_DEFAULT_SCRIPT),
|
||||
CONSTRUCT_PROPERTY(color, ),
|
||||
CONSTRUCT_PROPERTY(modelURL, ""),
|
||||
CONSTRUCT_PROPERTY(animationURL, ""),
|
||||
CONSTRUCT_PROPERTY(animationFPS, ModelEntityItem::DEFAULT_ANIMATION_FPS),
|
||||
CONSTRUCT_PROPERTY(animationFrameIndex, ModelEntityItem::DEFAULT_ANIMATION_FRAME_INDEX),
|
||||
CONSTRUCT_PROPERTY(animationIsPlaying, ModelEntityItem::DEFAULT_ANIMATION_IS_PLAYING),
|
||||
CONSTRUCT_PROPERTY(registrationPoint, DEFAULT_REGISTRATION_POINT),
|
||||
CONSTRUCT_PROPERTY(angularVelocity, DEFAULT_ANGULAR_VELOCITY),
|
||||
CONSTRUCT_PROPERTY(angularDamping, DEFAULT_ANGULAR_DAMPING),
|
||||
CONSTRUCT_PROPERTY(ignoreForCollisions, DEFAULT_IGNORE_FOR_COLLISIONS),
|
||||
CONSTRUCT_PROPERTY(collisionsWillMove, DEFAULT_COLLISIONS_WILL_MOVE),
|
||||
CONSTRUCT_PROPERTY(registrationPoint, ENTITY_ITEM_DEFAULT_REGISTRATION_POINT),
|
||||
CONSTRUCT_PROPERTY(angularVelocity, ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY),
|
||||
CONSTRUCT_PROPERTY(angularDamping, ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING),
|
||||
CONSTRUCT_PROPERTY(ignoreForCollisions, ENTITY_ITEM_DEFAULT_IGNORE_FOR_COLLISIONS),
|
||||
CONSTRUCT_PROPERTY(collisionsWillMove, ENTITY_ITEM_DEFAULT_COLLISIONS_WILL_MOVE),
|
||||
CONSTRUCT_PROPERTY(isSpotlight, false),
|
||||
CONSTRUCT_PROPERTY(diffuseColor, ),
|
||||
CONSTRUCT_PROPERTY(ambientColor, ),
|
||||
|
@ -54,10 +56,10 @@ EntityItemProperties::EntityItemProperties() :
|
|||
CONSTRUCT_PROPERTY(quadraticAttenuation, 0.0f),
|
||||
CONSTRUCT_PROPERTY(exponent, 0.0f),
|
||||
CONSTRUCT_PROPERTY(cutoff, PI),
|
||||
CONSTRUCT_PROPERTY(locked, false),
|
||||
CONSTRUCT_PROPERTY(locked, ENTITY_ITEM_DEFAULT_LOCKED),
|
||||
CONSTRUCT_PROPERTY(textures, ""),
|
||||
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(lineHeight, TextEntityItem::DEFAULT_LINE_HEIGHT),
|
||||
CONSTRUCT_PROPERTY(textColor, TextEntityItem::DEFAULT_TEXT_COLOR),
|
||||
|
@ -858,7 +860,7 @@ AABox EntityItemProperties::getAABoxInMeters() const {
|
|||
// _position represents the position of the registration point.
|
||||
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;
|
||||
Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
|
||||
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
|
||||
|
||||
void EntityMotionState::applyVelocities() const {
|
||||
void EntityMotionState::updateObjectEasy(uint32_t flags, uint32_t frame) {
|
||||
#ifdef USE_BULLET_PHYSICS
|
||||
if (_body) {
|
||||
setVelocity(_entity->getVelocityInMeters());
|
||||
// DANGER! EntityItem stores angularVelocity in degrees/sec!!!
|
||||
setAngularVelocity(glm::radians(_entity->getAngularVelocity()));
|
||||
_body->setActivationState(ACTIVE_TAG);
|
||||
}
|
||||
#endif // USE_BULLET_PHYSICS
|
||||
}
|
||||
if (flags & (EntityItem::DIRTY_POSITION | EntityItem::DIRTY_VELOCITY)) {
|
||||
if (flags & EntityItem::DIRTY_POSITION) {
|
||||
_sentPosition = _entity->getPositionInMeters() - ObjectMotionState::getWorldOffset();
|
||||
btTransform worldTrans;
|
||||
worldTrans.setOrigin(glmToBullet(_sentPosition));
|
||||
|
||||
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
|
||||
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);
|
||||
}
|
||||
#endif // USE_BULLET_PHYSICS
|
||||
|
@ -123,7 +161,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
|||
_sentAngularVelocity = bulletToGLM(_body->getAngularVelocity());
|
||||
|
||||
// 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);
|
||||
if (zeroSpeed) {
|
||||
_sentVelocity = glm::vec3(0.0f);
|
||||
|
|
|
@ -54,8 +54,8 @@ public:
|
|||
#endif // USE_BULLET_PHYSICS
|
||||
|
||||
// these relay incoming values to the RigidBody
|
||||
void applyVelocities() const;
|
||||
void applyGravity() const;
|
||||
void updateObjectEasy(uint32_t flags, uint32_t frame);
|
||||
void updateObjectVelocities();
|
||||
|
||||
void computeShapeInfo(ShapeInfo& info);
|
||||
|
||||
|
|
|
@ -123,9 +123,9 @@ bool ObjectMotionState::doesNotNeedToSendUpdate() const {
|
|||
|
||||
const float FIXED_SUBSTEP = 1.0f / 60.0f;
|
||||
|
||||
bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame, float subStepRemainder) {
|
||||
bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame) {
|
||||
assert(_body);
|
||||
float dt = (float)(simulationFrame - _sentFrame) * FIXED_SUBSTEP + subStepRemainder;
|
||||
float dt = (float)(simulationFrame - _sentFrame) * FIXED_SUBSTEP;
|
||||
_sentFrame = simulationFrame;
|
||||
bool isActive = _body->isActive();
|
||||
|
||||
|
@ -183,7 +183,7 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame, float subStep
|
|||
}
|
||||
const float MIN_ROTATION_DOT = 0.98f;
|
||||
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
|
||||
|
|
|
@ -56,8 +56,9 @@ public:
|
|||
ObjectMotionState();
|
||||
~ObjectMotionState();
|
||||
|
||||
virtual void applyVelocities() const = 0;
|
||||
virtual void applyGravity() const = 0;
|
||||
// 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 updateObjectVelocities() = 0;
|
||||
|
||||
virtual void computeShapeInfo(ShapeInfo& info) = 0;
|
||||
|
||||
|
@ -84,7 +85,7 @@ public:
|
|||
void clearOutgoingPacketFlags(uint32_t flags) { _outgoingPacketFlags &= ~flags; }
|
||||
|
||||
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 MotionType computeMotionType() const = 0;
|
||||
|
|
|
@ -41,14 +41,12 @@ void PhysicsEngine::updateEntitiesInternal(const quint64& now) {
|
|||
|
||||
// this is step (4)
|
||||
QSet<ObjectMotionState*>::iterator stateItr = _outgoingPackets.begin();
|
||||
uint32_t frame = getFrameCount();
|
||||
float subStepRemainder = getSubStepRemainder();
|
||||
while (stateItr != _outgoingPackets.end()) {
|
||||
ObjectMotionState* state = *stateItr;
|
||||
if (state->doesNotNeedToSendUpdate()) {
|
||||
stateItr = _outgoingPackets.erase(stateItr);
|
||||
} else if (state->shouldSendUpdate(frame, subStepRemainder)) {
|
||||
state->sendUpdate(_entityPacketSender, frame);
|
||||
} else if (state->shouldSendUpdate(_frameCount)) {
|
||||
state->sendUpdate(_entityPacketSender, _frameCount);
|
||||
++stateItr;
|
||||
} else {
|
||||
++stateItr;
|
||||
|
@ -140,7 +138,8 @@ void PhysicsEngine::relayIncomingChangesToSimulation() {
|
|||
updateObjectHard(body, motionState, flags);
|
||||
} else if (flags) {
|
||||
// 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->updateInertiaTensor();
|
||||
motionState->_body = body;
|
||||
motionState->applyVelocities();
|
||||
motionState->applyGravity();
|
||||
motionState->updateObjectVelocities();
|
||||
// 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;
|
||||
}
|
||||
case MOTION_TYPE_STATIC:
|
||||
|
@ -334,7 +337,7 @@ void PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio
|
|||
}
|
||||
bool easyUpdate = flags & EASY_DIRTY_PHYSICS_FLAGS;
|
||||
if (easyUpdate) {
|
||||
updateObjectEasy(body, motionState, flags);
|
||||
motionState->updateObjectEasy(flags, _frameCount);
|
||||
}
|
||||
|
||||
// update the motion parameters
|
||||
|
@ -385,31 +388,4 @@ void PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio
|
|||
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
|
||||
|
|
|
@ -71,12 +71,6 @@ public:
|
|||
/// \return number of simulation frames the physics engine has taken
|
||||
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:
|
||||
void updateObjectHard(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags);
|
||||
void updateObjectEasy(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags);
|
||||
|
|
Loading…
Reference in a new issue