Blender V4.3
IK_QSegment.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#pragma once
10
11#include "IK_Math.h"
12#include "IK_QJacobian.h"
13
14#include <vector>
15
36 public:
37 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
38 virtual ~IK_QSegment();
39
40 // start: a user defined translation
41 // rest_basis: a user defined rotation
42 // basis: a user defined rotation
43 // length: length of this segment
44
45 void SetTransform(const Vector3d &start,
46 const Matrix3d &rest_basis,
47 const Matrix3d &basis,
48 const double length);
49
50 // tree structure access
51 void SetParent(IK_QSegment *parent);
52
54 {
55 return m_child;
56 }
57
59 {
60 return m_sibling;
61 }
62
64 {
65 return m_parent;
66 }
67
68 // for combining two joints into one from the interface
69 void SetComposite(IK_QSegment *seg);
70
72 {
73 return m_composite;
74 }
75
76 // number of degrees of freedom
77 int NumberOfDoF() const
78 {
79 return m_num_DoF;
80 }
81
82 // unique id for this segment, for identification in the jacobian
83 int DoFId() const
84 {
85 return m_DoF_id;
86 }
87
88 void SetDoFId(int dof_id)
89 {
90 m_DoF_id = dof_id;
91 }
92
93 // the max distance of the end of this bone from the local origin.
94 const double MaxExtension() const
95 {
96 return m_max_extension;
97 }
98
99 // the change in rotation and translation w.r.t. the rest pose
100 Matrix3d BasisChange() const;
101 Vector3d TranslationChange() const;
102
103 // the start and end of the segment
104 const Vector3d GlobalStart() const
105 {
106 return m_global_start;
107 }
108
109 const Vector3d GlobalEnd() const
110 {
111 return m_global_transform.translation();
112 }
113
114 // the global transformation at the end of the segment
115 const Affine3d &GlobalTransform() const
116 {
117 return m_global_transform;
118 }
119
120 // is a translational segment?
121 bool Translational() const
122 {
123 return m_translational;
124 }
125
126 // locking (during inner clamping loop)
127 bool Locked(int dof) const
128 {
129 return m_locked[dof];
130 }
131
132 void UnLock()
133 {
134 m_locked[0] = m_locked[1] = m_locked[2] = false;
135 }
136
137 // per dof joint weighting
138 double Weight(int dof) const
139 {
140 return m_weight[dof];
141 }
142
143 void ScaleWeight(int dof, double scale)
144 {
145 m_weight[dof] *= scale;
146 }
147
148 // recursively update the global coordinates of this segment, 'global'
149 // is the global transformation from the parent segment
150 void UpdateTransform(const Affine3d &global);
151
152 // get axis from rotation matrix for derivative computation
153 virtual Vector3d Axis(int dof) const = 0;
154
155 // update the angles using the dTheta's computed using the jacobian matrix
156 virtual bool UpdateAngle(const IK_QJacobian &, Vector3d &, bool *) = 0;
157 virtual void Lock(int, IK_QJacobian &, Vector3d &) {}
158 virtual void UpdateAngleApply() = 0;
159
160 // set joint limits
161 virtual void SetLimit(int, double, double) {}
162
163 // set joint weights (per axis)
164 virtual void SetWeight(int, double) {}
165
166 virtual void SetBasis(const Matrix3d &basis)
167 {
168 m_basis = basis;
169 }
170
171 // functions needed for pole vector constraint
172 void PrependBasis(const Matrix3d &mat);
173 void Reset();
174
175 // scale
176 virtual void Scale(double scale);
177
178 protected:
179 // num_DoF: number of degrees of freedom
180 IK_QSegment(int num_DoF, bool translational);
181
182 // remove child as a child of this segment
183 void RemoveChild(IK_QSegment *child);
184
185 // tree structure variables
190
191 // full transform =
192 // start * rest_basis * basis * translation
193 Vector3d m_start;
194 Matrix3d m_rest_basis;
195 Matrix3d m_basis;
197
198 // original basis
199 Matrix3d m_orig_basis;
201
202 // maximum extension of this segment
204
205 // accumulated transformations starting from root
208
209 // number degrees of freedom, (first) id of this segments DOF's
211
212 bool m_locked[3];
214 double m_weight[3];
215};
216
218 public:
220
221 Vector3d Axis(int dof) const;
222
223 bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp);
224 void Lock(int dof, IK_QJacobian &jacobian, Vector3d &delta);
225 void UpdateAngleApply();
226
227 bool ComputeClampRotation(Vector3d &clamp);
228
229 void SetLimit(int axis, double lmin, double lmax);
230 void SetWeight(int axis, double weight);
231
232 private:
233 Matrix3d m_new_basis;
234 bool m_limit_x, m_limit_y, m_limit_z;
235 double m_min[2], m_max[2];
236 double m_min_y, m_max_y, m_max_x, m_max_z, m_offset_x, m_offset_z;
237 double m_locked_ax, m_locked_ay, m_locked_az;
238};
239
241 public:
243
244 bool UpdateAngle(const IK_QJacobian &, Vector3d &, bool *)
245 {
246 return false;
247 }
249
250 Vector3d Axis(int) const
251 {
252 return Vector3d(0, 0, 0);
253 }
254 void SetBasis(const Matrix3d &)
255 {
256 m_basis.setIdentity();
257 }
258};
259
261 public:
262 // axis: the axis of the DoF, in range 0..2
263 IK_QRevoluteSegment(int axis);
264
265 Vector3d Axis(int dof) const;
266
267 bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp);
268 void Lock(int dof, IK_QJacobian &jacobian, Vector3d &delta);
269 void UpdateAngleApply();
270
271 void SetLimit(int axis, double lmin, double lmax);
272 void SetWeight(int axis, double weight);
273 void SetBasis(const Matrix3d &basis);
274
275 private:
276 int m_axis;
277 double m_angle, m_new_angle;
278 bool m_limit;
279 double m_min, m_max;
280};
281
283 public:
284 // XZ DOF, uses one direct rotation
286
287 Vector3d Axis(int dof) const;
288
289 bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp);
290 void Lock(int dof, IK_QJacobian &jacobian, Vector3d &delta);
291 void UpdateAngleApply();
292
293 void SetLimit(int axis, double lmin, double lmax);
294 void SetWeight(int axis, double weight);
295 void SetBasis(const Matrix3d &basis);
296
297 private:
298 Matrix3d m_new_basis;
299 bool m_limit_x, m_limit_z;
300 double m_min[2], m_max[2];
301 double m_max_x, m_max_z, m_offset_x, m_offset_z;
302};
303
305 public:
306 // XY or ZY DOF, uses two sequential rotations: first rotate around
307 // X or Z, then rotate around Y (twist)
308 IK_QElbowSegment(int axis);
309
310 Vector3d Axis(int dof) const;
311
312 bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp);
313 void Lock(int dof, IK_QJacobian &jacobian, Vector3d &delta);
314 void UpdateAngleApply();
315
316 void SetLimit(int axis, double lmin, double lmax);
317 void SetWeight(int axis, double weight);
318 void SetBasis(const Matrix3d &basis);
319
320 private:
321 int m_axis;
322
323 double m_twist, m_angle, m_new_twist, m_new_angle;
324 double m_cos_twist, m_sin_twist;
325
326 bool m_limit, m_limit_twist;
327 double m_min, m_max, m_min_twist, m_max_twist;
328};
329
331 public:
332 // 1DOF, 2DOF or 3DOF translational segments
333 IK_QTranslateSegment(int axis1);
334 IK_QTranslateSegment(int axis1, int axis2);
336
337 Vector3d Axis(int dof) const;
338
339 bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp);
340 void Lock(int, IK_QJacobian &, Vector3d &);
341 void UpdateAngleApply();
342
343 void SetWeight(int axis, double weight);
344 void SetLimit(int axis, double lmin, double lmax);
345
346 void Scale(double scale);
347
348 private:
349 int m_axis[3];
350 bool m_axis_enabled[3], m_limit[3];
351 Vector3d m_new_translation;
352 double m_min[3], m_max[3];
353};
Vector3d Axis(int dof) const
void SetLimit(int axis, double lmin, double lmax)
IK_QElbowSegment(int axis)
void Lock(int dof, IK_QJacobian &jacobian, Vector3d &delta)
void SetWeight(int axis, double weight)
bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
void SetBasis(const Matrix3d &basis)
Vector3d Axis(int) const
void UpdateAngleApply()
bool UpdateAngle(const IK_QJacobian &, Vector3d &, bool *)
void SetBasis(const Matrix3d &)
void SetWeight(int axis, double weight)
bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
Vector3d Axis(int dof) const
IK_QRevoluteSegment(int axis)
void SetBasis(const Matrix3d &basis)
void Lock(int dof, IK_QJacobian &jacobian, Vector3d &delta)
void SetLimit(int axis, double lmin, double lmax)
int NumberOfDoF() const
Definition IK_QSegment.h:77
virtual void SetBasis(const Matrix3d &basis)
int DoFId() const
Definition IK_QSegment.h:83
Vector3d m_start
const Vector3d GlobalStart() const
const Affine3d & GlobalTransform() const
void UnLock()
virtual EIGEN_MAKE_ALIGNED_OPERATOR_NEW ~IK_QSegment()
const Vector3d GlobalEnd() const
Vector3d m_translation
Matrix3d m_basis
virtual void Lock(int, IK_QJacobian &, Vector3d &)
virtual void UpdateAngleApply()=0
virtual bool UpdateAngle(const IK_QJacobian &, Vector3d &, bool *)=0
Vector3d m_orig_translation
Vector3d m_global_start
void ScaleWeight(int dof, double scale)
bool Translational() const
bool m_translational
bool Locked(int dof) const
void UpdateTransform(const Affine3d &global)
IK_QSegment * m_sibling
IK_QSegment * Parent() const
Definition IK_QSegment.h:63
bool m_locked[3]
const double MaxExtension() const
Definition IK_QSegment.h:94
Matrix3d m_orig_basis
virtual Vector3d Axis(int dof) const =0
Affine3d m_global_transform
double m_max_extension
virtual void Scale(double scale)
IK_QSegment * m_child
double m_weight[3]
Matrix3d m_rest_basis
virtual void SetWeight(int, double)
IK_QSegment * m_parent
void SetComposite(IK_QSegment *seg)
Matrix3d BasisChange() const
IK_QSegment(int num_DoF, bool translational)
double Weight(int dof) const
IK_QSegment * Composite() const
Definition IK_QSegment.h:71
void PrependBasis(const Matrix3d &mat)
void SetParent(IK_QSegment *parent)
void SetDoFId(int dof_id)
Definition IK_QSegment.h:88
IK_QSegment * m_composite
IK_QSegment * Child() const
Definition IK_QSegment.h:53
void RemoveChild(IK_QSegment *child)
IK_QSegment * Sibling() const
Definition IK_QSegment.h:58
virtual void SetLimit(int, double, double)
Vector3d TranslationChange() const
void SetTransform(const Vector3d &start, const Matrix3d &rest_basis, const Matrix3d &basis, const double length)
void SetWeight(int axis, double weight)
Vector3d Axis(int dof) const
void Lock(int dof, IK_QJacobian &jacobian, Vector3d &delta)
bool ComputeClampRotation(Vector3d &clamp)
bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
void SetLimit(int axis, double lmin, double lmax)
void SetWeight(int axis, double weight)
void Lock(int dof, IK_QJacobian &jacobian, Vector3d &delta)
Vector3d Axis(int dof) const
bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
void SetLimit(int axis, double lmin, double lmax)
void SetBasis(const Matrix3d &basis)
void SetWeight(int axis, double weight)
void Lock(int, IK_QJacobian &, Vector3d &)
void Scale(double scale)
Vector3d Axis(int dof) const
bool UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
void SetLimit(int axis, double lmin, double lmax)