using a normalvector of a Terrain

I have a very simple question:
I am making a car game. I need to orient the car to align with the terrain. I am using a Collision Ray to get a Collision Entry. From that entry I get a surface normal and a surface point. How do I use the normal? Is there a simple way of making the Z axis of the car face the same direction as the Normal?

Well the tough part is that its trigonometry. One thing you might try is to solve for the two angles you need, which you can find various solutions on the web.

Start with trying to deduce the pitch you need on the car.

Make sure the normal is relative to the car, then take Vec2(y,z) , and dot it against Vec2(0,1). This will put the problem in 2d space.

From there you can use math.acos to get a non-signed solution in radians.

The sign can be determined by looking at how the cross product between Vec3(0,y,z) and Vec3(0,0,1) reacts to the orientation of the vector)

Thanks zpavlov,
I am working on this game with Frodi. I am not sure i understand your answer though.
The method that we are using now is to get the new vector for the direction of the car as follows: We cross the current direction vector with the normal of the face to get a new vector. This vector is in the plane of the collision face, but perpendicular to the travel direction (heading). We then cross this vector with the normal to get a vector with the same heading as the first direction vector but in the plane of the face.
The way we get the vector for the direction of the car is by having a dummy node parented to the car (tractor) and positioned (1,0,0) from it. Then when the car rotates we can get it´s relative position to the car, which is it´s direction.
The trouble is how to rotate the car. I admit our trigonometry skills are not that great. Some code:


...

dummyNode = render.attachNewNode("Dummy")
dummyNode.reparentTo(tractor.returnModel())
dummyNode.setPos(1,0,0)

...

    for i in range (cHandler.getNumEntries()):
        entry = cHandler.getEntry(i)
        if i == 0: #closest object
            colPoint = entry.getSurfacePoint(render)
            colNormal = entry.getSurfaceNormal(render)
            temp = colNormal.cross(dummyNode.getPos())
            temp = temp.cross(colNormal)

...

The temp vector should be the new direction for the car.

sounds great! One thing to beware of is that your dummyNode will always return Vec3(1,0,0). If you want to get the forward vector, use


dummyNode.getPos(render)-tractor.getPos(render)

This would probably be wise, since your surface normal is with respect to render.

Anywho, as long as the car isn’t pointing straight up, you can call:


tractor.lookAt(Point3(tractor.getPos(render)+temp))

Thank you for your help. the game is finished and will be available on the web soon!

Is it possible to post it in the showcase forum with code, models, … or make a little website for it.
I think this would be helpfull for many users here to see another example