start on spring action

This commit is contained in:
Seth Alves 2015-06-08 14:16:03 -07:00
parent 7c0e70b1d1
commit 1e858d8bc5
5 changed files with 208 additions and 6 deletions

View file

@ -22,6 +22,9 @@ EntityActionType EntityActionInterface::actionTypeFromString(QString actionTypeS
if (normalizedActionTypeString == "pulltopoint") {
return ACTION_TYPE_PULL_TO_POINT;
}
if (normalizedActionTypeString == "spring") {
return ACTION_TYPE_SPRING;
}
qDebug() << "Warning -- EntityActionInterface::actionTypeFromString got unknown action-type name" << actionTypeString;
return ACTION_TYPE_NONE;
@ -33,6 +36,8 @@ QString EntityActionInterface::actionTypeToString(EntityActionType actionType) {
return "none";
case ACTION_TYPE_PULL_TO_POINT:
return "pullToPoint";
case ACTION_TYPE_SPRING:
return "spring";
}
assert(false);
return "none";
@ -43,21 +48,21 @@ glm::vec3 EntityActionInterface::extractVec3Argument(QString objectName, QVarian
if (!arguments.contains(argumentName)) {
qDebug() << objectName << "requires argument:" << argumentName;
ok = false;
return vec3();
return glm::vec3();
}
QVariant resultV = arguments[argumentName];
if (resultV.type() != (QVariant::Type) QMetaType::QVariantMap) {
qDebug() << objectName << "argument" << argumentName << "must be a map";
ok = false;
return vec3();
return glm::vec3();
}
QVariantMap resultVM = resultV.toMap();
if (!resultVM.contains("x") || !resultVM.contains("y") || !resultVM.contains("z")) {
qDebug() << objectName << "argument" << argumentName << "must be a map with keys of x, y, z";
ok = false;
return vec3();
return glm::vec3();
}
QVariant xV = resultVM["x"];
@ -73,13 +78,60 @@ glm::vec3 EntityActionInterface::extractVec3Argument(QString objectName, QVarian
if (!xOk || !yOk || !zOk) {
qDebug() << objectName << "argument" << argumentName << "must be a map with keys of x, y, z and values of type float.";
ok = false;
return vec3();
return glm::vec3();
}
return vec3(x, y, z);
return glm::vec3(x, y, z);
}
glm::quat EntityActionInterface::extractQuatArgument(QString objectName, QVariantMap arguments,
QString argumentName, bool& ok) {
if (!arguments.contains(argumentName)) {
qDebug() << objectName << "requires argument:" << argumentName;
ok = false;
return glm::quat();
}
QVariant resultV = arguments[argumentName];
if (resultV.type() != (QVariant::Type) QMetaType::QVariantMap) {
qDebug() << objectName << "argument" << argumentName << "must be a map";
ok = false;
return glm::quat();
}
QVariantMap resultVM = resultV.toMap();
if (!resultVM.contains("x") || !resultVM.contains("y") || !resultVM.contains("z")) {
qDebug() << objectName << "argument" << argumentName << "must be a map with keys of x, y, z";
ok = false;
return glm::quat();
}
QVariant xV = resultVM["x"];
QVariant yV = resultVM["y"];
QVariant zV = resultVM["z"];
QVariant wV = resultVM["w"];
bool xOk = true;
bool yOk = true;
bool zOk = true;
bool wOk = true;
float x = xV.toFloat(&xOk);
float y = yV.toFloat(&yOk);
float z = zV.toFloat(&zOk);
float w = wV.toFloat(&wOk);
if (!xOk || !yOk || !zOk || !wOk) {
qDebug() << objectName << "argument" << argumentName
<< "must be a map with keys of x, y, z, w and values of type float.";
ok = false;
return glm::quat();
}
return glm::quat(x, y, z, w);
}
float EntityActionInterface::extractFloatArgument(QString objectName, QVariantMap arguments,
QString argumentName, bool& ok) {
if (!arguments.contains(argumentName)) {

View file

@ -19,7 +19,8 @@ class EntitySimulation;
enum EntityActionType {
// keep these synchronized with actionTypeFromString and actionTypeToString
ACTION_TYPE_NONE,
ACTION_TYPE_PULL_TO_POINT
ACTION_TYPE_PULL_TO_POINT,
ACTION_TYPE_SPRING
};
@ -41,6 +42,7 @@ public:
protected:
static glm::vec3 extractVec3Argument(QString objectName, QVariantMap arguments, QString argumentName, bool& ok);
static glm::quat extractQuatArgument(QString objectName, QVariantMap arguments, QString argumentName, bool& ok);
static float extractFloatArgument(QString objectName, QVariantMap arguments, QString argumentName, bool& ok);
};

View file

@ -0,0 +1,107 @@
//
// ObjectActionSpring.cpp
// libraries/physics/src
//
// Created by Seth Alves 2015-6-5
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "ObjectMotionState.h"
#include "BulletUtil.h"
#include "ObjectActionSpring.h"
ObjectActionSpring::ObjectActionSpring(QUuid id, EntityItemPointer ownerEntity) :
ObjectAction(id, ownerEntity) {
#if WANT_DEBUG
qDebug() << "ObjectActionSpring::ObjectActionSpring";
#endif
}
ObjectActionSpring::~ObjectActionSpring() {
#if WANT_DEBUG
qDebug() << "ObjectActionSpring::~ObjectActionSpring";
#endif
}
void ObjectActionSpring::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) {
if (!tryLockForRead()) {
// don't risk hanging the thread running the physics simulation
return;
}
void* physicsInfo = _ownerEntity->getPhysicsInfo();
if (_active && physicsInfo) {
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
btRigidBody* rigidBody = motionState->getRigidBody();
if (rigidBody) {
glm::vec3 offset = _positionalTarget - bulletToGLM(rigidBody->getCenterOfMassPosition());
// btQuaternion getOrientation() const;
// const btTransform& getCenterOfMassTransform() const;
float offsetLength = glm::length(offset);
float speed = offsetLength; // XXX use _positionalSpringConstant
float interpolation_value = 0.5; // XXX
const glm::quat slerped_quat = glm::slerp(bulletToGLM(rigidBody->getOrientation()),
_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()));
}
}
}
unlock();
}
bool ObjectActionSpring::updateArguments(QVariantMap arguments) {
// targets are required, spring-constants are optional
bool ok = true;
glm::vec3 positionalTarget =
EntityActionInterface::extractVec3Argument("spring action", arguments, "positionalTarget", ok);
bool pscOK = true;
float positionalSpringConstant =
EntityActionInterface::extractFloatArgument("spring action", arguments, "positionalSpringConstant", pscOK);
glm::quat rotationalTarget =
EntityActionInterface::extractQuatArgument("spring action", arguments, "rotationalTarget", ok);
bool rscOK = true;
float rotationalSpringConstant =
EntityActionInterface::extractFloatArgument("spring action", arguments, "rotationalSpringConstant", rscOK);
if (!ok) {
return false;
}
lockForWrite();
_positionalTarget = positionalTarget;
if (pscOK) {
_positionalSpringConstant = positionalSpringConstant;
} else {
_positionalSpringConstant = 0.5; // XXX pick a good default;
}
_rotationalTarget = rotationalTarget;
if (rscOK) {
_rotationalSpringConstant = rotationalSpringConstant;
} else {
_rotationalSpringConstant = 0.5; // XXX pick a good default;
}
_active = true;
unlock();
return true;
}

View file

@ -0,0 +1,37 @@
//
// ObjectActionSpring.h
// libraries/physics/src
//
// Created by Seth Alves 2015-6-5
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_ObjectActionSpring_h
#define hifi_ObjectActionSpring_h
#include <QUuid>
#include <EntityItem.h>
#include "ObjectAction.h"
class ObjectActionSpring : public ObjectAction {
public:
ObjectActionSpring(QUuid id, EntityItemPointer ownerEntity);
virtual ~ObjectActionSpring();
virtual bool updateArguments(QVariantMap arguments);
virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep);
private:
glm::vec3 _positionalTarget;
float _positionalSpringConstant;
glm::quat _rotationalTarget;
float _rotationalSpringConstant;
};
#endif // hifi_ObjectActionSpring_h

View file

@ -13,6 +13,7 @@
#include "PhysicsLogging.h"
#include "ShapeManager.h"
#include "ObjectActionPullToPoint.h"
#include "ObjectActionSpring.h"
#include "PhysicalEntitySimulation.h"
@ -245,6 +246,9 @@ EntityActionPointer PhysicalEntitySimulation::actionFactory(EntityActionType typ
case ACTION_TYPE_PULL_TO_POINT:
action = (EntityActionPointer) new ObjectActionPullToPoint(id, ownerEntity);
break;
case ACTION_TYPE_SPRING:
action = (EntityActionPointer) new ObjectActionSpring(id, ownerEntity);
break;
}
bool ok = action->updateArguments(arguments);