Painting the terrain dynamically?

Hi!



The only info I am finding is from 3 years ago or older.

I saw the way we can paint in the JMonkey SDK Alpha4.

But I want to do that while the game is running!



I couldnt find any terrain painting code on the engine, so I think it is not there yet, only on the SDK.

Will it be moved to the engine?



Any tips?



thx!

i guess one way is to have an object or sorts, a cube or sphere and as it you drag it along the terrain it intersects and gets all x,z, coordinates and you colour that into a bufferedimage splat with a red,green or blue, so say for example you select a road sphere in game you drag this sphere around 0,0 (x,z) to 10,10 while its being draged you acquire all the terrain x,z do some calculation to convert them to image coordinates (so 0,0 x,z on terrain is assumed center so 256,256 on a 512 size image) and set the pixel on the splat bufferedimage to either a red(lets say thats the one for road), green (dirt), or blue (rock),

and then just update the material texture to this splat bufferedimage.

far as im aware you can only have 3 textures to a material so your limited to that, unless you come up with some ingenius way to change it, you must also preset the colour to texture info, i.e.

[java]

Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");

grass.setWrap(WrapMode.Repeat);

mat_terrain.setTexture("m_Tex1", grass); == red pixels on your splat

mat_terrain.setFloat("m_Tex1Scale", 64f);

/** 1.3) Add DIRT texture into the green layer (m_Tex2) /

Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");

dirt.setWrap(WrapMode.Repeat); == green pixels on your splat

mat_terrain.setTexture("m_Tex2", dirt);

mat_terrain.setFloat("m_Tex2Scale", 32f);

/
* 1.4) Add ROAD texture into the blue layer (m_Tex3) */

Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");

rock.setWrap(WrapMode.Repeat); etc etc

mat_terrain.setTexture("m_Tex3", rock);

mat_terrain.setFloat("m_Tex3Scale", 128f);

[/java]

i hope i was clear enough as i just woke up i imagine alot of english mistakes, also this is just something i thought up so might not be the best method in terms of performance but i know it would work as ive changed round dirt/road dynamically in game by just material.setTexture

Do you want to do something like that ?



http://www.youtube.com/watch?v=pbzqzmhALiU

wow thats nice, is there code available for that ? i imagine its similar to how terrain editor works in sdk

yes there is code that does that, it is in the SDK in TerrainEditorController.doPaintTexture(int selectedTextureIndex, Vector3f markerLocation, float toolRadius, float toolWeight)



it takes the index of the texture, where to paint, the radius of the paint area, and how heavy to apply the paint)

1 Like

Thx @Sploreg!



I got the TerrainEditorController.java (and the whole SDK) from the SVN.

I had to add a few libraries (openide etc) to make it work (I am on eclipse).

I made a few changes to that class to make it independent from the missing libs.

And it worked on JME3 !! (dont need to supply all libs. if some code are broken but not being used, it wont cause trouble!)

.

One trouble I am having is that the weight of the painting tool, is too weak, so I have to apply it 10 times in a loop to fully paint it on the ground, what I think is very CPU consuming, so I am willing to put it on a thread (now that I learned how to create threads properly :D)

.

Another is that when terrain textures change, it seems to affect other objects textures (So I will try to make those for the terrain, a copy on another path). But, it is affecting also the plain colors from ColorRGBA, a solid color Black transparent geometry sometimes get white, other times red, or even completely transparent. As I am still making many random tests I couldnt trace a pattern to understand its source.

.

Anyway, It works very well, and I think even if it does not get coded in the core engine, it could be isolated to be easly attached to other applications as an addon!



@stomrage,

yep, its like that!!



@ryuu,

actually the code from SDK supports 4 textures! (or completely black if you “erase” them all, what may count as a 5th!)

it seems to mix all them, and the painting happens on the alpha channel (showing more or less of each texture).

also, it seems to have AlphaMap_1 and AlphaMap_2 on the Material Definitions, but it is not supported on the SDK yet, so I dont know how to use it.

you should take a look on it!

The paint weight is low because it is intended to be used by a human-controlled brush in the editor. You can play with the toolWeight parameter to increase/decrease its effect.



The terrain paint tool paints to the alpha maps. So if something else is using them, the it will be affected too. If it is not that, then something bizzare is going on with your code.



As for the multiple alpha maps and more textures beyond 4, I am working on that right now :slight_smile:

Huhu more than 4 textures. I am looking forward to trying! :stuck_out_tongue:

@teique I’ve totally rewrite the terrain system and it’s must be the wrong way to do it. However, I can give you my project to see how I create the texture edition.

The tool weight says, from 0 to 1, I tried to put 10, and it didnt change, worked like 1; so my guess is I can change the way that value is used after doPaintTexture(), will look at it thx :slight_smile:



When I start the application, the grass texture is red (not green); when I do the paints with grass on terrain, it gets more green, even if I use another copy in another path for that texture. But I changed its name to grass2.jpg, and it now seems to be working properly. I think it reuses the textures by name even if on different paths? anyway I renamed the copies all to ex. TERRAIN_grass.jpg



Another thing I found is that the solid black geometry, I had to use ColorRGBA.Black.clone() instead of without clone(), and it fixed also!, it seems that we can change the original ColorRGBA.Black values (and all others), they seem not final.



At last, there seems to be having also some lighting conflict, as the Pond material, and some others that have specular I think become too lightened after that BombControl.java explosion effect happens. I am not sure if it happened b4 painting the terrain. Must do more tests.



I think those texture copies were using the alpha maps even if I have not directly coded them to do it. I will see if I can create a test case for that!



Great! will work great to add snow, earth, sand etc etc thx! :smiley:



Btw, I thought if the textures on terrain could be animated, and they can by changing the texture by another, it promptly changes on the terrain! and dont seem to be CPU costly, great!

teique said:
I think it reuses the textures by name even if on different paths?

Not if you are using the asset manager to load the textures. If they are on different paths they are different textures.

Do you have a screenshot of what is going on?

Keep up the good experimentation @teique

@stomrage

have you coded caves? or some kind of easly modifiable ceiling to use in the terrain? :smiley:

teique said:
@stomrage
have you coded caves? or some kind of easly modifiable ceiling to use in the terrain? :D

Heh, interesting idea. Simply by using two terrains and making the upper ones material dual-sided (material.getAdditionalRenderStates().setFaceCullMode()) you should be able to try around with that.
1 Like

@normen,

worked great!!



I believe a few small TerrainQuad can be used to compose even a cavern with a few floors above each other. At first I thought that would be too much trouble but at that time I was thinking on rotating the terrain :)… thru face culling seems much easier thx!



Btw, I believe two TerrainQuad could be attached one above another, with its edges joined, so modifications to one affect another; but to cope with that, we would need to be able to create holes in the terrain quad, is that possible? (so when heights match the other terrainquad, a hole would appear; I mean a hole that has physics, not simple face cull). I tried to rotate the terrain anyway, even putting it on a node and rotating the node, but nothing happened.





@Sploreg



I use the same asset manager from SimpleApplication, everywhere.



For the round object on floor, I used this texture:

“Textures/Terrain/splat/grass.jpg” and I ignore the normal image and etc… use just this.



For the rectangular one I used this only:

“Textures/Terrain/splat/road.jpg”.



For painting the terrain I used these ones:

“Textures/terrain-textures/TERRAIN_grass.jpg” (identical copy of grass.jpg)

“Textures/terrain-textures/TERRAIN_grass_normal.png” (idem)



when I move the player around, it “erases” the paint on floor below him, for 1.0f weight on doPaintTexture(). If I put that on a 10 loop, it would erase it all and the textures wouldnt have these color problems; because of that I thought the problem was gone; I do many changes at a time, sometimes…



When I step over the painted grass (it is erased a bit), it tints both geometries with green tint, dont know why…

http://i.imgur.com/AaIuX.png



When I step outside it removes the green component :open_mouth: (it is erasing the other default terrain texture “Textures/terrain-textures/TERRAIN_BrickWall.jpg” btw, but the grass is already completely erased at the new spot it is stepping over, I think that is the reason to loose all green tint; I think this default texture have no green tint!).

http://i.imgur.com/2rJ44.png

The code seems to be affecting the base color of all textures :O.



PS.: my texture choices are what came with JME3 :slight_smile:



PS.: to upload images, the other day I the browser navigated away from this forum! :O, good I only use chrome, so I didnt loose what I have typed :), now I open in a tab.



PS.: btw the round object has a capsule collider scaled, I still have no idea how to make a conical colision shape tho :/, even if I can create a conical geometry for it…