flutter3d_physics library
Collision, character movement and cloth, with nothing above them.
Shapes that overlap exactly, a broadphase over a uniform grid, sweeps and rays that do not tunnel, and a controller that walks, jumps, climbs a step and rides a lift. Nothing here knows what a monster is, what a level is, or how a frame is drawn.
src/cloth/ was its own package once — an XPBD solver reacting to
this package's own CollisionShapes and depending on nothing else, which
made "a package of its own" the only reason it stayed apart. It moved
here rather than the other way round because collision is the older,
larger half and cloth is the one thing that only ever pushed against it.
Plain Dart. No Flutter and no flutter3d, so the whole of it runs under
dart test on the VM. That is not tidiness: the failures this code has are
the ones that happen once in a thousand steps — a body that ends up inside
geometry, a sweep that passes through a wall at a high speed, a platform
that stops carrying its passenger — and finding those means running
thousands of steps in a loop, which is possible exactly because none of it
needs a device.
Layers are numbers here, and names somewhere else
A collider carries a layer and a mask, and two of them meet when each is
in the other's mask. Which bit means what is a game's business: this package
shipped as part of one for a while and its layer list named monster,
pickup and projectile, which is exactly the knowledge a collision world
must not have. Layers.all is the only constant left, because "every bit"
means the same thing in every game.
Classes
- CharacterController
- Moves a box through a CollisionWorld the way a player expects.
- ClothMesh
- A grid of particles and the constraints between them, as flat arrays — the shape every hot loop in this package walks without an allocation.
- ClothObstacle
- One CollisionShape, positioned, for a cloth to push itself out of.
- ClothSettings
- How a ClothMesh moves, as values rather than as solver internals.
- Collider
- A shape, somewhere, that takes part in collision.
- CollisionBox
- An axis-aligned box: level geometry, and the player.
- CollisionCapsule
-
An upright capsule: a segment of length
2 * halfHeightwith radius around it. - CollisionHeightfield
- Ground as a grid of sampled heights: the fifth shape, and the first one that is not convex.
- CollisionListener
- Told when colliders begin, continue and stop overlapping.
- CollisionShape
- A collision volume, positioned by whatever owns it.
- CollisionSphere
- A sphere: pickups, projectiles, blast radii.
- CollisionWedge
- A box with one edge cut away: a ramp.
- CollisionWorld
- Everything in the level that can be collided with, and the queries over it.
- Contact
- Two shapes, overlapping.
- Dynamics
- Layers
- The one layer constant that means the same thing in every game.
- MovementTuning
- Every number that decides how the player feels, in one place.
- Nearly
- What "close enough" means in this package, once.
- RayHit
- Where a ray met something.
- RigidBody
- SpatialGrid
- A uniform grid over the XZ plane, holding integer handles.
- SweepHit
- Where a swept shape first touched something.
- SweptContact
- What a ContactFilter is told about the contact it is judging.
- WindSettings
- A uniform wind field, applied per triangle as drag along its own normal.
Enums
- ColliderKind
- How a collider takes part in the world.
- WedgeUphill
- Which way a CollisionWedge climbs.
Functions
-
contactBetween(
CollisionShape a, Vector3 aAt, CollisionShape b, Vector3 bAt, Contact out, {double margin = 0.02}) → void -
Fills
outwhen the two shapes overlap, and clears it when they do not. -
pushOutsideObstacle(
Vector3 point, ClothObstacle obstacle, double thickness) → bool -
Pushes
pointoutside every convexobstaclesshape it has ended up inside, bythickness. -
readNumber(
Object? value) → double - A number from a snapshot, or nought.
-
readVector(
Object? value, Vector3 out) → bool - Reading a saved body back.
-
stepCloth(
ClothMesh mesh, ClothSettings settings, double dt, {List< ClothObstacle> obstacles = const []}) → void -
Advances
meshbydtseconds, in place.
Typedefs
- ContactFilter = bool Function(SweptContact contact)
- Whether a contact counts, asked of the collider and the way it faces.