Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Original author: Laurence 00024 * Contributor(s): Brecht 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #ifndef NAN_INCLUDED_IK_QSegment_h 00035 #define NAN_INCLUDED_IK_QSegment_h 00036 00037 #include "MT_Vector3.h" 00038 #include "MT_Transform.h" 00039 #include "MT_Matrix4x4.h" 00040 #include "IK_QJacobian.h" 00041 00042 #include <vector> 00043 00065 class IK_QSegment 00066 { 00067 public: 00068 virtual ~IK_QSegment(); 00069 00070 // start: a user defined translation 00071 // rest_basis: a user defined rotation 00072 // basis: a user defined rotation 00073 // length: length of this segment 00074 00075 void SetTransform( 00076 const MT_Vector3& start, 00077 const MT_Matrix3x3& rest_basis, 00078 const MT_Matrix3x3& basis, 00079 const MT_Scalar length 00080 ); 00081 00082 // tree structure access 00083 void SetParent(IK_QSegment *parent); 00084 00085 IK_QSegment *Child() const 00086 { return m_child; } 00087 00088 IK_QSegment *Sibling() const 00089 { return m_sibling; } 00090 00091 IK_QSegment *Parent() const 00092 { return m_parent; } 00093 00094 // for combining two joints into one from the interface 00095 void SetComposite(IK_QSegment *seg); 00096 00097 IK_QSegment *Composite() const 00098 { return m_composite; } 00099 00100 // number of degrees of freedom 00101 int NumberOfDoF() const 00102 { return m_num_DoF; } 00103 00104 // unique id for this segment, for identification in the jacobian 00105 int DoFId() const 00106 { return m_DoF_id; } 00107 00108 void SetDoFId(int dof_id) 00109 { m_DoF_id = dof_id; } 00110 00111 // the max distance of the end of this bone from the local origin. 00112 const MT_Scalar MaxExtension() const 00113 { return m_max_extension; } 00114 00115 // the change in rotation and translation w.r.t. the rest pose 00116 MT_Matrix3x3 BasisChange() const; 00117 MT_Vector3 TranslationChange() const; 00118 00119 // the start and end of the segment 00120 const MT_Point3 &GlobalStart() const 00121 { return m_global_start; } 00122 00123 const MT_Point3 &GlobalEnd() const 00124 { return m_global_transform.getOrigin(); } 00125 00126 // the global transformation at the end of the segment 00127 const MT_Transform &GlobalTransform() const 00128 { return m_global_transform; } 00129 00130 // is a translational segment? 00131 bool Translational() const 00132 { return m_translational; } 00133 00134 // locking (during inner clamping loop) 00135 bool Locked(int dof) const 00136 { return m_locked[dof]; } 00137 00138 void UnLock() 00139 { m_locked[0] = m_locked[1] = m_locked[2] = false; } 00140 00141 // per dof joint weighting 00142 MT_Scalar Weight(int dof) const 00143 { return m_weight[dof]; } 00144 00145 void ScaleWeight(int dof, MT_Scalar scale) 00146 { m_weight[dof] *= scale; } 00147 00148 // recursively update the global coordinates of this segment, 'global' 00149 // is the global transformation from the parent segment 00150 void UpdateTransform(const MT_Transform &global); 00151 00152 // get axis from rotation matrix for derivative computation 00153 virtual MT_Vector3 Axis(int dof) const=0; 00154 00155 // update the angles using the dTheta's computed using the jacobian matrix 00156 virtual bool UpdateAngle(const IK_QJacobian&, MT_Vector3&, bool*)=0; 00157 virtual void Lock(int, IK_QJacobian&, MT_Vector3&) {} 00158 virtual void UpdateAngleApply()=0; 00159 00160 // set joint limits 00161 virtual void SetLimit(int, MT_Scalar, MT_Scalar) {}; 00162 00163 // set joint weights (per axis) 00164 virtual void SetWeight(int, MT_Scalar) {}; 00165 00166 virtual void SetBasis(const MT_Matrix3x3& basis) { m_basis = basis; } 00167 00168 // functions needed for pole vector constraint 00169 void PrependBasis(const MT_Matrix3x3& mat); 00170 void Reset(); 00171 00172 // scale 00173 virtual void Scale(float scale); 00174 00175 protected: 00176 00177 // num_DoF: number of degrees of freedom 00178 IK_QSegment(int num_DoF, bool translational); 00179 00180 // remove child as a child of this segment 00181 void RemoveChild(IK_QSegment *child); 00182 00183 // tree structure variables 00184 IK_QSegment *m_parent; 00185 IK_QSegment *m_child; 00186 IK_QSegment *m_sibling; 00187 IK_QSegment *m_composite; 00188 00189 // full transform = 00190 // start * rest_basis * basis * translation 00191 MT_Vector3 m_start; 00192 MT_Matrix3x3 m_rest_basis; 00193 MT_Matrix3x3 m_basis; 00194 MT_Vector3 m_translation; 00195 00196 // original basis 00197 MT_Matrix3x3 m_orig_basis; 00198 MT_Vector3 m_orig_translation; 00199 00200 // maximum extension of this segment 00201 MT_Scalar m_max_extension; 00202 00203 // accumulated transformations starting from root 00204 MT_Point3 m_global_start; 00205 MT_Transform m_global_transform; 00206 00207 // number degrees of freedom, (first) id of this segments DOF's 00208 int m_num_DoF, m_DoF_id; 00209 00210 bool m_locked[3]; 00211 bool m_translational; 00212 MT_Scalar m_weight[3]; 00213 }; 00214 00215 class IK_QSphericalSegment : public IK_QSegment 00216 { 00217 public: 00218 IK_QSphericalSegment(); 00219 00220 MT_Vector3 Axis(int dof) const; 00221 00222 bool UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& delta, bool *clamp); 00223 void Lock(int dof, IK_QJacobian& jacobian, MT_Vector3& delta); 00224 void UpdateAngleApply(); 00225 00226 bool ComputeClampRotation(MT_Vector3& clamp); 00227 00228 void SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax); 00229 void SetWeight(int axis, MT_Scalar weight); 00230 00231 private: 00232 MT_Matrix3x3 m_new_basis; 00233 bool m_limit_x, m_limit_y, m_limit_z; 00234 MT_Scalar m_min[2], m_max[2]; 00235 MT_Scalar m_min_y, m_max_y, m_max_x, m_max_z, m_offset_x, m_offset_z; 00236 MT_Scalar m_locked_ax, m_locked_ay, m_locked_az; 00237 }; 00238 00239 class IK_QNullSegment : public IK_QSegment 00240 { 00241 public: 00242 IK_QNullSegment(); 00243 00244 bool UpdateAngle(const IK_QJacobian&, MT_Vector3&, bool*) { return false; } 00245 void UpdateAngleApply() {} 00246 00247 MT_Vector3 Axis(int) const { return MT_Vector3(0, 0, 0); } 00248 void SetBasis(const MT_Matrix3x3&) { m_basis.setIdentity(); } 00249 }; 00250 00251 class IK_QRevoluteSegment : public IK_QSegment 00252 { 00253 public: 00254 // axis: the axis of the DoF, in range 0..2 00255 IK_QRevoluteSegment(int axis); 00256 00257 MT_Vector3 Axis(int dof) const; 00258 00259 bool UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& delta, bool *clamp); 00260 void Lock(int dof, IK_QJacobian& jacobian, MT_Vector3& delta); 00261 void UpdateAngleApply(); 00262 00263 void SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax); 00264 void SetWeight(int axis, MT_Scalar weight); 00265 void SetBasis(const MT_Matrix3x3& basis); 00266 00267 private: 00268 int m_axis; 00269 MT_Scalar m_angle, m_new_angle; 00270 bool m_limit; 00271 MT_Scalar m_min, m_max; 00272 }; 00273 00274 class IK_QSwingSegment : public IK_QSegment 00275 { 00276 public: 00277 // XZ DOF, uses one direct rotation 00278 IK_QSwingSegment(); 00279 00280 MT_Vector3 Axis(int dof) const; 00281 00282 bool UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& delta, bool *clamp); 00283 void Lock(int dof, IK_QJacobian& jacobian, MT_Vector3& delta); 00284 void UpdateAngleApply(); 00285 00286 void SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax); 00287 void SetWeight(int axis, MT_Scalar weight); 00288 void SetBasis(const MT_Matrix3x3& basis); 00289 00290 private: 00291 MT_Matrix3x3 m_new_basis; 00292 bool m_limit_x, m_limit_z; 00293 MT_Scalar m_min[2], m_max[2]; 00294 MT_Scalar m_max_x, m_max_z, m_offset_x, m_offset_z; 00295 }; 00296 00297 class IK_QElbowSegment : public IK_QSegment 00298 { 00299 public: 00300 // XY or ZY DOF, uses two sequential rotations: first rotate around 00301 // X or Z, then rotate around Y (twist) 00302 IK_QElbowSegment(int axis); 00303 00304 MT_Vector3 Axis(int dof) const; 00305 00306 bool UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& delta, bool *clamp); 00307 void Lock(int dof, IK_QJacobian& jacobian, MT_Vector3& delta); 00308 void UpdateAngleApply(); 00309 00310 void SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax); 00311 void SetWeight(int axis, MT_Scalar weight); 00312 void SetBasis(const MT_Matrix3x3& basis); 00313 00314 private: 00315 int m_axis; 00316 00317 MT_Scalar m_twist, m_angle, m_new_twist, m_new_angle; 00318 MT_Scalar m_cos_twist, m_sin_twist; 00319 00320 bool m_limit, m_limit_twist; 00321 MT_Scalar m_min, m_max, m_min_twist, m_max_twist; 00322 }; 00323 00324 class IK_QTranslateSegment : public IK_QSegment 00325 { 00326 public: 00327 // 1DOF, 2DOF or 3DOF translational segments 00328 IK_QTranslateSegment(int axis1); 00329 IK_QTranslateSegment(int axis1, int axis2); 00330 IK_QTranslateSegment(); 00331 00332 MT_Vector3 Axis(int dof) const; 00333 00334 bool UpdateAngle(const IK_QJacobian &jacobian, MT_Vector3& delta, bool *clamp); 00335 void Lock(int, IK_QJacobian&, MT_Vector3&); 00336 void UpdateAngleApply(); 00337 00338 void SetWeight(int axis, MT_Scalar weight); 00339 void SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax); 00340 00341 void Scale(float scale); 00342 00343 private: 00344 int m_axis[3]; 00345 bool m_axis_enabled[3], m_limit[3]; 00346 MT_Vector3 m_new_translation; 00347 MT_Scalar m_min[3], m_max[3]; 00348 }; 00349 00350 #endif 00351