Physics Engine from Scratch
HTML-код
- Опубликовано: 12 дек 2024
- I built a constraint-based 3D rigid body physics engine and an ECS (entity-component-system) from scratch in C and C++. The physics engine runs on the ECS and uses constraints to model collision, joints, and motors.
This video gives a very high-level overview of the most critical pieces of the engine: the constraint solver, collision pipeline, ECS, and the editor. Everything mentioned in this video is open source, check out the links below!
Check out Slingshot on GitHub!
github.com/Sli...
Checkout T-RECS on GitHub!
github.com/Sli...
Sander Mertens' blog
/ ajmmertens
Entity Component System wiki
en.wikipedia.o...
Mathy bits generated with manim
github.com/Man...
Monster foot steps - Sound Effect by LordSonny on Pixabay
Meow - Sound Effect from Pixabay
Fabulous! To not only be able to make a physics engine, but to present it well, that's a rare combination of brains and beauty. Very well done.
Superb work!
For anyone looking to delve more into the physics check out the paper: Detailed Rigid Body Simulation with Extended Position Based Dynamics.
I implemented some of the features described in the paper and I must admit is trickier than it seems. For you to have implemented all of that is incredible.
As someone from engineering background, I am a sucker for physics engines. Thank you for this video.
god damn, that's sooo good. I recently created my own too, and it's so much slower and worse. I will definitely come back to this video and comment section for resources once I'm ready to improve mine.
Quick note: CMake is a MEAT-build system, as the actual build system (in the MSVC-context usually) would then be MSBuild (which is what Visual Studio would use behind the scenes)
lovely vid!
I saw your comment on one of my videos and decided to check out your channel. I've got to say...this is amazing! I'm dabbling into physics for my horror game and this is so inspirational! I look forward to more of your content :)
It is been a while since I had enjoyed a video this much. Congratulations for your engine, you did something that very few people are able to do.
A physics engine with real time shadows, that is fancy.
We bougie
Very very good. Kudos.
This is fantastic ! Bravo 👏I'm super impressed by how stable and modular it looks. Amazing 😁
Hello! What about energy and momentum conservation. Does it works with those simple constrains? I mean imagine a real 2 rigid body pendulum. It will keep the total energy and follow the correct velocity patern? Thanks a lot!!!
Great question! A pendulum with no friction built out of constraints will slowly lose kinetic energy over time. This happens because of a combination of (1) not using a symplectic integrator and (2) constraint impulse calculations not adhering to conservation laws. More (2) than (1) tbh
@@therealjtgill Thanks! I am trying to do constrains that keep the real physics using very strong and short springs, but its a nightmare. I need really small integration steps and using doubles... any idea :)
@@samsaraAI2025 If all you want to build is a simple double pendulum that conserves all the standard mechanics quantities, then I'd look into a minimal coordinate representation and a symplectic integrator. You can derive the dynamics of the minimal coordinate representation by hand by setting up a Lagrangian, or Drake (another physics engine) could probably do it for you.
Section IV.A of this paper has a short discussion about the difference between maximal coordinate systems vs minimal coordinate systems (slingshot is maximal coordinate).
arxiv.org/pdf/2203.00806.pdf
Note that a symplectic integrator won't necessarily conserve energy on a frame-by-frame basis. But over long sampling periods the system's average energy from period to period will be roughly constant.
@@therealjtgill I will research about that idea. I dont want to use another engine, I want to create my own one. For real simulation you know.. Newtons, meters, real watts etc.. for simulation a car suspension etc.
Very impressive!
that intro was hilarious! Very impressive work, I know building a physics engine is not an easy feat.
Physics engines are so cool. This video is worth a sub!
NIce. Keep em coming👍
Cool stuff man. Trying to achieve stable stack of boxes in my end. This is inspiring.
Just keep at it and you'll get there. Stable stacks are probably the most difficult feature for collision detection/resolution. Mine will eventually slide apart if the engine runs for long enough, my contact manifolds aren't spatially consistent across frames. It really just comes down to a combination of a well-tuned constraint solver, consistent (or at least smoothly varying) contact manifolds, and good friction approximations.
Awesome project. I'm new to programming and wanted to ask :
1) C++ has no inherent graphics capabilities. How did you implement graphics into your project?
OpenGL :)
@@therealjtgillYou really are very very skilled 😵
How many years have you been a programmer for?
@@aarfeenanees9147 Thanks! I've been programming for quite a while
Amazing work, very impressive. What's the peformance like with ridiculous amounts of objects, are you using a BVH to cull collision checks, and have you considered adding convex mesh shapes?
Thanks! With ridiculous numbers of objects performance would be pretty bad. I'm running this on a single thread with no BVH, so broad phase is O(N^2).
Fun story, this engine started out *only* supporting convex meshes, but I switched to quartic shapes to take advantage of axis test speediness. It would be pretty straightforward to include convex meshes. I'm sidetracked on improving the renderer and ECS, but once those are finished I plan on re-attacking slingshot's collision pipeline.
i was wondering if you had any references for building up a contact manifold from EPA or did you use another algorithm?
I use a process that's similar to this talk by Dirk Gregorious.
www.gdcvault.com/play/1022194/Physics-for-Game-Programmers-Robust
Contact manifolds are made in one shot. I use the contact point and contact normal from narrow phase (GJK+EPA or SAT) to find a closed, convex set of points on body A and body B that:
1. Contain the contact point
2. Have a surface normal with maximum cosine similarity to the contact normal (or the negative of the contact normal)
These closed, convex regions (CCRs, but not the band 🤣) are either faces, line segments, or single points. From here the process is pretty similar to the slides in the link:
1. Clip the CCRs according to penetration (e.g. only include the parts of the CCRs that are actually inside either body)
2. Clip the clipped CCRs against each other (gives you a polygon, line segment, or point where the bodies are actually in contact)
3. If the CCR is a polygon with more than four vertices, find the four vertices on the polygon that give you a smaller polygon with maximum surface area
4. Reproject the clipped/reduced vertices onto both bodies
5. Use the reprojected vertex pairs as contact constraints (with the normal that came from narrow phase)
This is the contact manifold calculation entry point in slingshot:
github.com/Slingshot-Physics/slingshot-community/blob/main/physics%2Fcollision_pipeline%2Fcollision_contacts.hpp
Let me know if you have any more questions!
Very cool, thanks for sharing! How difficult was it for you to understand and implement these algorithms?
Thank you for watching! It kinda depends on the algorithm - but I'd say anywhere from a few hours to a few months.
The collision system and the constraint solver are the most math-intensive parts of the engine and the algorithms they use are intricate.
The notion of mixed linear complementarity problems was the most difficult to tackle and I'm *still* finding ways to improve my implementation.
Collision detection through contact manifold calculation uses the widest variety of algorithms, and some of those were difficult to implement because they required a bunch of boot-strapping.
GJK is a good example. If you want to use GJK to figure out if two shapes are colliding/what their closest points of contact are, you have to have:
- closest-point-on-[0, 1, 2, 3 simplex]-to-point
- support functions for every convex shape you're going to support
- barycentric coordinate calculator for [0, 1, 2, 3] simplex
- probably some coordinate transformation info (but this depends on how you store shape information and how your support functions expect to receive data)
So that's technically at least 9 algorithms that you have to implement *just to tell if two shapes are colliding*. But the nice thing is that a lot of this can be re-used for algorithms like EPA.
I'm sorry for the info dump - this stuff is just exciting, and it's cool when people ask about it :)
@@therealjtgill thanks for sharing and the info dump is appreciated ;)
I’ve looked into making a physics engine before but all the collision detection and resolution looked overwhelming so I’ve never dived too deep in. It’s nice to know this wasn’t “done in a day” so to speak.
I like doing simulations with sound (there’s some demos on my channel if you’re curious). Are you interested in sound related things?
Great project again and thanks for the reply!
@@gedaliakoehler6992 Your videos are FANTASTIC
@@therealjtgill Thank you so much:) I'm glad you appreciate them. They're kinda straight up - here is the demo - but I appreciate more the approach you did and others do where there's a bit more talking 😆
Amazing video! Pls do more
Hello! Maybe u can clarify a bit obtain distance when I know current velocity and time in seconds where object will decelerate to 0 speed but from max speed, like if we stops 0.2s from 4000 velocity to 0 then from 2000 we should do it in 0.1s accordingly? Classic acceleration formulas seems not consider I compute it in between integrating steps like velocity is not that big or mapped as dt pos += velo * dt, instead a full second range and it provide distance that too much longer than when I integrate with RK4 or velocity verlet 😅 something like 20-25 times longer. Example max speed 4000 and time to full stop 0.2s, i apply deceleration amount as MaxSpeed / decelTime with inverted to velocity direction and I stops something like braking length 500-600 position units, when I try compute somewhere length when in motion for current speed or even on full speed for such time 0.2s via classic newton formulas I get braking distance 2700 something like that. So thought maybe just multiply to dt to obtain intermediate fraction so this will be kinda meaning of what dynamic acceleration equation deriving may looks like, but then values is 5-6 units in position, like 100 times smaller 😢 or I miss something dunno.
Thank you for sharing your knowledge.
Can you list some resources you used to study game physics?
Sure thing!
These are the websites that I probably used the most - most of them have some overlapping content.
www.gdcvault.com/play/1022193/Physics-for-Game-Programmers-Robust
archive.org/details/GDC2013Gregorius
mft-spirit.nl/files/articles/ImpulseSolverBrief.pdf
www.math.usm.edu/lambers/mat610/sum10/lecture9.pdf
roboticsproceedings.org/rss04/p12.pdf
box2d.org/files/ErinCatto_ContactManifolds_GDC2007.pdf
www.cs.cmu.edu/~baraff/pbm/rigid2.pdf
danielchappuis.ch/download/ConstraintsDerivationRigidBody3D.pdf
www.cdsimpson.net/2014/10/barycentric-coordinates.html
www.cs.drexel.edu/~david/Classes/CS430/Lectures/L-05_Polygons.6.pdf
Book resources:
Real-Time Collision Detection by Ericson is an invaluable resource and well-worth the price
Matrix Computations, 4th edition
Aircraft Control and Simulation by Stevens, Lewis, and Johnson (for coordinate frame things)
@@therealjtgill
Thank you for your detailed answer!
I was wondering if you have any advice on specific resources or projects that could help in learning ECS and DOD design for creating a physics engine.
I've always used an OOP approach, but I'd like to transition to a more data-oriented approach. I've wached some videos and read some tutorial, but I'm looking for more detailed and practical aspects, preferably with source code examples.
Any recommendations you could provide would be greatly appreciated!
I'd say *the* book on DOD is "Data-Oriented Design" by Richard Fabian. There's a big difference between DOD and ECS: DOD is very much application-specific. Your application will have a particular set of data flows (or data usage patterns), and the goal of DOD is to exploit those specific flows to build a maximally efficient piece of software.
ECS, on the other hand, aren't designed with a single project in mind - they're made to be useful for one or more *classes* of projects. I like to think of an ECS as a library of data usage patterns that arise from applying DOD to several similar projects. In my experience ECS implementations usually cater toward a particular subset of use cases. Those use cases are entirely dependent on the author of the ECS.
Austin Morlan has a good starting-point ECS implementation (note that it's very much a starting point - AM's implementation only covers very basic use cases of an ECS).
Austin Morlan's ECS: austinmorlan.com/posts/entity_component_system/
Sander Mertens has an excellent series of blog posts that go much deeper into ECS design patterns.
ajmmertens.medium.com/building-an-ecs-1-where-are-my-entities-and-components-63d07c7da742
There's a discord server for FLECS by Sander Mertens with people who are interested in building/using ECS for all kinds of projects. You should be able to find the link to it in his blog posts or from the github repo for FLECS.
love thanks for share
Wow you are my GOAT
Incredible
This is very impressive. I'm still trying to figure out how to make my AABB game physics work properly with gravity and pushing against each other (lol). Maybe one day I will get to implement not-axis-aligned box colliders for my game: that is "my dream". :D
You'll get there! Check out SAT or OBB collisions. There are tons of resources online for collision detection and resolution.
how do i learn to build this?
One feature at a time! Start with a basic n-body physics engine, then add equality constraints, then inequality constraints, then collisions
Cool.
I bet you cant do it on templeOS
I would never think to desecrate those hallowed grounds with my unholy C++
noice
nice vid
fpb
🤔