w0rm / elm-physics Goto Github PK
View Code? Open in Web Editor NEW3D physics engine in Elm
Home Page: https://package.elm-lang.org/packages/w0rm/elm-physics/latest
License: BSD 3-Clause "New" or "Revised" License
3D physics engine in Elm
Home Page: https://package.elm-lang.org/packages/w0rm/elm-physics/latest
License: BSD 3-Clause "New" or "Revised" License
https://en.wikipedia.org/wiki/Capsule_(geometry)
Capsule shape is nice for modelling many interesting things.
Unlike the cylinder shape, it doesn't have to be approximated internally as a convex polyhedron with many vertices.
This makes it efficient for collisions.
TDB: api for Shape.capsule
(because elm-geometry currently doesn't support Capsule3d)
Convert non-shortcutting recursive functions to use folds instead
-- makes them more idiomatic and so easier to understand, and more efficient.
Convert short-cutting recursive functions (and those that SHOULD be short-cutting for better performance) to use visitor functions and generic recursion functions in the style of fold functions like
listRecurseUntil : (b -> Bool) -> (a -> b -> b) -> b -> List a -> b
listRecurseUntil doneFn fn seed list =
to isolate reusable recursive navigation from each function's node-specific processing.
Export fold-like generic functions that use function-typed arguments and dependent typing to reduce package dependencies. I.e. one exported fold-based function that takes a "visitor function" argument and a dependently typed acc argument and return value could replace several specialized exported functions that walk the same structure for different purposes.
Propagate this visitor pattern up the API chain to bypass the building, concatenating, mapping of temporary result lists.
Some of the recent changes caused a bug for spheres to move at a high velocity and not colliding properly.
The default max iterations per step can sometimes lead to simulation instabilities. In other cases it's too high and reduces performance. I think it would be useful if there was an "advanced" version of Physics.World.simulate
that lets the user choose a max iteration.
The current collision implementation doesn’t have a broad phase, and has n^2 complexity, because every two bodies are tested against each other.
The idea of the broad phase is to reduce potential number of collisions by building a tree that segments the space and indexes bodies inside the branches. Then this tree can be used to lookup bodies that exist within certain bounds. This lets us reduce the number of possible collision pairs.
I don’t have enough knowledge on this topic, but AABB tree seems to be what we need.
Reading the documentation for Physics.Constraint.pointToPoint
it isn't clear to me if it behaves like a weld joint or a ball joint. I'm guessing the two objects can freely rotate (unless they collide with eachother) but maybe the documentation could be explicit about this behavior?
Given a ray (world origin point and normal), we need to be able to return details like BodyId, (Body?,) contactPoint, and worldTransform of the nearest collision to the ray's origin along its normal.
It's not clear to me whether this would benefit from being implemented as a Ray Shape -- I suspect not?
There are several possible strategies differing in the order in which elements -- faces, edges, or vertices -- are tested.
Of the 6 possible permutations, "faces then edges then vertices" or "vertices then edges then faces" seem like the most promising alternatives to the current one "vertices then faces then edges".
Each strategy may have its own variants based on how much cached state (e.g. the adjacent faces lists) it uses to minimize its recalculations.
There should be a way to bypass collisions between certain bodies. This is absolutely necessary for the lock constraint, where bodies should not be collided together.
Usually this is done by assigning a body to layers that it belongs to, and collision masks that specify layers that the body collides with. Layers and collision masks can be stored as bitmasks. Then collision check between two bodies can be done using bitwise and
operation between the two.
For reference, check the corresponding section in the Godot engine documentation
My assumption was to create a fresh elm project, install elm-physics
, download an example to src/ (ie Animate.elm
) and run make
. That didn't work for me!
And the imported module names do not intuitively point to the needed packages, or what to move from indirect to direct.
I suggest to add a README.md
to the examples
folder that specifies their dependencies.
Based on an a new function
ConvexPolyhedron.fromVertices : Array Vec3 -> Result (Maybe Vec3, String) ConvexPolyhedron
based on a new function
ConvexPolyhedron.facesFromVertices : Array Vec3 -> Result (List Vec3, String) List (List Int)
that calculates a set of faces that wrap all of the vertices. Error conditions detected would include 3 or fewer vertices provided, 3 or more colinear vertices provided, 4 or more coplanar vertices provided, and vertexes would require concavity.
This allows the user to safely define a ConvexPolyhedron Shape knowing only its vertices. This relieves the tedium of listing out faces for an arbitrary ConvexPolyhedron, but at some runtime cost over explicitly hand-coding the faces.
The Physics module could also wrap the ConvexPolyhedron.facesFromVertices function making a correct hard-coded faces list discoverable to the user wanting to tune their app.
These are suspected to be caused my inconsistent handling of opposite edge vectors which are supposed to have equivalent effects. Both convex/convex and (prototype) sphere/convex collisions seem to have similar issues.
Calculate up front and cache an (Array (List Int)) of the connectedFaces for each face to prevent n-squared cycling in collision detection. BTW, I slightly prefer the term "adjacent face" to "connected face".
There should be a top-level directory for functions that we would rather not have to duplicate between the benchmarks and the tests for a given library function. At a minimum, the directory could contain the definitions of any shared sample data like definitions of useful hulls for NarrowPhase and ConvexPolyhedron testing/benchmarking. At the other extreme, it could contain the definitions of entire test cases or series of test cases -- all that would be left to do in the benchmarks and tests modules, respectively, would be to wrap them in Benchmark boilerplate and to wrap them in Test boilerplate adding their expected result values. Actually, for the sake of keeping things in sync, it would probably make sense for the expected result values to be defined in the common code alongside each test case, even though they would only be useful in tests and not in benchmarks.
Some of this common code could also be useful in constructing example demos.
"sampleData" or "commonData" would be a clear name if we were limiting ourselves to sample data initialization.
Would "sampleCalls" or "commonCalls" be a better name if the intent were more ambitious?
The goal here is to extend elm-physics API so that simulations like raycast vehicle could be built in external Elm packages.
Some functions are already implemented in the raycast vehicle PR and could be extracted and merged individually.
velocityAt : Point3d Meters WorldCoordinates -> Body data -> Vector3d MetersPerSecond WorldCoordinates
mass : Body data -> Maybe Mass
placeIn : Frame3d Meters WorldCoordinates { defines : BodyCoordinates } -> Body data -> Body data
tbd : Body data -> Vector3d units1 WorldCoordinates -> Vector3d units2 WorldCoordinates
Combine sphere physics with the improved sphere rendering and other visualization improvements, i.e. lighting and shadows.
At a minimum, the series of addSphereConvexContacts calls in benchmarks/NarrowPhase.elm should be tested to ensure that the benchmarked cases are set up correctly and are getting expected results.
Tests should be in place before any attempt to tune addSphereConvexContacts to guard against regression.
Would it make sense to have a map : (a -> b) -> Body a -> Body b
function?
Inspiration comes from classic TEA, Html.map
, Cmd.map
, etc.
I would like to define some bodies outside the main module but it is hard because there are bind by the same data
.
It looks trivial to implement, but can only be done at package level since the Body
type is opaque.
First of all I would like to say that you did an amazing job creating this elm package. It's a well documented package and friendly starting point for learning Elm, while playing with the physics and WebGL.
But it feels like the engine start missing to detect collisions when the velocity of objects become slightly higher. Even though when I use larger objects and a fixed frame rate (1/60 seconds). In my opinion the velocity is not even that high in the first place. So I'm wondering if there is something wrong in the collision detection? Isn't Elm not suitable for this? Or is it me doing something wrong?
Below you see the basic setup for a pinball game I'm creating. Of course this GIF is running with a lower frame rate than the real game, which runs almost exactly 60 frames per seconds. There are two problems:
I can prevent these issues from happening by either:
Hopefully you can help me to find the source of the problem.
Kind regards,
Jarno Le Conté
The idea is to implement a debugger that could hook into any Elm program, grab a snapshot of elm-physics world, and open up a 3D visualiser for it in a new window, where everything is inspectable, clickable, etc. And where you can save the snapshot and examine it later.
Because the debugger needs to expose internals, that otherwise might not be available through the public API, its code could be colocated with Elm physics code but have a different elm.json
file.
https://m.youtube.com/watch?v=1RphLzpQiJY was the inspiration for this idea
Benchmarks are needed to motivate and inform and monitor the possible changes described in issue #14 and possibly other future rework.
Reduce the copy/pasted boilerplate required to develop each new visual example demo. Build up one or more modules of support functions for things such as diagnostics display, common WebGL snippets, etc.
I created a physics simulation and ran it but it appeared to be frozen. I lost a few minutes before realizing that bodies default to the static behavior. Maybe it would make more sense if defining a body always requires you to explicitly choose a behavior instead?
Allow support for concave bodies composed of individually transformed ConvexPolyhedron shapes.
Support for constructing arbitrary tetrahedron shapes would also help here, providing universal building blocks for constructing arbitrary concave polyhedron bodies.
This would allow testing equivalences such as between a body consisting of a single cube shape with side length N and a body composed of NxNxN offset unit cubes with the same total mass uniformly apportioned.
The elements of the current arrays: faces and normals (and soon connectedFaces) could become the attributes of the record elements in the one Array.
This would reduce clumsy parallel array indexing with its requisite increments and Maybe-based failure handling, superfluous for same-sized Arrays.
The current moment of inertia calculation is oversimplified, it takes the bounding box of a body and assumes the cuboid shape according to the formula from the wikipedia page.
This doesn't work for bodies that are not boxes:
This may also be the reason why a compound body behaves very differently from the same parts connected with a lock constraint.
With the release of https://package.elm-lang.org/packages/w0rm/elm-obj-file/latest there is an easy way to load TriangularMesh
from Blender. elm-physics currently only supports Block3d
(which is internally defined as a convex polyhedron).
Collision algorithm is limited to convex shapes. There are several options to construct a convex polyhedron shape:
Point3d
TriangularMesh
of Point3d
and returns a Maybe
of Shape
(Nothing
if a shape isn’t convex)TriangularMesh
of Point3d
and returns a Shape
While 1. and 2. are good because they make it impossible to create wrong shapes, they are computationally intensive.
Open question: what to do with the center of mass of a convex polyhedron. Shall it be calculated or provided by the user.
I played with the Dominoes demo and left it in this state:
an hour later, the fallen dominos have wandered / rotated to a totally different place.
So there seems to be a tiny drift that accumulates after a long time.
How about a global flag that freezes the sim and is reset by any plausible state change?
Provide example UI for more dynamic control.
Possibly refactor into fold-like generic functions with "visitor function" arguments to reduce duplication of production code.
Hi, we're designing a space game where a ship has many components (e.g. fuel tanks, boosters), each with a different mass. We could combine our ship into a Compound
but then we can't allow different parts have different masses. We've been able to kind of simulate this by having three hinge constraints, one for each axis, but this seems to break down if the bodies are overlapping at all at the start, or if they go beyond a certain acceleration value. Sometimes wonky things happen even without going beyond a certain acceleration. Would it be possible to add a new type of constraint like the point constraint that also constrains the mutual rotation?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.