Editing models inside my engine has been something I wanted to support for a long time now. Especially when you're not the one creating the assets, but do have to work with them inside the editor it can be time consuming to send back a model with incorrect material names or a mesh that should be split to optimize rendering, or vice versa. With this tool I will eliminate the need to have artists re-export their models because of tiny mistakes/changes and should provide a much cleaner pipeline in general.
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...
Super cool. I really admire you're dedication :)
ReplyDeleteWhat plans u got in store for high density models?
Thanks! :)
ReplyDeleteI guess for high density models the most important thing is to support a solid set of group-selection tools. I don't expect to do a lot of per-vertex changes on complex models, it will most likely be splitting it into smaller meshes or adding dummies etc. (could be really useful for weapons and meshes that require attachments)
For the re-applying vertex operations problem, you might try storing the original vertex position as well as the index in the action. If this position differs from what is stored in the model, you can generate a warning because vertex indexes might have changed.
ReplyDeleteThat could work. Luckily model data is split per-mesh inside the processor (including indices), so if one mesh was changed in the source, the others will still process with the correct changes.
ReplyDeleteI guess a baking options wouldn't hurt, especially for meshes that have been split-up and are on their own, baking them into a new .xnb will prevent loss of data after the source file is renewed.
how are you selecting and moving the verts? have you tried edge selection? perhaps a per poly, per mesh selection? btw I follow you pretty close and I really enjoy your progress especially because you share your knowledge of things I am very thankful for that.
ReplyDelete`Baker
I'm converting the mesh to use a DynamicVertexBuffer while editing. After finishing with the edits it is turned back into a regular VertexBuffer again. Using .GetData I generate a list of vertices and use this list to make the changes and push the changes back into the buffer with .SetData. Selection and moving is done using a modified version of the Gizmo and handles the vertices as if they were any type of transformable object.
ReplyDeleteEdge-selection etc. shouldn't be good difficult all the information is available inside the mesh already - it's just a matter of making the components (gizmo etc.) communicate with the available mesh-data.
I'm currently working on 'Actions', that will be used by this system among others (undo/redo-system and a really cool new feature that I will talk about at a later time)
awesome thanks for the info, I'll be sure to check back for the update you have me intrigued. Thanks again.
ReplyDelete`Baker