Exemple #1
0
        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());
        }
Exemple #2
0
 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);
        }
Exemple #8
0
        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);
        }
Exemple #10
0
        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);
        }