mirror of
https://github.com/fadden/6502bench.git
synced 2026-04-25 05:22:03 +00:00
Switch to left-handed coordinate system
There's no "standard" coordinate system, so the choice is arbitrary. However, an examination of the Transporter mesh in Elite revealed that the mesh was designed for a left-handed coordinate system. We can compensate for that trivially in the Elite visualizer, but we might as well match what they're doing. (The only change required in the code is a couple of sign changes on the Z coordinate, and an update to the rotation matrix.) This also downsizes Matrix44 to Matrix33, exposes the rotation mode enum, and adds a left-handed ZYX rotation mode. This does mean that meshes that put the front at +Z will show their backsides initially, since we're now oriented as if we're flying the ships rather than facing them. I considered adding a 180-degree Y rotation (with a tweak to the rotation matrix handedness to correct the first rotation axis) to have them facing by default, but figured that might be confusing since +Z is supposed to be away. Anybody who really wants it to be the other way can trivially flip the coordinates in their visualizer (negate xc/zc). The Z coordinates in the visualization test project were flipped so that the design is still facing the viewer at rotation (0,0,0).
This commit is contained in:
@@ -246,8 +246,18 @@ namespace SourceGen {
|
||||
scale = (scale * zadj) / (zadj + 0.3);
|
||||
}
|
||||
|
||||
Matrix44 rotMat = new Matrix44();
|
||||
rotMat.SetRotationEuler(eulerX, eulerY, eulerZ);
|
||||
// In a left-handed coordinate system, +Z is away from the viewer. The
|
||||
// visualizer expects a left-handed system with the "nose" aimed toward +Z,
|
||||
// which leaves us looking at the back end of things. We can add a 180 degree
|
||||
// rotation about Y so we're looking at the front instead, though this
|
||||
// effectively reverses the direction of rotation about X. We can compensate
|
||||
// for it by reversing the handedness of the X rotation.
|
||||
//eulerY = (eulerY + 180) % 360;
|
||||
|
||||
// Form rotation matrix.
|
||||
Matrix33 rotMat = new Matrix33();
|
||||
rotMat.SetRotationEuler(eulerX, eulerY, eulerZ, Matrix33.RotMode.ZYX_LLL);
|
||||
//Debug.WriteLine("ROT: " + rotMat);
|
||||
|
||||
if (doBfc) {
|
||||
// Mark faces as visible or not. This is determined with the surface normal,
|
||||
@@ -264,9 +274,9 @@ namespace SourceGen {
|
||||
face.IsVisible = true;
|
||||
continue;
|
||||
}
|
||||
Vector3 camVec = rotMat.Multiply(face.Vert.Vec);
|
||||
Vector3 camVec = rotMat.Multiply(face.Vert.Vec); // transform
|
||||
camVec = camVec.Multiply(-scale); // scale to [-1,1] and negate to get -C
|
||||
camVec = camVec.Add(new Vector3(0, 0, zadj)); // translate
|
||||
camVec = camVec.Add(new Vector3(0, 0, -zadj)); // translate
|
||||
|
||||
// Now compute the dot product of the camera vector.
|
||||
double dot = Vector3.Dot(camVec, rotNorm);
|
||||
@@ -278,7 +288,7 @@ namespace SourceGen {
|
||||
// For orthographic projection, the camera is essentially looking
|
||||
// down the Z axis at every X,Y, so we can trivially check the
|
||||
// value of Z in the transformed normal.
|
||||
face.IsVisible = (rotNorm.Z >= 0);
|
||||
face.IsVisible = (rotNorm.Z <= 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -300,9 +310,9 @@ namespace SourceGen {
|
||||
double x0, y0, x1, y1;
|
||||
|
||||
if (doPersp) {
|
||||
// +Z on the shape is closer to the viewer, so we negate it here
|
||||
double z0 = -trv0.Z * scale;
|
||||
double z1 = -trv1.Z * scale;
|
||||
// Left-handed system, so +Z is away from viewer.
|
||||
double z0 = trv0.Z * scale;
|
||||
double z1 = trv1.Z * scale;
|
||||
x0 = (trv0.X * scale * zadj) / (zadj + z0);
|
||||
y0 = (trv0.Y * scale * zadj) / (zadj + z0);
|
||||
x1 = (trv1.X * scale * zadj) / (zadj + z1);
|
||||
|
||||
Reference in New Issue
Block a user