Game Development Community

ContainerRayCast returns at bounding box, not collision mesh

by James Terry · in Torque Game Engine · 12/05/2006 (11:18 am) · 5 replies

I have a bunch of static shapes in my game all being rotated about a central point. I am using the object selection resource and it uses containerRayCast to find out which object I am clicking on.

It works perfectly fine if everything is in its initial positions. As I rotate my stuff around, the bounding boxes start stretching and growing and all of the rayCasts are returning when they hit that bounding box, not the collision mesh itself.

Is there an easy way or a toggle to switch the raycast functionality between the collision meshes on the shapes? I know the collision meshes are working for actual collision detection (my player can get on top of the objects based on their meshes and not their bounding boxes)

Thanks for any help,

James

#1
12/05/2006 (12:13 pm)
For ray casts, the world box is always used.

In Container::castRay :
if (ptr->getWorldBox().collideLine(start, end) || chain->object->isGlobalBounds())

Where ptr is the object in question.

The world box does "grow" and "shrink" IIRC when you rotate the object because it's the minimum sized box that will fix the local object's box in world space. If you rotate a selected object in the editor, the outer box is the world box.

The player represents its collision as a box, not as a mesh. It's up to the objects the player collides with (such as the objects your scene) on how they represent themselves - in your case a collision mesh specified in the .dts .

To get a rayCast that checks against the objects meshes requires some engine coding AFAIK. But it is entirely possible.

- Eric
#2
12/05/2006 (12:16 pm)
Hmm, might you know of any resources or directions to look to build a raycast function with that functionality?

Thanks
#3
12/05/2006 (3:18 pm)
Did you search for castRay or raycast in the engine code?

The function :

bool ShapeBase::castRay(const Point3F &start, const Point3F &end, RayInfo* info)

Should handle your mesh collisions with a ray cast. Make it a method that can be called from script, and as an added precaution make sure only the server can call it (i.e. isServerObject() ).

- Eric
#4
12/05/2006 (3:36 pm)
I tried using ShapeBase's castRay and it wasn't working as intended. I was sending it the same start and end point that I use for containerRayCast and is selects the object I am using castRay from erratically.

Here is my current code

ConsoleMethod(ShapeBase, CheckRayCast, const char*, 3, 3, "Usage: CheckRayCast(\"%startX, %startY, %startZ, %endX, %endY, %endZ\")")
{
	Point3F spos, epos;
	dSscanf(argv[2], "%f %f %f %f %f %f", &spos.x, &spos.y, &spos.z, &epos.x, &epos.y, &epos.z);
	
	char *returnBuffer = Con::getReturnBuffer(256);
	RayInfo RayEvent;
	bool returnType = object->castRay(spos, epos, &RayEvent);
	S32 ret = 0;
    if (returnType == true)
      ret = RayEvent.object->getId();


   if(ret)
   {
      dSprintf(returnBuffer, 256, "%d %g %g %g %g %g %g",
               ret, RayEvent.point.x, RayEvent.point.y, RayEvent.point.z,
               RayEvent.normal.x, RayEvent.normal.y, RayEvent.normal.z);
   }
   else
   {
      returnBuffer[0] = '0';
      returnBuffer[1] = '[[628157b16001e]]';
   }

   return(returnBuffer);
}

and my call to it is

%mouseVec = %this.getMouse3DVec();
   %cameraPoint = %this.getMouse3DPos();
   
   %selectRange = 200;
   %mouseScaled = VectorScale(%mouseVec, %selectRange);
   %rangeEnd = VectorAdd(%cameraPoint, %mouseScaled);
   
   %objectNum = firstWord(RotatingCube3D.CheckRayCast(%cameraPoint SPC %rangeEnd));

   commandToServer('SelectObject', %objectNum);

It looks like ShapeBase's castRay only returns if the ray you sent it intersects the ShapeBase that is calling the function, or maybe I am doing something wrong
#5
12/06/2006 (1:18 pm)
I figured it all out

I modified Player.cc's castRay implementation and figured out that it checks to see if the player is intersecting the ray, and the closest position it is intersecting at.

My castRay code now checks that algorithm against all the objects I am looking for and returns the closest one.