mirror of
https://github.com/lubosz/overte.git
synced 2025-04-14 04:26:18 +02:00
got the spline working in myskeleton model, need to clean up
This commit is contained in:
parent
3994311583
commit
e2a729b68b
4 changed files with 70 additions and 15 deletions
|
@ -33,6 +33,39 @@ Rig::CharacterControllerState convertCharacterControllerState(CharacterControlle
|
|||
};
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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"));
|
||||
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;
|
||||
|
||||
// the the ik targets to compute the spline with
|
||||
CubicHermiteSplineFunctorWithArcLength spline = computeSplineFromTipAndBase(headIKTargetPose, hipsIKTargetPose);
|
||||
|
||||
// measure the total arc length along the spline
|
||||
float totalArcLength = spline.arcLength(1.0f);
|
||||
float t = spline.arcLengthInverse(ratio * totalArcLength);
|
||||
|
||||
glm::vec3 spine2Translation = spline(t);
|
||||
|
||||
return spine2Translation;
|
||||
|
||||
}
|
||||
|
||||
static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) {
|
||||
glm::mat4 worldToSensorMat = glm::inverse(myAvatar->getSensorToWorldMatrix());
|
||||
|
||||
|
@ -233,6 +266,12 @@ 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;
|
||||
|
||||
const float SPINE2_ROTATION_FILTER = 0.5f;
|
||||
AnimPose currentSpine2Pose;
|
||||
AnimPose currentHeadPose;
|
||||
|
@ -253,6 +292,11 @@ 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();
|
||||
qCDebug(animation) << "my skeleton model spline spine2 " << rigSpine2.trans();
|
||||
qCDebug(animation) << "my skeleton model current spine2 " << currentSpine2Pose.trans();
|
||||
// qCDebug(animation) << "my skeleton model spline hips " << sensorToRigPose * sensorHips;
|
||||
// qCDebug(animation) << "my skeleton model current hips " << currentHipsPose.trans();
|
||||
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;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <avatars-renderer/SkeletonModel.h>
|
||||
#include <AnimUtil.h>
|
||||
#include "MyAvatar.h"
|
||||
#include <CubicHermiteSpline.h>
|
||||
|
||||
/// A skeleton loaded from a model.
|
||||
class MySkeletonModel : public SkeletonModel {
|
||||
|
|
|
@ -147,7 +147,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const
|
|||
tipTarget.setWeight(1.0f);
|
||||
tipTarget.setFlexCoefficients(_numTipTargetFlexCoefficients, _tipTargetFlexCoefficients);
|
||||
|
||||
|
||||
/*
|
||||
AnimChain jointChain;
|
||||
AnimPoseVec absolutePoses;
|
||||
absolutePoses.resize(_poses.size());
|
||||
|
@ -156,6 +156,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const
|
|||
solveTargetWithSpline(context, _baseJointIndex, tipTarget, absolutePoses, context.getEnableDebugDrawIKChains(), jointChain);
|
||||
jointChain.buildDirtyAbsolutePoses();
|
||||
jointChain.outputRelativePoses(_poses);
|
||||
*/
|
||||
|
||||
IKTarget midTarget;
|
||||
if (_midJointIndex != -1) {
|
||||
|
@ -167,7 +168,9 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const
|
|||
AnimPose afterSolveMidTarget = _skeleton->getAbsolutePose(_midJointIndex, _poses);
|
||||
// use the rotation from the ik target value, if there is one.
|
||||
glm::quat midTargetRotation = animVars.lookupRigToGeometry(_midRotationVar, afterSolveMidTarget.rot());
|
||||
AnimPose updatedMidTarget = AnimPose(midTargetRotation, afterSolveMidTarget.trans());
|
||||
glm::vec3 midTargetPosition = animVars.lookupRigToGeometry(_midPositionVar, afterSolveMidTarget.trans());
|
||||
AnimPose updatedMidTarget = AnimPose(midTargetRotation, midTargetPosition);
|
||||
//qCDebug(animation) << "spine2 in AnimSpline " << updatedMidTarget.trans();
|
||||
midTarget.setPose(updatedMidTarget.rot(), updatedMidTarget.trans());
|
||||
midTarget.setWeight(1.0f);
|
||||
midTarget.setFlexCoefficients(_numMidTargetFlexCoefficients, _midTargetFlexCoefficients);
|
||||
|
@ -194,9 +197,10 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const
|
|||
|
||||
// set the mid to tip segment to match the absolute rotation of the tip target.
|
||||
AnimPose midTargetPose(midTarget.getRotation(), midTarget.getTranslation());
|
||||
_poses[childOfMiddleJointIndex] = midTargetPose.inverse() * childOfMiddleJointAbsolutePoseAfterBaseTipSpline;
|
||||
//_poses[childOfMiddleJointIndex] = midTargetPose.inverse() * childOfMiddleJointAbsolutePoseAfterBaseTipSpline;
|
||||
}
|
||||
|
||||
_splineJointInfoMap.clear();
|
||||
|
||||
AnimChain upperJointChain;
|
||||
AnimPoseVec finalAbsolutePoses;
|
||||
|
@ -206,7 +210,7 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const
|
|||
solveTargetWithSpline(context, _midJointIndex, tipTarget, finalAbsolutePoses, context.getEnableDebugDrawIKChains(), upperJointChain);
|
||||
upperJointChain.buildDirtyAbsolutePoses();
|
||||
upperJointChain.outputRelativePoses(_poses);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -370,8 +374,10 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c
|
|||
tipPose.rot() = -tipPose.rot();
|
||||
}
|
||||
// find or create splineJointInfo for this target
|
||||
const std::vector<SplineJointInfo>* splineJointInfoVec = findOrCreateSplineJointInfo(context, target);
|
||||
const std::vector<SplineJointInfo>* splineJointInfoVec = findOrCreateSplineJointInfo(context, base, target);
|
||||
|
||||
//qCDebug(animation) << "the size of the splineJointInfo is " << splineJointInfoVec->size() << " and the base index is "<<baseIndex;
|
||||
|
||||
if (splineJointInfoVec && splineJointInfoVec->size() > 0) {
|
||||
const int baseParentIndex = _skeleton->getParentIndex(baseIndex);
|
||||
AnimPose parentAbsPose = (baseParentIndex >= 0) ? absolutePoses[baseParentIndex] : AnimPose();
|
||||
|
@ -403,9 +409,9 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c
|
|||
::blend(1, &absolutePoses[splineJointInfo.jointIndex], &desiredAbsPose, target.getFlexCoefficient(i), &flexedAbsPose);
|
||||
|
||||
AnimPose relPose = parentAbsPose.inverse() * flexedAbsPose;
|
||||
|
||||
/*
|
||||
bool constrained = false;
|
||||
if (splineJointInfo.jointIndex != _baseJointIndex) {
|
||||
if (splineJointInfo.jointIndex != base) {
|
||||
// constrain the amount the spine can stretch or compress
|
||||
float length = glm::length(relPose.trans());
|
||||
const float EPSILON = 0.0001f;
|
||||
|
@ -425,6 +431,7 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c
|
|||
relPose.trans() = glm::vec3(0.0f);
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (!chainInfoOut.setRelativePoseAtJointIndex(splineJointInfo.jointIndex, relPose)) {
|
||||
qCDebug(animation) << "we didn't find the joint index for the spline!!!!";
|
||||
}
|
||||
|
@ -439,13 +446,13 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, c
|
|||
}
|
||||
}
|
||||
|
||||
const std::vector<AnimSplineIK::SplineJointInfo>* AnimSplineIK::findOrCreateSplineJointInfo(const AnimContext& context, const IKTarget& target) const {
|
||||
const std::vector<AnimSplineIK::SplineJointInfo>* AnimSplineIK::findOrCreateSplineJointInfo(const AnimContext& context, int base, const IKTarget& target) const {
|
||||
// find or create splineJointInfo for this target
|
||||
auto iter = _splineJointInfoMap.find(target.getIndex());
|
||||
if (iter != _splineJointInfoMap.end()) {
|
||||
return &(iter->second);
|
||||
} else {
|
||||
computeAndCacheSplineJointInfosForIKTarget(context, target);
|
||||
computeAndCacheSplineJointInfosForIKTarget(context, base, target);
|
||||
auto iter = _splineJointInfoMap.find(target.getIndex());
|
||||
if (iter != _splineJointInfoMap.end()) {
|
||||
return &(iter->second);
|
||||
|
@ -455,12 +462,14 @@ const std::vector<AnimSplineIK::SplineJointInfo>* AnimSplineIK::findOrCreateSpli
|
|||
}
|
||||
|
||||
// pre-compute information about each joint influenced by this spline IK target.
|
||||
void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, const IKTarget& target) const {
|
||||
void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, int base, const IKTarget& target) const {
|
||||
std::vector<SplineJointInfo> splineJointInfoVec;
|
||||
|
||||
//qCDebug(animation) << "the base in compute cache is " << base;
|
||||
|
||||
// build spline between the default poses.
|
||||
AnimPose tipPose = _skeleton->getAbsoluteDefaultPose(target.getIndex());
|
||||
AnimPose basePose = _skeleton->getAbsoluteDefaultPose(_baseJointIndex);
|
||||
AnimPose basePose = _skeleton->getAbsoluteDefaultPose(base);
|
||||
|
||||
CubicHermiteSplineFunctorWithArcLength spline;
|
||||
if (target.getIndex() == _tipJointIndex) {
|
||||
|
@ -481,10 +490,11 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext&
|
|||
|
||||
int index = target.getIndex();
|
||||
int endIndex;
|
||||
// fix this statement. AA
|
||||
if (target.getIndex() == _tipJointIndex) {
|
||||
endIndex = _skeleton->getParentIndex(_baseJointIndex);
|
||||
endIndex = _skeleton->getParentIndex(base);
|
||||
} else {
|
||||
endIndex = _skeleton->getParentIndex(_baseJointIndex);
|
||||
endIndex = _skeleton->getParentIndex(base);
|
||||
}
|
||||
while (index != endIndex) {
|
||||
AnimPose defaultPose = _skeleton->getAbsoluteDefaultPose(index);
|
||||
|
|
|
@ -95,8 +95,8 @@ protected:
|
|||
|
||||
bool _lastEnableDebugDrawIKTargets { false };
|
||||
void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const;
|
||||
void computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, const IKTarget& target) const;
|
||||
const std::vector<SplineJointInfo>* findOrCreateSplineJointInfo(const AnimContext& context, const IKTarget& target) const;
|
||||
void computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, int base, const IKTarget& target) const;
|
||||
const std::vector<SplineJointInfo>* findOrCreateSplineJointInfo(const AnimContext& context, int base, const IKTarget& target) const;
|
||||
mutable std::map<int, std::vector<SplineJointInfo>> _splineJointInfoMap;
|
||||
|
||||
// no copies
|
||||
|
|
Loading…
Reference in a new issue