Beispiel #1
0
        private void ProjectPolygon()
        {
            Vec3 v    = _normal;
            bool flag = false;

            if (v.X == 0f && v.Y == 0f && v.Z == 0f)
            {
                ComputeNormal(ref v);
                _normal = v;
                flag    = true;
            }
            int num = Vec3.LongAxis(ref v);

            _sUnit[num]           = 0f;
            _sUnit[(num + 1) % 3] = SUnitX;
            _sUnit[(num + 2) % 3] = SUnitY;
            _tUnit[num]           = 0f;
            _tUnit[(num + 1) % 3] = ((v[num] > 0f) ? (0f - SUnitY) : SUnitY);
            _tUnit[(num + 2) % 3] = ((v[num] > 0f) ? SUnitX : (0f - SUnitX));
            for (MeshUtils.Vertex next = _mesh._vHead._next; next != _mesh._vHead; next = next._next)
            {
                Vec3.Dot(ref next._coords, ref _sUnit, out next._s);
                Vec3.Dot(ref next._coords, ref _tUnit, out next._t);
            }
            if (flag)
            {
                CheckOrientation();
            }
            bool flag2 = true;

            for (MeshUtils.Vertex next2 = _mesh._vHead._next; next2 != _mesh._vHead; next2 = next2._next)
            {
                if (flag2)
                {
                    _bminX = (_bmaxX = next2._s);
                    _bminY = (_bmaxY = next2._t);
                    flag2  = false;
                }
                else
                {
                    if (next2._s < _bminX)
                    {
                        _bminX = next2._s;
                    }
                    if (next2._s > _bmaxX)
                    {
                        _bmaxX = next2._s;
                    }
                    if (next2._t < _bminY)
                    {
                        _bminY = next2._t;
                    }
                    if (next2._t > _bmaxY)
                    {
                        _bmaxY = next2._t;
                    }
                }
            }
        }
Beispiel #2
0
        private void ProjectPolygon()
        {
            var norm = _normal;

            bool computedNormal = false;

            if (norm.X == new DeterministicFloat(0) && norm.Y == new DeterministicFloat(0) && norm.Z == new DeterministicFloat(0))
            {
                ComputeNormal(ref norm);
                _normal        = norm;
                computedNormal = true;
            }

            int i = Vec3.LongAxis(ref norm);

            _sUnit[i]           = new DeterministicFloat(0);
            _sUnit[(i + 1) % 3] = SUnitX;
            _sUnit[(i + 2) % 3] = SUnitY;

            _tUnit[i]           = new DeterministicFloat(0);
            _tUnit[(i + 1) % 3] = norm[i] > new DeterministicFloat(0) ? -SUnitY : SUnitY;
            _tUnit[(i + 2) % 3] = norm[i] > new DeterministicFloat(0) ? 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;
                    }
                }
            }
        }
Beispiel #3
0
        private void ComputeNormal(ref Vec3 norm)
        {
            var v = _mesh._vHead._next;

            var minVal = new DeterministicFloat[3] {
                v._coords.X, v._coords.Y, v._coords.Z
            };
            var minVert = new MeshUtils.Vertex[3] {
                v, v, v
            };
            var maxVal = new DeterministicFloat[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(new DeterministicFloat(0), new DeterministicFloat(0), new DeterministicFloat(1));
                return;
            }

            // Look for a third vertex which forms the triangle with maximum area
            // (Length of normal == twice the triangle area)
            DeterministicFloat maxLen2 = new DeterministicFloat(0), 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 <= new DeterministicFloat(0))
            {
                // All points lie on a single line -- any decent normal will do
                norm    = Vec3.Zero;
                i       = Vec3.LongAxis(ref d1);
                norm[i] = new DeterministicFloat(1);
            }
        }
Beispiel #4
0
        private void ComputeNormal(ref Vec3 norm)
        {
            MeshUtils.Vertex next  = _mesh._vHead._next;
            float[]          array = new float[3]
            {
                next._coords.X,
                next._coords.Y,
                next._coords.Z
            };
            MeshUtils.Vertex[] array2 = new MeshUtils.Vertex[3]
            {
                next,
                next,
                next
            };
            float[] array3 = new float[3]
            {
                next._coords.X,
                next._coords.Y,
                next._coords.Z
            };
            MeshUtils.Vertex[] array4 = new MeshUtils.Vertex[3]
            {
                next,
                next,
                next
            };
            while (next != _mesh._vHead)
            {
                if (next._coords.X < array[0])
                {
                    array[0]  = next._coords.X;
                    array2[0] = next;
                }
                if (next._coords.Y < array[1])
                {
                    array[1]  = next._coords.Y;
                    array2[1] = next;
                }
                if (next._coords.Z < array[2])
                {
                    array[2]  = next._coords.Z;
                    array2[2] = next;
                }
                if (next._coords.X > array3[0])
                {
                    array3[0] = next._coords.X;
                    array4[0] = next;
                }
                if (next._coords.Y > array3[1])
                {
                    array3[1] = next._coords.Y;
                    array4[1] = next;
                }
                if (next._coords.Z > array3[2])
                {
                    array3[2] = next._coords.Z;
                    array4[2] = next;
                }
                next = next._next;
            }
            int num = 0;

            if (array3[1] - array[1] > array3[0] - array[0])
            {
                num = 1;
            }
            if (array3[2] - array[2] > array3[num] - array[num])
            {
                num = 2;
            }
            if (array[num] >= array3[num])
            {
                norm = new Vec3
                {
                    X = 0f,
                    Y = 0f,
                    Z = 1f
                };
            }
            else
            {
                float            num2   = 0f;
                MeshUtils.Vertex obj    = array2[num];
                MeshUtils.Vertex vertex = array4[num];
                Vec3.Sub(ref obj._coords, ref vertex._coords, out Vec3 result);
                for (next = _mesh._vHead._next; next != _mesh._vHead; next = next._next)
                {
                    Vec3.Sub(ref next._coords, ref vertex._coords, out Vec3 result2);
                    Vec3 vec = default(Vec3);
                    vec.X = result.Y * result2.Z - result.Z * result2.Y;
                    vec.Y = result.Z * result2.X - result.X * result2.Z;
                    vec.Z = result.X * result2.Y - result.Y * result2.X;
                    float num3 = vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z;
                    if (num3 > num2)
                    {
                        num2 = num3;
                        norm = vec;
                    }
                }
                if (num2 <= 0f)
                {
                    norm      = Vec3.Zero;
                    num       = Vec3.LongAxis(ref result);
                    norm[num] = 1f;
                }
            }
        }