@@ -159,12 +159,31 @@ type CapsuleShape =
159159 TransformOpt : Affine option
160160 PropertiesOpt : BodyShapeProperties option }
161161
162- /// The shape of a physics body capsule .
162+ /// The shape of a physics body rounded box .
163163type BoxRoundedShape =
164164 { Size : Vector3
165165 Radius : single
166166 TransformOpt : Affine option
167167 PropertiesOpt : BodyShapeProperties option }
168+
169+ /// The shape of a massless physics body in terms of one line segment.
170+ /// Collision occurs at its side.
171+ type EdgeShape =
172+ { Start : Vector3
173+ Stop : Vector3
174+ TransformOpt : Affine option
175+ PropertiesOpt : BodyShapeProperties option }
176+
177+ /// The shape of a massless physics body in terms of a free form sequence of line segments.
178+ /// Collision occurs at its sides. When closed, the last link connects to the first.
179+ /// It is expected that self-intersection does not occur.
180+ /// It properly handles ghost collisions compared to multiple EdgeShapes: https://box2d.org/posts/2020/06/ghost-collisions/
181+ /// Box2D and Aether.Physics2D call this a ChainShape, but it's not a physical chain.
182+ type ContourShape =
183+ { Links : Vector3 array
184+ Closed : bool
185+ TransformOpt : Affine option
186+ PropertiesOpt : BodyShapeProperties option }
168187
169188/// The shape of a physics body defined by body-relative points.
170189type PointsShape =
@@ -214,6 +233,8 @@ type BodyShape =
214233 | SphereShape of SphereShape
215234 | CapsuleShape of CapsuleShape
216235 | BoxRoundedShape of BoxRoundedShape
236+ | EdgeShape of EdgeShape
237+ | ContourShape of ContourShape
217238 | PointsShape of PointsShape
218239 | GeometryShape of GeometryShape
219240 | StaticModelShape of StaticModelShape
@@ -229,6 +250,8 @@ type BodyShape =
229250 | SphereShape sphere -> sphere.TransformOpt
230251 | CapsuleShape capsule -> capsule.TransformOpt
231252 | BoxRoundedShape boxRounded -> boxRounded.TransformOpt
253+ | EdgeShape edge -> edge.TransformOpt
254+ | ContourShape contour -> contour.TransformOpt
232255 | PointsShape points -> points.TransformOpt
233256 | GeometryShape geometry -> geometry.TransformOpt
234257 | StaticModelShape staticModel -> staticModel.TransformOpt
@@ -244,6 +267,8 @@ type BodyShape =
244267 | SphereShape sphere -> sphere.PropertiesOpt
245268 | CapsuleShape capsule -> capsule.PropertiesOpt
246269 | BoxRoundedShape boxRounded -> boxRounded.PropertiesOpt
270+ | EdgeShape edge -> edge.PropertiesOpt
271+ | ContourShape contour -> contour.PropertiesOpt
247272 | PointsShape points -> points.PropertiesOpt
248273 | GeometryShape geometry -> geometry.PropertiesOpt
249274 | StaticModelShape staticModel -> staticModel.PropertiesOpt
@@ -260,6 +285,8 @@ type BodyShape =
260285 | SphereShape _
261286 | CapsuleShape _
262287 | BoxRoundedShape _
288+ | EdgeShape _
289+ | ContourShape _
263290 | PointsShape _ -> true
264291 | GeometryShape _
265292 | StaticModelShape _
@@ -410,11 +437,11 @@ type BodyJointId =
410437
411438/// Allows users to create their own one-body 2D joints.
412439type OneBodyJoint2d =
413- { CreateOneBodyJoint : nkast .Aether .Physics2D .Dynamics .Body -> nkast .Aether .Physics2D .Dynamics .Joints .Joint }
440+ { CreateOneBodyJoint : ( single -> single ) -> ( Vector3 -> nkast . Aether . Physics2D . Common . Vector2 ) -> nkast .Aether .Physics2D .Dynamics .Body -> nkast .Aether .Physics2D .Dynamics .Joints .Joint }
414441
415442/// Allows users to create their own two-body 2D joints.
416443type TwoBodyJoint2d =
417- { CreateTwoBodyJoint : nkast .Aether .Physics2D .Dynamics .Body -> nkast .Aether .Physics2D .Dynamics .Body -> nkast .Aether .Physics2D .Dynamics .Joints .Joint }
444+ { CreateTwoBodyJoint : ( single -> single ) -> ( Vector3 -> nkast . Aether . Physics2D . Common . Vector2 ) -> nkast .Aether .Physics2D .Dynamics .Body -> nkast .Aether .Physics2D .Dynamics .Body -> nkast .Aether .Physics2D .Dynamics .Joints .Joint }
418445
419446/// Allows users to create their own one-body 3D joints.
420447type OneBodyJoint3d =
@@ -614,6 +641,9 @@ type PhysicsEngineRenderContext = interface end
614641/// TODO: investigate if we'll ever have to handle enough physics or integration messages to necessitate the use of
615642/// SList instead of List.
616643type PhysicsEngine =
644+
645+ /// Get the global gravity used in the physics engine.
646+ abstract Gravity : Vector3
617647
618648 /// Check that the physics engine contain the body with the given body id.
619649 abstract GetBodyExists : bodyId : BodyId -> bool
@@ -674,6 +704,7 @@ type [<ReferenceEquality>] StubPhysicsEngine =
674704 private { StubPhysicsEngine : unit }
675705 static member make () = { StubPhysicsEngine = () }
676706 interface PhysicsEngine with
707+ member physicsEngine.Gravity = v3Zero
677708 member physicsEngine.GetBodyExists _ = false
678709 member physicsEngine.GetBodyContactNormals _ = failwith " No bodies in StubPhysicsEngine"
679710 member physicsEngine.GetBodyLinearVelocity _ = failwith " No bodies in StubPhysicsEngine"
@@ -709,7 +740,8 @@ module Physics =
709740 | Constants.Physics.CollisionWildcard -> - 1
710741 | _ -> Convert.ToInt32 ( categoryMask, 2 )
711742
712- /// Localize a primitive body shape to a specific size; non-primitive shapes are unaffected.
743+ /// Localize a primitive body shape to a specific size, typically used in tile maps.
744+ /// Non-primitive shapes are unaffected as they should be scaled independently.
713745 let rec localizePrimitiveBodyShape ( size : Vector3 ) bodyShape =
714746 let scaleTranslation ( scalar : Vector3 ) ( transformOpt : Affine option ) =
715747 match transformOpt with
@@ -721,9 +753,11 @@ module Physics =
721753 | SphereShape sphereShape -> SphereShape { sphereShape with Radius = size.X * sphereShape.Radius; TransformOpt = scaleTranslation size sphereShape.TransformOpt }
722754 | CapsuleShape capsuleShape -> CapsuleShape { capsuleShape with Height = size.Y * capsuleShape.Height; Radius = size.Y * capsuleShape.Radius; TransformOpt = scaleTranslation size capsuleShape.TransformOpt }
723755 | BoxRoundedShape boxRoundedShape -> BoxRoundedShape { boxRoundedShape with Size = Vector3.Multiply ( size, boxRoundedShape.Size); Radius = size.X * boxRoundedShape.Radius; TransformOpt = scaleTranslation size boxRoundedShape.TransformOpt }
756+ | EdgeShape edgeShape -> EdgeShape { edgeShape with Start = edgeShape.Start * size; Stop = edgeShape.Stop * size; TransformOpt = scaleTranslation size edgeShape.TransformOpt }
757+ | ContourShape contourShape -> ContourShape { contourShape with Links = Array.map ( fun vertex -> size * vertex) contourShape.Links; TransformOpt = scaleTranslation size contourShape.TransformOpt }
724758 | PointsShape pointsShape -> PointsShape { pointsShape with Points = Array.map ( fun vertex -> size * vertex) pointsShape.Points; TransformOpt = scaleTranslation size pointsShape.TransformOpt }
725759 | GeometryShape _ as geometryShape -> geometryShape
726760 | StaticModelShape _ as staticModelShape -> staticModelShape
727761 | StaticModelSurfaceShape _ as staticModelSurfaceShape -> staticModelSurfaceShape
728762 | TerrainShape _ as terrainShape -> terrainShape
729- | BodyShapes bodyShapes -> BodyShapes ( List.map ( localizePrimitiveBodyShape size) bodyShapes)
763+ | BodyShapes bodyShapes -> BodyShapes ( List.map ( localizePrimitiveBodyShape size) bodyShapes)
0 commit comments