Exemplo n.º 1
0
 public LoopIterator(MyPolygon poly, int loopBegin)
 {
     m_data = poly.m_vertices;
     m_begin = loopBegin;
     m_currentIndex = -1;
     m_current = new Vertex();
     m_current.Next = m_begin;
 }
Exemplo n.º 2
0
 public LoopIterator(MyPolygon poly, int loopBegin)
 {
     m_data         = poly.m_vertices;
     m_begin        = loopBegin;
     m_currentIndex = -1;
     m_current      = new Vertex();
     m_current.Next = m_begin;
 }
Exemplo n.º 3
0
            public BoundPair(MyPolygon parent, int left, int minimum, int right, bool rightHorizontal)
            {
                Debug.Assert(parent != null);

                Parent = parent;
                Left = left;
                Minimum = minimum;
                Right = right;
                RightIsPrecededByHorizontal = rightHorizontal;

                m_minimumCoordinate = 0;
            }
Exemplo n.º 4
0
 private void PrepareTransforms(MyPolygon polyA)
 {
     m_projectionPlane        = polyA.PolygonPlane;
     Vector3 origin           = -polyA.PolygonPlane.Normal * polyA.PolygonPlane.D;
     Vector3 forward          = polyA.PolygonPlane.Normal;
     Vector3 right            = Vector3.CalculatePerpendicularVector(forward);
     Vector3 up               = Vector3.Cross(right, forward);
     m_invProjectionTransform = Matrix.CreateWorld(origin, forward, up);
     Matrix.Invert(ref m_invProjectionTransform, out m_projectionTransform);
 }
Exemplo n.º 5
0
        private void ProjectPoly(MyPolygon input, MyPolygon output, ref Matrix projection)
        {
            for (int i = 0; i < input.LoopCount; ++i)
            {
                m_tmpList.Clear();

                var iterator = input.GetLoopIterator(i);
                while (iterator.MoveNext())
                {
                    Vector3 transformed = Vector3.Transform(iterator.Current, projection);
                    m_tmpList.Add(transformed);
                }

                output.AddLoop(m_tmpList);
            }
        }
Exemplo n.º 6
0
 public MyPolygon Difference(MyPolygon polyA, MyPolygon polyB)
 {
     return PerformBooleanOperation(polyA, polyB, m_operationDifference);
 }
Exemplo n.º 7
0
 private MyPolygon PerformBooleanOperation(MyPolygon polyA, MyPolygon polyB, Operation operation)
 {
     Debug.Assert(polyA.PolygonPlane.Equals(polyB.PolygonPlane));
     Clear();
     PrepareTransforms(polyA);
     ProjectPoly(polyA, m_polyA, ref m_projectionTransform);
     ProjectPoly(polyB, m_polyB, ref m_projectionTransform);
     m_operation = operation;
     PerformInPlane();
     m_operation = null;
     return UnprojectResult();
 }
Exemplo n.º 8
0
        private static MatrixD DebugDrawBoundList(MatrixD drawMatrix, MyPolygon drawPoly, List<BoundPair> boundList)
        {
            foreach (var bound in boundList)
            {
                MyPolygon.Vertex v1, v2;
                Vector3 vec1 = default(Vector3);
                Vector3 vec2 = default(Vector3);

                int prev = bound.Left;
                drawPoly.GetVertex(prev, out v1);
                int current = v1.Prev;
                while (prev != bound.Minimum)
                {
                    drawPoly.GetVertex(current, out v2);

                    vec1 = Vector3.Transform(v1.Coord, drawMatrix);
                    vec2 = Vector3.Transform(v2.Coord, drawMatrix);

                    MyRenderProxy.DebugDrawLine3D(vec1, vec2, Color.Red, Color.Red, false);

                    prev = current;
                    v1 = v2;
                    current = v1.Prev;
                }

                MatrixD minimum = drawMatrix;
                minimum.Translation = vec2;
                MyRenderProxy.DebugDrawAxis(minimum, 0.25f, false);
                MyRenderProxy.DebugDrawSphere(vec2, 0.03f, Color.Yellow, 1.0f, false);

                prev = bound.Minimum;
                drawPoly.GetVertex(prev, out v1);
                current = v1.Prev;
                while (prev != bound.Right)
                {
                    drawPoly.GetVertex(current, out v2);

                    vec1 = Vector3.Transform(v1.Coord, drawMatrix);
                    vec2 = Vector3.Transform(v2.Coord, drawMatrix);

                    MyRenderProxy.DebugDrawLine3D(vec1, vec2, Color.Green, Color.Green, false);

                    prev = current;
                    v1 = v2;
                    current = v1.Prev;
                }

                if (bound.RightIsPrecededByHorizontal)
                {
                    MyRenderProxy.DebugDrawSphere(vec2, 0.03f, Color.Red, 1.0f, false);
                }
            }
            return drawMatrix;
        }
Exemplo n.º 9
0
 public MyPolygon Union(MyPolygon polyA, MyPolygon polyB)
 {
     return PerformBooleanOperation(polyA, polyB, m_operationUnion);
 }
Exemplo n.º 10
0
 private MyPolygon UnprojectResult()
 {
     MyPolygon tmp = new MyPolygon(new Plane(Vector3.Forward, 0));
     MyPolygon result = new MyPolygon(m_projectionPlane);
     foreach (var poly in m_results)
     {
         poly.Postprocess();
         var loop = poly.GetLoop();
         if (loop.Count == 0) continue;
         tmp.AddLoop(poly.GetLoop());
     }
     ProjectPoly(tmp, result, ref m_invProjectionTransform);
     return result;
 }
Exemplo n.º 11
0
        private static int FindLoopLocalMaximum(MyPolygon poly, int loop)
        {
            int index, maxIndex;
            Vector3 localMax;
            MyPolygon.Vertex vertex, otherVertex;

            index = poly.GetLoopStart(loop);
            poly.GetVertex(index, out vertex);

            maxIndex = index;
            localMax = vertex.Coord;

            // Find local maximum while going to the previous vertices in the loop
            index = vertex.Prev;
            poly.GetVertex(index, out otherVertex);
            while (otherVertex.Coord.Y > localMax.Y || (otherVertex.Coord.Y == localMax.Y && otherVertex.Coord.X > localMax.X))
            {
                maxIndex = index;
                localMax = otherVertex.Coord;
                index = otherVertex.Prev;
                poly.GetVertex(index, out otherVertex);
            }

            // Find local maximum while going to the next vertices in the loop
            index = vertex.Next;
            poly.GetVertex(index, out otherVertex);
            while (otherVertex.Coord.Y > localMax.Y || (otherVertex.Coord.Y == localMax.Y && otherVertex.Coord.X > localMax.X))
            {
                maxIndex = index;
                localMax = otherVertex.Coord;
                index = otherVertex.Next;
                poly.GetVertex(index, out otherVertex);
            }

            return maxIndex;
        }
Exemplo n.º 12
0
        private static void ConstructBoundPairs(MyPolygon poly, List<BoundPair> boundList)
        {
            for (int l = 0; l < poly.LoopCount; ++l)
            {
                int start, current, prev;
                MyPolygon.Vertex vertex;

                start = FindLoopLocalMaximum(poly, l);

                poly.GetVertex(start, out vertex);
                current = start;

                MyPolygon.Vertex otherVertex;
                poly.GetVertex(vertex.Prev, out otherVertex);

                BoundPair bounds = new BoundPair(poly, -1, -1, start, otherVertex.Coord.Y == vertex.Coord.Y);
                bool right = true;

                int comparison, prevComparison;
                comparison = -1;

                do
                {
                    Vector3 prevCoord = vertex.Coord;
                    prev = current;
                    current = vertex.Next;

                    poly.GetVertex(current, out vertex);
                    prevComparison = comparison;
                    comparison = CompareCoords(vertex.Coord, prevCoord);
                    Debug.Assert(comparison != 0, "Duplicate vertex in input polygon!");

                    if (right)
                    {
                        if (comparison > 0)
                        {
                            bounds.Minimum = prev;
                            right = false;
                        }
                    }
                    else
                    {
                        if (comparison < 0)
                        {
                            bounds.Left = prev;
                            Debug.Assert(bounds.IsValid());
                            boundList.Add(bounds);
                            bounds = new BoundPair(poly, -1, -1, prev, prevComparison == 0);
                            right = true;
                        }
                    }
                } while (current != start);

                bounds.Left = current;
                Debug.Assert(right == false);
                Debug.Assert(bounds.IsValid());
                boundList.Add(bounds);
            }
        }
Exemplo n.º 13
0
        private void RecalculateActiveEdge(ref Edge edge, ref MyPolygon.Vertex lowerVertex, ref MyPolygon.Vertex upperVertex, Side boundPairSide)
        {
            float Dy = upperVertex.Coord.Y - lowerVertex.Coord.Y;
            float Dx = upperVertex.Coord.X - lowerVertex.Coord.X;
            Debug.Assert(Dx != 0.0f || Dy != 0.0f, "Invalid polygon! Right point and minimum of a bound were the same point!");

            edge.TopVertexIndex = boundPairSide == Side.LEFT ? lowerVertex.Next : lowerVertex.Prev;
            edge.BottomX = lowerVertex.Coord.X;
            edge.TopY = upperVertex.Coord.Y;
            edge.DXdy = Dy == 0 ? Dx : Dx / Dy;

            InsertScanBeamDivide(upperVertex.Coord.Y);
        }
Exemplo n.º 14
0
        private Edge PrepareActiveEdge(int boundPairIndex, ref MyPolygon.Vertex lowerVertex, ref MyPolygon.Vertex upperVertex, PolygonType polyType, Side side)
        {
            Edge newEdge = new Edge();
            newEdge.BoundPairIndex = boundPairIndex;
            newEdge.BoundPairSide = side;
            newEdge.Kind = polyType;
            if (polyType == PolygonType.CLIP)
            {
                newEdge.OutputSide = m_operation.ClipInvert ? OtherSide(side) : side;
            }
            else
            {
                newEdge.OutputSide = m_operation.SubjectInvert ? OtherSide(side) : side;
            }

            RecalculateActiveEdge(ref newEdge, ref lowerVertex, ref upperVertex, side);

            return newEdge;
        }