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: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@12996 383ad7c9-94d9-4d36-a494-682f7c89f535
parent d30a8992
...@@ -73,7 +73,7 @@ void SkeletonEditingPlugin::pluginsInitialized() { ...@@ -73,7 +73,7 @@ void SkeletonEditingPlugin::pluginsInitialized() {
connect(toolBarActions_, SIGNAL(triggered(QAction*)), this, SLOT(slotSetEditingMode(QAction*)) ); connect(toolBarActions_, SIGNAL(triggered(QAction*)), this, SLOT(slotSetEditingMode(QAction*)) );
emit addToolbar(toolbar_); emit addToolbar(toolbar_);
pickToolbar_ = new QToolBar(tr("Skeleton Editing")); pickToolbar_ = new QToolBar(tr("Skeleton Editing"));
pickToolbar_->setAttribute(Qt::WA_AlwaysShowToolTips, true); pickToolbar_->setAttribute(Qt::WA_AlwaysShowToolTips, true);
pickToolBarActions_ = new QActionGroup(pickToolbar_); pickToolBarActions_ = new QActionGroup(pickToolbar_);
...@@ -122,7 +122,7 @@ void SkeletonEditingPlugin::pluginsInitialized() { ...@@ -122,7 +122,7 @@ void SkeletonEditingPlugin::pluginsInitialized() {
transformAllManipAction_->setCheckable(true); transformAllManipAction_->setCheckable(true);
transformAllManipAction_->setChecked(transformAllFrames_); transformAllManipAction_->setChecked(transformAllFrames_);
pickToolbar_->addAction(transformAllManipAction_); pickToolbar_->addAction(transformAllManipAction_);
transformChildManipAction_ = new QAction(tr("Transform Child Joints"), pickToolBarActions_); transformChildManipAction_ = new QAction(tr("Transform Child Joints"), pickToolBarActions_);
transformChildManipAction_->setStatusTip(tr("Apply joint transformation to child joints as well and thereby rigidly move the whole subtree.")); transformChildManipAction_->setStatusTip(tr("Apply joint transformation to child joints as well and thereby rigidly move the whole subtree."));
transformChildManipAction_->setToolTip(tr("<B>Transform child joints</B><br>Apply joint transformation to all child joints as well.")); transformChildManipAction_->setToolTip(tr("<B>Transform child joints</B><br>Apply joint transformation to all child joints as well."));
...@@ -130,7 +130,7 @@ void SkeletonEditingPlugin::pluginsInitialized() { ...@@ -130,7 +130,7 @@ void SkeletonEditingPlugin::pluginsInitialized() {
transformChildManipAction_->setCheckable(true); transformChildManipAction_->setCheckable(true);
transformChildManipAction_->setChecked(transformChildJoints_); transformChildManipAction_->setChecked(transformChildJoints_);
pickToolbar_->addAction(transformChildManipAction_); pickToolbar_->addAction(transformChildManipAction_);
inverseKinematicAction_ = new QAction(tr("Inverse kinematic"), pickToolBarActions_); inverseKinematicAction_ = new QAction(tr("Inverse kinematic"), pickToolBarActions_);
inverseKinematicAction_->setStatusTip(tr("Move selected joint using inverse kinematic.")); inverseKinematicAction_->setStatusTip(tr("Move selected joint using inverse kinematic."));
inverseKinematicAction_->setToolTip(tr("<B>Inverse kinematic</B><br>Move selected joint using inverse kinematic.")); inverseKinematicAction_->setToolTip(tr("<B>Inverse kinematic</B><br>Move selected joint using inverse kinematic."));
...@@ -272,10 +272,10 @@ void SkeletonEditingPlugin::slotPickModeChanged( const std::string& _mode) ...@@ -272,10 +272,10 @@ void SkeletonEditingPlugin::slotPickModeChanged( const std::string& _mode)
insertJointAction_->setChecked( _mode == "InsertJoints" ); insertJointAction_->setChecked( _mode == "InsertJoints" );
deleteJointAction_->setChecked( _mode == "DeleteJoints" ); deleteJointAction_->setChecked( _mode == "DeleteJoints" );
selectJointAction_->setChecked( _mode == "SelectJoints" ); selectJointAction_->setChecked( _mode == "SelectJoints" );
skeletonEditingAction_->setChecked( (_mode == "MoveJoints") ||(_mode == "InsertJoints") skeletonEditingAction_->setChecked( (_mode == "MoveJoints") ||(_mode == "InsertJoints")
||(_mode == "DeleteJoints")||(_mode == "SelectJoints") ); ||(_mode == "DeleteJoints")||(_mode == "SelectJoints") );
showManipulators(); showManipulators();
} }
...@@ -312,7 +312,7 @@ void SkeletonEditingPlugin::slotPickToolbarAction(QAction* _action) ...@@ -312,7 +312,7 @@ void SkeletonEditingPlugin::slotPickToolbarAction(QAction* _action)
inverseKinematic_ = inverseKinematicAction_->isChecked(); inverseKinematic_ = inverseKinematicAction_->isChecked();
else if (_action == rotateCoordSystemAction_) else if (_action == rotateCoordSystemAction_)
rotateCoordSystem_ = rotateCoordSystemAction_->isChecked(); rotateCoordSystem_ = rotateCoordSystemAction_->isChecked();
moveJointAction_->setChecked( _action == moveJointAction_); moveJointAction_->setChecked( _action == moveJointAction_);
insertJointAction_->setChecked( _action == insertJointAction_ ); insertJointAction_->setChecked( _action == insertJointAction_ );
deleteJointAction_->setChecked( _action == deleteJointAction_ ); deleteJointAction_->setChecked( _action == deleteJointAction_ );
...@@ -380,7 +380,7 @@ void SkeletonEditingPlugin::placeManip(QMouseEvent * _event) { ...@@ -380,7 +380,7 @@ void SkeletonEditingPlugin::placeManip(QMouseEvent * _event) {
//perform picking //perform picking
successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING, _event->pos(), node_idx, target_idx, &hitPoint) && successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING, _event->pos(), node_idx, target_idx, &hitPoint) &&
PluginFunctions::getPickedObject(node_idx, object); PluginFunctions::getPickedObject(node_idx, object);
//reenable picking for anything //reenable picking for anything
for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS) ; o_it != PluginFunctions::objectsEnd(); ++o_it) for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS) ; o_it != PluginFunctions::objectsEnd(); ++o_it)
o_it->enablePicking( true ); o_it->enablePicking( true );
...@@ -470,10 +470,10 @@ void SkeletonEditingPlugin::placeManip(QMouseEvent * _event) { ...@@ -470,10 +470,10 @@ void SkeletonEditingPlugin::placeManip(QMouseEvent * _event) {
// Disconnect a previously connected Signal // Disconnect a previously connected Signal
disconnect(object->manipulatorNode() , SIGNAL(manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)), disconnect(object->manipulatorNode() , SIGNAL(manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)),
this , SLOT( manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*))); this , SLOT( manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)));
disconnect(object->manipulatorNode() , SIGNAL(positionChanged(QtTranslationManipulatorNode*)), disconnect(object->manipulatorNode() , SIGNAL(positionChanged(QtTranslationManipulatorNode*)),
this , SLOT( ManipulatorPositionChanged(QtTranslationManipulatorNode*))); this , SLOT( ManipulatorPositionChanged(QtTranslationManipulatorNode*)));
// Reconnect the signals. // Reconnect the signals.
connect(object->manipulatorNode() , SIGNAL(manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)), connect(object->manipulatorNode() , SIGNAL(manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)),
this , SLOT( manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*))); this , SLOT( manipulatorMoved(QtTranslationManipulatorNode*,QMouseEvent*)));
...@@ -482,9 +482,9 @@ void SkeletonEditingPlugin::placeManip(QMouseEvent * _event) { ...@@ -482,9 +482,9 @@ void SkeletonEditingPlugin::placeManip(QMouseEvent * _event) {
this , SLOT( ManipulatorPositionChanged(QtTranslationManipulatorNode*))); this , SLOT( ManipulatorPositionChanged(QtTranslationManipulatorNode*)));
emit updateView(); emit updateView();
bool found = false; bool found = false;
for (uint i=0; i < activeManipulators_.size(); i++) for (uint i=0; i < activeManipulators_.size(); i++)
if ( activeManipulators_[i] == object->id() ){ if ( activeManipulators_[i] == object->id() ){
found = true; found = true;
...@@ -514,6 +514,7 @@ void SkeletonEditingPlugin::manipulatorMoved( QtTranslationManipulatorNode* _nod ...@@ -514,6 +514,7 @@ void SkeletonEditingPlugin::manipulatorMoved( QtTranslationManipulatorNode* _nod
int objectId = _node->getIdentifier(); int objectId = _node->getIdentifier();
// rotation matrix from the manipulator
ACG::Matrix4x4d mat; ACG::Matrix4x4d mat;
mat.identity(); mat.identity();
mat = _node->matrix(); mat = _node->matrix();
...@@ -536,35 +537,26 @@ void SkeletonEditingPlugin::manipulatorMoved( QtTranslationManipulatorNode* _nod ...@@ -536,35 +537,26 @@ void SkeletonEditingPlugin::manipulatorMoved( QtTranslationManipulatorNode* _nod
Skeleton::Pose* currentPose = activePose(PluginFunctions::skeletonObject(object)); Skeleton::Pose* currentPose = activePose(PluginFunctions::skeletonObject(object));
//now lets get our angle // we compute the rotation angle by applying the
//first, compute a simple rotation // rotation matrix from the manipulator to an arbitrary point
ACG::Vec3d tmpVec = ACG::Vec3d( 1.0, 1.0, 1.0 ).normalize(); ACG::Vec3d tmpVec = ACG::Vec3d( 1.0, 1.0, 1.0 ).normalize();
ACG::Vec3d tmpRotVec = mat.transform_point( tmpVec ).normalize(); ACG::Vec3d tmpRotVec = mat.transform_point( tmpVec ).normalize();
const ACG::Vec3d rotation_axis = cross(tmpVec,tmpRotVec).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));
tmpVec.normalize();
tmpRotVec.normalize();
const ACG::Vec3d right = cross(tmpVec, rotation_axis).normalize(); const ACG::Vec3d right = cross(tmpVec, rotation_axis).normalize();
double angle = acos( dot(tmpVec , tmpRotVec) ); double angle = acos( dot(tmpVec , tmpRotVec) );
if (angle != angle)//NaN? if (angle != angle) // NaN?
return; return;
//compute the direction // compute the direction of the rotation
if (cross(right,tmpRotVec)[0] < 0) if (dot(right, tmpRotVec) < 0)
angle = -angle; angle = -angle;
//now we can pass our rotation // count all joints from including the picked joint to the selected joint
Skeleton::Joint* iter = pickedJoint; Skeleton::Joint* iter = pickedJoint;
unsigned int count_joint = 0; unsigned int count_joint = 0;
while(iter && ((!iter->selected() && !iter->isRoot()) || iter == pickedJoint)) while(iter && ((!iter->selected() && !iter->isRoot()) || iter == pickedJoint))
{ {
...@@ -572,29 +564,29 @@ void SkeletonEditingPlugin::manipulatorMoved( QtTranslationManipulatorNode* _nod ...@@ -572,29 +564,29 @@ void SkeletonEditingPlugin::manipulatorMoved( QtTranslationManipulatorNode* _nod
iter = iter->parent(); iter = iter->parent();
} }
//the weight of our rotation // the weight of our rotation
//joints far away of our rotated joint will not be rotated so much // the first joint gets rotated by 100%
double weight = 1.0 - (1.0/count_joint); double weight = 1.0;
//rotate all joints // rotate the joints including the picked joints and its children
//with the given angle and the given weight // until the selected joint
//iter can be NULL, when pickedJoint == Root // with the given angle and the given weight
// iter can be NULL, when pickedJoint == Root
iter = pickedJoint; iter = pickedJoint;
while(iter && ((!iter->selected() && !iter->isRoot()) || iter == pickedJoint)) while(iter && ((!iter->selected() && !iter->isRoot()) || iter == pickedJoint))
{ {
unsigned int id = iter->id(); unsigned int id = iter->id();
//get our rotation_axis. notice: vector given back by "localTranslation" is in localMatrix space // 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)); ACG::Vec3d axis = currentPose->localTranslation(id);
ACG::Quaterniond quaternion(axis, weight*angle); ACG::Quaterniond quaternion(axis, weight*angle);
//pass our matrix to the global space // rotate the joint around its own axis
ACG::Vec3d tr = currentPose->globalTranslation(id); ACG::Matrix4x4d newLocalMatrix = currentPose->localMatrix(id) * quaternion.rotation_matrix();
ACG::Matrix4x4d changingMatrix = quaternion.rotation_matrix() * currentPose->globalMatrix(id); currentPose->setLocalMatrix(id, newLocalMatrix, true);
currentPose->setGlobalMatrix(id,changingMatrix, true);
currentPose->setGlobalTranslation(id,tr, true);
iter = iter->parent(); iter = iter->parent();
// interpolate the weight of the rotation between the joints
weight -= 1.0/count_joint; weight -= 1.0/count_joint;
} }
} }
...@@ -880,7 +872,7 @@ void SkeletonEditingPlugin::deleteJoint(QMouseEvent* _event) ...@@ -880,7 +872,7 @@ void SkeletonEditingPlugin::deleteJoint(QMouseEvent* _event)
else{ else{
//delete on release //delete on release
if ( wasSelected ){ if ( wasSelected ){
if (skeleton->jointCount() > 1){ if (skeleton->jointCount() > 1){
skeleton->removeJoint(joint); skeleton->removeJoint(joint);
PluginFunctions::skeletonObject(object)->updateIndices(); PluginFunctions::skeletonObject(object)->updateIndices();
...@@ -1322,18 +1314,18 @@ OpenMesh::Vec3d SkeletonEditingPlugin::getNearestJoint(SkeletonObject* _skeleton ...@@ -1322,18 +1314,18 @@ OpenMesh::Vec3d SkeletonEditingPlugin::getNearestJoint(SkeletonObject* _skeleton
ACG::Vec3d bestJoint; ACG::Vec3d bestJoint;
double bestDistance = DBL_MAX; double bestDistance = DBL_MAX;
_bestJointID = -1; _bestJointID = -1;
Skeleton* skeleton = PluginFunctions::skeleton(_skeletonObj); Skeleton* skeleton = PluginFunctions::skeleton(_skeletonObj);
Skeleton::Pose* pose = activePose(_skeletonObj); Skeleton::Pose* pose = activePose(_skeletonObj);
//find the nearest joint //find the nearest joint
for (unsigned int joint = 0; joint < skeleton->jointCount(); joint++){ for (unsigned int joint = 0; joint < skeleton->jointCount(); joint++){
double dist = (_hitPoint - pose->globalTranslation(joint)).sqrnorm(); double dist = (_hitPoint - pose->globalTranslation(joint)).sqrnorm();
if (dist < bestDistance){ if (dist < bestDistance){
bestJoint = pose->globalTranslation(joint); bestJoint = pose->globalTranslation(joint);
_bestJointID = joint; _bestJointID = 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