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())); } } }