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.

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 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 on other sites

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.

• What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 10
• 11
• 13
• 9
• 11
• Forum Statistics

• Total Topics
634091
• Total Posts
3015433
×