[Plib-users] ssgIsect question
Brought to you by:
sjbaker
From: McEvoy, N. <nic...@ds...> - 2002-01-23 05:50:20
|
What's up with ssgIsect (ie. how does it work) ??? YES, I have read the PLIB documentation. I want to find the distance between my player's center and the plane I hit. I use a sphere radius 10 at 0,0,0 as per the code below. When my player is at (0,0,9.68326) and the ground (or plane) is on the X-Y plane with normal (0,0,1) I use ssgIsect to return info about the ground below me that I wish to 'rest' on, ssgHit has plane (0.00,0.00,1.00,9.68326). Why is plane[3] = 9.68326 ? According to the equation of a plane D would be zero in my case cause my plane is X-Y (ie. all point on plane have z=0) (ref: http://astronomy.swin.edu.au/pbourke/geometry/planeeq/) Ax = By + Cz + D = 0 A = y1 (z2 - z3) + y2 (z3 - z1) + y3 (z1 - z2) B = z1 (x2 - x3) + z2 (x3 - x1) + z3 (x1 - x2) C = x1 (y2 - y3) + x2 (y3 - y1) + x3 (y1 - y2) - D = x1 (y2 z3 - y3 z2) + x2 (y3 z1 - y1 z3) + x3 (y1 z2 - y2 z1) Say O is my player (& sphere with radius 10 for isect test). +Z +Y | / | / O/ .------+X Now I hope I don't confuse the issue (by bringing ODE into the equation) ... but ... The problem is that when I pass the plane to a physics engine (ODE) it works out the depth of penetration by: #define dDOT(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2]) dReal k = dDOT(pos,plane); dReal depth = -plane[3] - k + sphere->radius; ie. depth = -9.68326 -9.68326 + 10 = -9.36652 The incorrect depth result causes my sphere to 'bounce' due to the large depth in penetration. Note I get same depth calculation result with PLIB: float dist = sgDistToPlaneVec3(h->plane, player_pos); float depth = sphere.getRadius() - dist; Is it something to do with the invmat[3][2] or setting the sphere at 0,0,0 ??? Do I need to raise the sphere or invmat[3][2] ? I'm quite not sure how PLIB works backwards to get the ssgHit. Believe me I have traced the code !!! Any ideas ??? -------------------------------------------------- sgMat4 invmat; sgMakeIdentMat4(invmat); sgSphere sphere; invmat[3][0] = -player_pos[SG_X]; invmat[3][1] = -player_pos[SG_Y]; invmat[3][2] = -player_pos[SG_Z]; { ... sphere.setCenter(0.0, 0.0, 0.0); sphere.setRadius(10.0); ssgHit *results ; int num_hits = ssgIsect(&mWorld, &sphere, invmat, &results); for (int i = 0; i < num_hits; i++) { ssgHit *h = &results[i]; printf("pos <%.1f:%.1f:%.1f> plane <%.1f:%.1f:%.1f:%.1f>\n", player_pos[0], player_pos[1], player_pos[2], h->plane[0], h->plane[1], h->plane[2], h->plane[3]); } ... } -------------------------------------------------- pos <0.00:0.00:9.68326> plane <0.00:0.00:1.00:9.68326> ...etc -------------------------------------------------- Nick http://members.ozemail.com.au/~ndmcevoy/ |