Code Monkey home page Code Monkey logo

elm-physics's People

Contributors

martinsstewart avatar paulmartel avatar shuhei avatar w0rm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

elm-physics's Issues

Style (performance?) improvement: refactor ConvexPolyhedron to use patterns and idioms.

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.

Let user configure max step iterations

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.

Improve collision detection using spatial indexing

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.

Does Physics.Constraint.pointToPoint constrain relative rotation?

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?

Add ray-body collision detection to enable future mouse support.

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?

Task: benchmark variations on sphere-convex collision detection.

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.

Introduce a way to bypass collisions

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

Samples need other/more dependecies

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.

Add Physics.shapeFromVertices : Array Vec3 -> Result (Maybe Vec3, String) Shape

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.

Bug: apparent collision misses with convex polyhedra.

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.

Task: reduce code duplication between benchmarks and tests.

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?

Body API additions for raycast vehicle simulation

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.

  • Get the linear velocity of a point on a body velocityAt : Point3d Meters WorldCoordinates -> Body data -> Vector3d MetersPerSecond WorldCoordinates
  • Get body mass mass : Body data -> Maybe Mass
  • Place a body in a frame placeIn : Frame3d Meters WorldCoordinates { defines : BodyCoordinates } -> Body data -> Body data
  • Transform vector with body inversed inertia tensor (function name TBD, alternatively the whole inertia could become its own module with useful functions) tbd : Body data -> Vector3d units1 WorldCoordinates -> Vector3d units2 WorldCoordinates

Task: Add NarrowPhase.elm tests

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.

Body.map

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.

Collision detection between a block and a sphere fails sometimes

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:

  1. Sometimes the paddle misses the ball.
  2. Sometimes the paddle is going through the wall.

I can prevent these issues from happening by either:

  1. Lowering the frame rate (e.g. 30 frames per second)
  2. Lowering the velocity of the objects.
    But that is not a real solution.

ezgif-2-8d135354276e

Hopefully you can help me to find the source of the problem.

Kind regards,
Jarno Le Conté

Build a pluggable debugger for physics

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.

  1. Maybe a wrapper around the Elm compiler with a special debug-physics mode that would post-process JavaScript to expose things for the physical debugger, that would be pointed at the JavaScript objects from the game using the same Elm types?
  2. Or maybe a json encoder/decoder for the physics World, so that the game could encode it, and debugger decode it — slower but could be useful for other use-cases

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

Feature: factored out example support module(s)

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.

Unexpected default behavior for Body

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?

Extend Physics.elm constructor methods to exercise multi-shape bodies.

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.

Support a convex polyhedron shape

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:

  1. As a convex hull from a list of Point3d
  2. A function that takes TriangularMesh of Point3d and returns a Maybe of Shape (Nothing if a shape isn’t convex)
  3. An unsafe function that takes 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.

Model state seems to miracliously change in the Dominoes Demo

I played with the Dominoes demo and left it in this state:

  • Run on Windows 10, Firefox
  • changed to wireframe, center of mass visible
  • run

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?

type of constraint that links two bodies, including rotation?

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.