Exemple #1
0
        public Material FindMaterial(uint materialId)
        {
            if (Materials.ContainsKey(materialId))
            {
                return(Materials [materialId]);
            }

            return(null);
        }
Exemple #2
0
 public bool TryAddMaterial(Material material)
 {
     if ((material == null) || string.IsNullOrEmpty(material.Name) || Materials.ContainsKey(material.Name))
     {
         return(false);
     }
     Materials.Add(material.Name, material);
     return(true);
 }
Exemple #3
0
        public static Material CreateMaterial(MaterialType type, MaterialParameters parameters = null, string name = "")
        {
            if (Materials.ContainsKey(name))
            {
                return(null);
            }

            Material material = new Material(type, parameters, name);

            Materials.Add(material.Name, material);

            return(material);
        }
        public double GetMaterial(string v)
        {
            if (Materials == null)
            {
                return(0.0);
            }

            if (!Materials.ContainsKey(v.ToLower()))
            {
                return(0.0);
            }

            return(Materials[v.ToLower()]);
        }
Exemple #5
0
        public bool Deserialize(object data)
        {
            JObject jm = data as JObject;

            if (jm == null)
            {
                return(false);
            }

            if (jm["BoneCount"] != null)
            {
                BoneCount = jm["BoneCount"].Value <int>();
            }

            if (jm["Mesh"] != null)
            {
                Mesh.Deserialize(jm["Mesh"]);
            }

            //
            JArray jmats = jm["Materials"].Value <JArray>();

            foreach (JObject jmat in jmats)
            {
                string linked_subsetname = jmat["LinkedSubset"].Value <string>().ToLower();
                if (Materials.ContainsKey(linked_subsetname) == false)
                {
                    string    mat_type = jmat["Type"].Value <string>();
                    CMaterial material = CMaterial.Create(mat_type, linked_subsetname);

                    if (material.Deserialize(jmat) == false)
                    {
                        continue;
                    }

                    Materials.Add(linked_subsetname, material);
                }
            }

            // anim
            JObject janimCtrl = jm["AnimCtrl"].Value <JObject>();
            JArray  janims    = janimCtrl["Anims"].Value <JArray>();

            if (janims.Count != 0)
            {
                Anim.Deserialize(janims.First.Value <JObject>());
            }

            return(true);
        }
Exemple #6
0
        public static void DeleteMaterial(string name)
        {
            if (!Materials.ContainsKey(name))
            {
                return;
            }

            Material defaultMat = GetMaterial(Settings.NameDefaultMaterial);

            foreach (var mesh in defaultMat.AssignedObjects)
            {
                mesh.MeshMaterial = defaultMat;
            }
            Materials.Remove(name);
        }
Exemple #7
0
 public bool TryAddShader(Shader shader)
 {
     if ((shader == null) || string.IsNullOrEmpty(shader.Name) || Shaders.ContainsKey(shader.Name))
     {
         return(false);
     }
     if (string.IsNullOrEmpty(shader.Material) || !Materials.ContainsKey(shader.Material))
     {
         return(false);
     }
     if (!string.IsNullOrEmpty(shader.Texture) && !Textures.ContainsKey(shader.Texture))
     {
         return(false);
     }
     Shaders.Add(shader.Name, shader);
     return(true);
 }
Exemple #8
0
 private void setMaterials(IntermediateNode materialLibraryNode)
 {
     //TODO: int count = 0;
     foreach (Node materialNode in materialLibraryNode)
     {
         if (materialNode is IntermediateNode)
         {
             uint materialId = CrcTool.FLModelCrc(materialNode.Name);
             if (!Materials.ContainsKey(materialId))
             {
                 Materials.Add(materialId, Material.FromNode(materialNode as IntermediateNode, this));
             }
         }
         //else if (subNode.Name.Equals("material count", StringComparison.OrdinalIgnoreCase))
         //count = (subNode as LeafNode).getIntegerBlaBLubb;
     }
     //if (count != materials.Count)
     //throw new Exception("Invalid material count: " + count + " != " + materials.Count);
 }
Exemple #9
0
        private void LoadMaterialDefinitionsByXPathNavigator(XPathNavigator navigator)
        {
            XPathNodeIterator materialDefinitions;

            try
            {
                materialDefinitions = navigator.Select("/Object/Array[@Name='MaterialDefinitions']/Object[@Class='MaterialDefinition']");
            }
            catch (Exception)
            {
                return;
            }

            while (materialDefinitions.MoveNext())
            {
                MaterialDefinition materialDefinition = MaterialDefinition.LoadFromXPathNavigator(materialDefinitions.Current);

                if (materialDefinition != null && false == Materials.ContainsKey(materialDefinition.NameHash))
                {
                    Materials.Add(materialDefinition.NameHash, materialDefinition);
                }
            }
        }
Exemple #10
0
        /// <summary>
        /// Loads an mtl file.
        /// </summary>
        /// <param name="objMaterialPath">The path to the mtl file.</param>
        public void LoadMaterial(string objMaterialPath)
        {
            if (!File.Exists(objMaterialPath))
            {
                throw new ArgumentException("File does not exist!", objMaterialPath);
            }

            var        objMaterialFolder       = Path.GetDirectoryName(objMaterialPath) ?? string.Empty;
            var        objMaterialStreamReader = new StreamReader(objMaterialPath);
            string     lastMaterialNameRead    = null;
            string     originalLine            = null;
            const char lineSeparator           = ' ';

            while ((originalLine = objMaterialStreamReader.ReadLine()) != null)
            {
                if (string.IsNullOrWhiteSpace(originalLine))
                {
                    continue;
                }

                var trimmedLine      = originalLine.Trim();
                var splittedLine     = trimmedLine.Split(lineSeparator);
                var splittedLineSize = splittedLine.Length;

                if (trimmedLine[0] == '#')
                {
                    continue;
                }

                if (splittedLineSize == 1)
                {
                    throw new ParseException(originalLine, "Arguments from the token are missing.");
                }

                if (splittedLine[0] == "newmtl" && splittedLineSize >= 2)
                {
                    var materialName = string.Join(new string(lineSeparator, 1), splittedLine.Skip(1));
                    lastMaterialNameRead            = materialName;
                    Materials[lastMaterialNameRead] = new ObjMaterial(lastMaterialNameRead);
                    continue;
                }

                if (splittedLine[0] == "Ka" && splittedLineSize >= 4)
                {
                    if (lastMaterialNameRead == null)
                    {
                        throw new ParseException(originalLine, "No material was defined before.");
                    }
                    if (!Materials.ContainsKey(lastMaterialNameRead))
                    {
                        throw new ParseException(originalLine, string.Format("Material {0} is undefined.", lastMaterialNameRead));
                    }
                    var    material = Materials[lastMaterialNameRead];
                    double r, g, b;
                    var    resultR = double.TryParse(splittedLine[1], NumberStyles.Any, CultureInfo.InvariantCulture, out r);
                    var    resultG = double.TryParse(splittedLine[2], NumberStyles.Any, CultureInfo.InvariantCulture, out g);
                    var    resultB = double.TryParse(splittedLine[3], NumberStyles.Any, CultureInfo.InvariantCulture, out b);
                    if (!(resultR && resultG && resultB))
                    {
                        throw new ParseException(originalLine, "Ambient rgb values must be floating point numbers.");
                    }
                    material.AmbientColor.Red   = r;
                    material.AmbientColor.Green = g;
                    material.AmbientColor.Blue  = b;
                    continue;
                }

                if (splittedLine[0] == "Kd" && splittedLineSize >= 4)
                {
                    if (lastMaterialNameRead == null)
                    {
                        throw new ParseException(originalLine, "No material was defined before.");
                    }
                    if (!Materials.ContainsKey(lastMaterialNameRead))
                    {
                        throw new ParseException(originalLine, string.Format("Material {0} is undefined.", lastMaterialNameRead));
                    }
                    var    material = Materials[lastMaterialNameRead];
                    double r, g, b;
                    var    resultR = double.TryParse(splittedLine[1], NumberStyles.Any, CultureInfo.InvariantCulture, out r);
                    var    resultG = double.TryParse(splittedLine[2], NumberStyles.Any, CultureInfo.InvariantCulture, out g);
                    var    resultB = double.TryParse(splittedLine[3], NumberStyles.Any, CultureInfo.InvariantCulture, out b);
                    if (!(resultR && resultG && resultB))
                    {
                        throw new ParseException(originalLine, "Ambient rgb values must be floating point numbers.");
                    }
                    material.DiffuseColor.Red   = r;
                    material.DiffuseColor.Green = g;
                    material.DiffuseColor.Blue  = b;
                    continue;
                }

                if (splittedLine[0] == "Ks" && splittedLineSize >= 4)
                {
                    if (lastMaterialNameRead == null)
                    {
                        throw new ParseException(originalLine, "No material was defined before.");
                    }
                    if (!Materials.ContainsKey(lastMaterialNameRead))
                    {
                        throw new ParseException(originalLine, string.Format("Material {0} is undefined.", lastMaterialNameRead));
                    }
                    var    material = Materials[lastMaterialNameRead];
                    double r, g, b;
                    var    resultR = double.TryParse(splittedLine[1], NumberStyles.Any, CultureInfo.InvariantCulture, out r);
                    var    resultG = double.TryParse(splittedLine[2], NumberStyles.Any, CultureInfo.InvariantCulture, out g);
                    var    resultB = double.TryParse(splittedLine[3], NumberStyles.Any, CultureInfo.InvariantCulture, out b);
                    if (!(resultR && resultG && resultB))
                    {
                        throw new ParseException(originalLine, "Ambient rgb values must be floating point numbers.");
                    }
                    material.SpecularColor.Red   = r;
                    material.SpecularColor.Green = g;
                    material.SpecularColor.Blue  = b;
                    continue;
                }

                if (splittedLine[0] == "Ns" && splittedLineSize >= 2)
                {
                    if (lastMaterialNameRead == null)
                    {
                        throw new ParseException(originalLine, "No material was defined before.");
                    }
                    if (!Materials.ContainsKey(lastMaterialNameRead))
                    {
                        throw new ParseException(originalLine, string.Format("Material {0} is undefined.", lastMaterialNameRead));
                    }
                    var    material = Materials[lastMaterialNameRead];
                    double ns;
                    var    result = double.TryParse(splittedLine[1], NumberStyles.Any, CultureInfo.InvariantCulture, out ns);
                    if (!result)
                    {
                        throw new ParseException(originalLine, "Ns value must be a floating point number.");
                    }
                    material.Shininess = ns;
                    continue;
                }

                if ((splittedLine[0] == "d" || splittedLine[0] == "Tr") &&
                    splittedLineSize >= 2)
                {
                    if (lastMaterialNameRead == null)
                    {
                        throw new ParseException(originalLine, "No material was defined before.");
                    }
                    if (!Materials.ContainsKey(lastMaterialNameRead))
                    {
                        throw new ParseException(originalLine, string.Format("Material {0} is undefined.", lastMaterialNameRead));
                    }
                    var    material = Materials[lastMaterialNameRead];
                    double transparency;
                    var    result = double.TryParse(splittedLine[1], NumberStyles.Any, CultureInfo.InvariantCulture,
                                                    out transparency);
                    if (!result)
                    {
                        throw new ParseException(originalLine, "Transparency value must be a floating point number.");
                    }
                    material.Transparency = transparency;
                    continue;
                }

                if (splittedLine[0] == "illum" && splittedLineSize >= 2)
                {
                    if (lastMaterialNameRead == null)
                    {
                        throw new ParseException(originalLine, "No material was defined before.");
                    }
                    if (!Materials.ContainsKey(lastMaterialNameRead))
                    {
                        throw new ParseException(originalLine, string.Format("Material {0} is undefined.", lastMaterialNameRead));
                    }
                    var material = Materials[lastMaterialNameRead];
                    int illum;
                    var result = int.TryParse(splittedLine[1], NumberStyles.Any, CultureInfo.InvariantCulture, out illum);
                    if (!result)
                    {
                        throw new ParseException(originalLine, "Illum value must be a integer number.");
                    }
                    material.Illumination = illum;
                    continue;
                }

                if (splittedLine[0] == "map_Ka" && splittedLineSize >= 2)
                {
                    // TODO : Need to add all options here, for complete parsing.
                    if (lastMaterialNameRead == null)
                    {
                        throw new ParseException(originalLine, "No material was defined before.");
                    }
                    if (!Materials.ContainsKey(lastMaterialNameRead))
                    {
                        throw new ParseException(originalLine, string.Format("Material {0} is undefined.", lastMaterialNameRead));
                    }
                    var material = Materials[lastMaterialNameRead];
                    if (splittedLine.Length >= 6 && splittedLine[1] == "-o")
                    {
                        material.AmbientTexture.ScaleU = double.Parse(splittedLine[2], CultureInfo.InvariantCulture);
                        material.AmbientTexture.ScaleV = double.Parse(splittedLine[3], CultureInfo.InvariantCulture);
                        var texturePath = string.Join(new string(lineSeparator, 1), splittedLine.Skip(5));
                        material.AmbientTexture.LoadImage(Path.Combine(objMaterialFolder, texturePath));
                    }
                    else
                    {
                        var texturePath = string.Join(new string(lineSeparator, 1), splittedLine.Skip(1));
                        material.AmbientTexture.LoadImage(Path.Combine(objMaterialFolder, texturePath));
                    }
                    continue;
                }

                if (splittedLine[0] == "map_Kd" && splittedLineSize >= 2)
                {
                    // TODO : Need to add all options here, for complete parsing.
                    if (lastMaterialNameRead == null)
                    {
                        throw new ParseException(originalLine, "No material was defined before.");
                    }
                    if (!Materials.ContainsKey(lastMaterialNameRead))
                    {
                        throw new ParseException(originalLine, string.Format("Material {0} is undefined.", lastMaterialNameRead));
                    }
                    var material = Materials[lastMaterialNameRead];
                    if (splittedLine.Length >= 6 && splittedLine[1] == "-o")
                    {
                        material.DiffuseTexture.ScaleU = double.Parse(splittedLine[2], CultureInfo.InvariantCulture);
                        material.DiffuseTexture.ScaleV = double.Parse(splittedLine[3], CultureInfo.InvariantCulture);
                        var texturePath = string.Join(new string(lineSeparator, 1), splittedLine.Skip(5));
                        material.DiffuseTexture.LoadImage(Path.Combine(objMaterialFolder, texturePath));
                    }
                    else
                    {
                        var texturePath = string.Join(new string(lineSeparator, 1), splittedLine.Skip(1));
                        material.DiffuseTexture.LoadImage(Path.Combine(objMaterialFolder, texturePath));
                    }
                    continue;
                }

                if (splittedLine[0] == "map_Ks" && splittedLineSize >= 2)
                {
                    // TODO : Need to add all options here, for complete parsing.
                    if (lastMaterialNameRead == null)
                    {
                        throw new ParseException(originalLine, "No material was defined before.");
                    }
                    if (!Materials.ContainsKey(lastMaterialNameRead))
                    {
                        throw new ParseException(originalLine, string.Format("Material {0} is undefined.", lastMaterialNameRead));
                    }
                    var material = Materials[lastMaterialNameRead];
                    if (splittedLine.Length >= 6 && splittedLine[1] == "-o")
                    {
                        material.SpecularTexture.ScaleU = double.Parse(splittedLine[2], CultureInfo.InvariantCulture);
                        material.SpecularTexture.ScaleV = double.Parse(splittedLine[3], CultureInfo.InvariantCulture);
                        var texturePath = string.Join(new string(lineSeparator, 1), splittedLine.Skip(5));
                        material.SpecularTexture.LoadImage(Path.Combine(objMaterialFolder, texturePath));
                    }
                    else
                    {
                        var texturePath = string.Join(new string(lineSeparator, 1), splittedLine.Skip(1));
                        material.SpecularTexture.LoadImage(Path.Combine(objMaterialFolder, texturePath));
                    }
                    continue;
                }

                if (splittedLine[0] == "Ni")
                {
                    continue;
                }

                throw new ParseException(originalLine, "Unable to parse because originalLine doesnt fit into the mtl format.");
            }
        }
Exemple #11
0
        /// <summary>
        /// Loads an obj file.
        /// </summary>
        /// <param name="objModelPath">The path to the obj file.</param>
        /// <throws>
        /// ParseException
        /// ArgumentException
        /// </throws>
        public void Load(string objModelPath)
        {
            if (!File.Exists(objModelPath))
            {
                throw new ArgumentException("File does not exist!", objModelPath);
            }

            var objModelFolder       = Path.GetDirectoryName(objModelPath) ?? string.Empty;
            var objModelStreamReader = new StreamReader(objModelPath);

            string     originalLine;
            string     lastObjectMaterialRead = null;
            string     lastObjectNameRead     = null;
            const char lineSeparator          = ' ';

            while ((originalLine = objModelStreamReader.ReadLine()) != null)
            {
                if (string.IsNullOrWhiteSpace(originalLine))
                {
                    continue;
                }

                var trimmedLine      = originalLine.Trim();
                var splittedLine     = trimmedLine.Split(lineSeparator);
                var splittedLineSize = splittedLine.Length;

                if (trimmedLine[0] == '#')
                {
                    continue;
                }

                if (splittedLineSize == 1)
                {
                    throw new ParseException(originalLine, "Arguments from the token are missing.");
                }

                if (splittedLine[0] == "mtllib" && splittedLineSize >= 2)
                {
                    var materialFileName = string.Join(new string(lineSeparator, 1), splittedLine.Skip(1));
                    LoadMaterial(Path.Combine(objModelFolder, materialFileName));
                    continue;
                }

                if (splittedLine[0] == "v" && splittedLineSize >= 4)
                {
                    double x, y, z;
                    var    resultX = double.TryParse(splittedLine[1], NumberStyles.Any, CultureInfo.InvariantCulture, out x);
                    var    resultY = double.TryParse(splittedLine[2], NumberStyles.Any, CultureInfo.InvariantCulture, out y);
                    var    resultZ = double.TryParse(splittedLine[3], NumberStyles.Any, CultureInfo.InvariantCulture, out z);
                    if (!(resultX && resultY && resultZ))
                    {
                        throw new ParseException(originalLine, "Vertexes coordinates must be floating point numbers.");
                    }
                    Vertices.Add(new ObjVertex {
                        X = x, Y = y, Z = z
                    });
                    continue;
                }

                if (splittedLine[0] == "vt" && splittedLineSize >= 3)
                {
                    double x, y;
                    var    resultX = double.TryParse(splittedLine[1], NumberStyles.Any, CultureInfo.InvariantCulture, out x);
                    var    resultY = double.TryParse(splittedLine[2], NumberStyles.Any, CultureInfo.InvariantCulture, out y);
                    if (!(resultX && resultY))
                    {
                        throw new ParseException(originalLine, "Texture coordinates must be floating point numbers.");
                    }
                    Textures.Add(new ObjTexture {
                        X = x, Y = y
                    });
                    continue;
                }

                if (splittedLine[0] == "vn" && splittedLineSize >= 4)
                {
                    double x, y, z;
                    var    resultX = double.TryParse(splittedLine[1], NumberStyles.Any, CultureInfo.InvariantCulture, out x);
                    var    resultY = double.TryParse(splittedLine[2], NumberStyles.Any, CultureInfo.InvariantCulture, out y);
                    var    resultZ = double.TryParse(splittedLine[3], NumberStyles.Any, CultureInfo.InvariantCulture, out z);
                    if (!(resultX && resultY && resultZ))
                    {
                        throw new ParseException(originalLine, "Vertexes coordinates must be floating point numbers.");
                    }
                    Normals.Add(new ObjNormal {
                        X = x, Y = y, Z = z
                    });
                    continue;
                }

                if (splittedLine[0] == "f")
                {
                    if (Objects.Count == 0)
                    {
                        Objects["Untitled"] = new ObjObject(this, "Untitled");
                        lastObjectNameRead  = "Untitled";
                    }

                    var newFace = new ObjFace(lastObjectMaterialRead);

                    for (var index = 1; index < splittedLineSize; index++)
                    {
                        var faceItem = new ObjFaceItem();
                        var tokens   = splittedLine[index].Split('/');

                        if (tokens.Length >= 1)
                        {
                            if (string.IsNullOrWhiteSpace(tokens[0]))
                            {
                                throw new ParseException(originalLine, "Faces need at least the vertex index to be present.");
                            }
                            int vertexIndex;
                            var result = int.TryParse(tokens[0], NumberStyles.Any, CultureInfo.InvariantCulture, out vertexIndex);
                            if (!result)
                            {
                                throw new ParseException(originalLine, "Faces require vertex index to be an integer value.");
                            }
                            faceItem.VertexIndex = vertexIndex - 1;
                        }
                        if (tokens.Length >= 2 && !string.IsNullOrWhiteSpace(tokens[1]))
                        {
                            int textureIndex;
                            var result = int.TryParse(tokens[1], NumberStyles.Any, CultureInfo.InvariantCulture, out textureIndex);
                            if (!result)
                            {
                                throw new ParseException(originalLine, "Faces require texture index to be an integer value.");
                            }
                            faceItem.TextureIndex = textureIndex - 1;
                        }
                        if (tokens.Length >= 3 && !string.IsNullOrWhiteSpace(tokens[2]))
                        {
                            int normalIndex;
                            var result = int.TryParse(tokens[2], NumberStyles.Any, CultureInfo.InvariantCulture, out normalIndex);
                            if (!result)
                            {
                                throw new ParseException(originalLine, "Faces require normal index to be an integer value.");
                            }
                            faceItem.NormalIndex = normalIndex - 1;
                        }
                        newFace.FaceItems.Add(faceItem);
                    }

                    Objects[lastObjectNameRead].Faces.Add(newFace);
                    continue;
                }

                if (splittedLine[0] == "o" && splittedLineSize >= 2)
                {
                    var objectName = string.Join(new string(lineSeparator, 1), splittedLine.Skip(1));
                    Objects[objectName] = new ObjObject(this, objectName);
                    lastObjectNameRead  = objectName;
                    continue;
                }

                if (splittedLine[0] == "usemtl" && splittedLineSize >= 2)
                {
                    var materialName = string.Join(new string(lineSeparator, 1), splittedLine.Skip(1));
                    if (!Materials.ContainsKey(materialName))
                    {
                        throw new ParseException(originalLine, string.Format("Unable to find the material {0}", materialName));
                    }
                    lastObjectMaterialRead = materialName;
                    continue;
                }

                if (splittedLine[0] == "g")
                {
                    // TODO : maybe handle groups?
                    continue;
                }

                if (splittedLine[0] == "s")
                {
                    // TODO : maybe handle smoothness (not necesary)
                    continue;
                }
                throw new ParseException(originalLine, "Unable to parse because originalLine doesnt fit into the obj format.");
            }

            // Calulcate min vetexes and max vertexes
            CalculateMaxAndMinVertex();

            foreach (var objObject in Objects.Values)
            {
                objObject.Build();
            }
        }
        protected override async Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
        {
            var assetManager = new AssetManager();

            while (Interlocked.Increment(ref spawnedFbxCommands) >= 2)
            {
                Interlocked.Decrement(ref spawnedFbxCommands);
                await Task.Delay(1, CancellationToken);
            }

            try
            {
                object exportedObject;

                if (ExportType == "animation")
                {
                    // Read from model file
                    var animationClip = LoadAnimation(commandContext, assetManager);
                    exportedObject = animationClip;
                    if (animationClip == null)
                    {
                        commandContext.Logger.Info("File {0} has an empty animation.", SourcePath);
                    }
                    else if (animationClip.Duration.Ticks == 0)
                    {
                        commandContext.Logger.Warning("File {0} has a 0 tick long animation.", SourcePath);
                    }
                    else
                    {
                        animationClip.RepeatMode = AnimationRepeatMode;
                        animationClip.Optimize();
                    }
                }
                else if (ExportType == "model")
                {
                    // Read from model file
                    var model = LoadModel(commandContext, assetManager);

                    model.BoundingBox = BoundingBox.Empty;
                    var hierarchyUpdater = new ModelViewHierarchyUpdater(model.Hierarchy.Nodes);
                    hierarchyUpdater.UpdateMatrices();

                    bool hasErrors = false;
                    foreach (var mesh in model.Meshes)
                    {
                        if (TessellationAEN)
                        {
                            // TODO: Generate AEN model view
                            commandContext.Logger.Error("TessellationAEN is not supported in {0}", ContextAsString);
                            hasErrors = true;
                            continue;
                        }

                        if (!Materials.ContainsKey(mesh.Name))
                        {
                            commandContext.Logger.Error("Mesh material [{0}] was not found in {1}", mesh.Name, ContextAsString);
                            hasErrors = true;
                            continue;
                        }

                        // set the material
                        var materialReference = Materials[mesh.Name];
                        mesh.Material = new ContentReference <MaterialData>(materialReference.Item1, materialReference.Item2);

                        // set the parameters
                        if (Parameters.ContainsKey(mesh.Name) && Parameters[mesh.Name] != null)
                        {
                            if (mesh.Parameters == null)
                            {
                                mesh.Parameters = new ParameterCollectionData();
                            }
                            foreach (var keyValue in Parameters[mesh.Name])
                            {
                                mesh.Parameters.Set(keyValue.Key, keyValue.Value);
                            }
                        }

                        // TODO: remove this when Lighting configuration will be behind a key in mesh parameters. This case will be handled by the code just above
                        // set the lighting configuration description
                        Tuple <Guid, string> lightingReference;
                        if (Lightings.TryGetValue(mesh.Name, out lightingReference))
                        {
                            mesh.Parameters.Set(LightingKeys.LightingConfigurations, new ContentReference <LightingConfigurationsSetData>(lightingReference.Item1, lightingReference.Item2));
                        }
                    }

                    // split the meshes if necessary
                    model.Meshes = SplitExtensions.SplitMeshes(model.Meshes, Allow32BitIndex);

                    // merge the meshes
                    if (Compact)
                    {
                        var indicesBlackList = new HashSet <int>();
                        if (PreservedNodes != null)
                        {
                            for (var index = 0; index < model.Hierarchy.Nodes.Length; ++index)
                            {
                                var node = model.Hierarchy.Nodes[index];
                                if (PreservedNodes.Contains(node.Name))
                                {
                                    indicesBlackList.Add(index);
                                }
                            }
                        }

                        // group meshes with same material and same root
                        var sameMaterialMeshes = new List <GroupList <int, MeshData> >();
                        GroupFromIndex(model, 0, indicesBlackList, model.Meshes, sameMaterialMeshes);

                        // remove meshes that cannot be merged
                        var excludedMeshes  = new List <MeshData>();
                        var finalMeshGroups = new List <GroupList <int, MeshData> >();
                        foreach (var meshList in sameMaterialMeshes)
                        {
                            var mergeList = new GroupList <int, MeshData> {
                                Key = meshList.Key
                            };

                            foreach (var mesh in meshList)
                            {
                                if (mesh.Skinning != null || indicesBlackList.Contains(mesh.NodeIndex))
                                {
                                    excludedMeshes.Add(mesh);
                                }
                                else
                                {
                                    mergeList.Add(mesh);
                                }
                            }

                            if (mergeList.Count <= 1)
                            {
                                excludedMeshes.AddRange(mergeList);
                            }
                            else
                            {
                                finalMeshGroups.Add(mergeList);
                            }
                        }

                        var finalMeshes = new List <MeshData>();

                        finalMeshes.AddRange(excludedMeshes);

                        foreach (var meshList in finalMeshGroups)
                        {
                            // transform the buffers
                            foreach (var mesh in meshList)
                            {
                                var transformationMatrix = GetMatrixFromIndex(model.Hierarchy.Nodes, hierarchyUpdater, meshList.Key, mesh.NodeIndex);
                                mesh.Draw.VertexBuffers[0].TransformBuffer(ref transformationMatrix);
                            }

                            // refine the groups base on several tests
                            var newMeshGroups = new List <GroupList <int, MeshData> > {
                                meshList
                            };
                            // only regroup meshes if they share the same parameters
                            newMeshGroups = RefineGroups(newMeshGroups, CompareParameters);
                            // only regroup meshes if they share the shadow options
                            newMeshGroups = RefineGroups(newMeshGroups, CompareShadowOptions);
                            //only regroup meshes if they share the same lighting configurations
                            newMeshGroups = RefineGroups(newMeshGroups, CompareLightingConfigurations);


                            // add to the final meshes groups
                            foreach (var sameParamsMeshes in newMeshGroups)
                            {
                                var baseMesh    = sameParamsMeshes[0];
                                var newMeshList = sameParamsMeshes.Select(x => x.Draw).ToList().GroupDrawData(Allow32BitIndex);
                                foreach (var generatedMesh in newMeshList)
                                {
                                    finalMeshes.Add(new MeshData {
                                        Material   = baseMesh.Material,
                                        Parameters = baseMesh.Parameters,
                                        Name       = baseMesh.Name,
                                        Draw       = generatedMesh,
                                        NodeIndex  = meshList.Key,
                                        Skinning   = null,
                                    });
                                }
                            }
                        }

                        // delete empty nodes (neither mesh nor bone attached)
                        var keptNodes = new bool[model.Hierarchy.Nodes.Length];
                        for (var i = 0; i < keptNodes.Length; ++i)
                        {
                            keptNodes[i] = false;
                        }
                        foreach (var keepIndex in indicesBlackList)
                        {
                            var nodeIndex = keepIndex;
                            while (nodeIndex != -1 && !keptNodes[nodeIndex])
                            {
                                keptNodes[nodeIndex] = true;
                                nodeIndex            = model.Hierarchy.Nodes[nodeIndex].ParentIndex;
                            }
                        }
                        foreach (var mesh in finalMeshes)
                        {
                            var nodeIndex = mesh.NodeIndex;
                            while (nodeIndex != -1 && !keptNodes[nodeIndex])
                            {
                                keptNodes[nodeIndex] = true;
                                nodeIndex            = model.Hierarchy.Nodes[nodeIndex].ParentIndex;
                            }

                            if (mesh.Skinning != null)
                            {
                                foreach (var bone in mesh.Skinning.Bones)
                                {
                                    nodeIndex = bone.NodeIndex;
                                    while (nodeIndex != -1 && !keptNodes[nodeIndex])
                                    {
                                        keptNodes[nodeIndex] = true;
                                        nodeIndex            = model.Hierarchy.Nodes[nodeIndex].ParentIndex;
                                    }
                                }
                            }
                        }

                        var newNodes   = new List <ModelNodeDefinition>();
                        var newMapping = new int[model.Hierarchy.Nodes.Length];
                        for (var i = 0; i < keptNodes.Length; ++i)
                        {
                            if (keptNodes[i])
                            {
                                var parentIndex = model.Hierarchy.Nodes[i].ParentIndex;
                                if (parentIndex != -1)
                                {
                                    model.Hierarchy.Nodes[i].ParentIndex = newMapping[parentIndex]; // assume that the nodes are well ordered
                                }
                                newMapping[i] = newNodes.Count;
                                newNodes.Add(model.Hierarchy.Nodes[i]);
                            }
                        }

                        foreach (var mesh in finalMeshes)
                        {
                            mesh.NodeIndex = newMapping[mesh.NodeIndex];

                            if (mesh.Skinning != null)
                            {
                                for (var i = 0; i < mesh.Skinning.Bones.Length; ++i)
                                {
                                    mesh.Skinning.Bones[i].NodeIndex = newMapping[mesh.Skinning.Bones[i].NodeIndex];
                                }
                            }
                        }

                        model.Meshes          = finalMeshes;
                        model.Hierarchy.Nodes = newNodes.ToArray();

                        hierarchyUpdater = new ModelViewHierarchyUpdater(model.Hierarchy.Nodes);
                        hierarchyUpdater.UpdateMatrices();
                    }

                    // bounding boxes
                    foreach (var mesh in model.Meshes)
                    {
                        var vertexBuffers = mesh.Draw.VertexBuffers;
                        if (vertexBuffers.Length > 0)
                        {
                            // Compute local mesh bounding box (no node transformation)
                            Matrix matrix = Matrix.Identity;
                            mesh.BoundingBox = vertexBuffers[0].ComputeBoundingBox(ref matrix);

                            // Compute model bounding box (includes node transformation)
                            hierarchyUpdater.GetWorldMatrix(mesh.NodeIndex, out matrix);
                            var meshBoundingBox = vertexBuffers[0].ComputeBoundingBox(ref matrix);
                            BoundingBox.Merge(ref model.BoundingBox, ref meshBoundingBox, out model.BoundingBox);
                        }

                        // TODO: temporary Always try to compact
                        mesh.Draw.CompactIndexBuffer();
                    }

                    // merges all the Draw VB and IB together to produce one final VB and IB by entity.
                    var sizeVertexBuffer      = model.Meshes.SelectMany(x => x.Draw.VertexBuffers).Select(x => x.Buffer.Value.Content.Length).Sum();
                    var sizeIndexBuffer       = model.Meshes.Select(x => x.Draw.IndexBuffer).Select(x => x.Buffer.Value.Content.Length).Sum();
                    var vertexBuffer          = new BufferData(BufferFlags.VertexBuffer, new byte[sizeVertexBuffer]);
                    var indexBuffer           = new BufferData(BufferFlags.IndexBuffer, new byte[sizeIndexBuffer]);
                    var vertexBufferNextIndex = 0;
                    var indexBufferNextIndex  = 0;
                    foreach (var drawMesh in model.Meshes.Select(x => x.Draw))
                    {
                        // the index buffer
                        var oldIndexBuffer = drawMesh.IndexBuffer.Buffer.Value.Content;

                        Array.Copy(oldIndexBuffer, 0, indexBuffer.Content, indexBufferNextIndex, oldIndexBuffer.Length);

                        drawMesh.IndexBuffer.Offset = indexBufferNextIndex;
                        drawMesh.IndexBuffer.Buffer = indexBuffer;

                        indexBufferNextIndex += oldIndexBuffer.Length;

                        // the vertex buffers
                        foreach (var vertexBufferBinding in drawMesh.VertexBuffers)
                        {
                            var oldVertexBuffer = vertexBufferBinding.Buffer.Value.Content;

                            Array.Copy(oldVertexBuffer, 0, vertexBuffer.Content, vertexBufferNextIndex, oldVertexBuffer.Length);

                            vertexBufferBinding.Offset = vertexBufferNextIndex;
                            vertexBufferBinding.Buffer = vertexBuffer;

                            vertexBufferNextIndex += oldVertexBuffer.Length;
                        }
                    }


                    // If there were any errors while importing models
                    if (hasErrors)
                    {
                        return(ResultStatus.Failed);
                    }

                    // Convert to Entity
                    exportedObject = model;
                }
                else
                {
                    commandContext.Logger.Error("Unknown export type [{0}] {1}", ExportType, ContextAsString);
                    return(ResultStatus.Failed);
                }

                if (exportedObject != null)
                {
                    assetManager.Save(Location, exportedObject);
                }

                commandContext.Logger.Info("The {0} has been successfully imported.", ContextAsString);

                return(ResultStatus.Successful);
            }
            catch (Exception ex)
            {
                commandContext.Logger.Error("Unexpected error while importing {0}", ex, ContextAsString);
                return(ResultStatus.Failed);
            }
            finally
            {
                Interlocked.Decrement(ref spawnedFbxCommands);
            }
        }
Exemple #13
0
        /// <summary>
        /// Reads material file</summary>
        /// <param name="filename">Material file pathname</param>
        public void Read(string filename)
        {
            if (string.IsNullOrEmpty(filename))
            {
                throw new ArgumentNullException("filename");
            }

            StreamReader reader = null;

            if (!File.Exists(filename))
            {
                return;
            }

            try
            {
                // Create an instance of StreamReader to read from a file.
                reader = new StreamReader(filename);

                string      buf;
                bool        isValid    = false;
                MaterialDef currentMtl = null;

                while ((buf = reader.ReadLine()) != null)
                {
                    buf = buf.Trim();
                    if (string.IsNullOrEmpty(buf))
                    {
                        continue;
                    }
                    if (buf[0] == '#')
                    {
                        continue;
                    }

                    string[] split = buf.Split(s_stringDelimiters, StringSplitOptions.RemoveEmptyEntries);
                    switch (buf[0])
                    {
                    case 'n':     // newmtl name
                        if (split.Length >= 2)
                        {
                            string newMtl = split[1];

                            // Check for duplicate material
                            if (!Materials.ContainsKey(newMtl))
                            {
                                // Create a new material
                                currentMtl = new MaterialDef(newMtl);
                                Materials.Add(newMtl, currentMtl);
                                isValid = true;
                            }
                            else
                            {
                                isValid = false;
                            }
                        }
                        break;

                    case 'K':     // k* r g b
                        if (isValid && split.Length == 4)
                        {
                            switch (buf[1])
                            {
                            case 'a':         // ambient
                                currentMtl.Ambient = new Vec4F(
                                    float.Parse(split[1]),
                                    float.Parse(split[2]),
                                    float.Parse(split[3]),
                                    1.0f);
                                break;

                            case 'd':         // diffuse
                                currentMtl.Diffuse = new Vec4F(
                                    float.Parse(split[1]),
                                    float.Parse(split[2]),
                                    float.Parse(split[3]),
                                    1.0f);
                                break;

                            case 's':         // specular
                                currentMtl.Specular = new Vec4F(
                                    float.Parse(split[1]),
                                    float.Parse(split[2]),
                                    float.Parse(split[3]),
                                    1.0f);
                                break;
                            }
                        }
                        else
                        {
                            throw new Exception(string.Format("Error parsing k{0} in file: {1}", buf[1], filename));
                        }
                        break;

                    case 'N':     // Ns shininess
                        if (isValid && split.Length == 2 && buf[1] == 's')
                        {
                            currentMtl.Shininess = float.Parse(split[1]);
                        }
                        break;

                    case 'm':     // map_Kd texture
                        if (isValid && split.Length == 2 && split[0].Equals("map_Kd"))
                        {
                            currentMtl.TextureName = split[1];
                        }
                        break;

                    case 'd':     // d alpha
                    case 'T':     // Tf r g b or Tr alpha
                        if (isValid && split.Length <= 4 && (buf[0] == 'd' || buf[1] == 'f' || buf[1] == 'r'))
                        {
                            currentMtl.Alpha = float.Parse(split[1]);
                        }
                        break;

                    default:
                        break;
                    }
                }
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }
            }
        }