Game Development Community

Container::castRay - Object types all SceneObject!?

by Mr. Kristen Overmyer · in Torque Game Engine · 01/17/2006 (10:35 am) · 9 replies

Attempting to do a castRay against the terrain and am using WheeledVehicle::extendWheels as a model as to how to go about doing this. My code follows:

RayInfo lRayInfo ;
bool lCollided = mVehiclePtr->getContainer()->castRay
( lStart, lEnd
, TerrainObjectType & EnvironmentObjectType
, & lRayInfo ) ;

So far no luck. lCollided is always false even though other parts of the collision system for vehicle report collisions. I am assuming the following:

- lStart and lEnd are in world coordinates
- the filter types I should specify are as above


When I output diagnostics from Container::castRay, it appears that the exact type resulting from:

SceneObject* ptr = chain->object;

is always SceneObject (as given by typeid) instead of any of the derived types (e.g., TerrainBlock). Consequently, only SceneObjects implementation of castRay is ever called and it returns false. I am puzzled that no other types appear in the bin chain so that their implementations for performing ray intersection are called.

Any ideas?

Also, it appears to me that castRay does not use the SceneObject's working list. Is this true and as it should be?

Thanks in advance for any help you can through my way.

Kristen.

#1
01/17/2006 (11:27 am)
How are you determining your lEnd? Looking at the code in the manner extendWheels() does, it appears that it is assuming the distance between the spring point and the tip of the tire is guaranteed to have a collision (otherwise the tire isn't in contact, and that situation will be handled elsewhere--probably in the processTick() or updatePos() of the vehicle itself). My guess here is that there isn't in fact a collision with the terrain between your lStart and your lEnd.

TerrainBlock inherits from SceneObject, and does not reimplement SceneObject's castRay(), so using SceneObject's implementation is normal for this case.

IIRC, the working list isn't applicable for castRay since the distance used between lStart and lEnd is basically arbitrary...so instead of using an existing, or calculating a new working list, it just does the work from scratch.
#2
01/17/2006 (11:55 am)
Stephen,

Thanks for the quick follow up. You could be right about the start and end points. I'll try some more diagnostics to see if this is the problem. Also get your point about the working list and castRay.

I am mildly confused about TerrainBlock not having a "castRay" implementation. I show the following in "terrCollision.cpp" (TSE 1.3):

bool TerrainBlock::castRay(const Point3F &start, const Point3F &end, RayInfo *info)
{
   return castRayI(start, end, info, false);
}

bool TerrainBlock::castRayI(const Point3F &start, const Point3F &end, RayInfo *info, bool collideEmpty)
{
   std::clog << "\nTerrainBlock::castRayI" ; //!!!KO: 01-16-2006: 
   
   lineCount = 0;
   lineStart = start;
   ...

which looks like an implementation to me. Any thoughts?
#3
01/17/2006 (12:02 pm)
Interesting...when looking it up the castRay didn't show in UltraEdit--I probably just missed it! Ahh, actually I didn't check terCollision, my bad.

EDIT: removed incorrect statement.
#4
01/17/2006 (12:15 pm)
Ok, further research (and more discipline on my part on using search in files!):

Container::castRay is NOT virtual (makes sense, we don't derive from the Container class for any reason).

However, SceneObject::castRay() IS virtual, and therefore when you poll over the ptr's within chain, each of the reimplementations are called. This points back to the fact that it's most likely your lstart and lend ray doesn't in fact collide with anything. Try arbitrarily resetting your lEnd to a much higher value that should guarantee a collision, and then work back from there to a more appropriate length of the ray.
#5
01/17/2006 (12:16 pm)
Actually, here's the declaration in SceneObject.h:

virtual bool castRay(const Point3F &start, const Point3F &end, RayInfo* info);

As well, I'm wondering how a TerrainBlock castRay is ever evaluated under the present circumstances (that is all the types in the bin chain are SceneObject).

Again, thanks for the great support. I'll be interested to see what your co-workers turn up.
#6
01/17/2006 (12:19 pm)
Well, that's how virtual functions work: when a class defines a method as virtual, the compiler builds a table that keeps track of the entire chain of inheritence, and whenever you have a base class (like SceneObject) that has child classes with reimplementations of a virtually declared method, the compiler will link to the bottommost reimplementation. In other words, in this case, you are correct in that all of the ptr objects in the chain are going to be SceneObjects, but since castRay is virtually declared and reimplemented, the individual reimplementations are what will be called. In this particular case, TerrainBlock::castRay() gets called when the SceneObject representing the terrain block is found in the container.
#7
01/17/2006 (2:07 pm)
I guess what I meant was "exact" or actual derived types as reported by typeid. I wasn't referring to the pointer being of type SceneObject*.
#8
01/18/2006 (8:04 am)
Update on what I have found out after further investigation.

"typeid" was in fact reporting "SceneObject *" which was in fact the true type of the variable in question. I had neglected to dereference the pointer to ask for the actual derived type object. My bad. Once I did this, I found that AtlasInstance::castRay was getting called. Good. Its type mask however is "AtlasObjectType | StaticObjectType | StaticRenderedObjectType" and does not include "TerrainObjectType". So my initial filtering on "TerrainObjectType" was one problem.

Your idea of changing the start & end points to ensure an intersection was a good idea. Thanks for that. When I didn't get any, it led me to further investigate the filter. I now appear to be getting some results that I can work with.

Thanks for the help.

Kristen.
#9
01/18/2006 (9:57 am)
Ahh...you didn't mention that you were using/crossing in Atlas code :) That's TSE, and yes, the ObjectType flags are different.

BTW, you may or may not be aware of the private TSE forums as well, may want to subscribe to those--some really good stuff specific to TSE there.