Game Development Community

how can I do this with water?

by deepscratch · in Torque 3D Professional · 07/16/2009 (4:11 pm) · 13 replies

hi all,
another one of my odd questions:
how can I get the z position of the waves that are directly upon me, and use it to change my z position?
what do I mean?
when you go into a large body of water that has waves, like the ocean, you dont just float in one static position, you float with the lift and drop of the waves, going up and down as the water directly surrounding you goes up and down, right?
so how can this be done?
I'm thinking players and water craft here, but this would extend to anything that can float.
any ideas?
suggestions?
thanks.

#1
07/17/2009 (12:57 am)
Make the model's animation do the floating?
#2
07/17/2009 (1:10 am)
you miss the point
#3
07/17/2009 (1:43 am)
Lot's of ray casting (to find the surface level at "this" location) followed by many many getPosition/setPosition 's -- repeat. And then somewhere in there do some interpolation so that you don't appear to be riding a stop motion see-saw.

But what about multi-player? Is the water height always the same from point-to-point on the server and across all clients?
#4
07/17/2009 (1:53 am)
Hmmm, variation of the above thought... what if you had someway of determining the water level, like above, but you also had a "float" node in your player model. If the player is in the water but his/her head is above water and not swimming then make him/her float with the floatnode conforming to the current water height of "this" location -- sort of like you were mounted to the water surface.
#5
07/17/2009 (2:52 am)
@Michael, I like your second suggestion,
regarding multiplayer, its a single player game, no it wont matter.
#6
07/17/2009 (6:38 am)
Last time I read about people that wanted to do this. They explained that even though the waves actually rise up and down. The water block bounds determine if your head is underwater. So pretty much they recommended an animation. I know you don't like that answer.
#7
07/17/2009 (10:43 am)
Well, I don't think you can raycast into the waves, since the animation is probably driven by a vertex shader. However, that very fact can be used as a solution: by replicating the wave animation algorithm, and using the animation parameters from waterblock, you could calculate the wave height at any given point and use that information for your watercraft physics.
#8
07/17/2009 (11:07 am)
Edit: Manoel has the correct idea

The Player already receives buoyancy forces while in water based on the water coverage, water density, and the player's density.

Take a look at...

shapeBase.cpp ShapeBase::updateContainer() -->
containerQuery.cpp findRouter() -->
containerQuery.cpp waterFind()

The WaterObject is responsible for calculating the F32 coverage given a Box3F, a ShapeBase object's bounding box in this case. So the best fix it for WaterObject to account for the undulation within that method call. Then with the "correct" coverage buoyancy forces will just work.

#9
07/17/2009 (2:13 pm)
just thinking out loud here, I'm totaly clueless at this stuff,
but,
how about doing a raycast to the water texture, not the surface, from the players position when in water, and by doing so, keep his feet at z-1.5 from the texture surface at all times when he is not moving?

isnt there a function to get a distance to a texture?

I've set up projectiles to display a ripple as one of their emitters when they impact water, and I'm sure I noticed the ripple move up and down with the waves.

like I say, I dont know, just thinking out loud.

EDIT: I just checked something, if I choose a point at the waters edge where the wave wash over, and snipe at it, when it is exposed as the wave washes out, there is a dust puff, and if I shoot at the exact same spot when the wave washes over it, there is a splash, so the projectiles know where the water is, even though its a shader effect. how do they know?
and can that knowledge be passed on to the player? and a watercraft?
I will check this out more.

EDIT2: ok, its the pointInWater function, projectile has it, player has it commented out, as does shapeBase.
#10
07/17/2009 (2:52 pm)
Again only small ripple are done via texture. not the waves those are passed to the vertex shader.

Gonna have to go with James Ford on this one.
#11
07/18/2009 (2:33 am)
The pointInWater method that projectile uses boils down to the same "waterFind" method in containerQuery, which in turn is just calling getWaterCoverage on intersecting WaterObjects.

If you look at the implementation of getWaterCoverage within River, WaterBlock, and/or WaterPlane, none of them are accounting for waves. They could, though it would be tricky in the case of rivers.
#12
07/18/2009 (3:09 am)
I was chatting to Jacob Dankovchik, and he had a realy good idea on this,

in his own words:

" in the waterblock code make it's density change at the same rate as the waves
and then if you really wanted to get fancy, could probably do some work to make it uneven as well so the ship would tilt and rock, not just move up and down

for something like that, could probably work it as if density is decreasing, you're moving up, meaning a wave is comming up under you, so tilt the ship upward.. density raises, ship drops, wave is going away, tilt down"

I think that could work out super, comments on this?
or ideas how to implement it?
#13
07/18/2009 (3:27 am)
I don't think you want to animate density as that is not what it is for. As I said before, if the getWaterCoverage method returned a value that takes waves into account the buoyancy calculations should take care for the rest.

As for tilting a floating object... currently buoyancy is only calculated as a single upward force applied at the center of the floating object. That is really only correct for a big floating sphere, other shapes you might want to break up into sub-volumes to perform the coverange/buoyancy calculations on.

I don't mean to physically break up the mesh, I mean that updateContainer for your boat class will need to be extended to treat it this way.

Alternatively you could sort of fake it by aligning your boat to the water's surface normal including the waves. Since RayInfo returned by castRay includes a normal you might use to retrieve it. But again... you would need to extend castRay as it is implemented in all derived WaterObject classes to properly calculate a normal including waves.