mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-08 07:32:10 +02:00
Decouple MyAvatar.centerOfGravityModelEnabled from the user standing state.
Engine code no longer controls MyAvatar.centerOfGravityModelEnabled. Maybe we should deprecate it now, since its reason to exist seemed to be only to disable the CG model while the user was sitting, which is now done more explicitly (see below). MyAvatar::FollowHelper: - rename shouldActivateHorizontal to shouldActivateHorizontal_userSitting, now private. - rename shouldActivateHorizontalCG to shouldActivateHorizontal_userStanding, now private. - add new shouldActivateHorizontal that calls one of the above based on the user's sit/stand state. - these functions no longer modify their 'myAvatar' parameter. Add USER_CAN_TURN_BODY_WHILE_SITTING (false), which retains the old rotation behaviour of lean recentering: a lean recenter doesn't rotate the body if the user is sitting (new: unless the feet are tracked). In other words, the lean recentering assumes the user isn't on a swivel chair and keeps the avatar pointing in the same direction. It might be good to expose that as an option. (Regardless, rotation recentering does kick-in if they turn too far).
This commit is contained in:
parent
a95d29d327
commit
dd2a11f53b
2 changed files with 73 additions and 31 deletions
|
@ -4619,7 +4619,7 @@ bool MyAvatar::getFlyingHMDPref() {
|
|||
}
|
||||
|
||||
// Public interface for targetscale
|
||||
float MyAvatar::getAvatarScale() {
|
||||
float MyAvatar::getAvatarScale() const {
|
||||
return getTargetScale();
|
||||
}
|
||||
|
||||
|
@ -5341,7 +5341,6 @@ void MyAvatar::setIsInSittingState(bool isSitting) {
|
|||
// on reset height we need the count to be more than one in case the user sits and stands up quickly.
|
||||
_isInSittingState.set(isSitting);
|
||||
setResetMode(true);
|
||||
setCenterOfGravityModelEnabled(!isSitting);
|
||||
setSitStandStateChange(true);
|
||||
}
|
||||
|
||||
|
@ -5679,7 +5678,10 @@ bool MyAvatar::FollowHelper::shouldActivateRotation(const MyAvatar& myAvatar,
|
|||
return glm::dot(-myAvatar.getHeadControllerFacingMovingAverage(), bodyFacing) < FOLLOW_ROTATION_THRESHOLD;
|
||||
}
|
||||
|
||||
bool MyAvatar::FollowHelper::shouldActivateHorizontal(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix) const {
|
||||
// Determine if the horizontal following should activate, for a user who is sitting in the real world.
|
||||
bool MyAvatar::FollowHelper::shouldActivateHorizontal_userSitting(const MyAvatar& myAvatar,
|
||||
const glm::mat4& desiredBodyMatrix,
|
||||
const glm::mat4& currentBodyMatrix) const {
|
||||
if (!myAvatar.isAllowedToLean()) {
|
||||
controller::Pose currentHeadPose = myAvatar.getControllerPoseInAvatarFrame(controller::Action::HEAD);
|
||||
if (!withinBaseOfSupport(currentHeadPose)) {
|
||||
|
@ -5711,13 +5713,21 @@ bool MyAvatar::FollowHelper::shouldActivateHorizontal(const MyAvatar& myAvatar,
|
|||
return stepDetected;
|
||||
}
|
||||
|
||||
bool MyAvatar::FollowHelper::shouldActivateHorizontalCG(MyAvatar& myAvatar) const {
|
||||
// Determine if the horizontal following should activate, for a user who is standing in the real world.
|
||||
// resetModeOut: (out) true if setResetMode(true) should be called if this function returns true.
|
||||
// currentHeadPoseForWalkingStateOut: (out) the head pose, in the avatar frame,
|
||||
// that can be tested in order to trigger walking state if this function returns true.
|
||||
bool MyAvatar::FollowHelper::shouldActivateHorizontal_userStanding(
|
||||
const MyAvatar& myAvatar,
|
||||
bool& resetModeOut,
|
||||
controller::Pose& currentHeadPoseForWalkingStateOut) const {
|
||||
|
||||
if (myAvatar.getIsInWalkingState()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
controller::Pose currentHeadPose = myAvatar.getControllerPoseInAvatarFrame(controller::Action::HEAD);
|
||||
currentHeadPoseForWalkingStateOut = myAvatar.getControllerPoseInAvatarFrame(controller::Action::HEAD);
|
||||
controller::Pose& currentHeadPose = currentHeadPoseForWalkingStateOut;
|
||||
bool stepDetected = false;
|
||||
|
||||
if (!withinBaseOfSupport(currentHeadPose)) {
|
||||
|
@ -5750,20 +5760,30 @@ bool MyAvatar::FollowHelper::shouldActivateHorizontalCG(MyAvatar& myAvatar) cons
|
|||
float anatomicalHeadToHipsDistance = glm::length(defaultHeadPosition - defaultHipsPosition);
|
||||
if (!isActive(CharacterController::FollowType::Horizontal) && (!isActive(CharacterController::FollowType::Vertical)) &&
|
||||
(glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + (DEFAULT_AVATAR_SPINE_STRETCH_LIMIT * anatomicalHeadToHipsDistance)))) {
|
||||
myAvatar.setResetMode(true);
|
||||
resetModeOut = true;
|
||||
stepDetected = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (stepDetected) {
|
||||
if (glm::length(currentHeadPose.velocity) > DEFAULT_AVATAR_WALK_SPEED_THRESHOLD) {
|
||||
myAvatar.setIsInWalkingState(true);
|
||||
}
|
||||
}
|
||||
|
||||
return stepDetected;
|
||||
}
|
||||
|
||||
// Determine if the horizontal following should activate.
|
||||
// resetModeOut: (out) true if setResetMode(true) should be called if this function returns true.
|
||||
// currentHeadPoseForWalkingStateOut: (out) the head pose, in the avatar frame,
|
||||
// that can be tested in order to trigger walking state if this function returns true.
|
||||
bool MyAvatar::FollowHelper::shouldActivateHorizontal(const MyAvatar& myAvatar,
|
||||
const glm::mat4& desiredBodyMatrix,
|
||||
const glm::mat4& currentBodyMatrix,
|
||||
bool& resetModeOut,
|
||||
controller::Pose& currentHeadPoseForWalkingStateOut) const {
|
||||
if (myAvatar.getIsInSittingState()) {
|
||||
return shouldActivateHorizontal_userSitting(myAvatar, desiredBodyMatrix, currentBodyMatrix);
|
||||
} else {
|
||||
return shouldActivateHorizontal_userStanding(myAvatar, resetModeOut, currentHeadPoseForWalkingStateOut);
|
||||
}
|
||||
}
|
||||
|
||||
bool MyAvatar::FollowHelper::shouldActivateVertical(const MyAvatar& myAvatar,
|
||||
const glm::mat4& desiredBodyMatrix,
|
||||
const glm::mat4& currentBodyMatrix) const {
|
||||
|
@ -5807,7 +5827,7 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar,
|
|||
}
|
||||
}
|
||||
|
||||
// Horizontal and rotation recenter
|
||||
// Lean recenter
|
||||
|
||||
if ((myAvatar.areFeetTracked() || getForceActivateHorizontal()) && !isActive(CharacterController::FollowType::Horizontal)) {
|
||||
activate(CharacterController::FollowType::Horizontal, myAvatar.areFeetTracked());
|
||||
|
@ -5815,22 +5835,33 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar,
|
|||
} else {
|
||||
if ((myAvatar.getAllowAvatarLeaningPreference() != MyAvatar::AllowAvatarLeaningPreference::AlwaysNoRecenter) &&
|
||||
qApp->getCamera().getMode() != CAMERA_MODE_MIRROR) {
|
||||
if (myAvatar.getCenterOfGravityModelEnabled()) {
|
||||
if (!isActive(CharacterController::FollowType::Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) {
|
||||
activate(CharacterController::FollowType::Horizontal, false);
|
||||
if (myAvatar.getEnableStepResetRotation()) {
|
||||
activate(CharacterController::FollowType::Rotation, false);
|
||||
myAvatar.setHeadControllerFacingMovingAverage(myAvatar.getHeadControllerFacing());
|
||||
}
|
||||
|
||||
bool resetModeOut = false;
|
||||
controller::Pose currentHeadPoseForWalkingStateOut;
|
||||
|
||||
// True if the user can turn their body while sitting (eg. swivel chair).
|
||||
// Todo?: We could expose this as an option.
|
||||
// (Regardless, rotation recentering does kick-in if they turn too far).
|
||||
constexpr bool USER_CAN_TURN_BODY_WHILE_SITTING = false;
|
||||
|
||||
if (!isActive(CharacterController::FollowType::Horizontal) &&
|
||||
(shouldActivateHorizontal(myAvatar, desiredBodyMatrix, currentBodyMatrix,
|
||||
resetModeOut, currentHeadPoseForWalkingStateOut) ||
|
||||
hasDriveInput)) {
|
||||
activate(CharacterController::FollowType::Horizontal, false);
|
||||
if (myAvatar.getEnableStepResetRotation() &&
|
||||
(USER_CAN_TURN_BODY_WHILE_SITTING || !myAvatar.getIsInSittingState())) {
|
||||
activate(CharacterController::FollowType::Rotation, false);
|
||||
myAvatar.setHeadControllerFacingMovingAverage(myAvatar.getHeadControllerFacing());
|
||||
}
|
||||
} else {
|
||||
// center of gravity model is not enabled
|
||||
if (!isActive(CharacterController::FollowType::Horizontal) &&
|
||||
(shouldActivateHorizontal(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) {
|
||||
activate(CharacterController::FollowType::Horizontal, false);
|
||||
if (myAvatar.getEnableStepResetRotation() && !myAvatar.getIsInSittingState()) {
|
||||
activate(CharacterController::FollowType::Rotation, false);
|
||||
myAvatar.setHeadControllerFacingMovingAverage(myAvatar.getHeadControllerFacing());
|
||||
|
||||
if (resetModeOut) {
|
||||
myAvatar.setResetMode(true);
|
||||
}
|
||||
|
||||
if (currentHeadPoseForWalkingStateOut.isValid()) {
|
||||
if (glm::length(currentHeadPoseForWalkingStateOut.velocity) > DEFAULT_AVATAR_WALK_SPEED_THRESHOLD) {
|
||||
myAvatar.setIsInWalkingState(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1634,7 +1634,7 @@ public:
|
|||
* @function MyAvatar.getAvatarScale
|
||||
* @returns {number} The target scale for the avatar, range <code>0.005</code> – <code>1000.0</code>.
|
||||
*/
|
||||
Q_INVOKABLE float getAvatarScale();
|
||||
Q_INVOKABLE float getAvatarScale() const;
|
||||
|
||||
/**jsdoc
|
||||
* Sets the target scale of the avatar. The target scale is the desired scale of the avatar without any restrictions on
|
||||
|
@ -2908,8 +2908,11 @@ private:
|
|||
void decrementTimeRemaining(float dt);
|
||||
bool shouldActivateRotation(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix, bool& shouldSnapOut) const;
|
||||
bool shouldActivateVertical(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix) const;
|
||||
bool shouldActivateHorizontal(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix) const;
|
||||
bool shouldActivateHorizontalCG(MyAvatar& myAvatar) const;
|
||||
bool shouldActivateHorizontal(const MyAvatar& myAvatar,
|
||||
const glm::mat4& desiredBodyMatrix,
|
||||
const glm::mat4& currentBodyMatrix,
|
||||
bool& resetModeOut,
|
||||
controller::Pose& currentHeadPoseForWalkingStateOut) const;
|
||||
void prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat4& bodySensorMatrix, const glm::mat4& currentBodyMatrix, bool hasDriveInput);
|
||||
glm::mat4 postPhysicsUpdate(MyAvatar& myAvatar, const glm::mat4& currentBodyMatrix);
|
||||
bool getForceActivateRotation() const;
|
||||
|
@ -2924,6 +2927,14 @@ private:
|
|||
std::atomic<bool> _forceActivateVertical { false };
|
||||
std::atomic<bool> _forceActivateHorizontal { false };
|
||||
std::atomic<bool> _toggleHipsFollowing { true };
|
||||
|
||||
private:
|
||||
bool shouldActivateHorizontal_userSitting(const MyAvatar& myAvatar,
|
||||
const glm::mat4& desiredBodyMatrix,
|
||||
const glm::mat4& currentBodyMatrix) const;
|
||||
bool shouldActivateHorizontal_userStanding(const MyAvatar& myAvatar,
|
||||
bool& resetModeOut,
|
||||
controller::Pose& currentHeadPoseForWalkingStateOut) const;
|
||||
};
|
||||
|
||||
FollowHelper _follow;
|
||||
|
|
Loading…
Reference in a new issue