Author
Topic: Simple ocean / water surface / waves (Read 7645 times)

After searching the web I found it very difficult to find a basic simulation of the oceans surface / waves - there's plenty of complex fluid simulations, but what I wanted was effectively just a 3D sine wave. After a bit more searching for 3D sine wave algorithms and a bit of experimentation I've ended up with a modified series of a hyperbolic paraboloid (also known as a saddle surface - http://en.wikipedia.org/wiki/Paraboloid).

Forgive my code if there's a lot better / more efficient way to create/animate the 3D surface, I'm extremely new to 3D coding.Changes to the code you may want to make :* You can get slightly different wave shapes by changing the "-" in the formula to either a "+" or a "*"* The higher the wave frequency variable the shorter the period of the sine wave shape. Suggested figures 18,36,72. If you change to other numbers you will have to change the AnimationFrameMax variable as the start and end frames wont line up any more. * The lower the SizeFactor variable the higher the amplitude of the sine wave.* Comment out the "DRAWRECT" lines creating the water "texture" and use the LOADSPRITE instead to make it look a lot prettier.* use some "X_MOVEMENT" and "X_DRAWOBJ" commands to increase the size of the ocean

I haven't gotten around to working out how to change the direction the waves are moving, but I'll leave that as an exercise for the reader

CONSTANT WaveAnimationFrameMax%=20// How many frames before we return to the start frameCONSTANT GridSizeX%=40CONSTANT GridSizeZ%=40CONSTANT SizeFactor%=3// A lower number = higher sine wave amplitudeCONSTANT WaveFrequency%=36// Higher number = shorter sine wave period

GLOBAL HeightMap#[]// The array storing the heights for each square in our water surfaceDIM HeightMap#[GridSizeX%][GridSizeZ%]

GLOBAL WaterTexture // Sprite for the textureGLOBAL GlobalTimer

// ------------------------------------------------------------- //// --- MAIN ---// ------------------------------------------------------------- //WaterTexture=GENSPRITE()// Reserve the sprite for the water textureGOSUB CreateWaterTexture // Create/load the water texture

WHILETRUEX_MAKE3D1,600,45// Make 3D windowX_CAMERA0,10,-10,10,0,10// Set up the cameraX_AMBIENT_LT0,RGB(255,255,255)

//timer = 100 ms UpdateGrid(200)// Create the waves

X_SETTEXTURE WaterTexture,-1// Give them textureX_DRAWOBJ1,0

//need this for right time, must be with showscreen GlobalTimer=GETTIMER()SHOWSCREEN// Display them on the screenWEND

I altered your code so that the program can run full speed.The difference is, i stored gettimer() value to time the ocean.To use gettimer, you must have the gettimer right before showscreen,AND sleep 1, MUST be right after showscreen.If you dont take these steps, then the ocean will "jitter", as gettimer has some bug if you dont sleep 1 millisecond after showscreen.I use the gettimer value inside the update function.A second parameter to the function is added to set the milliseconds per frame.This allows you to set the time for only the ocean, while the whole program can run max speed.

Hemlos, I've updated my code to reflect your changes and fix a small bug yours had. You were updating the animation frame once every game loop, but only drawing whatever frame was current after the timer delay (which meant frames were getting missed). I've fixed it so AnimationFrame only advances when the timer delay has passed (ie. when timer=0 from your code)

I am trying the Ocean Surface and am getting only 4 FPS (in the best condition).I read in the topic of 3300 FPS!!!!Is there something wrong on my computer or 3300 is exhausted?I miss something?Someone can try?Thank you