home   drawings   cartoons   stories   waffles   projects   virtual worlds   files   blog

Waves 1

Should be displaying my first waves experimental VRML world here
If instead you're seeing this text, you need a more modern web browser.

Drag your mouse around the background to rotate the view.
Roll the mouse wheel, or on a touch screen drag 2 fingers, to look up or down.
Right-click, or long-tap to get the menu if you want to choose full-screen view.
The ESC key escapes from full-screen, or on a touch-screen long-tap brings up the menu again then choose to end full-screen mode.

I wanted to make simple animated water waves for my VRML worlds, but this shows it's probably more trouble than it's worth... using this technique, anyway.

As VRML's ElevationGrid node, which is it's version of the heightfield in most 3D systems has no way to directly interact with VRML's built-in animation system I had to try making a simple plane as an IndexedFaceSet. Unfortunately this requires three times the data points to be animated. While this might be useful if I want to make more accurate waves, where points move in a circular motion instead of just up and down, for this very simple simulation it is overkill.

Making the plane by hand, which is a grid of 8x8 points, would have become complicated when writing out how the points were to be connected, so I made it in Blender. My first plane was terrible because the grid points were all mixed up. I needed them to be ordered sequentially so I could animate them cleanly.

My second attempt was much better. Beginning with a single point (ctrl-RMB in edit mode), I added more, one by one, to make a line. Then I extruded the line (e z, move with the mouse, and ENTER when satisfied) 7 times. This gave me a plane with the points nicely ordered.

Blender exported the X3D point coordinates all on one line, so first, I wrote a little awk program to reformat the values as X,Y,Z triplets to make it easy to manipulate:

awk '{ for (i=1; i<=NF; ++i) if (i%3==0) print $i; else printf $i " " }' points.txt >points-triplets.txt

This data was a bit unwieldy, so I rewrote it to round the values to integers. Awk does have an int() function, but its printf command does it anyway.

awk '{ for (i=1; i<=NF; ++i) if (i%3==0) printf "%.0f\n", $i; else printf "%.0f ", $i }' points.txt >points-triplets.txt

Unfortunately awk is not smart enough to realise -0 is just 0, so I used sed (actually my eed search-replace) to get rid of all the minus signs. Now I can see instantly that the points are all nicely ordered.

In my first attempt I made the 8x8 square horizontally, so since Blender and VRML disagree on whether up is Y (VRML) or forward is Y (Blender), I used awk to swap the Y and Z values:

awk '{print $1, $3, $2}' points-triplets.txt >points-YZswapped.txt

But in my second attempt I built the square like a wall, where Z is up, so I didn't need to swap the values for VRML.

Next, I used awk to read the coordinates, substituting sine positions for Y the original Y positions, doing this 4 times for different starting positions gave the keyframe data, which I pasted into the VRML file.

awk '{printf "%d %.2f %d\n", $1, sin(NR*0.785), $3}' points-triplets.txt  >points-triplets-wave-1.txt

awk '{printf "%d %.2f %d\n", $1, sin(NR*0.785+1.57), $3}' points-triplets.txt >points-triplets-wave-2.txt

awk '{printf "%d %.2f %d\n", $1, sin(NR*0.785+3.14), $3}' points-triplets.txt >points-triplets-wave-3.txt

awk '{printf "%d %.2f %d\n", $1, sin(NR*0.785+4.71), $3}' points-triplets.txt >points-triplets-wave-4.txt

And now it works.

You can download the waves.wrl file to examine it more closely.