Blender  V2.93
implicit_blender.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) Blender Foundation
17  * All rights reserved.
18  */
19 
24 #include "implicit.h"
25 
26 #ifdef IMPLICIT_SOLVER_BLENDER
27 
28 # include "MEM_guardedalloc.h"
29 
30 # include "DNA_meshdata_types.h"
31 # include "DNA_object_force_types.h"
32 # include "DNA_object_types.h"
33 # include "DNA_scene_types.h"
34 # include "DNA_texture_types.h"
35 
36 # include "BLI_math.h"
37 # include "BLI_utildefines.h"
38 
39 # include "BKE_cloth.h"
40 # include "BKE_collision.h"
41 # include "BKE_effect.h"
42 
43 # include "SIM_mass_spring.h"
44 
45 # ifdef __GNUC__
46 # pragma GCC diagnostic ignored "-Wtype-limits"
47 # endif
48 
49 # ifdef _OPENMP
50 # define CLOTH_OPENMP_LIMIT 512
51 # endif
52 
53 //#define DEBUG_TIME
54 
55 # ifdef DEBUG_TIME
56 # include "PIL_time.h"
57 # endif
58 
59 static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
60 static float ZERO[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
61 
62 # if 0
63 # define C99
64 # ifdef C99
65 # defineDO_INLINE inline
66 # else
67 # defineDO_INLINE static
68 # endif
69 # endif /* if 0 */
70 
71 struct Cloth;
72 
74 /* fast vector / matrix library, enhancements are welcome :) -dg */
76 
77 /* DEFINITIONS */
78 typedef float lfVector[3];
79 typedef struct fmatrix3x3 {
80  float m[3][3]; /* 3x3 matrix */
81  unsigned int c, r; /* column and row number */
82  // int pinned; /* is this vertex allowed to move? */
83  float n1, n2, n3; /* three normal vectors for collision constrains */
84  unsigned int vcount; /* vertex count */
85  unsigned int scount; /* spring count */
87 
89 /* float[3] vector */
91 /* simple vector code */
92 /* STATUS: verified */
93 DO_INLINE void mul_fvector_S(float to[3], const float from[3], float scalar)
94 {
95  to[0] = from[0] * scalar;
96  to[1] = from[1] * scalar;
97  to[2] = from[2] * scalar;
98 }
99 /* simple v^T * v product ("outer product") */
100 /* STATUS: HAS TO BE verified (*should* work) */
101 DO_INLINE void mul_fvectorT_fvector(float to[3][3], const float vectorA[3], const float vectorB[3])
102 {
103  mul_fvector_S(to[0], vectorB, vectorA[0]);
104  mul_fvector_S(to[1], vectorB, vectorA[1]);
105  mul_fvector_S(to[2], vectorB, vectorA[2]);
106 }
107 /* simple v^T * v product with scalar ("outer product") */
108 /* STATUS: HAS TO BE verified (*should* work) */
109 DO_INLINE void mul_fvectorT_fvectorS(float to[3][3], float vectorA[3], float vectorB[3], float aS)
110 {
111  mul_fvectorT_fvector(to, vectorA, vectorB);
112 
113  mul_fvector_S(to[0], to[0], aS);
114  mul_fvector_S(to[1], to[1], aS);
115  mul_fvector_S(to[2], to[2], aS);
116 }
117 
118 # if 0
119 /* printf vector[3] on console: for debug output */
120 static void print_fvector(float m3[3])
121 {
122  printf("%f\n%f\n%f\n\n", m3[0], m3[1], m3[2]);
123 }
124 
126 /* long float vector float (*)[3] */
128 /* print long vector on console: for debug output */
129 DO_INLINE void print_lfvector(float (*fLongVector)[3], unsigned int verts)
130 {
131  unsigned int i = 0;
132  for (i = 0; i < verts; i++) {
133  print_fvector(fLongVector[i]);
134  }
135 }
136 # endif
137 
138 /* create long vector */
140 {
141  /* TODO: check if memory allocation was successful */
142  return (lfVector *)MEM_callocN(verts * sizeof(lfVector), "cloth_implicit_alloc_vector");
143  // return (lfVector *)cloth_aligned_malloc(&MEMORY_BASE, verts * sizeof(lfVector));
144 }
145 /* delete long vector */
146 DO_INLINE void del_lfvector(float (*fLongVector)[3])
147 {
148  if (fLongVector != NULL) {
149  MEM_freeN(fLongVector);
150  // cloth_aligned_free(&MEMORY_BASE, fLongVector);
151  }
152 }
153 /* copy long vector */
154 DO_INLINE void cp_lfvector(float (*to)[3], float (*from)[3], unsigned int verts)
155 {
156  memcpy(to, from, verts * sizeof(lfVector));
157 }
158 /* init long vector with float[3] */
159 DO_INLINE void init_lfvector(float (*fLongVector)[3], const float vector[3], unsigned int verts)
160 {
161  unsigned int i = 0;
162  for (i = 0; i < verts; i++) {
163  copy_v3_v3(fLongVector[i], vector);
164  }
165 }
166 /* zero long vector with float[3] */
167 DO_INLINE void zero_lfvector(float (*to)[3], unsigned int verts)
168 {
169  memset(to, 0.0f, verts * sizeof(lfVector));
170 }
171 /* multiply long vector with scalar*/
172 DO_INLINE void mul_lfvectorS(float (*to)[3],
173  float (*fLongVector)[3],
174  float scalar,
175  unsigned int verts)
176 {
177  unsigned int i = 0;
178 
179  for (i = 0; i < verts; i++) {
180  mul_fvector_S(to[i], fLongVector[i], scalar);
181  }
182 }
183 /* multiply long vector with scalar*/
184 /* A -= B * float */
185 DO_INLINE void submul_lfvectorS(float (*to)[3],
186  float (*fLongVector)[3],
187  float scalar,
188  unsigned int verts)
189 {
190  unsigned int i = 0;
191  for (i = 0; i < verts; i++) {
192  VECSUBMUL(to[i], fLongVector[i], scalar);
193  }
194 }
195 /* dot product for big vector */
196 DO_INLINE float dot_lfvector(float (*fLongVectorA)[3],
197  float (*fLongVectorB)[3],
198  unsigned int verts)
199 {
200  long i = 0;
201  float temp = 0.0;
202  /* XXX brecht, disabled this for now (first schedule line was already disabled),
203  * due to non-commutative nature of floating point ops this makes the sim give
204  * different results each time you run it!
205  * schedule(guided, 2) */
206  //#pragma omp parallel for reduction(+: temp) if (verts > CLOTH_OPENMP_LIMIT)
207  for (i = 0; i < (long)verts; i++) {
208  temp += dot_v3v3(fLongVectorA[i], fLongVectorB[i]);
209  }
210  return temp;
211 }
212 /* A = B + C --> for big vector */
213 DO_INLINE void add_lfvector_lfvector(float (*to)[3],
214  float (*fLongVectorA)[3],
215  float (*fLongVectorB)[3],
216  unsigned int verts)
217 {
218  unsigned int i = 0;
219 
220  for (i = 0; i < verts; i++) {
221  add_v3_v3v3(to[i], fLongVectorA[i], fLongVectorB[i]);
222  }
223 }
224 /* A = B + C * float --> for big vector */
225 DO_INLINE void add_lfvector_lfvectorS(float (*to)[3],
226  float (*fLongVectorA)[3],
227  float (*fLongVectorB)[3],
228  float bS,
229  unsigned int verts)
230 {
231  unsigned int i = 0;
232 
233  for (i = 0; i < verts; i++) {
234  VECADDS(to[i], fLongVectorA[i], fLongVectorB[i], bS);
235  }
236 }
237 /* A = B * float + C * float --> for big vector */
238 DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3],
239  float (*fLongVectorA)[3],
240  float aS,
241  float (*fLongVectorB)[3],
242  float bS,
243  unsigned int verts)
244 {
245  unsigned int i = 0;
246 
247  for (i = 0; i < verts; i++) {
248  VECADDSS(to[i], fLongVectorA[i], aS, fLongVectorB[i], bS);
249  }
250 }
251 /* A = B - C * float --> for big vector */
252 DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3],
253  float (*fLongVectorA)[3],
254  float (*fLongVectorB)[3],
255  float bS,
256  unsigned int verts)
257 {
258  unsigned int i = 0;
259  for (i = 0; i < verts; i++) {
260  VECSUBS(to[i], fLongVectorA[i], fLongVectorB[i], bS);
261  }
262 }
263 /* A = B - C --> for big vector */
264 DO_INLINE void sub_lfvector_lfvector(float (*to)[3],
265  float (*fLongVectorA)[3],
266  float (*fLongVectorB)[3],
267  unsigned int verts)
268 {
269  unsigned int i = 0;
270 
271  for (i = 0; i < verts; i++) {
272  sub_v3_v3v3(to[i], fLongVectorA[i], fLongVectorB[i]);
273  }
274 }
276 // 3x3 matrix
278 # if 0
279 /* printf 3x3 matrix on console: for debug output */
280 static void print_fmatrix(float m3[3][3])
281 {
282  printf("%f\t%f\t%f\n", m3[0][0], m3[0][1], m3[0][2]);
283  printf("%f\t%f\t%f\n", m3[1][0], m3[1][1], m3[1][2]);
284  printf("%f\t%f\t%f\n\n", m3[2][0], m3[2][1], m3[2][2]);
285 }
286 
287 static void print_sparse_matrix(fmatrix3x3 *m)
288 {
289  if (m) {
290  unsigned int i;
291  for (i = 0; i < m[0].vcount + m[0].scount; i++) {
292  printf("%d:\n", i);
293  print_fmatrix(m[i].m);
294  }
295  }
296 }
297 # endif
298 
299 # if 0
300 static void print_lvector(lfVector *v, int numverts)
301 {
302  int i;
303  for (i = 0; i < numverts; i++) {
304  if (i > 0) {
305  printf("\n");
306  }
307 
308  printf("%f,\n", v[i][0]);
309  printf("%f,\n", v[i][1]);
310  printf("%f,\n", v[i][2]);
311  }
312 }
313 # endif
314 
315 # if 0
316 static void print_bfmatrix(fmatrix3x3 *m)
317 {
318  int tot = m[0].vcount + m[0].scount;
319  int size = m[0].vcount * 3;
320  float *t = MEM_callocN(sizeof(float) * size * size, "bfmatrix");
321  int q, i, j;
322 
323  for (q = 0; q < tot; q++) {
324  int k = 3 * m[q].r;
325  int l = 3 * m[q].c;
326 
327  for (j = 0; j < 3; j++) {
328  for (i = 0; i < 3; i++) {
329 # if 0
330  if (t[k + i + (l + j) * size] != 0.0f) {
331  printf("warning: overwriting value at %d, %d\n", m[q].r, m[q].c);
332  }
333 # endif
334  if (k == l) {
335  t[k + i + (k + j) * size] += m[q].m[i][j];
336  }
337  else {
338  t[k + i + (l + j) * size] += m[q].m[i][j];
339  t[l + j + (k + i) * size] += m[q].m[j][i];
340  }
341  }
342  }
343  }
344 
345  for (j = 0; j < size; j++) {
346  if (j > 0 && j % 3 == 0) {
347  printf("\n");
348  }
349 
350  for (i = 0; i < size; i++) {
351  if (i > 0 && i % 3 == 0) {
352  printf(" ");
353  }
354 
356  }
357  printf("\n");
358  }
359 
360  MEM_freeN(t);
361 }
362 # endif
363 
364 /* copy 3x3 matrix */
365 DO_INLINE void cp_fmatrix(float to[3][3], const float from[3][3])
366 {
367  // memcpy(to, from, sizeof(float[3][3]));
368  copy_v3_v3(to[0], from[0]);
369  copy_v3_v3(to[1], from[1]);
370  copy_v3_v3(to[2], from[2]);
371 }
372 
373 /* copy 3x3 matrix */
374 DO_INLINE void initdiag_fmatrixS(float to[3][3], float aS)
375 {
376  cp_fmatrix(to, ZERO);
377 
378  to[0][0] = aS;
379  to[1][1] = aS;
380  to[2][2] = aS;
381 }
382 
383 # if 0
384 /* calculate determinant of 3x3 matrix */
385 DO_INLINE float det_fmatrix(float m[3][3])
386 {
387  return m[0][0] * m[1][1] * m[2][2] + m[1][0] * m[2][1] * m[0][2] + m[0][1] * m[1][2] * m[2][0] -
388  m[0][0] * m[1][2] * m[2][1] - m[0][1] * m[1][0] * m[2][2] - m[2][0] * m[1][1] * m[0][2];
389 }
390 
391 DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3])
392 {
393  unsigned int i, j;
394  float d;
395 
396  if ((d = det_fmatrix(from)) == 0) {
397  printf("can't build inverse");
398  exit(0);
399  }
400  for (i = 0; i < 3; i++) {
401  for (j = 0; j < 3; j++) {
402  int i1 = (i + 1) % 3;
403  int i2 = (i + 2) % 3;
404  int j1 = (j + 1) % 3;
405  int j2 = (j + 2) % 3;
407  to[j][i] = (from[i1][j1] * from[i2][j2] - from[i1][j2] * from[i2][j1]) / d;
418  }
419  }
420 }
421 # endif
422 
423 /* 3x3 matrix multiplied by a scalar */
424 /* STATUS: verified */
425 DO_INLINE void mul_fmatrix_S(float matrix[3][3], float scalar)
426 {
427  mul_fvector_S(matrix[0], matrix[0], scalar);
428  mul_fvector_S(matrix[1], matrix[1], scalar);
429  mul_fvector_S(matrix[2], matrix[2], scalar);
430 }
431 
432 /* a vector multiplied by a 3x3 matrix */
433 /* STATUS: verified */
434 DO_INLINE void mul_fvector_fmatrix(float *to, const float *from, const float matrix[3][3])
435 {
436  to[0] = matrix[0][0] * from[0] + matrix[1][0] * from[1] + matrix[2][0] * from[2];
437  to[1] = matrix[0][1] * from[0] + matrix[1][1] * from[1] + matrix[2][1] * from[2];
438  to[2] = matrix[0][2] * from[0] + matrix[1][2] * from[1] + matrix[2][2] * from[2];
439 }
440 
441 /* 3x3 matrix multiplied by a vector */
442 /* STATUS: verified */
443 DO_INLINE void mul_fmatrix_fvector(float *to, const float matrix[3][3], const float from[3])
444 {
445  to[0] = dot_v3v3(matrix[0], from);
446  to[1] = dot_v3v3(matrix[1], from);
447  to[2] = dot_v3v3(matrix[2], from);
448 }
449 /* 3x3 matrix addition with 3x3 matrix */
450 DO_INLINE void add_fmatrix_fmatrix(float to[3][3],
451  const float matrixA[3][3],
452  const float matrixB[3][3])
453 {
454  add_v3_v3v3(to[0], matrixA[0], matrixB[0]);
455  add_v3_v3v3(to[1], matrixA[1], matrixB[1]);
456  add_v3_v3v3(to[2], matrixA[2], matrixB[2]);
457 }
458 /* A -= B*x + C*y (3x3 matrix sub-addition with 3x3 matrix) */
460  float to[3][3], const float matrixA[3][3], float aS, const float matrixB[3][3], float bS)
461 {
462  VECSUBADDSS(to[0], matrixA[0], aS, matrixB[0], bS);
463  VECSUBADDSS(to[1], matrixA[1], aS, matrixB[1], bS);
464  VECSUBADDSS(to[2], matrixA[2], aS, matrixB[2], bS);
465 }
466 /* A = B - C (3x3 matrix subtraction with 3x3 matrix) */
467 DO_INLINE void sub_fmatrix_fmatrix(float to[3][3],
468  const float matrixA[3][3],
469  const float matrixB[3][3])
470 {
471  sub_v3_v3v3(to[0], matrixA[0], matrixB[0]);
472  sub_v3_v3v3(to[1], matrixA[1], matrixB[1]);
473  sub_v3_v3v3(to[2], matrixA[2], matrixB[2]);
474 }
476 /* special functions */
478 /* 3x3 matrix multiplied+added by a vector */
479 /* STATUS: verified */
480 DO_INLINE void muladd_fmatrix_fvector(float to[3], const float matrix[3][3], const float from[3])
481 {
482  to[0] += dot_v3v3(matrix[0], from);
483  to[1] += dot_v3v3(matrix[1], from);
484  to[2] += dot_v3v3(matrix[2], from);
485 }
486 
487 DO_INLINE void muladd_fmatrixT_fvector(float to[3], const float matrix[3][3], const float from[3])
488 {
489  to[0] += matrix[0][0] * from[0] + matrix[1][0] * from[1] + matrix[2][0] * from[2];
490  to[1] += matrix[0][1] * from[0] + matrix[1][1] * from[1] + matrix[2][1] * from[2];
491  to[2] += matrix[0][2] * from[0] + matrix[1][2] * from[1] + matrix[2][2] * from[2];
492 }
493 
494 BLI_INLINE void outerproduct(float r[3][3], const float a[3], const float b[3])
495 {
496  mul_v3_v3fl(r[0], a, b[0]);
497  mul_v3_v3fl(r[1], a, b[1]);
498  mul_v3_v3fl(r[2], a, b[2]);
499 }
500 
501 BLI_INLINE void cross_m3_v3m3(float r[3][3], const float v[3], const float m[3][3])
502 {
503  cross_v3_v3v3(r[0], v, m[0]);
504  cross_v3_v3v3(r[1], v, m[1]);
505  cross_v3_v3v3(r[2], v, m[2]);
506 }
507 
508 BLI_INLINE void cross_v3_identity(float r[3][3], const float v[3])
509 {
510  r[0][0] = 0.0f;
511  r[1][0] = v[2];
512  r[2][0] = -v[1];
513  r[0][1] = -v[2];
514  r[1][1] = 0.0f;
515  r[2][1] = v[0];
516  r[0][2] = v[1];
517  r[1][2] = -v[0];
518  r[2][2] = 0.0f;
519 }
520 
521 BLI_INLINE void madd_m3_m3fl(float r[3][3], const float m[3][3], float f)
522 {
523  r[0][0] += m[0][0] * f;
524  r[0][1] += m[0][1] * f;
525  r[0][2] += m[0][2] * f;
526  r[1][0] += m[1][0] * f;
527  r[1][1] += m[1][1] * f;
528  r[1][2] += m[1][2] * f;
529  r[2][0] += m[2][0] * f;
530  r[2][1] += m[2][1] * f;
531  r[2][2] += m[2][2] * f;
532 }
533 
535 
537 /* SPARSE SYMMETRIC big matrix with 3x3 matrix entries */
539 /* printf a big matrix on console: for debug output */
540 # if 0
541 static void print_bfmatrix(fmatrix3x3 *m3)
542 {
543  unsigned int i = 0;
544 
545  for (i = 0; i < m3[0].vcount + m3[0].scount; i++) {
546  print_fmatrix(m3[i].m);
547  }
548 }
549 # endif
550 
551 BLI_INLINE void init_fmatrix(fmatrix3x3 *matrix, int r, int c)
552 {
553  matrix->r = r;
554  matrix->c = c;
555 }
556 
557 /* create big matrix */
558 DO_INLINE fmatrix3x3 *create_bfmatrix(unsigned int verts, unsigned int springs)
559 {
560  /* TODO: check if memory allocation was successful */
561  fmatrix3x3 *temp = (fmatrix3x3 *)MEM_callocN(sizeof(fmatrix3x3) * (verts + springs),
562  "cloth_implicit_alloc_matrix");
563  int i;
564 
565  temp[0].vcount = verts;
566  temp[0].scount = springs;
567 
568  /* vertex part of the matrix is diagonal blocks */
569  for (i = 0; i < verts; i++) {
570  init_fmatrix(temp + i, i, i);
571  }
572 
573  return temp;
574 }
575 /* delete big matrix */
577 {
578  if (matrix != NULL) {
579  MEM_freeN(matrix);
580  }
581 }
582 
583 /* copy big matrix */
585 {
586  /* TODO bounds checking */
587  memcpy(to, from, sizeof(fmatrix3x3) * (from[0].vcount + from[0].scount));
588 }
589 
590 /* init big matrix */
591 /* slow in parallel */
592 DO_INLINE void init_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
593 {
594  unsigned int i;
595 
596  for (i = 0; i < matrix[0].vcount + matrix[0].scount; i++) {
597  cp_fmatrix(matrix[i].m, m3);
598  }
599 }
600 
601 /* init the diagonal of big matrix */
602 /* slow in parallel */
603 DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
604 {
605  unsigned int i, j;
606  float tmatrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
607 
608  for (i = 0; i < matrix[0].vcount; i++) {
609  cp_fmatrix(matrix[i].m, m3);
610  }
611  for (j = matrix[0].vcount; j < matrix[0].vcount + matrix[0].scount; j++) {
612  cp_fmatrix(matrix[j].m, tmatrix);
613  }
614 }
615 
616 /* SPARSE SYMMETRIC multiply big matrix with long vector*/
617 /* STATUS: verified */
618 DO_INLINE void mul_bfmatrix_lfvector(float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
619 {
620  unsigned int vcount = from[0].vcount;
621  lfVector *temp = create_lfvector(vcount);
622 
623  zero_lfvector(to, vcount);
624 
625 # pragma omp parallel sections if (vcount > CLOTH_OPENMP_LIMIT)
626  {
627 # pragma omp section
628  {
629  for (unsigned int i = from[0].vcount; i < from[0].vcount + from[0].scount; i++) {
630  /* This is the lower triangle of the sparse matrix,
631  * therefore multiplication occurs with transposed submatrices. */
632  muladd_fmatrixT_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]);
633  }
634  }
635 # pragma omp section
636  {
637  for (unsigned int i = 0; i < from[0].vcount + from[0].scount; i++) {
638  muladd_fmatrix_fvector(temp[from[i].r], from[i].m, fLongVector[from[i].c]);
639  }
640  }
641  }
642  add_lfvector_lfvector(to, to, temp, from[0].vcount);
643 
644  del_lfvector(temp);
645 }
646 
647 /* SPARSE SYMMETRIC sub big matrix with big matrix*/
648 /* A -= B * float + C * float --> for big matrix */
649 /* VERIFIED */
651  fmatrix3x3 *to, fmatrix3x3 *from, float aS, fmatrix3x3 *matrix, float bS)
652 {
653  unsigned int i = 0;
654 
655  /* process diagonal elements */
656  for (i = 0; i < matrix[0].vcount + matrix[0].scount; i++) {
657  subadd_fmatrixS_fmatrixS(to[i].m, from[i].m, aS, matrix[i].m, bS);
658  }
659 }
660 
662 /* simulator start */
664 
665 typedef struct Implicit_Data {
666  /* inputs */
667  fmatrix3x3 *bigI; /* identity (constant) */
668  fmatrix3x3 *tfm; /* local coordinate transform */
669  fmatrix3x3 *M; /* masses */
670  lfVector *F; /* forces */
671  fmatrix3x3 *dFdV, *dFdX; /* force jacobians */
672  int num_blocks; /* number of off-diagonal blocks (springs) */
673 
674  /* motion state data */
675  lfVector *X, *Xnew; /* positions */
676  lfVector *V, *Vnew; /* velocities */
677 
678  /* internal solver data */
679  lfVector *B; /* B for A*dV = B */
680  fmatrix3x3 *A; /* A for A*dV = B */
681 
682  lfVector *dV; /* velocity change (solution of A*dV = B) */
683  lfVector *z; /* target velocity in constrained directions */
684  fmatrix3x3 *S; /* filtering matrix for constraints */
685  fmatrix3x3 *P, *Pinv; /* pre-conditioning matrix */
687 
688 Implicit_Data *SIM_mass_spring_solver_create(int numverts, int numsprings)
689 {
690  Implicit_Data *id = (Implicit_Data *)MEM_callocN(sizeof(Implicit_Data), "implicit vecmat");
691 
692  /* process diagonal elements */
693  id->tfm = create_bfmatrix(numverts, 0);
694  id->A = create_bfmatrix(numverts, numsprings);
695  id->dFdV = create_bfmatrix(numverts, numsprings);
696  id->dFdX = create_bfmatrix(numverts, numsprings);
697  id->S = create_bfmatrix(numverts, 0);
698  id->Pinv = create_bfmatrix(numverts, numsprings);
699  id->P = create_bfmatrix(numverts, numsprings);
700  id->bigI = create_bfmatrix(numverts, numsprings); /* TODO 0 springs */
701  id->M = create_bfmatrix(numverts, numsprings);
702  id->X = create_lfvector(numverts);
703  id->Xnew = create_lfvector(numverts);
704  id->V = create_lfvector(numverts);
705  id->Vnew = create_lfvector(numverts);
706  id->F = create_lfvector(numverts);
707  id->B = create_lfvector(numverts);
708  id->dV = create_lfvector(numverts);
709  id->z = create_lfvector(numverts);
710 
711  initdiag_bfmatrix(id->bigI, I);
712 
713  return id;
714 }
715 
717 {
718  del_bfmatrix(id->tfm);
719  del_bfmatrix(id->A);
720  del_bfmatrix(id->dFdV);
721  del_bfmatrix(id->dFdX);
722  del_bfmatrix(id->S);
723  del_bfmatrix(id->P);
724  del_bfmatrix(id->Pinv);
725  del_bfmatrix(id->bigI);
726  del_bfmatrix(id->M);
727 
728  del_lfvector(id->X);
729  del_lfvector(id->Xnew);
730  del_lfvector(id->V);
731  del_lfvector(id->Vnew);
732  del_lfvector(id->F);
733  del_lfvector(id->B);
734  del_lfvector(id->dV);
735  del_lfvector(id->z);
736 
737  MEM_freeN(id);
738 }
739 
740 /* ==== Transformation from/to root reference frames ==== */
741 
742 BLI_INLINE void world_to_root_v3(Implicit_Data *data, int index, float r[3], const float v[3])
743 {
744  copy_v3_v3(r, v);
745  mul_transposed_m3_v3(data->tfm[index].m, r);
746 }
747 
748 BLI_INLINE void root_to_world_v3(Implicit_Data *data, int index, float r[3], const float v[3])
749 {
750  mul_v3_m3v3(r, data->tfm[index].m, v);
751 }
752 
754  int index,
755  float r[3][3],
756  const float m[3][3])
757 {
758  float trot[3][3];
759  copy_m3_m3(trot, data->tfm[index].m);
760  transpose_m3(trot);
761  mul_m3_m3m3(r, trot, m);
762 }
763 
765  int index,
766  float r[3][3],
767  const float m[3][3])
768 {
769  mul_m3_m3m3(r, data->tfm[index].m, m);
770 }
771 
772 /* ================================ */
773 
775 {
776  unsigned int i = 0;
777 
778  for (i = 0; i < S[0].vcount; i++) {
779  mul_m3_v3(S[i].m, V[S[i].r]);
780  }
781 }
782 
783 /* this version of the CG algorithm does not work very well with partial constraints
784  * (where S has non-zero elements). */
785 # if 0
786 static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S)
787 {
788  /* Solves for unknown X in equation AX=B */
789  unsigned int conjgrad_loopcount = 0, conjgrad_looplimit = 100;
790  float conjgrad_epsilon = 0.0001f /* , conjgrad_lasterror=0 */ /* UNUSED */;
791  lfVector *q, *d, *tmp, *r;
792  float s, starget, a, s_prev;
793  unsigned int numverts = lA[0].vcount;
794  q = create_lfvector(numverts);
795  d = create_lfvector(numverts);
796  tmp = create_lfvector(numverts);
797  r = create_lfvector(numverts);
798 
799  // zero_lfvector(ldV, CLOTHPARTICLES);
800  filter(ldV, S);
801 
802  add_lfvector_lfvector(ldV, ldV, z, numverts);
803 
804  // r = B - Mul(tmp, A, X); /* just use B if X known to be zero. */
805  cp_lfvector(r, lB, numverts);
806  mul_bfmatrix_lfvector(tmp, lA, ldV);
807  sub_lfvector_lfvector(r, r, tmp, numverts);
808 
809  filter(r, S);
810 
811  cp_lfvector(d, r, numverts);
812 
813  s = dot_lfvector(r, r, numverts);
814  starget = s * sqrtf(conjgrad_epsilon);
815 
816  while (s > starget && conjgrad_loopcount < conjgrad_looplimit) {
817  // Mul(q, A, d); /* q = A*d; */
818  mul_bfmatrix_lfvector(q, lA, d);
819 
820  filter(q, S);
821 
822  a = s / dot_lfvector(d, q, numverts);
823 
824  /* X = X + d*a; */
825  add_lfvector_lfvectorS(ldV, ldV, d, a, numverts);
826 
827  /* r = r - q*a; */
828  sub_lfvector_lfvectorS(r, r, q, a, numverts);
829 
830  s_prev = s;
831  s = dot_lfvector(r, r, numverts);
832 
833  /* d = r+d*(s/s_prev); */
834  add_lfvector_lfvectorS(d, r, d, (s / s_prev), numverts);
835 
836  filter(d, S);
837 
838  conjgrad_loopcount++;
839  }
840  /* conjgrad_lasterror = s; */ /* UNUSED */
841 
842  del_lfvector(q);
843  del_lfvector(d);
844  del_lfvector(tmp);
845  del_lfvector(r);
846  // printf("W/O conjgrad_loopcount: %d\n", conjgrad_loopcount);
847 
848  return conjgrad_loopcount <
849  conjgrad_looplimit; /* true means we reached desired accuracy in given time - ie stable */
850 }
851 # endif
852 
853 static int cg_filtered(lfVector *ldV,
854  fmatrix3x3 *lA,
855  lfVector *lB,
856  lfVector *z,
857  fmatrix3x3 *S,
859 {
860  /* Solves for unknown X in equation AX=B */
861  unsigned int conjgrad_loopcount = 0, conjgrad_looplimit = 100;
862  float conjgrad_epsilon = 0.01f;
863 
864  unsigned int numverts = lA[0].vcount;
865  lfVector *fB = create_lfvector(numverts);
866  lfVector *AdV = create_lfvector(numverts);
867  lfVector *r = create_lfvector(numverts);
868  lfVector *c = create_lfvector(numverts);
869  lfVector *q = create_lfvector(numverts);
870  lfVector *s = create_lfvector(numverts);
871  float bnorm2, delta_new, delta_old, delta_target, alpha;
872 
873  cp_lfvector(ldV, z, numverts);
874 
875  /* d0 = filter(B)^T * P * filter(B) */
876  cp_lfvector(fB, lB, numverts);
877  filter(fB, S);
878  bnorm2 = dot_lfvector(fB, fB, numverts);
879  delta_target = conjgrad_epsilon * conjgrad_epsilon * bnorm2;
880 
881  /* r = filter(B - A * dV) */
882  mul_bfmatrix_lfvector(AdV, lA, ldV);
883  sub_lfvector_lfvector(r, lB, AdV, numverts);
884  filter(r, S);
885 
886  /* c = filter(P^-1 * r) */
887  cp_lfvector(c, r, numverts);
888  filter(c, S);
889 
890  /* delta = r^T * c */
891  delta_new = dot_lfvector(r, c, numverts);
892 
893 # ifdef IMPLICIT_PRINT_SOLVER_INPUT_OUTPUT
894  printf("==== A ====\n");
895  print_bfmatrix(lA);
896  printf("==== z ====\n");
897  print_lvector(z, numverts);
898  printf("==== B ====\n");
899  print_lvector(lB, numverts);
900  printf("==== S ====\n");
901  print_bfmatrix(S);
902 # endif
903 
904  while (delta_new > delta_target && conjgrad_loopcount < conjgrad_looplimit) {
905  mul_bfmatrix_lfvector(q, lA, c);
906  filter(q, S);
907 
908  alpha = delta_new / dot_lfvector(c, q, numverts);
909 
910  add_lfvector_lfvectorS(ldV, ldV, c, alpha, numverts);
911 
912  add_lfvector_lfvectorS(r, r, q, -alpha, numverts);
913 
914  /* s = P^-1 * r */
915  cp_lfvector(s, r, numverts);
916  delta_old = delta_new;
917  delta_new = dot_lfvector(r, s, numverts);
918 
919  add_lfvector_lfvectorS(c, s, c, delta_new / delta_old, numverts);
920  filter(c, S);
921 
922  conjgrad_loopcount++;
923  }
924 
925 # ifdef IMPLICIT_PRINT_SOLVER_INPUT_OUTPUT
926  printf("==== dV ====\n");
927  print_lvector(ldV, numverts);
928  printf("========\n");
929 # endif
930 
931  del_lfvector(fB);
932  del_lfvector(AdV);
933  del_lfvector(r);
934  del_lfvector(c);
935  del_lfvector(q);
936  del_lfvector(s);
937  // printf("W/O conjgrad_loopcount: %d\n", conjgrad_loopcount);
938 
939  result->status = conjgrad_loopcount < conjgrad_looplimit ? SIM_SOLVER_SUCCESS :
941  result->iterations = conjgrad_loopcount;
942  result->error = bnorm2 > 0.0f ? sqrtf(delta_new / bnorm2) : 0.0f;
943 
944  return conjgrad_loopcount <
945  conjgrad_looplimit; /* true means we reached desired accuracy in given time - ie stable */
946 }
947 
948 # if 0
949 /* block diagonalizer */
950 DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv)
951 {
952  unsigned int i = 0;
953 
954  /* Take only the diagonal blocks of A */
955  // #pragma omp parallel for private(i) if (lA[0].vcount > CLOTH_OPENMP_LIMIT)
956  for (i = 0; i < lA[0].vcount; i++) {
957  /* block diagonalizer */
958  cp_fmatrix(P[i].m, lA[i].m);
959  inverse_fmatrix(Pinv[i].m, P[i].m);
960  }
961 }
962 
963 # if 0
964 /* version 1.3 */
965 static int cg_filtered_pre(lfVector *dv,
966  fmatrix3x3 *lA,
967  lfVector *lB,
968  lfVector *z,
969  fmatrix3x3 *S,
970  fmatrix3x3 *P,
971  fmatrix3x3 *Pinv)
972 {
973  unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit = 100;
974  float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0;
975  float conjgrad_epsilon = 0.0001; /* 0.2 is dt for steps=5 */
976  lfVector *r = create_lfvector(numverts);
977  lfVector *p = create_lfvector(numverts);
978  lfVector *s = create_lfvector(numverts);
979  lfVector *h = create_lfvector(numverts);
980 
981  BuildPPinv(lA, P, Pinv);
982 
983  filter(dv, S);
984  add_lfvector_lfvector(dv, dv, z, numverts);
985 
986  mul_bfmatrix_lfvector(r, lA, dv);
987  sub_lfvector_lfvector(r, lB, r, numverts);
988  filter(r, S);
989 
990  mul_prevfmatrix_lfvector(p, Pinv, r);
991  filter(p, S);
992 
993  deltaNew = dot_lfvector(r, p, numverts);
994 
995  delta0 = deltaNew * sqrt(conjgrad_epsilon);
996 
997 # ifdef DEBUG_TIME
998  double start = PIL_check_seconds_timer();
999 # endif
1000 
1001  while ((deltaNew > delta0) && (iterations < conjgrad_looplimit)) {
1002  iterations++;
1003 
1004  mul_bfmatrix_lfvector(s, lA, p);
1005  filter(s, S);
1006 
1007  alpha = deltaNew / dot_lfvector(p, s, numverts);
1008 
1009  add_lfvector_lfvectorS(dv, dv, p, alpha, numverts);
1010 
1011  add_lfvector_lfvectorS(r, r, s, -alpha, numverts);
1012 
1013  mul_prevfmatrix_lfvector(h, Pinv, r);
1014  filter(h, S);
1015 
1016  deltaOld = deltaNew;
1017 
1018  deltaNew = dot_lfvector(r, h, numverts);
1019 
1020  add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts);
1021 
1022  filter(p, S);
1023  }
1024 
1025 # ifdef DEBUG_TIME
1026  double end = PIL_check_seconds_timer();
1027  printf("cg_filtered_pre time: %f\n", (float)(end - start));
1028 # endif
1029 
1030  del_lfvector(h);
1031  del_lfvector(s);
1032  del_lfvector(p);
1033  del_lfvector(r);
1034 
1035  printf("iterations: %d\n", iterations);
1036 
1037  return iterations < conjgrad_looplimit;
1038 }
1039 # endif
1040 
1041 /* version 1.4 */
1042 static int cg_filtered_pre(lfVector *dv,
1043  fmatrix3x3 *lA,
1044  lfVector *lB,
1045  lfVector *z,
1046  fmatrix3x3 *S,
1047  fmatrix3x3 *P,
1048  fmatrix3x3 *Pinv,
1049  fmatrix3x3 *bigI)
1050 {
1051  unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit = 100;
1052  float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0, tol = 0;
1053  lfVector *r = create_lfvector(numverts);
1054  lfVector *p = create_lfvector(numverts);
1055  lfVector *s = create_lfvector(numverts);
1056  lfVector *h = create_lfvector(numverts);
1057  lfVector *bhat = create_lfvector(numverts);
1058  lfVector *btemp = create_lfvector(numverts);
1059 
1060  BuildPPinv(lA, P, Pinv);
1061 
1062  initdiag_bfmatrix(bigI, I);
1063  sub_bfmatrix_Smatrix(bigI, bigI, S);
1064 
1065  /* x = Sx_0+(I-S)z */
1066  filter(dv, S);
1067  add_lfvector_lfvector(dv, dv, z, numverts);
1068 
1069  /* b_hat = S(b-A(I-S)z) */
1070  mul_bfmatrix_lfvector(r, lA, z);
1071  mul_bfmatrix_lfvector(bhat, bigI, r);
1072  sub_lfvector_lfvector(bhat, lB, bhat, numverts);
1073 
1074  /* r = S(b-Ax) */
1075  mul_bfmatrix_lfvector(r, lA, dv);
1076  sub_lfvector_lfvector(r, lB, r, numverts);
1077  filter(r, S);
1078 
1079  /* p = SP^-1r */
1080  mul_prevfmatrix_lfvector(p, Pinv, r);
1081  filter(p, S);
1082 
1083  /* delta0 = bhat^TP^-1bhat */
1084  mul_prevfmatrix_lfvector(btemp, Pinv, bhat);
1085  delta0 = dot_lfvector(bhat, btemp, numverts);
1086 
1087  /* deltaNew = r^TP */
1088  deltaNew = dot_lfvector(r, p, numverts);
1089 
1090 # if 0
1091  filter(dv, S);
1092  add_lfvector_lfvector(dv, dv, z, numverts);
1093 
1094  mul_bfmatrix_lfvector(r, lA, dv);
1095  sub_lfvector_lfvector(r, lB, r, numverts);
1096  filter(r, S);
1097 
1098  mul_prevfmatrix_lfvector(p, Pinv, r);
1099  filter(p, S);
1100 
1101  deltaNew = dot_lfvector(r, p, numverts);
1102 
1103  delta0 = deltaNew * sqrt(conjgrad_epsilon);
1104 # endif
1105 
1106 # ifdef DEBUG_TIME
1107  double start = PIL_check_seconds_timer();
1108 # endif
1109 
1110  tol = (0.01 * 0.2);
1111 
1112  while ((deltaNew > delta0 * tol * tol) && (iterations < conjgrad_looplimit)) {
1113  iterations++;
1114 
1115  mul_bfmatrix_lfvector(s, lA, p);
1116  filter(s, S);
1117 
1118  alpha = deltaNew / dot_lfvector(p, s, numverts);
1119 
1120  add_lfvector_lfvectorS(dv, dv, p, alpha, numverts);
1121 
1122  add_lfvector_lfvectorS(r, r, s, -alpha, numverts);
1123 
1124  mul_prevfmatrix_lfvector(h, Pinv, r);
1125  filter(h, S);
1126 
1127  deltaOld = deltaNew;
1128 
1129  deltaNew = dot_lfvector(r, h, numverts);
1130 
1131  add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts);
1132 
1133  filter(p, S);
1134  }
1135 
1136 # ifdef DEBUG_TIME
1137  double end = PIL_check_seconds_timer();
1138  printf("cg_filtered_pre time: %f\n", (float)(end - start));
1139 # endif
1140 
1141  del_lfvector(btemp);
1142  del_lfvector(bhat);
1143  del_lfvector(h);
1144  del_lfvector(s);
1145  del_lfvector(p);
1146  del_lfvector(r);
1147 
1148  // printf("iterations: %d\n", iterations);
1149 
1150  return iterations < conjgrad_looplimit;
1151 }
1152 # endif
1153 
1155 {
1156  unsigned int numverts = data->dFdV[0].vcount;
1157 
1158  lfVector *dFdXmV = create_lfvector(numverts);
1159  zero_lfvector(data->dV, numverts);
1160 
1161  cp_bfmatrix(data->A, data->M);
1162 
1163  subadd_bfmatrixS_bfmatrixS(data->A, data->dFdV, dt, data->dFdX, (dt * dt));
1164 
1165  mul_bfmatrix_lfvector(dFdXmV, data->dFdX, data->V);
1166 
1167  add_lfvectorS_lfvectorS(data->B, data->F, dt, dFdXmV, (dt * dt), numverts);
1168 
1169 # ifdef DEBUG_TIME
1170  double start = PIL_check_seconds_timer();
1171 # endif
1172 
1173  /* Conjugate gradient algorithm to solve Ax=b. */
1174  cg_filtered(data->dV, data->A, data->B, data->z, data->S, result);
1175 
1176  // cg_filtered_pre(id->dV, id->A, id->B, id->z, id->S, id->P, id->Pinv, id->bigI);
1177 
1178 # ifdef DEBUG_TIME
1179  double end = PIL_check_seconds_timer();
1180  printf("cg_filtered calc time: %f\n", (float)(end - start));
1181 # endif
1182 
1183  /* advance velocities */
1184  add_lfvector_lfvector(data->Vnew, data->V, data->dV, numverts);
1185 
1186  del_lfvector(dFdXmV);
1187 
1188  return result->status == SIM_SOLVER_SUCCESS;
1189 }
1190 
1192 {
1193  int numverts = data->M[0].vcount;
1194 
1195  /* advance positions */
1196  add_lfvector_lfvectorS(data->Xnew, data->X, data->Vnew, dt, numverts);
1197 
1198  return true;
1199 }
1200 
1202 {
1203  int numverts = data->M[0].vcount;
1204  cp_lfvector(data->X, data->Xnew, numverts);
1205  cp_lfvector(data->V, data->Vnew, numverts);
1206 }
1207 
1209 {
1210  unit_m3(data->M[index].m);
1211  mul_m3_fl(data->M[index].m, mass);
1212 }
1213 
1214 void SIM_mass_spring_set_rest_transform(Implicit_Data *data, int index, float tfm[3][3])
1215 {
1216 # ifdef CLOTH_ROOT_FRAME
1217  copy_m3_m3(data->tfm[index].m, tfm);
1218 # else
1219  unit_m3(data->tfm[index].m);
1220  (void)tfm;
1221 # endif
1222 }
1223 
1225  int index,
1226  const float x[3],
1227  const float v[3])
1228 {
1229  world_to_root_v3(data, index, data->X[index], x);
1230  world_to_root_v3(data, index, data->V[index], v);
1231 }
1232 
1233 void SIM_mass_spring_set_position(Implicit_Data *data, int index, const float x[3])
1234 {
1235  world_to_root_v3(data, index, data->X[index], x);
1236 }
1237 
1238 void SIM_mass_spring_set_velocity(Implicit_Data *data, int index, const float v[3])
1239 {
1240  world_to_root_v3(data, index, data->V[index], v);
1241 }
1242 
1244  int index,
1245  float x[3],
1246  float v[3])
1247 {
1248  if (x) {
1249  root_to_world_v3(data, index, x, data->X[index]);
1250  }
1251  if (v) {
1252  root_to_world_v3(data, index, v, data->V[index]);
1253  }
1254 }
1255 
1256 void SIM_mass_spring_get_position(struct Implicit_Data *data, int index, float x[3])
1257 {
1258  root_to_world_v3(data, index, x, data->X[index]);
1259 }
1260 
1261 void SIM_mass_spring_get_velocity(struct Implicit_Data *data, int index, float v[3])
1262 {
1263  root_to_world_v3(data, index, v, data->V[index]);
1264 }
1265 
1266 void SIM_mass_spring_get_new_position(struct Implicit_Data *data, int index, float x[3])
1267 {
1268  root_to_world_v3(data, index, x, data->Xnew[index]);
1269 }
1270 
1271 void SIM_mass_spring_set_new_position(struct Implicit_Data *data, int index, const float x[3])
1272 {
1273  world_to_root_v3(data, index, data->Xnew[index], x);
1274 }
1275 
1276 void SIM_mass_spring_get_new_velocity(struct Implicit_Data *data, int index, float v[3])
1277 {
1278  root_to_world_v3(data, index, v, data->Vnew[index]);
1279 }
1280 
1281 void SIM_mass_spring_set_new_velocity(struct Implicit_Data *data, int index, const float v[3])
1282 {
1283  world_to_root_v3(data, index, data->Vnew[index], v);
1284 }
1285 
1286 /* -------------------------------- */
1287 
1289 {
1290  int s = data->M[0].vcount + data->num_blocks; /* index from array start */
1291  BLI_assert(s < data->M[0].vcount + data->M[0].scount);
1292  ++data->num_blocks;
1293 
1294  /* tfm and S don't have spring entries (diagonal blocks only) */
1295  init_fmatrix(data->bigI + s, v1, v2);
1296  init_fmatrix(data->M + s, v1, v2);
1297  init_fmatrix(data->dFdX + s, v1, v2);
1298  init_fmatrix(data->dFdV + s, v1, v2);
1299  init_fmatrix(data->A + s, v1, v2);
1300  init_fmatrix(data->P + s, v1, v2);
1301  init_fmatrix(data->Pinv + s, v1, v2);
1302 
1303  return s;
1304 }
1305 
1307 {
1308  int i, numverts = data->S[0].vcount;
1309  for (i = 0; i < numverts; i++) {
1310  unit_m3(data->S[i].m);
1311  zero_v3(data->z[i]);
1312  }
1313 }
1314 
1315 void SIM_mass_spring_add_constraint_ndof0(Implicit_Data *data, int index, const float dV[3])
1316 {
1317  zero_m3(data->S[index].m);
1318 
1319  world_to_root_v3(data, index, data->z[index], dV);
1320 }
1321 
1323  Implicit_Data *data, int index, const float c1[3], const float c2[3], const float dV[3])
1324 {
1325  float m[3][3], p[3], q[3], u[3], cmat[3][3];
1326 
1327  world_to_root_v3(data, index, p, c1);
1328  mul_fvectorT_fvector(cmat, p, p);
1329  sub_m3_m3m3(m, I, cmat);
1330 
1331  world_to_root_v3(data, index, q, c2);
1332  mul_fvectorT_fvector(cmat, q, q);
1333  sub_m3_m3m3(m, m, cmat);
1334 
1335  /* XXX not sure but multiplication should work here */
1336  copy_m3_m3(data->S[index].m, m);
1337  // mul_m3_m3m3(data->S[index].m, data->S[index].m, m);
1338 
1339  world_to_root_v3(data, index, u, dV);
1340  add_v3_v3(data->z[index], u);
1341 }
1342 
1344  int index,
1345  const float c1[3],
1346  const float dV[3])
1347 {
1348  float m[3][3], p[3], u[3], cmat[3][3];
1349 
1350  world_to_root_v3(data, index, p, c1);
1351  mul_fvectorT_fvector(cmat, p, p);
1352  sub_m3_m3m3(m, I, cmat);
1353 
1354  copy_m3_m3(data->S[index].m, m);
1355  // mul_m3_m3m3(data->S[index].m, data->S[index].m, m);
1356 
1357  world_to_root_v3(data, index, u, dV);
1358  add_v3_v3(data->z[index], u);
1359 }
1360 
1362 {
1363  int numverts = data->M[0].vcount;
1364  zero_lfvector(data->F, numverts);
1365  init_bfmatrix(data->dFdX, ZERO);
1366  init_bfmatrix(data->dFdV, ZERO);
1367 
1368  data->num_blocks = 0;
1369 }
1370 
1372  int index,
1373  const float acceleration[3],
1374  const float omega[3],
1375  const float domega_dt[3],
1376  float mass)
1377 {
1378 # ifdef CLOTH_ROOT_FRAME
1379  float acc[3], w[3], dwdt[3];
1380  float f[3], dfdx[3][3], dfdv[3][3];
1381  float euler[3], coriolis[3], centrifugal[3], rotvel[3];
1382  float deuler[3][3], dcoriolis[3][3], dcentrifugal[3][3], drotvel[3][3];
1383 
1384  world_to_root_v3(data, index, acc, acceleration);
1385  world_to_root_v3(data, index, w, omega);
1386  world_to_root_v3(data, index, dwdt, domega_dt);
1387 
1388  cross_v3_v3v3(euler, dwdt, data->X[index]);
1389  cross_v3_v3v3(coriolis, w, data->V[index]);
1390  mul_v3_fl(coriolis, 2.0f);
1391  cross_v3_v3v3(rotvel, w, data->X[index]);
1392  cross_v3_v3v3(centrifugal, w, rotvel);
1393 
1394  sub_v3_v3v3(f, acc, euler);
1395  sub_v3_v3(f, coriolis);
1396  sub_v3_v3(f, centrifugal);
1397 
1398  mul_v3_fl(f, mass); /* F = m * a */
1399 
1400  cross_v3_identity(deuler, dwdt);
1401  cross_v3_identity(dcoriolis, w);
1402  mul_m3_fl(dcoriolis, 2.0f);
1403  cross_v3_identity(drotvel, w);
1404  cross_m3_v3m3(dcentrifugal, w, drotvel);
1405 
1406  add_m3_m3m3(dfdx, deuler, dcentrifugal);
1407  negate_m3(dfdx);
1408  mul_m3_fl(dfdx, mass);
1409 
1410  copy_m3_m3(dfdv, dcoriolis);
1411  negate_m3(dfdv);
1412  mul_m3_fl(dfdv, mass);
1413 
1414  add_v3_v3(data->F[index], f);
1415  add_m3_m3m3(data->dFdX[index].m, data->dFdX[index].m, dfdx);
1416  add_m3_m3m3(data->dFdV[index].m, data->dFdV[index].m, dfdv);
1417 # else
1418  (void)data;
1419  (void)index;
1420  (void)acceleration;
1421  (void)omega;
1422  (void)domega_dt;
1423 # endif
1424 }
1425 
1426 void SIM_mass_spring_force_gravity(Implicit_Data *data, int index, float mass, const float g[3])
1427 {
1428  /* force = mass * acceleration (in this case: gravity) */
1429  float f[3];
1430  world_to_root_v3(data, index, f, g);
1431  mul_v3_fl(f, mass);
1432 
1433  add_v3_v3(data->F[index], f);
1434 }
1435 
1437 {
1438  int i, numverts = data->M[0].vcount;
1439  for (i = 0; i < numverts; i++) {
1440  float tmp[3][3];
1441 
1442  /* NB: uses root space velocity, no need to transform */
1443  madd_v3_v3fl(data->F[i], data->V[i], -drag);
1444 
1445  copy_m3_m3(tmp, I);
1446  mul_m3_fl(tmp, -drag);
1447  add_m3_m3m3(data->dFdV[i].m, data->dFdV[i].m, tmp);
1448  }
1449 }
1450 
1452  struct Implicit_Data *data, int i, const float f[3], float dfdx[3][3], float dfdv[3][3])
1453 {
1454  float tf[3], tdfdx[3][3], tdfdv[3][3];
1455  world_to_root_v3(data, i, tf, f);
1456  world_to_root_m3(data, i, tdfdx, dfdx);
1457  world_to_root_m3(data, i, tdfdv, dfdv);
1458 
1459  add_v3_v3(data->F[i], tf);
1460  add_m3_m3m3(data->dFdX[i].m, data->dFdX[i].m, tdfdx);
1461  add_m3_m3m3(data->dFdV[i].m, data->dFdV[i].m, tdfdv);
1462 }
1463 
1464 static float calc_nor_area_tri(float nor[3],
1465  const float v1[3],
1466  const float v2[3],
1467  const float v3[3])
1468 {
1469  float n1[3], n2[3];
1470 
1471  sub_v3_v3v3(n1, v1, v2);
1472  sub_v3_v3v3(n2, v2, v3);
1473 
1474  cross_v3_v3v3(nor, n1, n2);
1475  return normalize_v3(nor) / 2.0f;
1476 }
1477 
1478 /* XXX does not support force jacobians yet, since the effector system does not provide them either
1479  */
1481  Implicit_Data *data, int v1, int v2, int v3, const float (*winvec)[3])
1482 {
1483  const float effector_scale = 0.02f;
1484  const int vs[3] = {v1, v2, v3};
1485  float win[3], nor[3], area;
1486  float factor, base_force;
1487  float force[3];
1488 
1489  /* calculate face normal and area */
1490  area = calc_nor_area_tri(nor, data->X[v1], data->X[v2], data->X[v3]);
1491  /* The force is calculated and split up evenly for each of the three face verts */
1492  factor = effector_scale * area / 3.0f;
1493 
1494  /* Calculate wind pressure at each vertex by projecting the wind field on the normal. */
1495  for (int i = 0; i < 3; i++) {
1496  world_to_root_v3(data, vs[i], win, winvec[vs[i]]);
1497 
1498  force[i] = dot_v3v3(win, nor);
1499  }
1500 
1501  /* Compute per-vertex force values from local pressures.
1502  * From integrating the pressure over the triangle and deriving
1503  * equivalent vertex forces, it follows that:
1504  *
1505  * force[idx] = (sum(pressure) + pressure[idx]) * area / 12
1506  *
1507  * Effectively, 1/4 of the pressure acts just on its vertex,
1508  * while 3/4 is split evenly over all three.
1509  */
1510  mul_v3_fl(force, factor / 4.0f);
1511 
1512  base_force = force[0] + force[1] + force[2];
1513 
1514  /* add pressure to each of the face verts */
1515  madd_v3_v3fl(data->F[v1], nor, base_force + force[0]);
1516  madd_v3_v3fl(data->F[v2], nor, base_force + force[1]);
1517  madd_v3_v3fl(data->F[v3], nor, base_force + force[2]);
1518 }
1519 
1521  Implicit_Data *data, int v1, int v2, int v3, const float (*forcevec)[3])
1522 {
1523  const float effector_scale = 0.02f;
1524  const int vs[3] = {v1, v2, v3};
1525  float nor[3], area;
1526  float factor, base_force[3];
1527  float force[3][3];
1528 
1529  /* calculate face normal and area */
1530  area = calc_nor_area_tri(nor, data->X[v1], data->X[v2], data->X[v3]);
1531  /* The force is calculated and split up evenly for each of the three face verts */
1532  factor = effector_scale * area / 3.0f;
1533 
1534  /* Compute common and per-vertex force vectors from the original inputs. */
1535  zero_v3(base_force);
1536 
1537  for (int i = 0; i < 3; i++) {
1538  world_to_root_v3(data, vs[i], force[i], forcevec[vs[i]]);
1539 
1540  mul_v3_fl(force[i], factor / 4.0f);
1541  add_v3_v3(base_force, force[i]);
1542  }
1543 
1544  /* Apply the common and vertex components to all vertices. */
1545  for (int i = 0; i < 3; i++) {
1546  add_v3_v3(force[i], base_force);
1547  add_v3_v3(data->F[vs[i]], force[i]);
1548  }
1549 }
1550 
1552 {
1553  /* The result will be 6x the volume */
1554  return volume_tri_tetrahedron_signed_v3_6x(data->X[v1], data->X[v2], data->X[v3]);
1555 }
1556 
1557 float SIM_tri_area(struct Implicit_Data *data, int v1, int v2, int v3)
1558 {
1559  float nor[3];
1560 
1561  return calc_nor_area_tri(nor, data->X[v1], data->X[v2], data->X[v3]);
1562 }
1563 
1565  int v1,
1566  int v2,
1567  int v3,
1568  float common_pressure,
1569  const float *vertex_pressure,
1570  const float weights[3])
1571 {
1572  float nor[3], area;
1573  float factor, base_force;
1574  float force[3];
1575 
1576  /* calculate face normal and area */
1577  area = calc_nor_area_tri(nor, data->X[v1], data->X[v2], data->X[v3]);
1578  /* The force is calculated and split up evenly for each of the three face verts */
1579  factor = area / 3.0f;
1580  base_force = common_pressure * factor;
1581 
1582  /* Compute per-vertex force values from local pressures.
1583  * From integrating the pressure over the triangle and deriving
1584  * equivalent vertex forces, it follows that:
1585  *
1586  * force[idx] = (sum(pressure) + pressure[idx]) * area / 12
1587  *
1588  * Effectively, 1/4 of the pressure acts just on its vertex,
1589  * while 3/4 is split evenly over all three.
1590  */
1591  if (vertex_pressure) {
1592  copy_v3_fl3(force, vertex_pressure[v1], vertex_pressure[v2], vertex_pressure[v3]);
1593  mul_v3_fl(force, factor / 4.0f);
1594 
1595  base_force += force[0] + force[1] + force[2];
1596  }
1597  else {
1598  zero_v3(force);
1599  }
1600 
1601  /* add pressure to each of the face verts */
1602  madd_v3_v3fl(data->F[v1], nor, (base_force + force[0]) * weights[0]);
1603  madd_v3_v3fl(data->F[v2], nor, (base_force + force[1]) * weights[1]);
1604  madd_v3_v3fl(data->F[v3], nor, (base_force + force[2]) * weights[2]);
1605 }
1606 
1607 static void edge_wind_vertex(const float dir[3],
1608  float length,
1609  float radius,
1610  const float wind[3],
1611  float f[3],
1612  float UNUSED(dfdx[3][3]),
1613  float UNUSED(dfdv[3][3]))
1614 {
1615  const float density = 0.01f; /* XXX arbitrary value, corresponds to effect of air density */
1616  float cos_alpha, sin_alpha, cross_section;
1617  float windlen = len_v3(wind);
1618 
1619  if (windlen == 0.0f) {
1620  zero_v3(f);
1621  return;
1622  }
1623 
1624  /* angle of wind direction to edge */
1625  cos_alpha = dot_v3v3(wind, dir) / windlen;
1626  sin_alpha = sqrtf(1.0f - cos_alpha * cos_alpha);
1627  cross_section = radius * ((float)M_PI * radius * sin_alpha + length * cos_alpha);
1628 
1629  mul_v3_v3fl(f, wind, density * cross_section);
1630 }
1631 
1633  Implicit_Data *data, int v1, int v2, float radius1, float radius2, const float (*winvec)[3])
1634 {
1635  float win[3], dir[3], length;
1636  float f[3], dfdx[3][3], dfdv[3][3];
1637 
1638  sub_v3_v3v3(dir, data->X[v1], data->X[v2]);
1639  length = normalize_v3(dir);
1640 
1641  world_to_root_v3(data, v1, win, winvec[v1]);
1642  edge_wind_vertex(dir, length, radius1, win, f, dfdx, dfdv);
1643  add_v3_v3(data->F[v1], f);
1644 
1645  world_to_root_v3(data, v2, win, winvec[v2]);
1646  edge_wind_vertex(dir, length, radius2, win, f, dfdx, dfdv);
1647  add_v3_v3(data->F[v2], f);
1648 }
1649 
1651  int v,
1652  float UNUSED(radius),
1653  const float (*winvec)[3])
1654 {
1655  const float density = 0.01f; /* XXX arbitrary value, corresponds to effect of air density */
1656 
1657  float wind[3];
1658  float f[3];
1659 
1660  world_to_root_v3(data, v, wind, winvec[v]);
1661  mul_v3_v3fl(f, wind, density);
1662  add_v3_v3(data->F[v], f);
1663 }
1664 
1665 BLI_INLINE void dfdx_spring(float to[3][3], const float dir[3], float length, float L, float k)
1666 {
1667  /* dir is unit length direction, rest is spring's restlength, k is spring constant. */
1668  // return ( (I-outerprod(dir, dir))*Min(1.0f, rest/length) - I) * -k;
1669  outerproduct(to, dir, dir);
1670  sub_m3_m3m3(to, I, to);
1671 
1672  mul_m3_fl(to, (L / length));
1673  sub_m3_m3m3(to, to, I);
1674  mul_m3_fl(to, k);
1675 }
1676 
1677 /* unused */
1678 # if 0
1679 BLI_INLINE void dfdx_damp(float to[3][3],
1680  const float dir[3],
1681  float length,
1682  const float vel[3],
1683  float rest,
1684  float damping)
1685 {
1686  /* inner spring damping vel is the relative velocity of the endpoints. */
1687  // return (I-outerprod(dir, dir)) * (-damping * -(dot(dir, vel)/Max(length, rest)));
1688  mul_fvectorT_fvector(to, dir, dir);
1689  sub_fmatrix_fmatrix(to, I, to);
1690  mul_fmatrix_S(to, (-damping * -(dot_v3v3(dir, vel) / MAX2(length, rest))));
1691 }
1692 # endif
1693 
1694 BLI_INLINE void dfdv_damp(float to[3][3], const float dir[3], float damping)
1695 {
1696  /* Derivative of force with regards to velocity. */
1697  outerproduct(to, dir, dir);
1698  mul_m3_fl(to, -damping);
1699 }
1700 
1701 BLI_INLINE float fb(float length, float L)
1702 {
1703  float x = length / L;
1704  float xx = x * x;
1705  float xxx = xx * x;
1706  float xxxx = xxx * x;
1707  return (-11.541f * xxxx + 34.193f * xxx - 39.083f * xx + 23.116f * x - 9.713f);
1708 }
1709 
1710 BLI_INLINE float fbderiv(float length, float L)
1711 {
1712  float x = length / L;
1713  float xx = x * x;
1714  float xxx = xx * x;
1715  return (-46.164f * xxx + 102.579f * xx - 78.166f * x + 23.116f);
1716 }
1717 
1718 BLI_INLINE float fbstar(float length, float L, float kb, float cb)
1719 {
1720  float tempfb_fl = kb * fb(length, L);
1721  float fbstar_fl = cb * (length - L);
1722 
1723  if (tempfb_fl < fbstar_fl) {
1724  return fbstar_fl;
1725  }
1726 
1727  return tempfb_fl;
1728 }
1729 
1730 /* Function to calculate bending spring force (taken from Choi & Co). */
1731 BLI_INLINE float fbstar_jacobi(float length, float L, float kb, float cb)
1732 {
1733  float tempfb_fl = kb * fb(length, L);
1734  float fbstar_fl = cb * (length - L);
1735 
1736  if (tempfb_fl < fbstar_fl) {
1737  return -cb;
1738  }
1739 
1740  return -kb * fbderiv(length, L);
1741 }
1742 
1743 /* calculate elongation */
1745  int i,
1746  int j,
1747  float r_extent[3],
1748  float r_dir[3],
1749  float *r_length,
1750  float r_vel[3])
1751 {
1752  sub_v3_v3v3(r_extent, data->X[j], data->X[i]);
1753  sub_v3_v3v3(r_vel, data->V[j], data->V[i]);
1754  *r_length = len_v3(r_extent);
1755 
1756  if (*r_length > ALMOST_ZERO) {
1757 # if 0
1758  if (length > L) {
1759  if ((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) &&
1760  (((length - L) * 100.0f / L) > clmd->sim_parms->maxspringlen)) {
1761  /* cut spring! */
1762  s->flags |= CSPRING_FLAG_DEACTIVATE;
1763  return false;
1764  }
1765  }
1766 # endif
1767  mul_v3_v3fl(r_dir, r_extent, 1.0f / (*r_length));
1768  }
1769  else {
1770  zero_v3(r_dir);
1771  }
1772 
1773  return true;
1774 }
1775 
1777  int i,
1778  int j,
1779  const float f[3],
1780  const float dfdx[3][3],
1781  const float dfdv[3][3])
1782 {
1783  int block_ij = SIM_mass_spring_add_block(data, i, j);
1784 
1785  add_v3_v3(data->F[i], f);
1786  sub_v3_v3(data->F[j], f);
1787 
1788  add_m3_m3m3(data->dFdX[i].m, data->dFdX[i].m, dfdx);
1789  add_m3_m3m3(data->dFdX[j].m, data->dFdX[j].m, dfdx);
1790  sub_m3_m3m3(data->dFdX[block_ij].m, data->dFdX[block_ij].m, dfdx);
1791 
1792  add_m3_m3m3(data->dFdV[i].m, data->dFdV[i].m, dfdv);
1793  add_m3_m3m3(data->dFdV[j].m, data->dFdV[j].m, dfdv);
1794  sub_m3_m3m3(data->dFdV[block_ij].m, data->dFdV[block_ij].m, dfdv);
1795 }
1796 
1798  int i,
1799  int j,
1800  float restlen,
1801  float stiffness_tension,
1802  float damping_tension,
1803  float stiffness_compression,
1804  float damping_compression,
1805  bool resist_compress,
1806  bool new_compress,
1807  float clamp_force)
1808 {
1809  float extent[3], length, dir[3], vel[3];
1810  float f[3], dfdx[3][3], dfdv[3][3];
1811  float damping = 0;
1812 
1813  /* calculate elongation */
1814  spring_length(data, i, j, extent, dir, &length, vel);
1815 
1816  /* This code computes not only the force, but also its derivative.
1817  * Zero derivative effectively disables the spring for the implicit solver.
1818  * Thus length > restlen makes cloth unconstrained at the start of simulation. */
1819  if ((length >= restlen && length > 0) || resist_compress) {
1820  float stretch_force;
1821 
1822  damping = damping_tension;
1823 
1824  stretch_force = stiffness_tension * (length - restlen);
1825  if (clamp_force > 0.0f && stretch_force > clamp_force) {
1826  stretch_force = clamp_force;
1827  }
1828  mul_v3_v3fl(f, dir, stretch_force);
1829 
1830  dfdx_spring(dfdx, dir, length, restlen, stiffness_tension);
1831  }
1832  else if (new_compress) {
1833  /* This is based on the Choi and Ko bending model,
1834  * which works surprisingly well for compression. */
1835  float kb = stiffness_compression;
1836  float cb = kb; /* cb equal to kb seems to work, but a factor can be added if necessary */
1837 
1838  damping = damping_compression;
1839 
1840  mul_v3_v3fl(f, dir, fbstar(length, restlen, kb, cb));
1841 
1842  outerproduct(dfdx, dir, dir);
1843  mul_m3_fl(dfdx, fbstar_jacobi(length, restlen, kb, cb));
1844  }
1845  else {
1846  return false;
1847  }
1848 
1849  madd_v3_v3fl(f, dir, damping * dot_v3v3(vel, dir));
1850  dfdv_damp(dfdv, dir, damping);
1851 
1852  apply_spring(data, i, j, f, dfdx, dfdv);
1853 
1854  return true;
1855 }
1856 
1857 /* See "Stable but Responsive Cloth" (Choi, Ko 2005) */
1859  Implicit_Data *data, int i, int j, float restlen, float kb, float cb)
1860 {
1861  float extent[3], length, dir[3], vel[3];
1862 
1863  /* calculate elongation */
1864  spring_length(data, i, j, extent, dir, &length, vel);
1865 
1866  if (length < restlen) {
1867  float f[3], dfdx[3][3], dfdv[3][3];
1868 
1869  mul_v3_v3fl(f, dir, fbstar(length, restlen, kb, cb));
1870 
1871  outerproduct(dfdx, dir, dir);
1872  mul_m3_fl(dfdx, fbstar_jacobi(length, restlen, kb, cb));
1873 
1874  /* XXX damping not supported */
1875  zero_m3(dfdv);
1876 
1877  apply_spring(data, i, j, f, dfdx, dfdv);
1878 
1879  return true;
1880  }
1881 
1882  return false;
1883 }
1884 
1885 BLI_INLINE void poly_avg(lfVector *data, const int *inds, int len, float r_avg[3])
1886 {
1887  float fact = 1.0f / (float)len;
1888 
1889  zero_v3(r_avg);
1890 
1891  for (int i = 0; i < len; i++) {
1892  madd_v3_v3fl(r_avg, data[inds[i]], fact);
1893  }
1894 }
1895 
1896 BLI_INLINE void poly_norm(lfVector *data, int i, int j, int *inds, int len, float r_dir[3])
1897 {
1898  float mid[3];
1899 
1900  poly_avg(data, inds, len, mid);
1901 
1902  normal_tri_v3(r_dir, data[i], data[j], mid);
1903 }
1904 
1905 BLI_INLINE void edge_avg(lfVector *data, int i, int j, float r_avg[3])
1906 {
1907  r_avg[0] = (data[i][0] + data[j][0]) * 0.5f;
1908  r_avg[1] = (data[i][1] + data[j][1]) * 0.5f;
1909  r_avg[2] = (data[i][2] + data[j][2]) * 0.5f;
1910 }
1911 
1912 BLI_INLINE void edge_norm(lfVector *data, int i, int j, float r_dir[3])
1913 {
1914  sub_v3_v3v3(r_dir, data[i], data[j]);
1915  normalize_v3(r_dir);
1916 }
1917 
1918 BLI_INLINE float bend_angle(const float dir_a[3], const float dir_b[3], const float dir_e[3])
1919 {
1920  float cos, sin;
1921  float tmp[3];
1922 
1923  cos = dot_v3v3(dir_a, dir_b);
1924 
1925  cross_v3_v3v3(tmp, dir_a, dir_b);
1926  sin = dot_v3v3(tmp, dir_e);
1927 
1928  return atan2f(sin, cos);
1929 }
1930 
1932  int i,
1933  int j,
1934  int *i_a,
1935  int *i_b,
1936  int len_a,
1937  int len_b,
1938  float r_dir_a[3],
1939  float r_dir_b[3],
1940  float *r_angle,
1941  float r_vel_a[3],
1942  float r_vel_b[3])
1943 {
1944  float dir_e[3], vel_e[3];
1945 
1946  poly_norm(data->X, j, i, i_a, len_a, r_dir_a);
1947  poly_norm(data->X, i, j, i_b, len_b, r_dir_b);
1948 
1949  edge_norm(data->X, i, j, dir_e);
1950 
1951  *r_angle = bend_angle(r_dir_a, r_dir_b, dir_e);
1952 
1953  poly_avg(data->V, i_a, len_a, r_vel_a);
1954  poly_avg(data->V, i_b, len_b, r_vel_b);
1955 
1956  edge_avg(data->V, i, j, vel_e);
1957 
1958  sub_v3_v3(r_vel_a, vel_e);
1959  sub_v3_v3(r_vel_b, vel_e);
1960 }
1961 
1962 /* Angular springs roughly based on the bending model proposed by Baraff and Witkin in "Large Steps
1963  * in Cloth Simulation". */
1965  int i,
1966  int j,
1967  int *i_a,
1968  int *i_b,
1969  int len_a,
1970  int len_b,
1971  float restang,
1972  float stiffness,
1973  float damping)
1974 {
1975  float angle, dir_a[3], dir_b[3], vel_a[3], vel_b[3];
1976  float f_a[3], f_b[3], f_e[3];
1977  float force;
1978  int x;
1979 
1980  spring_angle(data, i, j, i_a, i_b, len_a, len_b, dir_a, dir_b, &angle, vel_a, vel_b);
1981 
1982  /* spring force */
1983  force = stiffness * (angle - restang);
1984 
1985  /* damping force */
1986  force += -damping * (dot_v3v3(vel_a, dir_a) + dot_v3v3(vel_b, dir_b));
1987 
1988  mul_v3_v3fl(f_a, dir_a, force / len_a);
1989  mul_v3_v3fl(f_b, dir_b, force / len_b);
1990 
1991  for (x = 0; x < len_a; x++) {
1992  add_v3_v3(data->F[i_a[x]], f_a);
1993  }
1994 
1995  for (x = 0; x < len_b; x++) {
1996  add_v3_v3(data->F[i_b[x]], f_b);
1997  }
1998 
1999  mul_v3_v3fl(f_a, dir_a, force * 0.5f);
2000  mul_v3_v3fl(f_b, dir_b, force * 0.5f);
2001 
2002  add_v3_v3v3(f_e, f_a, f_b);
2003 
2004  sub_v3_v3(data->F[i], f_e);
2005  sub_v3_v3(data->F[j], f_e);
2006 
2007  return true;
2008 }
2009 
2010 /* Jacobian of a direction vector.
2011  * Basically the part of the differential orthogonal to the direction,
2012  * inversely proportional to the length of the edge.
2013  *
2014  * dD_ij/dx_i = -dD_ij/dx_j = (D_ij * D_ij^T - I) / len_ij
2015  */
2017  Implicit_Data *data, int i, int j, float edge[3], float dir[3], float grad_dir[3][3])
2018 {
2019  float length;
2020 
2021  sub_v3_v3v3(edge, data->X[j], data->X[i]);
2022  length = normalize_v3_v3(dir, edge);
2023 
2024  if (length > ALMOST_ZERO) {
2025  outerproduct(grad_dir, dir, dir);
2026  sub_m3_m3m3(grad_dir, I, grad_dir);
2027  mul_m3_fl(grad_dir, 1.0f / length);
2028  }
2029  else {
2030  zero_m3(grad_dir);
2031  }
2032 }
2033 
2035  int i,
2036  int j,
2037  int k,
2038  const float goal[3],
2039  float stiffness,
2040  float damping,
2041  int q,
2042  const float dx[3],
2043  const float dv[3],
2044  float r_f[3])
2045 {
2046  float edge_ij[3], dir_ij[3];
2047  float edge_jk[3], dir_jk[3];
2048  float vel_ij[3], vel_jk[3], vel_ortho[3];
2049  float f_bend[3], f_damp[3];
2050  float fk[3];
2051  float dist[3];
2052 
2053  zero_v3(fk);
2054 
2055  sub_v3_v3v3(edge_ij, data->X[j], data->X[i]);
2056  if (q == i) {
2057  sub_v3_v3(edge_ij, dx);
2058  }
2059  if (q == j) {
2060  add_v3_v3(edge_ij, dx);
2061  }
2062  normalize_v3_v3(dir_ij, edge_ij);
2063 
2064  sub_v3_v3v3(edge_jk, data->X[k], data->X[j]);
2065  if (q == j) {
2066  sub_v3_v3(edge_jk, dx);
2067  }
2068  if (q == k) {
2069  add_v3_v3(edge_jk, dx);
2070  }
2071  normalize_v3_v3(dir_jk, edge_jk);
2072 
2073  sub_v3_v3v3(vel_ij, data->V[j], data->V[i]);
2074  if (q == i) {
2075  sub_v3_v3(vel_ij, dv);
2076  }
2077  if (q == j) {
2078  add_v3_v3(vel_ij, dv);
2079  }
2080 
2081  sub_v3_v3v3(vel_jk, data->V[k], data->V[j]);
2082  if (q == j) {
2083  sub_v3_v3(vel_jk, dv);
2084  }
2085  if (q == k) {
2086  add_v3_v3(vel_jk, dv);
2087  }
2088 
2089  /* bending force */
2090  sub_v3_v3v3(dist, goal, edge_jk);
2091  mul_v3_v3fl(f_bend, dist, stiffness);
2092 
2093  add_v3_v3(fk, f_bend);
2094 
2095  /* damping force */
2096  madd_v3_v3v3fl(vel_ortho, vel_jk, dir_jk, -dot_v3v3(vel_jk, dir_jk));
2097  mul_v3_v3fl(f_damp, vel_ortho, damping);
2098 
2099  sub_v3_v3(fk, f_damp);
2100 
2101  copy_v3_v3(r_f, fk);
2102 }
2103 
2104 /* Finite Differences method for estimating the jacobian of the force */
2106  int i,
2107  int j,
2108  int k,
2109  const float goal[3],
2110  float stiffness,
2111  float damping,
2112  int q,
2113  float dfdx[3][3])
2114 {
2115  const float delta = 0.00001f; /* TODO find a good heuristic for this */
2116  float dvec_null[3][3], dvec_pos[3][3], dvec_neg[3][3];
2117  float f[3];
2118  int a, b;
2119 
2120  zero_m3(dvec_null);
2121  unit_m3(dvec_pos);
2122  mul_m3_fl(dvec_pos, delta * 0.5f);
2123  copy_m3_m3(dvec_neg, dvec_pos);
2124  negate_m3(dvec_neg);
2125 
2126  /* XXX TODO offset targets to account for position dependency */
2127 
2128  for (a = 0; a < 3; a++) {
2130  data, i, j, k, goal, stiffness, damping, q, dvec_pos[a], dvec_null[a], f);
2131  copy_v3_v3(dfdx[a], f);
2132 
2134  data, i, j, k, goal, stiffness, damping, q, dvec_neg[a], dvec_null[a], f);
2135  sub_v3_v3(dfdx[a], f);
2136 
2137  for (b = 0; b < 3; b++) {
2138  dfdx[a][b] /= delta;
2139  }
2140  }
2141 }
2142 
2143 /* Finite Differences method for estimating the jacobian of the force */
2145  int i,
2146  int j,
2147  int k,
2148  const float goal[3],
2149  float stiffness,
2150  float damping,
2151  int q,
2152  float dfdv[3][3])
2153 {
2154  const float delta = 0.00001f; /* TODO find a good heuristic for this */
2155  float dvec_null[3][3], dvec_pos[3][3], dvec_neg[3][3];
2156  float f[3];
2157  int a, b;
2158 
2159  zero_m3(dvec_null);
2160  unit_m3(dvec_pos);
2161  mul_m3_fl(dvec_pos, delta * 0.5f);
2162  copy_m3_m3(dvec_neg, dvec_pos);
2163  negate_m3(dvec_neg);
2164 
2165  /* XXX TODO offset targets to account for position dependency */
2166 
2167  for (a = 0; a < 3; a++) {
2169  data, i, j, k, goal, stiffness, damping, q, dvec_null[a], dvec_pos[a], f);
2170  copy_v3_v3(dfdv[a], f);
2171 
2173  data, i, j, k, goal, stiffness, damping, q, dvec_null[a], dvec_neg[a], f);
2174  sub_v3_v3(dfdv[a], f);
2175 
2176  for (b = 0; b < 3; b++) {
2177  dfdv[a][b] /= delta;
2178  }
2179  }
2180 }
2181 
2182 /* Angular spring that pulls the vertex toward the local target
2183  * See "Artistic Simulation of Curly Hair" (Pixar technical memo #12-03a)
2184  */
2186  int i,
2187  int j,
2188  int k,
2189  const float target[3],
2190  float stiffness,
2191  float damping)
2192 {
2193  float goal[3];
2194  float fj[3], fk[3];
2195  float dfj_dxi[3][3], dfj_dxj[3][3], dfk_dxi[3][3], dfk_dxj[3][3], dfk_dxk[3][3];
2196  float dfj_dvi[3][3], dfj_dvj[3][3], dfk_dvi[3][3], dfk_dvj[3][3], dfk_dvk[3][3];
2197 
2198  const float vecnull[3] = {0.0f, 0.0f, 0.0f};
2199 
2200  int block_ij = SIM_mass_spring_add_block(data, i, j);
2201  int block_jk = SIM_mass_spring_add_block(data, j, k);
2202  int block_ik = SIM_mass_spring_add_block(data, i, k);
2203 
2204  world_to_root_v3(data, j, goal, target);
2205 
2206  spring_hairbend_forces(data, i, j, k, goal, stiffness, damping, k, vecnull, vecnull, fk);
2207  negate_v3_v3(fj, fk); /* counterforce */
2208 
2209  spring_hairbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, i, dfk_dxi);
2210  spring_hairbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, j, dfk_dxj);
2211  spring_hairbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, k, dfk_dxk);
2212  copy_m3_m3(dfj_dxi, dfk_dxi);
2213  negate_m3(dfj_dxi);
2214  copy_m3_m3(dfj_dxj, dfk_dxj);
2215  negate_m3(dfj_dxj);
2216 
2217  spring_hairbend_estimate_dfdv(data, i, j, k, goal, stiffness, damping, i, dfk_dvi);
2218  spring_hairbend_estimate_dfdv(data, i, j, k, goal, stiffness, damping, j, dfk_dvj);
2219  spring_hairbend_estimate_dfdv(data, i, j, k, goal, stiffness, damping, k, dfk_dvk);
2220  copy_m3_m3(dfj_dvi, dfk_dvi);
2221  negate_m3(dfj_dvi);
2222  copy_m3_m3(dfj_dvj, dfk_dvj);
2223  negate_m3(dfj_dvj);
2224 
2225  /* add forces and jacobians to the solver data */
2226 
2227  add_v3_v3(data->F[j], fj);
2228  add_v3_v3(data->F[k], fk);
2229 
2230  add_m3_m3m3(data->dFdX[j].m, data->dFdX[j].m, dfj_dxj);
2231  add_m3_m3m3(data->dFdX[k].m, data->dFdX[k].m, dfk_dxk);
2232 
2233  add_m3_m3m3(data->dFdX[block_ij].m, data->dFdX[block_ij].m, dfj_dxi);
2234  add_m3_m3m3(data->dFdX[block_jk].m, data->dFdX[block_jk].m, dfk_dxj);
2235  add_m3_m3m3(data->dFdX[block_ik].m, data->dFdX[block_ik].m, dfk_dxi);
2236 
2237  add_m3_m3m3(data->dFdV[j].m, data->dFdV[j].m, dfj_dvj);
2238  add_m3_m3m3(data->dFdV[k].m, data->dFdV[k].m, dfk_dvk);
2239 
2240  add_m3_m3m3(data->dFdV[block_ij].m, data->dFdV[block_ij].m, dfj_dvi);
2241  add_m3_m3m3(data->dFdV[block_jk].m, data->dFdV[block_jk].m, dfk_dvj);
2242  add_m3_m3m3(data->dFdV[block_ik].m, data->dFdV[block_ik].m, dfk_dvi);
2243 
2244  /* XXX analytical calculation of derivatives below is incorrect.
2245  * This proved to be difficult, but for now just using the finite difference method for
2246  * estimating the jacobians should be sufficient.
2247  */
2248 # if 0
2249  float edge_ij[3], dir_ij[3], grad_dir_ij[3][3];
2250  float edge_jk[3], dir_jk[3], grad_dir_jk[3][3];
2251  float dist[3], vel_jk[3], vel_jk_ortho[3], projvel[3];
2252  float target[3];
2253  float tmp[3][3];
2254  float fi[3], fj[3], fk[3];
2255  float dfi_dxi[3][3], dfj_dxi[3][3], dfj_dxj[3][3], dfk_dxi[3][3], dfk_dxj[3][3], dfk_dxk[3][3];
2256  float dfdvi[3][3];
2257 
2258  /* TESTING */
2259  damping = 0.0f;
2260 
2261  zero_v3(fi);
2262  zero_v3(fj);
2263  zero_v3(fk);
2264  zero_m3(dfi_dxi);
2265  zero_m3(dfj_dxi);
2266  zero_m3(dfk_dxi);
2267  zero_m3(dfk_dxj);
2268  zero_m3(dfk_dxk);
2269 
2270  /* jacobian of direction vectors */
2271  spring_grad_dir(data, i, j, edge_ij, dir_ij, grad_dir_ij);
2272  spring_grad_dir(data, j, k, edge_jk, dir_jk, grad_dir_jk);
2273 
2274  sub_v3_v3v3(vel_jk, data->V[k], data->V[j]);
2275 
2276  /* bending force */
2277  mul_v3_v3fl(target, dir_ij, restlen);
2278  sub_v3_v3v3(dist, target, edge_jk);
2279  mul_v3_v3fl(fk, dist, stiffness);
2280 
2281  /* damping force */
2282  madd_v3_v3v3fl(vel_jk_ortho, vel_jk, dir_jk, -dot_v3v3(vel_jk, dir_jk));
2283  madd_v3_v3fl(fk, vel_jk_ortho, damping);
2284 
2285  /* XXX this only holds true as long as we assume straight rest shape!
2286  * eventually will become a bit more involved since the opposite segment
2287  * gets its own target, under condition of having equal torque on both sides.
2288  */
2289  copy_v3_v3(fi, fk);
2290 
2291  /* counterforce on the middle point */
2292  sub_v3_v3(fj, fi);
2293  sub_v3_v3(fj, fk);
2294 
2295  /* === derivatives === */
2296 
2297  madd_m3_m3fl(dfk_dxi, grad_dir_ij, stiffness * restlen);
2298 
2299  madd_m3_m3fl(dfk_dxj, grad_dir_ij, -stiffness * restlen);
2300  madd_m3_m3fl(dfk_dxj, I, stiffness);
2301 
2302  madd_m3_m3fl(dfk_dxk, I, -stiffness);
2303 
2304  copy_m3_m3(dfi_dxi, dfk_dxk);
2305  negate_m3(dfi_dxi);
2306 
2307  /* dfj_dfi == dfi_dfj due to symmetry,
2308  * dfi_dfj == dfk_dfj due to fi == fk
2309  * XXX see comment above on future bent rest shapes
2310  */
2311  copy_m3_m3(dfj_dxi, dfk_dxj);
2312 
2313  /* dfj_dxj == -(dfi_dxj + dfk_dxj) due to fj == -(fi + fk) */
2314  sub_m3_m3m3(dfj_dxj, dfj_dxj, dfj_dxi);
2315  sub_m3_m3m3(dfj_dxj, dfj_dxj, dfk_dxj);
2316 
2317  /* add forces and jacobians to the solver data */
2318  add_v3_v3(data->F[i], fi);
2319  add_v3_v3(data->F[j], fj);
2320  add_v3_v3(data->F[k], fk);
2321 
2322  add_m3_m3m3(data->dFdX[i].m, data->dFdX[i].m, dfi_dxi);
2323  add_m3_m3m3(data->dFdX[j].m, data->dFdX[j].m, dfj_dxj);
2324  add_m3_m3m3(data->dFdX[k].m, data->dFdX[k].m, dfk_dxk);
2325 
2326  add_m3_m3m3(data->dFdX[block_ij].m, data->dFdX[block_ij].m, dfj_dxi);
2327  add_m3_m3m3(data->dFdX[block_jk].m, data->dFdX[block_jk].m, dfk_dxj);
2328  add_m3_m3m3(data->dFdX[block_ik].m, data->dFdX[block_ik].m, dfk_dxi);
2329 # endif
2330 
2331  return true;
2332 }
2333 
2335  int i,
2336  const float goal_x[3],
2337  const float goal_v[3],
2338  float stiffness,
2339  float damping)
2340 {
2341  float root_goal_x[3], root_goal_v[3], extent[3], length, dir[3], vel[3];
2342  float f[3], dfdx[3][3], dfdv[3][3];
2343 
2344  /* goal is in world space */
2345  world_to_root_v3(data, i, root_goal_x, goal_x);
2346  world_to_root_v3(data, i, root_goal_v, goal_v);
2347 
2348  sub_v3_v3v3(extent, root_goal_x, data->X[i]);
2349  sub_v3_v3v3(vel, root_goal_v, data->V[i]);
2350  length = normalize_v3_v3(dir, extent);
2351 
2352  if (length > ALMOST_ZERO) {
2353  mul_v3_v3fl(f, dir, stiffness * length);
2354 
2355  /* Ascher & Boxman, p.21: Damping only during elongation
2356  * something wrong with it. */
2357  madd_v3_v3fl(f, dir, damping * dot_v3v3(vel, dir));
2358 
2359  dfdx_spring(dfdx, dir, length, 0.0f, stiffness);
2360  dfdv_damp(dfdv, dir, damping);
2361 
2362  add_v3_v3(data->F[i], f);
2363  add_m3_m3m3(data->dFdX[i].m, data->dFdX[i].m, dfdx);
2364  add_m3_m3m3(data->dFdV[i].m, data->dFdV[i].m, dfdv);
2365 
2366  return true;
2367  }
2368 
2369  return false;
2370 }
2371 
2372 #endif /* IMPLICIT_SOLVER_BLENDER */
typedef float(TangentPoint)[2]
#define VECADDS(v1, v2, v3, bS)
Definition: BKE_cloth.h:168
#define DO_INLINE
Definition: BKE_cloth.h:40
#define VECSUBS(v1, v2, v3, bS)
Definition: BKE_cloth.h:182
#define VECADDSS(v1, v2, aS, v3, bS)
Definition: BKE_cloth.h:161
#define VECSUBADDSS(v1, v2, aS, v3, bS)
Definition: BKE_cloth.h:154
#define VECSUBMUL(v1, v2, aS)
Definition: BKE_cloth.h:175
#define ALMOST_ZERO
Definition: BKE_cloth.h:47
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_INLINE
sqrt(x)+1/max(0
#define M_PI
Definition: BLI_math_base.h:38
float volume_tri_tetrahedron_signed_v3_6x(const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:307
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:51
void sub_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:1080
void negate_m3(float R[3][3])
Definition: math_matrix.c:993
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:930
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:89
void unit_m3(float m[3][3])
Definition: math_matrix.c:58
void mul_m3_fl(float R[3][3], float f)
Definition: math_matrix.c:960
void add_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:1036
void zero_m3(float m[3][3])
Definition: math_matrix.c:41
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
Definition: math_matrix.c:901
void transpose_m3(float R[3][3])
Definition: math_matrix.c:1312
void mul_transposed_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:940
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:391
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
#define UNUSED(x)
#define MAX2(a, b)
Object is a sort of wrapper for general info.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint i1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Read Guarded memory(de)allocation.
Platform independent time functions.
@ SIM_SOLVER_SUCCESS
@ SIM_SOLVER_NO_CONVERGENCE
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
Definition: btQuaternion.h:895
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
StackEntry * from
static CCL_NAMESPACE_BEGIN const double alpha
BLI_INLINE void print_lvector(const lVector3f &v)
Definition: eigen_utils.h:206
static float verts[][3]
uint nor
BLI_INLINE void implicit_print_matrix_elem(float v)
Definition: implicit.h:62
void SIM_mass_spring_force_gravity(Implicit_Data *data, int index, float mass, const float g[3])
void SIM_mass_spring_set_vertex_mass(Implicit_Data *data, int index, float mass)
void SIM_mass_spring_clear_forces(Implicit_Data *data)
BLI_INLINE void apply_spring(Implicit_Data *data, int i, int j, const float f[3], const float dfdx[3][3], const float dfdv[3][3])
DO_INLINE void add_lfvector_lfvector(float(*to)[3], float(*fLongVectorA)[3], float(*fLongVectorB)[3], unsigned int verts)
void SIM_mass_spring_clear_constraints(Implicit_Data *data)
BLI_INLINE float fbstar_jacobi(float length, float L, float kb, float cb)
void SIM_mass_spring_force_pressure(Implicit_Data *data, int v1, int v2, int v3, float common_pressure, const float *vertex_pressure, const float weights[3])
DO_INLINE void add_lfvector_lfvectorS(float(*to)[3], float(*fLongVectorA)[3], float(*fLongVectorB)[3], float bS, unsigned int verts)
DO_INLINE void add_fmatrix_fmatrix(float to[3][3], const float matrixA[3][3], const float matrixB[3][3])
void SIM_mass_spring_add_constraint_ndof0(Implicit_Data *data, int index, const float dV[3])
static void edge_wind_vertex(const float dir[3], float length, float radius, const float wind[3], float f[3], float UNUSED(dfdx[3][3]), float UNUSED(dfdv[3][3]))
DO_INLINE void mul_fvectorT_fvector(float to[3][3], const float vectorA[3], const float vectorB[3])
void SIM_mass_spring_get_motion_state(struct Implicit_Data *data, int index, float x[3], float v[3])
DO_INLINE void del_lfvector(float(*fLongVector)[3])
BLI_INLINE void cross_m3_v3m3(float r[3][3], const float v[3], const float m[3][3])
bool SIM_mass_spring_force_spring_bending_hair(Implicit_Data *data, int i, int j, int k, const float target[3], float stiffness, float damping)
BLI_INLINE float fb(float length, float L)
struct fmatrix3x3 fmatrix3x3
void SIM_mass_spring_set_velocity(Implicit_Data *data, int index, const float v[3])
DO_INLINE lfVector * create_lfvector(unsigned int verts)
DO_INLINE void mul_fvectorT_fvectorS(float to[3][3], float vectorA[3], float vectorB[3], float aS)
DO_INLINE void mul_fmatrix_S(float matrix[3][3], float scalar)
bool SIM_mass_spring_solve_positions(Implicit_Data *data, float dt)
DO_INLINE void initdiag_fmatrixS(float to[3][3], float aS)
Implicit_Data * SIM_mass_spring_solver_create(int numverts, int numsprings)
void SIM_mass_spring_set_new_velocity(struct Implicit_Data *data, int index, const float v[3])
BLI_INLINE float fbderiv(float length, float L)
BLI_INLINE void madd_m3_m3fl(float r[3][3], const float m[3][3], float f)
DO_INLINE void mul_lfvectorS(float(*to)[3], float(*fLongVector)[3], float scalar, unsigned int verts)
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
DO_INLINE void muladd_fmatrix_fvector(float to[3], const float matrix[3][3], const float from[3])
DO_INLINE void zero_lfvector(float(*to)[3], unsigned int verts)
DO_INLINE void mul_bfmatrix_lfvector(float(*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
BLI_INLINE void spring_hairbend_forces(Implicit_Data *data, int i, int j, int k, const float goal[3], float stiffness, float damping, int q, const float dx[3], const float dv[3], float r_f[3])
float SIM_tri_area(struct Implicit_Data *data, int v1, int v2, int v3)
bool SIM_mass_spring_force_spring_goal(Implicit_Data *data, int i, const float goal_x[3], const float goal_v[3], float stiffness, float damping)
void SIM_mass_spring_force_face_extern(Implicit_Data *data, int v1, int v2, int v3, const float(*forcevec)[3])
DO_INLINE void muladd_fmatrixT_fvector(float to[3], const float matrix[3][3], const float from[3])
bool SIM_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSolverResult *result)
DO_INLINE void mul_fvector_fmatrix(float *to, const float *from, const float matrix[3][3])
void SIM_mass_spring_get_velocity(struct Implicit_Data *data, int index, float v[3])
BLI_INLINE void init_fmatrix(fmatrix3x3 *matrix, int r, int c)
void SIM_mass_spring_add_constraint_ndof2(Implicit_Data *data, int index, const float c1[3], const float dV[3])
BLI_INLINE bool spring_length(Implicit_Data *data, int i, int j, float r_extent[3], float r_dir[3], float *r_length, float r_vel[3])
void SIM_mass_spring_get_new_position(struct Implicit_Data *data, int index, float x[3])
static int SIM_mass_spring_add_block(Implicit_Data *data, int v1, int v2)
BLI_INLINE void edge_avg(lfVector *data, int i, int j, float r_avg[3])
void SIM_mass_spring_force_drag(Implicit_Data *data, float drag)
DO_INLINE fmatrix3x3 * create_bfmatrix(unsigned int verts, unsigned int springs)
DO_INLINE void subadd_fmatrixS_fmatrixS(float to[3][3], const float matrixA[3][3], float aS, const float matrixB[3][3], float bS)
BLI_INLINE void root_to_world_m3(Implicit_Data *data, int index, float r[3][3], const float m[3][3])
void SIM_mass_spring_solver_free(Implicit_Data *id)
BLI_INLINE void cross_v3_identity(float r[3][3], const float v[3])
DO_INLINE void init_lfvector(float(*fLongVector)[3], const float vector[3], unsigned int verts)
DO_INLINE void mul_fmatrix_fvector(float *to, const float matrix[3][3], const float from[3])
bool SIM_mass_spring_force_spring_linear(Implicit_Data *data, int i, int j, float restlen, float stiffness_tension, float damping_tension, float stiffness_compression, float damping_compression, bool resist_compress, bool new_compress, float clamp_force)
BLI_INLINE void outerproduct(float r[3][3], const float a[3], const float b[3])
bool SIM_mass_spring_force_spring_bending(Implicit_Data *data, int i, int j, float restlen, float kb, float cb)
DO_INLINE void mul_fvector_S(float to[3], const float from[3], float scalar)
DO_INLINE float dot_lfvector(float(*fLongVectorA)[3], float(*fLongVectorB)[3], unsigned int verts)
static float ZERO[3][3]
void SIM_mass_spring_set_motion_state(Implicit_Data *data, int index, const float x[3], const float v[3])
void SIM_mass_spring_set_position(Implicit_Data *data, int index, const float x[3])
DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], const float matrixA[3][3], const float matrixB[3][3])
struct Implicit_Data Implicit_Data
DO_INLINE void add_lfvectorS_lfvectorS(float(*to)[3], float(*fLongVectorA)[3], float aS, float(*fLongVectorB)[3], float bS, unsigned int verts)
BLI_INLINE void dfdx_spring(float to[3][3], const float dir[3], float length, float L, float k)
void SIM_mass_spring_set_rest_transform(Implicit_Data *data, int index, float tfm[3][3])
void SIM_mass_spring_get_position(struct Implicit_Data *data, int index, float x[3])
static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, ImplicitSolverResult *result)
DO_INLINE void cp_fmatrix(float to[3][3], const float from[3][3])
BLI_INLINE void poly_norm(lfVector *data, int i, int j, int *inds, int len, float r_dir[3])
void SIM_mass_spring_set_new_position(struct Implicit_Data *data, int index, const float x[3])
DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
void SIM_mass_spring_force_edge_wind(Implicit_Data *data, int v1, int v2, float radius1, float radius2, const float(*winvec)[3])
DO_INLINE void cp_bfmatrix(fmatrix3x3 *to, fmatrix3x3 *from)
BLI_INLINE void spring_grad_dir(Implicit_Data *data, int i, int j, float edge[3], float dir[3], float grad_dir[3][3])
void SIM_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3, const float(*winvec)[3])
static float calc_nor_area_tri(float nor[3], const float v1[3], const float v2[3], const float v3[3])
BLI_INLINE void root_to_world_v3(Implicit_Data *data, int index, float r[3], const float v[3])
BLI_INLINE void poly_avg(lfVector *data, const int *inds, int len, float r_avg[3])
void SIM_mass_spring_get_new_velocity(struct Implicit_Data *data, int index, float v[3])
DO_INLINE void subadd_bfmatrixS_bfmatrixS(fmatrix3x3 *to, fmatrix3x3 *from, float aS, fmatrix3x3 *matrix, float bS)
void SIM_mass_spring_add_constraint_ndof1(Implicit_Data *data, int index, const float c1[3], const float c2[3], const float dV[3])
BLI_INLINE void world_to_root_m3(Implicit_Data *data, int index, float r[3][3], const float m[3][3])
static float I[3][3]
DO_INLINE void sub_lfvector_lfvector(float(*to)[3], float(*fLongVectorA)[3], float(*fLongVectorB)[3], unsigned int verts)
DO_INLINE void submul_lfvectorS(float(*to)[3], float(*fLongVector)[3], float scalar, unsigned int verts)
BLI_INLINE void edge_norm(lfVector *data, int i, int j, float r_dir[3])
DO_INLINE void sub_lfvector_lfvectorS(float(*to)[3], float(*fLongVectorA)[3], float(*fLongVectorB)[3], float bS, unsigned int verts)
BLI_INLINE void spring_hairbend_estimate_dfdv(Implicit_Data *data, int i, int j, int k, const float goal[3], float stiffness, float damping, int q, float dfdv[3][3])
BLI_INLINE float fbstar(float length, float L, float kb, float cb)
DO_INLINE void del_bfmatrix(fmatrix3x3 *matrix)
void SIM_mass_spring_force_reference_frame(Implicit_Data *data, int index, const float acceleration[3], const float omega[3], const float domega_dt[3], float mass)
float SIM_tri_tetra_volume_signed_6x(Implicit_Data *data, int v1, int v2, int v3)
bool SIM_mass_spring_force_spring_angular(Implicit_Data *data, int i, int j, int *i_a, int *i_b, int len_a, int len_b, float restang, float stiffness, float damping)
BLI_INLINE void spring_hairbend_estimate_dfdx(Implicit_Data *data, int i, int j, int k, const float goal[3], float stiffness, float damping, int q, float dfdx[3][3])
BLI_INLINE void world_to_root_v3(Implicit_Data *data, int index, float r[3], const float v[3])
BLI_INLINE void dfdv_damp(float to[3][3], const float dir[3], float damping)
void SIM_mass_spring_force_extern(struct Implicit_Data *data, int i, const float f[3], float dfdx[3][3], float dfdv[3][3])
float lfVector[3]
void SIM_mass_spring_apply_result(Implicit_Data *data)
BLI_INLINE float bend_angle(const float dir_a[3], const float dir_b[3], const float dir_e[3])
BLI_INLINE void spring_angle(Implicit_Data *data, int i, int j, int *i_a, int *i_b, int len_a, int len_b, float r_dir_a[3], float r_dir_b[3], float *r_angle, float r_vel_a[3], float r_vel_b[3])
DO_INLINE void init_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
DO_INLINE void cp_lfvector(float(*to)[3], float(*from)[3], unsigned int verts)
void SIM_mass_spring_force_vertex_wind(Implicit_Data *data, int v, float UNUSED(radius), const float(*winvec)[3])
#define atan2f(x, y)
#define sqrtf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static float P(float k)
Definition: math_interp.c:41
#define M
#define L
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:319
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:311
static void area(int d1, int d2, int e1, int e2, float weights[2])
fmatrix3x3 * M
fmatrix3x3 * bigI
fmatrix3x3 * A
fmatrix3x3 * Pinv
fmatrix3x3 * S
fmatrix3x3 * dFdX
fmatrix3x3 * dFdV
fmatrix3x3 * P
fmatrix3x3 * tfm
unsigned int r
float m[3][3]
unsigned int c
unsigned int scount
unsigned int vcount
double PIL_check_seconds_timer(void)
Definition: time.c:80
CCL_NAMESPACE_BEGIN struct View V
uint len