One of the tools I made for my current project is a model editor. Basically it can import in .fbx or .x models, and then you can apply my custom effects, set parameters, set textures, and then save it using my custom model format I named “.jsm” (it’s just XML…don’t tell anyone!). Anyway one of the neat features I wanted it to have was the ability to add a model to my game’s Content project so that you wouldn’t have to manually do it through Visual Studio. And since the Content Pipeline uses MSBuild, this is easy to do:
// Load up the content project Engine.GlobalEngine.BinPath = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(); Project contentProject = new Project(); contentProject.Load(projectFileName); // Add it BuildItem newItem = contentProject.AddNewItem("Compile", "Models\\" + modelName + ".fbx"); newItem.SetMetadata("Link", "Models\\" + modelName + ".fbx"); newItem.SetMetadata("Name", modelName); newItem.SetMetadata("Importer", "FbxImporter"); newItem.SetMetadata("Processor", "ModelProcessor"); // Save it contentProject.Save(projectFileName);
This is of course the generic version and not the actual code I used, but you get the idea. The “projectFileName” string should contain a path to your Content.contentproj file in your Content subfolder. “modelName” would just be a name for your model, minus the extension. What’s going on is pretty simple: I load up the Content project using the Engine and Project classes found in Microsoft.Build.BuildEngine. Then I create a new BuildItem for the model, which I add to the Project. When I create the BuildItem, the string I send to the constructor contains the path to the model file relative to the .contentproj file. The first bit of metadata specifies that I want to add the file as a link, not as a copy. The string specifies how the file shows up in the project hierarchy (AKA, how it will show up when you expand the Content node in Visual Studio). The second bit of metadata is just a name associated with the file. Then the third specifies the ContentImporter to use, and the fourth specifies the ContentProcessor to use.