The company I work for requires some fresh meat, and so we invited some pending Computer Science graduates from UKZN to visit the company and gave some presentations so as to try lure them in. I've been maintaining the graphics engine for the last few years, and so I was asked to speak about that. On Friday I had to dig around for a few images for the talk. I quite like some of them and so I decided to upload a few (since I haven't posted anything in months).
Showing posts with label mining sims. Show all posts
Showing posts with label mining sims. Show all posts
Sunday, August 17, 2014
Friday, August 2, 2013
Voxel Collision Heightmap
Posted by
Damien Classen
One of the unexpectedly challenging aspects of getting our voxel systems integrated fully into the engine is achieving stable and efficient collision detection and response, and decent vehicle behaviour when driving over portions of the world implemented using voxels.
Currently, the voxel system collision detection system I have in place works correctly. However, if you dig deep enough into a large voxel volume so that much of it has been eaten away, the optimization steps I can take to keep the number of intersections against individual voxels lessens. To put it another way, when you’ve dug into the voxel system sufficiently, the voxel data has been expanded a lot and so many calculations need to be performed. In my stress testing I had a vehicle driving through a large voxel tunnel where most of it had been dug away, with all of the vehicle collisions volumes / lines enabled (there are a lot). I encountered two problems.
Currently, the voxel system collision detection system I have in place works correctly. However, if you dig deep enough into a large voxel volume so that much of it has been eaten away, the optimization steps I can take to keep the number of intersections against individual voxels lessens. To put it another way, when you’ve dug into the voxel system sufficiently, the voxel data has been expanded a lot and so many calculations need to be performed. In my stress testing I had a vehicle driving through a large voxel tunnel where most of it had been dug away, with all of the vehicle collisions volumes / lines enabled (there are a lot). I encountered two problems.
The first problem was that the performance dropped significantly, to the point where I started to become very concerned about where to go next. However, I gave it some thought and have some solutions planned (and partially implemented). I am optimistic about these, and will elaborate further in a moment.
The second problem I had was that if we had pursued the more simplistic method I had in mind initially, the wheels would be moving over a relatively blocky surface when you’re digging up or down an incline (which we do need to do). This would give erratic behaviour, and we’d need to find a solution to this. Smoothing it out by using a greater number of smaller voxels helps the dynamics behaviour but would compound performance difficulties. This got me to thinking that converting the 'ground layer' of the voxel system into a collision heightmap that you drive on top of would be a better alternative.
What I mean by this is that when performing wheel collisions tests I sample a collision heightmap instead. This heightmap is constructed using the voxel data (it essentially reduces a 3D problem to a 2D problem so as to improve vehicle driving behaviour).
I have been hacking away and have a significant portion of the collision heightmap code implemented, though it is still a work-in-progress and so more work will need to be done before it is useable (I'm estimating a day or two). A benefit of this is that I can eliminate sharp jumps in height (i.e. the surface beneath the wheels will appear to the dynamics to be smooth rather than blocky).
I have been hacking away and have a significant portion of the collision heightmap code implemented, though it is still a work-in-progress and so more work will need to be done before it is useable (I'm estimating a day or two). A benefit of this is that I can eliminate sharp jumps in height (i.e. the surface beneath the wheels will appear to the dynamics to be smooth rather than blocky).
I will achieve this via interpolation. So, for example, if you sample the collision heightmap beneath the wheel, I will also sample surrounding height values and filter the results. I have recently implemented exactly the same functionality in the D3D11-based engine / demo I have been working on at home (see previous blog entries), and so I can just bring in and re-use that code, which has been honed and works well. Basically it makes use of hand-coded bilinear interpolation.
Note that this technique makes certain assumptions about the intended usage of the sim -- it assumes a single 'layer' of empty space. You couldn't, for example, construct a bridge out of voxels with this feature enabled and expect it to behave as expected. But for our current purposes the limiting assumption holds true, and so this is not a concern.
To summarize, using a collision heightmap will give smooth, stable behaviour when driving over a surface or tunnel represented by voxels, and will also yield performance benefits.
Here is a screenshot of some debug lines used to visualize a small portion of the underlying heightmap data. It is difficult to see from this picture (perhaps I should use tiny boxes instead to show heights), but these lines extend from the base of the heightmap to the first section of empty space directly above them.
Monday, July 15, 2013
Voxel system update
Posted by
Damien Classen
I've been working on adding a voxel framework to our engine for use in sims where we need destructible terrain / rock. The first project that will use this technology is a continuous miner simulation. Although the framework has been in place for a while, it has only become stable (bug free and efficient) in the last week or two. I've had to do a fair bit of profiling in order to eliminate bottlenecks and boost performance (I use a tool called Luke Stackwalker, which I quite like).
I had a gloomy moment when I first integrated it into the sim because there was a noticeable frame rate drop, but it turned out to simply be some debugging / debug visualization code I had left in. After commenting that out the framerate went right back up to a point that was actually better than anticipated considering (a) how much collision detection logic I'm running, (b) that the state of the system is being propagated through the system via state packets and (c) that I was running both dynamics and graphics on the same PC (so twice the load). It cuts through the wall pretty smoothly and the framerate is currently above 60fps.
Friday, June 21, 2013
Voxel Systems on a Distributed Architecture
Posted by
Damien Classen
One of our current projects is a continuous miner -- a mining machine designed to cut coal and soft minerals. The operator will have be, to some extent, free to dig / cut where he pleases, which introduced the need for the development of new technology to meet this requirement. At a tech meeting a few months back we came to the conclusion that voxels would be a suitable fit for these requirements, and so for the past few months I have been working on developing a voxel framework and integrating it into our engine. For this particular project there will be three separate systems in the world, each representing a 'diggable' / destroyable part of the world.
We were a bit wary starting off, knowing that developing voxel technology isn't an undertaking to be taken lightly, especially given time constraints and some relatively unique aspects of our architecture.
One of the challenges I've faced is ensuring that the voxel systems work with our recording / playback system. A feature of our sims is the ability to store and play back exercises, which works by storing the state of the system at short intervals into a database. Voxels require a massive amount of data to store, and saving it all to disk many times a second simply wasn't feasible.
In addition to this, we have a distributed architecture, whereby the core sim logic is performed on a dynamics node, which then pumps out network packets to multiple graphics nodes. To clarify: we have one PC acting as a server, receiving the input from the driver and handling the main logic and physics. The state of the sim is handled on this main server and is propogated to various client PCs via network packets. Each of these client PCs is a graphics node, each rendering to its own screen (the operator will typically be surrounded by several screens showing the 3D world).
Again, the massive amount of data required for a voxel representation of part of the world is much larger than what most people realize. This data set needs to exist on each node. As the vehicle digs into the rock (i.e. as voxels are destroyed), the data set changes and these changes need to be propogated to the client machines so that the visual representation is updated as well.
My initial implementation was to go the typical sparse voxel octree route. However, the fact that I needed to maintain the same data set over several nodes made this option less attractive than a slightly simpler, flat representation. I chose to rather partition the entire system into a fixed number of 'clumps'. So, for example, one might create a voxel system that is 10m x 10m x 10m, and specify that you want each clump to be 1m x 1m x 1m large, and that you want each voxel to be 10cm x 10cm x 10cm. In this instance, you would have 1000 voxel clumps, and each of those clumps would consist of 1000 voxels.
Rather than transmitting the entire data set per network packet update (and similarly, rather than save the entire dataset to the database each time), I transmit only a single voxel clump. Currently, each voxel is represented as a single byte. So for each network update I would be sending across (and storing), in the example described above, 1000 bytes, which is not too bad.
I was considering bit-packing them so that each voxel was one bit instead (which would mean 8 times less memory required). However, unfortunately voxels do require more than a binary state, and so this isn't feasible. One would think that a binary state is sufficient (after all, each voxel represents either solid space or empty space). But its a bit more complicated than that, since I need to keep track of other information that allows me to generate renderable geometry representing only the shell (that is, the outer layer of voxels). So a voxel's state can be one of the following:
- empty space
- solid space adjacent to empty space
- solid space surrounded by solid space
- solid space at one of the outer edges of the system
One of the issues I have faced so far is due to the fact that, as you dig into the rock, the data needs to be sent over a network and you're only sending information for a single clump at a time. If you destroy many voxels very quickly it takes a while for all of that information to be propogated, and so you see the visual representation kind-of fizzling and eating away at itself more slowly than it should. In the actual sim this shouldn't be a problem for two reasons -- firstly, you can only dig through rock at a fairly slow rate. Secondly, your vision will be obscured by the massive machinery, dust etc.
Another problem is the vehicle physics. One of the main ways our physics engine handles collision detection and response is using collision lines. We perform intersection tests on various programmer-defined lines against the world geometry and the dynamics team has the vehicle's behaviour based on reacttions to those. I had to implement line collisions tests for the voxel system. Although there are many, many optimizations that can be (and have been) made, in the end there is always going to be some unavoidable brute force 'is this line intersecting this box' logic going on. So far though, we seem to be ok. We won't really know if the current optimizations are enough to yield suitable performance until we're a bit further in.
Tuesday, August 9, 2011
LHD Mining Vehicle Project
Posted by
Damien Classen
I am currently working on a mining sim vehicle. The vehicle is called an LHD (load-haul dumper). The company has done quite a few of these in the past and often each project requires some degree of repitition. As such, we have identified various common components so that we can design a generic LHD framework as we develop this project, moving common functionality into various generic classes (that project-specific classes will inherit from) as well as providing interfaces for project-specific classes to implement. Much of the design work is now out of the way, leaving internal logics, scoring and faults to be implemented from my side.
Subscribe to:
Posts (Atom)









