mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 01:10:12 +02:00
avatar follows HMD using velocity motor
This commit is contained in:
parent
a8af8d6027
commit
59e6ca8f8d
3 changed files with 38 additions and 77 deletions
|
@ -1387,9 +1387,7 @@ void MyAvatar::harvestResultsFromPhysicsSimulation(float deltaTime) {
|
||||||
//_bodySensorMatrix = deriveBodyFromHMDSensor();
|
//_bodySensorMatrix = deriveBodyFromHMDSensor();
|
||||||
|
|
||||||
if (_characterController.isEnabledAndReady()) {
|
if (_characterController.isEnabledAndReady()) {
|
||||||
setVelocity(_characterController.getLinearVelocity() + _characterController.getFollowVelocity());
|
setVelocity(_characterController.getLinearVelocity());
|
||||||
} else {
|
|
||||||
setVelocity(getVelocity() + _characterController.getFollowVelocity());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_follow.postPhysicsUpdate(*this);
|
_follow.postPhysicsUpdate(*this);
|
||||||
|
|
|
@ -75,9 +75,6 @@ CharacterController::CharacterController() {
|
||||||
_takeoffToInAirStartTime = 0;
|
_takeoffToInAirStartTime = 0;
|
||||||
_jumpButtonDownStartTime = 0;
|
_jumpButtonDownStartTime = 0;
|
||||||
_jumpButtonDownCount = 0;
|
_jumpButtonDownCount = 0;
|
||||||
_followTime = 0.0f;
|
|
||||||
_followLinearDisplacement = btVector3(0, 0, 0);
|
|
||||||
_followAngularDisplacement = btQuaternion::getIdentity();
|
|
||||||
_hasSupport = false;
|
_hasSupport = false;
|
||||||
|
|
||||||
_pendingFlags = PENDING_FLAG_UPDATE_SHAPE;
|
_pendingFlags = PENDING_FLAG_UPDATE_SHAPE;
|
||||||
|
@ -203,6 +200,43 @@ const btScalar MIN_TARGET_SPEED_SQUARED = MIN_TARGET_SPEED * MIN_TARGET_SPEED;
|
||||||
|
|
||||||
void CharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) {
|
void CharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) {
|
||||||
btVector3 velocity = _rigidBody->getLinearVelocity() - _parentVelocity;
|
btVector3 velocity = _rigidBody->getLinearVelocity() - _parentVelocity;
|
||||||
|
if (_following) {
|
||||||
|
// OUTOFBODY_HACK -- these consts were copied from elsewhere, and then tuned
|
||||||
|
const float NORMAL_WALKING_SPEED = 2.5f; // actual walk speed is 2.5 m/sec
|
||||||
|
const float FOLLOW_TIMESCALE = 0.8f;
|
||||||
|
const float FOLLOW_ROTATION_THRESHOLD = PI / 6.0f;
|
||||||
|
const float FOLLOW_FACTOR = 0.5f;
|
||||||
|
const float MAX_ANGULAR_SPEED = FOLLOW_ROTATION_THRESHOLD / FOLLOW_TIMESCALE;
|
||||||
|
|
||||||
|
// linear part uses a motor
|
||||||
|
btTransform bodyTransform = _rigidBody->getWorldTransform();
|
||||||
|
btVector3 startPos = bodyTransform.getOrigin();
|
||||||
|
btVector3 deltaPos = _followDesiredBodyTransform.getOrigin() - startPos;
|
||||||
|
btVector3 vel = deltaPos * (FOLLOW_FACTOR / dt);
|
||||||
|
btScalar speed = vel.length();
|
||||||
|
if (speed > NORMAL_WALKING_SPEED) {
|
||||||
|
vel *= NORMAL_WALKING_SPEED / speed;
|
||||||
|
}
|
||||||
|
const float HORIZONTAL_FOLLOW_TIMESCALE = 0.01f; // a very small timescale here is OK
|
||||||
|
const float VERTICAL_FOLLOW_TIMESCALE = (_state == State::Hover) ? HORIZONTAL_FOLLOW_TIMESCALE : 20.0f;
|
||||||
|
glm::quat motorRotation;
|
||||||
|
addMotor(bulletToGLM(vel), motorRotation, HORIZONTAL_FOLLOW_TIMESCALE, VERTICAL_FOLLOW_TIMESCALE);
|
||||||
|
|
||||||
|
// angular part uses incremental teleports
|
||||||
|
btQuaternion startRot = bodyTransform.getRotation();
|
||||||
|
glm::vec2 currentFacing = getFacingDir2D(bulletToGLM(startRot));
|
||||||
|
glm::vec2 currentRight(currentFacing.y, - currentFacing.x);
|
||||||
|
glm::vec2 desiredFacing = getFacingDir2D(bulletToGLM(_followDesiredBodyTransform.getRotation()));
|
||||||
|
float deltaAngle = acosf(glm::clamp(glm::dot(currentFacing, desiredFacing), -1.0f, 1.0f));
|
||||||
|
float angularSpeed = 0.5f * deltaAngle / dt;
|
||||||
|
if (angularSpeed > MAX_ANGULAR_SPEED) {
|
||||||
|
angularSpeed *= MAX_ANGULAR_SPEED / angularSpeed;
|
||||||
|
}
|
||||||
|
float sign = copysignf(1.0f, glm::dot(desiredFacing, currentRight));
|
||||||
|
btQuaternion angularDisplacement = btQuaternion(btVector3(0.0f, 1.0f, 0.0f), sign * angularSpeed * dt);
|
||||||
|
btQuaternion endRot = angularDisplacement * startRot;
|
||||||
|
_rigidBody->setWorldTransform(btTransform(endRot, startPos));
|
||||||
|
}
|
||||||
computeNewVelocity(dt, velocity);
|
computeNewVelocity(dt, velocity);
|
||||||
|
|
||||||
if (_moveKinematically) {
|
if (_moveKinematically) {
|
||||||
|
@ -222,50 +256,6 @@ void CharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) {
|
||||||
// This mirrors the computation done in MyAvatar::FollowHelper::postPhysicsUpdate().
|
// This mirrors the computation done in MyAvatar::FollowHelper::postPhysicsUpdate().
|
||||||
|
|
||||||
_rigidBody->setLinearVelocity(velocity + _parentVelocity);
|
_rigidBody->setLinearVelocity(velocity + _parentVelocity);
|
||||||
if (_following) {
|
|
||||||
// OUTOFBODY_HACK -- these consts were copied from elsewhere, and then tuned
|
|
||||||
const float NORMAL_WALKING_SPEED = 1.5f; // actual walk speed is 2.5 m/sec
|
|
||||||
const float FOLLOW_TIME = 0.8f;
|
|
||||||
const float FOLLOW_ROTATION_THRESHOLD = cosf(PI / 6.0f);
|
|
||||||
const float FOLLOW_FACTOR = 0.5f;
|
|
||||||
|
|
||||||
const float MAX_ANGULAR_SPEED = FOLLOW_ROTATION_THRESHOLD / FOLLOW_TIME;
|
|
||||||
|
|
||||||
btTransform bodyTransform = _rigidBody->getWorldTransform();
|
|
||||||
|
|
||||||
btVector3 startPos = bodyTransform.getOrigin();
|
|
||||||
btVector3 deltaPos = _followDesiredBodyTransform.getOrigin() - startPos;
|
|
||||||
btVector3 vel = deltaPos * (FOLLOW_FACTOR / dt);
|
|
||||||
btScalar speed = vel.length();
|
|
||||||
if (speed > NORMAL_WALKING_SPEED) {
|
|
||||||
vel *= NORMAL_WALKING_SPEED / speed;
|
|
||||||
}
|
|
||||||
btVector3 linearDisplacement = vel * dt;
|
|
||||||
btVector3 endPos = startPos + linearDisplacement;
|
|
||||||
|
|
||||||
btQuaternion startRot = bodyTransform.getRotation();
|
|
||||||
glm::vec2 currentFacing = getFacingDir2D(bulletToGLM(startRot));
|
|
||||||
glm::vec2 currentRight(currentFacing.y, -currentFacing.x);
|
|
||||||
glm::vec2 desiredFacing = getFacingDir2D(bulletToGLM(_followDesiredBodyTransform.getRotation()));
|
|
||||||
float deltaAngle = acosf(glm::clamp(glm::dot(currentFacing, desiredFacing), -1.0f, 1.0f));
|
|
||||||
float angularSpeed = 0.5f * deltaAngle / dt;
|
|
||||||
if (angularSpeed > MAX_ANGULAR_SPEED) {
|
|
||||||
angularSpeed *= MAX_ANGULAR_SPEED / angularSpeed;
|
|
||||||
}
|
|
||||||
float sign = copysignf(1.0f, glm::dot(desiredFacing, currentRight));
|
|
||||||
btQuaternion angularDisplacement = btQuaternion(btVector3(0.0f, 1.0f, 0.0f), sign * angularSpeed * dt);
|
|
||||||
btQuaternion endRot = angularDisplacement * startRot;
|
|
||||||
|
|
||||||
// in order to accumulate displacement of avatar position, we need to take _shapeLocalOffset into account.
|
|
||||||
btVector3 shapeLocalOffset = glmToBullet(_shapeLocalOffset);
|
|
||||||
btVector3 swingDisplacement = rotateVector(endRot, -shapeLocalOffset) - rotateVector(startRot, -shapeLocalOffset);
|
|
||||||
|
|
||||||
_followLinearDisplacement = linearDisplacement + swingDisplacement + _followLinearDisplacement;
|
|
||||||
_followAngularDisplacement = angularDisplacement * _followAngularDisplacement;
|
|
||||||
|
|
||||||
_rigidBody->setWorldTransform(btTransform(endRot, endPos));
|
|
||||||
}
|
|
||||||
_followTime += dt;
|
|
||||||
_ghost.setWorldTransform(_rigidBody->getWorldTransform());
|
_ghost.setWorldTransform(_rigidBody->getWorldTransform());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -422,22 +412,6 @@ void CharacterController::setFollowParameters(const glm::mat4& desiredWorldBodyM
|
||||||
_following = true;
|
_following = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 CharacterController::getFollowLinearDisplacement() const {
|
|
||||||
return bulletToGLM(_followLinearDisplacement);
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::quat CharacterController::getFollowAngularDisplacement() const {
|
|
||||||
return bulletToGLM(_followAngularDisplacement);
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 CharacterController::getFollowVelocity() const {
|
|
||||||
if (_followTime > 0.0f) {
|
|
||||||
return bulletToGLM(_followLinearDisplacement) / _followTime;
|
|
||||||
} else {
|
|
||||||
return glm::vec3();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 CharacterController::getLinearVelocity() const {
|
glm::vec3 CharacterController::getLinearVelocity() const {
|
||||||
glm::vec3 velocity(0.0f);
|
glm::vec3 velocity(0.0f);
|
||||||
if (_rigidBody) {
|
if (_rigidBody) {
|
||||||
|
@ -700,10 +674,6 @@ void CharacterController::preSimulation() {
|
||||||
|
|
||||||
_previousFlags = _pendingFlags;
|
_previousFlags = _pendingFlags;
|
||||||
_pendingFlags &= ~PENDING_FLAG_JUMP;
|
_pendingFlags &= ~PENDING_FLAG_JUMP;
|
||||||
|
|
||||||
_followTime = 0.0f;
|
|
||||||
_followLinearDisplacement = btVector3(0.0f, 0.0f, 0.0f);
|
|
||||||
_followAngularDisplacement = btQuaternion::getIdentity();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterController::postSimulation() {
|
void CharacterController::postSimulation() {
|
||||||
|
|
|
@ -88,10 +88,6 @@ public:
|
||||||
void setParentVelocity(const glm::vec3& parentVelocity);
|
void setParentVelocity(const glm::vec3& parentVelocity);
|
||||||
void setFollowParameters(const glm::mat4& desiredWorldBodyMatrix);
|
void setFollowParameters(const glm::mat4& desiredWorldBodyMatrix);
|
||||||
void disableFollow() { _following = false; }
|
void disableFollow() { _following = false; }
|
||||||
float getFollowTime() const { return _followTime; }
|
|
||||||
glm::vec3 getFollowLinearDisplacement() const;
|
|
||||||
glm::quat getFollowAngularDisplacement() const;
|
|
||||||
glm::vec3 getFollowVelocity() const;
|
|
||||||
|
|
||||||
glm::vec3 getLinearVelocity() const;
|
glm::vec3 getLinearVelocity() const;
|
||||||
glm::vec3 getVelocityChange() const;
|
glm::vec3 getVelocityChange() const;
|
||||||
|
@ -177,9 +173,6 @@ protected:
|
||||||
btScalar _gravity;
|
btScalar _gravity;
|
||||||
|
|
||||||
btScalar _jumpSpeed;
|
btScalar _jumpSpeed;
|
||||||
btScalar _followTime;
|
|
||||||
btVector3 _followLinearDisplacement;
|
|
||||||
btQuaternion _followAngularDisplacement;
|
|
||||||
btVector3 _linearAcceleration;
|
btVector3 _linearAcceleration;
|
||||||
bool _following { false };
|
bool _following { false };
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue