mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 12:37:51 +02:00
fix spring action so that it can be linear or rotational or both
This commit is contained in:
parent
8f2fc24885
commit
7ce0ef2ec4
4 changed files with 65 additions and 38 deletions
|
@ -113,7 +113,8 @@ void AvatarActionHold::prepareForPhysicsSimulation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AvatarActionHold::getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
bool AvatarActionHold::getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
||||||
glm::vec3& linearVelocity, glm::vec3& angularVelocity) {
|
glm::vec3& linearVelocity, glm::vec3& angularVelocity,
|
||||||
|
float& linearTimeScale, float& angularTimeScale) {
|
||||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||||
auto holdingAvatar = std::static_pointer_cast<Avatar>(avatarManager->getAvatarBySessionID(_holderID));
|
auto holdingAvatar = std::static_pointer_cast<Avatar>(avatarManager->getAvatarBySessionID(_holderID));
|
||||||
|
|
||||||
|
@ -213,6 +214,9 @@ bool AvatarActionHold::getTarget(float deltaTimeStep, glm::quat& rotation, glm::
|
||||||
|
|
||||||
// update linearVelocity based on offset via _relativePosition;
|
// update linearVelocity based on offset via _relativePosition;
|
||||||
linearVelocity = linearVelocity + glm::cross(angularVelocity, position - palmPosition);
|
linearVelocity = linearVelocity + glm::cross(angularVelocity, position - palmPosition);
|
||||||
|
|
||||||
|
linearTimeScale = _linearTimeScale;
|
||||||
|
angularTimeScale = _angularTimeScale;
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -38,7 +38,8 @@ public:
|
||||||
|
|
||||||
bool getAvatarRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation);
|
bool getAvatarRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation);
|
||||||
virtual bool getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
virtual bool getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
||||||
glm::vec3& linearVelocity, glm::vec3& angularVelocity) override;
|
glm::vec3& linearVelocity, glm::vec3& angularVelocity,
|
||||||
|
float& linearTimeScale, float& angularTimeScale) override;
|
||||||
|
|
||||||
virtual void prepareForPhysicsSimulation() override;
|
virtual void prepareForPhysicsSimulation() override;
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "PhysicsLogging.h"
|
#include "PhysicsLogging.h"
|
||||||
|
|
||||||
const float SPRING_MAX_SPEED = 10.0f;
|
const float SPRING_MAX_SPEED = 10.0f;
|
||||||
|
const float MAX_SPRING_TIMESCALE = 600.0f; // 10 min is a long time
|
||||||
|
|
||||||
const uint16_t ObjectActionSpring::springVersion = 1;
|
const uint16_t ObjectActionSpring::springVersion = 1;
|
||||||
|
|
||||||
|
@ -42,11 +43,16 @@ ObjectActionSpring::~ObjectActionSpring() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectActionSpring::getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
bool ObjectActionSpring::getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
||||||
glm::vec3& linearVelocity, glm::vec3& angularVelocity) {
|
glm::vec3& linearVelocity, glm::vec3& angularVelocity,
|
||||||
rotation = _desiredRotationalTarget;
|
float& linearTimeScale, float& angularTimeScale) {
|
||||||
position = _desiredPositionalTarget;
|
withReadLock([&]{
|
||||||
linearVelocity = glm::vec3();
|
rotation = _desiredRotationalTarget;
|
||||||
angularVelocity = glm::vec3();
|
position = _desiredPositionalTarget;
|
||||||
|
linearVelocity = glm::vec3();
|
||||||
|
angularVelocity = glm::vec3();
|
||||||
|
linearTimeScale = _linearTimeScale;
|
||||||
|
angularTimeScale = _angularTimeScale;
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,8 +67,10 @@ bool ObjectActionSpring::prepareForSpringUpdate(btScalar deltaTimeStep) {
|
||||||
glm::vec3 linearVelocity;
|
glm::vec3 linearVelocity;
|
||||||
glm::vec3 angularVelocity;
|
glm::vec3 angularVelocity;
|
||||||
|
|
||||||
bool valid = false;
|
bool linearValid = false;
|
||||||
int springCount = 0;
|
int linearSpringCount = 0;
|
||||||
|
bool angularValid = false;
|
||||||
|
int angularSpringCount = 0;
|
||||||
|
|
||||||
QList<EntityDynamicPointer> springDerivedActions;
|
QList<EntityDynamicPointer> springDerivedActions;
|
||||||
springDerivedActions.append(ownerEntity->getActionsOfType(DYNAMIC_TYPE_SPRING));
|
springDerivedActions.append(ownerEntity->getActionsOfType(DYNAMIC_TYPE_SPRING));
|
||||||
|
@ -73,41 +81,55 @@ bool ObjectActionSpring::prepareForSpringUpdate(btScalar deltaTimeStep) {
|
||||||
std::shared_ptr<ObjectActionSpring> springAction = std::static_pointer_cast<ObjectActionSpring>(action);
|
std::shared_ptr<ObjectActionSpring> springAction = std::static_pointer_cast<ObjectActionSpring>(action);
|
||||||
glm::quat rotationForAction;
|
glm::quat rotationForAction;
|
||||||
glm::vec3 positionForAction;
|
glm::vec3 positionForAction;
|
||||||
glm::vec3 linearVelocityForAction, angularVelocityForAction;
|
glm::vec3 linearVelocityForAction;
|
||||||
bool success = springAction->getTarget(deltaTimeStep, rotationForAction,
|
glm::vec3 angularVelocityForAction;
|
||||||
positionForAction, linearVelocityForAction,
|
float linearTimeScale;
|
||||||
angularVelocityForAction);
|
float angularTimeScale;
|
||||||
|
bool success = springAction->getTarget(deltaTimeStep,
|
||||||
|
rotationForAction, positionForAction,
|
||||||
|
linearVelocityForAction, angularVelocityForAction,
|
||||||
|
linearTimeScale, angularTimeScale);
|
||||||
if (success) {
|
if (success) {
|
||||||
springCount ++;
|
if (angularTimeScale < MAX_SPRING_TIMESCALE) {
|
||||||
if (springAction.get() == this) {
|
angularValid = true;
|
||||||
// only use the rotation for this action
|
angularSpringCount++;
|
||||||
valid = true;
|
angularVelocity += angularVelocityForAction;
|
||||||
rotation = rotationForAction;
|
if (springAction.get() == this) {
|
||||||
|
// only use the rotation for this action
|
||||||
|
rotation = rotationForAction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
position += positionForAction;
|
if (linearTimeScale < MAX_SPRING_TIMESCALE) {
|
||||||
linearVelocity += linearVelocityForAction;
|
linearValid = true;
|
||||||
angularVelocity += angularVelocityForAction;
|
linearSpringCount++;
|
||||||
|
position += positionForAction;
|
||||||
|
linearVelocity += linearVelocityForAction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid && springCount > 0) {
|
if ((angularValid && angularSpringCount > 0) || (linearValid && linearSpringCount > 0)) {
|
||||||
position /= springCount;
|
|
||||||
linearVelocity /= springCount;
|
|
||||||
angularVelocity /= springCount;
|
|
||||||
|
|
||||||
withWriteLock([&]{
|
withWriteLock([&]{
|
||||||
_positionalTarget = position;
|
if (linearValid && linearSpringCount > 0) {
|
||||||
_rotationalTarget = rotation;
|
position /= linearSpringCount;
|
||||||
_linearVelocityTarget = linearVelocity;
|
linearVelocity /= linearSpringCount;
|
||||||
_angularVelocityTarget = angularVelocity;
|
_positionalTarget = position;
|
||||||
_positionalTargetSet = true;
|
_linearVelocityTarget = linearVelocity;
|
||||||
_rotationalTargetSet = true;
|
_positionalTargetSet = true;
|
||||||
_active = true;
|
_active = true;
|
||||||
|
}
|
||||||
|
if (angularValid && angularSpringCount > 0) {
|
||||||
|
angularVelocity /= angularSpringCount;
|
||||||
|
_rotationalTarget = rotation;
|
||||||
|
_angularVelocityTarget = angularVelocity;
|
||||||
|
_rotationalTargetSet = true;
|
||||||
|
_active = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return valid;
|
return linearValid || angularValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,8 +155,7 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float MAX_TIMESCALE = 600.0f; // 10 min is a long time
|
if (_linearTimeScale < MAX_SPRING_TIMESCALE) {
|
||||||
if (_linearTimeScale < MAX_TIMESCALE) {
|
|
||||||
btVector3 targetVelocity(0.0f, 0.0f, 0.0f);
|
btVector3 targetVelocity(0.0f, 0.0f, 0.0f);
|
||||||
btVector3 offset = rigidBody->getCenterOfMassPosition() - glmToBullet(_positionalTarget);
|
btVector3 offset = rigidBody->getCenterOfMassPosition() - glmToBullet(_positionalTarget);
|
||||||
float offsetLength = offset.length();
|
float offsetLength = offset.length();
|
||||||
|
@ -150,7 +171,7 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) {
|
||||||
rigidBody->setLinearVelocity(targetVelocity);
|
rigidBody->setLinearVelocity(targetVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_angularTimeScale < MAX_TIMESCALE) {
|
if (_angularTimeScale < MAX_SPRING_TIMESCALE) {
|
||||||
btVector3 targetVelocity(0.0f, 0.0f, 0.0f);
|
btVector3 targetVelocity(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
btQuaternion bodyRotation = rigidBody->getOrientation();
|
btQuaternion bodyRotation = rigidBody->getOrientation();
|
||||||
|
|
|
@ -28,7 +28,8 @@ public:
|
||||||
virtual void deserialize(QByteArray serializedArguments) override;
|
virtual void deserialize(QByteArray serializedArguments) override;
|
||||||
|
|
||||||
virtual bool getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
virtual bool getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
||||||
glm::vec3& linearVelocity, glm::vec3& angularVelocity);
|
glm::vec3& linearVelocity, glm::vec3& angularVelocity,
|
||||||
|
float& linearTimeScale, float& angularTimeScale);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const uint16_t springVersion;
|
static const uint16_t springVersion;
|
||||||
|
|
Loading…
Reference in a new issue