Selecting a part of a terrain using a square selector

Hi there. I just began to use JME3 a few days before. I am trying to build a game in which a player can mimic a land manager. One of the most fundamental behaviors that a player can conduct is to select a piece of land and grow something like crops. I have tried a lot of methods and read carefully the Javadoc about Texture, Geometry, Mesh, etc., but in vain.

but what you need exactly?

modify terrain height in square?
modify terrain texture in square?
place something on terrain in that area?
(grow crops can be done multiple ways depend on game)

i have grass lib, and detail plotter lib (for example leaves on terrain arround tree) so everything is possible, but need to know how it need look for your game to suggest you solution.

very simple solution 1:
you use some grass lib, but replace grass with crop.

then check in “crop” terrain textureMap if there is “crop” and how much(texture color)
if there is, you can “collect crop” and lower texture color (so there will be less crop because of collect)

solution 2:
make custom lib for crop, and make it like in Farming Simulator so its like “game objects” but in library memory. Populate them in areas(that have for example 10x10 or 100x50 / etc map) also and when there is “collect crop” made, just update and remove ones that were collected. For “crop” Y(height) position just check terrain height in that location. (remember to have 1 geometry per Crop area)

there are more solutions ofc.

Appreciate your help very much. My problem is how to select a specific area on irregular terrain. Please see the snapshot. I tried a method to make a green square to select an area, and the square should adapt automatically to the terrain’s irregular shape. I tried to apply a square as a texture to the terrain. However, the texture covers the whole landscape instead a portion of the landscape. So, I am wondering if there is a way to just let the texture cover a small part of the landscape (e.g., the area that only one square covers as highlighted with a red square in the snapshot).

Do you mean like this

1 Like

Yes, thanks for showing the video. I want to do this while the game is running. So I can specify which part of the land to grow some vegetation.

I think what you should do is:
1: 3D Mouse Picking

2: Terrain Test Modify Height
focus on the following methods
getWorldIntersection(), adjustHeight(Vector3f loc, float radius, float height)

1 Like

Thank you so much! I will try these methods!

well,again there are multiple solutions. Your way is one, but it had lack of positioning/limiting of this.

I suppose what you are really searching for is Decal Projector. There are some libs for JME like for example recent one. Example video of decal projecting:

Recent project:

(but as mentioned for terrain it can be slow, so you might search other Decal projector or adjust it for terrain)

Also you might need “synchronize it” with area that really will be affected to grow crop.

Myself i just prefer Draw 3D visual tool for area, but also thought of using decal projector

2 Likes

Thanks for mentioning the Decal Projection method. Decal Projection is very interesting and more accurate, but I did not find any packages. I have used raycasting to realize the function I needed. I may implement the Decal method if i improve the game in the later stage.

Appreciate your advice very much. I have successfully implemented my ideas.

However, I find another problem when I tried to organize my code into different classes.

I created a class named “selector” but failed to access all the variables in SimpleApplication because they are all protected. I am wondering how a JMonkey project should be organized instead of writing all the code in the same subclass of SimpleApplication?

you can search for some repos in github, i found for example:

@yaRnMcDonuts can say if its about decal projecting, but seems like it is it.

2 Likes

This is very helpful! I will try it. Thanks!

yes I haven’t updated that repo in a long time but it should work still I think.

The other decal library you linked is likely better than mine for creating static decals for decorating a scene in the normal way you’d think of decals. I never implemented vertex-clipping to trim down the decal mesh to be smaller than the objects its being projected onto, so when you create a decal (or TextureEffect as its currently named) with my library, its really just cloning the geometries and terrains and discards all the pixels outside of the decals radius in the fragment shader.

So the main thing I focused on when making my decal library was the shader it uses to dynamically alter the decal at runtime for generating fancy effects on the ground that can fade in/out and grow/shrink smoothly, without having to regenerate the mesh everytime.

But that also ends up being good for making a movable selector brush for terrains, since the decal mesh doesn’t get regenerated everytime the brush moves. Here’s an old video I made that shows my decal system being used for selecting areas of a terrain to paint

2 Likes

To access the variables and the methods of SimpleApplication class you have two ways
1: Pass the class object to other classes you wanted.
2: Extend AbstractAppState which by default it passes it for you.

If you are making an app state you should extend BaseAppState instead of AbstractAppState. AbstractAppState really only exists for legacy/backwards compatibility reasons.

1 Like

Thank you
the funny thing I liked using it in all my tests after I learnt it from studying MonkeyTrap

1 Like

Could you please give an example that uses BaseAppState? I am trying to structure my game, but SimpleApplication only offers protected variables that cannot be used in another class. Thanks!

There are a bunch of examples here:

…and they will all use BaseAppState to some degree for various things including menu UIs, networking, game session, etc…

sim-eth-basic is the closest thing to a full game, it is a networked game where players can login and fly spaceships around in 3D.

Thanks. I found your answer to another question quite helpful to my current question:
https://hub.jmonkeyengine.org/t/howto-obtain-getting-rootnode-inside-appstate-or-game-state/16423
I passed the instance of Application to my own classes and cast the instance to SimpleApplication, then everything seems to be accessible in my own classes.

But if you make app states then you don’t have to do that.

Treat app states like composable services. They can easily access one another, etc…