mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-07 20:22:27 +02:00
fix for pushing avatar into floor when exiting away mode.
* Removed MyAvatar.reset() access from JavaScript * Added HMD.centerUI() to JavaScript, which can be used to reset the 3D UI sphere around the current HMD orientation. * Added MyAvatar.clearIKJOintLimitHistory() which can be used to reset any remembered IK joint limit history. * Added MyAvatar.centerBody() which can be used to instantly re-orient the avatar's so that the hips and toes are facing the same direction as the current HMD orientation. away.js now uses the above new API's instead of MyAvatar.reset()
This commit is contained in:
parent
866ba2f185
commit
837b19ed1b
13 changed files with 90 additions and 7 deletions
|
@ -3404,6 +3404,10 @@ void Application::setOverlaysVisible(bool visible) {
|
|||
menu->setIsOptionChecked(MenuOption::Overlays, true);
|
||||
}
|
||||
|
||||
void Application::centerUI() {
|
||||
_overlayConductor.centerUI();
|
||||
}
|
||||
|
||||
void Application::cycleCamera() {
|
||||
auto menu = Menu::getInstance();
|
||||
if (menu->isOptionChecked(MenuOption::FullscreenMirror)) {
|
||||
|
|
|
@ -298,6 +298,7 @@ public slots:
|
|||
void cameraMenuChanged();
|
||||
void toggleOverlays();
|
||||
void setOverlaysVisible(bool visible);
|
||||
Q_INVOKABLE void centerUI();
|
||||
|
||||
void resetPhysicsReadyInformation();
|
||||
|
||||
|
|
|
@ -231,13 +231,46 @@ QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) {
|
|||
return AvatarData::toByteArray(cullSmallChanges, sendAll);
|
||||
}
|
||||
|
||||
void MyAvatar::reset(bool andRecenter, bool andReload, bool andHead) {
|
||||
|
||||
void MyAvatar::centerBody() {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "reset", Q_ARG(bool, andRecenter), Q_ARG(bool, andReload), Q_ARG(bool, andHead));
|
||||
QMetaObject::invokeMethod(this, "centerBody");
|
||||
return;
|
||||
}
|
||||
|
||||
// derive the desired body orientation from the current hmd orientation, before the sensor reset.
|
||||
auto newBodySensorMatrix = deriveBodyFromHMDSensor(); // Based on current cached HMD position/rotation..
|
||||
|
||||
// transform this body into world space
|
||||
auto worldBodyMatrix = _sensorToWorldMatrix * newBodySensorMatrix;
|
||||
auto worldBodyPos = extractTranslation(worldBodyMatrix);
|
||||
auto worldBodyRot = glm::normalize(glm::quat_cast(worldBodyMatrix));
|
||||
|
||||
// this will become our new position.
|
||||
setPosition(worldBodyPos);
|
||||
setOrientation(worldBodyRot);
|
||||
|
||||
// reset the body in sensor space
|
||||
_bodySensorMatrix = newBodySensorMatrix;
|
||||
|
||||
// rebuild the sensor to world matrix
|
||||
updateSensorToWorldMatrix();
|
||||
}
|
||||
|
||||
void MyAvatar::clearIKJointLimitHistory() {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "clearIKJointLimitHistory");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_rig) {
|
||||
_rig->clearIKJointLimitHistory();
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::reset(bool andRecenter, bool andReload, bool andHead) {
|
||||
|
||||
assert(QThread::currentThread() == thread());
|
||||
|
||||
// Reset dynamic state.
|
||||
_wasPushing = _isPushing = _isBraking = false;
|
||||
_follow.deactivate();
|
||||
|
|
|
@ -96,7 +96,11 @@ public:
|
|||
AudioListenerMode getAudioListenerModeCamera() const { return FROM_CAMERA; }
|
||||
AudioListenerMode getAudioListenerModeCustom() const { return CUSTOM; }
|
||||
|
||||
Q_INVOKABLE void reset(bool andRecenter = false, bool andReload = true, bool andHead = true);
|
||||
void reset(bool andRecenter = false, bool andReload = true, bool andHead = true);
|
||||
|
||||
Q_INVOKABLE void centerBody(); // thread-safe
|
||||
Q_INVOKABLE void clearIKJointLimitHistory(); // thread-safe
|
||||
|
||||
void update(float deltaTime);
|
||||
virtual void postUpdate(float deltaTime) override;
|
||||
void preDisplaySide(RenderArgs* renderArgs);
|
||||
|
|
|
@ -135,3 +135,7 @@ void HMDScriptingInterface::unsuppressKeyboard() {
|
|||
bool HMDScriptingInterface::isKeyboardVisible() {
|
||||
return qApp->getActiveDisplayPlugin()->isKeyboardVisible();
|
||||
}
|
||||
|
||||
void HMDScriptingInterface::centerUI() {
|
||||
QMetaObject::invokeMethod(qApp, "centerUI", Qt::QueuedConnection);
|
||||
}
|
||||
|
|
|
@ -55,6 +55,9 @@ public:
|
|||
/// Query the display plugin to determine the current VR keyboard visibility
|
||||
Q_INVOKABLE bool isKeyboardVisible();
|
||||
|
||||
// rotate the overlay UI sphere so that it is centered about the the current HMD position and orientation
|
||||
Q_INVOKABLE void centerUI();
|
||||
|
||||
public:
|
||||
HMDScriptingInterface();
|
||||
static QScriptValue getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine);
|
||||
|
|
|
@ -488,6 +488,12 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
|||
return _relativePoses;
|
||||
}
|
||||
|
||||
void AnimInverseKinematics::clearIKJointLimitHistory() {
|
||||
for (auto& pair : _constraints) {
|
||||
pair.second->clearHistory();
|
||||
}
|
||||
}
|
||||
|
||||
RotationConstraint* AnimInverseKinematics::getConstraint(int index) {
|
||||
RotationConstraint* constraint = nullptr;
|
||||
std::map<int, RotationConstraint*>::iterator constraintItr = _constraints.find(index);
|
||||
|
|
|
@ -37,6 +37,8 @@ public:
|
|||
virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, float dt, AnimNode::Triggers& triggersOut) override;
|
||||
virtual const AnimPoseVec& overlay(const AnimVariantMap& animVars, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) override;
|
||||
|
||||
void clearIKJointLimitHistory();
|
||||
|
||||
protected:
|
||||
void computeTargets(const AnimVariantMap& animVars, std::vector<IKTarget>& targets, const AnimPoseVec& underPoses);
|
||||
void solveWithCyclicCoordinateDescent(const std::vector<IKTarget>& targets);
|
||||
|
|
|
@ -295,6 +295,19 @@ void Rig::clearJointAnimationPriority(int index) {
|
|||
}
|
||||
}
|
||||
|
||||
void Rig::clearIKJointLimitHistory() {
|
||||
if (_animNode) {
|
||||
_animNode->traverse([&](AnimNode::Pointer node) {
|
||||
// only report clip nodes as valid roles.
|
||||
auto ikNode = std::dynamic_pointer_cast<AnimInverseKinematics>(node);
|
||||
if (ikNode) {
|
||||
ikNode->clearIKJointLimitHistory();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Rig::setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority) {
|
||||
if (isIndexValid(index)) {
|
||||
if (valid) {
|
||||
|
|
|
@ -103,6 +103,8 @@ public:
|
|||
void clearJointStates();
|
||||
void clearJointAnimationPriority(int index);
|
||||
|
||||
void clearIKJointLimitHistory();
|
||||
|
||||
// geometry space
|
||||
void setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority);
|
||||
|
||||
|
|
|
@ -35,6 +35,9 @@ public:
|
|||
/// \brief clear previous adjustment and adjust constraint limits to allow rotation
|
||||
virtual void dynamicallyAdjustLimits(const glm::quat& rotation) {}
|
||||
|
||||
/// \brief reset any remembered joint limit history
|
||||
virtual void clearHistory() {};
|
||||
|
||||
protected:
|
||||
glm::quat _referenceRotation = glm::quat();
|
||||
};
|
||||
|
|
|
@ -97,8 +97,7 @@ public:
|
|||
/// \return reference to SwingLimitFunction instance for unit-testing
|
||||
const SwingLimitFunction& getSwingLimitFunction() const { return _swingLimitFunction; }
|
||||
|
||||
/// \brief exposed for unit testing
|
||||
void clearHistory();
|
||||
void clearHistory() override;
|
||||
|
||||
private:
|
||||
float handleTwistBoundaryConditions(float twistAngle) const;
|
||||
|
|
|
@ -204,7 +204,16 @@ function goActive() {
|
|||
}
|
||||
MyAvatar.setEnableMeshVisible(true); // IWBNI we respected Developer->Avatar->Draw Mesh setting.
|
||||
stopAwayAnimation();
|
||||
MyAvatar.reset(true);
|
||||
|
||||
// update the UI sphere to be centered about the current HMD orientation.
|
||||
HMD.centerUI();
|
||||
|
||||
// forget about any IK joint limits
|
||||
MyAvatar.clearIKJointLimitHistory();
|
||||
|
||||
// update the avatar hips to point in the same direction as the HMD orientation.
|
||||
MyAvatar.centerBody();
|
||||
|
||||
hideOverlay();
|
||||
|
||||
// restore overlays state to what it was when we went "away"
|
||||
|
|
Loading…
Reference in a new issue