At last, the new version of the demo has reached a point where I’m comfortable releasing it. RPM Project
This new version has been written from the ground up so the code inside is considerable neater and it has much better support for multi-threading, which means it has better performance over the old version and it’s less likely to crash as DirectX is only ever accessed through the main thread (not that I was randomly changing things on different threads in the first place mind) and everything is much better organised.
We also have much nicer graphics, better models, higher resolution textures, lighting, shadows, and a slightly toonish look to the whole thing. There are also different menus to change the display and controller settings, which have been moved from the title screen to an in-game menu so there’s no delay from starting the game and seeing the car and you don’t need to restart the race to re-map a button! Handy.
The physics have also had a few bug fixes which have improved the handling and the friction curves and suspension have been adjusted again so the car should perform a little closer to reality. Unfortunately I still haven’t implemented anything in the way of an anti-roll bar for the suspension so the car rolls quite a bit in the corners, to combat the rolling the suspension is a little stiffer than it should be, but it’s not so bad as you don’t need to be sitting in the car while it goes around the track.
The best improvement though is that I’ve added a tachometer HUD element widgety thing, which makes knowing when to change gears unfathomably easier that it was before, also until I get some force feedback and sound into the game it’s a handy way to see if the tyres are starting to slip (as the needle starts to shudder, or suddenly hits 8000rpm but that might be a bit late).
You can download the source and binaries for the new version here
While working through some fixes and updates for the physics in my racing demo I noticed that when going over a curve there would be small but noticeable bumps as your rolled from one set of triangles in the physics mesh to the next, which was caused by the sudden change in the gradient of the surface.
While these minute bumps aren’t detrimental to the simulation they are an artifact that I wanted to get rid of. The simplest and most expensive way of smoothing out these bumps are to add more triangles to our mesh, but it’s just not practical to use so many poly’s in a physics mesh. What we need is a way to enhance the current mesh at runtime when looking for collisions.
My next thought was to subdivide the triangle mesh at runtime when we know with a fair degree of certainty that there will be a collision with those triangles. We can set up a bezier triangle with control points derived from the vertex normals and use that to subdivide the triangles we are colliding with (PN Triangles, or N-Patches), this gives us the higher resolution mesh without the full cost of checking against thousands of extra triangles. Unfortunately it’s quite slow and has much higher memory requirements as we subdivide the triangles over and over at runtime.
Instead of generating new triangles to collide with I decided to use the bezier patch to directly work out the contact point, the downside of this is that we no longer collide exactly where we should, as you can see from this crudely drawn diagram:
The points Va and Vb represent the triangle in a side on view, the point pC is the closest point on the triangle to the object we are detecting a collision with. The dotted line going along the triangle is the bezier curve. When trying to use the bezier curve to quickly determine if we are touching the curve I use point pC as the point on the curve to check, from the diagram we can see that we’re not quite on the curve at our test point pC, but we are penetrating the curve just to the right of it. We could always use a whole bunch of test points, but then we start getting to the point where you can’t really justify the cost of the extra operations on every triangle.
Generating the control points for a bezier surface is still an expensive cost for a one time check on the curve, if you need to split triangles or check against various points then a bezier surface is the way to go, but for our single test there is a quicker way which produces remarkably similar curves without the need to generate the control points.
We have all the data we need to do a little bit of maths to get a cubic curve (y’know, ax³ + bx² + cx +d) that will tell us the elevation from the regular triangle surface at the point we are interested in.
The only data we have is the normal at each vertex, and the (interpolated) normal at the contact point. The derivative a a cubic function (a quadratic) gives us the gradient of the curve for each value of x, since we know the gradients for two points (by using the normal from a vertex and the normal at our contact point), and using the midpoint between the vertex and the contact point, we can solve the quadratic equation that describes the gradient of the cubic equation that we need.
If we make the vertex the origin, then the coefficient C in our quadratic is the gradient at the vertex since anything multiplied by zero is zero. We then need to use the midpoint and the contact point to solve for the coefficients a and b, where the values of x for the points are their distance from the vertex. It’s just solving simultaneous equations so I’m not going to go into any detail there.
When getting the integral of our equation we have to add a new coefficient, but since our vertex is acting as the origin and the elevation of the surface at each vertex should be zero (so the surface passes through it) the new coefficient is also zero.
To get a smooth and accurate representation of a 3d surface from a 2d curvy line we need to repeat the process for all three vertices, and then take a weighted average from each using the barycentric coordinates. While this sounds like more work it’s actually a lot cheaper than calculating the control points for a real bezier surface.
I also very generously made a little video of the result of these approximated curved surfaces in a rather extreme case, even though we don’t end up with a perfectly smooth surface I’d still say it’s a huge improvement.
I’m currently updating some of the content on the project pages. The changes include a new layout for the project pages, some fancy pictures and even a few videos!
Not all projects have been updated yet but I’m quite a way through, so some of the projects will have the shiny new layout and others will be using the older layout (if you can call it that).
It’s been a while since I made any formal updates but that doesn’t necessarily mean I haven’t been doing anything. I have in fact, been playing around with shaders and trying to find a visual style for RPM that I can actually achieve and that doesn’t distract from the actual simulation.
Having already dismissed the idea of aiming for ultra realistic rendering because of a lack of resources like normal maps, specular maps, half decent models etc. I had to find something that was still appealing and that masked the lack of high quality resources. So we head off into Non-Photo-Realistic Rendering, most stuff you see creates very blocky lighting and outlines just like you’d see in some anime or some such. Unfortunately most stuff you find around the net is rather simplistic and is right at the other end of the ‘Scale of Realism’ and I wanted to have something a little different, and a little more realistic, a nice middle ground.
What I’ve gone for is a more subtle outline with finer details filled in, coupled with some fairly decent per-pixel lighting which I adjust based of a few thresholds. Rather than having a harsh cut-off point however I blend through to the next threshold which gives a more painted look.
It’s difficult to describe so here are some preliminary shots for you to look at, firs though a reminder of what I have generously provided so far:
Ye Olde Artistic view of the car
Ye Olde Standard view of the car
I know, it’s not that nice. I’ll also admit that I forgot to enable the built-in specular lighting, I disabled it at some point then never turned it back on, I’m sorry.
Still, lets take a look at what we get now:
Damn, even a poor quality line drawing of the Elise manages to look good
The car even looks happy now.
Excluding the minor alpha problems from these screenies, I quite like it. I’ll probably continue tweaking it, more lines, less lines, smoother transition on the lights, harsher thresholds. Ah, endless hours of fun right there.
If anybody apart from spammers, bots and that one person ever checks this website, then keep your eyes peeled for the next exiting update in the ‘Anthony does some stuff on the computer’ saga.
UPDATE: As part of a new effort to enhance the content on the site I’ve started taking videos and additional screen-shots for some projects, so here’s a sneak preview of the new look for the demo:
The lighting isn’t quite right, with the track looking a little dull and I haven’t put the shadows in yet, but it’s coming along.
I’ve been meaning to rewrite a large chunk of the renderer for quite a while now, and I’ve finally got around to it. It was originally written a couple of years ago with the help of a book which even at the time was a little dated.
I’ll also admit that it took a lot longer to do than I thought it would, but only because I have two rather strict rules that I have to follow when changing the Renderer interface and putting in implementations.
Rule 1: Interface can’t be implementation specific – Which basically means that the interfaces can’t have any specific functions or data that will only be usable to a specific implementation of the renderer (which in this case is DirectX). I plan to create an OpenGL implementation of the renderer at some point so I need to make sure that the interface will work just as easily with both.
Rule 2: Don’t make assumptions – It’s easy to make assumptions during the implementation of some function for the sake of convenience, but for the interface to actually be usable it needs to be flexible. To gain flexibility you need to get more information from the users via a more robust interface which loops us back to Rule 1. I also have to walk a fine line between usability and flexibility, to be as flexible as all of the OpenGL extensions and features for example would require an incredibly complex interface at which point you may as well just use your API of choice directly.
So those are my excuses.
You won’t actually be able to see any changes just yet as I still need to integrate the changes into the RPM Demo. But sit back and relax with the knowledge that I’ll be working on that next, as well as tidying up some of the code in that demo – has any body looked at the house of cards that is the ‘code’ for the menu? No? Good.
The main differences for me as a developer using the Renderer is that I now have a bunch of new features like off-screen rendering (shocking that it wasn’t there before, isn’t it), delayed rendering, more flexibility stability and speed. The difference to the end-user is that there will be a (probably small) increase in performance and you’ll get some nicer looking graphics as I put in shadows, depth of field and other nice effects.
Now when I say delayed rendering I don’t mean deferred rendering I quite literately mean delayed. You can use a command buffer to store all your operations through the renderer and run them back later on, I’d like to point out that performance gains you’d get from using my command buffer are negligible. I did play around with internally logging all of the actual DirectX calls which did yield a little boost in frame rate, but the massive amounts of data you need to log every one of those calls was shocking, so I opted to just log the higher level calls to my rendering interface instead.
RPM – The vehicle simulation demo has been updated with improved physics, a new 3D track to race around, and a handy lap timer.
I’ve moved away from trying to make use of Pacejka’s magic formula, it just doesn’t give the results I need and only really works for a very small range of cases. As is so often the case I now just make everything up as I go along and use my own tyre modelling technique, which is simply to use a set of curves that determine how the tyre behaves under specific conditions and use those to give me the friction that the tyre should be producing. The beauty of it is, is that you can see the curves and drag them around with the mouse which makes editing them much more simple, and you can add an infinite number of different curves to help simulate the tyre. At the moment for example I don’t take temperature into consideration but in a while I’ll add that curve and then temperature will affect the tire. Ahh, no more messing about with silly formulas or relying on other peoples work.
So yeah, now that there is something to actually do in the game with a car that is actually drivable I urge you to going and take a look here.
Oh yeah, one thing that really gets my goat (if I had one). Has anybody seen TORCS? Ever read the FAQ? More specifically section 1.10? In the event that you haven’t here it is:
1.10 Should I start my own racing sim project?
Definitively not, no! Why? Do a search on sf.net and Google, you will find between 15 and 40 open source car/driving/racing sim projects, and most of them have been “promising” and died. Instead of starting another dead project contribute to the few existing successful ones.
Believe it or not, but your project will very likely be a dead one as well. The reason is quite simple, people underestimate the required effort and the change of their lives during the project lifespan, think about it. Just that you get an idea, TORCS turns now 10…
I stumbled on that a couple of years ago, before I even decided to make a physics engine and thought it was a piece of something you might find on the sole of your shoe. If I were less of a developer I might have read that and shied away from a physics engine or vehicle simulation, but being the complete lunatic I am I make what I want without worrying about the time or effort I might have to put in. So for anybody who catches this message, if you want to make something and people tell you it’s too hard what they mean is it’s too hard for them. If you’re determined to do something then you shouldn’t let other people stop you.
I know my vehicle sim is severely lacking in the features department, but I did write everything from scratch starting with no knowledge of physics simulations or vehicle dynamics and the collision physics are still better than in TORCS (at least last time I played with TORCS last year anyway) I can’t really comment on the tyre physics though since I’ve nothing to accurately compare to, though I suspect they aren’t as accurate to reality. So let this be an example, however poor, of what you can achieve if you try. You can then put it in a bag and swing it in the face of the neigh sayers who said it was too difficult, maybe give them a nose bleed.
The library that powers my data tool DataMan now has a half-twin, the CppDataLib which is almost identical to the original except that it is written using native C++ instead of managed C#. This means that any native application can now easily integrate the DataLib to use and modify files generated by DataMan. Although the implementation of the CppDataLib somewhat limits it to the Windows platform, it should not be too difficult to replace the small usage of windows functions to port it to other platforms.
That’s right my SVN repo’s are now on-line so you can always get the latest code, although I cannot guarantee that the latest code will work as intended or even compile.
The repositories are not hosted on the same server as the rest of the website and are instead hosted here with me, while I’ll try my best to keep them available I am at the mercy of my ISP.
Not all projects are accessible to everybody, but most projects are available as read only to the general public and you are able to view them and checkout the repositories to your machine.
You can view the repositories at https://svn.skgenius.co.uk/, to check out a repository to your local machine you just need to use the same URL as you see in your browser.
One last point is that I haven’t paid for an established Certificate Authority to issue an SSL certificate, and instead have issued my own, as such you may receive a warning from your browser or SVN client until such a time as I do pay for a trusted certificate.
It has been a while since I last updated the website but I have been busy, or at least I haven’t been doing nothing. Recently I came upon a situation where I needed some extra functionality out of my data tool and I wasn’t prepared to update and maintain the existing version so I started fresh.
This latest version is a huge improvement over the original, with a much nicer layout easier to use controls and a bunch of new features which make me start to think I should charge people for this stuff. It also allows you to extend the data types you can use by writing your own, all you need do is use a couple of the provided interfaces and the application will pick up your data type. Apart from being much better from the users point of view, it’s much nicer inside as well with everything in it’s place and a place for everything. I’ve also made sure to set it up in such a way that will allow for much better integration with the level editor (which by the way, will not work with latest version data files). One of the biggest additions is the ability to embed raw file data into the file, meaning instead of having a folder with hundreds of little files you can have one file that has been kindly crafted by the data tool and your application can extract the files from that.
Well, if anybody apart from bots ever crosses this page I urge you to take a look at the tool. It’s not just useful for games but almost any application where you need to store arbitrary bits of data or files. You could even use it as a simple file archiver. Check the project here.
After what seems like a lot more effort than it’s worth there have been some minor updates to the RPM demo. For me however it has been a grand journey of discovery with secret caves and hidden treasure and strange plot twists where you find out your sister is your mother.
Updates to the demo include:
Fixed physics time steps for greater accuracy
Some boxes for you to drive in to
A 0-60 timer to measure the cars acceleration
You can now actually enable V-Sync (it was previously disabled, on purpose)
I initially set out to add some multi threading to the physics engine. It seemed simple enough but I was mistaken. My biggest problem was trying to figure out how I was going to use multiple threads, what was each of them going to do and how to make sure they play nice with each other.
After a short while (2 days) of passive thinking on the problem the idea eventually came to me after watching Merlin on BBC One. I could split every little physics task up and add them to a queue for the threads to pick off, and I’d only add tasks if they didn’t use a body or other element that was already being processed. So Integrating became a task, as did resolving the velocities between two bodies that have collided, resolving the positions, and a bunch of other little bits. The next task was to implement it, so I made a thread safe queue using a linked list and a semaphore. It’s at this point that I discovered that locking and waiting for a semaphore is an incredibly slow operation and one that obliterated frame rates. I then attempted a lock-free solution that supported multiple consumers of the list, it took a while but I finally worked it all out. It’s at this point that I discovered the ABA problem, if you don’t know what it is then you should do a quick search on it now because it’s a right git. Eventually I settled on a lock-free circular queue which works just fine for multiple producers and consumers, but with the absolutely enormous warning sign which states that if you add more items to the queue than there is actually room for, then it will silently fail and everything is likely to explode – including the cup of tea on your desk.
So yeah, multi threading, easy. It was actually a lot more painful than this paragraph makes out as there where all those hours of debugging a multi-threaded memory trampling problem, and I now understand why I avoided it for so long. At least I have my Multi-Threading badge now, which I can sew into my shirt.
Once the whole threading thing was sorted I wanted to improve the springs a little. I make it a rule that I never copy any code that I don’t understand because it will almost certainly byte you in the arse some time later. This was an exception to that rule, I had copied some very strange spring constraint code from the Box2D engine and then adapted it to 3D, but it had some quirks (like the damping actually prevented the spring from returning to its neutral position). So I set out to implement something using Hooks Law, I figured that my integrator (Symplectic Euler) would’nt play too nice with my the standard spring equations so I went off to investigate using RK4. I spent quite a while implementing the RK4 integrator and fitting into the physics engine (mostly using a hammer) and in the end it turned out that Rk4 was indeed much more accurate, and the springs where as smooth as a baby’s bottom. Unfortunately RK4 prevents me from using warm starting (where we pre-emptively apply forces from the previous frame) so while more accurate, it was much less stable for stacking boxes and other such things. There was also a performance hit for the extra integration work, and the extra iterations in the solver that the warm starting would have helped eliminate the need for. So for all those people that push RK4 so hard, it’s not as great as you thought and is not really suitable for games and such. In the end I opted to keep the Symplectic Euler with the modification that the position is now calculated directly from the acceleration for that frame, so it should be slightly more accurate.
Well to cut this story a little short I now have 3 different integration methods to choose from, a Force Generator system where each rigid body has a set of force generators that will be run accordingly for each integrator – gravity is set up as one of these force generators for example (it’s a constant force so it doesn’t really need to be, but hey). The physics engine now supports running with fixed time steps (The RPM demo now runs at 120Hz in the background), and we can interpolate between physics states to eliminate temporal aliasing caused by rendering and physics updates that no longer match up!