first attempt at getting spring-action to handle rotation

This commit is contained in:
Seth Alves 2015-06-08 17:10:13 -07:00
parent 1e858d8bc5
commit b3bc9c3ef0
4 changed files with 80 additions and 51 deletions

View file

@ -44,9 +44,11 @@ QString EntityActionInterface::actionTypeToString(EntityActionType actionType) {
} }
glm::vec3 EntityActionInterface::extractVec3Argument(QString objectName, QVariantMap arguments, glm::vec3 EntityActionInterface::extractVec3Argument(QString objectName, QVariantMap arguments,
QString argumentName, bool& ok) { QString argumentName, bool& ok, bool required) {
if (!arguments.contains(argumentName)) { if (!arguments.contains(argumentName)) {
qDebug() << objectName << "requires argument:" << argumentName; if (required) {
qDebug() << objectName << "requires argument:" << argumentName;
}
ok = false; ok = false;
return glm::vec3(); return glm::vec3();
} }
@ -86,16 +88,18 @@ glm::vec3 EntityActionInterface::extractVec3Argument(QString objectName, QVarian
glm::quat EntityActionInterface::extractQuatArgument(QString objectName, QVariantMap arguments, glm::quat EntityActionInterface::extractQuatArgument(QString objectName, QVariantMap arguments,
QString argumentName, bool& ok) { QString argumentName, bool& ok, bool required) {
if (!arguments.contains(argumentName)) { if (!arguments.contains(argumentName)) {
qDebug() << objectName << "requires argument:" << argumentName; if (required) {
qDebug() << objectName << "requires argument:" << argumentName;
}
ok = false; ok = false;
return glm::quat(); return glm::quat();
} }
QVariant resultV = arguments[argumentName]; QVariant resultV = arguments[argumentName];
if (resultV.type() != (QVariant::Type) QMetaType::QVariantMap) { if (resultV.type() != (QVariant::Type) QMetaType::QVariantMap) {
qDebug() << objectName << "argument" << argumentName << "must be a map"; qDebug() << objectName << "argument" << argumentName << "must be a map, not" << resultV.typeName();
ok = false; ok = false;
return glm::quat(); return glm::quat();
} }
@ -133,9 +137,11 @@ glm::quat EntityActionInterface::extractQuatArgument(QString objectName, QVarian
float EntityActionInterface::extractFloatArgument(QString objectName, QVariantMap arguments, float EntityActionInterface::extractFloatArgument(QString objectName, QVariantMap arguments,
QString argumentName, bool& ok) { QString argumentName, bool& ok, bool required) {
if (!arguments.contains(argumentName)) { if (!arguments.contains(argumentName)) {
qDebug() << objectName << "requires argument:" << argumentName; if (required) {
qDebug() << objectName << "requires argument:" << argumentName;
}
ok = false; ok = false;
return 0.0f; return 0.0f;
} }

View file

@ -41,9 +41,12 @@ public:
protected: protected:
static glm::vec3 extractVec3Argument(QString objectName, QVariantMap arguments, QString argumentName, bool& ok); static glm::vec3 extractVec3Argument (QString objectName, QVariantMap arguments,
static glm::quat extractQuatArgument(QString objectName, QVariantMap arguments, QString argumentName, bool& ok); QString argumentName, bool& ok, bool required = true);
static float extractFloatArgument(QString objectName, QVariantMap arguments, QString argumentName, bool& ok); static glm::quat extractQuatArgument (QString objectName, QVariantMap arguments,
QString argumentName, bool& ok, bool required = true);
static float extractFloatArgument(QString objectName, QVariantMap arguments,
QString argumentName, bool& ok, bool required = true);
}; };
typedef std::shared_ptr<EntityActionInterface> EntityActionPointer; typedef std::shared_ptr<EntityActionInterface> EntityActionPointer;

View file

@ -38,27 +38,30 @@ void ObjectActionSpring::updateAction(btCollisionWorld* collisionWorld, btScalar
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo); ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
btRigidBody* rigidBody = motionState->getRigidBody(); btRigidBody* rigidBody = motionState->getRigidBody();
if (rigidBody) { if (rigidBody) {
glm::vec3 offset = _positionalTarget - bulletToGLM(rigidBody->getCenterOfMassPosition()); // handle the linear part
if (_positionalTargetSet) {
glm::vec3 offset = _positionalTarget - bulletToGLM(rigidBody->getCenterOfMassPosition());
float offsetLength = glm::length(offset);
float speed = offsetLength / _linearTimeScale;
if (offsetLength > IGNORE_POSITION_DELTA) {
glm::vec3 newVelocity = glm::normalize(offset) * speed;
rigidBody->setLinearVelocity(glmToBullet(newVelocity));
// void setAngularVelocity (const btVector3 &ang_vel);
rigidBody->activate();
} else {
rigidBody->setLinearVelocity(glmToBullet(glm::vec3()));
}
}
// btQuaternion getOrientation() const; // handle rotation
// const btTransform& getCenterOfMassTransform() const; if (_rotationalTargetSet) {
glm::quat qZeroInverse = glm::inverse(bulletToGLM(rigidBody->getOrientation()));
float offsetLength = glm::length(offset); glm::quat deltaQ = _rotationalTarget * qZeroInverse;
float speed = offsetLength; // XXX use _positionalSpringConstant glm::vec3 axis = glm::axis(deltaQ);
float angle = glm::angle(deltaQ);
float interpolation_value = 0.5; // XXX glm::vec3 newAngularVelocity = (-angle / _angularTimeScale) * glm::normalize(axis);
const glm::quat slerped_quat = glm::slerp(bulletToGLM(rigidBody->getOrientation()), rigidBody->setAngularVelocity(glmToBullet(newAngularVelocity));
_rotationalTarget,
interpolation_value);
if (offsetLength > IGNORE_POSITION_DELTA) {
glm::vec3 newVelocity = glm::normalize(offset) * speed;
rigidBody->setLinearVelocity(glmToBullet(newVelocity));
// void setAngularVelocity (const btVector3 &ang_vel);
rigidBody->activate();
} else {
rigidBody->setLinearVelocity(glmToBullet(glm::vec3()));
} }
} }
} }
@ -68,37 +71,52 @@ void ObjectActionSpring::updateAction(btCollisionWorld* collisionWorld, btScalar
bool ObjectActionSpring::updateArguments(QVariantMap arguments) { bool ObjectActionSpring::updateArguments(QVariantMap arguments) {
// targets are required, spring-constants are optional // targets are required, spring-constants are optional
bool ok = true; bool ptOk = true;
glm::vec3 positionalTarget = glm::vec3 positionalTarget =
EntityActionInterface::extractVec3Argument("spring action", arguments, "positionalTarget", ok); EntityActionInterface::extractVec3Argument("spring action", arguments, "targetPosition", ptOk, false);
bool pscOK = true; bool pscOk = true;
float positionalSpringConstant = float linearTimeScale =
EntityActionInterface::extractFloatArgument("spring action", arguments, "positionalSpringConstant", pscOK); EntityActionInterface::extractFloatArgument("spring action", arguments, "linearTimeScale", pscOk, false);
if (ptOk && pscOk && linearTimeScale <= 0.0f) {
qDebug() << "spring action -- linearTimeScale must be greater than zero.";
return false;
}
bool rtOk = true;
glm::quat rotationalTarget = glm::quat rotationalTarget =
EntityActionInterface::extractQuatArgument("spring action", arguments, "rotationalTarget", ok); EntityActionInterface::extractQuatArgument("spring action", arguments, "targetRotation", rtOk, false);
bool rscOK = true; bool rscOk = true;
float rotationalSpringConstant = float angularTimeScale =
EntityActionInterface::extractFloatArgument("spring action", arguments, "rotationalSpringConstant", rscOK); EntityActionInterface::extractFloatArgument("spring action", arguments, "angularTimeScale", rscOk, false);
if (!ok) { if (!ptOk && !rtOk) {
qDebug() << "spring action requires either targetPosition or targetRotation argument";
return false; return false;
} }
lockForWrite(); lockForWrite();
_positionalTarget = positionalTarget; _positionalTargetSet = _rotationalTargetSet = false;
if (pscOK) {
_positionalSpringConstant = positionalSpringConstant; if (ptOk) {
} else { _positionalTarget = positionalTarget;
_positionalSpringConstant = 0.5; // XXX pick a good default; _positionalTargetSet = true;
if (pscOk) {
_linearTimeScale = linearTimeScale;
} else {
_linearTimeScale = 0.1;
}
} }
_rotationalTarget = rotationalTarget; if (rtOk) {
if (rscOK) { _rotationalTarget = rotationalTarget;
_rotationalSpringConstant = rotationalSpringConstant;
} else { if (rscOk) {
_rotationalSpringConstant = 0.5; // XXX pick a good default; _angularTimeScale = angularTimeScale;
} else {
_angularTimeScale = 0.1;
}
} }
_active = true; _active = true;

View file

@ -28,10 +28,12 @@ public:
private: private:
glm::vec3 _positionalTarget; glm::vec3 _positionalTarget;
float _positionalSpringConstant; float _linearTimeScale;
bool _positionalTargetSet;
glm::quat _rotationalTarget; glm::quat _rotationalTarget;
float _rotationalSpringConstant; float _angularTimeScale;
bool _rotationalTargetSet;
}; };
#endif // hifi_ObjectActionSpring_h #endif // hifi_ObjectActionSpring_h