cocos2d / cocos2d-objc

Cocos2d for iOS and OS X, built using Objective-C
http://www.cocos2d-objc.org
Other
4.07k stars 1.16k forks source link

Feature request: fast raycasting (blocking) for CCPhysics #559

Closed tanis2000 closed 10 years ago

tanis2000 commented 10 years ago

I have been studying different ways to handle fast moving physics bodies and I noticed that there is a widely adopted practice to use a quick ray cast to check for hits between frames.

As an example, the Unity community makes use of this script http://wiki.unity3d.com/index.php?title=DontGoThroughThings to avoid having to turn on continuous collision detection on fast moving objects for the usual reasons.

CCPhysics does have a ray cast method but it's got two drawbacks:

Is there any chance this could be added to CCPhysics?

tanis2000 commented 10 years ago

I achieved this in my own code by accessing the ObjectiveChipmunk code directly, but a wrapper would be a really nice addition.

Here's the sample code:

        CCPhysicsNode *w = self.parent
        ChipmunkSegmentQueryInfo *qi = [w.space segmentQueryFirstFrom:self.position to:ccp(self.position.x+self.physicsBody.velocity.x*delta, self.position.y) radius:0.5 filter:CP_SHAPE_FILTER_ALL];
        if (qi != nil) {
            CCPhysicsShape *shape = [cpShapeGetUserData(qi.shape.shape) userData];
            for (NSString *s in shape.collisionCategories) {
                if ([s isEqualToString:@"floor"]) {
                    // We are hitting something
                }
             }
          }
slembcke commented 10 years ago

So originally I was going to include it, but decided against it due to the filtering parameters. The "first" version of the segment query function isn't very useful without them. That's a lot of extra parameters to pass and an expensive conversion step for each query.

CCPhysics isn't supposed to be a complete wrapper around Chipmunk, but enough to make it easy to use. Since "easy to use" usually also means "not very powerful", I tried to make it so it was easy to get at the Chipmunk layer underneath. In this case I'm happy enough with how it works out.

I'd still like to do something with automatic raycast projectiles though.

tanis2000 commented 10 years ago

@slembcke I understand your point but being able to cast rays and grab the first collision detected is a very handy feature. Right now I have exactly the problem you're talking about. I'm not filtering, thus receiving the collision of my own body if shooting the ray from the center of that body to any direction. I guess I'll have a look into building the filter object starting from your code. Another approach (maybe faster?) could be to write a ray cast method that works on the sprites instead of the physics bodies.. I don't know if that would be quicker by bypassing the physics system though.

slembcke commented 10 years ago

Well the point of the CCPhysics layer is to take Chipmunk and make it much easier to use by removing or avoiding certain features. If it did everything that Objective-Chipmunk did and was just as complicated then there would have been no point in creating CCPhysics at all. Instead it's supposed to be a decent starting point that does a lot of what beginning users want while being open enough so it can be extended by more advanced users like what you are doing. Sort of like how Cocos2D itself isn't as nearly as complicated as OpenGL yet allows you to extend it with custom OpenGL code.

If you want to do filtering you need to build a cpShapeFilter struct using the [CCPhysicsNode bitmaskForCategories:] method. You'll want to cache the filter to avoid needing to regenerate the bitmask for each call though.

Raycasting on sprites? I'm not sure what that implies. Pixels? bounds? You would have to duplicate a lot of the things that Chipmunk already does (spatial indexing, etc) to make it even a fraction as fast.

tanis2000 commented 10 years ago

You have a good point. Thanks for the explanation. It all makes sense now. If I may suggest something, maybe it would be a nice plus to have a tutorial that explains how to access the Objective-Chipmunk methods and structures starting from the CCPhysics entities.

I managed to find it out by looking at the code and doing some trial and error but it would have been really helpful to have a couple of paragraphs telling me where to look for the underlying structure.

BTW I'll follow your suggestion and build the filters and cache them for reuse.

Neophen commented 10 years ago

any news on this?

tanis2000 commented 10 years ago

@Neophen as @slembcke stated, this is not going to be part of Cocos2D as it's out of scope and it's already a feature of Chipmunk, which is included in Cocos2D. I might post some code to show you how to access the Chipmunk layer to do the ray tests if you need it. Just let me know and I'll work on it as I get some spare time.

Neophen commented 10 years ago

I think at the moment all of if would just go over my head, I'm trying to implement the pool like line where it shows the direction the ball will bounce as well as the other one. But thank you anyway :)