X_GETCOLLISIONFACE bug?

Previous topic - Next topic

FutureCow

I've simplified part of my code to make the problem easy to see. As you can see here I'm creating a triangle strip of 6 triangles. When I run this code
Code (glbasic) Select
counter=0
GridCollisionObj=GENX_OBJ()
X_OBJSTART GridCollisionObj
FOR X=0 TO 3
X_OBJADDVERTEX   X,   0, Z+1, 0, 0, RGB(0,0,255) // Create quad
X_OBJADDVERTEX   X,   0, Z  , 0, 1, RGB(0,0,255)
counter=counter+1
NEXT
DEBUG "Counter = " + counter + "\n"
DEBUG "Num Faces = " + X_NUMFACES(GridCollisionObj) + " "



  • Counter = 4 -so i know the loop rang the correct number of times
  • X_NUMFACES(GridCollisionObj) = 6 - which is correct
BUT, if I use X_GETCOLLISIONFACE to work out which which triangle in the strip my mouse is over, i.e.
Code (glbasic) Select
X_SCREEN2WORLD MX, MY,  0, x, y, z
X_SCREEN2WORLD MX, MY, -1, x2,y2,z2
IF X_COLLISIONRAY(GridCollisionObj, 0, x, y, z, x2-x, y2-y, z2-z)<>0
MouseCollisionFace=X_GETCOLLISIONFACE()
DEBUG "Face = " + MouseCollisionFace + " "
ENDIF

then in the debug output I can get a result of 0,3,6,9,12 or 15 from X_GETCOLLISIONFACE, not 0,1,2,3,4 or 5.

According to the documentation "X_GETCOLLISIONFACE returns the index of the surface that triggered a collision in the last X_COLLISION... query".
From what I can see it's not returning the index of the surface, it's returning the index of the last vertex for the surface. The manual says to pass the result from X_GETCOLLISIONFACE to X_GETFACE to find out details about it. If you look at the X_GETFACE manual page, you pass it an object, the frame number, and index where - "index# is the index of the triangle in the model and must be within the range 0 and X_NUMFACES(obj#)-1." This also suggests to me that X_GETCOLLISIONFACE is broken as you should be passing a triangle number to X_GETFACE, not the vertex number from the triangle.

If I'm reading the manual correctly and it is a bug then yes I know I could divide the result by 3, but that's not the point.  ;)

Kitty Hello

Code (glbasic) Select

// --------------------------------- //
// Project: X_Collision
// Start: Thursday, December 10, 2009
// IDE Version: 7.198

SYSTEMPOINTER TRUE
AUTOPAUSE FALSE

LOCAL mx, my, b1, b2
CreateSphere(111, 5, 15, 0xffffff)

WHILE TRUE

MOUSESTATE mx, my, b1, b2
X_MAKE3D 1, 100, 45
X_CAMERA 1,1,25, 1,2,.5 // Use odd numbers to show it's not just working with 0,0,0, 1,0,0 or so...

// X_MOVEMENT 1,2,0.5 // offset just to be safe it's really working
X_CULLMODE 1
X_DRAWOBJ 111, 0

// Make a 3D ray under the mouse pointer
IF PickTriangle(111,0, mx, my)
LOCAL iPick% = X_GETCOLLISIONFACE() / 3 // /3 - GLBasic Bug in Version <= 7.198
LOCAL face[]
X_GETFACE 111, 0, iPick, face[]

// face[node 0..2][x,y,z,tx,ty,col]
X_LINE face[0][0], face[0][1], face[0][2], face[1][0], face[1][1], face[1][2], 4, RGB(0,0,255)
X_LINE face[2][0], face[2][1], face[2][2], face[1][0], face[1][1], face[1][2], 4, RGB(0,0,255)
X_LINE face[0][0], face[0][1], face[0][2], face[2][0], face[2][1], face[2][2], 4, RGB(0,0,255)
ENDIF
SHOWSCREEN
WEND


FUNCTION PickTriangle%: iObj, iFrame, mx, my
LOCAL x1,y1,z1, x2,y2,z2
X_SCREEN2WORLD mx, my, -1000, x1,y1,z1
X_SCREEN2WORLD mx, my,  1000, x2,y2,z2
IF X_COLLISIONRAY(iObj, iFrame, x1,y1,z1, x2-x1, y2-y1, z2-z1) <> 0.0 THEN RETURN TRUE
RETURN FALSE
ENDFUNCTION




// ------------------------------------------------------------- //
// -=#  SPHERE  #=-
// ------------------------------------------------------------- //
FUNCTION CreateSphere: num, r, n, col
LOCAL i,j, theta1, theta2, theta3, pi
pi = ACOS(0)*2
IF r < 0 THEN r = -r
IF n < 4 THEN n = 4

X_AUTONORMALS 2 // smooth edges
X_OBJSTART num
FOR j=0 TO INTEGER(n/2) -1
theta1 = j * 2*pi / n - pi/2;
theta2 = (j + 1) * 2*pi / n - pi/2;
FOR i=0 TO n
theta3 = i * 2*pi / n;
X_OBJADDVERTEX r*COS(theta2) * COS(theta3), r*SIN(theta2), _
r*COS(theta2) * SIN(theta3), i/n, 2*(j+1)/n, col
X_OBJADDVERTEX r*COS(theta1) * COS(theta3), r*SIN(theta1), _
r*COS(theta1) * SIN(theta3), i/n, 2*j/n, col
NEXT
X_OBJNEWGROUP
NEXT
X_OBJEND
ENDFUNCTION // n


There was a bug. You have to divide the return value of X_GETCOLLISIONFACE() by 3. Sorry. Update soon.

FutureCow

Thanks for the quick reply as always Gernot!!!  :booze:
I'm not worried about it, I'm just happy that it shows I'm beginning to know what's going on with this 3D stuff!

Hemlos

Just remember this about 3d....each time you call a 3d command, it is using a stack of information from the last time around...and is reset by a new x_movement.
This is something i find a common error, on my behalf, more often than not.
Bing ChatGpt is pretty smart :O

Kitty Hello

there's X_PUSHMATRIX to keep the transformations of parent objects.