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; } }
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); }