예제 #1
0
    public void DissipateDeformation(bool addNoise)
    {
        foreach (VertexGroup group in vertexQueue)
        {
            // Debug.Log("Initial queue contains " + group.vertexIndices[0]);
        }

        while (vertexQueue.Count > 0)
        {
            VertexGroup current = vertexQueue.Dequeue();
            current.SetEnqueued(teamId, false);
            // Debug.Log("Vertex group " + current.vertexIndices[0] + " dequeued");

            oldEdgeSqrLengths.Clear();
            for (int j = 0; j < current.connectingEdges.Count; j++)
            {
                oldEdgeSqrLengths.Add(current.connectingEdges[j].sqrLength);
            }

            float sqrStretchiness = stretchiness * stretchiness;

            for (int j = 0; j < current.connectingEdges.Count; j++)
            {
                VertexGroup adjacent = current.connectingEdges[j].OtherVertexGroup(current);

                //  Check if adjacent vertex has been moved.
                if (adjacent.GetWasMoved(teamId))
                {
                    //  Get vector of edge between vertices.
                    Vector3 edge = current.pos - adjacent.pos;
                    //  ohno edge too long
                    if (edge.sqrMagnitude > sqrStretchiness * oldEdgeSqrLengths[j])
                    {
                        //  make edge right length
                        edge.Normalize();
                        float randomNoise = 1;
                        if (addNoise)
                        {
                            randomNoise = Random.value * 0.2f + 0.9f;
                        }
                        float edgeStretchiness = stretchiness * randomNoise;
                        edge *= edgeStretchiness * Mathf.Sqrt(oldEdgeSqrLengths[j]);

                        //  move vertices so edge is not too long.
                        current.MoveTo(vertices, adjacent.pos + edge, false);
                        current.connectingEdges[j].UpdateEdgeLength();
                        current.SetWasMoved(teamId, true);
                    }
                }
            }

            if (current.GetWasMoved(teamId))
            {
                //  Add adjacent, unmoved vertices into the queue for traversal
                for (int j = 0; j < current.connectingEdges.Count; j++)
                {
                    //  Get adjacent vertex group
                    VertexGroup adjacent = current.connectingEdges[j].OtherVertexGroup(current);

                    //  Add it to the queue if it hasn't already been moved
                    if (!adjacent.GetEnqueued(teamId) && !adjacent.GetWasMoved(teamId))
                    {
                        vertexQueue.Enqueue(adjacent);
                        adjacent.SetEnqueued(teamId, true);
                        // Debug.Log("Vertex group " + adjacent.vertexIndices[0] + " enqueued");
                    }
                }
            }

            //moved.Add(current);
            current.SetWasMoved(teamId, true);
        }

        string meshName;

        if (meshType == MeshstateTracker.MeshTypes.interceptor)
        {
            meshName = "interceptor";
        }
        else if (meshType == MeshstateTracker.MeshTypes.ace)
        {
            meshName = "ace";
        }
        else if (meshType == MeshstateTracker.MeshTypes.bomber)
        {
            meshName = "bomber";
        }
        else
        {
            meshName = "bike";
        }

        for (int i = 0; i < meshGraph.groups.Length; i++)
        {
            meshGraph.groups[i].SetWasMoved(teamId, false);
            if (meshGraph.groups[i].GetEnqueued(teamId))
            {
                Debug.LogWarning("Vertex group " + meshGraph.groups[i].vertexIndices[0] + " marked as still in queue. mesh: " + meshName);
                meshGraph.groups[i].SetEnqueued(teamId, false);
            }
        }

        //  Update the mesh
        deformableMeshes[0].GetMeshFilter().mesh.SetVertices(vertices);
        deformableMeshes[0].GetMeshFilter().mesh.RecalculateNormals();

        if (interfaceCar != null)
        {
            frWheel.transform.localPosition = frWheelVertexGroup.pos;
            flWheel.transform.localPosition = flWheelVertexGroup.pos;
            rrWheel.transform.localPosition = rrWheelVertexGroup.pos;
            rlWheel.transform.localPosition = rlWheelVertexGroup.pos;
        }
    }
예제 #2
0
    // Explode the mesh at a given position, with a given force
    public void ExplodeMeshAt(Vector3 pos, float force, bool addNoise = true)
    {
        pos = transform.InverseTransformPoint(pos);

        VertexGroup closest = GetClosestVertexGroup(pos);

        //  Make a queue (it breadth first traversal time)
        vertexQueue.Enqueue(closest);
        closest.SetEnqueued(teamId, true);

        // Move each vertex, making sure that it doesn't stretch too far from its neighbours
        while (vertexQueue.Count > 0)
        {
            VertexGroup current = vertexQueue.Dequeue();
            current.SetEnqueued(teamId, false);

            oldEdgeSqrLengths.Clear();
            for (int j = 0; j < current.connectingEdges.Count; j++)
            {
                oldEdgeSqrLengths.Add(current.connectingEdges[j].sqrLength);
            }

            //  Calculate deformation vector
            Vector3 deformation      = current.pos - pos;
            float   deformationForce = force / deformation.sqrMagnitude;
            if (addNoise)
            {
                deformationForce *= Random.value * 0.2f + 0.9f;
            }
            deformation.Normalize();
            deformation *= Mathf.Clamp(deformationForce / vertexWeight, 0, 0.5f);

            current.MoveBy(vertices, deformation, false);

            for (int j = 0; j < current.connectingEdges.Count; j++)
            {
                VertexGroup adjacent = current.connectingEdges[j].OtherVertexGroup(current);

                //  Check if adjacent vertex has been moved.
                if (adjacent.GetWasMoved(teamId))
                {
                    //  Get vector of edge between vertices.
                    Vector3 edge = current.pos - adjacent.pos;
                    //  ohno edge too long
                    if (edge.sqrMagnitude > stretchiness * stretchiness * oldEdgeSqrLengths[j])
                    {
                        //  make edge right length
                        edge.Normalize();
                        float randomNoise = 1;
                        if (addNoise)
                        {
                            randomNoise = Random.value * 0.2f + 0.9f;
                        }
                        float edgeStretchiness = stretchiness * randomNoise;
                        edge *= edgeStretchiness * Mathf.Sqrt(oldEdgeSqrLengths[j]);

                        //  move vertices so edge is not too long.
                        current.MoveTo(vertices, adjacent.pos + edge, false);
                        current.connectingEdges[j].UpdateEdgeLength();
                    }
                }
            }

            current.SetWasMoved(teamId, true);

            //  Add adjacent, unmoved vertices into the queue for traversal
            for (int j = 0; j < current.connectingEdges.Count; j++)
            {
                //  Get adjacent vertex group
                VertexGroup adjacent = current.connectingEdges[j].OtherVertexGroup(current);

                //  Add it to the queue if it hasn't already been moved
                if (!adjacent.GetEnqueued(teamId) && !adjacent.GetWasMoved(teamId))
                {
                    vertexQueue.Enqueue(adjacent);
                    adjacent.SetEnqueued(teamId, true);
                }
            }
        }

        for (int i = 0; i < meshGraph.groups.Length; i++)
        {
            meshGraph.groups[i].SetWasMoved(teamId, false);
            if (meshGraph.groups[i].GetEnqueued(teamId))
            {
                Debug.LogWarning("Vertex marked as still in queue.");
                meshGraph.groups[i].SetEnqueued(teamId, false);
            }
        }

        //  Update the mesh
        deformableMeshes[0].GetMeshFilter().mesh.SetVertices(vertices);
        deformableMeshes[0].GetMeshFilter().mesh.RecalculateNormals();
    }