mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 17:14:59 +02:00
fix update logic of ObjectActionOffset
This commit is contained in:
parent
46bca30698
commit
612e9649d8
2 changed files with 61 additions and 44 deletions
|
@ -16,7 +16,11 @@
|
|||
const uint16_t ObjectActionOffset::offsetVersion = 1;
|
||||
|
||||
ObjectActionOffset::ObjectActionOffset(const QUuid& id, EntityItemPointer ownerEntity) :
|
||||
ObjectAction(ACTION_TYPE_OFFSET, id, ownerEntity) {
|
||||
ObjectAction(ACTION_TYPE_OFFSET, id, ownerEntity),
|
||||
_pointToOffsetFrom(0.f),
|
||||
_linearDistance(0.0f),
|
||||
_linearTimeScale(FLT_MAX),
|
||||
_positionalTargetSet(false) {
|
||||
#if WANT_DEBUG
|
||||
qDebug() << "ObjectActionOffset::ObjectActionOffset";
|
||||
#endif
|
||||
|
@ -44,6 +48,7 @@ void ObjectActionOffset::updateActionWorker(btScalar deltaTimeStep) {
|
|||
unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
|
||||
btRigidBody* rigidBody = motionState->getRigidBody();
|
||||
if (!rigidBody) {
|
||||
|
@ -52,21 +57,32 @@ void ObjectActionOffset::updateActionWorker(btScalar deltaTimeStep) {
|
|||
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));
|
||||
const float MAX_LINEAR_TIMESCALE = 600.0f; // 10 minutes is a long time
|
||||
if (_positionalTargetSet && _linearTimeScale < MAX_LINEAR_TIMESCALE) {
|
||||
if (_needsActivation) {
|
||||
rigidBody->activate();
|
||||
_needsActivation = false;
|
||||
}
|
||||
glm::vec3 objectPosition = bulletToGLM(rigidBody->getCenterOfMassPosition());
|
||||
glm::vec3 springAxis = objectPosition - _pointToOffsetFrom; // from anchor to object
|
||||
float distance = glm::length(springAxis);
|
||||
if (distance > FLT_EPSILON) {
|
||||
springAxis /= distance; // normalize springAxis
|
||||
|
||||
// compute (critically damped) target velocity of spring relaxation
|
||||
glm::vec3 offset = (distance - _linearDistance) * springAxis;
|
||||
glm::vec3 targetVelocity = (-1.0f / _linearTimeScale) * offset;
|
||||
|
||||
// compute current velocity and its parallel component
|
||||
glm::vec3 currentVelocity = bulletToGLM(rigidBody->getLinearVelocity());
|
||||
glm::vec3 parallelVelocity = glm::dot(currentVelocity, springAxis) * springAxis;
|
||||
|
||||
// we blend the parallel component with the spring's target velocity to get the new velocity
|
||||
float blend = deltaTimeStep / _linearTimeScale;
|
||||
if (blend > 1.0f) {
|
||||
blend = 1.0f;
|
||||
}
|
||||
rigidBody->setLinearVelocity(glmToBullet(currentVelocity + blend * (targetVelocity - parallelVelocity));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,45 +91,45 @@ void ObjectActionOffset::updateActionWorker(btScalar deltaTimeStep) {
|
|||
|
||||
|
||||
bool ObjectActionOffset::updateArguments(QVariantMap arguments) {
|
||||
bool pOk0 = true;
|
||||
bool ok = true;
|
||||
glm::vec3 pointToOffsetFrom =
|
||||
EntityActionInterface::extractVec3Argument("offset action", arguments, "pointToOffsetFrom", pOk0, true);
|
||||
EntityActionInterface::extractVec3Argument("offset action", arguments, "pointToOffsetFrom", ok, true);
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool pOk1 = true;
|
||||
ok = true;
|
||||
float linearTimeScale =
|
||||
EntityActionInterface::extractFloatArgument("offset action", arguments, "linearTimeScale", pOk1, false);
|
||||
EntityActionInterface::extractFloatArgument("offset action", arguments, "linearTimeScale", ok, false);
|
||||
if (ok) {
|
||||
if (linearTimeScale <= 0.0f) {
|
||||
qDebug() << "offset action -- linearTimeScale must be greater than zero.";
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
linearTimeScale = 0.1f;
|
||||
}
|
||||
|
||||
bool pOk2 = true;
|
||||
ok = 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;
|
||||
EntityActionInterface::extractFloatArgument("offset action", arguments, "linearDistance", ok, false);
|
||||
if (!ok) {
|
||||
linearDistance = 0.0f;
|
||||
}
|
||||
|
||||
lockForWrite();
|
||||
|
||||
_pointToOffsetFrom = pointToOffsetFrom;
|
||||
_positionalTargetSet = true;
|
||||
|
||||
if (pOk1) {
|
||||
// only change stuff if something actually changed
|
||||
if (_pointToOffsetFrom != pointToOffsetFrom
|
||||
|| _linearTimeScale != linearTimeScale
|
||||
|| _linearDistance != linearDistance) {
|
||||
lockForWrite();
|
||||
_pointToOffsetFrom = pointToOffsetFrom;
|
||||
_linearTimeScale = linearTimeScale;
|
||||
} else {
|
||||
_linearTimeScale = 0.1f;
|
||||
}
|
||||
|
||||
if (pOk2) {
|
||||
_linearDistance = linearDistance;
|
||||
} else {
|
||||
_linearDistance = 1.0f;
|
||||
_positionalTargetSet = true;
|
||||
_active = true;
|
||||
_needsActivation = true;
|
||||
unlock();
|
||||
}
|
||||
|
||||
_active = true;
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ public:
|
|||
float _linearDistance;
|
||||
float _linearTimeScale;
|
||||
bool _positionalTargetSet;
|
||||
bool _needsActivation = true;
|
||||
};
|
||||
|
||||
#endif // hifi_ObjectActionOffset_h
|
||||
|
|
Loading…
Reference in a new issue