Best practices for kinematic bodies in modern Chipmunk?

Official forum for the Chipmunk2D Physics Library.
Post Reply
mcc
Posts: 27
Joined: Sun Mar 30, 2008 9:00 pm
Contact:

Best practices for kinematic bodies in modern Chipmunk?

Post by mcc »

Hi. I used Chipmunk a lot in the early '10s, I'm using a modern version now [7.0.2 but can upgrade]. I'm trying to understand some of the new capabilities...

I want to do an effect where the "room is shaking". More specifically, the [player grabs and physically moves the game world](https://www.youtube.com/watch?v=HLBAjKQNmFI) with a pointing device, and I want objects to realistically react as if the "floor moved"; if the floor drops down, I want them to experience momentary weightlessness, if the floor pulls up, I want them to "flip up" like flipping a pancake, if the floor wiggles side to side I want stacked objects to fall over.

My first thought was to use kinematic objects, a newer feature. The docs say: "Kinematic bodies are controlled by setting their velocity, which will cause them to move. Good examples of kinematic bodies might include things like moving platforms". This sounds like what I want. So I try replacing the static body that I had been attaching my "walls and floors" to with a cpBodyNewKinematic() body. I then take the amount the user moved the UI world-container and I set the move since the last frame, divided by the timestep (yes, I'm using non-constant timesteps currently), as the velocity of the walls-floors kinematic body. So what I assume will happen is that this will cause the walls-floors to move to the new position over the course of the timestep.

I see two odd problems:
1. When I read back the position of the kinematic body using cpBodyGetPosition, it always printfs as 0.000000, 0.000000. I have not tested yet whether it is actually 0 or just something smaller than 0.0000005.
2. When I move the world-containers even only just a little, the objects "pop up" VERY intensely and fast. It does not look like a natural movement, it looks like a "bounce". Moreover, this is the only interaction I see. If I jiggle the world-container side to side the objects do not move side to side, I only get the "popping" when something is touching the floor and the floor moves. It looks more than anything like the rapid popping-out when an object winds up overlapping with a wall and is pushed out.

My problem 1 implies maybe I may be doing something deeply wrong rather than just a little wrong. This said, when I look in the docs, I see this explanation about kinematic objects:
For dynamic bodies, setting the velocity explicitly every frame can cause problems. For example, a problem occurs when a light dynamic body (like a person) is pressed against a heavy dynamic body (like a car), and you set velocity of the small object so that it’s pushing it into the big body. To the physics engine, the change in velocity is the same as applying a large impulse (a very short, very large force).
This sounds a lot like my problem! It continues:
The easiest way to avoid both of these problems is to make smaller changes to the body’s velocity, accelerating it over a fraction of a second instead of a single frame. An even better solution, which is covered more thoroughly later, is to use constraints to move the object.
The first suggestion here is not a realistic option for me because the movement is being controlled by direct-manipulation user input— I could *smooth* the drag, but if I change it too much it will not look realistic.
The second suggestion sounds very appealing! But, I cannot find the "covered more thoroughly later" explanation of how to do this. I ctrl-Fed through mentions of "constraint" in the docs and did not find any relevant information.

Is there a best-practice guide or sample code somewhere explaining how to use a kinematic body to simulate a "magically" moving object that moves independent of physics?

How could I use constraints to move a "worldlike object" (walls and floors, immovable) in sync with an interface like a pointing device, as the manual suggests? Is there a section in the manual I overlooked?

Thanks!
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Best practices for kinematic bodies in modern Chipmunk?

Post by slembcke »

Hmm. So previously Chipmunk used "rogue bodies". You created them, and instead of adding them to the space you updated all their parameters yourself. Similarly static bodies were just rogue bodies with infinite mass and moment that never moved.

At some point I added cpBodyNewKinematic() and cpBodyNewStatic(), these bodies are supposed to be added to the space using cpSpaceAddBody(). (well... static bodies are optional IIRC, but not important for your question...) If you were doing it "ye olde school" style that would explain why 1) the position was not updating and 2) the overlap behavior. Although... it should still be transferring velocity through friction, so there might still be something else going on. Kinematic bodies should be a good way to implement this otherwise.

Are all of the boxes/screens simulated in a single contiguous world? (I kind of assume not since it looks like they are allowed to overlap visually, and they aren't all on the same plane?) If they are in different spaces, I would probably try implementing the physics in their relative reference frames using intergration callbacks. The reasoning for this isn't terribly technical, but it would mean that the coordinates of each box stays the same when drawing which sounds nice... unless it ends up requiring more lines of code. Instead of using a kinematic body you use a regular static body that never moves, and define the space's motion to be relative to the level's geometry. In an integration callback, I think you would just need to add the motion of the world to the body's velocity before calling the builtin function. (example from the Planet demo: https://github.com/slembcke/Chipmunk2D/ ... anet.c#L36) On the other hand the idea might be crummy as I've never tried implementing it. ;)

Smoothing: Yes absolutely add smoothing! I get a lot of grumpy replies when I say this because I think it brings back that one time people tried turning on mouse smoothing in a shooter game and it made everything mushy. User input tends to be super noisy (especially for VR tracking), and physics engines really to hate this. Since the smoothing is really only apparent by the motion of the objects in the frame, you can probably get away with more than you'd think.

Constraints: This doesn't really apply. Apparently I meant it was covered in the demos, specifically ones like Tank, and Crane or even the Demo's mouse grabber joint. (I'll update that, whoops) They use the properties like maxBias and maxForce to control bodies without generating huge forces or jittery movements.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
mcc
Posts: 27
Joined: Sun Mar 30, 2008 9:00 pm
Contact:

Re: Best practices for kinematic bodies in modern Chipmunk?

Post by mcc »

Scott, thanks. I added the kinematic body to the space and both the physics and the reporting are now working better.
At some point I added cpBodyNewKinematic() and cpBodyNewStatic(), these bodies are supposed to be added to the space using cpSpaceAddBody(). (well... static bodies are optional IIRC, but not important for your question...)
I think this is a documentation bug then. The documentation offhandedly mentions that kinematic bodies should not be added to the space:
Call func for each body in the space also passing along your data pointer. Sleeping bodies are included, but static and kinematic bodies are not as they aren’t added to the space.
This is in the "iterators" section but based on this I intentionally did not add the kinematic body to the space.

Let me experiment with how things are working now and get back to you.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest