/** * $Id$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. The Blender * Foundation also sells licenses for use in proprietary software under * the Blender License. See http://www.blender.org/BL/ for information * about this. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * * The Original Code is: all of this file. * * Contributor(s): none yet. * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ #include "IK_Chain.h" using namespace std; IK_Chain:: IK_Chain( ) { // nothing to do; }; const vector & IK_Chain:: Segments( ) const { return m_segments; }; vector & IK_Chain:: Segments( ){ return m_segments; }; void IK_Chain:: UpdateGlobalTransformations( ){ // now iterate through the segment list // compute their local transformations if needed // assign their global transformations // (relative to chain origin) vector::const_iterator s_end = m_segments.end(); vector::iterator s_it = m_segments.begin(); MT_Transform global; global.setIdentity(); for (; s_it != s_end; ++s_it) { s_it->UpdateGlobal(global); global = s_it->GlobalTransform(); } // compute the position of the end effector and it's pose const MT_Transform &last_t = m_segments.back().GlobalTransform(); m_end_effector = last_t.getOrigin(); MT_Matrix3x3 last_basis = last_t.getBasis(); last_basis.transpose(); MT_Vector3 m_end_pose = last_basis[2]; }; const TNT::Matrix & IK_Chain:: Jacobian( ) const { return m_jacobian; } ; const TNT::Matrix & IK_Chain:: TransposedJacobian( ) const { return m_t_jacobian; }; void IK_Chain:: ComputeJacobian( ){ // let's assume that the chain's global transfomations // have already been computed. int dof = DoF(); int num_segs = m_segments.size(); vector::const_iterator segs = m_segments.begin(); m_t_jacobian.newsize(dof,3); m_jacobian.newsize(3,dof); // compute the transposed jacobian first int n; int i = 0; for (n= 0; n < num_segs; n++) { const MT_Matrix3x3 &basis = segs[n].GlobalTransform().getBasis(); const MT_Vector3 &origin = segs[n].GlobalSegmentStart(); MT_Vector3 p = origin-m_end_effector; // iterate through the active angle vectors of this segment int angle_ind =0; int seg_dof = segs[n].DoF(); const std::vector & angle_vectors = segs[n].AngleVectors(); for (angle_ind = 0;angle_ind ::const_iterator s_end = m_segments.end(); vector::const_iterator s_it = m_segments.begin(); int dof = 0; for (;s_it != s_end; ++s_it) { dof += s_it->DoF(); } return dof; }