slembcke / Chipmunk2D

A fast and lightweight 2D game physics library.
http://chipmunk2d.net
MIT License
2.22k stars 352 forks source link

How do I perform shape-specific operations on the result of a collision? #205

Closed psigen closed 3 years ago

psigen commented 3 years ago

I am trying to use the output of a collision query as part of a larger geometric computation, but I'm a bit stuck.

The resulting collision info is a pair of shape pointers. However, I need to do different things with that result depending on whether it was a circle and a polyline, or two polylines, etc. In this case, I want to find points along the surface of the collision shape that are on either side of the point of collision. This is something that I can do geometrically, by simply getting the vertices+radius or center+radius of the underlying shape.

From the documentation:

When creating different types of shapes, you will always be given a cpShape* pointer back. This is because Chipmunk shapes are meant to be opaque types. Think of the specific collision types such as cpCircleShape, cpSegmentShape and cpPolyShape as private subclasses of cpShape. You can still read some properties from them using the getter functions, but you are not intended to cast cpShape pointers to their specific types.

But how can I know whether calling cpCircleShapeGetOffset will succeed or fail if I only have the cpShape *?

aismann commented 3 years ago

One way:

cpDataPointer cpShapeGetUserData(const cpShape *shape)
void cpShapeSetUserData(cpShape *shape, cpDataPointer value)

A user definable data pointer. If you set this to point at the game object the shapes is for, then you can access your game object from Chipmunk callbacks.

slembcke commented 3 years ago

Err, sorry this is... extremely late. Apparently I need to read my notifications more often.

Generally speaking you aren't supposed to go digging around in the inner bits of the Chipmunk structs because they aren't part of the public API. However, feel free to use include chipmunk_structs.h, and use the shape->klass->type enum variable to figure out what the raw shape type is. At this point, it's incredibly unlikely that it will change.