mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-09 00:02:21 +02:00
try having all spring derived actions agree on a target
This commit is contained in:
parent
5a86640526
commit
44beca1687
5 changed files with 112 additions and 78 deletions
|
@ -93,13 +93,13 @@ void AvatarActionHold::prepareForPhysicsSimulation() {
|
|||
activateBody(true);
|
||||
}
|
||||
|
||||
std::shared_ptr<Avatar> AvatarActionHold::getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
||||
glm::vec3& linearVelocity, glm::vec3& angularVelocity) {
|
||||
bool AvatarActionHold::getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
||||
glm::vec3& linearVelocity, glm::vec3& angularVelocity) {
|
||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||
auto holdingAvatar = std::static_pointer_cast<Avatar>(avatarManager->getAvatarBySessionID(_holderID));
|
||||
|
||||
if (!holdingAvatar) {
|
||||
return holdingAvatar;
|
||||
return false;;
|
||||
}
|
||||
|
||||
withReadLock([&]{
|
||||
|
@ -171,62 +171,17 @@ std::shared_ptr<Avatar> AvatarActionHold::getTarget(float deltaTimeStep, glm::qu
|
|||
linearVelocity = linearVelocity + glm::cross(angularVelocity, position - palmPosition);
|
||||
});
|
||||
|
||||
return holdingAvatar;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
|
||||
glm::quat rotation;
|
||||
glm::vec3 position;
|
||||
glm::vec3 linearVelocity;
|
||||
glm::vec3 angularVelocity;
|
||||
bool valid = false;
|
||||
int holdCount = 0;
|
||||
|
||||
auto ownerEntity = _ownerEntity.lock();
|
||||
if (!ownerEntity) {
|
||||
return;
|
||||
}
|
||||
QList<EntityActionPointer> holdActions = ownerEntity->getActionsOfType(ACTION_TYPE_HOLD);
|
||||
foreach (EntityActionPointer action, holdActions) {
|
||||
std::shared_ptr<AvatarActionHold> holdAction = std::static_pointer_cast<AvatarActionHold>(action);
|
||||
glm::quat rotationForAction;
|
||||
glm::vec3 positionForAction;
|
||||
glm::vec3 linearVelocityForAction, angularVelocityForAction;
|
||||
std::shared_ptr<Avatar> holdingAvatar = holdAction->getTarget(deltaTimeStep, rotationForAction, positionForAction, linearVelocityForAction, angularVelocityForAction);
|
||||
if (holdingAvatar) {
|
||||
holdCount ++;
|
||||
if (holdAction.get() == this) {
|
||||
// only use the rotation for this action
|
||||
valid = true;
|
||||
rotation = rotationForAction;
|
||||
}
|
||||
|
||||
position += positionForAction;
|
||||
linearVelocity += linearVelocityForAction;
|
||||
angularVelocity += angularVelocityForAction;
|
||||
}
|
||||
}
|
||||
|
||||
if (valid && holdCount > 0) {
|
||||
position /= holdCount;
|
||||
linearVelocity /= holdCount;
|
||||
angularVelocity /= holdCount;
|
||||
|
||||
withWriteLock([&]{
|
||||
_positionalTarget = position;
|
||||
_rotationalTarget = rotation;
|
||||
_linearVelocityTarget = linearVelocity;
|
||||
_angularVelocityTarget = angularVelocity;
|
||||
_positionalTargetSet = true;
|
||||
_rotationalTargetSet = true;
|
||||
_active = true;
|
||||
});
|
||||
if (_kinematic) {
|
||||
if (_kinematic) {
|
||||
if (prepareForSpringUpdate(deltaTimeStep)) {
|
||||
doKinematicUpdate(deltaTimeStep);
|
||||
} else {
|
||||
forceBodyNonStatic();
|
||||
ObjectActionSpring::updateActionWorker(deltaTimeStep);
|
||||
}
|
||||
} else {
|
||||
forceBodyNonStatic();
|
||||
ObjectActionSpring::updateActionWorker(deltaTimeStep);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@ public:
|
|||
virtual bool shouldSuppressLocationEdits() override { return _active && !_ownerEntity.expired(); }
|
||||
|
||||
bool getAvatarRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation);
|
||||
std::shared_ptr<Avatar> getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
||||
glm::vec3& linearVelocity, glm::vec3& angularVelocity);
|
||||
virtual bool getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
||||
glm::vec3& linearVelocity, glm::vec3& angularVelocity) override;
|
||||
|
||||
virtual void prepareForPhysicsSimulation() override;
|
||||
|
||||
|
@ -51,9 +51,6 @@ private:
|
|||
QString _hand { "right" };
|
||||
QUuid _holderID;
|
||||
|
||||
glm::vec3 _linearVelocityTarget;
|
||||
glm::vec3 _angularVelocityTarget;
|
||||
|
||||
bool _kinematic { false };
|
||||
bool _kinematicSetVelocity { false };
|
||||
bool _previousSet { false };
|
||||
|
|
|
@ -21,9 +21,11 @@ const uint16_t ObjectActionSpring::springVersion = 1;
|
|||
ObjectActionSpring::ObjectActionSpring(const QUuid& id, EntityItemPointer ownerEntity) :
|
||||
ObjectAction(ACTION_TYPE_SPRING, id, ownerEntity),
|
||||
_positionalTarget(glm::vec3(0.0f)),
|
||||
_desiredPositionalTarget(glm::vec3(0.0f)),
|
||||
_linearTimeScale(FLT_MAX),
|
||||
_positionalTargetSet(true),
|
||||
_rotationalTarget(glm::quat()),
|
||||
_desiredRotationalTarget(glm::quat()),
|
||||
_angularTimeScale(FLT_MAX),
|
||||
_rotationalTargetSet(true) {
|
||||
#if WANT_DEBUG
|
||||
|
@ -37,9 +39,82 @@ ObjectActionSpring::~ObjectActionSpring() {
|
|||
#endif
|
||||
}
|
||||
|
||||
bool ObjectActionSpring::getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
||||
glm::vec3& linearVelocity, glm::vec3& angularVelocity) {
|
||||
rotation = _desiredRotationalTarget;
|
||||
position = _desiredPositionalTarget;
|
||||
linearVelocity = glm::vec3();
|
||||
angularVelocity = glm::vec3();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ObjectActionSpring::prepareForSpringUpdate(btScalar deltaTimeStep) {
|
||||
glm::quat rotation;
|
||||
glm::vec3 position;
|
||||
glm::vec3 linearVelocity;
|
||||
glm::vec3 angularVelocity;
|
||||
|
||||
bool valid = false;
|
||||
int springCount = 0;
|
||||
|
||||
auto ownerEntity = _ownerEntity.lock();
|
||||
if (!ownerEntity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QList<EntityActionPointer> springDerivedActions;
|
||||
springDerivedActions.append(ownerEntity->getActionsOfType(ACTION_TYPE_SPRING));
|
||||
springDerivedActions.append(ownerEntity->getActionsOfType(ACTION_TYPE_HOLD));
|
||||
|
||||
foreach (EntityActionPointer action, springDerivedActions) {
|
||||
std::shared_ptr<ObjectActionSpring> springAction = std::static_pointer_cast<ObjectActionSpring>(action);
|
||||
glm::quat rotationForAction;
|
||||
glm::vec3 positionForAction;
|
||||
glm::vec3 linearVelocityForAction, angularVelocityForAction;
|
||||
bool success = springAction->getTarget(deltaTimeStep, rotationForAction,
|
||||
positionForAction, linearVelocityForAction,
|
||||
angularVelocityForAction);
|
||||
if (success) {
|
||||
springCount ++;
|
||||
if (springAction.get() == this) {
|
||||
// only use the rotation for this action
|
||||
valid = true;
|
||||
rotation = rotationForAction;
|
||||
}
|
||||
|
||||
position += positionForAction;
|
||||
linearVelocity += linearVelocityForAction;
|
||||
angularVelocity += angularVelocityForAction;
|
||||
}
|
||||
}
|
||||
|
||||
if (valid && springCount > 0) {
|
||||
position /= springCount;
|
||||
linearVelocity /= springCount;
|
||||
angularVelocity /= springCount;
|
||||
|
||||
withWriteLock([&]{
|
||||
_positionalTarget = position;
|
||||
_rotationalTarget = rotation;
|
||||
_linearVelocityTarget = linearVelocity;
|
||||
_angularVelocityTarget = angularVelocity;
|
||||
_positionalTargetSet = true;
|
||||
_rotationalTargetSet = true;
|
||||
_active = true;
|
||||
});
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
||||
void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) {
|
||||
// don't risk hanging the thread running the physics simulation
|
||||
auto lockResult = withTryReadLock([&]{
|
||||
if (!prepareForSpringUpdate(deltaTimeStep)) {
|
||||
return;
|
||||
}
|
||||
|
||||
withReadLock([&]{
|
||||
auto ownerEntity = _ownerEntity.lock();
|
||||
if (!ownerEntity) {
|
||||
return;
|
||||
|
@ -101,9 +176,6 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) {
|
|||
rigidBody->setAngularVelocity(targetVelocity);
|
||||
}
|
||||
});
|
||||
if (!lockResult) {
|
||||
qDebug() << "ObjectActionSpring::updateActionWorker lock failed";
|
||||
}
|
||||
}
|
||||
|
||||
const float MIN_TIMESCALE = 0.1f;
|
||||
|
@ -122,7 +194,7 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) {
|
|||
bool ok = true;
|
||||
positionalTarget = EntityActionInterface::extractVec3Argument("spring action", arguments, "targetPosition", ok, false);
|
||||
if (!ok) {
|
||||
positionalTarget = _positionalTarget;
|
||||
positionalTarget = _desiredPositionalTarget;
|
||||
}
|
||||
ok = true;
|
||||
linearTimeScale = EntityActionInterface::extractFloatArgument("spring action", arguments, "linearTimeScale", ok, false);
|
||||
|
@ -133,7 +205,7 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) {
|
|||
ok = true;
|
||||
rotationalTarget = EntityActionInterface::extractQuatArgument("spring action", arguments, "targetRotation", ok, false);
|
||||
if (!ok) {
|
||||
rotationalTarget = _rotationalTarget;
|
||||
rotationalTarget = _desiredRotationalTarget;
|
||||
}
|
||||
|
||||
ok = true;
|
||||
|
@ -144,9 +216,9 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) {
|
|||
}
|
||||
|
||||
if (somethingChanged ||
|
||||
positionalTarget != _positionalTarget ||
|
||||
positionalTarget != _desiredPositionalTarget ||
|
||||
linearTimeScale != _linearTimeScale ||
|
||||
rotationalTarget != _rotationalTarget ||
|
||||
rotationalTarget != _desiredRotationalTarget ||
|
||||
angularTimeScale != _angularTimeScale) {
|
||||
// something changed
|
||||
needUpdate = true;
|
||||
|
@ -155,9 +227,9 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) {
|
|||
|
||||
if (needUpdate) {
|
||||
withWriteLock([&] {
|
||||
_positionalTarget = positionalTarget;
|
||||
_desiredPositionalTarget = positionalTarget;
|
||||
_linearTimeScale = glm::max(MIN_TIMESCALE, glm::abs(linearTimeScale));
|
||||
_rotationalTarget = rotationalTarget;
|
||||
_desiredRotationalTarget = rotationalTarget;
|
||||
_angularTimeScale = glm::max(MIN_TIMESCALE, glm::abs(angularTimeScale));
|
||||
_active = true;
|
||||
|
||||
|
@ -177,9 +249,9 @@ QVariantMap ObjectActionSpring::getArguments() {
|
|||
QVariantMap arguments = ObjectAction::getArguments();
|
||||
withReadLock([&] {
|
||||
arguments["linearTimeScale"] = _linearTimeScale;
|
||||
arguments["targetPosition"] = glmToQMap(_positionalTarget);
|
||||
arguments["targetPosition"] = glmToQMap(_desiredPositionalTarget);
|
||||
|
||||
arguments["targetRotation"] = glmToQMap(_rotationalTarget);
|
||||
arguments["targetRotation"] = glmToQMap(_desiredRotationalTarget);
|
||||
arguments["angularTimeScale"] = _angularTimeScale;
|
||||
});
|
||||
return arguments;
|
||||
|
@ -194,10 +266,10 @@ QByteArray ObjectActionSpring::serialize() const {
|
|||
dataStream << ObjectActionSpring::springVersion;
|
||||
|
||||
withReadLock([&] {
|
||||
dataStream << _positionalTarget;
|
||||
dataStream << _desiredPositionalTarget;
|
||||
dataStream << _linearTimeScale;
|
||||
dataStream << _positionalTargetSet;
|
||||
dataStream << _rotationalTarget;
|
||||
dataStream << _desiredRotationalTarget;
|
||||
dataStream << _angularTimeScale;
|
||||
dataStream << _rotationalTargetSet;
|
||||
dataStream << localTimeToServerTime(_expires);
|
||||
|
@ -226,11 +298,11 @@ void ObjectActionSpring::deserialize(QByteArray serializedArguments) {
|
|||
}
|
||||
|
||||
withWriteLock([&] {
|
||||
dataStream >> _positionalTarget;
|
||||
dataStream >> _desiredPositionalTarget;
|
||||
dataStream >> _linearTimeScale;
|
||||
dataStream >> _positionalTargetSet;
|
||||
|
||||
dataStream >> _rotationalTarget;
|
||||
dataStream >> _desiredRotationalTarget;
|
||||
dataStream >> _angularTimeScale;
|
||||
dataStream >> _rotationalTargetSet;
|
||||
|
||||
|
|
|
@ -27,16 +27,26 @@ public:
|
|||
virtual QByteArray serialize() const override;
|
||||
virtual void deserialize(QByteArray serializedArguments) override;
|
||||
|
||||
virtual bool getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position,
|
||||
glm::vec3& linearVelocity, glm::vec3& angularVelocity);
|
||||
|
||||
protected:
|
||||
static const uint16_t springVersion;
|
||||
|
||||
glm::vec3 _positionalTarget;
|
||||
glm::vec3 _desiredPositionalTarget;
|
||||
float _linearTimeScale;
|
||||
bool _positionalTargetSet;
|
||||
|
||||
glm::quat _rotationalTarget;
|
||||
glm::quat _desiredRotationalTarget;
|
||||
float _angularTimeScale;
|
||||
bool _rotationalTargetSet;
|
||||
|
||||
glm::vec3 _linearVelocityTarget;
|
||||
glm::vec3 _angularVelocityTarget;
|
||||
|
||||
virtual bool ObjectActionSpring::prepareForSpringUpdate(btScalar deltaTimeStep);
|
||||
};
|
||||
|
||||
#endif // hifi_ObjectActionSpring_h
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */
|
||||
|
||||
Script.include("../libraries/utils.js");
|
||||
Script.include("/~/system/libraries/utils.js");
|
||||
|
||||
|
||||
//
|
||||
|
@ -28,7 +28,7 @@ var WANT_DEBUG_SEARCH_NAME = null;
|
|||
|
||||
var TRIGGER_SMOOTH_RATIO = 0.1; // Time averaging of trigger - 0.0 disables smoothing
|
||||
var TRIGGER_ON_VALUE = 0.4; // Squeezed just enough to activate search or near grab
|
||||
var TRIGGER_GRAB_VALUE = 0.85; // Squeezed far enough to complete distant grab
|
||||
var TRIGGER_GRAB_VALUE = 0.75; // Squeezed far enough to complete distant grab
|
||||
var TRIGGER_OFF_VALUE = 0.15;
|
||||
|
||||
var BUMPER_ON_VALUE = 0.5;
|
||||
|
|
Loading…
Reference in a new issue