git rid if pull-to-point action (spring handles this). add new action which tries to maintain an entity's distance from a given point

This commit is contained in:
Seth Alves 2015-06-17 11:22:10 -07:00
parent 0ef75da5d5
commit 85564199c6
10 changed files with 164 additions and 116 deletions

View file

@ -12,7 +12,7 @@
#include <avatar/AvatarActionHold.h>
#include <ObjectActionPullToPoint.h>
#include <ObjectActionOffset.h>
#include <ObjectActionSpring.h>
#include "InterfaceActionFactory.h"
@ -27,8 +27,8 @@ EntityActionPointer InterfaceActionFactory::factory(EntitySimulation* simulation
switch (type) {
case ACTION_TYPE_NONE:
return nullptr;
case ACTION_TYPE_PULL_TO_POINT:
action = (EntityActionPointer) new ObjectActionPullToPoint(id, ownerEntity);
case ACTION_TYPE_OFFSET:
action = (EntityActionPointer) new ObjectActionOffset(id, ownerEntity);
break;
case ACTION_TYPE_SPRING:
action = (EntityActionPointer) new ObjectActionSpring(id, ownerEntity);

View file

@ -29,6 +29,12 @@ AvatarActionHold::~AvatarActionHold() {
void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
if (!tryLockForRead()) {
// don't risk hanging the thread running the physics simulation
return;
}
glm::vec3 palmPosition;
if (_hand == "right") {
palmPosition = myAvatar->getRightPalmPosition();
@ -40,8 +46,11 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
auto offset = rotation * _relativePosition;
auto position = palmPosition + offset;
rotation *= _relativeRotation;
unlock();
lockForWrite();
if (!tryLockForWrite()) {
return;
}
_positionalTarget = position;
_rotationalTarget = rotation;
unlock();

View file

@ -19,8 +19,8 @@ EntityActionType EntityActionInterface::actionTypeFromString(QString actionTypeS
if (normalizedActionTypeString == "none") {
return ACTION_TYPE_NONE;
}
if (normalizedActionTypeString == "pulltopoint") {
return ACTION_TYPE_PULL_TO_POINT;
if (normalizedActionTypeString == "offset") {
return ACTION_TYPE_OFFSET;
}
if (normalizedActionTypeString == "spring") {
return ACTION_TYPE_SPRING;
@ -37,8 +37,8 @@ QString EntityActionInterface::actionTypeToString(EntityActionType actionType) {
switch(actionType) {
case ACTION_TYPE_NONE:
return "none";
case ACTION_TYPE_PULL_TO_POINT:
return "pullToPoint";
case ACTION_TYPE_OFFSET:
return "offset";
case ACTION_TYPE_SPRING:
return "spring";
case ACTION_TYPE_HOLD:

View file

@ -21,7 +21,7 @@ class EntitySimulation;
enum EntityActionType {
// keep these synchronized with actionTypeFromString and actionTypeToString
ACTION_TYPE_NONE,
ACTION_TYPE_PULL_TO_POINT,
ACTION_TYPE_OFFSET,
ACTION_TYPE_SPRING,
ACTION_TYPE_HOLD
};

View file

@ -28,7 +28,7 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta
return;
}
if (!_ownerEntity) {
qDebug() << "ObjectActionPullToPoint::updateAction no owner entity";
qDebug() << "ObjectAction::updateAction no owner entity";
return;
}
updateActionWorker(deltaTimeStep);

View file

@ -59,6 +59,7 @@ protected:
bool tryLockForRead() { return _lock.tryLockForRead(); }
void lockForWrite() { _lock.lockForWrite(); }
bool tryLockForWrite() { return _lock.tryLockForWrite(); }
void unlock() { _lock.unlock(); }
bool _active;

View file

@ -0,0 +1,109 @@
//
// ObjectActionOffset.cpp
// libraries/physics/src
//
// Created by Seth Alves 2015-6-17
// 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 "ObjectActionOffset.h"
ObjectActionOffset::ObjectActionOffset(QUuid id, EntityItemPointer ownerEntity) :
ObjectAction(id, ownerEntity) {
#if WANT_DEBUG
qDebug() << "ObjectActionOffset::ObjectActionOffset";
#endif
}
ObjectActionOffset::~ObjectActionOffset() {
#if WANT_DEBUG
qDebug() << "ObjectActionOffset::~ObjectActionOffset";
#endif
}
void ObjectActionOffset::updateActionWorker(btScalar deltaTimeStep) {
if (!tryLockForRead()) {
// don't risk hanging the thread running the physics simulation
return;
}
void* physicsInfo = _ownerEntity->getPhysicsInfo();
if (!physicsInfo) {
unlock();
return;
}
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
btRigidBody* rigidBody = motionState->getRigidBody();
if (!rigidBody) {
unlock();
qDebug() << "ObjectActionOffset::updateActionWorker no rigidBody";
return;
}
if (_positionalTargetSet) {
glm::vec3 offset = _pointToOffsetFrom - bulletToGLM(rigidBody->getCenterOfMassPosition());
float offsetLength = glm::length(offset);
float offsetError = _linearDistance - offsetLength;
// if (glm::abs(offsetError) > IGNORE_POSITION_DELTA) {
if (glm::abs(offsetError) > 0.0f) {
float offsetErrorAbs = glm::abs(offsetError);
float offsetErrorDirection = - offsetError / offsetErrorAbs;
glm::vec3 previousVelocity = bulletToGLM(rigidBody->getLinearVelocity());
glm::vec3 velocityAdjustment = glm::normalize(offset) * offsetErrorDirection * offsetErrorAbs / _linearTimeScale;
rigidBody->setLinearVelocity(glmToBullet(previousVelocity + velocityAdjustment));
// rigidBody->setLinearVelocity(glmToBullet(velocityAdjustment));
rigidBody->activate();
}
}
unlock();
}
bool ObjectActionOffset::updateArguments(QVariantMap arguments) {
bool pOk0 = true;
glm::vec3 pointToOffsetFrom =
EntityActionInterface::extractVec3Argument("offset action", arguments, "pointToOffsetFrom", pOk0, true);
bool pOk1 = true;
float linearTimeScale =
EntityActionInterface::extractFloatArgument("offset action", arguments, "linearTimeScale", pOk1, false);
bool pOk2 = true;
float linearDistance =
EntityActionInterface::extractFloatArgument("offset action", arguments, "linearDistance", pOk2, false);
if (!pOk0) {
return false;
}
if (pOk1 && linearTimeScale <= 0.0f) {
qDebug() << "offset action -- linearTimeScale must be greater than zero.";
return false;
}
lockForWrite();
_pointToOffsetFrom = pointToOffsetFrom;
_positionalTargetSet = true;
if (pOk1) {
_linearTimeScale = linearTimeScale;
} else {
_linearTimeScale = 0.1f;
}
if (pOk2) {
_linearDistance = linearDistance;
} else {
_linearDistance = 1.0f;
}
_active = true;
unlock();
return true;
}

View file

@ -0,0 +1,35 @@
//
// ObjectActionOffset.h
// libraries/physics/src
//
// Created by Seth Alves 2015-6-17
// 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_ObjectActionOffset_h
#define hifi_ObjectActionOffset_h
#include <QUuid>
#include <EntityItem.h>
#include "ObjectAction.h"
class ObjectActionOffset : public ObjectAction {
public:
ObjectActionOffset(QUuid id, EntityItemPointer ownerEntity);
virtual ~ObjectActionOffset();
virtual bool updateArguments(QVariantMap arguments);
virtual void updateActionWorker(float deltaTimeStep);
private:
glm::vec3 _pointToOffsetFrom;
float _linearDistance;
float _linearTimeScale;
bool _positionalTargetSet;
};
#endif // hifi_ObjectActionOffset_h

View file

@ -1,72 +0,0 @@
//
// ObjectActionPullToPoint.cpp
// libraries/physics/src
//
// Created by Seth Alves 2015-6-2
// 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 "ObjectActionPullToPoint.h"
ObjectActionPullToPoint::ObjectActionPullToPoint(QUuid id, EntityItemPointer ownerEntity) :
ObjectAction(id, ownerEntity) {
#if WANT_DEBUG
qDebug() << "ObjectActionPullToPoint::ObjectActionPullToPoint";
#endif
}
ObjectActionPullToPoint::~ObjectActionPullToPoint() {
#if WANT_DEBUG
qDebug() << "ObjectActionPullToPoint::~ObjectActionPullToPoint";
#endif
}
void ObjectActionPullToPoint::updateActionWorker(btScalar deltaTimeStep) {
if (!tryLockForRead()) {
// don't risk hanging the thread running the physics simulation
return;
}
void* physicsInfo = _ownerEntity->getPhysicsInfo();
if (!physicsInfo) {
unlock();
return;
}
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
btRigidBody* rigidBody = motionState->getRigidBody();
if (!rigidBody) {
unlock();
return;
}
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();
}
bool ObjectActionPullToPoint::updateArguments(QVariantMap arguments) {
bool ok = true;
glm::vec3 target = EntityActionInterface::extractVec3Argument("pull-to-point action", arguments, "target", ok);
float speed = EntityActionInterface::extractFloatArgument("pull-to-point action", arguments, "speed", ok);
if (ok) {
lockForWrite();
_target = target;
_speed = speed;
_active = true;
unlock();
return true;
}
return false;
}

View file

@ -1,34 +0,0 @@
//
// ObjectActionPullToPoint.h
// libraries/physics/src
//
// Created by Seth Alves 2015-6-3
// 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_ObjectActionPullToPoint_h
#define hifi_ObjectActionPullToPoint_h
#include <QUuid>
#include <EntityItem.h>
#include "ObjectAction.h"
class ObjectActionPullToPoint : public ObjectAction {
public:
ObjectActionPullToPoint(QUuid id, EntityItemPointer ownerEntity);
virtual ~ObjectActionPullToPoint();
virtual bool updateArguments(QVariantMap arguments);
virtual void updateActionWorker(float deltaTimeStep);
private:
glm::vec3 _target;
float _speed;
};
#endif // hifi_ObjectActionPullToPoint_h