Avatar Debug Draw Default Pose now works

This commit is contained in:
Anthony J. Thibault 2015-11-21 10:53:24 -08:00
parent 6cfd831a5a
commit fe683edb66
4 changed files with 61 additions and 73 deletions

View file

@ -628,7 +628,7 @@ void MyAvatar::setEnableDebugDrawDefaultPose(bool isEnabled) {
_enableDebugDrawDefaultPose = isEnabled;
if (!isEnabled) {
AnimDebugDraw::getInstance().removeSkeleton("myAvatar");
AnimDebugDraw::getInstance().removeAbsolutePoses("myAvatarDefaultPoses");
}
}
@ -636,7 +636,7 @@ void MyAvatar::setEnableDebugDrawAnimPose(bool isEnabled) {
_enableDebugDrawAnimPose = isEnabled;
if (!isEnabled) {
AnimDebugDraw::getInstance().removeAbsolutePoses("myAvatar");
AnimDebugDraw::getInstance().removeAbsolutePoses("myAvatarAnimPoses");
}
}
@ -1261,27 +1261,27 @@ void MyAvatar::preRender(RenderArgs* renderArgs) {
auto animSkeleton = _rig->getAnimSkeleton();
// bones are aligned such that z is forward, not -z.
glm::quat rotY180 = glm::angleAxis((float)M_PI, glm::vec3(0.0f, 1.0f, 0.0f));
AnimPose xform(glm::vec3(1), getOrientation() * rotY180, getPosition());
if (_enableDebugDrawDefaultPose && animSkeleton) {
AnimPose xform(glm::vec3(1), getOrientation(), getPosition());
glm::vec4 gray(0.2f, 0.2f, 0.2f, 0.2f);
AnimDebugDraw::getInstance().addSkeleton("myAvatar", animSkeleton, xform, gray);
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarDefaultPoses", animSkeleton, _rig->getAbsoluteDefaultPoses(), xform, gray);
}
if (_enableDebugDrawAnimPose && animSkeleton) {
glm::vec4 cyan(0.1f, 0.6f, 0.6f, 1.0f);
auto rig = _skeletonModel.getRig();
// getJointTransforms are aligned such that z is forward, not -z.
// so they need a 180 flip
glm::quat rotY180 = glm::angleAxis((float)M_PI, glm::vec3(0.0f, 1.0f, 0.0f));
AnimPose xform(glm::vec3(1), getOrientation() * rotY180, getPosition());
// build absolute AnimPoseVec from rig
AnimPoseVec absPoses;
absPoses.reserve(rig->getJointStateCount());
absPoses.reserve(_rig->getJointStateCount());
for (int i = 0; i < _rig->getJointStateCount(); i++) {
absPoses.push_back(AnimPose(_rig->getJointTransform(i)));
}
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatar", animSkeleton, absPoses, xform, cyan);
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarAnimPoses", animSkeleton, absPoses, xform, cyan);
}
}

View file

@ -172,8 +172,9 @@ void Rig::destroyAnimGraph() {
void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset) {
setModelOffset(modelOffset);
_geometryOffset = AnimPose(geometry.offset);
setModelOffset(modelOffset);
_animSkeleton = std::make_shared<AnimSkeleton>(geometry);
computeEyesInRootFrame(_animSkeleton->getRelativeDefaultPoses());
@ -181,7 +182,7 @@ void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOff
_relativePoses.clear();
_relativePoses = _animSkeleton->getRelativeDefaultPoses();
buildAbsolutePoses();
buildAbsoluteRigPoses(_relativePoses, _absolutePoses, true);
_overridePoses.clear();
_overridePoses = _animSkeleton->getRelativeDefaultPoses();
@ -189,6 +190,8 @@ void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOff
_overrideFlags.clear();
_overrideFlags.resize(_animSkeleton->getNumJoints(), false);
buildAbsoluteRigPoses(_animSkeleton->getRelativeDefaultPoses(), _absoluteDefaultPoses);
_rootJointIndex = geometry.rootJointIndex;
_leftHandJointIndex = geometry.leftHandJointIndex;
_leftElbowJointIndex = _leftHandJointIndex >= 0 ? geometry.joints.at(_leftHandJointIndex).parentIndex : -1;
@ -207,7 +210,7 @@ void Rig::reset(const FBXGeometry& geometry) {
_relativePoses.clear();
_relativePoses = _animSkeleton->getRelativeDefaultPoses();
buildAbsolutePoses();
buildAbsoluteRigPoses(_relativePoses, _absolutePoses, true);
_overridePoses.clear();
_overridePoses = _animSkeleton->getRelativeDefaultPoses();
@ -215,6 +218,8 @@ void Rig::reset(const FBXGeometry& geometry) {
_overrideFlags.clear();
_overrideFlags.resize(_animSkeleton->getNumJoints(), false);
buildAbsoluteRigPoses(_animSkeleton->getRelativeDefaultPoses(), _absoluteDefaultPoses);
_rootJointIndex = geometry.rootJointIndex;
_leftHandJointIndex = geometry.leftHandJointIndex;
_leftElbowJointIndex = _leftHandJointIndex >= 0 ? geometry.joints.at(_leftHandJointIndex).parentIndex : -1;
@ -244,13 +249,22 @@ int Rig::indexOfJoint(const QString& jointName) const {
}
}
void Rig::setModelOffset(const glm::mat4& modelOffset) {
_modelOffset = AnimPose(modelOffset);
void Rig::setModelOffset(const glm::mat4& modelOffsetMat) {
AnimPose newModelOffset = AnimPose(modelOffsetMat);
if (!isEqual(_modelOffset.trans, newModelOffset.trans) ||
!isEqual(_modelOffset.rot, newModelOffset.rot) ||
!isEqual(_modelOffset.scale, newModelOffset.scale)) {
// compute geometryToAvatarTransforms
glm::quat yFlip180 = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f));
_geometryToRigTransform = AnimPose(glm::vec3(1), yFlip180, glm::vec3()) * _modelOffset * _geometryOffset;
_rigToGeometryTransform = glm::inverse(_geometryToRigTransform);
_modelOffset = newModelOffset;
// compute geometryToAvatarTransforms
glm::quat yFlip180 = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f));
_geometryToRigTransform = AnimPose(glm::vec3(1), yFlip180, glm::vec3()) * _modelOffset * _geometryOffset;
_rigToGeometryTransform = glm::inverse(_geometryToRigTransform);
// rebuild cached default poses
buildAbsoluteRigPoses(_animSkeleton->getRelativeDefaultPoses(), _absoluteDefaultPoses);
}
}
bool Rig::getJointStateRotation(int index, glm::quat& rotation) const {
@ -430,12 +444,16 @@ void Rig::computeEyesInRootFrame(const AnimPoseVec& poses) {
AnimPose Rig::getAbsoluteDefaultPose(int index) const {
if (_animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints()) {
return AnimPose(_geometryToRigTransform) * _animSkeleton->getAbsoluteDefaultPose(index);
return _absoluteDefaultPoses[index];
} else {
return AnimPose::identity;
}
}
const AnimPoseVec& Rig::getAbsoluteDefaultPoses() const {
return _absoluteDefaultPoses;
}
// animation reference speeds.
static const std::vector<float> FORWARD_SPEEDS = { 0.4f, 1.4f, 4.5f }; // m/s
static const std::vector<float> BACKWARD_SPEEDS = { 0.6f, 1.45f }; // m/s
@ -719,7 +737,7 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) {
}
applyOverridePoses();
buildAbsolutePoses();
buildAbsoluteRigPoses(_relativePoses, _absolutePoses, true);
}
void Rig::inverseKinematics(int endIndex, glm::vec3 targetPosition, const glm::quat& targetRotation, float priority,
@ -1005,26 +1023,35 @@ void Rig::applyOverridePoses() {
}
}
void Rig::buildAbsolutePoses() {
// AJT: TODO: we should ALWAYS have the 180 flip.
// However currently matrices used for rendering require it.
// we need to find were the 180 is applied down the pipe and remove it,
// cluster matrices? render parts?
void Rig::buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut, bool omitY180Flip) {
if (!_animSkeleton) {
return;
}
ASSERT(_animSkeleton->getNumJoints() == (int)_relativePoses.size());
ASSERT(_animSkeleton->getNumJoints() == (int)relativePoses.size());
_absolutePoses.resize(_relativePoses.size());
for (int i = 0; i < (int)_relativePoses.size(); i++) {
// flatten all poses out so they are absolute not relative
absolutePosesOut.resize(relativePoses.size());
for (int i = 0; i < (int)relativePoses.size(); i++) {
int parentIndex = _animSkeleton->getParentIndex(i);
if (parentIndex == -1) {
_absolutePoses[i] = _relativePoses[i];
absolutePosesOut[i] = relativePoses[i];
} else {
_absolutePoses[i] = _absolutePoses[parentIndex] * _relativePoses[i];
absolutePosesOut[i] = absolutePosesOut[parentIndex] * relativePoses[i];
}
}
AnimPose rootTransform(_modelOffset * _geometryOffset);
// transform all absolute poses into rig space.
AnimPose geometryToRigTransform(_geometryToRigTransform);
if (omitY180Flip) {
geometryToRigTransform = _modelOffset * _geometryOffset;
}
for (int i = 0; i < (int)_absolutePoses.size(); i++) {
_absolutePoses[i] = rootTransform * _absolutePoses[i];
absolutePosesOut[i] = geometryToRigTransform * absolutePosesOut[i];
}
}

View file

@ -88,7 +88,7 @@ public:
int getJointStateCount() const;
int indexOfJoint(const QString& jointName) const;
void setModelOffset(const glm::mat4& modelOffset);
void setModelOffset(const glm::mat4& modelOffsetMat);
bool getJointStateRotation(int index, glm::quat& rotation) const;
bool getJointStateTranslation(int index, glm::vec3& translation) const;
@ -147,6 +147,7 @@ public:
const glm::vec3& getEyesInRootFrame() const { return _eyesInRootFrame; }
AnimPose getAbsoluteDefaultPose(int index) const; // avatar space
const AnimPoseVec& getAbsoluteDefaultPoses() const; // avatar space
void copyJointsIntoJointData(QVector<JointData>& jointDataVec) const;
void copyJointsFromJointData(const QVector<JointData>& jointDataVec);
@ -155,7 +156,7 @@ public:
bool isValid(int index) const { return _animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints(); }
void updateAnimationStateHandlers();
void applyOverridePoses();
void buildAbsolutePoses();
void buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut, bool omitY180Flip = false);
void updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist);
void updateNeckJoint(int index, const HeadParameters& params);
@ -173,6 +174,8 @@ public:
AnimPoseVec _overridePoses; // geometry space relative to parent.
std::vector<bool> _overrideFlags;
AnimPoseVec _absoluteDefaultPoses; // avatar space, not relative to parent.
glm::mat4 _geometryToRigTransform;
glm::mat4 _rigToGeometryTransform;

View file

@ -349,17 +349,6 @@ void AnimDebugDraw::update() {
// AJT: FIX ME
/*
for (auto& iter : _skeletons) {
AnimSkeleton::ConstPointer& skeleton = std::get<0>(iter.second);
numVerts += skeleton->getNumJoints() * VERTICES_PER_BONE;
for (int i = 0; i < skeleton->getNumJoints(); i++) {
auto parentIndex = skeleton->getParentIndex(i);
if (parentIndex >= 0) {
numVerts += VERTICES_PER_LINK;
}
}
}
for (auto& iter : _animNodes) {
AnimNode::ConstPointer& animNode = std::get<0>(iter.second);
auto poses = animNode->getPosesInternal();
@ -407,37 +396,6 @@ void AnimDebugDraw::update() {
Vertex* verts = (Vertex*)data._vertexBuffer->editData();
Vertex* v = verts;
// AJT: fixme
// draw skeletons
/*
for (auto& iter : _skeletons) {
AnimSkeleton::ConstPointer& skeleton = std::get<0>(iter.second);
AnimPose rootPose = std::get<1>(iter.second);
int hipsIndex = skeleton->nameToJointIndex("Hips");
if (hipsIndex >= 0) {
rootPose.trans -= skeleton->getRelativeBindPose(hipsIndex).trans;
}
glm::vec4 color = std::get<2>(iter.second);
for (int i = 0; i < skeleton->getNumJoints(); i++) {
AnimPose pose = skeleton->getAbsoluteBindPose(i);
const float radius = BONE_RADIUS / (pose.scale.x * rootPose.scale.x);
// draw bone
addBone(rootPose, pose, radius, v);
// draw link to parent
auto parentIndex = skeleton->getParentIndex(i);
if (parentIndex >= 0) {
assert(parentIndex < skeleton->getNumJoints());
AnimPose parentPose = skeleton->getAbsoluteBindPose(parentIndex);
addLink(rootPose, pose, parentPose, radius, color, v);
}
}
}
*/
// AJT: FIXME
/*
// draw animNodes