Dynamic alphamap for terrain texture splatting

Hi

I’m completely new to JME, so hopefully someone is going to help we with my question.



The game I’m about to design should feature some basic terraforming possibility. Not a mature ‘level editor’, but just the possibilities to ‘create hills and valleys’ in-game. So I should have some kind of modifiable terrain… I guess this might work by using a variable RawHeightMap as my terrain and then do some mouse picking. But the problem will come with texture splatting. In contrast to the heightmap, there seems to be no “dynamic” alpha map, just an image based map. This problem is even elaborated in the basic “Hello Terrain” tutorial (http://www.hub.jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_terrain), as it applies for using the “HillHeightMap”, too. So I guess I’m not the only one having this problem, but sadly I didn’t find any solution on the Internet or on your forums.

To clarify my intensions, I don’t want to provide any “texture painting” on my terrain, but rather the possibility to define something like: At terrain height x, use sand texture, at terrain height y, use grass texture, above that use rock texture, and then let the user rise and lower the terrain.

I’ve come up with a couple of ideas:

a. Construct an “Image” object (used by the Texture class) out of byte[] (would have to find out the byte format by try-and-error)

b. The TerraMonkey editor seems to use a similar thing itself. So download its source and analyze it. (Is the source code available somewhere, by the way?)

c. Create an Image file dynamically, store it to the hard disc, load it back, change it, store it… (I don’t think this will be a good idea)

d. In JME2, there was obviously a ProceduralTextureGenerator class that seemed to do exactly the job I’m looking for, but sadly, it’s gone. So reverse-engineering it, but I suspect it doesn’t work anymore with the architecture of JME3.



Did I miss something? Which way should I go? Did somebody already find a solution to this problem?

Thank you in advance for any help.

-I don’t want to provide any “texture painting”
-Create an Image file dynamically, store it to the hard disc, load it back, change it, store it…

Pls choose one of these things....

a. Construct an “Image” object (used by the Texture class) out of byte[]

[java] private Image generateImage(int width, int height)
{
ByteBuffer bb =ByteBuffer.allocateDirect(width*height*4);

for(int i=0;i<width*height*4;i++)
{
bb.position( i );
bb.put(float2byte(1)); //your values
}
bb.rewind();

return new Image(Image.Format.RGBA8,width,height,bb);
}

private byte float2byte(float f){
return (byte) (f * 255f);
}[/java]

ogerlord,

thank you very much. It works like a charm!



I did just add some utility code for testing which allows to create an alpha map by providing some simple RBGA values. Maybe this is useful for anyone else.



[java]

public static Image generateImage(int width, int height, ColorRGBA[] rgbList) {

ByteBuffer bb = ByteBuffer.allocateDirect(width * height * 4);

fillBuffer(bb, getRgb(rgbList));



return new Image(Image.Format.RGBA8, width, height, bb);

}



private static void fillBuffer(ByteBuffer bb, float[][] rgbList) {

int bufferPos = 0;

for (int i = 0; i < rgbList.length; i++) {

addToBuffer(bb, bufferPos, rgbList);

bufferPos+=4;

}

bb.rewind();

}



private static void addToBuffer(ByteBuffer bb, int startPos, float[] rgb) {

for (int i = 0; i < rgb.length; i++) {

bb.position(startPos+ i);

bb.put(float2byte(rgb));

}

}



private static float[][] getRgb(ColorRGBA[] colors) {

float[][] ret = new float[colors.length][];

for (int i = 0; i < colors.length; i++) {

ret = getRgb(colors);

}

return ret;

}



private static float[] getRgb(ColorRGBA color) {

return new float[]{color.r, color.g, color.b, color.a};

}

[/java]



So in order to create a 5x5 test alphamap:



[java]

ColorRGBA red = ColorRGBA.Red;

ColorRGBA blu = ColorRGBA.Blue;

ColorRGBA grn = ColorRGBA.Green;



ColorRGBA[] rgbList = new ColorRGBA[]{

red, red, red, red, red,

red, red, red, red, red,

blu, blu, blu, blu, blu,

grn, grn, grn, grn, grn,

grn, grn, grn, grn, grn

};

Image alphaImage = TerrainTextureGenerator.generateImage(5, 5, rgbList);

[/java]



Next, I will implement a truly “dynamic” TextureGenerator (creates an alpha map based on the heightmap). Thank you again!