public static void Normalize(ref Vec3 v) { float len = v.X * v.X + v.Y * v.Y + v.Z * v.Z; Debug.Assert(len >= 0.0f); len = 1.0f / (float)Math.Sqrt(len); v.X *= len; v.Y *= len; v.Z *= len; }
public static int LongAxis(ref Vec3 v) { int i = 0; if (Math.Abs(v.Y) > Math.Abs(v.X)) i = 1; if (Math.Abs(v.Z) > Math.Abs(i == 0 ? v.X : v.Y)) i = 2; return i; }
public static void Dot(ref Vec3 u, ref Vec3 v, out float dot) { dot = u.X * v.X + u.Y * v.Y + u.Z * v.Z; }
public static void Neg(ref Vec3 v) { v.X = -v.X; v.Y = -v.Y; v.Z = -v.Z; }
public static void Sub(ref Vec3 lhs, ref Vec3 rhs, out Vec3 result) { result.X = lhs.X - rhs.X; result.Y = lhs.Y - rhs.Y; result.Z = lhs.Z - rhs.Z; }
public Tess() { _normal = Vec3.Zero; _bminX = _bminY = _bmaxX = _bmaxY = 0.0f; _windingRule = WindingRule.EvenOdd; _mesh = null; _vertices = null; _vertexCount = 0; _elements = null; _elementCount = 0; }
private void ComputeNormal(ref Vec3 norm) { var v = _mesh._vHead._next; var minVal = new float[3] { v._coords.X, v._coords.Y, v._coords.Z }; var minVert = new MeshUtils.Vertex[3] { v, v, v }; var maxVal = new float[3] { v._coords.X, v._coords.Y, v._coords.Z }; var maxVert = new MeshUtils.Vertex[3] { v, v, v }; for (; v != _mesh._vHead; v = v._next) { if (v._coords.X < minVal [0]) { minVal [0] = v._coords.X; minVert [0] = v; } if (v._coords.Y < minVal [1]) { minVal [1] = v._coords.Y; minVert [1] = v; } if (v._coords.Z < minVal [2]) { minVal [2] = v._coords.Z; minVert [2] = v; } if (v._coords.X > maxVal [0]) { maxVal [0] = v._coords.X; maxVert [0] = v; } if (v._coords.Y > maxVal [1]) { maxVal [1] = v._coords.Y; maxVert [1] = v; } if (v._coords.Z > maxVal [2]) { maxVal [2] = v._coords.Z; maxVert [2] = v; } } // Find two vertices separated by at least 1/sqrt(3) of the maximum // distance between any two vertices int i = 0; if (maxVal [1] - minVal [1] > maxVal [0] - minVal [0]) { i = 1; } if (maxVal [2] - minVal [2] > maxVal [i] - minVal [i]) { i = 2; } if (minVal [i] >= maxVal [i]) { // All vertices are the same -- normal doesn't matter norm = new Vec3 { X = 0.0f, Y = 0.0f, Z = 1.0f }; return; } // Look for a third vertex which forms the triangle with maximum area // (Length of normal == twice the triangle area) float maxLen2 = 0.0f, tLen2; var v1 = minVert [i]; var v2 = maxVert [i]; Vec3 d1, d2, tNorm; Vec3.Sub(ref v1._coords, ref v2._coords, out d1); for (v = _mesh._vHead._next; v != _mesh._vHead; v = v._next) { Vec3.Sub(ref v._coords, ref v2._coords, out d2); tNorm.X = d1.Y * d2.Z - d1.Z * d2.Y; tNorm.Y = d1.Z * d2.X - d1.X * d2.Z; tNorm.Z = d1.X * d2.Y - d1.Y * d2.X; tLen2 = tNorm.X * tNorm.X + tNorm.Y * tNorm.Y + tNorm.Z * tNorm.Z; if (tLen2 > maxLen2) { maxLen2 = tLen2; norm = tNorm; } } if (maxLen2 <= 0.0f) { // All points lie on a single line -- any decent normal will do norm = Vec3.Zero; i = Vec3.LongAxis(ref d1); norm [i] = 1.0f; } }