@@ -955,14 +955,6 @@ static mjtNum mj_raySdfNormal(const mjModel* m, const mjData* d, int g,
955955 return -1 ;
956956}
957957
958-
959- // intersect ray with signed distance field
960- static mjtNum ray_sdf (const mjModel * m , const mjData * d , int g ,
961- const mjtNum pnt [3 ], const mjtNum vec [3 ]) {
962- return mj_raySdfNormal (m , d , g , pnt , vec , NULL );
963- }
964-
965-
966958// intersect ray with mesh, compute normal if given
967959static mjtNum mj_rayMeshNormal (const mjModel * m , const mjData * d , int id , const mjtNum pnt [3 ],
968960 const mjtNum vec [3 ], mjtNum normal [3 ]) {
@@ -1488,14 +1480,18 @@ void mju_multiRayPrepare(const mjModel* m, const mjData* d, const mjtNum pnt[3],
14881480}
14891481
14901482
1491- // Performs single ray intersection
1483+ // Performs single ray intersection, compute normal if given
14921484static mjtNum mju_singleRay (const mjModel * m , mjData * d , const mjtNum pnt [3 ], const mjtNum vec [3 ],
1493- int * ray_eliminate , mjtNum * geom_ba , int geomid [1 ]) {
1485+ int * ray_eliminate , mjtNum * geom_ba , int geomid [1 ],
1486+ mjtNum normal [3 ]) {
14941487 mjtNum dist , newdist ;
1488+ mjtNum normal_local [3 ];
1489+ mjtNum * p_normal = normal ? normal_local : NULL ;
14951490
14961491 // clear result
14971492 dist = -1 ;
14981493 * geomid = -1 ;
1494+ if (normal ) mju_zero3 (normal );
14991495
15001496 // get ray spherical coordinates
15011497 mjtNum azimuth = longitude (vec );
@@ -1530,25 +1526,24 @@ static mjtNum mju_singleRay(const mjModel* m, mjData* d, const mjtNum pnt[3], co
15301526 }
15311527 }
15321528
1533- // handle mesh and hfield separately
1534- if (m -> geom_type [i ] == mjGEOM_MESH ) {
1535- newdist = mj_rayMesh (m , d , i , pnt , vec );
1536- } else if (m -> geom_type [i ] == mjGEOM_HFIELD ) {
1537- newdist = mj_rayHfield (m , d , i , pnt , vec );
1538- } else if (m -> geom_type [i ] == mjGEOM_SDF ) {
1539- newdist = ray_sdf (m , d , i , pnt , vec );
1540- }
1541-
1542- // otherwise general dispatch
1543- else {
1544- newdist = mju_rayGeom (d -> geom_xpos + 3 * i , d -> geom_xmat + 9 * i ,
1545- m -> geom_size + 3 * i , pnt , vec , m -> geom_type [i ]);
1529+ // dispatch to type-specific ray function
1530+ int type = m -> geom_type [i ];
1531+ if (type == mjGEOM_MESH ) {
1532+ newdist = mj_rayMeshNormal (m , d , i , pnt , vec , p_normal );
1533+ } else if (type == mjGEOM_HFIELD ) {
1534+ newdist = mj_rayHfieldNormal (m , d , i , pnt , vec , p_normal );
1535+ } else if (type == mjGEOM_SDF ) {
1536+ newdist = mj_raySdfNormal (m , d , i , pnt , vec , p_normal );
1537+ } else {
1538+ newdist = mju_rayGeomNormal (d -> geom_xpos + 3 * i , d -> geom_xmat + 9 * i ,
1539+ m -> geom_size + 3 * i , pnt , vec , type , p_normal );
15461540 }
15471541
15481542 // update if closer intersection found
15491543 if (newdist >= 0 && (newdist < dist || dist < 0 )) {
15501544 dist = newdist ;
15511545 * geomid = i ;
1546+ if (normal ) mju_copy3 (normal , normal_local );
15521547 }
15531548 }
15541549 }
@@ -1557,10 +1552,10 @@ static mjtNum mju_singleRay(const mjModel* m, mjData* d, const mjtNum pnt[3], co
15571552}
15581553
15591554
1560- // performs multiple ray intersections with the precomputed bv and flags
1561- void mj_multiRay (const mjModel * m , mjData * d , const mjtNum pnt [3 ], const mjtNum * vec ,
1562- const mjtByte * geomgroup , mjtByte flg_static , int bodyexclude ,
1563- int * geomid , mjtNum * dist , int nray , mjtNum cutoff ) {
1555+ // performs multiple ray intersections, compute normals if given
1556+ void mj_multiRayNormal (const mjModel * m , mjData * d , const mjtNum pnt [3 ], const mjtNum * vec ,
1557+ const mjtByte * geomgroup , mjtByte flg_static , int bodyexclude ,
1558+ int * geomid , mjtNum * dist , mjtNum * normal , int nray , mjtNum cutoff ) {
15641559 mj_markStack (d );
15651560
15661561 // allocate source
@@ -1576,9 +1571,20 @@ void mj_multiRay(const mjModel* m, mjData* d, const mjtNum pnt[3], const mjtNum*
15761571 if (mju_dot3 (vec + 3 * i , vec + 3 * i ) < mjMINVAL ) {
15771572 dist [i ] = -1 ;
15781573 } else {
1579- dist [i ] = mju_singleRay (m , d , pnt , vec + 3 * i , geom_eliminate , geom_ba , geomid + i );
1574+ dist [i ] = mju_singleRay (m , d , pnt , vec + 3 * i , geom_eliminate , geom_ba , geomid + i ,
1575+ normal ? normal + 3 * i : NULL );
15801576 }
15811577 }
15821578
15831579 mj_freeStack (d );
15841580}
1581+
1582+
1583+ // performs multiple ray intersections with the precomputed bv and flags
1584+ void mj_multiRay (const mjModel * m , mjData * d , const mjtNum pnt [3 ], const mjtNum vec [3 ],
1585+ const mjtByte * geomgroup , mjtByte flg_static , int bodyexclude ,
1586+ int * geomid , mjtNum * dist , int nray , mjtNum cutoff ) {
1587+ mj_multiRayNormal (m , d , pnt , vec , geomgroup , flg_static , bodyexclude ,
1588+ geomid , dist , NULL , nray , cutoff );
1589+ }
1590+
0 commit comments