private static void Main(string[] args) { Stopwatch.StartNew(); Assembly executingAssembly = Assembly.GetExecutingAssembly(); string executingAssemblyFolder = Path.GetDirectoryName(executingAssembly.Location); var pathSeparator = Path.DirectorySeparatorChar; string outputFolder = Path.GetFullPath(Path.Combine(executingAssemblyFolder, String.Format(@"..{0}..{0}..{0}..{0}Output", pathSeparator))); List <Manifest> manifestMaster = new List <Manifest>(); // Make an inventory of what images there are var imageList = FileHelper.FindImageFiles(Path.Combine(executingAssemblyFolder, "Resources")); // Uses Reflection to create a list containing one instance of each group of models List <dynamic> allModelGroups = new List <dynamic>(); foreach (var type in executingAssembly.GetTypes()) { var modelGroupAttribute = type.GetCustomAttribute <ModelGroupAttribute>(); if (modelGroupAttribute != null) { ConstructorInfo ctor = type.GetConstructor(new Type[] { typeof(List <string>) }); dynamic modelGroup = ctor.Invoke(new dynamic[] { imageList }); allModelGroups.Add(modelGroup); } } var modelGroupIndex = 0; foreach (var modelGroup in allModelGroups) { List <List <Property> > combos = ComboHelper.AttributeCombos(modelGroup); ReadmeBuilder readme = new ReadmeBuilder(); modelGroup.id = modelGroupIndex++; Manifest manifest = new Manifest(modelGroup.modelGroupName); string modelGroupFolder = Path.Combine(outputFolder, modelGroup.modelGroupName.ToString()); FileHelper.ClearOldFiles(outputFolder, modelGroupFolder); Directory.CreateDirectory(modelGroupFolder); // Copy all of the images used by the model group into that model group's output directory FileHelper.CopyImageFiles(executingAssemblyFolder, modelGroupFolder, modelGroup.usedFigures); FileHelper.CopyImageFiles(executingAssemblyFolder, modelGroupFolder, modelGroup.usedTextures, useThumbnails: true); readme.SetupHeader(modelGroup); int numCombos = combos.Count; for (int comboIndex = 0; comboIndex < numCombos; comboIndex++) { string[] name = ReadmeStringHelper.GenerateName(combos[comboIndex]); var asset = new Runtime.Asset { Generator = "glTF Asset Generator", Version = "2.0", Extras = new Runtime.Extras { // Inserts a string into the .gltf containing the properties that are set for a given model, for debug. Attributes = String.Join(" - ", name) } }; var gltf = new glTFLoader.Schema.Gltf { Asset = asset.ConvertToSchema() }; var dataList = new List <Data>(); var geometryData = new Data(modelGroup.modelGroupName.ToString() + "_" + comboIndex.ToString("00") + ".bin"); dataList.Add(geometryData); Runtime.GLTF wrapper = Common.SinglePlane(); wrapper.Asset = asset; Runtime.Material mat = new Runtime.Material(); // Takes the current combo and uses it to bundle together the data for the desired properties wrapper = modelGroup.SetModelAttributes(wrapper, mat, combos[comboIndex], ref gltf); // Passes the desired properties to the runtime layer, which then coverts that data into // a gltf loader object, ready to create the model Runtime.GLTFConverter.ConvertRuntimeToSchema(wrapper, ref gltf, geometryData); // Makes last second changes to the model that bypass the runtime layer // in order to add 'features that don't really exist otherwise modelGroup.PostRuntimeChanges(combos[comboIndex], ref gltf); // Creates the .gltf file and writes the model's data to it var filename = modelGroup.modelGroupName.ToString() + "_" + comboIndex.ToString("00") + ".gltf"; var assetFile = Path.Combine(modelGroupFolder, filename); glTFLoader.Interface.SaveModel(gltf, assetFile); // Creates the .bin file and writes the model's data to it foreach (var data in dataList) { data.Writer.Flush(); var dataFile = Path.Combine(modelGroupFolder, data.Name); File.WriteAllBytes(dataFile, ((MemoryStream)data.Writer.BaseStream).ToArray()); } readme.SetupTable(modelGroup, comboIndex, combos); manifest.models.Add( new Manifest.Model(filename, modelGroup.modelGroupName, modelGroup.noSampleImages)); } readme.WriteOut(executingAssembly, modelGroup, modelGroupFolder); manifestMaster.Add(manifest); // Write out the manifest JSON specific to this model group string json = Newtonsoft.Json.JsonConvert.SerializeObject(manifest, Newtonsoft.Json.Formatting.Indented); File.WriteAllText(Path.Combine(modelGroupFolder, "Manifest.json"), json); } // Write out the master manifest JSON containing all of the model groups string jsonMaster = Newtonsoft.Json.JsonConvert.SerializeObject(manifestMaster.ToArray(), Newtonsoft.Json.Formatting.Indented); File.WriteAllText(Path.Combine(outputFolder, "Manifest.json"), jsonMaster); // Update the main readme ReadmeBuilder.UpdateMainReadme(executingAssembly, outputFolder, manifestMaster); Console.WriteLine("Model Creation Complete!"); Console.WriteLine("Completed in : " + TimeSpan.FromTicks(Stopwatch.GetTimestamp()).ToString()); }
public glTFLoader.Schema.Gltf Import(string path) { glTFLoader.Schema.Gltf gltf = glTFLoader.Interface.LoadModel(path); return(gltf); }
public Runtime.GLTF SetModelAttributes(Runtime.GLTF wrapper, Runtime.Material material, List <Property> combo, ref glTFLoader.Schema.Gltf gltf) { // Switch from the flat plane to a model with multiple nodes wrapper = Common.MultiNode(); var nodeList = new List <Runtime.Node>(); nodeList.Add(wrapper.Scenes[0].Nodes[0]); nodeList.Add(wrapper.Scenes[0].Nodes[0].Children[0]); // Clear the vertex normal and tangent values already in the model foreach (var node in nodeList) { node.Mesh.MeshPrimitives[0].Normals = null; node.Mesh.MeshPrimitives[0].Tangents = null; } // Apply non-transforming attributes first, so they're copied to the control nodes foreach (Property property in combo) { if (property.name == Propertyname.NormalTexture) { material.NormalTexture = new Runtime.Texture(); material.NormalTexture.Source = property.value; } else if (property.name == Propertyname.BaseColorTexture) { material.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); material.MetallicRoughnessMaterial.BaseColorTexture = new Runtime.Texture(); material.MetallicRoughnessMaterial.BaseColorTexture.Source = property.value; } else if (property.name == Propertyname.MetallicRoughnessTexture) { material.MetallicRoughnessMaterial.MetallicRoughnessTexture = new Runtime.Texture(); material.MetallicRoughnessMaterial.MetallicRoughnessTexture.Source = property.value; } else { foreach (var node in nodeList) { if (property.name == Propertyname.VertexNormal) { node.Mesh.MeshPrimitives[0].Normals = property.value; } else if (property.name == Propertyname.VertexTangent) { node.Mesh.MeshPrimitives[0].Tangents = property.value; } } } } foreach (Property property in combo) { if (property.name == Propertyname.Matrix) { nodeList[1].Matrix = specialProperties[0].value; } else if (property.name == Propertyname.Scale) { nodeList[1].Scale = property.value; } } // Apply the material to each node foreach (var node in nodeList) { node.Mesh.MeshPrimitives[0].Material = material; } return(wrapper); }
public Runtime.GLTF SetModelAttributes(Runtime.GLTF wrapper, Runtime.Material material, List <Property> combo, ref glTFLoader.Schema.Gltf gltf) { // Determines which of the primitives will have the material and attributes applied to it var splitType = combo.Find(e => e.propertyGroup == 1); foreach (Property property in combo) { if (property.name == Propertyname.Primitives_Split1 || property.name == Propertyname.Primitives_Split2 || property.name == Propertyname.Primitives_Split3 || property.name == Propertyname.Primitives_Split4) { // Same plane, but split into two triangle primitives var primitive0 = specialProperties.Find(e => e.name == Propertyname.Primitive_0); var primitive1 = specialProperties.Find(e => e.name == Propertyname.Primitive_1); Runtime.MeshPrimitive prim0 = new Runtime.MeshPrimitive { Positions = primitive0.value.Positions, Indices = primitive0.value.Indices, }; Runtime.MeshPrimitive prim1 = new Runtime.MeshPrimitive { Positions = primitive1.value.Positions, Indices = primitive1.value.Indices, }; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives = new List <Runtime.MeshPrimitive> { prim0, prim1 }; } if (property.name == Propertyname.BaseColorTexture) { if (material.MetallicRoughnessMaterial == null) { material.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); material.MetallicRoughnessMaterial.BaseColorTexture = new Runtime.Texture(); } material.MetallicRoughnessMaterial.BaseColorTexture.Source = property.value; material.MetallicRoughnessMaterial.BaseColorTexture.TexCoordIndex = 0; } if (property.name == Propertyname.NormalTexture) { if (material.NormalTexture == null) { material.NormalTexture = new Runtime.Texture(); } material.NormalTexture.Source = property.value; material.NormalTexture.TexCoordIndex = 0; } // Attributes set for only the first primitive if (splitType.name == Propertyname.Primitives_Split1) { if (property.name == Propertyname.VertexNormal) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Normals = property.value; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Normals = null; } else if (property.name == Propertyname.VertexTangent) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Tangents = property.value; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Tangents = null; } else if (property.name == Propertyname.VertexColor_Vector4_Float) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Colors = property.value; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Colors = null; } else if (ReadmeStringHelper.GenerateNameWithSpaces(property.name.ToString()) == ReadmeStringHelper.GenerateNameWithSpaces(Propertyname.Primitive0VertexUV0.ToString())) // All UV0 { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = new List <List <Vector2> >(); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive0VertexUV0).value); } else if (ReadmeStringHelper.GenerateNameWithSpaces(property.name.ToString()) == ReadmeStringHelper.GenerateNameWithSpaces(Propertyname.Primitive0VertexUV1.ToString())) // All UV1 { if (wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets == null) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = new List <List <Vector2> >(); } wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive0VertexUV1).value); } } // Attributes set for only the second primitive else if (splitType.name == Propertyname.Primitives_Split2) { if (property.name == Propertyname.VertexNormal) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Normals = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Normals = property.value; } else if (property.name == Propertyname.VertexTangent) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Tangents = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Tangents = property.value; } else if (property.name == Propertyname.VertexColor_Vector4_Float) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Colors = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Colors = property.value; } else if (ReadmeStringHelper.GenerateNameWithSpaces(property.name.ToString()) == ReadmeStringHelper.GenerateNameWithSpaces(Propertyname.Primitive1VertexUV0.ToString())) // All UV0 { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = new List <List <Vector2> >(); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive1VertexUV0).value); } else if (ReadmeStringHelper.GenerateNameWithSpaces(property.name.ToString()) == ReadmeStringHelper.GenerateNameWithSpaces(Propertyname.Primitive1VertexUV1.ToString())) // All UV1 { if (wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets == null) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = new List <List <Vector2> >(); } wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive1VertexUV1).value); } } // Attributes set for both of the primitives else if (splitType.name == Propertyname.Primitives_Split3) { if (property.name == Propertyname.VertexNormal) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Normals = property.value; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Normals = property.value; } else if (property.name == Propertyname.VertexTangent) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Tangents = property.value; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Tangents = property.value; } else if (property.name == Propertyname.VertexColor_Vector4_Float) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Colors = property.value; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Colors = property.value; } else if (property.name == Propertyname.Primitive0VertexUV0) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = new List <List <Vector2> >(); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive0VertexUV0).value); } else if (property.name == Propertyname.Primitive1VertexUV0) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = new List <List <Vector2> >(); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive1VertexUV0).value); } else if (property.name == Propertyname.Primitive0VertexUV1) { if (wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets == null) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = new List <List <Vector2> >(); } wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive0VertexUV1).value); } else if (property.name == Propertyname.Primitive1VertexUV1) { if (wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets == null) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = new List <List <Vector2> >(); } wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive1VertexUV1).value); } } // Attributes set for neither of the primitives else if (splitType.name == Propertyname.Primitives_Split4) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Normals = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Normals = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Tangents = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Tangents = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Colors = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Colors = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = null; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = null; } } // Material needs to be a deep copy here, or both primitives will get the same Mat. if (material.MetallicRoughnessMaterial != null) { if (splitType.name == Propertyname.Primitives_Split1 || splitType.name == Propertyname.Primitives_Split3) { var mat = DeepCopy.CloneObject(material); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Material = mat; } if (splitType.name == Propertyname.Primitives_Split2 || splitType.name == Propertyname.Primitives_Split3) { var mat = DeepCopy.CloneObject(material); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Material = mat; } } // Use the second UV if it has been set if (splitType.name != Propertyname.Primitives_Split4) { var prim0UV1 = combo.Find(e => e.name == Propertyname.Primitive0VertexUV1); var prim1UV1 = combo.Find(e => e.name == Propertyname.Primitive1VertexUV1); if (prim0UV1 != null) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0]. Material.MetallicRoughnessMaterial.BaseColorTexture.TexCoordIndex = 1; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0]. Material.NormalTexture.TexCoordIndex = 1; } if (prim1UV1 != null) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1]. Material.MetallicRoughnessMaterial.BaseColorTexture.TexCoordIndex = 1; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1]. Material.NormalTexture.TexCoordIndex = 1; } } return(wrapper); }
public Runtime.GLTF SetModelAttributes(Runtime.GLTF wrapper, Runtime.Material material, List <Property> combo, ref glTFLoader.Schema.Gltf gltf) { // Same plane, but split into two triangle primitives var primitive1 = specialProperties.Find(e => e.name == Propertyname.Primitives_Split1); var primitive2 = specialProperties.Find(e => e.name == Propertyname.Primitives_Split2); Runtime.MeshPrimitive prim0 = new Runtime.MeshPrimitive { Positions = primitive1.value.Positions, Indices = primitive1.value.Indices, }; Runtime.MeshPrimitive prim2 = new Runtime.MeshPrimitive { Positions = primitive2.value.Positions, Indices = primitive2.value.Indices, }; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives = new List <Runtime.MeshPrimitive> { prim0, prim2 }; foreach (Property property in combo) { if (property.name == Propertyname.BaseColorTexture) { if (material.MetallicRoughnessMaterial == null) { material.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); material.MetallicRoughnessMaterial.BaseColorTexture = new Runtime.Texture(); } material.MetallicRoughnessMaterial.BaseColorTexture.Source = property.value; material.MetallicRoughnessMaterial.BaseColorTexture.TexCoordIndex = 0; } if (property.name == Propertyname.NormalTexture) { if (material.NormalTexture == null) { material.NormalTexture = new Runtime.Texture(); } material.NormalTexture.Source = property.value; material.NormalTexture.TexCoordIndex = 0; } if (property.name == Propertyname.VertexNormal) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Normals = property.value; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Normals = property.value; } else if (property.name == Propertyname.VertexTangent) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Tangents = property.value; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Tangents = property.value; } else if (property.name == Propertyname.VertexColor_Vector4_Float) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Colors = property.value; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Colors = property.value; } else if (property.name == Propertyname.Primitive0VertexUV0) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets = new List <List <Vector2> >(); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive0VertexUV0).value); } else if (property.name == Propertyname.Primitive1VertexUV0) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets = new List <List <Vector2> >(); wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].TextureCoordSets.Add( specialProperties.Find(e => e.name == Propertyname.Primitive1VertexUV0).value); } } if (material.MetallicRoughnessMaterial != null) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Material = material; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Material = material; } return(wrapper); }
public Runtime.GLTF SetModelAttributes(Runtime.GLTF wrapper, Runtime.Material material, List <Property> combo, ref glTFLoader.Schema.Gltf gltf) { foreach (Property req in requiredProperty) { if (req.name == Propertyname.AlphaMode_Blend) { material.AlphaMode = req.value; } } foreach (Property property in combo) { if (property.propertyGroup == 3) // Alpha Cutoff { material.AlphaCutoff = property.value; } else if (property.name == Propertyname.BaseColorFactor) { if (material.MetallicRoughnessMaterial == null) { material.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); } material.MetallicRoughnessMaterial.BaseColorFactor = property.value; } else if (property.name == Propertyname.BaseColorTexture) { if (material.MetallicRoughnessMaterial == null) { material.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); } material.MetallicRoughnessMaterial.BaseColorTexture = new Runtime.Texture(); material.MetallicRoughnessMaterial.BaseColorTexture.Source = property.value; } else if (property.name == Propertyname.VertexColor_Vector4_Float) { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].ColorComponentType = Runtime.MeshPrimitive.ColorComponentTypeEnum.FLOAT; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].ColorType = Runtime.MeshPrimitive.ColorTypeEnum.VEC4; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Colors = property.value; } } wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Material = material; return(wrapper); }
public Runtime.GLTF SetModelAttributes(Runtime.GLTF wrapper, Runtime.Material material, List <Property> combo, ref glTFLoader.Schema.Gltf gltf) { // Switch from the flat plane to a model with multiple nodes wrapper = Common.MultiNode(); var nodeList = new List <Runtime.Node>(); nodeList.Add(wrapper.Scenes[0].Nodes[0]); nodeList.Add(wrapper.Scenes[0].Nodes[0].Children[0]); // Add a new child node that will inherit the transformations nodeList.Add((DeepCopy.CloneObject(wrapper.Scenes[0].Nodes[0]))); nodeList[2].Name = "Node1"; nodeList[2].Children = null; nodeList[1].Children = new List <Runtime.Node>(); nodeList[1].Children.Add(nodeList[2]); // Clear the vertex normal and tangent values already in the model foreach (var node in nodeList) { node.Mesh.MeshPrimitives[0].Normals = null; node.Mesh.MeshPrimitives[0].Tangents = null; } foreach (Property property in combo) { if (property.name == Propertyname.Matrix) { nodeList[1].Matrix = specialProperties[0].value; } else if (property.name == Propertyname.Translation || property.name == Propertyname.Translation_X || property.name == Propertyname.Translation_Y || property.name == Propertyname.Translation_Z) { nodeList[1].Translation = property.value; } else if (property.name == Propertyname.Rotation) { nodeList[1].Rotation = specialProperties[1].value; } else if (property.name == Propertyname.Scale) { nodeList[1].Scale = property.value; } } // Apply the material to each node foreach (var node in nodeList) { node.Mesh.MeshPrimitives[0].Material = material; } return(wrapper); }
private static void Main(string[] args) { Stopwatch.StartNew(); Assembly executingAssembly = Assembly.GetExecutingAssembly(); string executingAssemblyFolder = Path.GetDirectoryName(executingAssembly.Location); char pathSeparator = Path.DirectorySeparatorChar; string outputFolder = Path.GetFullPath(Path.Combine(executingAssemblyFolder, string.Format(@"..{0}..{0}..{0}..{0}Output", pathSeparator))); string positiveTestsFolder = Path.Combine(outputFolder, "Positive"); string negativeTestsFolder = Path.Combine(outputFolder, "Negative"); var jsonSerializer = new JsonSerializer { Formatting = Formatting.Indented, ContractResolver = new CamelCasePropertyNamesContractResolver() }; // Make an inventory of what images there are. var imageList = FileHelper.FindImageFiles(Path.Combine(executingAssemblyFolder, "Resources")); // Create an ordered list initalizing each model group. var positiveTests = new List <ModelGroup> { new Animation_Node(imageList), new Animation_NodeMisc(imageList), new Animation_Skin(imageList), new Animation_SkinType(imageList), new Buffer_Interleaved(imageList), new Compatibility(imageList), new Material(imageList), new Material_AlphaBlend(imageList), new Material_AlphaMask(imageList), new Material_AlphaMaskTraining(imageList), new Material_DoubleSided(imageList), new Material_MetallicRoughness(imageList), new Material_Mixed(imageList), new Material_SpecularGlossiness(imageList), new Mesh_PrimitiveAttribute(imageList), new Mesh_PrimitiveMode(imageList), new Mesh_PrimitiveVertexColor(imageList), new Mesh_Primitives(imageList), new Mesh_PrimitivesUV(imageList), new Node_Attribute(imageList), new Node_NegativeScale(imageList), new Texture_Sampler(imageList), new Animation_SamplerType(imageList), new Instancing(imageList), }; var negativeTests = new List <ModelGroup> { new Mesh_PrimitiveRestart(imageList), new Mesh_NoPosition(imageList), }; // Retains the manifest from each test type for use in updating the main readme table. var mainManifests = new List <List <Manifest> > { ProcessModelGroups(positiveTests, positiveTestsFolder), ProcessModelGroups(negativeTests, negativeTestsFolder), }; ReadmeBuilder.UpdateMainReadme(executingAssembly, mainManifests, Directory.GetParent(outputFolder).ToString(), new string[] { "Positive", "Negative" }); // Writes a readme explaining the different test types. using (var newReadme = new FileStream(Path.Combine(outputFolder, "README.md"), FileMode.Create)) { executingAssembly.GetManifestResourceStream("AssetGenerator.ReadmeTemplates.Page_Output.md").CopyTo(newReadme); } Console.WriteLine("Model Creation Complete!"); Console.WriteLine($"Completed in : {TimeSpan.FromTicks(Stopwatch.GetTimestamp()).ToString()}"); /// <summary> /// Saves each model group to a master manifest as it is created, and writes that manifest to file. /// </summary> /// <returns>Manifest containing all of the model groups and created.</returns> List <Manifest> ProcessModelGroups(List <ModelGroup> modelGroupList, string savePath) { // Generates the models and saves the model group manifest in with the master manifest. var manifests = new List <Manifest>(); foreach (var modelGroup in modelGroupList) { manifests.Add(GenerateModels(modelGroup, savePath)); } // Writes the master manifest to file. using (var writeManifest = new StreamWriter(Path.Combine(savePath, "Manifest.json"))) { jsonSerializer.Serialize(writeManifest, manifests.ToArray()); } return(manifests); } /// <summary> /// Create and write all models contained in a model group. Writes a mini-manifest for just the model group to file. /// Generates a readme describing the models created. Also copies over required textures and figures. /// </summary> /// <returns>Manifest containing the model group's models.</returns> Manifest GenerateModels(ModelGroup modelGroup, string savePath) { var readme = new ReadmeBuilder(); var manifest = new Manifest(modelGroup.Id); string modelGroupFolder = Path.Combine(savePath, modelGroup.Id.ToString()); Directory.CreateDirectory(modelGroupFolder); // Copy all of the images used by the model group into that model group's output directory. FileHelper.CopyImageFiles(executingAssemblyFolder, modelGroupFolder, modelGroup.UsedFigures); FileHelper.CopyImageFiles(executingAssemblyFolder, modelGroupFolder, modelGroup.UsedTextures, useThumbnails: true); readme.SetupHeader(modelGroup); var numCombos = modelGroup.Models.Count; for (var comboIndex = 0; comboIndex < numCombos; comboIndex++) { var model = modelGroup.Models[comboIndex]; var filename = $"{modelGroup.Id}_{comboIndex:00}.gltf"; using (var data = new Data($"{modelGroup.Id}_{comboIndex:00}.bin")) { // Pass the desired properties to the runtime layer, which then coverts that data into // a gltf loader object, ready to create the model. var converter = new Runtime.GLTFConverter { CreateInstanceOverride = model.CreateSchemaInstance }; glTFLoader.Schema.Gltf gltf = converter.ConvertRuntimeToSchema(model.GLTF, data); // Makes last second changes to the model that bypass the runtime layer. model.PostRuntimeChanges?.Invoke(gltf); // Create the .gltf file and writes the model's data to it. string assetFile = Path.Combine(modelGroupFolder, filename); glTFLoader.Interface.SaveModel(gltf, assetFile); // Create the .bin file and writes the model's data to it. string dataFile = Path.Combine(modelGroupFolder, data.Name); File.WriteAllBytes(dataFile, data.ToArray()); } readme.SetupTable(modelGroup, comboIndex, model, Path.GetFileName(savePath)); manifest.Models.Add(new Manifest.Model(filename, modelGroup.Id, modelGroup.NoSampleImages, model.Camera, model.Animated, model.Loadable)); } // Write the readme and manifest specific to this model group. readme.WriteOut(executingAssembly, modelGroup, modelGroupFolder); using (var writeModelGroupManifest = new StreamWriter(Path.Combine(modelGroupFolder, "Manifest.json"))) { jsonSerializer.Serialize(writeModelGroupManifest, manifest); } return(manifest); } }
public Runtime.GLTF SetModelAttributes(Runtime.GLTF wrapper, Runtime.Material material, List <Property> combo, ref glTFLoader.Schema.Gltf gltf) { foreach (Property property in combo) { if (property.name == Propertyname.MinVersion) { wrapper.Asset.MinVersion = property.value; } else if (property.name == Propertyname.Version || property.name == Propertyname.Version_Current) { wrapper.Asset.Version = property.value; } else if (property.name == Propertyname.Description_ExtensionRequired) { wrapper.ExtensionsRequired = new List <string>(); wrapper.ExtensionsRequired.Add("EXT_QuantumRendering"); material.MetallicRoughnessMaterial = null; material.Extensions = new List <Runtime.Extensions.Extension>(); material.Extensions.Add(new Runtime.Extensions.EXT_QuantumRendering()); var extension = material.Extensions[0] as Runtime.Extensions.EXT_QuantumRendering; extension.PlanckFactor = new Vector4(0.2f, 0.2f, 0.2f, 0.8f); extension.CopenhagenTexture = new Runtime.Texture(); extension.EntanglementFactor = new Vector3(0.4f, 0.4f, 0.4f); extension.ProbabilisticFactor = 0.3f; extension.SuperpositionCollapseTexture = new Runtime.Texture(); } else if (property.name == Propertyname.Description_WithFallback) { // Fallback alpha mode will be set in the PostRuntimeChanges function } } if (combo.Count > 0) // Don't set the material on the empty set { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Material = material; } return(wrapper); }
public Runtime.GLTF SetModelAttributes(Runtime.GLTF wrapper, Runtime.Material material, List <Property> combo, ref glTFLoader.Schema.Gltf gltf) { // Initialize MetallicRoughness for the empty set if (combo.Count == 0) { material.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); } foreach (Property property in combo) { if (material.MetallicRoughnessMaterial == null) { material.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); } switch (property.name) { case Propertyname.BaseColorFactor: { material.MetallicRoughnessMaterial.BaseColorFactor = property.value; break; } case Propertyname.MetallicFactor: { material.MetallicRoughnessMaterial.MetallicFactor = property.value; break; } case Propertyname.RoughnessFactor: { material.MetallicRoughnessMaterial.RoughnessFactor = property.value; break; } case Propertyname.BaseColorTexture: { material.MetallicRoughnessMaterial.BaseColorTexture = new Runtime.Texture(); material.MetallicRoughnessMaterial.BaseColorTexture.Source = property.value; break; } case Propertyname.MetallicRoughnessTexture: { material.MetallicRoughnessMaterial.MetallicRoughnessTexture = new Runtime.Texture(); material.MetallicRoughnessMaterial.MetallicRoughnessTexture.Source = property.value; break; } case Propertyname.VertexColor_Vector3_Float: { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].ColorComponentType = Runtime.MeshPrimitive.ColorComponentTypeEnum.FLOAT; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].ColorType = Runtime.MeshPrimitive.ColorTypeEnum.VEC3; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Colors = property.value; break; } } } wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Material = material; return(wrapper); }
public Runtime.GLTF SetModelAttributes(Runtime.GLTF wrapper, Runtime.Material material0, List <Property> combo, ref glTFLoader.Schema.Gltf gltf) { // Same plane, but split into two triangle primitives var primitive1 = specialProperties.Find(e => e.name == Propertyname.Primitives_Split1); var primitive2 = specialProperties.Find(e => e.name == Propertyname.Primitives_Split2); Runtime.MeshPrimitive prim0 = new Runtime.MeshPrimitive { Positions = primitive1.value.Positions, Indices = primitive1.value.Indices, }; Runtime.MeshPrimitive prim2 = new Runtime.MeshPrimitive { Positions = primitive2.value.Positions, Indices = primitive2.value.Indices, }; wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives = new List <Runtime.MeshPrimitive> { prim0, prim2 }; // Make a second material var material1 = DeepCopy.CloneObject(material0); // Set the base color factor on both materials material0.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); material1.MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness(); material0.MetallicRoughnessMaterial.BaseColorFactor = requiredProperty.Find(e => e.name == Propertyname.Material0WithBaseColorFactor).value; material1.MetallicRoughnessMaterial.BaseColorFactor = requiredProperty.Find(e => e.name == Propertyname.Material1WithBaseColorFactor).value; foreach (Property property in combo) { switch (property.name) { case Propertyname.Primitive0_Material0BaseColorFactor: { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Material = material0; break; } case Propertyname.Primitive0_Material1BaseColorFactor: { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[0].Material = material1; break; } case Propertyname.Primitive1_Material0BaseColorFactor: { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Material = material0; break; } case Propertyname.Primitive1_Material1BaseColorFactor: { wrapper.Scenes[0].Nodes[0].Mesh.MeshPrimitives[1].Material = material1; break; } } } return(wrapper); }