@@ -903,6 +903,26 @@ static void rotmat(mjtNum R[9], const mjtNum axis[3]) {
903903
904904
905905
906+ // return nonzero if the ray v1v2 intersects the triangle v3v4v5
907+ static inline int rayTriangle (const mjtNum v1 [3 ], const mjtNum v2 [3 ], const mjtNum v3 [3 ],
908+ const mjtNum v4 [3 ], const mjtNum v5 [3 ]) {
909+ mjtNum diff12 [3 ], diff13 [3 ], diff14 [3 ], diff15 [3 ];
910+ sub3 (diff12 , v2 , v1 );
911+ sub3 (diff13 , v3 , v1 );
912+ sub3 (diff14 , v4 , v1 );
913+ sub3 (diff15 , v5 , v1 );
914+
915+ mjtNum vol1 = det3 (diff13 , diff14 , diff12 );
916+ mjtNum vol2 = det3 (diff14 , diff15 , diff12 );
917+ mjtNum vol3 = det3 (diff15 , diff13 , diff12 );
918+
919+ if (vol1 >= 0 && vol2 >= 0 && vol3 >= 0 ) return 1 ;
920+ if (vol1 <= 0 && vol2 <= 0 && vol3 <= 0 ) return -1 ;
921+ return 0 ;
922+ }
923+
924+
925+
906926// create a polytope from a 1-simplex (returns 0 on success)
907927static int polytope2 (Polytope * pt , mjCCDStatus * status , mjCCDObj * obj1 , mjCCDObj * obj2 ) {
908928 mjtNum * v1 = status -> simplex [0 ].vert , * v2 = status -> simplex [1 ].vert ;
@@ -970,9 +990,9 @@ static int polytope2(Polytope* pt, mjCCDStatus* status, mjCCDObj* obj1, mjCCDObj
970990 return polytope3 (pt , status , obj1 , obj2 );
971991 }
972992
973- // check that origin is in the hexahedron
974- if (status -> dist > 10 * mjMINVAL && ! testTetra (v1 , v3 , v4 , v5 ) && ! testTetra ( v2 , v3 , v4 , v5 )) {
975- return mjEPA_P2_MISSING_ORIGIN ;
993+ // check hexahedron is convex
994+ if (! rayTriangle (v1 , v2 , v3 , v4 , v5 )) {
995+ return mjEPA_P2_NONCONVEX ;
976996 }
977997
978998 for (int i = 0 ; i < 6 ; i ++ ) {
0 commit comments