Ejemplo n.º 1
0
    private void AdjustVerticesForImpact(Vector3 impactPoint, Vector3 impactForce,
                                         Meshinator.ImpactShapes impactShape, Meshinator.ImpactTypes impactType)
    {
        // Get the radius from the impactPoint that we'll be looking into
        float impactRadius = impactForce.magnitude;

        // Figure out how many vertices we will move
        Dictionary <int, float> movedVertexToForceMagnitudeMap = new Dictionary <int, float>();

        for (int i = 0; i < m_Vertices.Count; i++)
        {
            Vector3 vertex = m_Vertices[i];

            // Figure out the distance from the impact to this vector in different ways to
            // determine the shape of the impact
            Vector3 distanceVector = Vector3.zero;
            switch (impactShape)
            {
            case Meshinator.ImpactShapes.FlatImpact:
                distanceVector = Vector3.Project(vertex - impactPoint, impactForce.normalized);
                break;

            case Meshinator.ImpactShapes.SphericalImpact:
                distanceVector = vertex - impactPoint;
                break;
            }

            // If we're using a FlatImpact and the angle between the impact vector, and this vertex to the point
            // if impact is greater than 90 degrees, then make the distance the negative of itself. This fixes some
            // weird issues that pop up by the physics system determining that the point of collision is inside the
            // mesh instead of on the surface
            float distance = distanceVector.magnitude;
            if (impactShape == Meshinator.ImpactShapes.FlatImpact &&
                Vector3.Angle(vertex - impactPoint, impactForce) > 90f)
            {
                distance = -distance;
            }

            // If this vertex is within the impact radius, then we'll be moving this vertex.
            // Store the magnitude of the force by which this vertex will be moved
            float vertexForceMagnitude = Mathf.Max(0, (impactRadius - distance)) * c_CompressionResistance;
            if (distance < impactRadius && vertexForceMagnitude > 0)
            {
                movedVertexToForceMagnitudeMap.Add(i, vertexForceMagnitude);
            }
        }

        // Depending on our ImpactType, deform the mesh appropriately
        switch (impactType)
        {
        case Meshinator.ImpactTypes.Compression:
            CompressMeshVertices(movedVertexToForceMagnitudeMap, impactForce);
            break;

        case Meshinator.ImpactTypes.Fracture:
            FractureMeshVertices(movedVertexToForceMagnitudeMap, impactForce);
            break;
        }
    }
Ejemplo n.º 2
0
    public void Impact(Vector3 impactPoint, Vector3 impactForce, Meshinator.ImpactShapes impactShape, Meshinator.ImpactTypes impactType)
    {
        // Look through all triangles to see which ones are within the impactForce from the impactPoint,
        // and measure the area of every triangle in the list
        Dictionary <int, float> triangleIndexToTriangleArea = new Dictionary <int, float>();

        foreach (int triangleIndex in GetIntersectedTriangleIndices(impactPoint, impactForce.magnitude))
        {
            float areaOfTriangle = GetAreaOfTriangle(triangleIndex);
            triangleIndexToTriangleArea.Add(triangleIndex, areaOfTriangle);
        }

        // Keep breaking down the largest triangle until there are more than c_MinTrianglesPerImpact
        // triangles in the list
        while (triangleIndexToTriangleArea.Keys.Count < c_MinTrianglesPerImpact)
        {
            // If we have 64988 vertices or more, we can't add any more or we risk going over the
            // 65000 limit, which causes problems for unity.
            if (m_Vertices.Count > 64988)
            {
                break;
            }

            // Get the index of the biggest triangle in our dictionary
            int indexOfLargestTriangle = GetIndexOfLargestTriangle(triangleIndexToTriangleArea);

            // Break that triangle down and remove it from the dictionary
            List <int> newTriangleIndices = BreakDownTriangle(indexOfLargestTriangle);
            triangleIndexToTriangleArea.Remove(indexOfLargestTriangle);

            // Measure the areas of the resulting triangles, and add them to the dictionary
            foreach (int triangleIndex in newTriangleIndices)
            {
                // Make sure each triangle is still intersected by our force before we add it back to the list
                if (IsTriangleIndexIntersected(triangleIndex, impactPoint, impactForce.magnitude))
                {
                    float areaOfTriangle = GetAreaOfTriangle(triangleIndex);
                    triangleIndexToTriangleArea.Add(triangleIndex, areaOfTriangle);
                }
            }
        }

        // Now that we have the proper vertices and triangles, actually go about deforming the mesh
        // by moving the vertices around.
        AdjustVerticesForImpact(impactPoint, impactForce, impactShape, impactType);
    }