Exemplo n.º 1
0
    /// <summary>
    /// ici est appelé directement depuis l'un des link
    /// </summary>
    public void AddLink(int index)
    {
        if (linkCount == linkCountMax || linkBreaked)
        {
            return;
        }
        if (index > listCircular.Count)
        {
            Debug.LogError("index out of range: " + index);
            return;
        }
        LinkCountAdd();

        GameObject closestLink = listCircular[index].Value;

        if (!closestLink)
        {
            listCircular.RemoveAllEmpty();
            closestLink = listCircular[index].Value;
        }


        GameObject newLink = ObjectsPooler.Instance.SpawnFromPool(GameData.PoolTag.Link, closestLink.transform.position, Quaternion.identity, parentLink);

        /*SpringJoint jointLink = */ newLink.transform.GetOrAddComponent <SpringJoint>();

        ChangeMeshRenrered(newLink.GetComponent <MeshRenderer>());

        //si l'index n'est pas le dernier (l'un des 2 gros objet), on peut le créé après
        if (index != listCircular.Count - 1)
        {
            listCircular.AddAfter(listCircular[index], newLink);

            SetupLink(newLink, index + 1);

            ChangeThisPring(index);
            ChangeThisPring(index + 1);
        }
        else
        {
            Debug.Log("ICI on ajoute sur le dernier ???");
            listCircular.AddBefore(listCircular[index], newLink);

            SetupLink(newLink, index - 0);
            ChangeThisPring(index - 1);
            ChangeThisPring(index - 0);
        }
        ChangeParamJointWhenAdding(1);
        CreateFakeListForDebug();
    }
Exemplo n.º 2
0
    // Finds a pair of inner contour vertex / outer contour vertex that are mutually visible
    public static Contour InsertInnerContourIntoOuterContour(Contour a_rOuterContour, Contour a_rInnerContour)
    {
        // Look for the inner vertex of maximum x-value
        Vector2 f2InnerContourVertexMax = Vector2.one * int.MinValue;
        CircularLinkedListNode <Vector2> rMutualVisibleInnerContourVertexNode = null;

        CircularLinkedList <Vector2>     rInnerContourVertexList = a_rInnerContour.Vertices;
        CircularLinkedListNode <Vector2> rInnerContourVertexNode = rInnerContourVertexList.First;

        do
        {
            // x-value
            Vector2 f2InnerContourVertex = rInnerContourVertexNode.Value;

            // New max x found
            if (f2InnerContourVertexMax.x < f2InnerContourVertex.x)
            {
                f2InnerContourVertexMax = f2InnerContourVertex;
                rMutualVisibleInnerContourVertexNode = rInnerContourVertexNode;
            }

            // Go to next vertex
            rInnerContourVertexNode = rInnerContourVertexNode.Next;
        }while(rInnerContourVertexNode != rInnerContourVertexList.First);

        // Visibility ray
        Ray     oInnerVertexVisibilityRay = new Ray(f2InnerContourVertexMax, Vector3.right);
        float   fClosestDistance          = int.MaxValue;
        Vector2 f2ClosestOuterEdgeStart   = Vector2.zero;
        Vector2 f2ClosestOuterEdgeEnd     = Vector2.zero;

        Contour rOuterCutContour = new Contour(a_rOuterContour.Region);

        rOuterCutContour.AddLast(a_rOuterContour.Vertices);

        CircularLinkedList <Vector2>     rOuterCutContourVertexList   = rOuterCutContour.Vertices;
        CircularLinkedListNode <Vector2> rOuterContourVertexEdgeStart = null;

        // Raycast from the inner contour vertex to every edge
        CircularLinkedListNode <Vector2> rOuterContourVertexNode = rOuterCutContourVertexList.First;

        do
        {
            // Construct outer edge from current and next outer contour vertices
            Vector2 f2OuterEdgeStart = rOuterContourVertexNode.Value;
            Vector2 f2OuterEdgeEnd   = rOuterContourVertexNode.Next.Value;
            Vector2 f2OuterEdge      = f2OuterEdgeEnd - f2OuterEdgeStart;

            // Orthogonal vector to edge (pointing to polygon interior)
            Vector2 f2OuterEdgeNormal = Uni2DMathUtils.PerpVector2(f2OuterEdge);

            // Vector from edge start to inner vertex
            Vector2 f2OuterEdgeStartToInnerVertex = f2InnerContourVertexMax - f2OuterEdgeStart;

            // If the inner vertex is on the left of the edge (interior),
            // test if there's any intersection
            if (Vector2.Dot(f2OuterEdgeStartToInnerVertex, f2OuterEdgeNormal) >= 0.0f)
            {
                float fDistanceT;

                // If visibility intersects outer edge...
                if (Uni2DMathUtils.Raycast2DSegment(oInnerVertexVisibilityRay, f2OuterEdgeStart, f2OuterEdgeEnd, out fDistanceT) == true)
                {
                    // Is it the closest intersection we found?
                    if (fClosestDistance > fDistanceT)
                    {
                        fClosestDistance             = fDistanceT;
                        rOuterContourVertexEdgeStart = rOuterContourVertexNode;

                        f2ClosestOuterEdgeStart = f2OuterEdgeStart;
                        f2ClosestOuterEdgeEnd   = f2OuterEdgeEnd;
                    }
                }
            }

            // Go to next edge
            rOuterContourVertexNode = rOuterContourVertexNode.Next;
        }while(rOuterContourVertexNode != rOuterCutContourVertexList.First);

        // Take the vertex of maximum x-value from the closest intersected edge
        Vector2 f2ClosestVisibleOuterContourVertex;
        CircularLinkedListNode <Vector2> rMutualVisibleOuterContourVertexNode;

        if (f2ClosestOuterEdgeStart.x < f2ClosestOuterEdgeEnd.x)
        {
            f2ClosestVisibleOuterContourVertex   = f2ClosestOuterEdgeEnd;
            rMutualVisibleOuterContourVertexNode = rOuterContourVertexEdgeStart.Next;
        }
        else
        {
            f2ClosestVisibleOuterContourVertex   = f2ClosestOuterEdgeStart;
            rMutualVisibleOuterContourVertexNode = rOuterContourVertexEdgeStart;
        }

        // Looking for points inside the triangle defined by inner vertex, intersection point an closest outer vertex
        // If a point is inside this triangle, at least one is a reflex vertex
        // The closest reflex vertex which minimises the angle this-vertex/inner vertex/intersection vertex
        // would be choosen as the mutual visible vertex
        Vector3 f3IntersectionPoint = oInnerVertexVisibilityRay.GetPoint(fClosestDistance);
        Vector2 f2InnerContourVertexToIntersectionPoint           = new Vector2(f3IntersectionPoint.x, f3IntersectionPoint.y) - f2InnerContourVertexMax;
        Vector2 f2NormalizedInnerContourVertexToIntersectionPoint = f2InnerContourVertexToIntersectionPoint.normalized;

        float fMaxDotAngle = float.MinValue;
        float fMinDistance = float.MaxValue;

        rOuterContourVertexNode = rOuterCutContourVertexList.First;
        do
        {
            Vector2 f2OuterContourVertex = rOuterContourVertexNode.Value;

            // if vertex not part of triangle
            if (f2OuterContourVertex != f2ClosestVisibleOuterContourVertex)
            {
                // if vertex is inside triangle...
                if (Uni2DMathUtils.IsPointInsideTriangle(f2InnerContourVertexMax, f3IntersectionPoint, f2ClosestVisibleOuterContourVertex, f2OuterContourVertex) == true)
                {
                    // if vertex is reflex
                    Vector2 f2PreviousOuterContourVertex = rOuterContourVertexNode.Previous.Value;
                    Vector2 f2NextOuterContourVertex     = rOuterContourVertexNode.Next.Value;

                    if (IsReflexVertex(f2OuterContourVertex, f2PreviousOuterContourVertex, f2NextOuterContourVertex) == true)
                    {
                        // Use dot product as distance
                        Vector2 f2InnerContourVertexToReflexVertex = f2OuterContourVertex - f2InnerContourVertexMax;

                        // INFO: f2NormalizedInnerContourVertexToIntersectionPoint == Vector3.right (if everything is right)
                        float fDistance = Vector2.Dot(f2NormalizedInnerContourVertexToIntersectionPoint, f2InnerContourVertexToReflexVertex);
                        float fDotAngle = Vector2.Dot(f2NormalizedInnerContourVertexToIntersectionPoint, f2InnerContourVertexToReflexVertex.normalized);

                        // New mutual visible vertex if angle smaller (e.g. dot angle larger) than min or equal and closer
                        if (fDotAngle > fMaxDotAngle || (fDotAngle == fMaxDotAngle && fDistance < fMinDistance))
                        {
                            fMaxDotAngle = fDotAngle;
                            fMinDistance = fDistance;
                            rMutualVisibleOuterContourVertexNode = rOuterContourVertexNode;
                        }
                    }
                }
            }

            // Go to next vertex
            rOuterContourVertexNode = rOuterContourVertexNode.Next;
        }while(rOuterContourVertexNode != rOuterCutContourVertexList.First);

        // Insert now the cut into the polygon
        // The cut starts from the outer contour mutual visible vertex to the inner vertex
        CircularLinkedListNode <Vector2> rOuterContourVertexNodeToInsertBefore = rMutualVisibleOuterContourVertexNode.Next;

        // Loop over the inner contour starting from the inner contour vertex...
        rInnerContourVertexNode = rMutualVisibleInnerContourVertexNode;
        do
        {
            // ... add the inner contour vertex before the outer contour vertex after the cut
            rOuterCutContourVertexList.AddBefore(rOuterContourVertexNodeToInsertBefore, rInnerContourVertexNode.Value);
            rInnerContourVertexNode = rInnerContourVertexNode.Next;
        }while(rInnerContourVertexNode != rMutualVisibleInnerContourVertexNode);

        // Close the cut by doubling the inner and outer contour vertices
        rOuterCutContourVertexList.AddBefore(rOuterContourVertexNodeToInsertBefore, rMutualVisibleInnerContourVertexNode.Value);
        rOuterCutContourVertexList.AddBefore(rOuterContourVertexNodeToInsertBefore, rMutualVisibleOuterContourVertexNode.Value);

        return(rOuterCutContour);
    }