mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-22 11:29:17 +02:00
hold action works
This commit is contained in:
parent
1c0c7f0fe3
commit
eccf4eb8a8
8 changed files with 67 additions and 82 deletions
|
@ -15,7 +15,7 @@
|
||||||
#include "AvatarActionHold.h"
|
#include "AvatarActionHold.h"
|
||||||
|
|
||||||
AvatarActionHold::AvatarActionHold(QUuid id, EntityItemPointer ownerEntity) :
|
AvatarActionHold::AvatarActionHold(QUuid id, EntityItemPointer ownerEntity) :
|
||||||
ObjectAction(id, ownerEntity) {
|
ObjectActionSpring(id, ownerEntity) {
|
||||||
#if WANT_DEBUG
|
#if WANT_DEBUG
|
||||||
qDebug() << "AvatarActionHold::AvatarActionHold";
|
qDebug() << "AvatarActionHold::AvatarActionHold";
|
||||||
#endif
|
#endif
|
||||||
|
@ -28,83 +28,57 @@ AvatarActionHold::~AvatarActionHold() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
|
void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
|
||||||
// handle the linear part
|
|
||||||
if (_linearOffsetSet) {
|
|
||||||
}
|
|
||||||
|
|
||||||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
|
|
||||||
glm::vec3 palmPosition = myAvatar->getRightPalmPosition();
|
glm::vec3 palmPosition = myAvatar->getRightPalmPosition();
|
||||||
glm::vec3 position = getPosition();
|
|
||||||
glm::vec3 positionalTarget = palmPosition + _linearOffset;
|
|
||||||
glm::vec3 offset = positionalTarget - position;
|
|
||||||
|
|
||||||
float offsetLength = glm::length(offset);
|
auto rotation = myAvatar->getWorldAlignedOrientation();
|
||||||
float speed = offsetLength / _timeScale;
|
auto offset = rotation * _relativePosition;
|
||||||
|
auto position = palmPosition + offset;
|
||||||
|
rotation *= _relativeRotation;
|
||||||
|
|
||||||
if (offsetLength > IGNORE_POSITION_DELTA) {
|
lockForWrite();
|
||||||
glm::vec3 newVelocity = glm::normalize(offset) * speed;
|
_positionalTarget = position;
|
||||||
setLinearVelocity(newVelocity);
|
_rotationalTarget = rotation;
|
||||||
} else {
|
unlock();
|
||||||
setLinearVelocity(glm::vec3(0.0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ObjectActionSpring::updateActionWorker(deltaTimeStep);
|
||||||
// handle rotation
|
|
||||||
if (_angularOffsetSet) {
|
|
||||||
glm::quat bodyRotation = getRotation();
|
|
||||||
// if qZero and qOne are too close to each other, we can get NaN for angle.
|
|
||||||
auto alignmentDot = glm::dot(bodyRotation, _angularOffset);
|
|
||||||
const float almostOne = 0.99999;
|
|
||||||
if (glm::abs(alignmentDot) < almostOne) {
|
|
||||||
glm::quat target = _angularOffset;
|
|
||||||
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() << "AvatarActionHold::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 / _timeScale) * glm::normalize(axis);
|
|
||||||
setAngularVelocity(newAngularVelocity);
|
|
||||||
} else {
|
|
||||||
setAngularVelocity(glm::vec3(0.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool AvatarActionHold::updateArguments(QVariantMap arguments) {
|
bool AvatarActionHold::updateArguments(QVariantMap arguments) {
|
||||||
// targets are required, spring-constants are optional
|
bool rPOk = true;
|
||||||
bool ptOk = true;
|
glm::vec3 relativePosition =
|
||||||
glm::vec3 linearOffset =
|
EntityActionInterface::extractVec3Argument("hold", arguments, "relativePosition", rPOk, false);
|
||||||
EntityActionInterface::extractVec3Argument("spring action", arguments, "targetPosition", ptOk, false);
|
bool rROk = true;
|
||||||
|
glm::quat relativeRotation =
|
||||||
bool rtOk = true;
|
EntityActionInterface::extractQuatArgument("hold", arguments, "relativeRotation", rROk, false);
|
||||||
glm::quat angularOffset =
|
bool tSOk = true;
|
||||||
EntityActionInterface::extractQuatArgument("spring action", arguments, "targetRotation", rtOk, false);
|
float timeScale =
|
||||||
|
EntityActionInterface::extractFloatArgument("hold", arguments, "timeScale", tSOk, false);
|
||||||
|
|
||||||
lockForWrite();
|
lockForWrite();
|
||||||
|
if (rPOk) {
|
||||||
_linearOffsetSet = _angularOffsetSet = false;
|
_relativePosition = relativePosition;
|
||||||
|
} else {
|
||||||
if (ptOk) {
|
_relativePosition = glm::vec3(0.0f, 0.0f, 1.0f);
|
||||||
_linearOffset = linearOffset;
|
|
||||||
_linearOffsetSet = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtOk) {
|
if (rROk) {
|
||||||
_angularOffset = angularOffset;
|
_relativeRotation = relativeRotation;
|
||||||
_angularOffsetSet = true;
|
} else {
|
||||||
|
_relativeRotation = glm::quat(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tSOk) {
|
||||||
|
_linearTimeScale = timeScale;
|
||||||
|
_angularTimeScale = timeScale;
|
||||||
|
} else {
|
||||||
|
_linearTimeScale = 0.2;
|
||||||
|
_angularTimeScale = 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
_positionalTargetSet = true;
|
||||||
|
_rotationalTargetSet = true;
|
||||||
_active = true;
|
_active = true;
|
||||||
unlock();
|
unlock();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -15,9 +15,9 @@
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
|
|
||||||
#include <EntityItem.h>
|
#include <EntityItem.h>
|
||||||
#include <ObjectAction.h>
|
#include <ObjectActionSpring.h>
|
||||||
|
|
||||||
class AvatarActionHold : public ObjectAction {
|
class AvatarActionHold : public ObjectActionSpring {
|
||||||
public:
|
public:
|
||||||
AvatarActionHold(QUuid id, EntityItemPointer ownerEntity);
|
AvatarActionHold(QUuid id, EntityItemPointer ownerEntity);
|
||||||
virtual ~AvatarActionHold();
|
virtual ~AvatarActionHold();
|
||||||
|
@ -26,14 +26,8 @@ public:
|
||||||
virtual void updateActionWorker(float deltaTimeStep);
|
virtual void updateActionWorker(float deltaTimeStep);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
glm::vec3 _relativePosition;
|
||||||
glm::vec3 _linearOffset;
|
glm::quat _relativeRotation;
|
||||||
bool _linearOffsetSet;
|
|
||||||
|
|
||||||
glm::quat _angularOffset;
|
|
||||||
bool _angularOffsetSet;
|
|
||||||
|
|
||||||
float _timeScale = 0.01;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AvatarActionHold_h
|
#endif // hifi_AvatarActionHold_h
|
||||||
|
|
|
@ -25,6 +25,9 @@ EntityActionType EntityActionInterface::actionTypeFromString(QString actionTypeS
|
||||||
if (normalizedActionTypeString == "spring") {
|
if (normalizedActionTypeString == "spring") {
|
||||||
return ACTION_TYPE_SPRING;
|
return ACTION_TYPE_SPRING;
|
||||||
}
|
}
|
||||||
|
if (normalizedActionTypeString == "hold") {
|
||||||
|
return ACTION_TYPE_HOLD;
|
||||||
|
}
|
||||||
|
|
||||||
qDebug() << "Warning -- EntityActionInterface::actionTypeFromString got unknown action-type name" << actionTypeString;
|
qDebug() << "Warning -- EntityActionInterface::actionTypeFromString got unknown action-type name" << actionTypeString;
|
||||||
return ACTION_TYPE_NONE;
|
return ACTION_TYPE_NONE;
|
||||||
|
|
|
@ -31,14 +31,7 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta
|
||||||
qDebug() << "ObjectActionPullToPoint::updateAction no owner entity";
|
qDebug() << "ObjectActionPullToPoint::updateAction no owner entity";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!tryLockForRead()) {
|
|
||||||
// don't risk hanging the thread running the physics simulation
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateActionWorker(deltaTimeStep);
|
updateActionWorker(deltaTimeStep);
|
||||||
|
|
||||||
unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectAction::debugDraw(btIDebugDraw* debugDrawer) {
|
void ObjectAction::debugDraw(btIDebugDraw* debugDrawer) {
|
||||||
|
|
|
@ -47,7 +47,7 @@ private:
|
||||||
QReadWriteLock _lock;
|
QReadWriteLock _lock;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
btRigidBody* getRigidBody();
|
virtual btRigidBody* getRigidBody();
|
||||||
virtual glm::vec3 getPosition();
|
virtual glm::vec3 getPosition();
|
||||||
virtual void setPosition(glm::vec3 position);
|
virtual void setPosition(glm::vec3 position);
|
||||||
virtual glm::quat getRotation();
|
virtual glm::quat getRotation();
|
||||||
|
|
|
@ -25,13 +25,20 @@ ObjectActionPullToPoint::~ObjectActionPullToPoint() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectActionPullToPoint::updateActionWorker(btScalar deltaTimeStep) {
|
void ObjectActionPullToPoint::updateActionWorker(btScalar deltaTimeStep) {
|
||||||
|
if (!tryLockForRead()) {
|
||||||
|
// don't risk hanging the thread running the physics simulation
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void* physicsInfo = _ownerEntity->getPhysicsInfo();
|
void* physicsInfo = _ownerEntity->getPhysicsInfo();
|
||||||
if (!physicsInfo) {
|
if (!physicsInfo) {
|
||||||
|
unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
|
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
|
||||||
btRigidBody* rigidBody = motionState->getRigidBody();
|
btRigidBody* rigidBody = motionState->getRigidBody();
|
||||||
if (!rigidBody) {
|
if (!rigidBody) {
|
||||||
|
unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +51,8 @@ void ObjectActionPullToPoint::updateActionWorker(btScalar deltaTimeStep) {
|
||||||
} else {
|
} else {
|
||||||
rigidBody->setLinearVelocity(glmToBullet(glm::vec3()));
|
rigidBody->setLinearVelocity(glmToBullet(glm::vec3()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,13 +25,23 @@ ObjectActionSpring::~ObjectActionSpring() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) {
|
void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) {
|
||||||
|
if (!tryLockForRead()) {
|
||||||
|
// don't risk hanging the thread running the physics simulation
|
||||||
|
qDebug() << "ObjectActionSpring::updateActionWorker lock failed";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void* physicsInfo = _ownerEntity->getPhysicsInfo();
|
void* physicsInfo = _ownerEntity->getPhysicsInfo();
|
||||||
if (!physicsInfo) {
|
if (!physicsInfo) {
|
||||||
|
unlock();
|
||||||
|
qDebug() << "ObjectActionSpring::updateActionWorker no physicsInfo";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
|
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
|
||||||
btRigidBody* rigidBody = motionState->getRigidBody();
|
btRigidBody* rigidBody = motionState->getRigidBody();
|
||||||
if (!rigidBody) {
|
if (!rigidBody) {
|
||||||
|
unlock();
|
||||||
|
qDebug() << "ObjectActionSpring::updateActionWorker no rigidBody";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +89,8 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) {
|
||||||
rigidBody->setAngularVelocity(glmToBullet(glm::vec3(0.0f)));
|
rigidBody->setAngularVelocity(glmToBullet(glm::vec3(0.0f)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
virtual bool updateArguments(QVariantMap arguments);
|
virtual bool updateArguments(QVariantMap arguments);
|
||||||
virtual void updateActionWorker(float deltaTimeStep);
|
virtual void updateActionWorker(float deltaTimeStep);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
|
|
||||||
glm::vec3 _positionalTarget;
|
glm::vec3 _positionalTarget;
|
||||||
float _linearTimeScale;
|
float _linearTimeScale;
|
||||||
|
|
Loading…
Reference in a new issue