Please log in or register to post a reply.

@elijah

Ok got you.

So if you have two unit vectors; your normal and the Z of the tank, you can get the cos of the angle between them by taking the dot product of the two vectors. So the acos of that then gives you the angle you need to rotate your tank by. Then if you take the cross product of the same two vectors and normalize the result you will get a unit vector axis that you can rotate your tank around by the aforementioned angle.

Then you can build a matrix to rotate your tank. Here is some crappy C++ code I wrote for that. Note that a) I am working left hand cooridnates b) I left off the last column of the matrix to save a bit of calculation. (I assume it to be 0,0,0,1 going down) and c) you will still have to multiply in the translation matrix to put your tank in the correct location on the hill. Read Reedbeta’s link for an overview.

```
template<class T> void TRPG3DMatrix<T>::Set(const TRPGVector<T> &clAx, T fTheta, CRPG3DAxisRotate &clType)
{
m_pType = &clType;
T c = cos(fTheta);
T s = sin(fTheta);
T t = 1.0-c;
T fX = clAx.X();
T fY = clAx.Y();
T fZ = clAx.Z();
m_a.D[0][0]= t*fX*fX + c; m_a.D[0][1]= t*fX*fY - s*fZ; m_a.D[0][2]= t*fX*fZ + s*fY;
m_a.D[1][0]= t*fX*fY + s*fZ; m_a.D[1][1]= t*fY*fY + c; m_a.D[1][2]= t*fY*fZ - s*fX;
m_a.D[2][0]= t*fX*fZ + s*fY; m_a.D[2][1]= t*fY*fZ + s*fX; m_a.D[2][2]= t*fZ*fZ + c;
m_a.D[3][0]= 0; m_a.D[3][1]= 0; m_a.D[3][2]= 0;
}
```

Hope that helps

If you have a fuzzy front, then make the up the normal of the triangle, cross to get the right, normalize the right (very important) then recross to get the real front.

just point the fuzzy front flat in the direction you generally want the tank to go in.

And that should work too - just dont expect it to go straight up a horizontal(vertical i mean) cliff, because thats the weakness with this method. :)

And as I guess you know, thats a valid basis for the models orientation, which is what you wanted.

Hi SyntaxError,

I have tried your recommendation. It works for most cases. I did this test on a cylinder. half of the body that is facing back gives the correct axis, but the front body of the cylinder gives the wrong axis. Any ideal how I can solved this ? This cylinder is cull back design.

I invented it sorry :). I mean point on the xz plane where you want the tank to “point” as if it was on flat ground.

then if you double cross and normalize like that youll “tilt” the tank onto a slanted ground but itll still have its turret pointing in the direction you want it.

@elijah

Now I’m confused again. You are using your cylinder as your tank or the cylinder as your terrain? You should be transforming your entire tank by the same matrix so if it’s wrong the whole thing should be wrong.

In any case if you are using a cylinder as your terrain, you need to make sure you are getting the correct surface normals. I’m not sure how you are storing your data but in a mesh edges can’t all be directed in one winding. If you draw out a mesh on a piece of paper you will notice you can’t make your triangles all one winding. Therefore you need to be able to somehow get the correct winding so you can get the correct normals. Perhaps that’s your problem. What mesh format are you using? Is it your own?

The other thing is there are special cases where your tank is already aligned with the terrain or exactly opposite the terrain. In those cases you can’t use cross product because it won’t give you an axis vector. Just add in a couple special cases for that.

Finally you still need to point your tank in the right direction. You can do that rotating around Z before you transform you tank to the terrain.

Actually I’m using the cylinder as a test case. When I press on the face of the triangle that made up the cylinder, the Z - Axis will point to the normal of the triangle.

The normal is calculate from the 3 points in the triangle. The code is below

public static Vector3f getTriangleNormal(Point3f p1, Point3f p2, Point3f
p3) {

Vector3f Normal, AB, AC;

AB = new Vector3f(p1);

AB.sub(p2);

AC = new Vector3f(p1);

AC.sub(p3);

Normal = AB.cross(AB, AC);

Normal.normalize();

if (Normal.getX() == -0.0f) { Normal.setX(0.0f); }

if (Normal.getY() == -0.0f) { Normal.setY(0.0f); }

if (Normal.getZ() == -0.0f) { Normal.setZ(0.0f); }

return Normal;

}

public Transform3D getTransform3D(){

Vector3f INVERSE_NORMAL = NORMAL.clone();

TRANSFORM_3D_AXIS = new Transform3D();

float Angle_Value = gcMaths.VectorDotProduct( INVERSE_NORMAL, Vector3f.POSITIVE_Z_AXIS );

float angle = FastMath.acos( Angle_Value );

//AXIS_VECTOR = gcMaths.VectorCrossProduct( INVERSE_NORMAL , Vector3f.POSITIVE_Z_AXIS );

AXIS_VECTOR = gcMaths.VectorCrossProduct( Vector3f.POSITIVE_Z_AXIS , INVERSE_NORMAL );

AXIS_VECTOR.normalize();

AXIS_ANGLE = new AxisAngle3f( AXIS_VECTOR, angle );

matrix = new Matrix4f();

matrix.set( AXIS_ANGLE );

TRANSFORM_3D_AXIS.set( matrix );

NAN_CASE = CheckNAN.checkTransform3D( TRANSFORM_3D_AXIS );

TRANSFORM_3D_AXIS = NegativeZeroCleanup.cleanTransform3D( TRANSFORM_3D_AXIS.getCopy() );

TRANSFORM_3D_AXIS = NANCleanup.cleanTransform3D( TRANSFORM_3D_AXIS.getCopy() );

return TRANSFORM_3D_AXIS;

}

Just think like a 3D cad drawing. Clicking on the surface of the object, the axis will point towards the normal of the face.

Hope you can help me on this.

@elijah

public static Vector3f getTriangleNormal(Point3f p1, Point3f p2, Point3f p3)

I’m not entirely familiar with the package you are using however one thing I would like to point out is the ordering of your points is important for normal calculation. This is called winding. For instance is p1, p2 p3 clockwise looking from the front of your triangle or counterclockwise? If you can’t guarantee it’s always the same your normals will be inverted sometimes.

@elijah

Just think like a 3D cad drawing. Clicking on the surface of the object, the axis will point towards the normal of the face.

Great…however CAD programs work in a particular winding. You need to choose one and enforce it. I use clockwise myself but it’s up to you.

- Upcoming Multiplatform Game Program...
- Our first game - looking for feedbacks
- Network Emulation Tool
- Trouble with accessing GLSL array
- Fiction
- Game Programming Patterns: Bytecode
- Interactive WebGL Water Demo
- Skeletal Animation Tutorial with GP...
- Unreal Engine 4
- Microsoft xbox one selling poorly

Hi

I am a new to graphic programming. I manage to get the surface normal of a triangle. Now I want to rotate an axis using right hand rule. How do you go about doing this ?

God Bless

Eng Huat