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