got the spline working in myskeleton model, need to clean up

This commit is contained in:
amantley 2019-01-29 17:25:25 -08:00
parent 3994311583
commit e2a729b68b
4 changed files with 70 additions and 15 deletions

View file

@ -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;

View file

@ -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 {

View file

@ -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);

View file

@ -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