Commit 5751beb2 authored by Isaak Lim's avatar Isaak Lim

introduced an initial fix for the rotation around the joints in the...

introduced an initial fix for the rotation around the joints in the SkeletonEditingPlugin and updated a misleading comment in the documentation for the function localTranslation in PoseT

git-svn-id: 383ad7c9-94d9-4d36-a494-682f7c89f535
parent d30a8992
......@@ -514,6 +514,7 @@ void SkeletonEditingPlugin::manipulatorMoved( QtTranslationManipulatorNode* _nod
int objectId = _node->getIdentifier();
// rotation matrix from the manipulator
ACG::Matrix4x4d mat;
mat = _node->matrix();
......@@ -536,35 +537,26 @@ void SkeletonEditingPlugin::manipulatorMoved( QtTranslationManipulatorNode* _nod
Skeleton::Pose* currentPose = activePose(PluginFunctions::skeletonObject(object));
//now lets get our angle
//first, compute a simple rotation
// we compute the rotation angle by applying the
// rotation matrix from the manipulator to an arbitrary point
ACG::Vec3d tmpVec = ACG::Vec3d( 1.0, 1.0, 1.0 ).normalize();
ACG::Vec3d tmpRotVec = mat.transform_point( tmpVec ).normalize();
const ACG::Vec3d rotation_axis = cross(tmpVec,tmpRotVec).normalize();
//extract the changing for our wanted rotation
tmpVec = tmpVec - rotation_axis * ( dot(rotation_axis,tmpVec));
tmpRotVec = tmpRotVec - rotation_axis * ( dot(rotation_axis,tmpRotVec));
const ACG::Vec3d right = cross(tmpVec, rotation_axis).normalize();
double angle = acos( dot(tmpVec , tmpRotVec) );
if (angle != angle)//NaN?
if (angle != angle) // NaN?
//compute the direction
if (cross(right,tmpRotVec)[0] < 0)
// compute the direction of the rotation
if (dot(right, tmpRotVec) < 0)
angle = -angle;
//now we can pass our rotation
// count all joints from including the picked joint to the selected joint
Skeleton::Joint* iter = pickedJoint;
unsigned int count_joint = 0;
while(iter && ((!iter->selected() && !iter->isRoot()) || iter == pickedJoint))
......@@ -572,29 +564,29 @@ void SkeletonEditingPlugin::manipulatorMoved( QtTranslationManipulatorNode* _nod
iter = iter->parent();
//the weight of our rotation
//joints far away of our rotated joint will not be rotated so much
double weight = 1.0 - (1.0/count_joint);
// the weight of our rotation
// the first joint gets rotated by 100%
double weight = 1.0;
//rotate all joints
//with the given angle and the given weight
//iter can be NULL, when pickedJoint == Root
// rotate the joints including the picked joints and its children
// until the selected joint
// with the given angle and the given weight
// iter can be NULL, when pickedJoint == Root
iter = pickedJoint;
while(iter && ((!iter->selected() && !iter->isRoot()) || iter == pickedJoint))
unsigned int id = iter->id();
//get our rotation_axis. notice: vector given back by "localTranslation" is in localMatrix space
ACG::Vec3d axis = currentPose->localMatrixInv(id).transform_vector(currentPose->localTranslation(id));
// get our rotation axis. notice: vector given back by "localTranslation" is in localMatrix space
ACG::Vec3d axis = currentPose->localTranslation(id);
ACG::Quaterniond quaternion(axis, weight*angle);
//pass our matrix to the global space
ACG::Vec3d tr = currentPose->globalTranslation(id);
ACG::Matrix4x4d changingMatrix = quaternion.rotation_matrix() * currentPose->globalMatrix(id);
currentPose->setGlobalMatrix(id,changingMatrix, true);
currentPose->setGlobalTranslation(id,tr, true);
// rotate the joint around its own axis
ACG::Matrix4x4d newLocalMatrix = currentPose->localMatrix(id) * quaternion.rotation_matrix();
currentPose->setLocalMatrix(id, newLocalMatrix, true);
iter = iter->parent();
// interpolate the weight of the rotation between the joints
weight -= 1.0/count_joint;
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