# faking 3D physics

I’ve long wondered about the possibility of making a rudimentary fake-3D-physics simulator in Codea.

I think I don’t have the time or the math or the Codea/Lua chops for it, but I’ll describe my concept and hopefully find out from you guys if it would theoretically work.

As far as I’ve figured it out, it can only work with spheres. Here’s what you do.

First, on your 2D physics simulator, you make 2 circles of the same size that can’t touch each other, that won’t collide, that will just pass right through each other, BUT that are constrained to always share the same y value.

You make each of them bouncy and make them bounce off the sides of the screen too.

Then in 3D space you define two planes that are perpendicular to each other, and that intersect in the middle, so that from overhead they’d look like an x. Let’s call them plane A and plane B.

Then you create a sphere of the same size as the circles, and you define x value of the the circle in plane A as the x value of this sphere, and the x value of the circle in plane B as the Z value of the sphere, and the common Y value as the sphere’s y.

Then when you ran the thing, you would see a 3D ball appearing to bounce around in a box… right?

I think you could also define another ball that would collide with the first–again you give it two 2D circles to map its x and z values to, but you make the new sphere’s x circle only collide with the other sphere’s x circle, and its z circle only collide with the other z circle. Then the new sphere would know whenever it collided with the other one on either axis, and you’d see two balls bouncing around in a box, and bouncing off of each other to boot.

I’ve never gone to the trouble to build this, partially because I don’t think it’s good for much beyond this simple trick, and partially because I’m not totally sure it would work.

Would it work?

Well, I didn’t follow all of that, but I think spheres are fairly simple, because all you need to do is check the distance from your sphere centre to the surface of each object.

If the distance is smaller than the circle radius, you have collided, and you can calculate the point of impact and the (3D) angle at which it hit, and bounce it back.

@Ignatz you shouldn’t need to calculate anything at all because it’s using the 2D physics engine to detect collisions.

I wish I could figure out how to say it simpler. You have two 2D physics circles and a 3D sphere, all of the same size, all sharing a y value. When you start the program, you’ll see the 2D circles bounce all over the place, and the 3D sphere bounce just up and down.

Then plot the x value of one of the circles to the x value of the sphere. Now the sphere will track that circle exactly; when you run the program they’ll bounce in unison.

Finally, plot the x value of the other circle to the z value of the sphere. Now when you run the program the 2D circles will bounce all over the place in 2D, and the 3D sphere will bounce all over in three dimensions: x, y, and z.

Well, try it by all means. I can see what you mean. I would build it using two separate 2D physics boxes, which removes the problem of preventing the two circles colliding.

3D physics is easy enough if all the dynamic bodies are spheres, and the static bodies are either spheres or planes aligned with one or more axes.

In that case there’s no point “faking” it, ie pretending that a 2D simulation is 3D, because the maths is the same anyway, circle meets line is the same set of sums as sphere meets (axes-aligned) plane, just with an extra z coordinate.

For a top-down tabletop 3D game, I once tried using Box2D as the underlying physics engine. It looked great, as long as everything stayed firmly stuck to the ground. At some point though, you’re certainly going to want something to fly up into the air, and as soon as one object has to pass over another object, the illusion is ruined, as your “spheres” are effectively infinitely tall cylinders that nothing can pas over or under of.

@yojimbo2000 that cylinder thing wouldn’t happen in this set up though; with two or more spheres, the spheres would have a full range of motion, over, under, side-to-side, wherever. You could have tons of different-sized balls, even.

In fact–just occurring to me–one way to cheat non-spherical shapes would be to put them inside the spheres. Like, a frog inside a sphere would be able to jump around like a 3D frog. Hm. That actually raises a lot of possibilities.

@Ignatz, Codea can instantiate two different physics environments? I didn’t know that.

In any case I’m glad you think it would work. It’s a bit beyond my abilities at the moment, but maybe I’ll do it someday when I have to time to struggle through it. I just always wondered if it would work, and I’m glad to get the theoretical thumbs up.

It’s not really two different environments, just two different sets of walled rectangles, each with a circle inside. If you put them back to back (out of sight offscreen) It only requires five physics edges to make the boxes.

Pretty simple, really.

@UberGoober - It seems to work quite well. (Note that while I’ve drawn two boxes at bottom right to show the movements in the two 2D planes, this is just to show what is happening, and there’s no need to draw them).

Code is here.

@Ignatz yay you did it!! Awesome!!

…not sure where this leads, but it seems to open up a lot of possibilities.

I don’t get it. This approach is more complex than just doing it in 3D. The calculations for resolving collisions with the planes (dot product to separate perpendicular from parallel force) are exactly the same, just with vec3s not vec2s.

I agree entirely, I would use math instead, but it was interesting to program, all the same

Here is a vector math based version, and it is very simple as the walls are vertical and horizontal. For example, to test for a collision with the left wall, you simply check if the X value, less the ball radius, is less than the X value of the wall, and if it is, you reverse the sign of the X velocity.

The only slightly tricky thing is that to avoid the ball penetrating the wall, you have to make it bounce back at the instant it touches, which will be between draw cycles, and requires a simple interpolation.

My AdjustPos function does this. I’m sure it could be tidied up somewhat.

Incidentally, on Twitter this morning I saw that bullet3D (3D equivalent to Box2D) has been added to Codea Craft. Here’s hoping that Codea’s feature set keeps pace with its new sibling.

Also in app-store related news, the hot new game of the week is Human Resource Machine, which is a programming game that bears more than a slight resemblance to Cargo Bot

From just this demo there may not be much advantage to it, but what it’s doing is essentially enabling many if not all of the 2D physics features to be done in 3D.

Sure, one could duplicate everything in the 2D physics engine using hand-rolled math, but the point is that with this method you don’t have to. Variable gravity, things repelling and attracting each other, sensors, even joints are possible.

This approach may be more complicated than calculating simple bouncing, but it’s definitely less complicated than re-implementing all of those other features.

From just this demo there may not be much advantage to it, but what it’s doing is essentially enabling many if not all of the 2D physics features to be done in 3D.

Sure, one could duplicate everything in the 2D physics engine using hand-rolled math, but the point is that with this method you don’t have to. Variable gravity, things repelling and attracting each other, sensors, even joints are possible.

Sorry, but, no, no, and no. Try adding a second ball and see what happens. 2 balls will trigger a collision in the xy plane, even if their z-coords are very far apart, and the same for the other plane.

EDIT just to clarify what I mean, you’ll get loads of false collisions, because a 3D volumetric space is much bigger than just 2 planes. Sorry if I sound like a party pooper

Surely all that’s required is that any collision on one plane is only acted upon if the two spheres are also colliding on the other?

Any collision in 3D space is a result of comparing three coordinates. With a linked Y and a plane for X and a plane for Z, we’re generating those. For irregular shapes like bricks or windowframes it won’t work, but for perfectly spherical shapes, I think it will.

Surely all that’s required is that any collision on one plane is only acted upon if the two spheres are also colliding on the other?

But how do you intercept that collision before Box2D resolves it?

You can turn impactful collisions on and off at will, can’t you? You can always detect when the boundaries come in contact, and you can toggle collisions on at the moment of contact and then off again immediately after the repulsive force is applied.

If it’s just for making spheres bounce around, honestly this 2 plane system is more complex than doing the 3D maths.

Doesn’t that bring us full circle?

Now I say it’s good for a lot of other stuff and you say no it isn’t, it can’t do ___, and I say what if you did ___, and you say well if that’s all it’s good for it’s more trouble than it’s worth. 20 goto 10.

No need to approve of this, it’s a kludge by any measure, no doubt.