Jump to content
  • Advertisement
Sign in to follow this  
Tape_Worm

Shearing and rotating a mesh on its local axes.

This topic is 4831 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;
	vz.Normalize();
	vy = up;
	vy.Normalize();
    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.
	rot.FromAxes(vx,vy,vz);
	// Translate.
	pos.Translate(primPosition + (normal * -0.5f));
	// Scale.
	scl.Scale(primScale);
	// 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];

			vtxIdx++;
		}
	}
}
Where 'up' and 'normal' are derived as follows:
switch(face)
{
	case BoxFaces.Front:
		up = Vector3D.UnitY;
		normal = -Vector3D.UnitZ;
		break;
	case BoxFaces.Bottom:
		up = -Vector3D.UnitZ;
		normal = -Vector3D.UnitY;
		break;
	case BoxFaces.Back:
		up = Vector3D.UnitY;
		normal = Vector3D.UnitZ;
		break;
	case BoxFaces.Left:
		up = Vector3D.UnitY;
		normal = -Vector3D.UnitX;
		break;
	case BoxFaces.Right:
		up = Vector3D.UnitY;
		normal = Vector3D.UnitX;
		break;
	case BoxFaces.Top:
		up = Vector3D.UnitZ;
		normal = Vector3D.UnitY;
		break;
}

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

BuildPlane(up,normal,vtxStart,vec);				
I'm really not sure how to fix this, can anyone help?

Share this post


Link to post
Share on other sites
Advertisement
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 GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!