Ferrum Engine

Ferrum Engine

45 devlogs
105h 30m
•  Ship certified
Created by Luka Trojan

A hand rolled 2D real-time Physics engine written in Rust.
Incorporates many different systems.
Gravity Simulation
Springs
Rigidbodies
Fixed Joints
Pivot Joints
etc.

Timeline

Ship 3

This ship is currently being voted on by the community. Check back later!

Luka Trojan

5 days ago

Luka Trojan Covers 12 devlogs and 25h 41m
Earned sticker

Finally managed to fix pivot joints which turned out to just be a small bug where we accidentally swap body a and body b and found that this error occurs in the springs and weld joints code as well (oops) Overall I now have a functional product ready for the next and likely final ship!

Earned sticker

Created a new release. Fixed the windows version. Now working on fixing pivot joints since it seems like they diverge over time. There seems to be a problem with the implementation, been trying things out but nothing is working will figure it out eventually I hope. Here you can see the two anchors NOT at the same position when they should be.

Update attachment

Improved Joints! Now you can spawn joints using the editor, there is a visible circle where a joint is present, you can delete a polygon connected to a joint without consequences, you can delete a joint itself as well. Here you can see the little joint display dot. The joint ghost which shows where a joint would be spawned if you left click, as well as the menu where you can choose to spawn a joint.

Update attachment

Made it so that if two polygons are attached to one another they will not separate in the collision detection step which means that they are permitted to be both colliding bodies now and can therefore take part in collisions. Also constrained values in the editors to prevent unstable simulations or (rare) crashes which would result.

Update attachment

I added fixed joints, and pivot joints as well as fixing some long standing bugs connected to dividing by zero, improperly implemented calculation and other, and improving user experience a bit. Here you can see the pivot joint in action with a double pendulum!

Refactored the entire code base to make it so that the World struct doesn't have literally EVERY function and EVERY parameter. Now we separate it into 6 smaller groups which makes things more modular and easier to follow! Will probably work a bit more on the refactor tomorrow.

Update attachment

I worked on colors some more. And created monochrome palette generation using the Oklab/Oklch color space. Will continue to work on it some more. Will try and get the GUI color to match the palette colors. Here you can see four generated color palettes.

Update attachment

Changed a bunch of stuff but the main perceivable difference is the new random color generator! Now we use HSL instead of RGB which allows for much more uniform looking Colors. However I hear that the Oklab color space is even better than HSL so I will probably update to use it instead tomorrow. Additionally I plan to implement a generator for a random color palette to make everything prettier! Top is using HSL. Bottom is using RGB

Update attachment

Made it so that the preview of the object to be spawned is transparent to show what is beneath it. As you can see the 10 sided 6m radius polygon which is to be spawned is clearly visible under the mouse. Which shows it's exact size and the position it is to be spawned at.

Update attachment

Now when in the spawn mode and spawning a polygon you get to see a preview of what is gonna be spawned under your mouse. Also added a little debug menu for the future. And fixed a weird bug that might of been haunting me (who knows!)

I tried to implement multithreading for the collision resolution sadly it didn't work out. After that I fixed springs properly finding the actually reason gravity was being applied multiple times. Added spring energy calculation and in turn found that energy was NAWT being conserved properly. Fixed the problem. Added a way to rotate polygons in game. Made it so that you can't spawn multiple overlapping polygons which was causing phasing and (arguably) performance problems. In this scene nothing has a velocity so no kinetic energy yet there is still energy stored in the springs as shown in the energy menu.

Update attachment

Time to start work on this project again. Got many plans and hopefully by the time we get to the next ship our project will be many times greater. Started off by making a plan and also fixing the code. First fix was fixing gravity since attaching objects together with a spring would also make them accelerate faster thanks to gravity. Added a divider to reduce the effect of gravity by a factor of how many objects are attached.

Update attachment

Ship 2

1 payout of shell 825.0 shells

Luka Trojan

25 days ago

Luka Trojan Covers 16 devlogs and 42h 17m

Created a build script so I don't have to do it painstakingly manually. You can edit springs now. Still a lot of work to do but I will leave that all to a later date. Time to ship!

Devlog covering work from like 10 days ago. I have been on vacation so I haven't been able to work on my projects sadly. While on the plane I worked on the read me some and also changed a couple things in the code for UX. Will try to do a bit more work mainly UX before shipping again, but sadly I will likely not be able to do a ton more before the end of SoM.

Update attachment

Couldn't do much today but still got some done mainly bug fixes. Update moment of inertia after editing mass of rigidbody. Correctly dampen drag springs. Edit collision resolution optimization code. Changed dragging check to be an enum and not bool to allow for 3 states Starting InProcess NotDragging instead of just dragging and not dragging. Added function to safely remove springs. Added function to get the current mouse world position. Added way to change input modes with keyboard. Added way to change spawned spring parameters. Here is me playing with the bug fixed springs. Still some errors but I'll get to fixing them.

Couldn't do very much work today was busy with a bunch of other stuff but I still managed to get some done. Added the ability to select rigid bodies and change their properties. I also added the ability to drag rigid bodies with springs and attach springs between rigid bodies. Gravity also now actually works as it should as I fixed some code that was made for stability reasons a long time ago which is now still stable when done correctly. Also gave the ability for certain polygons to be more affected by gravity as well as setting the strength of gravity in the config menu. Gonna add a couple more features and change the read me then ship again.

Worked on the GUI. Separated the GUI code from the rendering code to clean up and organize a bit. Made it so that input is ignored if you are hovering over a GUI element so that you can input data without having unwanted things occurring in the background. Added a menu selector so that you can choose what menu's you want to be shown and which you want to be hidden. Added a new menu for editing the properties of spawned bodies so that you can spawn whatever body you want. Next I will make it possible to edit existing polygons and create springs using in app input. After that I will be adding anchors, and ball and socket joints then updating the read me creating a build system. Creating a new release and shipping.

Managed to get egui working with wgpu. Put some simple widgets for camera controls and such just to test things out. It took a while to set things up because I couldn't find much documentation for how to use wgpu with egui and everything I could find was years old and didn't apply anymore. Eventually I found an example program added a couple lines of code and everything worked. I want you to be able to modify everything in app so no code is needed. Here is a video of me playing around with some settings.

Finally finished implementing the new graphics API (wgpu). In the 1M circle test case it turned out to be 22.5% faster but performs about the same as the old API in most real physics scenarios since the bottleneck is always the doing all the computations for the physics. More importantly a lot more libraries support wgpu so it will be easier to find graphics API's which can work in the physics engine. Additionally it has much more functionality for compute shaders and other GPU stuff so I could make some GPU accelerated physics :). Here is the explosion example with the new graphics API (looks the exact same (as it should)).

Been working on the rendering system swap. Managed to get the camera uniform working as well as drawing polygons. Will try to finish the swap by the end of today.

Added partitioning to the collision resolution code so that we only check if two rigid bodies are colliding if they are sufficiently close to one another. I also optimized the code for extracting the vertices and indices from the rigid bodies for rendering. Overall these two optimizations together increased the speed of the explosion example by ~~6x which is from the collision resolution optimization and a different test case for rendering bench marking was increased by ~~40%. Here is the video of the explosion example now with ~200fps (previously 30fps)

Started porting the rendering system from miniquad to wgpu since wgpu is a faster, more versatile, better supported, but harder to use platform than miniquad. Using wgpu will give me a lot more options in the future and I will likely wanna swap to it eventually so might as well do it now. It seems like the port shouldn't be all too difficult but we will see. Here is a screenshot from the test program I made to figure out how to use wgpu. Using wgpu also opens up the opportunity for a web based version of the physics engine.

Update attachment

Added some useful displays for fps, total kinetic energy, and whether the pointer is being used. Now if you hover over the UI then you will no longer spawn/delete polygons or move the camera as would happen if you did it off the UI.

Decided to add a new crate for a GUI I struggled to get it working for a bit /:, will probably just be working on the GUI for the next couple days. My goal is for you to be able to do basically anything using just the in app GUI basically removing the need to program to use the engine. I could even serialize/save the in game state and allow you to replay anything. This will also probably make development easier since I could create test cases more easily. I also worked on the roadmap for this project so now I know what I want to implement for my next release as well as what I want to do for future releases! I might update the read me to include the roadmap. Here video of GUI test and cool spring.

Cleaned up a ton of the code base so it is now much more navigable, did some optimizations in the rendering code as well as other sections, refactored and removed magic numbers, Changed the rigid body constructors to allow you to set mass, restitution and color on creation rather than afterwards cleaning up many parts of the code and making things easier for the future. Springs also now are attached to an index in the main rigid body array rather than having their own rigid bodies which allows for cleaner collision resolution code, more functionality for springs by allowing multiple springs to attach to one rigid body (as shown in the video), and also a performance improvement.

Eucatastrophe Eucatastrophe about 2 months ago
That’s so cool!! Very impressive, physics simulations are so hard

Fixed up some code to be more modular. Optimized said more modular code to fix performance regression. Springs now account for angular momentum, are affected by gravity, and can collide with other rigid bodies, I think I might change the springs to use a reference to a rigid body to allow multiple springs to attach to the same body which would also help with cleaning up the collision detection code which is pretty messy with separate rigid body and spring collision resolution.

Edited the newly added springs to use RK4 as the numerical integration method instead of the simple newton's which increased accuracy by many orders of magnitude allowing the simulation to simulate springs at a much lower frequency than what was previously required. Current goal is to get a working double pendulum going.

Added Windows compatibility since my OpenGL shaders were giving errors when compiling for windows and the method I used for scrolling on Linux and Windows didn't work the same and required scaling the scroll amount by 100x. Tinkered with the collision resolution code, and added support for simple springs. Next I will probably try and make springs collide with other objects and try to tinker with more complex spring layouts. Also added two new test scenes for stability when standing on an edge and spring oscillation

Ship 1

1 payout of shell 1031.0 shells

Luka Trojan

3 months ago

Luka Trojan Covers 17 devlogs and 37h 31m

Refactored the code base and added lib.rs and some examples. I also added extra configuration options so that you can create your own simulations without needing to edit the engine itself! In the video you can see the three examples I prepared. I will probably move onto a different project for now likely an operating system but I will come back to this project later and improve the collision detection and resolution as well as adding more things such as gravity using newton's formula, springs, magnets, electric motors, and more!

Reinstalled my entire system today and didn't have much time to work. I forgot to install Wakatime on my IDE so no time was tracked (oops). Worked on collisions and accuracy + clipping. Recreated the simulation where block collisions compute PI (3.14159...)

Functional angular and linear impulses for collision resolution. Still a couple bugs with the calculation of contact points. I will probably just switch to a different algorithm for that since this one seems to be hopeless.

Implemented code to find the collision point between two colliding polygons and tried to implement angular impulse but there seem to be some bugs that I will try and iron out tomorrow.

Update attachment

Didn't do much programming today just reading about physics. Mainly Inertia tensors and angular momentum, once I finished reading I implemented the function for calculating the inertia tensor of a polygon and went to add angular momentum to the collision response code but found out the calculation of angular impulse requires the collision point. Sadly SAT my current collision detection function doesn't give me this so tomorrow I will need to implement GJK + EPA instead.

Update attachment

Added impulse based collision resolution, wrote the ODE solver (RK4) used it to apply gravity to some cubes. Tomorrow I will probably refactor a little bit and try to add angular momentum.

Added broad phase collision detection. Where we do a very cheap check to see which shapes are close enough to collide and then do a more expensive check to see which ones are actually colliding between the ones who are. This is a 4x speed improvement vs checking all shapes.

Just wanted to get a little bit done today. Decided to implement collision resolution. I plan to implement the Ordinary differential equation (ODE) solver soon and actually simulate some physics. I have more time now since the semester is officially over so I'll start working on this project a lot more.

Not much programming today because I had an exam and have another one tomorrow. Fixed a memory leak and did some optimization.

Narrow phase collision detection optimisation. Now we do a simple circle collision check on every polygon and only do a more vigorous check using SAT if the sum of the radii is less than the distance between the centers improved performance ~25x

Update attachment

You can now have shapes of arbitrary side counts

Rotation!

Refactored the code base twice. Made it so polygons can be any color and you can now zoom in or out

Update attachment

Added Vec2 math functions, added collision detection using SAT, fixed a bug where I was creating new buffers without deleting old ones. Code base is becoming a bit of a mess so I will probably spend tomorrow cleaning it up a bit so its easier to make new features since right now I have to rewrite whole portions for new features.

Fixed camera movement to be smoother
Fixed square placement to work with camera movement

Hobbes Hobbes 3 months ago

Looking great!

After hours of troubleshooting and going through non existent documentation I managed to refactor the code to allow for multiple polygons as well as adding polygons with the mouse button and moving the camera with the keyboard

Managed to render a triangle took a while but eventually figured it out using the demos of graphics library I am using (miniquad) as well as learnopengl.com

Update attachment