Beispiel #1
0
    private void CreateNewHulls(UvMapper uvMapper, Vector3[] points, Vector3[] normals, out IList <IHull> newHulls)
    {
        newHulls = new List <IHull>();

        // Add the starting hull
        newHulls.Add(hull);

        for (int j = 0; j < points.Length; j++)
        {
            int previousHullCount = newHulls.Count;

            for (int i = 0; i < previousHullCount; i++)
            {
                IHull previousHull = newHulls[0];

                // Split the previous hull
                IHull a, b;

                previousHull.Split(points[j], normals[j], fillCut, uvMapper, out a, out b);

                // Update the list
                newHulls.Remove(previousHull);

                if (!a.IsEmpty)
                {
                    newHulls.Add(a);
                }

                if (!b.IsEmpty)
                {
                    newHulls.Add(b);
                }
            }
        }
    }
Beispiel #2
0
        public BlendControl(BlendingController bcon, Blending blending,
                            MouseTracker mouseTracker, BlendingController.MousePosition mouseCurr)
            : base(bcon, blending, mouseTracker, mouseCurr)
        {
            fsmOperation = new FSM <OperationEnum>();

            FsmActivity.State(ActivityEnum.Inactive);
            FsmActivity.State(ActivityEnum.Active).Enter(fsm => {
                mouseTracker.OnSelectionDown += (mt, f) => {
                    switch (f)
                    {
                    case MouseTracker.ButtonFlag.Left:
                        if (mouseCurr.TryInitEdgeMode())
                        {
                            fsmOperation.Goto(OperationEnum.MoveBlendWidth);
                        }
                        break;

                    case MouseTracker.ButtonFlag.Right:
                        break;
                    }
                };
                mouseTracker.OnSelection += (mt, f) => {
                    fsmOperation.Update();
                };
                mouseTracker.OnSelectionUp += (mt, f) => {
                    fsmOperation.Goto(OperationEnum.None);
                };
            }).Update(fsm => {
                fsmOperation.Update();
            }).Exit(fsm => {
                fsmOperation.Goto(OperationEnum.None);
                mouseTracker.Clear();
            });
            FsmActivity.Init();

            fsmOperation.State(OperationEnum.None);
            fsmOperation.State(OperationEnum.MoveBlendWidth).Update(fsm => {
                if (bcon.IsOverGUI)
                {
                    return;
                }

                mouseCurr.Update();

                var duv       = mouseCurr.WorldDuv;
                var data      = blending.BlendingData;
                var ej        = new EdgeJoint(data, mouseCurr.selectedScreen, mouseCurr.selectedEdge);
                ej.Bandwidth += duv[ej.axis];
                UvMapper.UpdateUv(data.Screens, data.Edges, data.ViewportOffsets);
                data.Invalidate();
            });
            fsmOperation.Init();
        }
Beispiel #3
0
    /// <summary>
    /// Splits the game object using an array of planes, instantiating the pieces as new
    /// game objects (clones of the original) and destroying the original game object when finished.
    /// </summary>
    /// <param name="planes">
    /// An array of world-space planes with unit-length normals.
    /// </param>
    public void Split(Plane[] planes)
    {
        //if(gameObject.tag == "rope") {
        //    var joint = gameObject.GetComponent<HingeJoint>();
        //    joint.connectedBody = null;
        //    //Destroy(gameObject);
        //    return;
        //}
        if (planes != null && planes.Length > 0 && hull != null && !hull.IsEmpty)
        {
            UvMapper uvMapper = GetComponent <UvMapper>();

            if (uvMapper != null)
            {
                if (sendPreSplitMessage)
                {
                    SendMessage("PreSplit", planes, SendMessageOptions.DontRequireReceiver);
                }

                Vector3[] points, normals;

                ConvertPlanesToLocalspace(planes, out points, out normals);

                IList <IHull> newHulls;

                CreateNewHulls(uvMapper, points, normals, out newHulls);

                GameObject[] newGameObjects;

                CreateNewGameObjects(newHulls, out newGameObjects);

                //手动添加的代码
                for (int i = 0; i < newGameObjects.Length; i++)
                {
                    Destroy(newGameObjects[i], 0.5f);
                }

                if (sendPostSplitMessage)
                {
                    SendMessage("PostSplit", newGameObjects, SendMessageOptions.DontRequireReceiver);
                }

                Destroy(gameObject);
            }
            else
            {
                Debug.LogWarning(name + " has no UvMapper attached! Please attach a UvMapper to use the ShatterTool.", this);
            }
        }
    }
Beispiel #4
0
    /// <summary>
    /// Splits the game object using an array of planes, instantiating the pieces as new
    /// game objects (clones of the original) and destroying the original game object when finished.
    /// </summary>
    /// <param name="planes">
    /// An array of world-space planes with unit-length normals.
    /// </param>
    public GameObject[] Split(Plane[] planes)
    {
        if (planes != null && planes.Length > 0 && hull != null && !hull.IsEmpty)
        {
            UvMapper uvMapper = GetComponent <UvMapper>();

            if (uvMapper != null)
            {
                if (sendPreSplitMessage)
                {
                    SendMessage("PreSplit", planes, SendMessageOptions.DontRequireReceiver);
                }

                Vector3[] points, normals;

                ConvertPlanesToLocalspace(planes, out points, out normals);

                IList <IHull> newHulls;

                CreateNewHulls(uvMapper, points, normals, out newHulls);

                GameObject[] newGameObjects;

                CreateNewGameObjects(newHulls, out newGameObjects);

                if (sendPostSplitMessage)
                {
                    SendMessage("PostSplit", newGameObjects, SendMessageOptions.DontRequireReceiver);
                }

                Destroy(gameObject);
                return(newGameObjects);
            }
            else
            {
                Debug.LogWarning(name + " has no UvMapper attached! Please attach a UvMapper to use the ShatterTool.", this);
                return(null);
            }
        }
        return(null);
    }
Beispiel #5
0
    public void Start()
    {
        mf         = gameObject.GetComponent <MeshFilter> ();
        uvMapper   = Camera.main.GetComponent <UvMapper> ();
        sharedMesh = mf.sharedMesh;

        // Initialize the first generation hull
        if (hull == null)
        {
            if (internalHullType == HullType.FastHull)
            {
                hull = new FastHull(sharedMesh);
            }
            else if (internalHullType == HullType.LegacyHull)
            {
                hull = new LegacyHull(sharedMesh);
            }
        }

        // Update properties
        CalculateCenter();
    }
Beispiel #6
0
    private void FillCutEdges(Hull a, Hull b, IList <Edge> edgesA, IList <Edge> edgesB, Vector3 planeNormal, UvMapper uvMapper)
    {
        // Create outline data
        int outlineEdgeCount = edgesA.Count;

        Vector3[] outlinePoints = new Vector3[outlineEdgeCount];
        int[]     outlineEdges  = new int[outlineEdgeCount * 2];

        int startIndex = 0;

        for (int i = 0; i < outlineEdgeCount; i++)
        {
            int currentIndex = i;
            int nextIndex    = (i + 1) % outlineEdgeCount;

            Edge current = edgesA[currentIndex];
            Edge next    = edgesA[nextIndex];

            // Set point
            outlinePoints[i] = current.point0.position;

            // Set edge
            outlineEdges[i * 2 + 0] = currentIndex;

            if (current.point1 == next.point0)
            {
                outlineEdges[i * 2 + 1] = nextIndex;
            }
            else
            {
                outlineEdges[i * 2 + 1] = startIndex;

                startIndex = nextIndex;
            }
        }

        // Triangulate
        int[] newEdges, newTriangles, newTriangleEdges;

        ITriangulator triangulator = new Triangulator(outlinePoints, outlineEdges, planeNormal);

        triangulator.Fill(out newEdges, out newTriangles, out newTriangleEdges);

        // Calculate vertex properties
        Vector3 normalA = -planeNormal;
        Vector3 normalB = planeNormal;

        Vector4[] tangentsA, tangentsB;
        Vector2[] uvsA, uvsB;

        uvMapper.Map(outlinePoints, planeNormal, out tangentsA, out tangentsB, out uvsA, out uvsB);

        // Create new vertices
        int[] verticesA = new int[outlineEdgeCount];
        int[] verticesB = new int[outlineEdgeCount];

        for (int i = 0; i < outlineEdgeCount; i++)
        {
            a.AddVertex(outlinePoints[i], normalA, tangentsA[i], uvsA[i], edgesA[i].point0, out verticesA[i]);

            b.AddVertex(outlinePoints[i], normalB, tangentsB[i], uvsB[i], edgesB[i].point0, out verticesB[i]);
        }

        // Create new edges
        for (int i = 0; i < newEdges.Length / 2; i++)
        {
            int point0 = newEdges[i * 2 + 0];
            int point1 = newEdges[i * 2 + 1];

            Edge edgeA = new Edge(edgesA[point0].point0, edgesA[point1].point0);
            Edge edgeB = new Edge(edgesB[point0].point0, edgesB[point1].point0);

            edgesA.Add(edgeA);
            edgesB.Add(edgeB);

            a.edges.Add(edgeA);
            b.edges.Add(edgeB);
        }

        // Create new triangles
        for (int i = 0; i < newTriangles.Length / 3; i++)
        {
            int point0 = newTriangles[i * 3 + 0];
            int point1 = newTriangles[i * 3 + 1];
            int point2 = newTriangles[i * 3 + 2];

            int edge0 = newTriangleEdges[i * 3 + 0];
            int edge1 = newTriangleEdges[i * 3 + 1];
            int edge2 = newTriangleEdges[i * 3 + 2];

            Triangle triangleA = new Triangle(verticesA[point0], verticesA[point2], verticesA[point1], edgesA[point0].point0, edgesA[point2].point0, edgesA[point1].point0, edgesA[edge2], edgesA[edge1], edgesA[edge0]);
            Triangle triangleB = new Triangle(verticesB[point0], verticesB[point1], verticesB[point2], edgesB[point0].point0, edgesB[point1].point0, edgesB[point2].point0, edgesB[edge0], edgesB[edge1], edgesB[edge2]);

            a.triangles.Add(triangleA);
            b.triangles.Add(triangleB);
        }
    }
Beispiel #7
0
    public void Split(Vector3 localPointOnPlane, Vector3 localPlaneNormal, bool fillCut, UvMapper uvMapper, out Hull a, out Hull b)
    {
        lock (key)
        {
            if (localPlaneNormal == Vector3.zero)
            {
                localPlaneNormal = Vector3.up;
            }

            a = new Hull(this);
            b = new Hull(this);

            SetIndices();

            bool[] pointAbovePlane;

            AssignPoints(a, b, localPointOnPlane, localPlaneNormal, out pointAbovePlane);

            int[] oldToNewVertex;

            AssignVertices(a, b, pointAbovePlane, out oldToNewVertex);

            bool[]    edgeIntersectsPlane;
            EdgeHit[] edgeHits;

            AssignEdges(a, b, pointAbovePlane, localPointOnPlane, localPlaneNormal, out edgeIntersectsPlane, out edgeHits);

            IList <Edge> cutEdgesA, cutEdgesB;

            AssignTriangles(a, b, pointAbovePlane, edgeIntersectsPlane, edgeHits, oldToNewVertex, out cutEdgesA, out cutEdgesB);

            if (fillCut)
            {
                SortCutEdges(cutEdgesA, cutEdgesB);

                FillCutEdges(a, b, cutEdgesA, cutEdgesB, localPlaneNormal, uvMapper);
            }

            ValidateOutput(a, b, localPlaneNormal);

            Clear();
        }
    }
Beispiel #8
0
    public void Split(Vector3 localPointOnPlane, Vector3 localPlaneNormal, bool fillCut, UvMapper uvMapper, out IHull resultA, out IHull resultB)
    {
        if (localPlaneNormal == Vector3.zero)
        {
            localPlaneNormal = Vector3.up;
        }

        FastHull a = new FastHull(this);
        FastHull b = new FastHull(this);

        bool[] vertexAbovePlane;
        int[]  oldToNewVertexMap;

        AssignVertices(a, b, localPointOnPlane, localPlaneNormal, out vertexAbovePlane, out oldToNewVertexMap);

        IList <Vector3> cutEdges;

        AssignTriangles(a, b, vertexAbovePlane, oldToNewVertexMap, localPointOnPlane, localPlaneNormal, out cutEdges);

        if (fillCut)
        {
            FillCutEdges(a, b, cutEdges, localPlaneNormal, uvMapper);
        }

        ValidateOutput(a, b, localPlaneNormal);

        isValid = false;

        // Set output
        resultA = a;
        resultB = b;
    }
Beispiel #9
0
    private void FillCutEdges(FastHull a, FastHull b, IList <Vector3> edges, Vector3 planeNormal, UvMapper uvMapper)
    {
        int edgeCount = edges.Count / 2;

        List <Vector3> points  = new List <Vector3>(edgeCount);
        List <int>     outline = new List <int>(edgeCount * 2);

        int start = 0;

        for (int current = 0; current < edgeCount; current++)
        {
            int next = current + 1;

            // Find the next edge
            int   nearest         = start;
            float nearestDistance = (edges[current * 2 + 1] - edges[start * 2 + 0]).sqrMagnitude;

            for (int other = next; other < edgeCount; other++)
            {
                float distance = (edges[current * 2 + 1] - edges[other * 2 + 0]).sqrMagnitude;

                if (distance < nearestDistance)
                {
                    nearest         = other;
                    nearestDistance = distance;
                }
            }

            // Is the current edge the last edge in this edge loop?
            if (nearest == start && current > start)
            {
                int pointStart   = points.Count;
                int pointCounter = pointStart;

                // Add this edge loop to the triangulation lists
                for (int edge = start; edge < current; edge++)
                {
                    points.Add(edges[edge * 2 + 0]);
                    outline.Add(pointCounter++);
                    outline.Add(pointCounter);
                }

                points.Add(edges[current * 2 + 0]);
                outline.Add(pointCounter);
                outline.Add(pointStart);

                // Start a new edge loop
                start = next;
            }
            else if (next < edgeCount)
            {
                // Move the nearest edge so that it follows the current edge
                Vector3 n0 = edges[next * 2 + 0];
                Vector3 n1 = edges[next * 2 + 1];

                edges[next * 2 + 0] = edges[nearest * 2 + 0];
                edges[next * 2 + 1] = edges[nearest * 2 + 1];

                edges[nearest * 2 + 0] = n0;
                edges[nearest * 2 + 1] = n1;
            }
        }

        if (points.Count > 0)
        {
            // Triangulate the outline
            int[] newEdges, newTriangles, newTriangleEdges;

            ITriangulator triangulator = new Triangulator(points, outline, planeNormal);

            triangulator.Fill(out newEdges, out newTriangles, out newTriangleEdges);

            // Calculate the vertex properties
            Vector3   normalA = -planeNormal;
            Vector3   normalB = planeNormal;
            Vector4[] tangentsA, tangentsB;
            Vector2[] uvsA, uvsB;

            uvMapper.Map(points, planeNormal, out tangentsA, out tangentsB, out uvsA, out uvsB);

            // Add the new vertices
            int offsetA = a.vertices.Count;
            int offsetB = b.vertices.Count;

            for (int i = 0; i < points.Count; i++)
            {
                a.vertices.Add(points[i]);
                b.vertices.Add(points[i]);
            }

            if (normals != null)
            {
                for (int i = 0; i < points.Count; i++)
                {
                    a.normals.Add(normalA);
                    b.normals.Add(normalB);
                }
            }

            if (tangents != null)
            {
                for (int i = 0; i < points.Count; i++)
                {
                    a.tangents.Add(tangentsA[i]);
                    b.tangents.Add(tangentsB[i]);
                }
            }

            if (uvs != null)
            {
                for (int i = 0; i < points.Count; i++)
                {
                    a.uvs.Add(uvsA[i]);
                    b.uvs.Add(uvsB[i]);
                }
            }

            // Add the new triangles
            int newTriangleCount = newTriangles.Length / 3;

            for (int i = 0; i < newTriangleCount; i++)
            {
                a.indices.Add(offsetA + newTriangles[i * 3 + 0]);
                a.indices.Add(offsetA + newTriangles[i * 3 + 2]);
                a.indices.Add(offsetA + newTriangles[i * 3 + 1]);

                b.indices.Add(offsetB + newTriangles[i * 3 + 0]);
                b.indices.Add(offsetB + newTriangles[i * 3 + 1]);
                b.indices.Add(offsetB + newTriangles[i * 3 + 2]);
            }
        }
    }
Beispiel #10
0
 public void Awake()
 {
     uvMapper = GetComponent <UvMapper>();
 }