~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to intern/iksolver/intern/IK_Solver.cpp

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
 
43
43
class IK_QSolver {
44
44
public:
45
 
        IK_QSolver() : root(NULL) {};
 
45
        IK_QSolver() : root(NULL) {
 
46
        }
46
47
 
47
48
        IK_QJacobianSolver solver;
48
49
        IK_QSegment *root;
49
 
        std::list<IK_QTask*> tasks;
 
50
        std::list<IK_QTask *> tasks;
50
51
};
51
52
 
52
53
// FIXME: locks still result in small "residual" changes to the locked axes...
53
 
IK_QSegment *CreateSegment(int flag, bool translate)
 
54
static IK_QSegment *CreateSegment(int flag, bool translate)
54
55
{
55
56
        int ndof = 0;
56
 
        ndof += (flag & IK_XDOF)? 1: 0;
57
 
        ndof += (flag & IK_YDOF)? 1: 0;
58
 
        ndof += (flag & IK_ZDOF)? 1: 0;
 
57
        ndof += (flag & IK_XDOF) ? 1 : 0;
 
58
        ndof += (flag & IK_YDOF) ? 1 : 0;
 
59
        ndof += (flag & IK_ZDOF) ? 1 : 0;
59
60
 
60
61
        IK_QSegment *seg;
61
62
 
78
79
 
79
80
                if (flag & IK_XDOF) {
80
81
                        axis1 = 0;
81
 
                        axis2 = (flag & IK_YDOF)? 1: 2;
 
82
                        axis2 = (flag & IK_YDOF) ? 1 : 2;
82
83
                }
83
84
                else {
84
85
                        axis1 = 1;
91
92
                        if (axis1 + axis2 == 2)
92
93
                                seg = new IK_QSwingSegment();
93
94
                        else
94
 
                                seg = new IK_QElbowSegment((axis1 == 0)? 0: 2);
 
95
                                seg = new IK_QElbowSegment((axis1 == 0) ? 0 : 2);
95
96
                }
96
97
        }
97
98
        else {
131
132
 
132
133
void IK_FreeSegment(IK_Segment *seg)
133
134
{
134
 
        IK_QSegment *qseg = (IK_QSegment*)seg;
 
135
        IK_QSegment *qseg = (IK_QSegment *)seg;
135
136
 
136
137
        if (qseg->Composite())
137
138
                delete qseg->Composite();
140
141
 
141
142
void IK_SetParent(IK_Segment *seg, IK_Segment *parent)
142
143
{
143
 
        IK_QSegment *qseg = (IK_QSegment*)seg;
144
 
        IK_QSegment *qparent = (IK_QSegment*)parent;
 
144
        IK_QSegment *qseg = (IK_QSegment *)seg;
 
145
        IK_QSegment *qparent = (IK_QSegment *)parent;
145
146
 
146
147
        if (qparent && qparent->Composite())
147
148
                qseg->SetParent(qparent->Composite());
151
152
 
152
153
void IK_SetTransform(IK_Segment *seg, float start[3], float rest[][3], float basis[][3], float length)
153
154
{
154
 
        IK_QSegment *qseg = (IK_QSegment*)seg;
 
155
        IK_QSegment *qseg = (IK_QSegment *)seg;
155
156
 
156
157
        MT_Vector3 mstart(start);
157
158
        // convert from blender column major to moto row major
177
178
 
178
179
void IK_SetLimit(IK_Segment *seg, IK_SegmentAxis axis, float lmin, float lmax)
179
180
{
180
 
        IK_QSegment *qseg = (IK_QSegment*)seg;
 
181
        IK_QSegment *qseg = (IK_QSegment *)seg;
181
182
 
182
183
        if (axis >= IK_TRANS_X) {
183
 
                if(!qseg->Translational()) {
184
 
                        if(qseg->Composite() && qseg->Composite()->Translational())
 
184
                if (!qseg->Translational()) {
 
185
                        if (qseg->Composite() && qseg->Composite()->Translational())
185
186
                                qseg = qseg->Composite();
186
187
                        else
187
188
                                return;
188
189
                }
189
190
 
190
 
                if(axis == IK_TRANS_X) axis = IK_X;
191
 
                else if(axis == IK_TRANS_Y) axis = IK_Y;
192
 
                else axis = IK_Z;
 
191
                if      (axis == IK_TRANS_X) axis = IK_X;
 
192
                else if (axis == IK_TRANS_Y) axis = IK_Y;
 
193
                else                         axis = IK_Z;
193
194
        }
194
195
 
195
196
        qseg->SetLimit(axis, lmin, lmax);
197
198
 
198
199
void IK_SetStiffness(IK_Segment *seg, IK_SegmentAxis axis, float stiffness)
199
200
{
200
 
        if (stiffness < 0.0)
 
201
        if (stiffness < 0.0f)
201
202
                return;
202
203
        
203
 
        if (stiffness > 0.999)
204
 
                stiffness = 0.999;
 
204
        if (stiffness > (1.0 - IK_STRETCH_STIFF_EPS))
 
205
                stiffness = (1.0 - IK_STRETCH_STIFF_EPS);
205
206
 
206
 
        IK_QSegment *qseg = (IK_QSegment*)seg;
207
 
        MT_Scalar weight = 1.0-stiffness;
 
207
        IK_QSegment *qseg = (IK_QSegment *)seg;
 
208
        MT_Scalar weight = 1.0f - stiffness;
208
209
 
209
210
        if (axis >= IK_TRANS_X) {
210
 
                if(!qseg->Translational()) {
211
 
                        if(qseg->Composite() && qseg->Composite()->Translational())
 
211
                if (!qseg->Translational()) {
 
212
                        if (qseg->Composite() && qseg->Composite()->Translational())
212
213
                                qseg = qseg->Composite();
213
214
                        else
214
215
                                return;
215
216
                }
216
217
 
217
 
                if(axis == IK_TRANS_X) axis = IK_X;
218
 
                else if(axis == IK_TRANS_Y) axis = IK_Y;
 
218
                if (axis == IK_TRANS_X) axis = IK_X;
 
219
                else if (axis == IK_TRANS_Y) axis = IK_Y;
219
220
                else axis = IK_Z;
220
221
        }
221
222
 
224
225
 
225
226
void IK_GetBasisChange(IK_Segment *seg, float basis_change[][3])
226
227
{
227
 
        IK_QSegment *qseg = (IK_QSegment*)seg;
 
228
        IK_QSegment *qseg = (IK_QSegment *)seg;
228
229
 
229
230
        if (qseg->Translational() && qseg->Composite())
230
231
                qseg = qseg->Composite();
245
246
 
246
247
void IK_GetTranslationChange(IK_Segment *seg, float *translation_change)
247
248
{
248
 
        IK_QSegment *qseg = (IK_QSegment*)seg;
 
249
        IK_QSegment *qseg = (IK_QSegment *)seg;
249
250
 
250
251
        if (!qseg->Translational() && qseg->Composite())
251
252
                qseg = qseg->Composite();
263
264
                return NULL;
264
265
        
265
266
        IK_QSolver *solver = new IK_QSolver();
266
 
        solver->root = (IK_QSegment*)root;
 
267
        solver->root = (IK_QSegment *)root;
267
268
 
268
 
        return (IK_Solver*)solver;
 
269
        return (IK_Solver *)solver;
269
270
}
270
271
 
271
272
void IK_FreeSolver(IK_Solver *solver)
273
274
        if (solver == NULL)
274
275
                return;
275
276
 
276
 
        IK_QSolver *qsolver = (IK_QSolver*)solver;
277
 
        std::list<IK_QTask*>& tasks = qsolver->tasks;
278
 
        std::list<IK_QTask*>::iterator task;
 
277
        IK_QSolver *qsolver = (IK_QSolver *)solver;
 
278
        std::list<IK_QTask *>& tasks = qsolver->tasks;
 
279
        std::list<IK_QTask *>::iterator task;
279
280
 
280
281
        for (task = tasks.begin(); task != tasks.end(); task++)
281
282
                delete (*task);
288
289
        if (solver == NULL || tip == NULL)
289
290
                return;
290
291
 
291
 
        IK_QSolver *qsolver = (IK_QSolver*)solver;
292
 
        IK_QSegment *qtip = (IK_QSegment*)tip;
 
292
        IK_QSolver *qsolver = (IK_QSolver *)solver;
 
293
        IK_QSegment *qtip = (IK_QSegment *)tip;
293
294
 
294
295
        if (qtip->Composite())
295
296
                qtip = qtip->Composite();
306
307
        if (solver == NULL || tip == NULL)
307
308
                return;
308
309
 
309
 
        IK_QSolver *qsolver = (IK_QSolver*)solver;
310
 
        IK_QSegment *qtip = (IK_QSegment*)tip;
 
310
        IK_QSolver *qsolver = (IK_QSolver *)solver;
 
311
        IK_QSegment *qtip = (IK_QSegment *)tip;
311
312
 
312
313
        if (qtip->Composite())
313
314
                qtip = qtip->Composite();
327
328
        if (solver == NULL || tip == NULL)
328
329
                return;
329
330
 
330
 
        IK_QSolver *qsolver = (IK_QSolver*)solver;
331
 
        IK_QSegment *qtip = (IK_QSegment*)tip;
 
331
        IK_QSolver *qsolver = (IK_QSolver *)solver;
 
332
        IK_QSegment *qtip = (IK_QSegment *)tip;
332
333
 
333
334
        MT_Vector3 qgoal(goal);
334
335
        MT_Vector3 qpolegoal(polegoal);
335
336
 
336
337
        qsolver->solver.SetPoleVectorConstraint(
337
 
                qtip, qgoal, qpolegoal, poleangle, getangle);
 
338
            qtip, qgoal, qpolegoal, poleangle, getangle);
338
339
}
339
340
 
340
341
float IK_SolverGetPoleAngle(IK_Solver *solver)
342
343
        if (solver == NULL)
343
344
                return 0.0f;
344
345
 
345
 
        IK_QSolver *qsolver = (IK_QSolver*)solver;
 
346
        IK_QSolver *qsolver = (IK_QSolver *)solver;
346
347
 
347
348
        return qsolver->solver.GetPoleAngle();
348
349
}
349
350
 
350
 
void IK_SolverAddCenterOfMass(IK_Solver *solver, IK_Segment *root, float goal[3], float weight)
 
351
static void IK_SolverAddCenterOfMass(IK_Solver *solver, IK_Segment *root, float goal[3], float weight)
351
352
{
352
353
        if (solver == NULL || root == NULL)
353
354
                return;
354
355
 
355
 
        IK_QSolver *qsolver = (IK_QSolver*)solver;
356
 
        IK_QSegment *qroot = (IK_QSegment*)root;
 
356
        IK_QSolver *qsolver = (IK_QSolver *)solver;
 
357
        IK_QSegment *qroot = (IK_QSegment *)root;
357
358
 
358
359
        // convert from blender column major to moto row major
359
360
        MT_Vector3 center(goal);
368
369
        if (solver == NULL)
369
370
                return 0;
370
371
 
371
 
        IK_QSolver *qsolver = (IK_QSolver*)solver;
 
372
        IK_QSolver *qsolver = (IK_QSolver *)solver;
372
373
 
373
374
        IK_QSegment *root = qsolver->root;
374
375
        IK_QJacobianSolver& jacobian = qsolver->solver;
375
 
        std::list<IK_QTask*>& tasks = qsolver->tasks;
 
376
        std::list<IK_QTask *>& tasks = qsolver->tasks;
376
377
        MT_Scalar tol = tolerance;
377
378
 
378
 
        if(!jacobian.Setup(root, tasks))
 
379
        if (!jacobian.Setup(root, tasks))
379
380
                return 0;
380
381
 
381
382
        bool result = jacobian.Solve(root, tasks, tol, max_iterations);
382
383
 
383
 
        return ((result)? 1: 0);
 
384
        return ((result) ? 1 : 0);
384
385
}
385
386