"inconsistent cdBody" assert in castRayWithCollector

"inconsistent cdBody" assert in castRayWithCollector

andykarn's picture

Within a hkpWorld::castRay(...,hkpRayHitCollector&) call, I am getting the assert:

".\Shape\Convex\hkpConvexShape.cpp(31): [0x7f1735a0] Assert : 'cdBody.getShape() == this
inconsistent cdBody, shapePointer is wrong'"

in a call that looks like

pTriangleShape->castRayWithCollector(input, *pBody, *pClosestRayHitCollector);

with const hkpTriangleShape* pTriangleShape, const hkpCdBody* pBody, and hkpClosestRayHitCollector* pClosestRayHitCollector.

The cdBody has a custom shape myShape : public hkpTriSampledHeightFieldBvTreeShape,
which overrides ctors and dtor, both queryAabb methods, queryObb, castRayImpl, and castRayWithCollector.

The cdBody has shape key = -1 and parent = NULL, and is passed in to myShape::castRayWithCollector by hkpWorldRayCaster::addBroadPhaseHandle.

The assert occurs within hkpWorld::castRay(...,hkpRayHitCollector&), but not within hkpWorld::castRay(...,hkpWorldRayCastOutput&).

What could be causing this assert? Is the result continuing after the assert likely to be accurate? Is part of the implementation of myShape missing?

Thanks,
-Andy Karn

7 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
havokchris's picture

Hi Andy,
Can you post the full callstack from the assert? I'm surprised to see it going through hkpConvexShape; I would have expected to see it go straight through to hkpTriangleShape.

Could you add paste some of the code for your bvTreeShape's castRayImpl and castRayWithCollector functions? Also, just to make sure (and maybe this is the problem), you should be overriding hkpShape::castRayWithCollectorImpl, not castRayWithCollector (which isn't virtual). And if you implemented your own version of hkpTriSampledHeightFieldCollection, I'd like to see how you're creating the triangle. Feel free to redact as much of your internal code as you think is necessary.

-Chris

andykarn's picture

Thanks for answering, Chris.

The method castRayWithCollector is virtual, and overrides the one in hkpTriSampledHeightFieldBvTreeShape. There is no castRayCollectorImpl in Havok's codebase.

Since hkpTriangle has no castRayWithCollector method, the call is directly to hkpConvexShape::castRayWithCollector, which presumably calls the virtual method castRayImpl, which should be the one in hkpTriangle.

I think the problem is that my hkpTriangle is constructed on the fly in my class and reused by calling setVertex() with positions from my data. The assert in hkpConvexShape::castRayWithCollector() that (cdBody.getShape() == this) will always be false, because the cdBody has no way of getting a pointer to the hkpTriangle.

1. Can I harmlessly just slience this assert?

2. Can/should I call setVertex() on cdBody.getShape() instead? Is it safe to cast away the const? Is there any advantage to doing it this way?

3. Why does the hkConvexShape need the cdBody for raycasting with a collector but doesn't need it for raycasting without a collector? Is it using the cdBody's transform, or what?

-Andy Karn

havokchris's picture

Hi Andy,
We must be on different versions. The signature in Havok 6.5 is

HKP_SHAPE_VIRTUAL void castRayWithCollectorImpl( HKP_SHAPE_VIRTUAL_THIS const hkpShapeRayCastInput& input, const hkpCdBody& cdBody, hkpRayHitCollector& collector ) HKP_SHAPE_VIRTUAL_CONST;

I suspect that you can silence the assert without crashing, but I don't know if it'll give the right results.

I'm at home right now and don't have the full source, but I'll try to look closer tomorrow (unless sean.thurston beats me to it).

Sorry for the hassle...

-Chris

andykarn's picture

Sorry, Chris - I forgot to say I'm using version 5.5.0.

-Andy Karn

havokchris's picture
Quoting - andykarn Sorry, Chris - I forgot to say I'm using version 5.5.0.

-Andy Karn

Hi Andy,
No worries. The interface of castRayWthCollector changed around 6.0 so that it's like the castRay interface - the functionName is inlined, and functionNameImpl is virtual. It's ugly, but it makes a lot of stuff on "other platforms" a lot nicer. Just watch out when you upgrade :)

Anyway, it looks like what your heighfield raycast method should be doing is something like this:

const hkpShape* childShape = // create or update your triangle here
hkpCdBody childBody( &cdBody );
childBody.setShape( childShape, key );
childShape->castRayWithCollector( input, childBody, collector );

where "cdBody" was the argument to castRayWithCollector, and "key" is whatever shape key you're using. This should do the trick, based on looking at related code in hkpShapeCollection, which is doing the same thing that you do (create an hkpShape on the fly).

Hope that helps...

-Chris

andykarn's picture

Chris-

Silencing the warning seems to work ok. So does creating a child cd body as in your code snippet.

Thanks again.

-Andy Karn

Login to leave a comment.