mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 20:56:52 +02:00
Avatar Debug Draw Default Pose now works
This commit is contained in:
parent
6cfd831a5a
commit
fe683edb66
4 changed files with 61 additions and 73 deletions
|
@ -628,7 +628,7 @@ void MyAvatar::setEnableDebugDrawDefaultPose(bool isEnabled) {
|
||||||
_enableDebugDrawDefaultPose = isEnabled;
|
_enableDebugDrawDefaultPose = isEnabled;
|
||||||
|
|
||||||
if (!isEnabled) {
|
if (!isEnabled) {
|
||||||
AnimDebugDraw::getInstance().removeSkeleton("myAvatar");
|
AnimDebugDraw::getInstance().removeAbsolutePoses("myAvatarDefaultPoses");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,7 +636,7 @@ void MyAvatar::setEnableDebugDrawAnimPose(bool isEnabled) {
|
||||||
_enableDebugDrawAnimPose = isEnabled;
|
_enableDebugDrawAnimPose = isEnabled;
|
||||||
|
|
||||||
if (!isEnabled) {
|
if (!isEnabled) {
|
||||||
AnimDebugDraw::getInstance().removeAbsolutePoses("myAvatar");
|
AnimDebugDraw::getInstance().removeAbsolutePoses("myAvatarAnimPoses");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1261,27 +1261,27 @@ void MyAvatar::preRender(RenderArgs* renderArgs) {
|
||||||
|
|
||||||
auto animSkeleton = _rig->getAnimSkeleton();
|
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) {
|
if (_enableDebugDrawDefaultPose && animSkeleton) {
|
||||||
|
AnimPose xform(glm::vec3(1), getOrientation(), getPosition());
|
||||||
glm::vec4 gray(0.2f, 0.2f, 0.2f, 0.2f);
|
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) {
|
if (_enableDebugDrawAnimPose && animSkeleton) {
|
||||||
glm::vec4 cyan(0.1f, 0.6f, 0.6f, 1.0f);
|
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
|
// build absolute AnimPoseVec from rig
|
||||||
AnimPoseVec absPoses;
|
AnimPoseVec absPoses;
|
||||||
absPoses.reserve(rig->getJointStateCount());
|
absPoses.reserve(_rig->getJointStateCount());
|
||||||
for (int i = 0; i < _rig->getJointStateCount(); i++) {
|
for (int i = 0; i < _rig->getJointStateCount(); i++) {
|
||||||
absPoses.push_back(AnimPose(_rig->getJointTransform(i)));
|
absPoses.push_back(AnimPose(_rig->getJointTransform(i)));
|
||||||
}
|
}
|
||||||
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatar", animSkeleton, absPoses, xform, cyan);
|
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarAnimPoses", animSkeleton, absPoses, xform, cyan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -172,8 +172,9 @@ void Rig::destroyAnimGraph() {
|
||||||
|
|
||||||
void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset) {
|
void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset) {
|
||||||
|
|
||||||
setModelOffset(modelOffset);
|
|
||||||
_geometryOffset = AnimPose(geometry.offset);
|
_geometryOffset = AnimPose(geometry.offset);
|
||||||
|
setModelOffset(modelOffset);
|
||||||
|
|
||||||
_animSkeleton = std::make_shared<AnimSkeleton>(geometry);
|
_animSkeleton = std::make_shared<AnimSkeleton>(geometry);
|
||||||
|
|
||||||
computeEyesInRootFrame(_animSkeleton->getRelativeDefaultPoses());
|
computeEyesInRootFrame(_animSkeleton->getRelativeDefaultPoses());
|
||||||
|
@ -181,7 +182,7 @@ void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOff
|
||||||
_relativePoses.clear();
|
_relativePoses.clear();
|
||||||
_relativePoses = _animSkeleton->getRelativeDefaultPoses();
|
_relativePoses = _animSkeleton->getRelativeDefaultPoses();
|
||||||
|
|
||||||
buildAbsolutePoses();
|
buildAbsoluteRigPoses(_relativePoses, _absolutePoses, true);
|
||||||
|
|
||||||
_overridePoses.clear();
|
_overridePoses.clear();
|
||||||
_overridePoses = _animSkeleton->getRelativeDefaultPoses();
|
_overridePoses = _animSkeleton->getRelativeDefaultPoses();
|
||||||
|
@ -189,6 +190,8 @@ void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOff
|
||||||
_overrideFlags.clear();
|
_overrideFlags.clear();
|
||||||
_overrideFlags.resize(_animSkeleton->getNumJoints(), false);
|
_overrideFlags.resize(_animSkeleton->getNumJoints(), false);
|
||||||
|
|
||||||
|
buildAbsoluteRigPoses(_animSkeleton->getRelativeDefaultPoses(), _absoluteDefaultPoses);
|
||||||
|
|
||||||
_rootJointIndex = geometry.rootJointIndex;
|
_rootJointIndex = geometry.rootJointIndex;
|
||||||
_leftHandJointIndex = geometry.leftHandJointIndex;
|
_leftHandJointIndex = geometry.leftHandJointIndex;
|
||||||
_leftElbowJointIndex = _leftHandJointIndex >= 0 ? geometry.joints.at(_leftHandJointIndex).parentIndex : -1;
|
_leftElbowJointIndex = _leftHandJointIndex >= 0 ? geometry.joints.at(_leftHandJointIndex).parentIndex : -1;
|
||||||
|
@ -207,7 +210,7 @@ void Rig::reset(const FBXGeometry& geometry) {
|
||||||
_relativePoses.clear();
|
_relativePoses.clear();
|
||||||
_relativePoses = _animSkeleton->getRelativeDefaultPoses();
|
_relativePoses = _animSkeleton->getRelativeDefaultPoses();
|
||||||
|
|
||||||
buildAbsolutePoses();
|
buildAbsoluteRigPoses(_relativePoses, _absolutePoses, true);
|
||||||
|
|
||||||
_overridePoses.clear();
|
_overridePoses.clear();
|
||||||
_overridePoses = _animSkeleton->getRelativeDefaultPoses();
|
_overridePoses = _animSkeleton->getRelativeDefaultPoses();
|
||||||
|
@ -215,6 +218,8 @@ void Rig::reset(const FBXGeometry& geometry) {
|
||||||
_overrideFlags.clear();
|
_overrideFlags.clear();
|
||||||
_overrideFlags.resize(_animSkeleton->getNumJoints(), false);
|
_overrideFlags.resize(_animSkeleton->getNumJoints(), false);
|
||||||
|
|
||||||
|
buildAbsoluteRigPoses(_animSkeleton->getRelativeDefaultPoses(), _absoluteDefaultPoses);
|
||||||
|
|
||||||
_rootJointIndex = geometry.rootJointIndex;
|
_rootJointIndex = geometry.rootJointIndex;
|
||||||
_leftHandJointIndex = geometry.leftHandJointIndex;
|
_leftHandJointIndex = geometry.leftHandJointIndex;
|
||||||
_leftElbowJointIndex = _leftHandJointIndex >= 0 ? geometry.joints.at(_leftHandJointIndex).parentIndex : -1;
|
_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) {
|
void Rig::setModelOffset(const glm::mat4& modelOffsetMat) {
|
||||||
_modelOffset = AnimPose(modelOffset);
|
AnimPose newModelOffset = AnimPose(modelOffsetMat);
|
||||||
|
if (!isEqual(_modelOffset.trans, newModelOffset.trans) ||
|
||||||
|
!isEqual(_modelOffset.rot, newModelOffset.rot) ||
|
||||||
|
!isEqual(_modelOffset.scale, newModelOffset.scale)) {
|
||||||
|
|
||||||
// compute geometryToAvatarTransforms
|
_modelOffset = newModelOffset;
|
||||||
glm::quat yFlip180 = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f));
|
|
||||||
_geometryToRigTransform = AnimPose(glm::vec3(1), yFlip180, glm::vec3()) * _modelOffset * _geometryOffset;
|
// compute geometryToAvatarTransforms
|
||||||
_rigToGeometryTransform = glm::inverse(_geometryToRigTransform);
|
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 {
|
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 {
|
AnimPose Rig::getAbsoluteDefaultPose(int index) const {
|
||||||
if (_animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints()) {
|
if (_animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints()) {
|
||||||
return AnimPose(_geometryToRigTransform) * _animSkeleton->getAbsoluteDefaultPose(index);
|
return _absoluteDefaultPoses[index];
|
||||||
} else {
|
} else {
|
||||||
return AnimPose::identity;
|
return AnimPose::identity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AnimPoseVec& Rig::getAbsoluteDefaultPoses() const {
|
||||||
|
return _absoluteDefaultPoses;
|
||||||
|
}
|
||||||
|
|
||||||
// animation reference speeds.
|
// animation reference speeds.
|
||||||
static const std::vector<float> FORWARD_SPEEDS = { 0.4f, 1.4f, 4.5f }; // m/s
|
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
|
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();
|
applyOverridePoses();
|
||||||
buildAbsolutePoses();
|
buildAbsoluteRigPoses(_relativePoses, _absolutePoses, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rig::inverseKinematics(int endIndex, glm::vec3 targetPosition, const glm::quat& targetRotation, float priority,
|
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) {
|
if (!_animSkeleton) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(_animSkeleton->getNumJoints() == (int)_relativePoses.size());
|
ASSERT(_animSkeleton->getNumJoints() == (int)relativePoses.size());
|
||||||
|
|
||||||
_absolutePoses.resize(_relativePoses.size());
|
// flatten all poses out so they are absolute not relative
|
||||||
for (int i = 0; i < (int)_relativePoses.size(); i++) {
|
absolutePosesOut.resize(relativePoses.size());
|
||||||
|
for (int i = 0; i < (int)relativePoses.size(); i++) {
|
||||||
int parentIndex = _animSkeleton->getParentIndex(i);
|
int parentIndex = _animSkeleton->getParentIndex(i);
|
||||||
if (parentIndex == -1) {
|
if (parentIndex == -1) {
|
||||||
_absolutePoses[i] = _relativePoses[i];
|
absolutePosesOut[i] = relativePoses[i];
|
||||||
} else {
|
} 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++) {
|
for (int i = 0; i < (int)_absolutePoses.size(); i++) {
|
||||||
_absolutePoses[i] = rootTransform * _absolutePoses[i];
|
absolutePosesOut[i] = geometryToRigTransform * absolutePosesOut[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ public:
|
||||||
int getJointStateCount() const;
|
int getJointStateCount() const;
|
||||||
int indexOfJoint(const QString& jointName) 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 getJointStateRotation(int index, glm::quat& rotation) const;
|
||||||
bool getJointStateTranslation(int index, glm::vec3& translation) const;
|
bool getJointStateTranslation(int index, glm::vec3& translation) const;
|
||||||
|
@ -147,6 +147,7 @@ public:
|
||||||
const glm::vec3& getEyesInRootFrame() const { return _eyesInRootFrame; }
|
const glm::vec3& getEyesInRootFrame() const { return _eyesInRootFrame; }
|
||||||
|
|
||||||
AnimPose getAbsoluteDefaultPose(int index) const; // avatar space
|
AnimPose getAbsoluteDefaultPose(int index) const; // avatar space
|
||||||
|
const AnimPoseVec& getAbsoluteDefaultPoses() const; // avatar space
|
||||||
|
|
||||||
void copyJointsIntoJointData(QVector<JointData>& jointDataVec) const;
|
void copyJointsIntoJointData(QVector<JointData>& jointDataVec) const;
|
||||||
void copyJointsFromJointData(const QVector<JointData>& jointDataVec);
|
void copyJointsFromJointData(const QVector<JointData>& jointDataVec);
|
||||||
|
@ -155,7 +156,7 @@ public:
|
||||||
bool isValid(int index) const { return _animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints(); }
|
bool isValid(int index) const { return _animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints(); }
|
||||||
void updateAnimationStateHandlers();
|
void updateAnimationStateHandlers();
|
||||||
void applyOverridePoses();
|
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 updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist);
|
||||||
void updateNeckJoint(int index, const HeadParameters& params);
|
void updateNeckJoint(int index, const HeadParameters& params);
|
||||||
|
@ -173,6 +174,8 @@ public:
|
||||||
AnimPoseVec _overridePoses; // geometry space relative to parent.
|
AnimPoseVec _overridePoses; // geometry space relative to parent.
|
||||||
std::vector<bool> _overrideFlags;
|
std::vector<bool> _overrideFlags;
|
||||||
|
|
||||||
|
AnimPoseVec _absoluteDefaultPoses; // avatar space, not relative to parent.
|
||||||
|
|
||||||
glm::mat4 _geometryToRigTransform;
|
glm::mat4 _geometryToRigTransform;
|
||||||
glm::mat4 _rigToGeometryTransform;
|
glm::mat4 _rigToGeometryTransform;
|
||||||
|
|
||||||
|
|
|
@ -349,17 +349,6 @@ void AnimDebugDraw::update() {
|
||||||
|
|
||||||
// AJT: FIX ME
|
// 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) {
|
for (auto& iter : _animNodes) {
|
||||||
AnimNode::ConstPointer& animNode = std::get<0>(iter.second);
|
AnimNode::ConstPointer& animNode = std::get<0>(iter.second);
|
||||||
auto poses = animNode->getPosesInternal();
|
auto poses = animNode->getPosesInternal();
|
||||||
|
@ -407,37 +396,6 @@ void AnimDebugDraw::update() {
|
||||||
Vertex* verts = (Vertex*)data._vertexBuffer->editData();
|
Vertex* verts = (Vertex*)data._vertexBuffer->editData();
|
||||||
Vertex* v = verts;
|
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
|
// AJT: FIXME
|
||||||
/*
|
/*
|
||||||
// draw animNodes
|
// draw animNodes
|
||||||
|
|
Loading…
Reference in a new issue