Waves and Terrain V1.0 Release - Updated 4/22/11

Hey, so I made this dynamic wave system awhile back; it was okay, but I’ve updated it this time to be far more modular. Basically, you run a single function in your own script to get the wave to work. It looks like:

import Waves


And that’s it. It’s far easier to implement into new projects this way. Anyway, it might be a little faster, but I’ve also added randomization (not to the waves, but a complete randomization function) with seed and capping. It works pretty well.

Here’s a video showing it off:

Okay, so you can get it / read about it here.


Mmm… I added a rigid body sphere over it but isn’t affected by the waves. Anyways it looks good.

Switch either to the Flooring scene, or just recalculate the physics in every frame, like the floor in the Flooring scene.

Hahaha, sorry, so many times angry at people who doesn’t check up other scenes inside the same blend and I end up doing that too, xD

this would be neat if you could make the objects effect the water, as in when the ball drops, it goes through the mesh, creating ripples

That could be possible; I’m not sure how to get the central vertex (or vertices) that are closest to the point of entry into the water mesh for the object, though.

There seems to be a problem.
The Normals aren’t updated. :confused:
it all stays just the same grayish color.
Note: I don’t have glsl.

You’d probably get a list of vertices using the getVertex() function like used here and assign variable names to each vertex

In theory, you might be able to use the position property to get the vertex position, then you could use RayCast to cast a ray up the Z-axis to see if any are hitting an object and move them accordingly.

Or you can use getDistanceTo() to get the distance between a vertex and the center of an object about to go through the mesh since it works on points

Or if the position property can’t get the position of a vertex right now, it would likely not be too big a project if presented as a feature request.

@Zelen - I ran it using GLSL, which is what the screenshot shows. I’m not sure about what it looks like under non-GLSL mode - try using a point lamp and taking a screenshot for me.
@Ace - getDistanceTo could work, but I’m not sure if it’ll work with positions in space. I could work on dynamic waves… This is what I like about the BGE - if something isn’t implemented, it’s still possible to implement with Python or 3D shaders.

This link suggests it does work with simple X,Y,Z coordinates providing you create another variable that is a list of values for X, Y, and Z.

Hi Joeman,
I’m trying to re-create your work, but I’m only getting an oscillating plane. How the scenes are correlated between them? Do you created empty scenes or linked them? If it doesn’t get you annoying, could you write any lines to explain how you made it? I really appreciate that :slight_smile:

edit: just a note for 2.49 users: in the scripts, comment or delete the line that import the logic library from bge because this is automatically imported in 2.49.

For 2.49 users, the BGE imports GameLogic, which doesn’t exist in Blender 2.5, which is what I used to make the example file. So, the GE doesn’t import bge.logic - that should make it crash under Blender 2.49. So, Jiggo, you are correct in deleting the line about ‘import bge.logic’.

The plane should be oscillating normally, and the scenes aren’t related except the two floors should share scripts, and there isn’t really any relation between the two meshes (they’re both subdivided planes, obviously). The floor scene (with the ball in it) recalculates the physics mesh (a Replace Mesh logic brick, attached to an Always sensor). The script steps through each vertex in the plane and moves it upwards and downwards according to a time variable, which is being added to every frame (to account for time).

The basic way the ‘demo’ works is this:

  1. Create a plane.
  2. Have the plane run the wave script - an Always sensor attached to a Python controller that runs the wave script code (you could push the pulse sensor around to make it not so logic-heavy).
  3. In the Flooring scene, recalculate the physics mesh (every frame or not, depending on your needs). It’s not too difficult.

Looks great. All it needs is some white foam.

I managed to implement the object affecting the waves in my own file, however it’s not as obvious as I made use of the vertex array, and the indexes are not arranged in order (meaning the vertices have NO way of accessing their neighbours) (anyone know of a shortcut to arrange the mesh’s vertex indexes?) plus my energy transfer function isn’t perfect (I made it up :P)

Back to the affecting the waves, I used vertex paint to represent energy (higher paint, more energy, more energy, higher z co-ord (not physically, but hey)) I used a comparision, whenever a collision is detected, the colliding object is compared to each vertex (in the main for loop) own co-ords + the water objects co-ords (to make the vertex co-ords global), then I used a constant, so if the distance was within a specified area then it adds a proportional amount of energy… hope this helps advance this great implementation futher :smiley:

Video for the curious–

The waves would be affected out from the point of impact, if the vertices were in order, that is… (It looks like they just all go nuts with the current set-up)

I don’t know of a way to arrange vertex indices (or haven’t made one yet), but I have made a function to find other vertices that are exactly in the same position as the target position, I think (this is because the BGE splits up faces into individual ‘4 or 3 vertices make a face’ loops; i.e. a cube has 24 vertices, not the 8 you would think because each face has its own set of vertices).

the BGE only splits off vertices if the face they’re attached to isn’t set smooth, or has a different material than a face that it would normally share a vertex with. So while a cube generally will have all its vertices split, your wave plane most likely wouldn’t.

Also, it’s probably best to limit how often you update the collision mesh for the waves, it’s a pretty serious hit to the CPU time. Maybe only update once every 4 frames, or something.

Finally, if you wanted to add the possibility for objects to splash, I’d try just finding the X and Y coordinates where the object hits the water (or just teh object’s center’s X and Y coordinates) and add a circular wave function to the wave formula at that position, mulitplied by the object’s size (if you want to get really advanced, find the object’s cross section)
you could keep a list of wave functions and loop through them when calculating where to displace your vertices to next, and of course fade out the wave functions and remove them when they get insignificantly small. This might get a bit CPU heavy if you had a whole lot of functions running, but if you just have one water surface it’d probably be fine.

Yeah, updating the collision mesh is slow. This method sounds a bit complex, but it also sounds worth it. I believe someone’s made ripple-like effects using a soft body mesh, which might be a bit more CPU efficient than to do it this way.

Aside from performance and reliability issues with softbodies (they’re cool, but let’s face it- they’re not ready for real time application yet) a vertex displaced mesh allows for penetration- since you’re really just representing the surface of a large body of water, you want your objects to be able to pass through the mesh rather than bounce off it, and then handle the buoyancy calculations yourself. Physics updating is still handy because it allows you to just cast a ray up from the object, and if it hits your wave object then you know the object is underwater, and how far underwater it is. You might even be able to do a boolean calculation to determine how much of the object is underwater… though I’d imagine that’s a bit much for realtime.

Re-release of updated Waves in BGE. A bit faster, but much easier to use - you can use arguments in the function, as well, to change how it appears.

Fantastic! It works very nicely, I’ve been waiting for something like that for a very long time! This is the beginning of realtime procedural heightmap in Blender. Now we just need it to run faster, like a 100 folds!
Let us work hard!
Thank you SolarLune, this is a great resource!