Physics float in water

  • I've been playing around with this idea for a while, but have never been able to come up with a decent solution, so I figured I'd open it up to the forum.

    Attempt 1

    I had an object that would apply physics upwards whenever it was under water. This would simply make it bob up and down, eventually launching out of the water.

    I played around with the forces a few times, but it rarely helped. Even applying a greater physics the further away from the water's surface it is. If I had a long object, it would happily spin around in the water, rather than eventually straighten out.

    Attempt 2

    I fixed the last issue by applying a few sprites and linking them together, but it wasn't ideal because the object never stabilized, and would just rock and bounce around.

    So yeah, I was wondering if anyone had managed to create a clever way of doing physics floating in water in a realistic manner. Like a boat, if dropped at any height or any angle, would eventually right itself and come to a steady position and rotation. However, I'd want to ensure that if an object is dropped on the sprite, it would move it, or even sink it if enough weight was placed on it.

    Coming up with a smart way of applying this method to any shape would be ideal, rather than just squares, circles and generally shapes that are equal in height and width.

  • The realistic way would be to find the area of the object under the water and apply a force proportional to that area, and from the center of that area up.

    As a simple example let’s look at a non rotating box.

    Area = box.width * clamp(box.bottom-water.top, 0, box.height)

    Apply force up with magnitude area

    In the general case with any shape with rotation you could take the polygon of the object, slice it by the water level, and find the area and average center of anything below. I forget if the physics behavior

    Let’s you apply a force at any point of the object but that should take care of any torque if it does. If it doesn’t then you can take the vector from the com to the point to apply the force and do a cross product with the force vector. Maybe some unit conversion would be needed, I don’t recall.

    It’s an interesting enough problem I may attempt an example capx over the weekend. The bulk of it will be finding the area under the water.

  • R0J0hound Yeah, I'm finding it pretty interesting too. Trying to think of ways in which this can be applied to any shape, and any angle it's dropped into the water.

    One idea I've had is running a loop that will generate a series of small square sprites from the object's top-left corner to the object's bottom-right corner, deleting the object's that aren't overlapping said object, then connecting all the objects together with physics. The smaller the objects the better, but this seems like a pretty complicated way to do what may have an easier method.

    I was originally using the Chipmunk plugin as it's generally faster and allows impact points, but struggled somewhat in regards to the required forces. Chipmunk forces appear to be 10x the number of Box2D, but that's just a guess.

    I just tried box.width * clamp(box.bottom-water.top, 0, box.height) with both physics engines, and Box2D was able to get a regular 'bounce' with:

    (box.width * clamp(box.bottom-water.top, 0, box.height))/10

    but as I said, it does cause a bounce, where the object will repeatedly leave the water.

    Alternatively, I was unable to use that method to get anything regular with Chipmunk. The object sank for a while before launching out of the water. I probably just need to play around with the force a bit more.

    In an attempt to gain some inspiration, I've been watching some videos of the water puzzles in the game, Limbo.

    The way in which the floating object is affected by external forces is an important feature, and one in which I doubt would work with my ideas above.

  • Hi AnD4D

    A quick and simple method to implement a floating physics object without complex math is with joints.

    I made a simple capx for you to get the idea of my perspective .

    https://onedrive.live.com/?authkey=%21A ... ot&o=OneUp

    Cheers !

  • Nice example, saour. Many thanks.

  • Here's my solution.

    1. Take the object polygon and slice it by the water level to get the polygon of the area underneath.

    2. calculate the area and center of that area.

    3. Apply a buoyancy force proportionate to the area and do it at the calculated center.

    4. Apply some damping to the object to slow it's velocity when in water. This corrects the bouncing.

    3 and 4 will differ depending on what you use. I tried event based physics, chipmunk and the physics behaviors.

    https://www.dropbox.com/s/5gllhncklyzsp ... .capx?dl=1

    https://www.dropbox.com/s/1b95mjd4viv8d ... .capx?dl=1

    https://www.dropbox.com/s/3539qrtyc0l7c ... .capx?dl=1

    I didn't try to get each to be identical, tweaking the numbers in the last event can adjust the result.

    A few notes:

    * To make the objects sink more apply a lower force.

    * damping is done by applying a force opposite a fraction of the velocity. Too high of damping can cause the object to actually speed up.

    * angular damping was a bit more tricky. I found more damping is needed than with linear damping. There also appear to be some better approaches but they add complexity and so far the results seem "good enough."

    Also as a reference, here is a list of the units the Physics behavior uses.

    math-and-physics_p821290?#p821290

  • R0J0hound

    Sorry it's taken so long to get back to you, but I've only just taken a look at it.

    This is crazy impressive stuff, and I barely understand what I'm looking at. I'm amazed the first example looks so good but doesn't even use physics. The Box2D example appears to work the best at the moment, or how I'd imagine it to work in real life, with the perfectly square object coming to rest to a flat angle. The Chipmunk example had the square float with a corner pointing up. Seems like that is changed simply by house much underwater an object is. Perhaps that is the way things work in reality.

    Do you know how this might be adapted for objects that aren't squares and rectangles? I noticed that when I tried this with an L shape, it was still recognized as a square, so I see it's using the image points of an object. Increasing the number of image points to match the L shape and setting the "repeat 4 times" to "repeat imagepointcount+1" seems to work.

    So far, however, I've been unable to connect 2 separate objects together, which is a shame. But yeah, overall it's working really well. Using a few changes to variables, I think I should be able to demonstrate empty boxes and full ones, even resulting in them sinking over time.

  • All three examples just vary by the amount of linear damping, angular damping and amount the area affects the force. You can tweak all three to get things closer.

    For other shapes just add more image points, and make sure you place them in a clockwise order. Then in events 4 and 5 there are 4's, replace those with imagepointcount+1. You were halfway there.

    What do you mean connect things together? That would just be joints and is unrelated to the buoyancy here.

  • R0J0hound, one more impressive work )

  • R0J0hound Regarding the joints, I only tested it out quickly, but they gave unexpected results. Probably something I missed, as I rarely connect physics objects together.

    Comparing Chipmunk with Box2D, however, I did note that upon dropping another chipmunk physics sprite (non-floating) alongside the floating sprite, the floating object actually fell at a slower rate than the other. I compared the 2 versions and found that this was due to the local variable "Damp".

    This only affected things in the Chipmunk example. Setting this variable to a lower number made the sprites fall at (visually) identical speeds, but did result in a bounce upon hitting the water.

    When I changed this variable in the Box2D example, there was no change in falling speeds, but upon hitting the water, I did get undesirable results.

    I understand that this can be remedied by having an "Is overlapping" event in the latter event, but I try to avoid collision detection wherever possible, as I find it's usually a cause for errors. Are you aware of a method for solving this without overlap? or perhaps you are of the opinion that overlap doesn't cause enough of a problem to warrant additional changes?

    I much prefer the Chipmunk physics than Box2D, so that is my ideal engine, if only for the contact points.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • I’m on my phone but offhand:

    The calculated area will be zero when there’s no overlap. So the forces will evaluate to zero too because they are multiples by the area.

    I just kind of threw the three examples together, but the idea is to just tweak the numbers in the equations. I think I tried something different for the chipmunk damping maybe that’s no good?

    The two behaviors have many differences. I made no effort to match them up.

  • Wow R0J0hound !

    Great use of math (as always) and arrays !

    I notice it is very cpu intensive with box 2d .

    But your logic approach (specially with the use of arrays) is a gem !

    Cheers!

  • I had a look around at some other implementations for buoyancy that can give some more ideas.

    https://github.com/lawrencelomax/Chipmu ... Buoyancy.c

    The damping force was calculated with the relative velocity of the part under water. I forgot to do that in the examples.

    The angular damping is proportionate to the inertia of the shape under water. Could give improved results.

    http://www.iforce2d.net/b2dtut/buoyancy

    Again it uses relative velocity for damping.

    It has a cool idea to do the damping per edge to give more realistic results.

    Also it shows ideas how to take the whole thing further with lift. Very interesting.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)