It has been absolute ages since I've last posted on Cemetech, and I've been wanting to post this project for a while now, so I'm biting the bullet and showing what we've got so far!

This is a collaborative C++ project I'm doing together with olympus223. Where he's doing the graphics, and I work on the physics.

The graphics are done using the OpenGL library, with also a bunch of 2d graphics capabilities we use for debugging

The physics works using Spring Physics, this is a method where objects are simulated in discrete steps, and when the engine discovers that two objects are colliding, it applies forces to repel the objects.

We've got many important features finished, such as
- Friction
- attaching objects to one another
- many performance improvements, with the ability of simulating around 10'000 free objects at once.
- Ballhinges
- Lighting
- A playable ball character, you can run around and interact with the world!
- live part editing, moving, rotating, scaling, adding new parts, deleting parts

As for using the engine for later projects, though I've toyed with a few different game ideas, at the moment I'd rather keep working on the engine itself.

Working on the engine is extremely rewarding, it's the longest project we've ever undertaken (currently clocking in at a whopping 45'000 lines), and the passion is showing no signs of wearing thin! There's just so many different skills and concepts required in building this thing that you never get tired. Sure, there's some menial work (as I'm doing right now {reworking our Matrix class, it's a mess}) but it is far outweighed by the cool problems we get to work on, be it manually vectorizing functions for colission detection through intel intrinsics, working through the math for ballconstraints, building shaders, and learning about sooo many obscure c++ features. Everything builds on itself, which makes it rewarding in itself, and forces you to think things through and do them well.

In terms of the engine ever being "complete", there's always more work to be done.
But for a minimum viable product (an actually usable game engine), we're nearly there.
We still need:
- A dedicated system for terrain, terrain is currently implemented as nonmoving parts, but since we're limited to 10.000 moving parts, (and therefore 10.000 terrain parts in the current system) it's not currently feasible to make a truly large world.
- World saving/loading, olympus has done some important work in this area, but there is still some work left.
- Separation of the graphical part of the engine and the application using it (so it can be included as a .lib just like the physics engine itself). olympus is also working on that, but it's a big task.

I visited cemetech today, and saw that our project was featured! Perhaps it's time we updated you all on what we've been up to. (Which is a lot)

First of all, we've finished all of our todos mentioned in the last update:
Terrain:
Let's just say that's been taken care of

World loading and saving has been finished, this was a bigger challenge that expected, as we wanted to enforce a separation of concerns system where the physics library saves physics related stuff, while still allowing application customization.

Separation of Graphics and Engine has been finished, which may bring some of our future visions closer to reality (more on that at the end)

Aside from this, we have been working on a whole host of fancy new features:

Game engine changesResource Manager
We wanted a centralized hub where all of the resources used in the engine would be managed. This resource manager keeps track of textures, shaders, fonts, objects etc. It handles creation, management and destruction of all resources in the engine. This is also viewable ingame.

Entity Component System
This system defines every object in the world as an entity in a tree. This allows for access to all objects in the world through a unified interface. Every entity is composed of components which define the behaviour and appearance of that entity. Examples of components are a material, a mesh, a rigidbody, a light and much more! The tree structure allows for entities to have parents and children.

The ECS consists of a tree of entities, which may each contain various components, such as part's meshes, lights, and other properties.

Shift to imgui
We started with our own gui implementation, but quicky found it to be a far larger task than originally thought, so we switched to imgui-based guis.

Physics changes: The constraint system
something that has been the bane of my existence for the last couple of months

To get the full performance out of our constraints, we have divided them into 4 categories:

Fixed Attachments not to be confused with FixedConstraints, which fulfill the same purpose, but are actually Hard Constraints!
These are the bread and butter of constraints. They are the first constraints we implemented, and the easiest to understand. They just fix parts together. These are what make up the car body we showed in the first imgur album.

They don't actually have a "connecting constraint" representation, all parts that are attached through Fixed Attachments are grouped into one big object we call a Physical. For these Physicals we can precompute various properties such as total inertia, total mass, center of mass, etc.

Also, this is an important optimization in terms of part coplissions! Since two parts that are attached together don't move relative to one another, and if they were to touch, their respective colission forces would cancel each other out through the constraint, we can safely ignore any potential colissions between parts that are attached like this.

For all Physics computations, these Physicals are the new basic building block. I will use the word Part from here on as I think that makes for a clearer picture, but know that all constraints are defined in terms of Physicals under the hood.

Hard Constraints
HardConstraints are the newest member of the family, they are SemiHard Constraints with all 6 degrees of freedom taken away. This essentially means that we can define one part in terms of another. What this also means is that forces and moments are transferred perfectly from one part to another, there are no degrees of freedom in which forces or moments can be dissipated, as would be the case in a SemiHard constraint such as in Hinges or BallConstraints (where some or all moments are not transferred).

This allows for two important observations:

Any colission between parts, solely connected through hardConstraints (and fixed attachments) can be ignored as the forces would cancel each other out through the constraints.

Since parts are defined in terms of one another, there can be no loop in the constraints. So we can represent these constraints in a tree shape as shown below.

You could of course construct an object - for example, connecting 3 parts with pistons in a triangle - that would theoretically be valid. This is called an overconstrained system. But then one of the pistons would be redundant, or the whole assembly invalid if two of the pistons disagree over where exactly their connected part should be. Best to just disallow loops.

The tree representation allows for much easier working with the objects, as there is one base part from which the position and speed of all attached parts can be defined. This top node represents the whole group and we call it a MotorizedPhysical.

The intersection optimisation is also baked right into our BoundsTree representation of the world (see original post). We add a boolean to each node which tells the intersection check to stop early when they encounter such a node.

It is easy to define such constraints, you just have to provide a a function returning the offset of the piston/motor/whateveryouwant and the current relative motion.

SemiHard Constraints

These are the really difficuilt constraints. They take away 1-5 degrees of freedom. These are constraints such as hinges, ball joints, suspension pistons, ropes, etc. These must be modelled as series of equations. For example: ball joints define x,y and z of the attachpoint on part1 to be the same as x,y,z of the attachpoint on part2. This takes away 3 degrees of freedom. compare this to hinges, where once you fix one part, the other part can only be rotated along one axis, leaving just one degree of freedom.

Currently we have only implemented BallConstraints, but we are planning to support more types in the future. These are the most difficuilt as they are hard to model and hard to interoperate with other constraints.

Soft Constraints

Finally, perhaps the easiest kind of constraint, soft constraints. These are constraints that impose no reduction in degrees of freedom. They can only apply forces.

Examples are elastics, magnetic repulsion or attraction. If you fix one side in place, you can still move the other wherever you want.

For example: with elastics each tick we just have to calculate the length, and apply a force based on that.

Future PlansNear Term

Extending the layering system of the world, not just terrain and free object layers, but layers for noncolliding parts, and customizability for which parts collide.

Linux Support (Apparently Visual C++ is quite the dialect of standard C++, so we still have some reworking to do to make it GCC buildable!)

Surface effects, such as normal maps, and bump maps. This will allow us to create objects with greater variety in surface appearance.

Even more editing capabilities, so people can build and share their worlds.

Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.