Commit 280a4c0e authored by Mike Kremer's avatar Mike Kremer

Made root joint translatable. Added some documentation.

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@13151 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 362ad5c5
...@@ -342,150 +342,168 @@ void SkeletonEditingPlugin::transformJoint(int _objectId, int _jointId, ...@@ -342,150 +342,168 @@ void SkeletonEditingPlugin::transformJoint(int _objectId, int _jointId,
if (_matrix(0, 3) == 0 && _matrix(1, 3) == 0 && _matrix(2, 3) == 0) // no translation if (_matrix(0, 3) == 0 && _matrix(1, 3) == 0 && _matrix(2, 3) == 0) // no translation
return; return;
if (!joint->parent()) if (joint->isRoot()) {
return;
/*
// init params * Change translation of root joint.
bool parentIsNotBranch = (joint->parent()->size() == 1); */
bool hasOneChild = (joint->size() == 1);
ACG::Vec3d oldParentAxis(0.0, 0.0, 0.0); transformer.translateJoint(joint, ACG::Vec3d(_matrix(0, 3), _matrix(1, 3), _matrix(2, 3)), true);
ACG::Vec3d oldJointAxis(0.0, 0.0, 0.0);
ACG::Vec3d transParentAxis(0.0, 0.0, 0.0); } else {
ACG::Vec3d transJointAxis(0.0, 0.0, 0.0);
ACG::Vec3d parentRotAxis(0.0, 0.0, 0.0); /*
ACG::Vec3d jointRotAxis(0.0, 0.0, 0.0); * Change translation of non-root joint.
double parentRotAngle = 0.0; *
double jointRotAngle = 0.0; * In these cases, the rotation of the coordinate frame of the parent
* joint (unless it is not a branching joint) as well as the
// get the original parent axis: parent joint -----> current joint * the rotation of the coordinate frame of the current joint have to be
oldParentAxis = activePose->localTranslation(_jointId); * corrected in the following way:
// get the original joint axis: current joint -----> child joint *
if (hasOneChild) * We compute the rotation of the affected joints' coordinate system
oldJointAxis = activePose->localTranslation(joint->child(0)->id()); * such that the local(!) translation of the respective child
* joint remains constant. So, in 2D, consider configuration
// store the joint axes of all animations before the translation of the current joint * A --> B --> C, where C is a child of B is a child of A.
// so that the rotations can be calculated for the animation poses * If C has translation (2, 0) and B has translation (3,5), then, after
std::vector<ACG::Vec3d> oldAnimJoint, oldAnimParent; * global translation of B, the coordinate frames of A and B have to be rotated
for (unsigned int a = 0; a < skeleton->animationCount(); ++a) { * such that the joint axes remain constant, so B lies on the line (0,0) + x*(3,5)
for (unsigned int iFrame = 0; iFrame * with respect to A's coordinate system and C lies somewhere on the line (0,0) + y*(2,0)
< skeleton->animation(a)->frameCount(); iFrame++) { * with respect to B's coordinate system.
Skeleton::Pose* pose = skeleton->animation(a)->pose(iFrame); *
*/
if (hasOneChild)
oldAnimJoint.push_back( // init params
pose->localTranslation(joint->child(0)->id())); bool parentIsNotBranch = (joint->parent()->size() == 1);
bool hasOneChild = (joint->size() == 1);
oldAnimParent.push_back(pose->localTranslation(_jointId)); ACG::Vec3d oldParentAxis(0.0, 0.0, 0.0);
ACG::Vec3d oldJointAxis(0.0, 0.0, 0.0);
ACG::Vec3d transParentAxis(0.0, 0.0, 0.0);
ACG::Vec3d transJointAxis(0.0, 0.0, 0.0);
ACG::Vec3d parentRotAxis(0.0, 0.0, 0.0);
ACG::Vec3d jointRotAxis(0.0, 0.0, 0.0);
double parentRotAngle = 0.0;
double jointRotAngle = 0.0;
// get the original parent axis: parent joint -----> current joint
oldParentAxis = activePose->localTranslation(_jointId);
// get the original joint axis: current joint -----> child joint
if (hasOneChild)
oldJointAxis = activePose->localTranslation(joint->child(0)->id());
// store the joint axes of all animations before the translation of the current joint
// so that the rotations can be calculated for the animation poses
std::vector<ACG::Vec3d> oldAnimJoint, oldAnimParent;
for (unsigned int a = 0; a < skeleton->animationCount(); ++a) {
for (unsigned int iFrame = 0; iFrame < skeleton->animation(a)->frameCount(); iFrame++) {
Skeleton::Pose* pose = skeleton->animation(a)->pose(iFrame);
if (hasOneChild)
oldAnimJoint.push_back(pose->localTranslation(joint->child(0)->id()));
oldAnimParent.push_back(pose->localTranslation(_jointId));
}
} }
}
// translate the joint // translate the joint
transformer.translateJoint(joint, transformer.translateJoint(joint, ACG::Vec3d(_matrix(0, 3), _matrix(1, 3), _matrix(2, 3)), true);
ACG::Vec3d(_matrix(0, 3), _matrix(1, 3), _matrix(2, 3)), true);
// get translated parent axis // get translated parent axis
transParentAxis = activePose->localTranslation(_jointId); transParentAxis = activePose->localTranslation(_jointId);
if (hasOneChild) { if (hasOneChild) {
// get translated joint axis // get translated joint axis
transJointAxis = activePose->localTranslation(joint->child(0)->id()); transJointAxis = activePose->localTranslation(joint->child(0)->id());
} }
// now calculate the rotation that has to occur for a translation of the joint:
// get the rotation axis and angle between the old and new parent axis // now calculate the rotation that has to occur for a translation of the joint:
if (!ACG::Geometry::rotationOfTwoVectors<double>(oldParentAxis,
transParentAxis, parentRotAxis, parentRotAngle))
return;
// get rotation axis and angle between old and new joint axis // get the rotation axis and angle between the old and new parent axis
if (hasOneChild) { if (!ACG::Geometry::rotationOfTwoVectors<double>(oldParentAxis, transParentAxis, parentRotAxis, parentRotAngle))
if (!ACG::Geometry::rotationOfTwoVectors<double>(oldJointAxis,
transJointAxis, jointRotAxis, jointRotAngle))
return; return;
}
if (parentIsNotBranch) { // get rotation axis and angle between old and new joint axis
// parent rotation matrix if (hasOneChild) {
ACG::GLMatrixT<double> parentRotMatrix; if (!ACG::Geometry::rotationOfTwoVectors<double>(oldJointAxis, transJointAxis, jointRotAxis, jointRotAngle))
parentRotMatrix.identity(); return;
parentRotMatrix.rotate(parentRotAngle, parentRotAxis); }
// apply rotation to parent joint
ACG::Matrix4x4d localParent = activePose->localMatrix(
joint->parent()->id());
localParent *= parentRotMatrix;
activePose->setLocalMatrix(joint->parent()->id(), localParent, false);
}
if (hasOneChild) {
// joint rotation matrix
ACG::GLMatrixT<double> jointRotMatrix;
jointRotMatrix.identity();
jointRotMatrix.rotate(jointRotAngle, jointRotAxis);
// apply current joint
ACG::Matrix4x4d localJoint = activePose->localMatrix(joint->id());
localJoint *= jointRotMatrix;
activePose->setLocalMatrix(joint->id(), localJoint, false);
}
// apply rotations to animation
std::vector<ACG::Vec3d>::iterator jointIt, parentIt;
jointIt = oldAnimJoint.begin();
parentIt = oldAnimParent.begin();
for (unsigned int a = 0; a < skeleton->animationCount(); ++a) {
for (unsigned int iFrame = 0; iFrame
< skeleton->animation(a)->frameCount(); iFrame++) {
Skeleton::Pose* pose = skeleton->animation(a)->pose(iFrame);
// only apply rotation to parent joint if it is not a branch
if (parentIsNotBranch) {
// get the rotation axis and angle between the old and new parent axis
ACG::Vec3d translatedParent = pose->localTranslation(_jointId);
ACG::Vec3d parentRotAxis(0.0, 0.0, 0.0);
double parentRotAngle = 0.0;
if (!ACG::Geometry::rotationOfTwoVectors<double>(*parentIt,
translatedParent, parentRotAxis, parentRotAngle))
return;
// parent rotation matrix
ACG::GLMatrixT<double> parentRotMatrix;
parentRotMatrix.identity();
parentRotMatrix.rotate(parentRotAngle, parentRotAxis);
// apply rotation to parent joint
ACG::Matrix4x4d parentMat =
pose->localMatrix(joint->parent()->id());
parentMat *= parentRotMatrix;
pose->setLocalMatrix(joint->parent()->id(), parentMat, false);
++parentIt;
}
if (hasOneChild) { if (parentIsNotBranch) {
// get rotation axis and angle between old and new joint axis // parent rotation matrix
ACG::Vec3d translatedAxis = pose->localTranslation( ACG::GLMatrixT<double> parentRotMatrix;
joint->child(0)->id()); parentRotMatrix.identity();
ACG::Vec3d jointRotAxis(0.0, 0.0, 0.0); parentRotMatrix.rotate(parentRotAngle, parentRotAxis);
double jointRotAngle = 0.0;
if (!ACG::Geometry::rotationOfTwoVectors<double>(*jointIt, // apply rotation to parent joint
translatedAxis, jointRotAxis, jointRotAngle)) ACG::Matrix4x4d localParent = activePose->localMatrix(joint->parent()->id());
return; localParent *= parentRotMatrix;
activePose->setLocalMatrix(joint->parent()->id(), localParent, false);
}
// joint rotation matrix if (hasOneChild) {
ACG::GLMatrixT<double> jointRotMatrix; // joint rotation matrix
jointRotMatrix.identity(); ACG::GLMatrixT<double> jointRotMatrix;
jointRotMatrix.rotate(jointRotAngle, jointRotAxis); jointRotMatrix.identity();
jointRotMatrix.rotate(jointRotAngle, jointRotAxis);
// apply rotation to current joint // apply current joint
ACG::Matrix4x4d localMat = pose->localMatrix(joint->id()); ACG::Matrix4x4d localJoint = activePose->localMatrix(joint->id());
localMat *= jointRotMatrix; localJoint *= jointRotMatrix;
pose->setLocalMatrix(joint->id(), localMat, false); activePose->setLocalMatrix(joint->id(), localJoint, false);
}
++jointIt; // apply rotations to animation
std::vector<ACG::Vec3d>::iterator jointIt, parentIt;
jointIt = oldAnimJoint.begin();
parentIt = oldAnimParent.begin();
for (unsigned int a = 0; a < skeleton->animationCount(); ++a) {
for (unsigned int iFrame = 0; iFrame < skeleton->animation(a)->frameCount(); iFrame++) {
Skeleton::Pose* pose = skeleton->animation(a)->pose(iFrame);
// only apply rotation to parent joint if it is not a branch
if (parentIsNotBranch) {
// get the rotation axis and angle between the old and new parent axis
ACG::Vec3d translatedParent = pose->localTranslation(_jointId);
ACG::Vec3d parentRotAxis(0.0, 0.0, 0.0);
double parentRotAngle = 0.0;
if (!ACG::Geometry::rotationOfTwoVectors<double>(*parentIt, translatedParent, parentRotAxis,
parentRotAngle))
return;
// parent rotation matrix
ACG::GLMatrixT<double> parentRotMatrix;
parentRotMatrix.identity();
parentRotMatrix.rotate(parentRotAngle, parentRotAxis);
// apply rotation to parent joint
ACG::Matrix4x4d parentMat = pose->localMatrix(joint->parent()->id());
parentMat *= parentRotMatrix;
pose->setLocalMatrix(joint->parent()->id(), parentMat, false);
++parentIt;
}
if (hasOneChild) {
// get rotation axis and angle between old and new joint axis
ACG::Vec3d translatedAxis = pose->localTranslation(joint->child(0)->id());
ACG::Vec3d jointRotAxis(0.0, 0.0, 0.0);
double jointRotAngle = 0.0;
if (!ACG::Geometry::rotationOfTwoVectors<double>(*jointIt, translatedAxis, jointRotAxis, jointRotAngle))
return;
// joint rotation matrix
ACG::GLMatrixT<double> jointRotMatrix;
jointRotMatrix.identity();
jointRotMatrix.rotate(jointRotAngle, jointRotAxis);
// apply rotation to current joint
ACG::Matrix4x4d localMat = pose->localMatrix(joint->id());
localMat *= jointRotMatrix;
pose->setLocalMatrix(joint->id(), localMat, false);
++jointIt;
}
} }
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment