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