[Solved] How to lay something on the terrain?

I am trying to lay something like a stone on the terrain.

For example if the terrain goes down to a see, than the stone should also lay down to the see.

I am trying that in the following way:

Vector3f normalVector = terrainQuad.getNormal(axis);
tempModel.rotateUpTo(normalVector);

or

Vector3f normalVector = terrainQuad.getNormal(axis);
tempModel.lookAt(normalVector, Vector3f.UNIT_Y);

Both ways are not woking.
Am i doing something wrong? Is it a knowledge problem?

What i recognized so far is, that the getNormal method of the terrainQuad returns a vector between 0 and 1.
So i guess, i have to calculate that vector in some way to make it useable by the lookAt or rotateUptTo method.
But how do i do this?

I hope your know what i mean. If not please let me know.

Thanks for your help!

Not working how? Rotating strangely or not at all?

This doesn’t really make sense. A vector is 3 values. Do you mean that those values are between 0 and 1? Do you know what a normal vector is?

First, thanks for the fast answer!

All the meshes are rotated in the same direction. And that is wrong.

Yes, that is exactly what i mean.

A normal surface vector is a vector that stands 90° to a surface as far as i know.
That is the reason why i wanted to get the normal vector of the point of the terrain and to align the stone on that vector.

But maybe i miss the point that i need a vector that represents the up vector of the stone so the stone can be aligned on the terrain normal surface vector. That came to my mind, while i am writing these lines.
Am i on the right way or completly mistaken?

Not sure about the rotation issue, but you should multiply the value of your terrain by the terrain height multiplier. If for example your terrain height is 128, multiply it by that.

Well, a normal vector is a direction vector… unit length… so of course the values will be between 0 and +/-1. That’s why I asked.

Step 1: print out the normals to see if they are actually what is to be expected… ie: that they are different. I guess you are already doing this.

Else rotateUp() should work. You can verify that it’s doing its job by seeing what the result of getLocalRotation().mult(Vector3f.UNIT_Y) is… should be the same as the normal after the call.

Now i have it working!
Thanks very much at all helpers!

The problem was as follows:

Non working code:

final Vector3f normalVector = terrainQuad.getNormal(axis);

sa.enqueue(new Callable<Spatial>() {
                        @Override
                        public Spatial call() throws Exception {
                            tempModel.rotateUpTo(normalVector);

                            decorNode.attachChild(tempModel);
                            return tempModel;
                        }
});

Working code:

sa.enqueue(new Callable<Spatial>() {
                            @Override
                            public Spatial call() throws Exception {
                                Vector3f normalVector = terrainQuad.getNormal(axis);
                                tempModel.rotateUpTo(normalVector);
    
                                decorNode.attachChild(tempModel);
                                return tempModel;
                            }
    });

It seems that if i transport the value of the Vector by the final keyword, there goes something wrong.
Has anybody an idea why this is happen?

Yeah, the same instance will be used for every callable you create in that case… ie: they will share the same values.

Ok, thanks. Now i know what to think on in the future :smile: