public static IEnumerable <HitObject> MeshToHitObjects(Mesh mesh, ItemType itemType, IItem item) { var hitObjects = new List <HitObject>(); var addedEdges = new EdgeSet(); // add collision triangles and edges for (var i = 0; i < mesh.Indices.Length; i += 3) { var i0 = mesh.Indices[i]; var i1 = mesh.Indices[i + 1]; var i2 = mesh.Indices[i + 2]; // NB: HitTriangle wants CCW vertices, but for rendering we have them in CW order var rgv3D = new[] { mesh.Vertices[i0].GetVertex(), mesh.Vertices[i2].GetVertex(), mesh.Vertices[i1].GetVertex(), }; hitObjects.Add(new HitTriangle(rgv3D, itemType, item)); hitObjects.AddRange(addedEdges.AddHitEdge(i0, i1, rgv3D[0], rgv3D[2], itemType, item)); hitObjects.AddRange(addedEdges.AddHitEdge(i1, i2, rgv3D[2], rgv3D[1], itemType, item)); hitObjects.AddRange(addedEdges.AddHitEdge(i2, i0, rgv3D[1], rgv3D[0], itemType, item)); } // add collision vertices foreach (var vertex in mesh.Vertices) { hitObjects.Add(new HitPoint(vertex.GetVertex(), itemType, item)); } return(hitObjects); }
private HitObject[] GenerateCollidables(Mesh hitMesh, EdgeSet addedEdges, bool setHitObject, Table.Table table, IItem item) { var hitObjects = new List <HitObject>(); // add the normal drop target as collidable but without hit event for (var i = 0; i < hitMesh.Indices.Length; i += 3) { var i0 = hitMesh.Indices[i]; var i1 = hitMesh.Indices[i + 1]; var i2 = hitMesh.Indices[i + 2]; // NB: HitTriangle wants CCW vertices, but for rendering we have them in CW order var rgv3D = new [] { new Vertex3D(hitMesh.Vertices[i0].X, hitMesh.Vertices[i0].Y, hitMesh.Vertices[i0].Z), new Vertex3D(hitMesh.Vertices[i2].X, hitMesh.Vertices[i2].Y, hitMesh.Vertices[i2].Z), new Vertex3D(hitMesh.Vertices[i1].X, hitMesh.Vertices[i1].Y, hitMesh.Vertices[i1].Z) }; hitObjects.Add(SetupHitObject(new HitTriangle(rgv3D, ItemType.HitTarget, item), setHitObject, table)); hitObjects.AddRange(addedEdges.AddHitEdge(i0, i1, rgv3D[0], rgv3D[2], ItemType.HitTarget, item).Select(obj => SetupHitObject(obj, setHitObject, table))); hitObjects.AddRange(addedEdges.AddHitEdge(i1, i2, rgv3D[2], rgv3D[1], ItemType.HitTarget, item).Select(obj => SetupHitObject(obj, setHitObject, table))); hitObjects.AddRange(addedEdges.AddHitEdge(i2, i0, rgv3D[1], rgv3D[0], ItemType.HitTarget, item).Select(obj => SetupHitObject(obj, setHitObject, table))); } // add collision vertices foreach (var vertex in hitMesh.Vertices) { hitObjects.Add(SetupHitObject(new HitPoint(vertex.GetVertex(), ItemType.HitTarget, item), setHitObject, table)); } return(hitObjects.ToArray()); }
private static IEnumerable <HitObject> GenerateHitEdge(Mesh mesh, EdgeSet addedEdges, int i, int j) { var v1 = new Vertex3D(mesh.Vertices[i].X, mesh.Vertices[i].Y, mesh.Vertices[i].Z); var v2 = new Vertex3D(mesh.Vertices[j].X, mesh.Vertices[j].Y, mesh.Vertices[j].Z); return(addedEdges.AddHitEdge(i, j, v1, v2, ItemType.Rubber)); }
private HitObject[] GenerateHitTargetHits(Table.Table table, IItem item) { var addedEdges = new EdgeSet(); var hitMesh = _meshGenerator.GetRenderObjects(table, Origin.Original, false).RenderObjects[0].Mesh; var hitObjects = GenerateCollidables(hitMesh, addedEdges, _data.IsLegacy, table, item).ToList(); var tempMatrix = new Matrix3D().RotateZMatrix(MathF.DegToRad(_data.RotZ)); var fullMatrix = new Matrix3D().Multiply(tempMatrix); if (!_data.IsLegacy) { var rgv3D = new Vertex3D[DropTargetHitPlaneVertices.Length]; var hitShapeOffset = 0.18f; if (_data.TargetType == TargetType.DropTargetBeveled) { hitShapeOffset = 0.25f; } if (_data.TargetType == TargetType.DropTargetFlatSimple) { hitShapeOffset = 0.13f; } // now create a special hit shape with hit event enabled to prevent a hit event when hit from behind for (var i = 0; i < DropTargetHitPlaneVertices.Length; i++) { var dropTargetHitPlaneVertex = DropTargetHitPlaneVertices[i]; var vert = new Vertex3D( dropTargetHitPlaneVertex.X, dropTargetHitPlaneVertex.Y + hitShapeOffset, dropTargetHitPlaneVertex.Z ); vert.X *= _data.Size.X; vert.Y *= _data.Size.Y; vert.Z *= _data.Size.Z; vert.MultiplyMatrix(fullMatrix); rgv3D[i] = new Vertex3D( vert.X + _data.Position.X, vert.Y + _data.Position.Y, vert.Z * table.GetScaleZ() + _data.Position.Z + table.TableHeight ); } for (var i = 0; i < DropTargetHitPlaneIndices.Length; i += 3) { var i0 = DropTargetHitPlaneIndices[i]; var i1 = DropTargetHitPlaneIndices[i + 1]; var i2 = DropTargetHitPlaneIndices[i + 2]; // NB: HitTriangle wants CCW vertices, but for rendering we have them in CW order var rgv3D2 = new[] { rgv3D[i0], rgv3D[i2], rgv3D[i1] }; hitObjects.Add(SetupHitObject(new HitTriangle(rgv3D2, ItemType.HitTarget, item), true, table)); hitObjects.AddRange(addedEdges.AddHitEdge(i0, i1, rgv3D2[0], rgv3D2[2], ItemType.HitTarget, item).Select(obj => SetupHitObject(obj, true, table))); hitObjects.AddRange(addedEdges.AddHitEdge(i1, i2, rgv3D2[2], rgv3D2[1], ItemType.HitTarget, item).Select(obj => SetupHitObject(obj, true, table))); hitObjects.AddRange(addedEdges.AddHitEdge(i2, i0, rgv3D2[1], rgv3D2[0], ItemType.HitTarget, item).Select(obj => SetupHitObject(obj, true, table))); } // add collision vertices for (var i = 0; i < DropTargetHitPlaneVertices.Length; ++i) { hitObjects.Add(SetupHitObject(new HitPoint(rgv3D[i], ItemType.HitTarget, item), true, table)); } } return(hitObjects.ToArray()); }
public HitObject[] GenerateHitObjects(Table.Table table, PrimitiveMeshGenerator meshGenerator) { var hitObjects = new List <HitObject>(); if (_data.Name == "playfield_mesh") { _data.IsVisible = false; _primitive.UseAsPlayfield = true; } // playfield can't be a toy if (_data.IsToy && !_primitive.UseAsPlayfield) { return(hitObjects.ToArray()); } var mesh = meshGenerator.GetTransformedMesh(table, Origin.Global, false); var reducedVertices = System.Math.Max( (uint)MathF.Pow(mesh.Vertices.Length, MathF.Clamp(1f - _data.CollisionReductionFactor, 0f, 1f) * 0.25f + 0.75f), 420u //!! 420 = magic ); if (reducedVertices < mesh.Vertices.Length) { mesh = ComputeReducedMesh(mesh, reducedVertices); } var addedEdges = new EdgeSet(); // add collision triangles and edges for (var i = 0; i < mesh.Indices.Length; i += 3) { var i0 = mesh.Indices[i]; var i1 = mesh.Indices[i + 1]; var i2 = mesh.Indices[i + 2]; // NB: HitTriangle wants CCW vertices, but for rendering we have them in CW order var rgv3D = new[] { mesh.Vertices[i0].GetVertex(), mesh.Vertices[i2].GetVertex(), mesh.Vertices[i1].GetVertex(), }; hitObjects.Add(new HitTriangle(rgv3D, ItemType.Primitive)); hitObjects.AddRange(addedEdges.AddHitEdge(i0, i1, rgv3D[0], rgv3D[2], ItemType.Primitive)); hitObjects.AddRange(addedEdges.AddHitEdge(i1, i2, rgv3D[2], rgv3D[1], ItemType.Primitive)); hitObjects.AddRange(addedEdges.AddHitEdge(i2, i0, rgv3D[1], rgv3D[0], ItemType.Primitive)); } // add collision vertices foreach (var vertex in mesh.Vertices) { hitObjects.Add(new HitPoint(vertex.GetVertex(), ItemType.Primitive)); } return(hitObjects.Select(ho => SetupHitObject(ho, table)).ToArray()); }