entities use radians per second for angular velocity

This commit is contained in:
Andrew Meadows 2015-03-06 16:42:06 -08:00
parent 021510ae68
commit f5352333f0
6 changed files with 19 additions and 22 deletions

View file

@ -61,7 +61,7 @@ void OctreePacketProcessor::processPacket(const SharedNodePointer& sendingNode,
// check version of piggyback packet against expected version // check version of piggyback packet against expected version
if (packetVersion != expectedVersion if (packetVersion != expectedVersion
// TODO: remove the temporary exception below when everyone is using meters instead of DomainUnits // TODO: remove the temporary exception below when everyone is using meters instead of DomainUnits
&& !(PacketTypeEntityData == voxelPacketType && packetVersion < VERSION_ENTITIES_USE_METERS)) { && !(PacketTypeEntityData == voxelPacketType && packetVersion < VERSION_ENTITIES_USE_METERS_AND_RADIANS)) {
static QMultiMap<QUuid, PacketType> versionDebugSuppressMap; static QMultiMap<QUuid, PacketType> versionDebugSuppressMap;
QUuid senderUUID = uuidFromPacketHeader(packet); QUuid senderUUID = uuidFromPacketHeader(packet);

View file

@ -501,7 +501,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
EntityPropertyFlags propertyFlags = encodedPropertyFlags; EntityPropertyFlags propertyFlags = encodedPropertyFlags;
dataAt += propertyFlags.getEncodedLength(); dataAt += propertyFlags.getEncodedLength();
bytesRead += propertyFlags.getEncodedLength(); bytesRead += propertyFlags.getEncodedLength();
bool useMeters = (args.bitstreamVersion == VERSION_ENTITIES_USE_METERS); bool useMeters = (args.bitstreamVersion == VERSION_ENTITIES_USE_METERS_AND_RADIANS);
if (useMeters) { if (useMeters) {
READ_ENTITY_PROPERTY_SETTER(PROP_POSITION, glm::vec3, updatePosition); READ_ENTITY_PROPERTY_SETTER(PROP_POSITION, glm::vec3, updatePosition);
} else { } else {
@ -540,7 +540,11 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
READ_ENTITY_PROPERTY_SETTER(PROP_LIFETIME, float, updateLifetime); READ_ENTITY_PROPERTY_SETTER(PROP_LIFETIME, float, updateLifetime);
READ_ENTITY_PROPERTY_STRING(PROP_SCRIPT, setScript); READ_ENTITY_PROPERTY_STRING(PROP_SCRIPT, setScript);
READ_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, glm::vec3, _registrationPoint); READ_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, glm::vec3, _registrationPoint);
READ_ENTITY_PROPERTY_SETTER(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocity); if (useMeters) {
READ_ENTITY_PROPERTY_SETTER(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocity);
} else {
READ_ENTITY_PROPERTY_SETTER(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocityInDegrees);
}
READ_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, float, _angularDamping); READ_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, float, _angularDamping);
READ_ENTITY_PROPERTY(PROP_VISIBLE, bool, _visible); READ_ENTITY_PROPERTY(PROP_VISIBLE, bool, _visible);
READ_ENTITY_PROPERTY_SETTER(PROP_IGNORE_FOR_COLLISIONS, bool, updateIgnoreForCollisions); READ_ENTITY_PROPERTY_SETTER(PROP_IGNORE_FOR_COLLISIONS, bool, updateIgnoreForCollisions);
@ -683,41 +687,36 @@ void EntityItem::simulate(const quint64& now) {
void EntityItem::simulateKinematicMotion(float timeElapsed) { void EntityItem::simulateKinematicMotion(float timeElapsed) {
if (hasAngularVelocity()) { if (hasAngularVelocity()) {
// angular damping // angular damping
glm::vec3 angularVelocity = getAngularVelocity();
if (_angularDamping > 0.0f) { if (_angularDamping > 0.0f) {
angularVelocity *= powf(1.0f - _angularDamping, timeElapsed); _angularVelocity *= powf(1.0f - _angularDamping, timeElapsed);
#ifdef WANT_DEBUG #ifdef WANT_DEBUG
qDebug() << " angularDamping :" << _angularDamping; qDebug() << " angularDamping :" << _angularDamping;
qDebug() << " newAngularVelocity:" << angularVelocity; qDebug() << " newAngularVelocity:" << _angularVelocity;
#endif #endif
setAngularVelocity(angularVelocity);
} }
float angularSpeed = glm::length(_angularVelocity); float angularSpeed = glm::length(_angularVelocity);
const float EPSILON_ANGULAR_VELOCITY_LENGTH = 0.1f; // const float EPSILON_ANGULAR_VELOCITY_LENGTH = 0.0017453f; // 0.0017453 rad/sec = 0.1f degrees/sec
if (angularSpeed < EPSILON_ANGULAR_VELOCITY_LENGTH) { if (angularSpeed < EPSILON_ANGULAR_VELOCITY_LENGTH) {
if (angularSpeed > 0.0f) { if (angularSpeed > 0.0f) {
_dirtyFlags |= EntityItem::DIRTY_MOTION_TYPE; _dirtyFlags |= EntityItem::DIRTY_MOTION_TYPE;
} }
setAngularVelocity(ENTITY_ITEM_ZERO_VEC3); _angularVelocity = ENTITY_ITEM_ZERO_VEC3;
} else { } else {
// NOTE: angularSpeed is currently in degrees/sec!!!
// TODO: Andrew to convert to radians/sec
glm::vec3 angularVelocity = glm::radians(_angularVelocity);
// for improved agreement with the way Bullet integrates rotations we use an approximation // for improved agreement with the way Bullet integrates rotations we use an approximation
// and break the integration into bullet-sized substeps // and break the integration into bullet-sized substeps
glm::quat rotation = getRotation(); glm::quat rotation = getRotation();
float dt = timeElapsed; float dt = timeElapsed;
while (dt > PHYSICS_ENGINE_FIXED_SUBSTEP) { while (dt > PHYSICS_ENGINE_FIXED_SUBSTEP) {
glm::quat dQ = computeBulletRotationStep(angularVelocity, PHYSICS_ENGINE_FIXED_SUBSTEP); glm::quat dQ = computeBulletRotationStep(_angularVelocity, PHYSICS_ENGINE_FIXED_SUBSTEP);
rotation = glm::normalize(dQ * rotation); rotation = glm::normalize(dQ * rotation);
dt -= PHYSICS_ENGINE_FIXED_SUBSTEP; dt -= PHYSICS_ENGINE_FIXED_SUBSTEP;
} }
// NOTE: this final partial substep can drift away from a real Bullet simulation however // NOTE: this final partial substep can drift away from a real Bullet simulation however
// it only becomes significant for rapidly rotating objects // it only becomes significant for rapidly rotating objects
// (e.g. around PI/4 radians per substep, or 7.5 rotations/sec at 60 substeps/sec). // (e.g. around PI/4 radians per substep, or 7.5 rotations/sec at 60 substeps/sec).
glm::quat dQ = computeBulletRotationStep(angularVelocity, dt); glm::quat dQ = computeBulletRotationStep(_angularVelocity, dt);
rotation = glm::normalize(dQ * rotation); rotation = glm::normalize(dQ * rotation);
setRotation(rotation); setRotation(rotation);

View file

@ -275,6 +275,7 @@ public:
void updateGravityInDomainUnits(const glm::vec3& value); void updateGravityInDomainUnits(const glm::vec3& value);
void updateGravity(const glm::vec3& value); void updateGravity(const glm::vec3& value);
void updateAngularVelocity(const glm::vec3& value); void updateAngularVelocity(const glm::vec3& value);
void updateAngularVelocityInDegrees(const glm::vec3& value) { updateAngularVelocity(glm::radians(value)); }
void updateAngularDamping(float value); void updateAngularDamping(float value);
void updateIgnoreForCollisions(bool value); void updateIgnoreForCollisions(bool value);
void updateCollisionsWillMove(bool value); void updateCollisionsWillMove(bool value);

View file

@ -74,7 +74,7 @@ PacketVersion versionForPacketType(PacketType type) {
return 1; return 1;
case PacketTypeEntityAddOrEdit: case PacketTypeEntityAddOrEdit:
case PacketTypeEntityData: case PacketTypeEntityData:
return VERSION_ENTITIES_USE_METERS; return VERSION_ENTITIES_USE_METERS_AND_RADIANS;
case PacketTypeEntityErase: case PacketTypeEntityErase:
return 2; return 2;
case PacketTypeAudioStreamStats: case PacketTypeAudioStreamStats:

View file

@ -129,7 +129,7 @@ const PacketVersion VERSION_ENTITIES_HAVE_USER_DATA = 6;
const PacketVersion VERSION_ENTITIES_HAS_LAST_SIMULATED_TIME = 7; const PacketVersion VERSION_ENTITIES_HAS_LAST_SIMULATED_TIME = 7;
const PacketVersion VERSION_MODEL_ENTITIES_SUPPORT_SHAPE_TYPE = 8; const PacketVersion VERSION_MODEL_ENTITIES_SUPPORT_SHAPE_TYPE = 8;
const PacketVersion VERSION_ENTITIES_LIGHT_HAS_INTENSITY_AND_COLOR_PROPERTIES = 9; const PacketVersion VERSION_ENTITIES_LIGHT_HAS_INTENSITY_AND_COLOR_PROPERTIES = 9;
const PacketVersion VERSION_ENTITIES_USE_METERS = 10; const PacketVersion VERSION_ENTITIES_USE_METERS_AND_RADIANS = 10;
const PacketVersion VERSION_OCTREE_HAS_FILE_BREAKS = 1; const PacketVersion VERSION_OCTREE_HAS_FILE_BREAKS = 1;
#endif // hifi_PacketHeaders_h #endif // hifi_PacketHeaders_h

View file

@ -99,8 +99,7 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) {
_entity->setVelocity(v); _entity->setVelocity(v);
getAngularVelocity(v); getAngularVelocity(v);
// DANGER! EntityItem stores angularVelocity in degrees/sec!!! _entity->setAngularVelocity(v);
_entity->setAngularVelocity(glm::degrees(v));
_entity->setLastSimulated(usecTimestampNow()); _entity->setLastSimulated(usecTimestampNow());
@ -159,8 +158,7 @@ void EntityMotionState::updateObjectVelocities() {
_sentVelocity = _entity->getVelocity(); _sentVelocity = _entity->getVelocity();
setVelocity(_sentVelocity); setVelocity(_sentVelocity);
// DANGER! EntityItem stores angularVelocity in degrees/sec!!! _sentAngularVelocity = _entity->getAngularVelocity();
_sentAngularVelocity = glm::radians(_entity->getAngularVelocity());
setAngularVelocity(_sentAngularVelocity); setAngularVelocity(_sentAngularVelocity);
_sentAcceleration = _entity->getGravity(); _sentAcceleration = _entity->getGravity();
@ -219,8 +217,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
properties.setVelocity(_sentVelocity); properties.setVelocity(_sentVelocity);
_sentAcceleration = bulletToGLM(_body->getGravity()); _sentAcceleration = bulletToGLM(_body->getGravity());
properties.setGravity(_sentAcceleration); properties.setGravity(_sentAcceleration);
// DANGER! EntityItem stores angularVelocity in degrees/sec!!! properties.setAngularVelocity(_sentAngularVelocity);
properties.setAngularVelocity(glm::degrees(_sentAngularVelocity));
} }
// RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit. // RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit.