Advertisement Jump to content
Sign in to follow this  

Shearing and rotating a mesh on its local axes.

This topic is 4897 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

With my create cube functionality, I put in the ability to translate, scale and rotate it on its local axis. However, when I scale on the Z-axis and I rotate on the x-axis my mesh exhibits shearing. (Fig. 1) Shouldn't it look like this (I cheated and set the orientation after the model had been created, I don't know if it'd be exactly like this or not)? (Fig. 2) The shearing doesn't appear to happen on any of the other axes. The cube is composed of 6 single plane meshes, oriented to face the proper directions. The code I use to create them is as follows:
private void BuildPlane(Vector3D up,Vector3D normal,int vertexstart,Vector3D[] vertices)
	int row;											// Current row.
	int column;											// Current column.
	float divh, divv;									// Divisions per column/row.
	Matrix pos, rot, scl, final;						// Matrix for each transform.
	Vector3D vx,vy,vz;									// Vectors representing axes.
	int vtxIdx;											// Vertex index.

	// Calculate number of divisions.
	divh = 1.0f / (float)boxColumns;
	divv = 1.0f / (float)boxRows;

	// Begin transforms.
	final = pos = rot = scl = Matrix.Identity;
	vz = normal;
	vy = up;
    vx = vy.CrossProduct(vz);
	if (vx.Length == 0)
		throw new GorgonException(ErrorCodes.NormalParallel,"The up vector is parallel to the normal vector, cannot create face.");

	// Rotate.
	// Translate.
	pos.Translate(primPosition + (normal * -0.5f));
	// Scale.
	// Finalize.
	final = scl * pos * rot;

	// Build the actual plane.			
	vtxIdx = vertexstart;
	for (row = 0; row < boxRows+1; row++)
		for (column = 0; column < boxColumns+1; column++)				
			// Center to origin.
			vertices[vtxIdx].X = ((column * divh) - 0.5f);
			vertices[vtxIdx].Y = ((row * divv) - 0.5f);
			vertices[vtxIdx].Z = 0;//(normal * -0.5f);
			// Transform.
			vertices[vtxIdx] = final * vertices[vtxIdx];

Where 'up' and 'normal' are derived as follows:
	case BoxFaces.Front:
		up = Vector3D.UnitY;
		normal = -Vector3D.UnitZ;
	case BoxFaces.Bottom:
		up = -Vector3D.UnitZ;
		normal = -Vector3D.UnitY;
	case BoxFaces.Back:
		up = Vector3D.UnitY;
		normal = Vector3D.UnitZ;
	case BoxFaces.Left:
		up = Vector3D.UnitY;
		normal = -Vector3D.UnitX;
	case BoxFaces.Right:
		up = Vector3D.UnitY;
		normal = Vector3D.UnitX;
	case BoxFaces.Top:
		up = Vector3D.UnitZ;
		normal = Vector3D.UnitY;

// Calculate rotation.
up = primOrientation * up;
normal = primOrientation * normal;

I'm really not sure how to fix this, can anyone help?

Share this post

Link to post
Share on other sites
I only glanced through the code, but I'll just say, make sure you're applying the transformations in the order scale->rotate->translate (I'm assuming that's what you want). For row vectors (D3D style), you have:

v' = v*S*R*T

Column vectors (OpenGL style):

v' = T*R*S*v

Share this post

Link to post
Share on other sites
Hey thanks for replying.

I managed to figure it out. And the end result is I'm dumb and wasn't thinking clearly. The problem was that I was applying the transforms to each of the cube faces. So, in reality, it was transforming each face, and doing exactly what it was supposed to do: rotate around the local axis of each face (while correct, not what I wanted/expected). I should have applied the transformations to all the vertices of the cube at once, then it would have rotated around the local axis of the cube, which is what I wanted, and having corrected this the problem went away.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!