public HitObject[] GenerateHitObjects(Table.Table table, PrimitiveMeshGenerator meshGenerator, IItem item) { if (_data.Name == "playfield_mesh") { _data.IsVisible = false; _primitive.UseAsPlayfield = true; } // playfield can't be a toy if (_data.IsToy && !_primitive.UseAsPlayfield) { return(new HitObject[0]); } 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); } return(MeshToHitObjects(mesh, ItemType.Primitive, item).Select(ho => SetupHitObject(ho, table)).ToArray()); }
public Primitive(PrimitiveData data) : base(data) { _meshGenerator = new PrimitiveMeshGenerator(Data); _hitGenerator = new PrimitiveHitGenerator(this); }
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()); }