fix spring action so that it can be linear or rotational or both

This commit is contained in:
Seth Alves 2017-04-30 10:04:07 -07:00
parent 8f2fc24885
commit 7ce0ef2ec4
4 changed files with 65 additions and 38 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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();

View file

@ -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;