Advertisement

Physics: Determine which vertex hits floor first

Started by December 31, 2023 11:36 PM
5 comments, last by scott8 11 months, 3 weeks ago

I am working on implementing some simple physics in my engine and I am trying to implement physics for objects such as a cube where a corner of the cube might hit the floor first and we can perhaps apply an impulse there to give it a bounce like characteristic. I am wondering how you might go about determining which vertex of the cube hit the ground first. I am trying to keep it super simple at the moment. I am trying to determine which vertex hit the floor first if the floor is placed at 0,0,0.

I thought about looping through my cube's vertices and seeing which one is closest to the ground but the vertices do not update when you do something like glTranslate(....) and remain static from where you originally defined them. Even if this was useable I dont think it's the right approach?

Would appreciate any insight into how you might go about doing something like this.

snoken said:
Even if this was useable I dont think it's the right approach?

No expert here, but your actual idea is to ‘predict’ collisions. And this simply can not work. We can not even predict the trajectory of 3 bodies affecting each other due to gravity, and games are much more complex and chaotic than this.

So instead predicting which vertex might collide first in the future, i suggest to just detect collisions in the present frame and resolve them accordingly. That's how almost all physics engines work, although there are some ideas such as ‘speculative contacts’. But usually such ideas fail on correctness and work only for specific applications.

snoken said:
Would appreciate any insight into how you might go about doing something like this.

Consider to use a physics engine.
You have broken animations and broken UV parametrization in the works already. Adding more and more topics, each harder than the former, likely just piles up more broken stuff, and you do not really learn anything.

Using libraries is a good way to learn too, and it allows to focus and spending the required time on the things you really want to do yourself.

Advertisement

I think it's possible to make a somewhat convincing routine. Here's a high level description and a demo!

You'll have to generate some vertices in worldspace by using the vertices of your cube or a bounding box for more complex geometry. Take those 8 verts and apply your world transform (Orientaion, scaling, and position) to get their positions in worldspace.

  1. I have a vector (array) I keep all falling objects in.
  2. In each iteration object is updated:
    1. Moved down
    2. Velocity is increased (since gravity is an accelerating force)
    3. Rotation Updated (object may not be rotating)
  3. Get the three lowest (closest to ground) vertices of the bounding box that encompasses the object.
  4. Deterimine if the LOWEST (closest to ground) vertex is at or below ground level.
    1. If not, exit routine.
  5. Calculate the rebound vector and move the object so it's above ground level. In my demo, it's just straight up.
    1. The speed gets attenuated on each bounce. Attenuate the speed less if you want an object that bounces a lot
    2. At some threshold, stop the bouncing by setting the object's upward velocity to zero.
  6. The important part is to change the rotation of the object when the first vertex hits the ground
    1. The new rotation matrix can be defined by calculating a new axis of rotation.
    2. Center all vertices on the 2nd lowest vertex (ie ThirdLowestVertex -= SecondLowestVertex)
    3. Calculate the average of the 2nd and 3rd lowest vertex.
    4. The axis of rotation will be the the vector from the second lowest (now 0,0,0 because we centered it) and the average. It should be normalized too.
    5. I set an arbitratry # of radians to rotate when making the new rotation matrix. I just played around till it looked right. You want to make sure the sign (±) rotation is such that the lowest vertex is going to move UP.
    6. Use this rotation matrix to update the object till it hits the ground again..

One thing to check for is if all three of the lowest vertices are the same height. This means the object is falling completely flat - all four vertices will hit the ground at the same time. Then perhaps there should be NO rotation? Or a small random rotation?

@scott8 Thanks for the the detailed response! This has helped me understand a lot more. I am wondering how you're determining when the object is stationary? you're object bounces on it's corners and eventually evens out but if you have a shape such as a icosahedron, you're less likely to get this even landing almost if that makes sense. Would appreciate any insight.

snoken said:
I am wondering how you're determining when the object is stationary?

Usually that's a check if relative contact velocities are below some small threshold.

If so, the object is ‘at rest’, and we transition from simple pairwise collision resolution to solving for multi body contact forces, which is the hard part of rigid body simulation.
The usual toy problem is stacks of boxes. How many boxes can we stack up, without introducing jitter or boxes starting to fall down.

If all boxes of some stack are at rest, their state eventually transitions from resting to sleeping. That's basically turning simulation off, not wasting any cycles on objects which do not move anyway.

This sleep mode is often used to hide inaccuracy of the simulation. E.g. we have a dead ragdoll on the floor, but due to joint limits, some of its bodies may start oscillating. Or worse, they do some jumpy move, actually indicating some solver explosion issue. To prevent those problems, we can use a high sleep threshold, so the ragdoll goes to sleep quickly and stops moving like a zombie.

Those things are good to know if you evaluate multiple physics engines. To compare their accuracy and robustness, you might want to turn sleeping off, and construct difficult test scenes. Another good test is to implement something like a gravity gun, and see how bad the jitter is if the player pushes the carried object against a wall.

Simulation quality and also performance varies wildly across engines, and comparing them to each other in a fair and objective way is not trivial.

@snoken Basically what joeJ said. When the changes become small enough, call it good enough and set the amount of rotation such that all vertices are on the same plane.

I originally was thinking i could use this for my robot-shooting game. The robots explode and the legs/arms/body parts fall off. I thought I could have the pieces bounce on the ground a little. But then I had to worry about the pieces hitting other pieces or other items (crates, barrels). It got a little hairy and I wimped out! Plus I didn't want my levels littered with robot parts.

This topic is closed to new replies.

Advertisement