Example #1
0
        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());
        }
Example #5
0
        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());
        }