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;
 }
Exemple #2
0
 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;
 }
Exemple #3
0
        // The data array contains 4 values, it's the associated data of the vertices that resulted in an intersection.
        private static object VertexCombine(LibTessDotNet.Vec3 position, object[] data, float[] weights)
        {
            // Fetch the vertex data.
            var colors = new Color[] { (Color)data[0], (Color)data[1], (Color)data[2], (Color)data[3] };
            // Interpolate with the 4 weights.
            var rgba = new float[] {
                (float)colors[0].R * weights[0] + (float)colors[1].R * weights[1] + (float)colors[2].R * weights[2] + (float)colors[3].R * weights[3],
                (float)colors[0].G * weights[0] + (float)colors[1].G * weights[1] + (float)colors[2].G * weights[2] + (float)colors[3].G * weights[3],
                (float)colors[0].B * weights[0] + (float)colors[1].B * weights[1] + (float)colors[2].B * weights[2] + (float)colors[3].B * weights[3],
                (float)colors[0].A * weights[0] + (float)colors[1].A * weights[1] + (float)colors[2].A * weights[2] + (float)colors[3].A * weights[3]
            };

            // Return interpolated data for the new vertex.
            return(Color.FromArgb((int)rgba[3], (int)rgba[0], (int)rgba[1], (int)rgba[2]));
        }
Exemple #4
0
 private object VertexCombine(Vec3 position, object[] data, float[] weights)
 {
     var colors = new Color[] { (Color)data[0], (Color)data[1], (Color)data[2], (Color)data[3] };
     var rgba = new float[] {
         colors[0].R * weights[0] + colors[1].R * weights[1] + colors[2].R * weights[2] + colors[3].R * weights[3],
         colors[0].G * weights[0] + colors[1].G * weights[1] + colors[2].G * weights[2] + colors[3].G * weights[3],
         colors[0].B * weights[0] + colors[1].B * weights[1] + colors[2].B * weights[2] + colors[3].B * weights[3],
         colors[0].A * weights[0] + colors[1].A * weights[1] + colors[2].A * weights[2] + colors[3].A * weights[3]
     };
     return Color.FromArgb((int)rgba[3], (int)rgba[0], (int)rgba[1], (int)rgba[2]);
 }
 public static void Neg(ref Vec3 v)
 {
     v.X = -v.X;
     v.Y = -v.Y;
     v.Z = -v.Z;
 }
 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 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;
 }
Exemple #8
0
        private Vec3 Project(Vec3 v)
        {
            Vec3 norm = _tess.Normal;
            int i = Vec3.LongAxis(ref norm);

            Vec3 sUnit = Vec3.Zero;
            sUnit[i] = 0.0f;
            sUnit[(i + 1) % 3] = _tess.SUnitX;
            sUnit[(i + 2) % 3] = _tess.SUnitY;

            Vec3 tUnit = Vec3.Zero;
            tUnit[i] = 0.0f;
            tUnit[(i + 1) % 3] = norm[i] > 0.0f ? -_tess.SUnitY : _tess.SUnitY;
            tUnit[(i + 2) % 3] = norm[i] > 0.0f ? _tess.SUnitX : -_tess.SUnitX;

            Vec3 result = Vec3.Zero;
            // Project the vertices onto the sweep plane
            Vec3.Dot(ref v, ref sUnit, out result.X);
            Vec3.Dot(ref v, ref tUnit, out result.Y);
            return result;
        }
Exemple #9
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;
            }
        }
Exemple #10
0
        public Tess()
        {
            _normal = Vec3.Zero;
            _bminX = _bminY = _bmaxX = _bmaxY = 0.0f;

            _windingRule = WindingRule.EvenOdd;
            _mesh = null;

            _vertices = null;
            _vertexCount = 0;
            _elements = null;
            _elementCount = 0;
        }
Exemple #11
0
        private void ProjectPolygon()
        {
            var norm = _normal;

            bool computedNormal = false;

            if (norm.X == 0.0f && norm.Y == 0.0f && norm.Z == 0.0f)
            {
                ComputeNormal(ref norm);
                computedNormal = true;
            }

            int i = Vec3.LongAxis(ref norm);

            _sUnit[i]           = 0.0f;
            _sUnit[(i + 1) % 3] = SUnitX;
            _sUnit[(i + 2) % 3] = SUnitY;

            _tUnit[i]           = 0.0f;
            _tUnit[(i + 1) % 3] = norm[i] > 0.0f ? -SUnitY : SUnitY;
            _tUnit[(i + 2) % 3] = norm[i] > 0.0f ? SUnitX : -SUnitX;

            // Project the vertices onto the sweep plane
            for (var v = _mesh._vHead._next; v != _mesh._vHead; v = v._next)
            {
                Vec3.Dot(ref v._coords, ref _sUnit, out v._s);
                Vec3.Dot(ref v._coords, ref _tUnit, out v._t);
            }
            if (computedNormal)
            {
                CheckOrientation();
            }

            // Compute ST bounds.
            bool first = true;

            for (var v = _mesh._vHead._next; v != _mesh._vHead; v = v._next)
            {
                if (first)
                {
                    _bminX = _bmaxX = v._s;
                    _bminY = _bmaxY = v._t;
                    first  = false;
                }
                else
                {
                    if (v._s < _bminX)
                    {
                        _bminX = v._s;
                    }
                    if (v._s > _bmaxX)
                    {
                        _bmaxX = v._s;
                    }
                    if (v._t < _bminY)
                    {
                        _bminY = v._t;
                    }
                    if (v._t > _bmaxY)
                    {
                        _bmaxY = v._t;
                    }
                }
            }
        }
Exemple #12
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;
            }
        }
Exemple #13
0
 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;
 }
Exemple #14
0
 public static void Neg(ref Vec3 v)
 {
     v.X = 0f - v.X;
     v.Y = 0f - v.Y;
     v.Z = 0f - v.Z;
 }
Exemple #15
0
 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;
 }