Sunday, 26 June 2011
Vertex Manipulation (Mesh-editing)
Currently only the very core of this feature has been implemented (as seen in the video) and a lot of other stuff is still to follow, I will give a brief overview of how the fully functional tool should work once its complete. When any new model (.fbx or .x) is imported, it's processed by the content pipeline and turned into an .xnb file, an .xml file will be attached to the source (model) file that contains all changes to the model and will be processed during build-time. By default this .xml file is empty and nothing altered, during run-time a mesh can be converted to Editable Mesh (trying to keep this similar to 3D Studio Max's naming conventions) which allows vertex and triangle selection with support for any type of transformation that is supported by the gizmo component (translate, rotate, scale in local- and world-space) these transformations are stored inside Actions (I will talk about Actions a lot more at a later time, but it's basically what you use to support undo/redo in any kind of editing software) and written to the model Xml. The model is then re-build the next time the project is build and the actions are applied, this can hold any type of alteration including material renaming, splitting meshes and deleting / adding new vertices alongside vertex transformations.
Because the source model remains untouched, whenever the model is re-exported from any DCC-tool like 3D Studio Max or Maya the model will still build with all transformations and alterations applied. An example: A material named '#46 Material' is renamed at run-time to 'corridor_floor', if the artist then changes the name of '#46 Material' to 'corridor_floor' or something else in the source model, the run-time change is ignored because the original material name (#46 Material) can no longer be found... in a worst-case scenario this ignores the material properties you stored for the original name (material properties are stored elsewhere, so no data is actually lost) so even in the worst case, you are only a small step away from re-applying your previous changes (A warning dialog with failed conversions should help with this, making it potentially very quick and painless to manually re-assign the changes that are never lost, just ignored till resolved) The same applies to vertex transformations, but these can be a bit more difficult to keep track of once the indices of a certain mesh change inside the .fbx source file.
There is still a significant amount of work that has to be completed before this feature takes it full shape, with this first proof of concept up and running I believe it will be a very valuable tool to have available, and a lot of fun to create :)
It proved to be quite easy to convert the gizmo to support vertex manipulation (and selection) I will add these changes to the codeplex project at some point in the future...
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
To actually store your level you need to call the IntermediateSerializer.Serialize
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
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.
Thursday, 8 July 2010
Visual Scripting Editor (Video)
(Watch in HD & Fullscreen!)
Monday, 1 March 2010
Engine Update: Particles, Performance & Profiling
Since my last update over a week ago, a lot of progress has been made. First steps for Full-Screen post processing (HDR, Bloom, Gaussian) DPSF Particle system is integrated and works perfectly with Sunburn out-of-the-box. Progress has been made with the level & content management classes, loading/saving works great and a new method .CombineScenePart() is currently WIP to combine scenes or scene parts into a single level.
Other features like the CameraManager is coming along nicely and should be ready very soon. The manager allows you or the engine to add/remove and set a certain camera type and modify its properties. Dynamic actors have been updated, they now return to their original position when returning to EditMode (original being the last assigned position by either Xml or the Editor). Moving the dynamic objects while in PlayMode does not affect the EditMode position of that object.
Finally got some time to work with CLR Profiler. I wasn't sure how to use this little tool to my advantage, but after some hours of fiddling with the engine code and running it through the profiler I got the hang of it. Some silly code errors were altered/removed (Like an old and unused Matrix-array being called every draw-call for my game objects, the Matrix-array had no actual purpose it was merely a left-over from a previous XNA draw method. As a final optimization I had a better look at the xml files that were created when serializing my level data. The demo scene (screen in previous post) required 43.000 lines of xml data (The demo scene had about 350 objects) worth a total of 900 KB. It took me less than 15 minutes to get this down to 7.000 lines without losing any necessary data (A easy way was serializing only the Euler rotation property (of type Vector3) instead of a complete rotation Matrix (Thanks to Sean James)) The final Xml file only requires 150KB of disk space. The overall memory allocation have been decreased, it may be a bit early for memory optimizations, but it was good practice for later stages of development...
Unfortunately I have no new video/screenshots right now. I'll try to get some interesting footage later this week!
Monday, 15 February 2010
Level & Content management [Part 2]
Loading object data (position, rotation, scale) with XML is now (finally) complete...
What does this mean?
Every level has his own .xml file containing position, rotation and scale data for each object of that particular level. When loading a level, the appropriate xml file is loaded, assigning any stored data to the correct objects in the current level regardless of the Vector positions inside your C# code. This allows for persistence when building your levels. You no longer have to tweak Vector positions inside your code files, you can easily re-position your game objects while playing...Saving and later reloading when you're ready to play.
Video
Sunday, 14 February 2010
Level & Content management
- LevelCollection class manages a single LevelData class.
- LevelData class can hold all the game objects in the current scene.
- LevelCollection has control over Loading/Unloading (a particular scene) and XML LoadFromFile/SaveToFile methods (managing positions, rotations and scaling)
All the content is now being managed using Dictionaries. This provides great control over used and unused assets. In the current implementation a method is fired containing all the data of a particular scene. The current assets are compared with the assets required for the next scene. Unused data is unloaded. The remaining asset data is assigned to the proper game object.
That may sound either very straightforward or maybe you've completely lost it by now... Here's a quick summary:
LevelCollection.Load(*levelnametoload*) will know which scene you want to load, and will clear all current data present in the scene and loads all the new scene data as well as comparing current with new assets (models, textures etc.) to check if any new assets need to be loaded and if unused assets need to be unloaded to free memory.
When you're scene is loaded and visible on screen, you can either play it or start messing around with the positions. Changing a Position or Rotation will require LevelCollection.SaveToFile(*filename*) to persist after quiting the game.
I'd like to show a video about this very soon...So stay tuned!
Saturday, 9 January 2010
Tweaking variables using XML (Part 2)
In the provided sample the method is explained using a Vehicle class, with two instances of that class. the static 'FrictionDef' variable will declare the value that every instance of the class should use. a private 'frictionDef' variable will allow an instance to set this static value using the XMLSerializer. You as a developer can manually change the value of 'frictionDef' in the XML file (called 'SuperCar.xml' in this sample) and reload the file to set all instances to the new assigned values in the xml file. You can use this method to quickly change values in runtime on PC. For Xbox, the 'XNA console component' could help us out setting values in the xml file (of course, you will need a 'chatpad' to properly use the console on Xbox) so other solutions are still being explored. I've yet to implement this feature into the engine so I'll save it for a later blog entry.
For PC developers: keeping this type of gameplay specific data in easily readable XML format, will allow for easy cheating by players. You might want to consider running it through the content pipeline (as binary) when you're done tweaking. Alternatively, you might simply remove the whole code used to tweak, and assign the values to the variables in your source code. Doing so, will still safe you a lot of time compared to rebuilding your project for every slightly changed variable while tweaking your game.
Some articles of interest:
Shawn Hargreaves Blog: MotoGP Tweakables
Luminance: Changing constants at runtime
Link to sample code:
XML Tweaking Sample
Video
Tweaking variables using XML
With a fresh project coming up (got till about April to work on the engine, before I can put it to use for another school project) I can take some time to develop tools like the one mentioned before. I've no current plans to develop these tools for a wide audience, this makes it somewhat easier to code them. I do of course release snippets and full source when applicable. Most of my current code works, but is not qualified to be released without a proper cleanup. Releasing something to a wide audience of programmers without fully debugging or tweaking your code is not in anyone's best interest.
Like a lot of other previous posts, this one will be cut into two parts. The first part I will talk about a possible method that you can implement into your project/engine when trying to save time tweaking. The next part will show an example (with snippets etc.) using this method.
If you've ever made a game before, you will know how much time fine-tuning or tweaking any object in your game can consume of your total development cycle. To help reducing the amount of time spend building and rebuilding your game with only slight changes in your character's run speed, you need a tool. I use XML to help save time. It's still a work in progress, but tests have shown good results so far. I'll explain the concept below...
Every class that uses constant values that should not change during runtime (i.e. default run speed or friction in a spring) can be tweaked using this XML method. The tweakable value is not a 'const' as this would not allow us to change its value in runtime. Instead we will use a 'public static', which holds the value that is used for every instance of the class. to Get/Set this value with XML (explained in more detail in the second part) we will need a 'private (non-static)' value.
public static float FrictionDef;
private float frictionDef
{
get { return FrictionDef; }
set { FrictionDef = value; }
}
In its current implementation you will have to manually open the XML file created for the class (one XML file for every class that uses tweakables) in a text-editor and change the value to anything you'd like in runtime, saving the file and reloading it using a simple key command in-game will load your new values to the 'public static' variables. Any instance will now use the new values and you get direct feedback on any changes made.
I will go more in-depth of the coding required to achieve this in part two. And provide a video with the implementation in effect (if time permits)



