pull some common code out of subclasses and into ObjectAction

This commit is contained in:
Seth Alves 2015-06-09 16:17:48 -07:00
parent 6cce845984
commit b1a209b9db
7 changed files with 90 additions and 98 deletions

View file

@ -1012,7 +1012,9 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) {
void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) {
checkAndCallPreload(entityID);
auto entity = static_cast<EntityTree*>(_tree)->findEntityByID(entityID);
addEntityToScene(entity);
if (entity) {
addEntityToScene(entity);
}
}
void EntityTreeRenderer::addEntityToScene(EntityItemPointer entity) {

View file

@ -24,7 +24,27 @@ ObjectAction::~ObjectAction() {
}
void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) {
qDebug() << "ObjectAction::updateAction called";
if (!_active) {
return;
}
if (!_ownerEntity) {
qDebug() << "ObjectActionPullToPoint::updateAction no owner entity";
return;
}
if (!tryLockForRead()) {
// don't risk hanging the thread running the physics simulation
return;
}
void* physicsInfo = _ownerEntity->getPhysicsInfo();
if (physicsInfo) {
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
btRigidBody* rigidBody = motionState->getRigidBody();
if (rigidBody) {
updateActionWorker(collisionWorld, deltaTimeStep, motionState, rigidBody);
}
}
unlock();
}
void ObjectAction::debugDraw(btIDebugDraw* debugDrawer) {

View file

@ -13,11 +13,14 @@
#ifndef hifi_ObjectAction_h
#define hifi_ObjectAction_h
#include <btBulletDynamicsCommon.h>
#include <QUuid>
#include <btBulletDynamicsCommon.h>
#include <EntityItem.h>
#include "ObjectMotionState.h"
#include "BulletUtil.h"
class ObjectAction : public btActionInterface, public EntityActionInterface {
public:
@ -30,6 +33,10 @@ public:
virtual void setOwnerEntity(const EntityItemPointer ownerEntity) { _ownerEntity = ownerEntity; }
virtual bool updateArguments(QVariantMap arguments) { return false; }
// this is called from updateAction and should be overridden by subclasses
virtual void updateActionWorker(btCollisionWorld* collisionWorld, btScalar deltaTimeStep,
ObjectMotionState* motionState, btRigidBody* rigidBody) {}
// these are from btActionInterface
virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep);
virtual void debugDraw(btIDebugDraw* debugDrawer);

View file

@ -9,9 +9,6 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "ObjectMotionState.h"
#include "BulletUtil.h"
#include "ObjectActionPullToPoint.h"
ObjectActionPullToPoint::ObjectActionPullToPoint(QUuid id, EntityItemPointer ownerEntity) :
@ -27,33 +24,17 @@ ObjectActionPullToPoint::~ObjectActionPullToPoint() {
#endif
}
void ObjectActionPullToPoint::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) {
if (!_ownerEntity) {
qDebug() << "ObjectActionPullToPoint::updateAction no owner entity";
return;
void ObjectActionPullToPoint::updateActionWorker(btCollisionWorld* collisionWorld, btScalar deltaTimeStep,
ObjectMotionState* motionState, btRigidBody* rigidBody) {
glm::vec3 offset = _target - bulletToGLM(rigidBody->getCenterOfMassPosition());
float offsetLength = glm::length(offset);
if (offsetLength > IGNORE_POSITION_DELTA) {
glm::vec3 newVelocity = glm::normalize(offset) * _speed;
rigidBody->setLinearVelocity(glmToBullet(newVelocity));
rigidBody->activate();
} else {
rigidBody->setLinearVelocity(glmToBullet(glm::vec3()));
}
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 = _target - bulletToGLM(rigidBody->getCenterOfMassPosition());
float offsetLength = glm::length(offset);
if (offsetLength > IGNORE_POSITION_DELTA) {
glm::vec3 newVelocity = glm::normalize(offset) * _speed;
rigidBody->setLinearVelocity(glmToBullet(newVelocity));
rigidBody->activate();
} else {
rigidBody->setLinearVelocity(glmToBullet(glm::vec3()));
}
}
}
unlock();
}

View file

@ -23,7 +23,8 @@ public:
virtual ~ObjectActionPullToPoint();
virtual bool updateArguments(QVariantMap arguments);
virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep);
virtual void updateActionWorker(btCollisionWorld* collisionWorld, btScalar deltaTimeStep,
ObjectMotionState* motionState, btRigidBody* rigidBody);
private:

View file

@ -9,9 +9,6 @@
// 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) :
@ -27,69 +24,52 @@ ObjectActionSpring::~ObjectActionSpring() {
#endif
}
void ObjectActionSpring::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) {
if (!_ownerEntity) {
qDebug() << "ObjectActionSpring::updateAction no owner entity";
return;
}
if (!tryLockForRead()) {
// don't risk hanging the thread running the physics simulation
return;
}
void* physicsInfo = _ownerEntity->getPhysicsInfo();
void ObjectActionSpring::updateActionWorker(btCollisionWorld* collisionWorld, btScalar deltaTimeStep,
ObjectMotionState* motionState, btRigidBody* rigidBody) {
// handle the linear part
if (_positionalTargetSet) {
glm::vec3 offset = _positionalTarget - bulletToGLM(rigidBody->getCenterOfMassPosition());
float offsetLength = glm::length(offset);
float speed = offsetLength / _linearTimeScale;
if (_active && physicsInfo) {
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
btRigidBody* rigidBody = motionState->getRigidBody();
if (rigidBody) {
// 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()));
}
}
// handle rotation
if (_rotationalTargetSet) {
glm::quat bodyRotation = bulletToGLM(rigidBody->getOrientation());
// if qZero and qOne are too close to each other, we can get NaN for angle.
auto alignmentDot = glm::dot(bodyRotation, _rotationalTarget);
const float almostOne = 0.99999;
if (glm::abs(alignmentDot) < almostOne) {
glm::quat target = _rotationalTarget;
if (alignmentDot < 0) {
target = -target;
}
glm::quat qZeroInverse = glm::inverse(bodyRotation);
glm::quat deltaQ = target * qZeroInverse;
glm::vec3 axis = glm::axis(deltaQ);
float angle = glm::angle(deltaQ);
if (isNaN(angle)) {
qDebug() << "ObjectActionSpring::updateAction angle =" << angle
<< "body-rotation =" << bodyRotation.x << bodyRotation.y << bodyRotation.z << bodyRotation.w
<< "target-rotation ="
<< target.x << target.y << target.z<< target.w;
}
assert(!isNaN(angle));
glm::vec3 newAngularVelocity = (angle / _angularTimeScale) * glm::normalize(axis);
rigidBody->setAngularVelocity(glmToBullet(newAngularVelocity));
rigidBody->activate();
} else {
rigidBody->setAngularVelocity(glmToBullet(glm::vec3(0.0f)));
}
}
if (offsetLength > IGNORE_POSITION_DELTA) {
glm::vec3 newVelocity = glm::normalize(offset) * speed;
rigidBody->setLinearVelocity(glmToBullet(newVelocity));
rigidBody->activate();
} else {
rigidBody->setLinearVelocity(glmToBullet(glm::vec3(0.0f)));
}
}
// handle rotation
if (_rotationalTargetSet) {
glm::quat bodyRotation = bulletToGLM(rigidBody->getOrientation());
// if qZero and qOne are too close to each other, we can get NaN for angle.
auto alignmentDot = glm::dot(bodyRotation, _rotationalTarget);
const float almostOne = 0.99999;
if (glm::abs(alignmentDot) < almostOne) {
glm::quat target = _rotationalTarget;
if (alignmentDot < 0) {
target = -target;
}
glm::quat qZeroInverse = glm::inverse(bodyRotation);
glm::quat deltaQ = target * qZeroInverse;
glm::vec3 axis = glm::axis(deltaQ);
float angle = glm::angle(deltaQ);
if (isNaN(angle)) {
qDebug() << "ObjectActionSpring::updateAction angle =" << angle
<< "body-rotation =" << bodyRotation.x << bodyRotation.y << bodyRotation.z << bodyRotation.w
<< "target-rotation ="
<< target.x << target.y << target.z<< target.w;
}
assert(!isNaN(angle));
glm::vec3 newAngularVelocity = (angle / _angularTimeScale) * glm::normalize(axis);
rigidBody->setAngularVelocity(glmToBullet(newAngularVelocity));
rigidBody->activate();
} else {
rigidBody->setAngularVelocity(glmToBullet(glm::vec3(0.0f)));
}
}
unlock();
}

View file

@ -23,7 +23,8 @@ public:
virtual ~ObjectActionSpring();
virtual bool updateArguments(QVariantMap arguments);
virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep);
virtual void updateActionWorker(btCollisionWorld* collisionWorld, btScalar deltaTimeStep,
ObjectMotionState* motionState, btRigidBody* rigidBody);
private: