Пример #1
0
        public static void Create(BlobBuilder builder, HitObject src, ref BlobPtr <Collider> dest)
        {
            switch (src)
            {
            case KickerHit kickerHit:
                CircleCollider.Create(builder, kickerHit, ref dest, ColliderType.KickerCircle);
                break;

            case TriggerHitCircle triggerHitCircle:
                CircleCollider.Create(builder, triggerHitCircle, ref dest, ColliderType.TriggerCircle);
                break;

            case TriggerHitLineSeg triggerHitLine:
                LineCollider.Create(builder, triggerHitLine, ref dest, ColliderType.TriggerLine);
                break;

            case BumperHit bumperHit:
                CircleCollider.Create(builder, bumperHit, ref dest, ColliderType.Bumper);
                break;

            case HitCircle hitCircle:
                CircleCollider.Create(builder, hitCircle, ref dest);
                break;

            case LineSegSlingshot lineSegSlingshot:
                LineSlingshotCollider.Create(builder, lineSegSlingshot, ref dest);
                break;

            case FlipperHit flipperHit:
                FlipperCollider.Create(builder, flipperHit, ref dest);
                break;

            case GateHit gateHit:
                GateCollider.Create(builder, gateHit, ref dest);
                break;

            case LineSeg lineSeg:
                LineCollider.Create(builder, lineSeg, ref dest);
                break;

            case HitLine3D hitLine3D:
                Line3DCollider.Create(builder, hitLine3D, ref dest);
                break;

            case HitLineZ hitLineZ:
                LineZCollider.Create(builder, hitLineZ, ref dest);
                break;

            case HitPoint hitPoint:
                PointCollider.Create(builder, hitPoint, ref dest);
                break;

            case HitPlane hitPlane:
                PlaneCollider.Create(builder, hitPlane, ref dest);
                break;

            case PlungerHit plungerCollider:
                PlungerCollider.Create(builder, plungerCollider, ref dest);
                break;

            case SpinnerHit spinnerHit:
                SpinnerCollider.Create(builder, spinnerHit, ref dest);
                break;

            case HitTriangle hitTriangle:
                TriangleCollider.Create(builder, hitTriangle, ref dest);
                break;

            default:
                Logger.Warn("Unsupported collider {0}, skipping.", src.GetType().Name);
                break;
            }
        }
        internal void GenerateColliders(float tableHeight, List <ICollider> colliders, float margin = 0f)
        {
            var rv          = _meshGenerator.GetRampVertex(tableHeight, PhysicsConstants.HitShapeDetailLevel, true);
            var rgvLocal    = rv.RgvLocal;
            var rgHeight1   = rv.PointHeights;
            var vertexCount = rv.VertexCount;

            var h = GetWallHeights();
            var wallHeightRight = h.x;
            var wallHeightLeft  = h.y;

            float2 pv1, pv2, pv3 = new float2(), pv4 = new float2();

            // Add line segments for right ramp wall.
            if (wallHeightRight > 0.0f)
            {
                for (var i = 0; i < vertexCount - 1; i++)
                {
                    pv2 = rgvLocal[i].ToUnityFloat2();
                    pv3 = rgvLocal[i + 1].ToUnityFloat2();

                    GenerateWallLineSeg(pv2, pv3, i > 0, rgHeight1[i],
                                        rgHeight1[i + 1], wallHeightRight, colliders);
                    GenerateWallLineSeg(pv3, pv2, i < vertexCount - 2, rgHeight1[i],
                                        rgHeight1[i + 1], wallHeightRight, colliders);

                    // add joints at start and end of right wall
                    if (i == 0)
                    {
                        colliders.Add(new LineZCollider(pv2, rgHeight1[0], rgHeight1[0] + wallHeightRight,
                                                        _api.GetColliderInfo()));
                    }

                    if (i == vertexCount - 2)
                    {
                        colliders.Add(new LineZCollider(pv3, rgHeight1[vertexCount - 1], rgHeight1[vertexCount - 1] + wallHeightRight,
                                                        _api.GetColliderInfo()));
                    }
                }
            }

            // Add line segments for left ramp wall.
            if (wallHeightLeft > 0.0f)
            {
                for (var i = 0; i < vertexCount - 1; i++)
                {
                    pv2 = rgvLocal[vertexCount + i].ToUnityFloat2();
                    pv3 = rgvLocal[vertexCount + i + 1].ToUnityFloat2();

                    GenerateWallLineSeg(pv2, pv3, i > 0, rgHeight1[vertexCount - i - 2],
                                        rgHeight1[vertexCount - i - 1], wallHeightLeft, colliders);
                    GenerateWallLineSeg(pv3, pv2, i < vertexCount - 2, rgHeight1[vertexCount - i - 2],
                                        rgHeight1[vertexCount - i - 1], wallHeightLeft, colliders);

                    // add joints at start and end of left wall
                    if (i == 0)
                    {
                        colliders.Add(new LineZCollider(pv2, rgHeight1[vertexCount - 1],
                                                        rgHeight1[vertexCount - 1] + wallHeightLeft, _api.GetColliderInfo()));
                    }

                    if (i == vertexCount - 2)
                    {
                        colliders.Add(new LineZCollider(pv3, rgHeight1[0], rgHeight1[0] + wallHeightLeft,
                                                        _api.GetColliderInfo()));
                    }
                }
            }

            // Add hit triangles for the ramp floor.
            TriangleCollider ph3dPolyOld = default;
            var isOldSet = false;

            for (var i = 0; i < vertexCount - 1; i++)
            {
                /*
                 * Layout of one ramp quad seen from above, ramp direction is bottom to top:
                 *
                 *    3 - - 4
                 *    | \   |
                 *    |   \ |
                 *    2 - - 1
                 */
                pv1 = rgvLocal[i].ToUnityFloat2();                       // i-th right
                pv2 = rgvLocal[vertexCount * 2 - i - 1].ToUnityFloat2(); // i-th left
                pv3 = rgvLocal[vertexCount * 2 - i - 2].ToUnityFloat2(); // (i+1)-th left
                pv4 = rgvLocal[i + 1].ToUnityFloat2();                   // (i+1)-th right

                // left ramp floor triangle, CCW order
                var rg0 = new float3(pv2.x, pv2.y, rgHeight1[i] + margin);
                var rg1 = new float3(pv1.x, pv1.y, rgHeight1[i] + margin);
                var rg2 = new float3(pv3.x, pv3.y, rgHeight1[i + 1] + margin);

                // add joint for starting edge of ramp
                if (i == 0)
                {
                    colliders.Add(new Line3DCollider(rg0, rg1, _api.GetColliderInfo()));
                }

                // add joint for left edge
                colliders.Add(new Line3DCollider(rg0, rg2, _api.GetColliderInfo()));

                // degenerate triangles happen if width is 0 at some point
                if (!TriangleCollider.IsDegenerate(rg0, rg1, rg2))
                {
                    var ph3dPoly = new TriangleCollider(rg0, rg1, rg2, _api.GetColliderInfo());
                    colliders.Add(ph3dPoly);

                    CheckJoint(isOldSet, in ph3dPolyOld, in ph3dPoly, colliders);
                    ph3dPolyOld = ph3dPoly;
                    isOldSet    = true;
                }

                // right ramp floor triangle, CCW order
                rg0 = new float3(pv3.x, pv3.y, rgHeight1[i + 1] + margin);
                rg1 = new float3(pv1.x, pv1.y, rgHeight1[i] + margin);
                rg2 = new float3(pv4.x, pv4.y, rgHeight1[i + 1] + margin);

                // add joint for right edge
                colliders.Add(new Line3DCollider(rg1, rg2, _api.GetColliderInfo()));

                if (!TriangleCollider.IsDegenerate(rg0, rg1, rg2))
                {
                    var ph3dPoly = new TriangleCollider(rg0, rg1, rg2, _api.GetColliderInfo());
                    colliders.Add(ph3dPoly);

                    CheckJoint(isOldSet, in ph3dPolyOld, in ph3dPoly, colliders);
                    ph3dPolyOld = ph3dPoly;
                    isOldSet    = true;
                }
            }

            if (vertexCount >= 2)
            {
                // add joint for final edge of ramp
                var v1 = new float3(pv4.x, pv4.y, rgHeight1[vertexCount - 1]);
                var v2 = new float3(pv3.x, pv3.y, rgHeight1[vertexCount - 1]);
                colliders.Add(new Line3DCollider(v1, v2, _api.GetColliderInfo()));
            }

            // add outside bottom,
            // joints at the intersections are not needed since the inner surface has them
            // this surface is identical... except for the direction of the normal face.
            // hence the joints protect both surface edges from having a fall through
            for (var i = 0; i < vertexCount - 1; i++)
            {
                // see sketch above
                pv1 = rgvLocal[i].ToUnityFloat2();
                pv2 = rgvLocal[vertexCount * 2 - i - 1].ToUnityFloat2();
                pv3 = rgvLocal[vertexCount * 2 - i - 2].ToUnityFloat2();
                pv4 = rgvLocal[i + 1].ToUnityFloat2();

                // left ramp triangle, order CW
                var rg0 = new float3(pv1.x, pv1.y, rgHeight1[i]);
                var rg1 = new float3(pv2.x, pv2.y, rgHeight1[i]);
                var rg2 = new float3(pv3.x, pv3.y, rgHeight1[i + 1]);

                if (!TriangleCollider.IsDegenerate(rg0, rg1, rg2))
                {
                    colliders.Add(new TriangleCollider(rg0, rg1, rg2, _api.GetColliderInfo()));
                }

                // right ramp triangle, order CW
                rg0 = new float3(pv3.x, pv3.y, rgHeight1[i + 1]);
                rg1 = new float3(pv4.x, pv4.y, rgHeight1[i + 1]);
                rg2 = new float3(pv1.x, pv1.y, rgHeight1[i]);

                if (!TriangleCollider.IsDegenerate(rg0, rg1, rg2))
                {
                    colliders.Add(new TriangleCollider(rg0, rg1, rg2, _api.GetColliderInfo()));
                }
            }
        }