mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 08:14:48 +02:00
SpatiallyNestable: now with velocity support!
Moved velocity and angularVelocity into the SpatiallyNestable base class. Entity velocity and angularVelocity properties are now relative to their parent, similar to the way position and orientation work for entities. MyAvatar rig animations now use SpatiallyNestable to convert velocity into local frame to drive the animation state machine.
This commit is contained in:
parent
97bcc54360
commit
072172b1a2
11 changed files with 162 additions and 73 deletions
|
@ -16,8 +16,8 @@ function init() {
|
|||
isDynamic: false
|
||||
});
|
||||
if (platform) {
|
||||
MyAvatar.position = { x: 0, y: 3, z: 0 };
|
||||
if (MyAvatar.getParentID() != platform) {
|
||||
MyAvatar.position = { x: 0, y: 3, z: 0 };
|
||||
MyAvatar.setParentID(platform);
|
||||
}
|
||||
}
|
||||
|
@ -34,8 +34,7 @@ function shutdown() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
Script.setTimeout(init, 3000);
|
||||
|
||||
Script.update.connect(update);
|
||||
Script.scriptEnding.connect(shutdown);
|
||||
|
|
|
@ -86,9 +86,7 @@ Avatar::Avatar(RigPointer rig) :
|
|||
_positionDeltaAccumulator(0.0f),
|
||||
_lastVelocity(0.0f),
|
||||
_acceleration(0.0f),
|
||||
_angularVelocity(0.0f),
|
||||
_lastAngularVelocity(0.0f),
|
||||
_angularAcceleration(0.0f),
|
||||
_lastOrientation(),
|
||||
_leanScale(0.5f),
|
||||
_worldUpDirection(DEFAULT_UP_DIRECTION),
|
||||
|
@ -235,9 +233,6 @@ void Avatar::simulate(float deltaTime) {
|
|||
_displayNameAlpha = abs(_displayNameAlpha - _displayNameTargetAlpha) < 0.01f ? _displayNameTargetAlpha : _displayNameAlpha;
|
||||
}
|
||||
|
||||
// NOTE: we shouldn't extrapolate an Avatar instance forward in time...
|
||||
// until velocity is included in AvatarData update message.
|
||||
//_position += _velocity * deltaTime;
|
||||
measureMotionDerivatives(deltaTime);
|
||||
|
||||
simulateAttachments(deltaTime);
|
||||
|
@ -255,7 +250,7 @@ bool Avatar::isLookingAtMe(AvatarSharedPointer avatar) const {
|
|||
void Avatar::slamPosition(const glm::vec3& newPosition) {
|
||||
setPosition(newPosition);
|
||||
_positionDeltaAccumulator = glm::vec3(0.0f);
|
||||
_velocity = glm::vec3(0.0f);
|
||||
setVelocity(glm::vec3(0.0f));
|
||||
_lastVelocity = glm::vec3(0.0f);
|
||||
}
|
||||
|
||||
|
@ -269,15 +264,17 @@ void Avatar::measureMotionDerivatives(float deltaTime) {
|
|||
float invDeltaTime = 1.0f / deltaTime;
|
||||
// Floating point error prevents us from computing velocity in a naive way
|
||||
// (e.g. vel = (pos - oldPos) / dt) so instead we use _positionOffsetAccumulator.
|
||||
_velocity = _positionDeltaAccumulator * invDeltaTime;
|
||||
glm::vec3 velocity = _positionDeltaAccumulator * invDeltaTime;
|
||||
_positionDeltaAccumulator = glm::vec3(0.0f);
|
||||
_acceleration = (_velocity - _lastVelocity) * invDeltaTime;
|
||||
_lastVelocity = _velocity;
|
||||
_acceleration = (velocity - _lastVelocity) * invDeltaTime;
|
||||
_lastVelocity = velocity;
|
||||
setVelocity(velocity);
|
||||
|
||||
// angular
|
||||
glm::quat orientation = getOrientation();
|
||||
glm::quat delta = glm::inverse(_lastOrientation) * orientation;
|
||||
_angularVelocity = safeEulerAngles(delta) * invDeltaTime;
|
||||
_angularAcceleration = (_angularVelocity - _lastAngularVelocity) * invDeltaTime;
|
||||
glm::vec3 angularVelocity = glm::axis(delta) * glm::angle(delta) * invDeltaTime;
|
||||
setAngularVelocity(angularVelocity);
|
||||
_lastOrientation = getOrientation();
|
||||
}
|
||||
|
||||
|
|
|
@ -135,8 +135,6 @@ public:
|
|||
Q_INVOKABLE glm::vec3 getNeckPosition() const;
|
||||
|
||||
Q_INVOKABLE glm::vec3 getAcceleration() const { return _acceleration; }
|
||||
Q_INVOKABLE glm::vec3 getAngularVelocity() const { return _angularVelocity; }
|
||||
Q_INVOKABLE glm::vec3 getAngularAcceleration() const { return _angularAcceleration; }
|
||||
|
||||
Q_INVOKABLE bool getShouldRender() const { return !_shouldSkipRender; }
|
||||
|
||||
|
|
|
@ -1079,17 +1079,8 @@ void MyAvatar::rebuildCollisionShape() {
|
|||
void MyAvatar::prepareForPhysicsSimulation() {
|
||||
relayDriveKeysToCharacterController();
|
||||
|
||||
glm::vec3 parentVelocity;
|
||||
bool success;
|
||||
auto parentPtr = getParentPointer(success);
|
||||
if (success && parentPtr && parentPtr->getNestableType() == NestableType::Entity) {
|
||||
auto entityPtr = std::dynamic_pointer_cast<EntityItem>(parentPtr);
|
||||
if (entityPtr) {
|
||||
parentVelocity = entityPtr->getVelocity();
|
||||
}
|
||||
}
|
||||
|
||||
_characterController.setParentVelocity(parentVelocity);
|
||||
_characterController.setParentVelocity(getParentVelocity(success));
|
||||
_characterController.setTargetVelocity(getTargetVelocity());
|
||||
_characterController.setPositionAndOrientation(getPosition(), getOrientation());
|
||||
if (qApp->isHMDMode()) {
|
||||
|
|
|
@ -149,25 +149,9 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
|||
|
||||
Rig::CharacterControllerState ccState = convertCharacterControllerState(myAvatar->getCharacterController()->getState());
|
||||
|
||||
auto velocity = myAvatar->getVelocity();
|
||||
auto position = myAvatar->getPosition();
|
||||
auto orientation = myAvatar->getOrientation();
|
||||
|
||||
// check to see if we are attached to an Entity.
|
||||
bool success;
|
||||
auto parentPtr = myAvatar->getParentPointer(success);
|
||||
if (success && parentPtr && parentPtr->getNestableType() == NestableType::Entity) {
|
||||
auto entityPtr = std::dynamic_pointer_cast<EntityItem>(parentPtr);
|
||||
if (entityPtr) {
|
||||
// TODO: Do we need account for angularVelocity of entity?
|
||||
|
||||
auto invParentRot = glm::inverse(entityPtr->getOrientation());
|
||||
velocity = invParentRot * (myAvatar->getVelocity() - entityPtr->getVelocity());
|
||||
position = myAvatar->getLocalPosition();
|
||||
orientation = myAvatar->getLocalOrientation();
|
||||
}
|
||||
}
|
||||
|
||||
auto velocity = myAvatar->getLocalVelocity();
|
||||
auto position = myAvatar->getLocalPosition();
|
||||
auto orientation = myAvatar->getLocalOrientation();
|
||||
_rig->computeMotionAnimationState(deltaTime, position, velocity, orientation, ccState);
|
||||
|
||||
// evaluate AnimGraph animation and update jointStates.
|
||||
|
|
|
@ -64,7 +64,6 @@ AvatarData::AvatarData() :
|
|||
_billboard(),
|
||||
_errorLogExpiry(0),
|
||||
_owningAvatarMixer(),
|
||||
_velocity(0.0f),
|
||||
_targetVelocity(0.0f),
|
||||
_localAABox(DEFAULT_LOCAL_AABOX_CORNER, DEFAULT_LOCAL_AABOX_SCALE)
|
||||
{
|
||||
|
|
|
@ -151,6 +151,9 @@ class AvatarData : public QObject, public SpatiallyNestable {
|
|||
Q_PROPERTY(float headYaw READ getHeadYaw WRITE setHeadYaw)
|
||||
Q_PROPERTY(float headRoll READ getHeadRoll WRITE setHeadRoll)
|
||||
|
||||
Q_PROPERTY(glm::vec3 velocity READ getVelocity WRITE setVelocity)
|
||||
Q_PROPERTY(glm::vec3 angularVelocity READ getAngularVelocity WRITE setAngularVelocity)
|
||||
|
||||
Q_PROPERTY(float audioLoudness READ getAudioLoudness WRITE setAudioLoudness)
|
||||
Q_PROPERTY(float audioAverageLoudness READ getAudioAverageLoudness WRITE setAudioAverageLoudness)
|
||||
|
||||
|
@ -334,8 +337,6 @@ public:
|
|||
int getAverageBytesReceivedPerSecond() const;
|
||||
int getReceiveRate() const;
|
||||
|
||||
void setVelocity(const glm::vec3 velocity) { _velocity = velocity; }
|
||||
Q_INVOKABLE glm::vec3 getVelocity() const { return _velocity; }
|
||||
const glm::vec3& getTargetVelocity() const { return _targetVelocity; }
|
||||
|
||||
bool shouldDie() const { return _owningAvatarMixer.isNull() || getUsecsSinceLastUpdate() > AVATAR_SILENCE_THRESHOLD_USECS; }
|
||||
|
@ -406,7 +407,6 @@ protected:
|
|||
/// Loads the joint indices, names from the FST file (if any)
|
||||
virtual void updateJointMappings();
|
||||
|
||||
glm::vec3 _velocity;
|
||||
glm::vec3 _targetVelocity;
|
||||
|
||||
AABox _localAABox;
|
||||
|
|
|
@ -49,7 +49,6 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) :
|
|||
_localRenderAlpha(ENTITY_ITEM_DEFAULT_LOCAL_RENDER_ALPHA),
|
||||
_density(ENTITY_ITEM_DEFAULT_DENSITY),
|
||||
_volumeMultiplier(1.0f),
|
||||
_velocity(ENTITY_ITEM_DEFAULT_VELOCITY),
|
||||
_gravity(ENTITY_ITEM_DEFAULT_GRAVITY),
|
||||
_acceleration(ENTITY_ITEM_DEFAULT_ACCELERATION),
|
||||
_damping(ENTITY_ITEM_DEFAULT_DAMPING),
|
||||
|
@ -60,7 +59,6 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) :
|
|||
_scriptTimestamp(ENTITY_ITEM_DEFAULT_SCRIPT_TIMESTAMP),
|
||||
_collisionSoundURL(ENTITY_ITEM_DEFAULT_COLLISION_SOUND_URL),
|
||||
_registrationPoint(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT),
|
||||
_angularVelocity(ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY),
|
||||
_angularDamping(ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING),
|
||||
_visible(ENTITY_ITEM_DEFAULT_VISIBLE),
|
||||
_collisionless(ENTITY_ITEM_DEFAULT_COLLISIONLESS),
|
||||
|
@ -78,6 +76,8 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) :
|
|||
_physicsInfo(nullptr),
|
||||
_simulated(false)
|
||||
{
|
||||
setVelocity(ENTITY_ITEM_DEFAULT_VELOCITY);
|
||||
setAngularVelocity(ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY);
|
||||
// explicitly set transform parts to set dirty flags used by batch rendering
|
||||
setScale(ENTITY_ITEM_DEFAULT_DIMENSIONS);
|
||||
quint64 now = usecTimestampNow();
|
||||
|
@ -886,41 +886,45 @@ void EntityItem::simulateKinematicMotion(float timeElapsed, bool setFlags) {
|
|||
}
|
||||
|
||||
if (hasAngularVelocity()) {
|
||||
glm::vec3 angularVelocity = getAngularVelocity();
|
||||
|
||||
// angular damping
|
||||
if (_angularDamping > 0.0f) {
|
||||
_angularVelocity *= powf(1.0f - _angularDamping, timeElapsed);
|
||||
angularVelocity *= powf(1.0f - _angularDamping, timeElapsed);
|
||||
#ifdef WANT_DEBUG
|
||||
qCDebug(entities) << " angularDamping :" << _angularDamping;
|
||||
qCDebug(entities) << " newAngularVelocity:" << _angularVelocity;
|
||||
qCDebug(entities) << " newAngularVelocity:" << angularVelocity;
|
||||
#endif
|
||||
}
|
||||
|
||||
float angularSpeed = glm::length(_angularVelocity);
|
||||
float angularSpeed = glm::length(angularVelocity);
|
||||
|
||||
const float EPSILON_ANGULAR_VELOCITY_LENGTH = 0.0017453f; // 0.0017453 rad/sec = 0.1f degrees/sec
|
||||
if (angularSpeed < EPSILON_ANGULAR_VELOCITY_LENGTH) {
|
||||
if (setFlags && angularSpeed > 0.0f) {
|
||||
_dirtyFlags |= Simulation::DIRTY_MOTION_TYPE;
|
||||
}
|
||||
_angularVelocity = ENTITY_ITEM_ZERO_VEC3;
|
||||
angularVelocity = ENTITY_ITEM_ZERO_VEC3;
|
||||
} else {
|
||||
// for improved agreement with the way Bullet integrates rotations we use an approximation
|
||||
// and break the integration into bullet-sized substeps
|
||||
glm::quat rotation = getRotation();
|
||||
float dt = timeElapsed;
|
||||
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);
|
||||
dt -= PHYSICS_ENGINE_FIXED_SUBSTEP;
|
||||
}
|
||||
// NOTE: this final partial substep can drift away from a real Bullet simulation however
|
||||
// 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).
|
||||
glm::quat dQ = computeBulletRotationStep(_angularVelocity, dt);
|
||||
glm::quat dQ = computeBulletRotationStep(angularVelocity, dt);
|
||||
rotation = glm::normalize(dQ * rotation);
|
||||
|
||||
setRotation(rotation);
|
||||
}
|
||||
|
||||
setAngularVelocity(angularVelocity);
|
||||
}
|
||||
|
||||
if (hasVelocity()) {
|
||||
|
@ -1077,9 +1081,9 @@ EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProper
|
|||
void EntityItem::getAllTerseUpdateProperties(EntityItemProperties& properties) const {
|
||||
// a TerseUpdate includes the transform and its derivatives
|
||||
properties._position = getLocalPosition();
|
||||
properties._velocity = _velocity;
|
||||
properties._velocity = getLocalVelocity();
|
||||
properties._rotation = getLocalOrientation();
|
||||
properties._angularVelocity = _angularVelocity;
|
||||
properties._angularVelocity = getLocalAngularVelocity();
|
||||
properties._acceleration = _acceleration;
|
||||
|
||||
properties._positionChanged = true;
|
||||
|
@ -1406,13 +1410,15 @@ void EntityItem::updateVelocity(const glm::vec3& value) {
|
|||
if (shouldSuppressLocationEdits()) {
|
||||
return;
|
||||
}
|
||||
if (_velocity != value) {
|
||||
glm::vec3 velocity = getLocalVelocity();
|
||||
if (velocity != value) {
|
||||
const float MIN_LINEAR_SPEED = 0.001f;
|
||||
if (glm::length(value) < MIN_LINEAR_SPEED) {
|
||||
_velocity = ENTITY_ITEM_ZERO_VEC3;
|
||||
velocity = ENTITY_ITEM_ZERO_VEC3;
|
||||
} else {
|
||||
_velocity = value;
|
||||
velocity = value;
|
||||
}
|
||||
setLocalVelocity(velocity);
|
||||
_dirtyFlags |= Simulation::DIRTY_LINEAR_VELOCITY;
|
||||
}
|
||||
}
|
||||
|
@ -1436,13 +1442,15 @@ void EntityItem::updateAngularVelocity(const glm::vec3& value) {
|
|||
if (shouldSuppressLocationEdits()) {
|
||||
return;
|
||||
}
|
||||
if (_angularVelocity != value) {
|
||||
glm::vec3 angularVelocity = getLocalAngularVelocity();
|
||||
if (angularVelocity != value) {
|
||||
const float MIN_ANGULAR_SPEED = 0.0002f;
|
||||
if (glm::length(value) < MIN_ANGULAR_SPEED) {
|
||||
_angularVelocity = ENTITY_ITEM_ZERO_VEC3;
|
||||
angularVelocity = ENTITY_ITEM_ZERO_VEC3;
|
||||
} else {
|
||||
_angularVelocity = value;
|
||||
angularVelocity = value;
|
||||
}
|
||||
setLocalAngularVelocity(angularVelocity);
|
||||
_dirtyFlags |= Simulation::DIRTY_ANGULAR_VELOCITY;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -193,9 +193,7 @@ public:
|
|||
|
||||
float getDensity() const { return _density; }
|
||||
|
||||
const glm::vec3& getVelocity() const { return _velocity; } /// get velocity in meters
|
||||
void setVelocity(const glm::vec3& value) { _velocity = value; } /// velocity in meters
|
||||
bool hasVelocity() const { return _velocity != ENTITY_ITEM_ZERO_VEC3; }
|
||||
bool hasVelocity() const { return getVelocity() != ENTITY_ITEM_ZERO_VEC3; }
|
||||
|
||||
const glm::vec3& getGravity() const { return _gravity; } /// get gravity in meters
|
||||
void setGravity(const glm::vec3& value) { _gravity = value; } /// gravity in meters
|
||||
|
@ -255,9 +253,7 @@ public:
|
|||
void setRegistrationPoint(const glm::vec3& value)
|
||||
{ _registrationPoint = glm::clamp(value, 0.0f, 1.0f); requiresRecalcBoxes(); }
|
||||
|
||||
const glm::vec3& getAngularVelocity() const { return _angularVelocity; }
|
||||
void setAngularVelocity(const glm::vec3& value) { _angularVelocity = value; }
|
||||
bool hasAngularVelocity() const { return _angularVelocity != ENTITY_ITEM_ZERO_VEC3; }
|
||||
bool hasAngularVelocity() const { return getAngularVelocity() != ENTITY_ITEM_ZERO_VEC3; }
|
||||
|
||||
float getAngularDamping() const { return _angularDamping; }
|
||||
void setAngularDamping(float value) { _angularDamping = value; }
|
||||
|
@ -435,7 +431,6 @@ protected:
|
|||
// rather than in all of the derived classes. If we ever collapse these classes to one we could do it a
|
||||
// different way.
|
||||
float _volumeMultiplier = 1.0f;
|
||||
glm::vec3 _velocity;
|
||||
glm::vec3 _gravity;
|
||||
glm::vec3 _acceleration;
|
||||
float _damping;
|
||||
|
@ -446,7 +441,6 @@ protected:
|
|||
quint64 _scriptTimestamp;
|
||||
QString _collisionSoundURL;
|
||||
glm::vec3 _registrationPoint;
|
||||
glm::vec3 _angularVelocity;
|
||||
float _angularDamping;
|
||||
bool _visible;
|
||||
bool _collisionless;
|
||||
|
|
|
@ -391,6 +391,77 @@ void SpatiallyNestable::setOrientation(const glm::quat& orientation) {
|
|||
#endif
|
||||
}
|
||||
|
||||
glm::vec3 SpatiallyNestable::getVelocity(bool& success) const {
|
||||
glm::vec3 parentVelocity = getParentVelocity(success);
|
||||
Transform parentTransform = getParentTransform(success);
|
||||
glm::vec3 result;
|
||||
_transformLock.withReadLock([&] {
|
||||
// TODO: take parent angularVelocity into account.
|
||||
result = parentVelocity + parentTransform.getRotation() * _velocity;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
glm::vec3 SpatiallyNestable::getVelocity() const {
|
||||
bool success;
|
||||
return getVelocity(success);
|
||||
}
|
||||
|
||||
void SpatiallyNestable::setVelocity(const glm::vec3& velocity, bool& success) {
|
||||
glm::vec3 parentVelocity = getParentVelocity(success);
|
||||
Transform parentTransform = getParentTransform(success);
|
||||
_transformLock.withWriteLock([&] {
|
||||
// TODO: take parent angularVelocity into account.
|
||||
_velocity = glm::inverse(parentTransform.getRotation()) * velocity - parentVelocity;
|
||||
});
|
||||
}
|
||||
|
||||
void SpatiallyNestable::setVelocity(const glm::vec3& velocity) {
|
||||
bool success;
|
||||
setVelocity(velocity, success);
|
||||
}
|
||||
|
||||
glm::vec3 SpatiallyNestable::getParentVelocity(bool& success) const {
|
||||
glm::vec3 result;
|
||||
SpatiallyNestablePointer parent = getParentPointer(success);
|
||||
if (success && parent) {
|
||||
result = parent->getVelocity(success);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
glm::vec3 SpatiallyNestable::getAngularVelocity(bool& success) const {
|
||||
glm::vec3 parentAngularVelocity = getParentAngularVelocity(success);
|
||||
Transform parentTransform = getParentTransform(success);
|
||||
glm::vec3 result;
|
||||
_transformLock.withReadLock([&] {
|
||||
result = parentAngularVelocity + parentTransform.getRotation() * _angularVelocity;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
glm::vec3 SpatiallyNestable::getAngularVelocity() const {
|
||||
bool success;
|
||||
return getAngularVelocity(success);
|
||||
}
|
||||
|
||||
void SpatiallyNestable::setAngularVelocity(const glm::vec3& angularVelocity, bool& success) {
|
||||
glm::vec3 parentAngularVelocity = getParentAngularVelocity(success);
|
||||
Transform parentTransform = getParentTransform(success);
|
||||
_transformLock.withWriteLock([&] {
|
||||
_angularVelocity = glm::inverse(parentTransform.getRotation()) * angularVelocity - parentAngularVelocity;
|
||||
});
|
||||
}
|
||||
|
||||
void SpatiallyNestable::setAngularVelocity(const glm::vec3& angularVelocity) {
|
||||
bool success;
|
||||
setAngularVelocity(angularVelocity, success);
|
||||
}
|
||||
|
||||
glm::vec3 SpatiallyNestable::getParentAngularVelocity(bool& success) const {
|
||||
return glm::vec3();
|
||||
}
|
||||
|
||||
const Transform SpatiallyNestable::getTransform(bool& success) const {
|
||||
// return a world-space transform for this object's location
|
||||
Transform parentTransform = getParentTransform(success);
|
||||
|
@ -519,6 +590,34 @@ void SpatiallyNestable::setLocalOrientation(const glm::quat& orientation) {
|
|||
locationChanged();
|
||||
}
|
||||
|
||||
glm::vec3 SpatiallyNestable::getLocalVelocity() const {
|
||||
glm::vec3 result(glm::vec3::_null);
|
||||
_transformLock.withReadLock([&] {
|
||||
result = _velocity;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
void SpatiallyNestable::setLocalVelocity(const glm::vec3& velocity) {
|
||||
_transformLock.withWriteLock([&] {
|
||||
_velocity = velocity;
|
||||
});
|
||||
}
|
||||
|
||||
glm::vec3 SpatiallyNestable::getLocalAngularVelocity() const {
|
||||
glm::vec3 result(glm::vec3::_null);
|
||||
_transformLock.withReadLock([&] {
|
||||
result = _angularVelocity;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
void SpatiallyNestable::setLocalAngularVelocity(const glm::vec3& angularVelocity) {
|
||||
_transformLock.withWriteLock([&] {
|
||||
_angularVelocity = angularVelocity;
|
||||
});
|
||||
}
|
||||
|
||||
glm::vec3 SpatiallyNestable::getLocalScale() const {
|
||||
// TODO: scale
|
||||
glm::vec3 result;
|
||||
|
|
|
@ -68,6 +68,18 @@ public:
|
|||
virtual void setOrientation(const glm::quat& orientation, bool& success);
|
||||
virtual void setOrientation(const glm::quat& orientation);
|
||||
|
||||
virtual glm::vec3 getVelocity(bool& success) const;
|
||||
virtual glm::vec3 getVelocity() const;
|
||||
virtual void setVelocity(const glm::vec3& velocity, bool& success);
|
||||
virtual void setVelocity(const glm::vec3& velocity);
|
||||
virtual glm::vec3 getParentVelocity(bool& success) const;
|
||||
|
||||
virtual glm::vec3 getAngularVelocity(bool& success) const;
|
||||
virtual glm::vec3 getAngularVelocity() const;
|
||||
virtual void setAngularVelocity(const glm::vec3& angularVelocity, bool& success);
|
||||
virtual void setAngularVelocity(const glm::vec3& angularVelocity);
|
||||
virtual glm::vec3 getParentAngularVelocity(bool& success) const;
|
||||
|
||||
virtual AACube getMaximumAACube(bool& success) const;
|
||||
virtual bool computePuffedQueryAACube();
|
||||
|
||||
|
@ -94,6 +106,12 @@ public:
|
|||
virtual glm::quat getLocalOrientation() const;
|
||||
virtual void setLocalOrientation(const glm::quat& orientation);
|
||||
|
||||
virtual glm::vec3 getLocalVelocity() const;
|
||||
virtual void setLocalVelocity(const glm::vec3& velocity);
|
||||
|
||||
virtual glm::vec3 getLocalAngularVelocity() const;
|
||||
virtual void setLocalAngularVelocity(const glm::vec3& angularVelocity);
|
||||
|
||||
virtual glm::vec3 getLocalScale() const;
|
||||
virtual void setLocalScale(const glm::vec3& scale);
|
||||
|
||||
|
@ -148,6 +166,8 @@ private:
|
|||
mutable ReadWriteLockable _transformLock;
|
||||
mutable ReadWriteLockable _idLock;
|
||||
Transform _transform; // this is to be combined with parent's world-transform to produce this' world-transform.
|
||||
glm::vec3 _velocity;
|
||||
glm::vec3 _angularVelocity;
|
||||
mutable bool _parentKnowsMe { false };
|
||||
bool _isDead { false };
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue