Hi, I’m new in jMonkeyEngine and I need a help.
I want to make a program, where will be a water, after throwing an item I want to make wave after falling an item.
Where should I start, is here any libery which can help me with this? I saw “simple water” but I’m not sure about it, it seems to be like a unit “complex” and I’m sure about making new waves in it, is it possible or not?
Can anyone help me please?
I think you can do something similar using GLSL shaders,making it with java code it’s pretty unperformable.
How accurate do you want to be? Water simulation of this sort is non-trivial and there will always be tradeoffs depending on what you are actually trying to achieve. How big is the body of water? How big are the objects? How accurate must the ripples be? Will there be multiple sets of ripples at once?
None of the built in JME can handle this because there is no one-size solution.
The thing is, I want to make new waves after throwing an object in to water. It doesn’t matter how big object is, even I don’t want to make a hole after object, just new waves around object. Atm is 1 wave ok.
If you say so.
I think you will find that it very much DOES matter how big the object is in relation to the body of water, etc… no matter which approach you end up taking.
It’s still unclear whether you want actual geometry deformation or you just want to paint some texture in the shape of ripples. Either way, the size of the object will matter as it will control resolution and so on.
As I said before, this is kind of advanced stuff. It may be too advanced for your current skill level but it’s hard to tell for sure.
Well, I’m programing in Java for 4 years so it’s not problem, I just don’t know all the liberies here.
Anyway, I want to make “new texture, as you said” of wave.
Making a circular waves around of object, which will continue
(I know it’s advance math, but it’s ok).
I just don’t know if there is something, how can I make new texture of wave or I have to make it different way.
There is no built in way to do this. You will have to pick a starting point and add it yourself.
Ok, is there way to make one single way?
The approach I would use is to generate a normal map from the result of a ripple simulation. Then apply the normal map in the water shader locally.
Easier said than done though. You’ll have to find a cheap way to simulate the ripple. You may want to look into the “sombrero function”.
I guess that would be a start.
Thanks I going for it
…some time back, i was messing with similar thing, but i was altering waves (ripples) by changing height of vertices on water plane…maybe this can help you as it can produce nice ripples with various wave depths, but its sensitive on to number of tiles(vertices) your water surface mesh may have…around 100 x 100 tiles works very fast and its okay for most situations…i couldn’t find working file so i wrote it again, so forgive me for mistakes (im not sure am i changing vertices height properly)…other than that, code updating ripples is about right…
//some constants
//Vertices of loaded water patch
VertexBuffer vertices=my_water_patch_geometry.getMesh().getBuffer(VertexBuffer.Type.Position);
//These are wave map constants we will use to control waves
int currmap = 0;
int nextmap = 1;
//the higher this value the longer water will ripple
waterDampen = 60.0f;
//Our water plane tiles number along X and Y axes
//This can be any number..larger number, more processing time needed
int numTilesX = 100;
int numTilesY = 100;
//number of vertices along individual axes
int numVertsX = numTilesX+1;
int numVertsY = numTilesY+1;
int vertindex = 0;
//lets create our water wave map. This is where deformation update will happen as well as waves propagation
float[][][] waveMap = new float[2][numVertsX+1][numVertsY+1];
//Put this function somewhere inside update
Update_Water()
{
for(int countY=1;i<numVertsY+1;countY++)
{
for(int countX=1;i<numVertsX+1;countX++)
{
//calculate wave intensity for this point
float n = waveMap[currmap][countX-1][countY] + waveMap[currmap][countX+1][countY] + waveMap[currmap][countX][countY-1] + waveMap[currmap][countX][countY+1];
n = (n / 2) - waveMap[nextmap][countX][countY];
//dampen
n = n - ( n / waterDampen );
waveMap[nextmap][countX][countY] = n;
//set Point Height
vertindex = ((countY-1) * numVertsX) + countX;
//set height of corresponding vertex trough vertex buffer, im not sure about this..i really cant remember how i did it..i think its like this..
vertices.SetElementComponent(vertindex, 1, n);
}
}
//swap the wave maps
currmap = (currmap+1) % 2;
nextmap = (nextmap+1) % 2;
}
…now, if you want to simulate ripples, lets say, when you hit some key , do this…
Random ran;
ran = new Random();
int tileX = (0 + ran.nextInt(numTilesX + 1))+1;
ran = new Random();
int tileY = (0 + ran.nextInt(numTilesY + 1))+1;
//make ripples spreaded at random location
waveMap[currmap][tileX][tileY] = 10f;// <-increase this number to get deeper waves, decrease for less deep waves. Dont go negative numbers
…if you need ripple to start at specific location, just find out at which tile (X and Y) location, your object fall in to and use command previously posted…my apology for eventual errors…wave propagation function should be fine…im just not sure about way i was dealing with vertices, so do homework on that part…i hope this helps a bit…
Big heart , I like Keep it Simple approach you demonstrate and u still use GPU
My game may involve Lava, I think this approach can be useful in my case as well. I am expecting more challenges but I have a good hint
I think about using @Ecco code to generate the normal map or even a simple pump map , it could be even generated in separate thread instead of update. and apply it as per @nehon elaboration , instead of changing the vertices directly.
I am still new here, I am just asking is it will be more efficient or not ?
I preaty understand what is going on, just what is my_patch_geometry.getMesh(). ;
you are making wave man, but you don’t attach it anywhere. Do I have to use “simpleWater” and attach it in to rootNode?
In updateWater you have “vertices.SetElementComponent(vertindex, 1, n);” I know you wrote you don’t remember it, just what are you doing there? what should SetElemntComponent do?
thanks for your help man, it helps a lot @Ecco
…hi Sebastian…
‘my_water_patch_geometry’ is a spatial you load…probably prepare in blender or something else…basically, your water surface…you can create it on runtime as well…i just kept it simple…
numTilesX and int numTilesY directly depend on this patch you create manually in 3d modelling tool, so adjust that values based on that…
…with ‘vertices.SetElementComponent(vertindex, 1, n);’ , my intention was to move selected vertice along Y axis, so since wave will propagate, it will make effect of nice ripples which moving up/down, as waves does so its offseted along Y axis…
…ripples shoult travel trough entire water surface(if amplitude is large enough) and it will bounce back until rest…it will also interact with other ripples in case few ripples are generated (let say, you have hit some key twice or more times after each other )…
Ok, I will try, thanks
…this is a result you should get out of update function…
…now its time to sleep…1am …ugh. pajamas time…talk some other time guys…happy coding…
Sorry that I’m asking but I have a problem. @Ecco
private Spatial map =assetManager.loadModel(“Scenes/my_water_surface.j3o”);
VertexBuffer vertices = map.getMesh().getBuffer(VertexBuffer.Type.Position);
“getMesh()” where did you get this method? My jme3 can’t find this “symbol”
Please, can you tell me, where is the problem? Do I need any special plugins for this method?
Thanks
check the j3o in scene explorer you may need to cast it to geometry first
for example in this case
((Geometry) this.scene.getChild(“polySurface11”)).getMesh()