mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 16:36:54 +02:00
call a method on actions before each physics simulation step. use this to attempt to dejitter held objects
This commit is contained in:
parent
a422103e89
commit
d3c57821c0
11 changed files with 134 additions and 33 deletions
|
@ -2989,6 +2989,9 @@ void Application::update(float deltaTime) {
|
||||||
_physicsEngine->changeObjects(motionStates);
|
_physicsEngine->changeObjects(motionStates);
|
||||||
|
|
||||||
myAvatar->prepareForPhysicsSimulation();
|
myAvatar->prepareForPhysicsSimulation();
|
||||||
|
_physicsEngine->forEachAction([&](EntityActionPointer action) {
|
||||||
|
action->prepareForPhysicsSimulation();
|
||||||
|
});
|
||||||
|
|
||||||
getEntities()->getTree()->withWriteLock([&] {
|
getEntities()->getTree()->withWriteLock([&] {
|
||||||
_physicsEngine->stepSimulation();
|
_physicsEngine->stepSimulation();
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <QVariantGLM.h>
|
#include <QVariantGLM.h>
|
||||||
|
|
||||||
#include "avatar/AvatarManager.h"
|
#include "avatar/AvatarManager.h"
|
||||||
|
#include "CharacterController.h"
|
||||||
|
|
||||||
const uint16_t AvatarActionHold::holdVersion = 1;
|
const uint16_t AvatarActionHold::holdVersion = 1;
|
||||||
|
|
||||||
|
@ -32,6 +33,57 @@ AvatarActionHold::~AvatarActionHold() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AvatarActionHold::prepareForPhysicsSimulation() {
|
||||||
|
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||||
|
auto holdingAvatar = std::static_pointer_cast<Avatar>(avatarManager->getAvatarBySessionID(_holderID));
|
||||||
|
|
||||||
|
if (!holdingAvatar) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
withTryReadLock([&]{
|
||||||
|
bool isRightHand = (_hand == "right");
|
||||||
|
|
||||||
|
if (_ignoreIK && holdingAvatar->isMyAvatar()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (holdingAvatar->isMyAvatar()) {
|
||||||
|
glm::vec3 palmPosition { Vectors::ZERO };
|
||||||
|
glm::quat palmRotation { Quaternions::IDENTITY };
|
||||||
|
if (isRightHand) {
|
||||||
|
palmPosition = holdingAvatar->getHand()->getCopyOfPalmData(HandData::RightHand).getPosition();
|
||||||
|
palmRotation = holdingAvatar->getHand()->getCopyOfPalmData(HandData::RightHand).getRotation();
|
||||||
|
} else {
|
||||||
|
palmPosition = holdingAvatar->getHand()->getCopyOfPalmData(HandData::LeftHand).getPosition();
|
||||||
|
palmRotation = holdingAvatar->getHand()->getCopyOfPalmData(HandData::LeftHand).getRotation();
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX dup code
|
||||||
|
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
|
MyCharacterController* controller = myAvatar ? myAvatar->getCharacterController() : nullptr;
|
||||||
|
if (!controller) {
|
||||||
|
qDebug() << "AvatarActionHold::prepareForPhysicsSimulation failed to get character controller";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glm::vec3 avatarRigidBodyPosition;
|
||||||
|
glm::quat avatarRigidBodyRotation;
|
||||||
|
controller->getRigidBodyLocation(avatarRigidBodyPosition, avatarRigidBodyRotation);
|
||||||
|
|
||||||
|
|
||||||
|
if (isRightHand) {
|
||||||
|
palmPosition = holdingAvatar->getRightPalmPosition();
|
||||||
|
palmRotation = holdingAvatar->getRightPalmRotation();
|
||||||
|
} else {
|
||||||
|
palmPosition = holdingAvatar->getLeftPalmPosition();
|
||||||
|
palmRotation = holdingAvatar->getLeftPalmRotation();
|
||||||
|
}
|
||||||
|
|
||||||
|
_palmOffsetFromRigidBody = palmPosition - avatarRigidBodyPosition;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<Avatar> AvatarActionHold::getTarget(glm::quat& rotation, glm::vec3& position) {
|
std::shared_ptr<Avatar> AvatarActionHold::getTarget(glm::quat& rotation, glm::vec3& position) {
|
||||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||||
auto holdingAvatar = std::static_pointer_cast<Avatar>(avatarManager->getAvatarBySessionID(_holderID));
|
auto holdingAvatar = std::static_pointer_cast<Avatar>(avatarManager->getAvatarBySessionID(_holderID));
|
||||||
|
@ -44,7 +96,7 @@ std::shared_ptr<Avatar> AvatarActionHold::getTarget(glm::quat& rotation, glm::ve
|
||||||
bool isRightHand = (_hand == "right");
|
bool isRightHand = (_hand == "right");
|
||||||
glm::vec3 palmPosition { Vectors::ZERO };
|
glm::vec3 palmPosition { Vectors::ZERO };
|
||||||
glm::quat palmRotation { Quaternions::IDENTITY };
|
glm::quat palmRotation { Quaternions::IDENTITY };
|
||||||
|
|
||||||
if (_ignoreIK && holdingAvatar->isMyAvatar()) {
|
if (_ignoreIK && holdingAvatar->isMyAvatar()) {
|
||||||
// We cannot ignore other avatars IK and this is not the point of this option
|
// We cannot ignore other avatars IK and this is not the point of this option
|
||||||
// This is meant to make the grabbing behavior more reactive.
|
// This is meant to make the grabbing behavior more reactive.
|
||||||
|
@ -55,6 +107,22 @@ std::shared_ptr<Avatar> AvatarActionHold::getTarget(glm::quat& rotation, glm::ve
|
||||||
palmPosition = holdingAvatar->getHand()->getCopyOfPalmData(HandData::LeftHand).getPosition();
|
palmPosition = holdingAvatar->getHand()->getCopyOfPalmData(HandData::LeftHand).getPosition();
|
||||||
palmRotation = holdingAvatar->getHand()->getCopyOfPalmData(HandData::LeftHand).getRotation();
|
palmRotation = holdingAvatar->getHand()->getCopyOfPalmData(HandData::LeftHand).getRotation();
|
||||||
}
|
}
|
||||||
|
} else if (holdingAvatar->isMyAvatar()) {
|
||||||
|
// XXX dup code
|
||||||
|
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
|
MyCharacterController* controller = myAvatar ? myAvatar->getCharacterController() : nullptr;
|
||||||
|
if (!controller) {
|
||||||
|
qDebug() << "AvatarActionHold::prepareForPhysicsSimulation failed to get character controller";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glm::vec3 avatarRigidBodyPosition;
|
||||||
|
glm::quat avatarRigidBodyRotation;
|
||||||
|
controller->getRigidBodyLocation(avatarRigidBodyPosition, avatarRigidBodyRotation);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
palmPosition = avatarRigidBodyPosition + _palmOffsetFromRigidBody;
|
||||||
|
palmRotation = holdingAvatar->getRightPalmRotation(); // XXX
|
||||||
} else {
|
} else {
|
||||||
if (isRightHand) {
|
if (isRightHand) {
|
||||||
palmPosition = holdingAvatar->getRightPalmPosition();
|
palmPosition = holdingAvatar->getRightPalmPosition();
|
||||||
|
|
|
@ -25,18 +25,20 @@ public:
|
||||||
AvatarActionHold(const QUuid& id, EntityItemPointer ownerEntity);
|
AvatarActionHold(const QUuid& id, EntityItemPointer ownerEntity);
|
||||||
virtual ~AvatarActionHold();
|
virtual ~AvatarActionHold();
|
||||||
|
|
||||||
virtual bool updateArguments(QVariantMap arguments);
|
virtual bool updateArguments(QVariantMap arguments) override;
|
||||||
virtual QVariantMap getArguments();
|
virtual QVariantMap getArguments() override;
|
||||||
|
|
||||||
virtual void updateActionWorker(float deltaTimeStep);
|
virtual void updateActionWorker(float deltaTimeStep) override;
|
||||||
|
|
||||||
QByteArray serialize() const;
|
QByteArray serialize() const;
|
||||||
virtual void deserialize(QByteArray serializedArguments);
|
virtual void deserialize(QByteArray serializedArguments) override;
|
||||||
|
|
||||||
virtual bool shouldSuppressLocationEdits() { return _active && !_ownerEntity.expired(); }
|
virtual bool shouldSuppressLocationEdits() override { return _active && !_ownerEntity.expired(); }
|
||||||
|
|
||||||
std::shared_ptr<Avatar> getTarget(glm::quat& rotation, glm::vec3& position);
|
std::shared_ptr<Avatar> getTarget(glm::quat& rotation, glm::vec3& position);
|
||||||
|
|
||||||
|
virtual void prepareForPhysicsSimulation() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void doKinematicUpdate(float deltaTimeStep);
|
void doKinematicUpdate(float deltaTimeStep);
|
||||||
|
|
||||||
|
@ -56,6 +58,8 @@ private:
|
||||||
|
|
||||||
float _previousDeltaTimeStep = 0.0f;
|
float _previousDeltaTimeStep = 0.0f;
|
||||||
glm::vec3 _previousPositionalDelta;
|
glm::vec3 _previousPositionalDelta;
|
||||||
|
|
||||||
|
glm::vec3 _palmOffsetFromRigidBody;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AvatarActionHold_h
|
#endif // hifi_AvatarActionHold_h
|
||||||
|
|
|
@ -58,6 +58,8 @@ public:
|
||||||
|
|
||||||
virtual bool shouldSuppressLocationEdits() { return false; }
|
virtual bool shouldSuppressLocationEdits() { return false; }
|
||||||
|
|
||||||
|
virtual void prepareForPhysicsSimulation() { }
|
||||||
|
|
||||||
// these look in the arguments map for a named argument. if it's not found or isn't well formed,
|
// these look in the arguments map for a named argument. if it's not found or isn't well formed,
|
||||||
// ok will be set to false (note that it's never set to true -- set it to true before calling these).
|
// ok will be set to false (note that it's never set to true -- set it to true before calling these).
|
||||||
// if required is true, failure to extract an argument will cause a warning to be printed.
|
// if required is true, failure to extract an argument will cause a warning to be printed.
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include "BulletUtil.h"
|
#include "BulletUtil.h"
|
||||||
#include "PhysicsCollisionGroups.h"
|
#include "PhysicsCollisionGroups.h"
|
||||||
|
#include "ObjectMotionState.h"
|
||||||
|
|
||||||
const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f);
|
const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f);
|
||||||
const float JUMP_SPEED = 3.5f;
|
const float JUMP_SPEED = 3.5f;
|
||||||
|
@ -379,3 +380,15 @@ void CharacterController::preSimulation() {
|
||||||
void CharacterController::postSimulation() {
|
void CharacterController::postSimulation() {
|
||||||
// postSimulation() exists for symmetry and just in case we need to do something here later
|
// postSimulation() exists for symmetry and just in case we need to do something here later
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CharacterController::getRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation) {
|
||||||
|
if (!_rigidBody) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const btTransform& worldTrans = _rigidBody->getCenterOfMassTransform();
|
||||||
|
avatarRigidBodyPosition = bulletToGLM(worldTrans.getOrigin()) + ObjectMotionState::getWorldOffset();
|
||||||
|
avatarRigidBodyRotation = bulletToGLM(worldTrans.getRotation());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -79,6 +79,8 @@ public:
|
||||||
void setEnabled(bool enabled);
|
void setEnabled(bool enabled);
|
||||||
bool isEnabled() const { return _enabled && _dynamicsWorld; }
|
bool isEnabled() const { return _enabled && _dynamicsWorld; }
|
||||||
|
|
||||||
|
bool getRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateUpAxis(const glm::quat& rotation);
|
void updateUpAxis(const glm::quat& rotation);
|
||||||
|
|
||||||
|
|
|
@ -29,12 +29,12 @@ public:
|
||||||
ObjectAction(EntityActionType type, const QUuid& id, EntityItemPointer ownerEntity);
|
ObjectAction(EntityActionType type, const QUuid& id, EntityItemPointer ownerEntity);
|
||||||
virtual ~ObjectAction();
|
virtual ~ObjectAction();
|
||||||
|
|
||||||
virtual void removeFromSimulation(EntitySimulation* simulation) const;
|
virtual void removeFromSimulation(EntitySimulation* simulation) const override;
|
||||||
virtual EntityItemWeakPointer getOwnerEntity() const { return _ownerEntity; }
|
virtual EntityItemWeakPointer getOwnerEntity() const override { return _ownerEntity; }
|
||||||
virtual void setOwnerEntity(const EntityItemPointer ownerEntity) { _ownerEntity = ownerEntity; }
|
virtual void setOwnerEntity(const EntityItemPointer ownerEntity) override { _ownerEntity = ownerEntity; }
|
||||||
|
|
||||||
virtual bool updateArguments(QVariantMap arguments);
|
virtual bool updateArguments(QVariantMap arguments) override;
|
||||||
virtual QVariantMap getArguments();
|
virtual QVariantMap getArguments() override;
|
||||||
|
|
||||||
// this is called from updateAction and should be overridden by subclasses
|
// this is called from updateAction and should be overridden by subclasses
|
||||||
virtual void updateActionWorker(float deltaTimeStep) = 0;
|
virtual void updateActionWorker(float deltaTimeStep) = 0;
|
||||||
|
@ -43,25 +43,25 @@ public:
|
||||||
virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep);
|
virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep);
|
||||||
virtual void debugDraw(btIDebugDraw* debugDrawer);
|
virtual void debugDraw(btIDebugDraw* debugDrawer);
|
||||||
|
|
||||||
virtual QByteArray serialize() const = 0;
|
virtual QByteArray serialize() const override = 0;
|
||||||
virtual void deserialize(QByteArray serializedArguments) = 0;
|
virtual void deserialize(QByteArray serializedArguments) override = 0;
|
||||||
|
|
||||||
virtual bool lifetimeIsOver();
|
virtual bool lifetimeIsOver() override;
|
||||||
virtual quint64 getExpires() { return _expires; }
|
virtual quint64 getExpires() override { return _expires; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
quint64 localTimeToServerTime(quint64 timeValue) const;
|
quint64 localTimeToServerTime(quint64 timeValue) const;
|
||||||
quint64 serverTimeToLocalTime(quint64 timeValue) const;
|
quint64 serverTimeToLocalTime(quint64 timeValue) const;
|
||||||
|
|
||||||
virtual btRigidBody* getRigidBody();
|
virtual btRigidBody* getRigidBody();
|
||||||
virtual glm::vec3 getPosition();
|
virtual glm::vec3 getPosition() override;
|
||||||
virtual void setPosition(glm::vec3 position);
|
virtual void setPosition(glm::vec3 position) override;
|
||||||
virtual glm::quat getRotation();
|
virtual glm::quat getRotation() override;
|
||||||
virtual void setRotation(glm::quat rotation);
|
virtual void setRotation(glm::quat rotation) override;
|
||||||
virtual glm::vec3 getLinearVelocity();
|
virtual glm::vec3 getLinearVelocity() override;
|
||||||
virtual void setLinearVelocity(glm::vec3 linearVelocity);
|
virtual void setLinearVelocity(glm::vec3 linearVelocity) override;
|
||||||
virtual glm::vec3 getAngularVelocity();
|
virtual glm::vec3 getAngularVelocity() override;
|
||||||
virtual void setAngularVelocity(glm::vec3 angularVelocity);
|
virtual void setAngularVelocity(glm::vec3 angularVelocity) override;
|
||||||
virtual void activateBody();
|
virtual void activateBody();
|
||||||
virtual void forceBodyNonStatic();
|
virtual void forceBodyNonStatic();
|
||||||
|
|
||||||
|
|
|
@ -22,13 +22,13 @@ public:
|
||||||
ObjectActionOffset(const QUuid& id, EntityItemPointer ownerEntity);
|
ObjectActionOffset(const QUuid& id, EntityItemPointer ownerEntity);
|
||||||
virtual ~ObjectActionOffset();
|
virtual ~ObjectActionOffset();
|
||||||
|
|
||||||
virtual bool updateArguments(QVariantMap arguments);
|
virtual bool updateArguments(QVariantMap arguments) override;
|
||||||
virtual QVariantMap getArguments();
|
virtual QVariantMap getArguments() override;
|
||||||
|
|
||||||
virtual void updateActionWorker(float deltaTimeStep);
|
virtual void updateActionWorker(float deltaTimeStep) override;
|
||||||
|
|
||||||
virtual QByteArray serialize() const;
|
virtual QByteArray serialize() const override;
|
||||||
virtual void deserialize(QByteArray serializedArguments);
|
virtual void deserialize(QByteArray serializedArguments) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint16_t offsetVersion;
|
static const uint16_t offsetVersion;
|
||||||
|
|
|
@ -19,13 +19,13 @@ public:
|
||||||
ObjectActionSpring(const QUuid& id, EntityItemPointer ownerEntity);
|
ObjectActionSpring(const QUuid& id, EntityItemPointer ownerEntity);
|
||||||
virtual ~ObjectActionSpring();
|
virtual ~ObjectActionSpring();
|
||||||
|
|
||||||
virtual bool updateArguments(QVariantMap arguments);
|
virtual bool updateArguments(QVariantMap arguments) override;
|
||||||
virtual QVariantMap getArguments();
|
virtual QVariantMap getArguments() override;
|
||||||
|
|
||||||
virtual void updateActionWorker(float deltaTimeStep);
|
virtual void updateActionWorker(float deltaTimeStep) override;
|
||||||
|
|
||||||
virtual QByteArray serialize() const;
|
virtual QByteArray serialize() const override;
|
||||||
virtual void deserialize(QByteArray serializedArguments);
|
virtual void deserialize(QByteArray serializedArguments) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const uint16_t springVersion;
|
static const uint16_t springVersion;
|
||||||
|
|
|
@ -497,3 +497,11 @@ void PhysicsEngine::removeAction(const QUuid actionID) {
|
||||||
_objectActions.remove(actionID);
|
_objectActions.remove(actionID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysicsEngine::forEachAction(std::function<void(EntityActionPointer)> actor) {
|
||||||
|
QHashIterator<QUuid, EntityActionPointer> iter(_objectActions);
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.next();
|
||||||
|
actor(iter.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -97,6 +97,7 @@ public:
|
||||||
EntityActionPointer getActionByID(const QUuid& actionID) const;
|
EntityActionPointer getActionByID(const QUuid& actionID) const;
|
||||||
void addAction(EntityActionPointer action);
|
void addAction(EntityActionPointer action);
|
||||||
void removeAction(const QUuid actionID);
|
void removeAction(const QUuid actionID);
|
||||||
|
void forEachAction(std::function<void(EntityActionPointer)> actor);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void removeContacts(ObjectMotionState* motionState);
|
void removeContacts(ObjectMotionState* motionState);
|
||||||
|
|
Loading…
Reference in a new issue