Monday, 27 September 2010

Triangle-precision ray collision

Bullet collision was previously calculated using the triangle mesh capabilities of BEPU. This wasn't going to work efficiently with all the separate meshes that are going to be used in our levels. With the basics of triangle-picking already implemented in the editor tools it didn't take a lot of time to get a basic prototype up and running. In the image below you can see the new filtering algorithm.

each "group" (1 big sphere, 8 small ones) contain 41k polygons. (click image to read the text)

In a regular scene with a higher amount of objects with lower polygons per mesh that are spread across the scene, the optimization methods will become more efficient. This will be tested once the prototype level is complete.
The main focus of the new filtering system is excluding hidden models before they enter into the per-triangle collision check. This system is added on top of the bounding-sphere filter that was already present in the editor tool.

Overkill? 150 million triangles both rendered and tested against the bullet ray. This clearly wasn't going to run smoothly (roughly 0.1 fps)

(use 720p and fullscreen to read the filtering info in the topleft corner)

Saturday, 18 September 2010

Engine Update: Sketching in 3D

Over the past 2 months I haven't posted a lot of news. With the new project up and running (kick-off was the 13th) I'll start doing more regular postings like I used to.

With the project details still being worked on, there is some time to develop tools that should make life easier later on in the development stage. So I decided to work on some odd ideas that I came up with while traveling. The first one is a pretty cool feature, its sketching in 3d. It uses the 3d meshes inside the level as a canvas to draw on. I think this is very useful for level designers and to help process play-testing feedback.

For this particular feature to work, triangle precision ray-testing was required. Luckily the XNA Creators Club had a sample project to get me started. The lines are made of vertices combined into a LineStrip. In addition the triangle normal is tested against the ray direction to prevent drawing on back-faced triangles.

While implementing triangle-precision picking I updated the Gizmo so it is now able to select models by triangle instead of the small boundingbox. Being used to 3D studio max' selection methods I decided to implement multi-layer selection. Because that name probably makes no sense, I'll try to explain it. If multiple objects are behind one another, clicking multiple times will select the object behind the previously selected object, clicking again will select the one behind it etc. That means you can select any object even if another is blocking your view.

Each click will pass through another "layer" and select the object occluded by the one in front.

Tuesday, 7 September 2010

Level & Content management [Part 3]

I got a question about my level and object management recently and was asked if I could talk about it. So in this post I'll explain my old and current method of dealing with (level) serialization and how I combined it with my game editor.

A few months ago I created my levels using a hybrid implementation of a level editor and code to create and connect objects. A game would have several "Scene" classes to be filled with Entities and later set at the correct position in 3D space using the level editor. This worked pretty well, especially since our team had limited time to work on our projects (8 weeks) so I wasn't able to create a fully featured editor at the time. One advantage was the ease of setting up connections and events between objects in a level, because everything is available in the Scene class. An obvious disadvantage was the inability of adding objects on the fly (in runtime) it required some planning to work efficiently. With the game Needle Juice there was only a limited about of objects that required the use of the editor, so again, a fully featured editor wasn't necessary.

However, after completing Over Night I set aside some time to work on a more complex editor to aid in the upcoming project(s). This meant a new way of serializing the Scene to store any data. This new method will be explained below, with some code snippets. On a side-note I strongly recommend looking at existing editors (like UDK) Fool around with it, learn its basics and see what fits your needs and what doesn't. I occasionally opened up an existing Unreal Tournament 3 map and messed around with it to hunt for new features. If you're the only developer to use that tool you can mold it to your exact specifications and preferences very easily.

Before I go on, the following is in no way the only or the best way of doing it. It worked for me and should be easy to implement for yourself. It will hopefully give you a clear idea of you can combine your own requirements with the examples shown.

First off, any object that exists in my level is an ISceneEntity (interface) with a Position, Rotation, Scale etc. The interface holds data that is necessary for any object in the world. Any class that derives from this interface or any other subclass may have its own properties that need to be serialized as well. That means a flexible serializer is required. Luckily Shawn was so kind to explain everything you ever wanted to know about IntermediateSerializer. I recommend you read through his article.

To store all data in your level your engine needs to know what to serialize and what to ignore. I use a fairly simple Level class to keep track of any objects currently in the world (and part of the serialization list) You add your Entity to a List in your Level class. The IntermediateSerializer will go through the list and store all Entities in an Xml level file.

To actually store your level you need to call the IntermediateSerializer.Serialize() to write all of the level data to your disk.

The above method is part of the Level.cs class.

If you're following along, don't forget to add the Microsoft.Xna.Framework.Content reference to your project folder. By default its already part of your Content project, when referencing in code, you need to add it to your game project as well. The IntermediateSerializer class is part of the Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate namespace.

Your level is now stored on disk. Some class will require setting some Attributes in order to be stored properly. Use the [ContentSerializerIgnore] Attribute over any public property that you want excluded. Use the [ContentSerializer] Attribute to include private or protected variables.

Finally to load all of your previously stored data you need to call IntermediateSerializer.Deserialize(). For more info I recommend reading through some of Shawn's articles about it.

I was going to talk about a new feature (mentioned in my previous post) that allows preloading of assets, reducing overall idle-time. This post is already long enough so I'll keep it in mind for some other time.

I hope this helps anyone looking to create his own editor. Level serialization isn't a complex operation, the most important thing is properly structured component system. If you have any questions you can post your comments in the comment section below.