mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 06:44:06 +02:00
cache the spine2 spline default offset and ratio
This commit is contained in:
parent
e36877a861
commit
2e1a4545c6
4 changed files with 94 additions and 14 deletions
|
@ -44,25 +44,46 @@ static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const
|
|||
}
|
||||
|
||||
static glm::vec3 computeSpine2WithHeadHipsSpline(MyAvatar* myAvatar, AnimPose hipsIKTargetPose, AnimPose headIKTargetPose) {
|
||||
glm::vec3 basePosition = myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Hips"));
|
||||
glm::vec3 tipPosition = myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Head"));
|
||||
glm::vec3 spine2Position = myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Spine2"));
|
||||
/*
|
||||
AnimPose avatarToRigPose(glm::vec3(1.0f), Quaternions::Y_180, glm::vec3(0.0f));
|
||||
|
||||
AnimPose hipsDefaultPoseAvatarSpace(myAvatar->getAbsoluteDefaultJointRotationInObjectFrame(myAvatar->getJointIndex("Hips")), myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Hips")));
|
||||
AnimPose headDefaultPoseAvatarSpace(myAvatar->getAbsoluteDefaultJointRotationInObjectFrame(myAvatar->getJointIndex("Head")), myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Head")));
|
||||
AnimPose spine2DefaultPoseAvatarSpace(myAvatar->getAbsoluteDefaultJointRotationInObjectFrame(myAvatar->getJointIndex("Spine2")), myAvatar->getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar->getJointIndex("Spine2")));
|
||||
AnimPose hipsDefaultPoseRigSpace = avatarToRigPose * hipsDefaultPoseAvatarSpace;
|
||||
AnimPose headDefaultPoseRigSpace = avatarToRigPose * headDefaultPoseAvatarSpace;
|
||||
AnimPose spine2DefaultPoseRigSpace = avatarToRigPose * spine2DefaultPoseAvatarSpace;
|
||||
|
||||
|
||||
glm::vec3 basePosition = hipsDefaultPoseRigSpace.trans();
|
||||
glm::vec3 tipPosition = headDefaultPoseRigSpace.trans();
|
||||
glm::vec3 spine2Position = spine2DefaultPoseRigSpace.trans();
|
||||
glm::vec3 baseToTip = tipPosition - basePosition;
|
||||
float baseToTipLength = glm::length(baseToTip);
|
||||
glm::vec3 baseToTipNormal = baseToTip / baseToTipLength;
|
||||
glm::vec3 baseToSpine2 = spine2Position - basePosition;
|
||||
float ratio = glm::dot(baseToSpine2, baseToTipNormal) / baseToTipLength;
|
||||
|
||||
CubicHermiteSplineFunctorWithArcLength defaultSpline = computeSplineFromTipAndBase(headDefaultPoseRigSpace, hipsDefaultPoseRigSpace);
|
||||
// measure the total arc length along the spline
|
||||
float totalDefaultArcLength = defaultSpline.arcLength(1.0f);
|
||||
float t = defaultSpline.arcLengthInverse(ratio * totalDefaultArcLength);
|
||||
glm::vec3 defaultSplineSpine2Translation = defaultSpline(t);
|
||||
|
||||
glm::vec3 offset = spine2Position - defaultSplineSpine2Translation;
|
||||
|
||||
qCDebug(animation) << "the my skeleton model numbers are " << ratio << " and " << offset;
|
||||
*/
|
||||
// the the ik targets to compute the spline with
|
||||
CubicHermiteSplineFunctorWithArcLength spline = computeSplineFromTipAndBase(headIKTargetPose, hipsIKTargetPose);
|
||||
CubicHermiteSplineFunctorWithArcLength splineFinal = computeSplineFromTipAndBase(headIKTargetPose, hipsIKTargetPose);
|
||||
|
||||
// measure the total arc length along the spline
|
||||
float totalArcLength = spline.arcLength(1.0f);
|
||||
float t = spline.arcLengthInverse(ratio * totalArcLength);
|
||||
float totalArcLength = splineFinal.arcLength(1.0f);
|
||||
float tFinal = splineFinal.arcLengthInverse(myAvatar->getSpine2SplineRatio() * totalArcLength);
|
||||
|
||||
glm::vec3 spine2Translation = spline(t);
|
||||
glm::vec3 spine2Translation = splineFinal(tFinal);
|
||||
|
||||
return spine2Translation;
|
||||
return spine2Translation + myAvatar->getSpine2SplineOffset();
|
||||
|
||||
}
|
||||
|
||||
|
@ -266,11 +287,14 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
|||
myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() &&
|
||||
!(params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] & (uint8_t)Rig::ControllerFlags::Enabled)) {
|
||||
|
||||
controller::Pose headSplineControllerPose = myAvatar->getControllerPoseInSensorFrame(controller::Action::HEAD);
|
||||
AnimPose headSplinePose(headSplineControllerPose.getRotation(), headSplineControllerPose.getTranslation());
|
||||
glm::vec3 spine2TargetTranslation = computeSpine2WithHeadHipsSpline(myAvatar, sensorHips, headSplinePose);
|
||||
AnimPose sensorSpine2(Quaternions::IDENTITY, spine2TargetTranslation);
|
||||
AnimPose rigSpine2 = sensorToRigPose * sensorSpine2;
|
||||
// if (avatarHeadPose.isValid()) {
|
||||
|
||||
AnimPose headAvatarSpace(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation());
|
||||
AnimPose headRigSpace = avatarToRigPose * headAvatarSpace;
|
||||
AnimPose hipsRigSpace = sensorToRigPose * sensorHips;
|
||||
glm::vec3 spine2TargetTranslation = computeSpine2WithHeadHipsSpline(myAvatar, hipsRigSpace, headRigSpace);
|
||||
//AnimPose rigSpine2(Quaternions::IDENTITY, spine2TargetTranslation);
|
||||
//AnimPose rigSpine2 = sensorToRigPose * sensorSpine2;
|
||||
|
||||
const float SPINE2_ROTATION_FILTER = 0.5f;
|
||||
AnimPose currentSpine2Pose;
|
||||
|
@ -292,7 +316,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
|||
}
|
||||
generateBasisVectors(up, fwd, u, v, w);
|
||||
AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f)));
|
||||
currentSpine2Pose.trans() = rigSpine2.trans();
|
||||
currentSpine2Pose.trans() = spine2TargetTranslation;
|
||||
currentSpine2Pose.rot() = safeLerp(currentSpine2Pose.rot(), newSpinePose.rot(), SPINE2_ROTATION_FILTER);
|
||||
params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentSpine2Pose;
|
||||
params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated;
|
||||
|
|
|
@ -1420,11 +1420,13 @@ void Avatar::setModelURLFinished(bool success) {
|
|||
// rig is ready
|
||||
void Avatar::rigReady() {
|
||||
buildUnscaledEyeHeightCache();
|
||||
buildSpine2SplineRatioCache();
|
||||
}
|
||||
|
||||
// rig has been reset.
|
||||
void Avatar::rigReset() {
|
||||
clearUnscaledEyeHeightCache();
|
||||
clearSpine2SplineRatioCache();
|
||||
}
|
||||
|
||||
// create new model, can return an instance of a SoftAttachmentModel rather then Model
|
||||
|
@ -1821,10 +1823,54 @@ void Avatar::buildUnscaledEyeHeightCache() {
|
|||
}
|
||||
}
|
||||
|
||||
static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const AnimPose& tipPose, const AnimPose& basePose, float baseGain = 1.0f, float tipGain = 1.0f) {
|
||||
float linearDistance = glm::length(basePose.trans() - tipPose.trans());
|
||||
glm::vec3 p0 = basePose.trans();
|
||||
glm::vec3 m0 = baseGain * linearDistance * (basePose.rot() * Vectors::UNIT_Y);
|
||||
glm::vec3 p1 = tipPose.trans();
|
||||
glm::vec3 m1 = tipGain * linearDistance * (tipPose.rot() * Vectors::UNIT_Y);
|
||||
|
||||
return CubicHermiteSplineFunctorWithArcLength(p0, m0, p1, m1);
|
||||
}
|
||||
|
||||
void Avatar::buildSpine2SplineRatioCache() {
|
||||
if (_skeletonModel) {
|
||||
auto& rig = _skeletonModel->getRig();
|
||||
AnimPose hipsRigDefaultPose = rig.getAbsoluteDefaultPose(rig.indexOfJoint("Hips"));
|
||||
AnimPose headRigDefaultPose(rig.getAbsoluteDefaultPose(rig.indexOfJoint("Head")));
|
||||
glm::vec3 basePosition = hipsRigDefaultPose.trans();
|
||||
glm::vec3 tipPosition = headRigDefaultPose.trans();
|
||||
glm::vec3 spine2Position = rig.getAbsoluteDefaultPose(rig.indexOfJoint("Spine2")).trans();
|
||||
|
||||
glm::vec3 baseToTip = tipPosition - basePosition;
|
||||
float baseToTipLength = glm::length(baseToTip);
|
||||
glm::vec3 baseToTipNormal = baseToTip / baseToTipLength;
|
||||
glm::vec3 baseToSpine2 = spine2Position - basePosition;
|
||||
|
||||
_spine2SplineRatio = glm::dot(baseToSpine2, baseToTipNormal) / baseToTipLength;
|
||||
|
||||
CubicHermiteSplineFunctorWithArcLength defaultSpline = computeSplineFromTipAndBase(headRigDefaultPose, hipsRigDefaultPose);
|
||||
// measure the total arc length along the spline
|
||||
float totalDefaultArcLength = defaultSpline.arcLength(1.0f);
|
||||
float t = defaultSpline.arcLengthInverse(_spine2SplineRatio * totalDefaultArcLength);
|
||||
glm::vec3 defaultSplineSpine2Translation = defaultSpline(t);
|
||||
|
||||
_spine2SplineOffset = spine2Position - defaultSplineSpine2Translation;
|
||||
|
||||
qCDebug(avatars_renderer) << "the avatar spline numbers are " << _spine2SplineRatio << " and " << _spine2SplineOffset;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Avatar::clearUnscaledEyeHeightCache() {
|
||||
_unscaledEyeHeightCache.set(DEFAULT_AVATAR_EYE_HEIGHT);
|
||||
}
|
||||
|
||||
void Avatar::clearSpine2SplineRatioCache() {
|
||||
_spine2SplineRatio = DEFAULT_AVATAR_EYE_HEIGHT;
|
||||
_spine2SplineOffset = glm::vec3();
|
||||
}
|
||||
|
||||
float Avatar::getUnscaledEyeHeightFromSkeleton() const {
|
||||
|
||||
// TODO: if performance becomes a concern we can cache this value rather then computing it everytime.
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <render/Scene.h>
|
||||
#include <graphics-scripting/Forward.h>
|
||||
#include <GLMHelpers.h>
|
||||
#include <CubicHermiteSpline.h>
|
||||
|
||||
#include "Head.h"
|
||||
#include "SkeletonModel.h"
|
||||
|
@ -228,6 +229,9 @@ public:
|
|||
virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override { return false; }
|
||||
virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override { return false; }
|
||||
|
||||
virtual glm::vec3 getSpine2SplineOffset() const { return _spine2SplineOffset; }
|
||||
virtual float getSpine2SplineRatio() const { return _spine2SplineRatio; }
|
||||
|
||||
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
|
||||
virtual void setAttachmentData(const QVector<AttachmentData>& attachmentData) override;
|
||||
|
||||
|
@ -499,7 +503,9 @@ public slots:
|
|||
protected:
|
||||
float getUnscaledEyeHeightFromSkeleton() const;
|
||||
void buildUnscaledEyeHeightCache();
|
||||
void buildSpine2SplineRatioCache();
|
||||
void clearUnscaledEyeHeightCache();
|
||||
void clearSpine2SplineRatioCache();
|
||||
virtual const QString& getSessionDisplayNameForTransport() const override { return _empty; } // Save a tiny bit of bandwidth. Mixer won't look at what we send.
|
||||
QString _empty{};
|
||||
virtual void maybeUpdateSessionDisplayNameFromTransport(const QString& sessionDisplayName) override { _sessionDisplayName = sessionDisplayName; } // don't use no-op setter!
|
||||
|
@ -552,6 +558,7 @@ protected:
|
|||
float getHeadHeight() const;
|
||||
float getPelvisFloatingHeight() const;
|
||||
glm::vec3 getDisplayNamePosition() const;
|
||||
|
||||
|
||||
Transform calculateDisplayNameTransform(const ViewFrustum& view, const glm::vec3& textPosition) const;
|
||||
void renderDisplayName(gpu::Batch& batch, const ViewFrustum& view, const glm::vec3& textPosition) const;
|
||||
|
@ -607,6 +614,8 @@ protected:
|
|||
float _displayNameAlpha { 1.0f };
|
||||
|
||||
ThreadSafeValueCache<float> _unscaledEyeHeightCache { DEFAULT_AVATAR_EYE_HEIGHT };
|
||||
float _spine2SplineRatio { DEFAULT_SPINE2_SPLINE_PROPORTION };
|
||||
glm::vec3 _spine2SplineOffset;
|
||||
|
||||
std::unordered_map<std::string, graphics::MultiMaterial> _materials;
|
||||
std::mutex _materialsLock;
|
||||
|
|
|
@ -20,6 +20,7 @@ const float DEFAULT_AVATAR_EYE_TO_TOP_OF_HEAD = 0.11f; // meters
|
|||
const float DEFAULT_AVATAR_NECK_TO_TOP_OF_HEAD = 0.185f; // meters
|
||||
const float DEFAULT_AVATAR_NECK_HEIGHT = DEFAULT_AVATAR_HEIGHT - DEFAULT_AVATAR_NECK_TO_TOP_OF_HEAD;
|
||||
const float DEFAULT_AVATAR_EYE_HEIGHT = DEFAULT_AVATAR_HEIGHT - DEFAULT_AVATAR_EYE_TO_TOP_OF_HEAD;
|
||||
const float DEFAULT_SPINE2_SPLINE_PROPORTION = 0.75f;
|
||||
const float DEFAULT_AVATAR_SUPPORT_BASE_LEFT = -0.25f;
|
||||
const float DEFAULT_AVATAR_SUPPORT_BASE_RIGHT = 0.25f;
|
||||
const float DEFAULT_AVATAR_SUPPORT_BASE_FRONT = -0.20f;
|
||||
|
|
Loading…
Reference in a new issue