@@ -597,35 +597,59 @@ void mjCOctree::CreateOctree(const double aamm[6]) {
597
597
}
598
598
599
599
600
- static bool boxTriangle (const Triangle& element, const double aamm[6 ]) {
600
+ static double dot2 (const double * a, const double * b) {
601
+ return a[0 ] * b[0 ] + a[1 ] * b[1 ];
602
+ }
603
+
604
+
605
+ // From M. Schwarz and H.-P. Seidel, "Fast Parallel Surface and Solid Voxelization on GPUs".
606
+ static bool boxTriangle (const Triangle& v, const double aamm[6 ]) {
601
607
// bounding box tests
602
608
for (int i = 0 ; i < 3 ; i++) {
603
- if (element [0 ][i] < aamm[i] && element [1 ][i] < aamm[i] && element [2 ][i] < aamm[i]) {
609
+ if (v [0 ][i] < aamm[i] && v [1 ][i] < aamm[i] && v [2 ][i] < aamm[i]) {
604
610
return false ;
605
611
}
606
612
int j = i + 3 ;
607
- if (element [0 ][i] > aamm[j] && element [1 ][i] > aamm[j] && element [2 ][i] > aamm[j]) {
613
+ if (v [0 ][i] > aamm[j] && v [1 ][i] > aamm[j] && v [2 ][i] > aamm[j]) {
608
614
return false ;
609
615
}
610
616
}
611
617
612
618
// test for triangle plane and box overlap
613
619
double n[3 ];
614
- double v0[3 ] = {element[0 ][0 ], element[0 ][1 ], element[0 ][2 ]};
615
- double e1 [3 ] = {element[1 ][0 ] - v0[0 ], element[1 ][1 ] - v0[1 ], element[1 ][2 ] - v0[2 ]};
616
- double e2 [3 ] = {element[2 ][0 ] - v0[0 ], element[2 ][1 ] - v0[1 ], element[2 ][2 ] - v0[2 ]};
620
+ double e[3 ][3 ];
621
+ for (int i = 0 ; i < 3 ; i++) {
622
+ for (int j = 0 ; j < 3 ; j++) {
623
+ e[i][j] = v[(i+1 )%3 ][j] - v[i][j];
624
+ }
625
+ }
617
626
618
- mjuu_crossvec (n, e1 , e2 );
627
+ mjuu_crossvec (n, e[ 0 ], e[ 1 ] );
619
628
double size[3 ] = {aamm[3 ] - aamm[0 ], aamm[4 ] - aamm[1 ], aamm[5 ] - aamm[2 ]};
620
629
double c[3 ] = {n[0 ] > 0 ? size[0 ] : 0 , n[1 ] > 0 ? size[1 ] : 0 , n[2 ] > 0 ? size[2 ] : 0 };
621
- double c1[3 ] = {c[0 ] - v0 [0 ], c[1 ] - v0[ 1 ], c[2 ] - v0 [2 ]};
622
- double c2[3 ] = {size[0 ] - c[0 ] - v0 [0 ], size[1 ] - c[1 ] - v0[ 1 ], size[2 ] - c[2 ] - v0 [2 ]};
630
+ double c1[3 ] = {c[0 ] - v [0 ][ 0 ] , c[1 ] - v[ 0 ][ 1 ], c[2 ] - v[ 0 ] [2 ]};
631
+ double c2[3 ] = {size[0 ] - c[0 ] - v [0 ][ 0 ] , size[1 ] - c[1 ] - v[ 0 ][ 1 ], size[2 ] - c[2 ] - v[ 0 ] [2 ]};
623
632
624
633
if ((mjuu_dot3 (n, aamm) + mjuu_dot3 (n, c1)) * (mjuu_dot3 (n, aamm) + mjuu_dot3 (n, c2)) > 0 ) {
625
634
return false ;
626
635
}
627
636
628
- // TODO: add additionally separating axis tests
637
+ // test projection overlap
638
+ for (int a = 0 ; a < 3 ; a++) {
639
+ int b = (a + 1 ) % 3 ;
640
+ int c = (a + 2 ) % 3 ;
641
+ for (int i = 0 ; i < 3 ; i++) {
642
+ double sign = n[a] >= 0 ? 1 : -1 ;
643
+ double ne[2 ] = {-e[i][c] * sign, -e[i][b] * sign};
644
+ double vi[2 ] = {v[i][b], v[i][c]};
645
+ double d = -dot2 (ne, vi) + mju_max (0 , size[b]*ne[0 ]) + mju_max (0 , size[c]*ne[1 ]);
646
+ double p[2 ] = {aamm[b], aamm[c]};
647
+ if (dot2 (ne, p) + d < 0 ) {
648
+ return false ;
649
+ }
650
+ }
651
+ }
652
+
629
653
return true ;
630
654
}
631
655
0 commit comments