private MeshQuery.Result ModifyVertices(MeshQuery query, List <int> indecies) { var upMode = query.ForceDirection.y > 0; var modified = 0; var scannedTriangles = 0; // modify vertices for (int j = 0; j < indecies.Count; j++) { int outerIndex = indecies[j] * 3; for (var k = 0; k < 3; k++) { var index = outerIndex + k; var vertex = query.Vertices[index]; var distance = Vector3.Distance(vertex, query.Epicenter); if (distance < query.Radius) { float heightDiff = query.GetForceChange(distance); query.Vertices[index] = new Vector3( vertex.x, vertex.y + (upMode ? heightDiff : -heightDiff), vertex.z); modified++; } } scannedTriangles++; } return(new MeshQuery.Result(query.Vertices) { ModifiedVertices = modified, ScannedTriangles = scannedTriangles }); }
/// <summary> Modifies mesh plane based on it's equation parameters. </summary> protected MeshQuery.Result Modify(MeshQuery query, int startIndex, int endIndex, Vector3 n, float magnitude, float d) { var halfVertexCount = query.Vertices.Length / 2; var vertices = query.Vertices; int modified = 0; var destroyed = 0; for (int j = startIndex; j < endIndex; j += 3) { // triangle is already collapsed if (vertices[j] == vertices[j + 1]) { continue; } for (int i = j; i < j + 3; i++) { var v = vertices[i]; var distance = Vector3.Distance(v, query.Epicenter); if (distance < query.Radius) { var distanceToWall = (v.x * n.x + v.y * n.y + v.z * n.z - d) / magnitude; var forceChange = query.GetForceChange(distance); // NOTE whole traingle should be removed as one of the vertices is // moved more than threshold allows if (Math.Abs(distanceToWall + forceChange) > query.OffsetThreshold) { // collapse triangle into point var firstVertIndex = i - i % 3; vertices[firstVertIndex + 1] = vertices[firstVertIndex]; vertices[firstVertIndex + 2] = vertices[firstVertIndex]; var backSideIndex = halfVertexCount + firstVertIndex; vertices[backSideIndex + 1] = vertices[backSideIndex]; vertices[backSideIndex + 2] = vertices[backSideIndex]; destroyed += 3; break; } vertices[i] = v + forceChange * query.ForceDirection; vertices[halfVertexCount + i] = vertices[i]; modified++; } } } return(new MeshQuery.Result(query.Vertices) { DestroyedVertices = destroyed, ModifiedVertices = modified, ScannedTriangles = -1 }); }
/// <inheritdoc /> public MeshQuery.Result Modify(MeshQuery query) { var vertices = query.Vertices; int modified = 0; var destroyed = 0; for (int j = 0; j < vertices.Length; j += 3) { // triangle is already collapsed if (vertices[j] == vertices[j + 1]) { continue; } for (int i = j; i < j + 3; i++) { var v = vertices[i]; var distance = Vector3.Distance(v, query.Epicenter); if (distance < query.Radius) { var forceChange = query.GetForceChange(distance); var distanceToCenter = Vector3.Distance(v, _center); if (Math.Abs(_radius - distanceToCenter + forceChange) > query.OffsetThreshold) { // collapse triangle into point var firstVertIndex = i - i % 3; vertices[firstVertIndex + 1] = vertices[firstVertIndex]; vertices[firstVertIndex + 2] = vertices[firstVertIndex]; destroyed += 3; break; } var forceDirection = (_center - v).normalized; vertices[i] = v + forceChange * forceDirection; modified++; } } } return(new MeshQuery.Result(vertices) { DestroyedVertices = destroyed, ModifiedVertices = modified }); }