Blender  V2.93
GeomUtils.cpp
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 
22 #include "GeomUtils.h"
23 
25 
26 // This internal procedure is defined below.
27 bool intersect2dSegPoly(Vec2r *seg, Vec2r *poly, unsigned n);
28 
29 bool intersect2dSeg2dArea(const Vec2r &min, const Vec2r &max, const Vec2r &A, const Vec2r &B)
30 {
31  Vec2r seg[2];
32  seg[0] = A;
33  seg[1] = B;
34 
35  Vec2r poly[5];
36  poly[0][0] = min[0];
37  poly[0][1] = min[1];
38  poly[1][0] = max[0];
39  poly[1][1] = min[1];
40  poly[2][0] = max[0];
41  poly[2][1] = max[1];
42  poly[3][0] = min[0];
43  poly[3][1] = max[1];
44  poly[4][0] = min[0];
45  poly[4][1] = min[1];
46 
47  return intersect2dSegPoly(seg, poly, 4);
48 }
49 
50 bool include2dSeg2dArea(const Vec2r &min, const Vec2r &max, const Vec2r &A, const Vec2r &B)
51 {
52  if ((((max[0] > A[0]) && (A[0] > min[0])) && ((max[0] > B[0]) && (B[0] > min[0]))) &&
53  (((max[1] > A[1]) && (A[1] > min[1])) && ((max[1] > B[1]) && (B[1] > min[1])))) {
54  return true;
55  }
56  return false;
57 }
58 
60  const Vec2r &p1, const Vec2r &p2, const Vec2r &p3, const Vec2r &p4, Vec2r &res)
61 {
62  real a1, a2, b1, b2, c1, c2; // Coefficients of line eqns
63  real r1, r2, r3, r4; // 'Sign' values
64  real denom, num; // Intermediate values
65 
66  // Compute a1, b1, c1, where line joining points p1 and p2 is "a1 x + b1 y + c1 = 0".
67  a1 = p2[1] - p1[1];
68  b1 = p1[0] - p2[0];
69  c1 = p2[0] * p1[1] - p1[0] * p2[1];
70 
71  // Compute r3 and r4.
72  r3 = a1 * p3[0] + b1 * p3[1] + c1;
73  r4 = a1 * p4[0] + b1 * p4[1] + c1;
74 
75  // Check signs of r3 and r4. If both point 3 and point 4 lie on same side of line 1,
76  // the line segments do not intersect.
77  if (r3 != 0 && r4 != 0 && r3 * r4 > 0.0) {
78  return DONT_INTERSECT;
79  }
80 
81  // Compute a2, b2, c2
82  a2 = p4[1] - p3[1];
83  b2 = p3[0] - p4[0];
84  c2 = p4[0] * p3[1] - p3[0] * p4[1];
85 
86  // Compute r1 and r2
87  r1 = a2 * p1[0] + b2 * p1[1] + c2;
88  r2 = a2 * p2[0] + b2 * p2[1] + c2;
89 
90  // Check signs of r1 and r2. If both point 1 and point 2 lie on same side of second line
91  // segment, the line segments do not intersect.
92  if (r1 != 0 && r2 != 0 && r1 * r2 > 0.0) {
93  return DONT_INTERSECT;
94  }
95 
96  // Line segments intersect: compute intersection point.
97  denom = a1 * b2 - a2 * b1;
98  if (fabs(denom) < M_EPSILON) {
99  return COLINEAR;
100  }
101 
102  num = b1 * c2 - b2 * c1;
103  res[0] = num / denom;
104 
105  num = a2 * c1 - a1 * c2;
106  res[1] = num / denom;
107 
108  return DO_INTERSECT;
109 }
110 
112  const Vec2r &p1, const Vec2r &p2, const Vec2r &p3, const Vec2r &p4, Vec2r &res)
113 {
114  real a1, a2, b1, b2, c1, c2; // Coefficients of line eqns
115  real denom, num; // Intermediate values
116 
117  // Compute a1, b1, c1, where line joining points p1 and p2 is "a1 x + b1 y + c1 = 0".
118  a1 = p2[1] - p1[1];
119  b1 = p1[0] - p2[0];
120  c1 = p2[0] * p1[1] - p1[0] * p2[1];
121 
122  // Compute a2, b2, c2
123  a2 = p4[1] - p3[1];
124  b2 = p3[0] - p4[0];
125  c2 = p4[0] * p3[1] - p3[0] * p4[1];
126 
127  // Line segments intersect: compute intersection point.
128  denom = a1 * b2 - a2 * b1;
129  if (fabs(denom) < M_EPSILON) {
130  return COLINEAR;
131  }
132 
133  num = b1 * c2 - b2 * c1;
134  res[0] = num / denom;
135 
136  num = a2 * c1 - a1 * c2;
137  res[1] = num / denom;
138 
139  return DO_INTERSECT;
140 }
141 
143  const Vec2r &p2,
144  const Vec2r &p3,
145  const Vec2r &p4,
146  real &t,
147  real &u,
148  real epsilon)
149 {
150  real a1, a2, b1, b2, c1, c2; // Coefficients of line eqns
151  real r1, r2, r3, r4; // 'Sign' values
152  real denom, num; // Intermediate values
153 
154  // Compute a1, b1, c1, where line joining points p1 and p2 is "a1 x + b1 y + c1 = 0".
155  a1 = p2[1] - p1[1];
156  b1 = p1[0] - p2[0];
157  c1 = p2[0] * p1[1] - p1[0] * p2[1];
158 
159  // Compute r3 and r4.
160  r3 = a1 * p3[0] + b1 * p3[1] + c1;
161  r4 = a1 * p4[0] + b1 * p4[1] + c1;
162 
163  // Check signs of r3 and r4. If both point 3 and point 4 lie on same side of line 1,
164  // the line segments do not intersect.
165  if (r3 != 0 && r4 != 0 && r3 * r4 > 0.0) {
166  return DONT_INTERSECT;
167  }
168 
169  // Compute a2, b2, c2
170  a2 = p4[1] - p3[1];
171  b2 = p3[0] - p4[0];
172  c2 = p4[0] * p3[1] - p3[0] * p4[1];
173 
174  // Compute r1 and r2
175  r1 = a2 * p1[0] + b2 * p1[1] + c2;
176  r2 = a2 * p2[0] + b2 * p2[1] + c2;
177 
178  // Check signs of r1 and r2. If both point 1 and point 2 lie on same side of second line
179  // segment, the line segments do not intersect.
180  if (r1 != 0 && r2 != 0 && r1 * r2 > 0.0) {
181  return DONT_INTERSECT;
182  }
183 
184  // Line segments intersect: compute intersection point.
185  denom = a1 * b2 - a2 * b1;
186  if (fabs(denom) < epsilon) {
187  return COLINEAR;
188  }
189 
190  real d1, e1;
191 
192  d1 = p1[1] - p3[1];
193  e1 = p1[0] - p3[0];
194 
195  num = -b2 * d1 - a2 * e1;
196  t = num / denom;
197 
198  num = -b1 * d1 - a1 * e1;
199  u = num / denom;
200 
201  return DO_INTERSECT;
202 }
203 
204 // AABB-triangle overlap test code by Tomas Akenine-Möller
205 // Function: int triBoxOverlap(real boxcenter[3], real boxhalfsize[3],real triverts[3][3]);
206 // History:
207 // 2001-03-05: released the code in its first version
208 // 2001-06-18: changed the order of the tests, faster
209 //
210 // Acknowledgement: Many thanks to Pierre Terdiman for suggestions and discussions on how to
211 // optimize code. Thanks to David Hunt for finding a ">="-bug!
212 
213 #define X 0
214 #define Y 1
215 #define Z 2
216 
217 #define FINDMINMAX(x0, x1, x2, min, max) \
218  { \
219  min = max = x0; \
220  if (x1 < min) { \
221  min = x1; \
222  } \
223  if (x1 > max) { \
224  max = x1; \
225  } \
226  if (x2 < min) { \
227  min = x2; \
228  } \
229  if (x2 > max) { \
230  max = x2; \
231  } \
232  } \
233  (void)0
234 
235 //======================== X-tests ========================//
236 #define AXISTEST_X01(a, b, fa, fb) \
237  { \
238  p0 = a * v0[Y] - b * v0[Z]; \
239  p2 = a * v2[Y] - b * v2[Z]; \
240  if (p0 < p2) { \
241  min = p0; \
242  max = p2; \
243  } \
244  else { \
245  min = p2; \
246  max = p0; \
247  } \
248  rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \
249  if (min > rad || max < -rad) { \
250  return 0; \
251  } \
252  } \
253  (void)0
254 
255 #define AXISTEST_X2(a, b, fa, fb) \
256  { \
257  p0 = a * v0[Y] - b * v0[Z]; \
258  p1 = a * v1[Y] - b * v1[Z]; \
259  if (p0 < p1) { \
260  min = p0; \
261  max = p1; \
262  } \
263  else { \
264  min = p1; \
265  max = p0; \
266  } \
267  rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \
268  if (min > rad || max < -rad) { \
269  return 0; \
270  } \
271  } \
272  (void)0
273 
274 //======================== Y-tests ========================//
275 #define AXISTEST_Y02(a, b, fa, fb) \
276  { \
277  p0 = -a * v0[X] + b * v0[Z]; \
278  p2 = -a * v2[X] + b * v2[Z]; \
279  if (p0 < p2) { \
280  min = p0; \
281  max = p2; \
282  } \
283  else { \
284  min = p2; \
285  max = p0; \
286  } \
287  rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \
288  if (min > rad || max < -rad) { \
289  return 0; \
290  } \
291  } \
292  (void)0
293 
294 #define AXISTEST_Y1(a, b, fa, fb) \
295  { \
296  p0 = -a * v0[X] + b * v0[Z]; \
297  p1 = -a * v1[X] + b * v1[Z]; \
298  if (p0 < p1) { \
299  min = p0; \
300  max = p1; \
301  } \
302  else { \
303  min = p1; \
304  max = p0; \
305  } \
306  rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \
307  if (min > rad || max < -rad) { \
308  return 0; \
309  } \
310  } \
311  (void)0
312 
313 //======================== Z-tests ========================//
314 #define AXISTEST_Z12(a, b, fa, fb) \
315  { \
316  p1 = a * v1[X] - b * v1[Y]; \
317  p2 = a * v2[X] - b * v2[Y]; \
318  if (p2 < p1) { \
319  min = p2; \
320  max = p1; \
321  } \
322  else { \
323  min = p1; \
324  max = p2; \
325  } \
326  rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \
327  if (min > rad || max < -rad) { \
328  return 0; \
329  } \
330  } \
331  (void)0
332 
333 #define AXISTEST_Z0(a, b, fa, fb) \
334  { \
335  p0 = a * v0[X] - b * v0[Y]; \
336  p1 = a * v1[X] - b * v1[Y]; \
337  if (p0 < p1) { \
338  min = p0; \
339  max = p1; \
340  } \
341  else { \
342  min = p1; \
343  max = p0; \
344  } \
345  rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \
346  if (min > rad || max < -rad) { \
347  return 0; \
348  } \
349  } \
350  (void)0
351 
352 // This internal procedure is defined below.
353 bool overlapPlaneBox(Vec3r &normal, real d, Vec3r &maxbox);
354 
355 // Use separating axis theorem to test overlap between triangle and box need to test for overlap in
356 // these directions: 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle we
357 // do not even need to test these) 2) normal of the triangle 3) crossproduct(edge from tri,
358 // {x,y,z}-directin) this gives 3x3=9 more tests
359 bool overlapTriangleBox(Vec3r &boxcenter, Vec3r &boxhalfsize, Vec3r triverts[3])
360 {
361  Vec3r v0, v1, v2, normal, e0, e1, e2;
362  real min, max, d, p0, p1, p2, rad, fex, fey, fez;
363 
364  // This is the fastest branch on Sun
365  // move everything so that the boxcenter is in (0, 0, 0)
366  v0 = triverts[0] - boxcenter;
367  v1 = triverts[1] - boxcenter;
368  v2 = triverts[2] - boxcenter;
369 
370  // compute triangle edges
371  e0 = v1 - v0;
372  e1 = v2 - v1;
373  e2 = v0 - v2;
374 
375  // Bullet 3:
376  // Do the 9 tests first (this was faster)
377  fex = fabs(e0[X]);
378  fey = fabs(e0[Y]);
379  fez = fabs(e0[Z]);
380  AXISTEST_X01(e0[Z], e0[Y], fez, fey);
381  AXISTEST_Y02(e0[Z], e0[X], fez, fex);
382  AXISTEST_Z12(e0[Y], e0[X], fey, fex);
383 
384  fex = fabs(e1[X]);
385  fey = fabs(e1[Y]);
386  fez = fabs(e1[Z]);
387  AXISTEST_X01(e1[Z], e1[Y], fez, fey);
388  AXISTEST_Y02(e1[Z], e1[X], fez, fex);
389  AXISTEST_Z0(e1[Y], e1[X], fey, fex);
390 
391  fex = fabs(e2[X]);
392  fey = fabs(e2[Y]);
393  fez = fabs(e2[Z]);
394  AXISTEST_X2(e2[Z], e2[Y], fez, fey);
395  AXISTEST_Y1(e2[Z], e2[X], fez, fex);
396  AXISTEST_Z12(e2[Y], e2[X], fey, fex);
397 
398  // Bullet 1:
399  // first test overlap in the {x,y,z}-directions
400  // find min, max of the triangle each direction, and test for overlap in that direction -- this
401  // is equivalent to testing a minimal AABB around the triangle against the AABB
402 
403  // test in X-direction
404  FINDMINMAX(v0[X], v1[X], v2[X], min, max);
405  if (min > boxhalfsize[X] || max < -boxhalfsize[X]) {
406  return false;
407  }
408 
409  // test in Y-direction
410  FINDMINMAX(v0[Y], v1[Y], v2[Y], min, max);
411  if (min > boxhalfsize[Y] || max < -boxhalfsize[Y]) {
412  return false;
413  }
414 
415  // test in Z-direction
416  FINDMINMAX(v0[Z], v1[Z], v2[Z], min, max);
417  if (min > boxhalfsize[Z] || max < -boxhalfsize[Z]) {
418  return false;
419  }
420 
421  // Bullet 2:
422  // test if the box intersects the plane of the triangle
423  // compute plane equation of triangle: normal * x + d = 0
424  normal = e0 ^ e1;
425  d = -(normal * v0); // plane eq: normal.x + d = 0
426  if (!overlapPlaneBox(normal, d, boxhalfsize)) {
427  return false;
428  }
429 
430  return true; // box and triangle overlaps
431 }
432 
433 // Fast, Minimum Storage Ray-Triangle Intersection
434 //
435 // Tomas Möller
436 // Prosolvia Clarus AB
437 // Sweden
438 // <tompa@clarus.se>
439 //
440 // Ben Trumbore
441 // Cornell University
442 // Ithaca, New York
443 // <wbt@graphics.cornell.edu>
444 bool intersectRayTriangle(const Vec3r &orig,
445  const Vec3r &dir,
446  const Vec3r &v0,
447  const Vec3r &v1,
448  const Vec3r &v2,
449  real &t,
450  real &u,
451  real &v,
452  const real epsilon)
453 {
454  Vec3r edge1, edge2, tvec, pvec, qvec;
455  real det, inv_det;
456 
457  // find vectors for two edges sharing v0
458  edge1 = v1 - v0;
459  edge2 = v2 - v0;
460 
461  // begin calculating determinant - also used to calculate U parameter
462  pvec = dir ^ edge2;
463 
464  // if determinant is near zero, ray lies in plane of triangle
465  det = edge1 * pvec;
466 
467  // calculate distance from v0 to ray origin
468  tvec = orig - v0;
469  inv_det = 1.0 / det;
470 
471  qvec = tvec ^ edge1;
472 
473  if (det > epsilon) {
474  u = tvec * pvec;
475  if (u < 0.0 || u > det) {
476  return false;
477  }
478 
479  // calculate V parameter and test bounds
480  v = dir * qvec;
481  if (v < 0.0 || u + v > det) {
482  return false;
483  }
484  }
485  else if (det < -epsilon) {
486  // calculate U parameter and test bounds
487  u = tvec * pvec;
488  if (u > 0.0 || u < det) {
489  return false;
490  }
491 
492  // calculate V parameter and test bounds
493  v = dir * qvec;
494  if (v > 0.0 || u + v < det) {
495  return false;
496  }
497  }
498  else {
499  return false; // ray is parallel to the plane of the triangle
500  }
501 
502  u *= inv_det;
503  v *= inv_det;
504  t = (edge2 * qvec) * inv_det;
505 
506  return true;
507 }
508 
509 // Intersection between plane and ray, adapted from Graphics Gems, Didier Badouel
510 // The plane is represented by a set of points P implicitly defined as dot(norm, P) + d = 0.
511 // The ray is represented as r(t) = orig + dir * t.
513  const Vec3r &dir,
514  const Vec3r &norm,
515  const real d,
516  real &t,
517  const real epsilon)
518 {
519  real denom = norm * dir;
520 
521  if (fabs(denom) <= epsilon) { // plane and ray are parallel
522  if (fabs((norm * orig) + d) <= epsilon) {
523  return COINCIDENT; // plane and ray are coincident
524  }
525 
526  return COLINEAR;
527  }
528 
529  t = -(d + (norm * orig)) / denom;
530 
531  if (t < 0.0f) {
532  return DONT_INTERSECT;
533  }
534 
535  return DO_INTERSECT;
536 }
537 
538 bool intersectRayBBox(const Vec3r &orig,
539  const Vec3r &dir, // ray origin and direction
540  const Vec3r &boxMin,
541  const Vec3r &boxMax, // the bbox
542  real t0,
543  real t1,
544  real &tmin, // I0 = orig + tmin * dir is the first intersection
545  real &tmax, // I1 = orig + tmax * dir is the second intersection
546  real /*epsilon*/)
547 {
548  float tymin, tymax, tzmin, tzmax;
549  Vec3r inv_direction(1.0 / dir[0], 1.0 / dir[1], 1.0 / dir[2]);
550  int sign[3];
551  sign[0] = (inv_direction.x() < 0);
552  sign[1] = (inv_direction.y() < 0);
553  sign[2] = (inv_direction.z() < 0);
554 
555  Vec3r bounds[2];
556  bounds[0] = boxMin;
557  bounds[1] = boxMax;
558 
559  tmin = (bounds[sign[0]].x() - orig.x()) * inv_direction.x();
560  tmax = (bounds[1 - sign[0]].x() - orig.x()) * inv_direction.x();
561  tymin = (bounds[sign[1]].y() - orig.y()) * inv_direction.y();
562  tymax = (bounds[1 - sign[1]].y() - orig.y()) * inv_direction.y();
563  if ((tmin > tymax) || (tymin > tmax)) {
564  return false;
565  }
566  if (tymin > tmin) {
567  tmin = tymin;
568  }
569  if (tymax < tmax) {
570  tmax = tymax;
571  }
572  tzmin = (bounds[sign[2]].z() - orig.z()) * inv_direction.z();
573  tzmax = (bounds[1 - sign[2]].z() - orig.z()) * inv_direction.z();
574  if ((tmin > tzmax) || (tzmin > tmax)) {
575  return false;
576  }
577  if (tzmin > tmin) {
578  tmin = tzmin;
579  }
580  if (tzmax < tmax) {
581  tmax = tzmax;
582  }
583  return ((tmin < t1) && (tmax > t0));
584 }
585 
586 // Checks whether 3D points p lies inside or outside of the triangle ABC
587 bool includePointTriangle(const Vec3r &P, const Vec3r &A, const Vec3r &B, const Vec3r &C)
588 {
589  Vec3r AB(B - A);
590  Vec3r BC(C - B);
591  Vec3r CA(A - C);
592  Vec3r AP(P - A);
593  Vec3r BP(P - B);
594  Vec3r CP(P - C);
595 
596  Vec3r N(AB ^ BC); // triangle's normal
597 
598  N.normalize();
599 
600  Vec3r J(AB ^ AP), K(BC ^ BP), L(CA ^ CP);
601  J.normalize();
602  K.normalize();
603  L.normalize();
604 
605  if (J * N < 0) {
606  return false; // on the right of AB
607  }
608 
609  if (K * N < 0) {
610  return false; // on the right of BC
611  }
612 
613  if (L * N < 0) {
614  return false; // on the right of CA
615  }
616 
617  return true;
618 }
619 
620 void transformVertex(const Vec3r &vert, const Matrix44r &matrix, Vec3r &res)
621 {
622  HVec3r hvert(vert), res_tmp;
623  real scale;
624  for (unsigned int j = 0; j < 4; j++) {
625  scale = hvert[j];
626  for (unsigned int i = 0; i < 4; i++) {
627  res_tmp[i] += matrix(i, j) * scale;
628  }
629  }
630 
631  res[0] = res_tmp.x();
632  res[1] = res_tmp.y();
633  res[2] = res_tmp.z();
634 }
635 
636 void transformVertices(const vector<Vec3r> &vertices, const Matrix44r &trans, vector<Vec3r> &res)
637 {
638  size_t i;
639  res.resize(vertices.size());
640  for (i = 0; i < vertices.size(); i++) {
641  transformVertex(vertices[i], trans, res[i]);
642  }
643 }
644 
645 Vec3r rotateVector(const Matrix44r &mat, const Vec3r &v)
646 {
647  Vec3r res;
648  for (unsigned int i = 0; i < 3; i++) {
649  res[i] = 0;
650  for (unsigned int j = 0; j < 3; j++) {
651  res[i] += mat(i, j) * v[j];
652  }
653  }
654  res.normalize();
655  return res;
656 }
657 
658 // This internal procedure is defined below.
659 void fromCoordAToCoordB(const Vec3r &p, Vec3r &q, const real transform[4][4]);
660 
661 void fromWorldToCamera(const Vec3r &p, Vec3r &q, const real model_view_matrix[4][4])
662 {
663  fromCoordAToCoordB(p, q, model_view_matrix);
664 }
665 
666 void fromCameraToRetina(const Vec3r &p, Vec3r &q, const real projection_matrix[4][4])
667 {
668  fromCoordAToCoordB(p, q, projection_matrix);
669 }
670 
671 void fromRetinaToImage(const Vec3r &p, Vec3r &q, const int viewport[4])
672 {
673  // winX:
674  q[0] = viewport[0] + viewport[2] * (p[0] + 1.0) / 2.0;
675 
676  // winY:
677  q[1] = viewport[1] + viewport[3] * (p[1] + 1.0) / 2.0;
678 
679  // winZ:
680  q[2] = (p[2] + 1.0) / 2.0;
681 }
682 
683 void fromWorldToImage(const Vec3r &p,
684  Vec3r &q,
685  const real model_view_matrix[4][4],
686  const real projection_matrix[4][4],
687  const int viewport[4])
688 {
689  Vec3r p1, p2;
690  fromWorldToCamera(p, p1, model_view_matrix);
691  fromCameraToRetina(p1, p2, projection_matrix);
692  fromRetinaToImage(p2, q, viewport);
693  q[2] = p1[2];
694 }
695 
696 void fromWorldToImage(const Vec3r &p, Vec3r &q, const real transform[4][4], const int viewport[4])
697 {
699 
700  // winX:
701  q[0] = viewport[0] + viewport[2] * (q[0] + 1.0) / 2.0;
702 
703  // winY:
704  q[1] = viewport[1] + viewport[3] * (q[1] + 1.0) / 2.0;
705 }
706 
707 void fromImageToRetina(const Vec3r &p, Vec3r &q, const int viewport[4])
708 {
709  q = p;
710  q[0] = 2.0 * (q[0] - viewport[0]) / viewport[2] - 1.0;
711  q[1] = 2.0 * (q[1] - viewport[1]) / viewport[3] - 1.0;
712 }
713 
714 void fromRetinaToCamera(const Vec3r &p, Vec3r &q, real focal, const real projection_matrix[4][4])
715 {
716  if (projection_matrix[3][3] == 0.0) { // perspective
717  q[0] = (-p[0] * focal) / projection_matrix[0][0];
718  q[1] = (-p[1] * focal) / projection_matrix[1][1];
719  q[2] = focal;
720  }
721  else { // orthogonal
722  q[0] = p[0] / projection_matrix[0][0];
723  q[1] = p[1] / projection_matrix[1][1];
724  q[2] = focal;
725  }
726 }
727 
728 void fromCameraToWorld(const Vec3r &p, Vec3r &q, const real model_view_matrix[4][4])
729 {
730  real translation[3] = {
731  model_view_matrix[0][3],
732  model_view_matrix[1][3],
733  model_view_matrix[2][3],
734  };
735  for (unsigned short i = 0; i < 3; i++) {
736  q[i] = 0.0;
737  for (unsigned short j = 0; j < 3; j++) {
738  q[i] += model_view_matrix[j][i] * (p[j] - translation[j]);
739  }
740  }
741 }
742 
743 //
744 // Internal code
745 //
747 
748 // Copyright 2001, softSurfer (www.softsurfer.com)
749 // This code may be freely used and modified for any purpose providing that this copyright notice
750 // is included with it. SoftSurfer makes no warranty for this code, and cannot be held liable for
751 // any real or imagined damage resulting from its use. Users of this code must verify correctness
752 // for their application.
753 
754 #define PERP(u, v) ((u)[0] * (v)[1] - (u)[1] * (v)[0]) // 2D perp product
755 
756 inline bool intersect2dSegPoly(Vec2r *seg, Vec2r *poly, unsigned n)
757 {
758  if (seg[0] == seg[1]) {
759  return false;
760  }
761 
762  real tE = 0; // the maximum entering segment parameter
763  real tL = 1; // the minimum leaving segment parameter
764  real t, N, D; // intersect parameter t = N / D
765  Vec2r dseg = seg[1] - seg[0]; // the segment direction vector
766  Vec2r e; // edge vector
767 
768  for (unsigned int i = 0; i < n; i++) { // process polygon edge poly[i]poly[i+1]
769  e = poly[i + 1] - poly[i];
770  N = PERP(e, seg[0] - poly[i]);
771  D = -PERP(e, dseg);
772  if (fabs(D) < M_EPSILON) {
773  if (N < 0) {
774  return false;
775  }
776 
777  continue;
778  }
779 
780  t = N / D;
781  if (D < 0) { // segment seg is entering across this edge
782  if (t > tE) { // new max tE
783  tE = t;
784  if (tE > tL) { // seg enters after leaving polygon
785  return false;
786  }
787  }
788  }
789  else { // segment seg is leaving across this edge
790  if (t < tL) { // new min tL
791  tL = t;
792  if (tL < tE) { // seg leaves before entering polygon
793  return false;
794  }
795  }
796  }
797  }
798 
799  // tE <= tL implies that there is a valid intersection subsegment
800  return true;
801 }
802 
803 inline bool overlapPlaneBox(Vec3r &normal, real d, Vec3r &maxbox)
804 {
805  Vec3r vmin, vmax;
806 
807  for (unsigned int q = X; q <= Z; q++) {
808  if (normal[q] > 0.0f) {
809  vmin[q] = -maxbox[q];
810  vmax[q] = maxbox[q];
811  }
812  else {
813  vmin[q] = maxbox[q];
814  vmax[q] = -maxbox[q];
815  }
816  }
817  if ((normal * vmin) + d > 0.0f) {
818  return false;
819  }
820  if ((normal * vmax) + d >= 0.0f) {
821  return true;
822  }
823  return false;
824 }
825 
826 inline void fromCoordAToCoordB(const Vec3r &p, Vec3r &q, const real transform[4][4])
827 {
828  HVec3r hp(p);
829  HVec3r hq(0, 0, 0, 0);
830 
831  for (unsigned int i = 0; i < 4; i++) {
832  for (unsigned int j = 0; j < 4; j++) {
833  hq[i] += transform[i][j] * hp[j];
834  }
835  }
836 
837  if (hq[3] == 0) {
838  q = p;
839  return;
840  }
841 
842  for (unsigned int k = 0; k < 3; k++) {
843  q[k] = hq[k] / hq[3];
844  }
845 }
846 
847 } // namespace Freestyle::GeomUtils
#define D
#define K(key)
_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
#define X
Definition: GeomUtils.cpp:213
#define AXISTEST_Y02(a, b, fa, fb)
Definition: GeomUtils.cpp:275
#define FINDMINMAX(x0, x1, x2, min, max)
Definition: GeomUtils.cpp:217
#define AXISTEST_Z12(a, b, fa, fb)
Definition: GeomUtils.cpp:314
#define Z
Definition: GeomUtils.cpp:215
#define AXISTEST_Y1(a, b, fa, fb)
Definition: GeomUtils.cpp:294
#define Y
Definition: GeomUtils.cpp:214
#define AXISTEST_X2(a, b, fa, fb)
Definition: GeomUtils.cpp:255
#define AXISTEST_X01(a, b, fa, fb)
Definition: GeomUtils.cpp:236
#define PERP(u, v)
Definition: GeomUtils.cpp:754
#define AXISTEST_Z0(a, b, fa, fb)
Definition: GeomUtils.cpp:333
Various tools for geometry.
#define C
Definition: RandGen.cpp:39
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define A
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition: btDbvt.cpp:299
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
Definition: btVector3.h:263
value_type z() const
Definition: VecMat.h:487
value_type x() const
Definition: VecMat.h:477
value_type y() const
Definition: VecMat.h:482
value_type x() const
Definition: VecMat.h:532
value_type z() const
Definition: VecMat.h:552
value_type y() const
Definition: VecMat.h:542
Vec< T, N > & normalize()
Definition: VecMat.h:119
IconTextureDrawCall normal
static float P(float k)
Definition: math_interp.c:41
#define B
#define L
void fromRetinaToImage(const Vec3r &p, Vec3r &q, const int viewport[4])
Definition: GeomUtils.cpp:671
void fromWorldToImage(const Vec3r &p, Vec3r &q, const real model_view_matrix[4][4], const real projection_matrix[4][4], const int viewport[4])
Definition: GeomUtils.cpp:683
void transformVertex(const Vec3r &vert, const Matrix44r &matrix, Vec3r &res)
Definition: GeomUtils.cpp:620
void fromWorldToCamera(const Vec3r &p, Vec3r &q, const real model_view_matrix[4][4])
Definition: GeomUtils.cpp:661
intersection_test intersect2dSeg2dSegParametric(const Vec2r &p1, const Vec2r &p2, const Vec2r &p3, const Vec2r &p4, real &t, real &u, real epsilon)
Definition: GeomUtils.cpp:142
bool intersect2dSeg2dArea(const Vec2r &min, const Vec2r &max, const Vec2r &A, const Vec2r &B)
Definition: GeomUtils.cpp:29
intersection_test intersect2dSeg2dSeg(const Vec2r &p1, const Vec2r &p2, const Vec2r &p3, const Vec2r &p4, Vec2r &res)
Definition: GeomUtils.cpp:59
bool intersect2dSegPoly(Vec2r *seg, Vec2r *poly, unsigned n)
Definition: GeomUtils.cpp:756
bool overlapTriangleBox(Vec3r &boxcenter, Vec3r &boxhalfsize, Vec3r triverts[3])
Definition: GeomUtils.cpp:359
bool overlapPlaneBox(Vec3r &normal, real d, Vec3r &maxbox)
Definition: GeomUtils.cpp:803
void fromCoordAToCoordB(const Vec3r &p, Vec3r &q, const real transform[4][4])
Definition: GeomUtils.cpp:826
void fromCameraToWorld(const Vec3r &p, Vec3r &q, const real model_view_matrix[4][4])
Definition: GeomUtils.cpp:728
bool intersectRayTriangle(const Vec3r &orig, const Vec3r &dir, const Vec3r &v0, const Vec3r &v1, const Vec3r &v2, real &t, real &u, real &v, const real epsilon)
Definition: GeomUtils.cpp:444
bool includePointTriangle(const Vec3r &P, const Vec3r &A, const Vec3r &B, const Vec3r &C)
Definition: GeomUtils.cpp:587
void fromCameraToRetina(const Vec3r &p, Vec3r &q, const real projection_matrix[4][4])
Definition: GeomUtils.cpp:666
void transformVertices(const vector< Vec3r > &vertices, const Matrix44r &trans, vector< Vec3r > &res)
Definition: GeomUtils.cpp:636
bool intersectRayBBox(const Vec3r &orig, const Vec3r &dir, const Vec3r &boxMin, const Vec3r &boxMax, real t0, real t1, real &tmin, real &tmax, real)
Definition: GeomUtils.cpp:538
bool include2dSeg2dArea(const Vec2r &min, const Vec2r &max, const Vec2r &A, const Vec2r &B)
Definition: GeomUtils.cpp:50
intersection_test intersectRayPlane(const Vec3r &orig, const Vec3r &dir, const Vec3r &norm, const real d, real &t, const real epsilon)
Definition: GeomUtils.cpp:512
void fromRetinaToCamera(const Vec3r &p, Vec3r &q, real focal, const real projection_matrix[4][4])
Definition: GeomUtils.cpp:714
void fromImageToRetina(const Vec3r &p, Vec3r &q, const int viewport[4])
Definition: GeomUtils.cpp:707
intersection_test intersect2dLine2dLine(const Vec2r &p1, const Vec2r &p2, const Vec2r &p3, const Vec2r &p4, Vec2r &res)
Definition: GeomUtils.cpp:111
Vec3r rotateVector(const Matrix44r &mat, const Vec3r &v)
Definition: GeomUtils.cpp:645
VecMat::Vec3< real > Vec3r
Definition: Geom.h:42
static const real M_EPSILON
Definition: Precision.h:29
double real
Definition: Precision.h:26
double sign(double arg)
Definition: utility.h:250
static double epsilon
params N
#define min(a, b)
Definition: sort.c:51
float max
ccl_device_inline float2 fabs(const float2 &a)