22 lines
8 KiB
Markdown
22 lines
8 KiB
Markdown
![]() |
# Physics Engine
|
||
|
|
||
|
Physics engine is a [software](software.md) (usually a [library](library.md)) whose purpose is to simulate physical laws of mechanics, i.e. things such as forces, [rigid](rigid_body.md) and [soft](soft_body.md) body collisions, particle motion, fluid dynamics etc.
|
||
|
|
||
|
{ When it comes to classic 3D rigid body physics engines, they're extremely hard to make, much more than for example an advanced 3D rendering engine, especially when you want to make them [LRS](lrs.md) (without floating point, ...) and/or general and somewhat physically correct (being able to simulate e.g. the Dzhanibekov effect, satisfying all the conservation laws, continuous collision detection etc.). Good knowledge of mechanics and things like [quaternions](quaternion.md) and 3D rotations is just the beginning, difficulties arise in every aspect of the engine, and of those there are many. As I've found, 32 bit fixed point is not enough for a general engine (even though it is enough for a rendering engine), you'll run into precision problems as you need to represent both relatively high and low energies. You'll also run into stability issues such as stable contacts, situations with multiple objects stacked on top of each other starting to bounce on their own etc. Even things such as deciding in what order to resolve collisions are very difficult, they can lead to many bugs such as a car not being able to drive on a straight road made of several segments. Collision detection alone for all combinations of basic shapes (sphere, cuboid, cylinder, capsule, ... let alone general triangle mesh) are hard as you want to detect general cases (not only e.g. surface collisions) and you want to extract all the parameters of the collisions (collision point, normal etc.) AND you want to make it fast. And of course you'll want to add acceleration structures and many other thing on top. So think twice before deciding to write your own physics engine.
|
||
|
|
||
|
A sane approach may be to write a simplified engine specifically for your program, e.g. many times you get away with creating an engine that doesn't work with rigid bodies but some simple meshes made of spheres connected by springs. That's super simple, doable and probably [good enough](good_enough.md). ~drummyfish }
|
||
|
|
||
|
Physics engine is a wide term even though one usually imagines the traditional 3D rigid body engine used in games such as [GTA](gta.md). These engines may nevertheless have different purposes, features and even basic paradigms, some may e.g. be specialized just for computing precise ballistic trajectories for the army, some may serve for simulating weather etc. Some common classifications and possible characteristics of physics engines follow:
|
||
|
|
||
|
- **[2D](2d.md) vs [3D](3d.md)**: 2D engines are generally much more simple to implement than 3D, for example because of much more simple math for rotations and collision detections.
|
||
|
- **[real time](real_time.md) vs [offline](offline.md)**: Real-time ones are mostly intended to be used in the entertainment industry, i.e. [games](game.md), movies etc. as they can compute somewhat realistic looking results quickly but for the price of dropping high accuracy (they use many [approximations](approximation.md)). Scientific engines may prefer to be offline and taking longer time to compute more precise results.
|
||
|
- **[rigid body](rigid_body.md) vs [soft body](soft_body.md)**: Rigid body engines don't allow bodies to deform while soft body ones do -- in real life all bodies are soft, but neglecting this detail and considering shapes rigid can have benefits (such as being able to consider the body as a whole and not having to simulate all its individual points). Of course, a complex engine may implement both rigid and soft body physics.
|
||
|
- **paradigm**: The basic approach to implementing the simulation, e.g. being [impulse](impulse.md)-based (applying impulses to correct errors), constraint-based (solving equations to satisfy imposed constraints), penalty-based (trying to find equilibriums of forces) etc.
|
||
|
- **[discrete](discrete.md) vs [continuous](continuous.md) collision detection**: Discrete collision detection only detects collisions at single points in time (at each engine tick) and are simple than those implementing continuous collision detection. Discrete engine are less accurate, consider e.g. that a very fast moving object can pass through a wall because at one instant it is in front of it while at the next tick it is behind it. Continuous collisions won't allow this to happen, but are more difficult to program, may be slower etc. For games discrete collisions are usually [good enough](good_enough.md).
|
||
|
- **features: fluid, cloth, particles, [ragdoll](ragdoll.md), [inverse kinematics](inverse_kinematics.md), [GPU](gpu.md) acceleration, [determinism](determinism.md), [voxels](voxel.md), ...**: These are a number of additional features the engine can have such as the ability to simulate fluids (which itself is a huge field of its own) or cloths.
|
||
|
|
||
|
A typical physics engine will work something like this: we create a so called **physics world**, a [data structure](data_structure.md) that represents the space in which the simulation takes place (it is similar to a [scene](scene.md) in rendering engines). We then populate this world with physics elements such as rigid bodies (which can have attributes such as mass, elasticity etc.). These bodies are normally basic geometric shapes such as spheres, cylinders, boxes or capsules, or objects composed of several such basic shapes. This is unlike with rendering engines in which we normally have triangle meshes -- in physics engines triangle meshes are extremely slow to process, so for the sake of a physics engine we approximate this mesh with some of the above basic shapes (for example a creature in a game that's rendered as a hi-poly 3D model may in the physics engine be something as simple as a plain sphere). Furthermore the bodies can be **[static](static.md)** (cannot move, this is sometimes done by setting the mass to infinity) or **[dynamic](dynamic.md)** (can move); static bodies normally represent the environment (e.g. the game level), dynamic ones the entities in it (player, NPCs, projectiles, ...). Making a body static has performance benefits as its movement doesn't have to be calculated and the engine can also precalculate some things for it that will make e.g. collision detections faster. We then simulate the physics of the world in so called *ticks* (similar to [frames](frame.md) in rendering); in simple cases one tick can be equivalent to one rendering frame, but properly it shouldn't be so (physics shouldn't be affected by the rendering speed, and also for the physics simulation we can usually get away with smaller "[FPS](fps.md)" than for rendering, saving some performance). Usually one tick has set some constant time length (e.g. 1/60th of a second). In each tick the engine performs a **collision detection**, i.e. it finds out which bodies are touching or penetrating other bodies (this is accelerated with things such as [bounding spheres](bounding_sphere.md)). Then it performs so called **collision resolution**, i.e. updating the positions, velocities and forces so that the bodies no longer collide and react to these collisions as they would in the real world (e.g. a ball will bounce after hitting the floor). There can be many more things, for example **constraints**: we may e.g. say that one body must never get further away from another body than 10 meters (imagine it's tied to it by a rope) and the engine will try to make it so that this always holds. The engine will also offer a number of other functions such as casting rays and calculating where it hits (obviously useful for shooter games).
|
||
|
|
||
|
## Existing Engines
|
||
|
|
||
|
One of the best and most famous [FOSS](foss.md) 3D physics engines is [Bullet](bullet_physics.md) ([zlib](zlib.md) license), it has many features (rigid and soft bodies, GPU acceleration, constraints, ...) and has been used in many projects ([Blender](blender.md), [Godot](godot.md), ...). [Box2D](box2d.md) is a famous 2D physics engine under [MIT](mit.md) license, written in [C++](cpp.md).
|