Пример #1
0
        /// <summary>
        /// Creates the material
        /// </summary>
        void CreateMaterilas(Model model, Scene scene)
        {
            Debug.Assert(null != scene);
            {
                return;
            }

            int numMaterials = model.MaterialLib.Count;
            scene.Materials.Clear();
            if (model.MaterialLib.Count == 0)
            {
                Debug.WriteLine("OBJ: no materials specified");
                return;
            }

            for (int matIndex = 0; matIndex < numMaterials; matIndex++)
            {
                // Store material name
                // No material found, use the default material
                Material currentMaterial;
                if (!model.MaterialMap.TryGetValue(model.MaterialLib[matIndex], out currentMaterial))
                {
                    continue;
                }

                var mat = new AssimpSharp.Material();
                mat.Name = currentMaterial.MaterialName;

                // convert illumination model
                ShadingMode sm = 0;
                switch (currentMaterial.IlluminationModel)
                {
                    case 0:
                        sm = ShadingMode.NoShading;
                        break;
                    case 1:
                        sm = ShadingMode.Gouraud;
                        break;
                    case 2:
                        sm = ShadingMode.Phong;
                        break;
                    default:
                        sm = ShadingMode.Gouraud;
                        Debug.WriteLine("OBJ: unexpected illumination model (0-2 recognized)");
                        break;
                }
                mat.ShadingMode = sm;

                // multiplying the specular exponent with 2 seems to yield better results
                currentMaterial.Shineness *= 4f;

                // Adding material colors
                mat.ColorAmbient = new Color4(currentMaterial.Ambient);
                mat.ColorDiffuse = new Color4(currentMaterial.Diffuse);
                mat.ColorSpecular = new Color4(currentMaterial.Specular);
                mat.ColorEmissive = new Color4(currentMaterial.Emissive);
                mat.Shininess = currentMaterial.Shineness;
                mat.Opacity = currentMaterial.Alpha;

                // Adding refraction index
                mat.Reflectivity = currentMaterial.IOR;

                // Adding textures
                if (!string.IsNullOrEmpty(currentMaterial.Texture))
                {
                    mat.TextureDiffuse = new TextureSlot()
                    {
                        TextureBase = currentMaterial.Texture
                    };
                    if (currentMaterial.Clamp[(int)Material.TextureType.DiffuseType])
                    {
                        AddTextureMappingModeProperty(mat, TextureType.Diffuse);
                    }
                }

                if (!string.IsNullOrEmpty(currentMaterial.TextureAmbient))
                {
                    mat.TextureAmbient = new TextureSlot()
                    {
                        TextureBase = currentMaterial.TextureAmbient
                    };
                    if (currentMaterial.Clamp[(int)Material.TextureType.AmbientType])
                    {
                        AddTextureMappingModeProperty(mat, TextureType.Ambient);
                    }
                }

                if (!string.IsNullOrEmpty(currentMaterial.TextureEmissive))
                {
                    mat.TextureAmbient = new TextureSlot()
                    {
                        TextureBase = currentMaterial.TextureEmissive
                    };
                }

                if (!string.IsNullOrEmpty(currentMaterial.TextureSpecular))
                {
                    mat.TextureSpecular = new TextureSlot()
                    {
                        TextureBase = currentMaterial.TextureSpecular
                    };
                    if (currentMaterial.Clamp[(int)Material.TextureType.SpecularType])
                    {
                        AddTextureMappingModeProperty(mat, TextureType.Specular);
                    }
                }

                if (!string.IsNullOrEmpty(currentMaterial.TextureBump))
                {
                    mat.TextureHeight = new TextureSlot()
                    {
                        TextureBase = currentMaterial.TextureBump
                    };
                    if (currentMaterial.Clamp[(int)Material.TextureType.BumpType])
                    {
                        AddTextureMappingModeProperty(mat, TextureType.Height);
                    }
                }

                if (!string.IsNullOrEmpty(currentMaterial.TextureNormal))
                {
                    mat.TextureNormals = new TextureSlot()
                    {
                        TextureBase = currentMaterial.TextureNormal
                    };
                    if (currentMaterial.Clamp[(int)Material.TextureType.NormalType])
                    {
                        AddTextureMappingModeProperty(mat, TextureType.Normals);
                    }
                }

                if (!string.IsNullOrEmpty(currentMaterial.TextureDisp))
                {
                    mat.TextureDisplacement = new TextureSlot()
                    {
                        TextureBase = currentMaterial.TextureDisp
                    };
                    if (currentMaterial.Clamp[(int)Material.TextureType.DispType])
                    {
                        AddTextureMappingModeProperty(mat, TextureType.Displacement);
                    }
                }

                if (!string.IsNullOrEmpty(currentMaterial.TextureOpacity))
                {
                    mat.TextureOpacity = new TextureSlot()
                    {
                        TextureBase = currentMaterial.TextureOpacity
                    };
                    if (currentMaterial.Clamp[(int)Material.TextureType.OpacityType])
                    {
                        AddTextureMappingModeProperty(mat, TextureType.Opacity);
                    }
                }

                if (!string.IsNullOrEmpty(currentMaterial.TextureSpecularity))
                {
                    mat.TextureShininess = new TextureSlot()
                    {
                        TextureBase = currentMaterial.TextureSpecularity
                    };
                    if (currentMaterial.Clamp[(int)Material.TextureType.SpecularityType])
                    {
                        AddTextureMappingModeProperty(mat, TextureType.Shininess);
                    }
                }

                // Store material property info in material array in scene
                scene.Materials.Add(mat);
            }

            // Test number of created materials.
            Debug.Assert(scene.Materials.Count == numMaterials);
        }
Пример #2
0
        /// <summary>
        /// Converts all materials in the given array and stores them in the
        ///  scene's material list.
        /// </summary>
        /// <param name="scene">The scene to hold the converted materials.</param>
        /// <param name="materials">The material array to convert.</param>
        protected void ConvertMaterials(AssimpSharp.Scene scene, List<AssimpSharp.XFile.Material> materials)
        {
            // count the non-referrer materials in the array
            var numNewMaterials = materials.Count(e => { return !e.IsReference; });

            // resize the scene's material list to offer enough space for the new materials
            if (numNewMaterials > 0)
            {
                scene.Materials.Capacity = scene.Materials.Count + numNewMaterials;

            }

            // convert all the materials given in the array
            for (int a = 0; a < materials.Count; a++)
            {
                XFile.Material oldMat = materials[a];
                if (oldMat.IsReference)
                {
                    // find the material it refers to by name, and store its index
                    for (int b = 0; b < scene.Materials.Count; b++)
                    {
                        var name = scene.Materials[b].Name;
                        if (name == oldMat.Name)
                        {
                            oldMat.SceneIndex = a;
                            break;
                        }
                    }

                    if (oldMat.SceneIndex == int.MaxValue)
                    {
                        throw (new Exception());
                        oldMat.SceneIndex = 0;
                    }
                    continue;
                }

                var mat = new aiMaterial();
                mat.Name = oldMat.Name;

                var shadeMode = (oldMat.SpecularExponent == 0.0f)
                    ? AssimpSharp.ShadingMode.Gouraud : ShadingMode.Phong;
                mat.ShadingMode = shadeMode;

                mat.ColorEmissive = new Color4(oldMat.Emissive, 1);
                mat.ColorDiffuse = oldMat.Diffuse;
                mat.ColorSpecular = new Color4(oldMat.Specular, 1);
                mat.Shininess = oldMat.SpecularExponent;

                if (1 == oldMat.Textures.Count)
                {
                    var otex = oldMat.Textures[0];
                    if (!string.IsNullOrEmpty(otex.Name))
                    {
                        string tex = otex.Name;
                        if (otex.IsNormalMap)
                        {
                            mat.TextureNormals = new TextureSlot() { TextureBase = tex };
                        }
                        else
                        {
                            mat.TextureDiffuse = new TextureSlot() { TextureBase = tex };
                        }
                    }
                }
                else
                {
                    int iHM = 0, iNM = 0, iDM = 0, iSM = 0, iAM = 0, iEM = 0;
                    for (int b = 0; b < oldMat.Textures.Count; b++)
                    {
                        var otex = oldMat.Textures[b];
                        var sz = otex.Name;
                        if (string.IsNullOrEmpty(sz))
                        {
                            continue;
                        }

                        int s = sz.LastIndexOf("\\/");
                        if (s == -1)
                        {
                            s = 0;
                        }

                        int sExt = sz.LastIndexOf('.');
                        if (sExt > 0)
                        {
                            sz = sz.Substring(0, sExt - 1) + '\0' + sz.Substring(sExt);
                        }

                        sz = sz.ToLower();

                        var tex = new TextureSlot() { TextureBase = oldMat.Textures[b].Name };

                        if (sz.Substring(s).Contains("bump") || sz.Substring(s).Contains("height"))
                        {
                            mat.TextureHeight = tex;
                        }
                        else if (otex.IsNormalMap || sz.Substring(s).Contains("normal") || sz.Substring(s).Contains("nm"))
                        {
                            mat.TextureNormals = tex;
                        }
                        else if (sz.Substring(s).Contains("spec") || sz.Substring(s).Contains("glanz"))
                        {
                            mat.TextureSpecular = tex;
                        }
                        else if (sz.Substring(s).Contains("ambi") || sz.Substring(s).Contains("env"))
                        {
                            mat.TextureAmbient = tex;
                        }
                        else if (sz.Substring(s).Contains("emissive") || sz.Substring(s).Contains("self"))
                        {
                            mat.TextureEmmisive = tex;
                        }
                        else
                        {
                            mat.TextureDiffuse = tex;
                        }
                    }
                }
                scene.Materials.Add(mat);
                //scene.Materials[scene.Materials.Count] = mat;
                oldMat.SceneIndex = scene.Materials.Count - 1;
            }
        }
Пример #3
0
        /// <summary>
        /// Constructs the return data structure out of the imported data.
        /// </summary>
        /// <param name="scene">The scene to construct the return data in.</param>
        /// <param name="sdata">The imported data in the internal temporary representation.</param>
        protected void CreateDataRepresentationFromImport(AssimpSharp.Scene scene, Scene data)
        {
            // Read the global materials first so that meshes referring to them can find them later
            ConvertMaterials(scene, data.GlobalMaterial);

            // copy nodes, extracting meshes and materials on the way
            scene.RootNode = CreateNodes(scene, null, data.RootNode);

            // extract animations
            CreateAnimations(scene, data);

            // read the global meshes that were stored outside of any node
            if (data.GlobalMeshes.Count > 0)
            {
                // create a root node to hold them if there isn't any, yet
                if (scene.RootNode == null)
                {
                    scene.RootNode = new AssimpSharp.Node();
                    scene.RootNode.Name = "$dummy_node";
                }

                // convert all global meshes and store them in the root node.
                // If there was one before, the global meshes now suddenly have its transformation matrix...
                // Don't know what to do there, I don't want to insert another node under the present root node
                // just to avoid this.
                CreateMeshes(scene, scene.RootNode, data.GlobalMeshes);
            }

            if (scene.RootNode == null)
            {
                throw (new DeadlyImportError("No root node"));
            }

            // Convert everything to OpenGL space... it's the same operation as the conversion back, so we can reuse the step directly
            var convertProcess = new MakeLeftHandedProcess();
            convertProcess.Execute(scene);

            var flipper = new FlipWindingOrderProcess();
            flipper.Execute(scene);

            // finally: create a dummy material if not material was imported
            if (scene.Materials.Count == 0)
            {
                var mat = new aiMaterial();
                mat.ShadingMode = ShadingMode.Gouraud;
                mat.ColorEmissive = new Color4(0, 0, 0, 1);
                mat.ColorSpecular = new Color4(0, 0, 0, 1);
                mat.ColorDiffuse = new Color4(0.5f, 0.5f, 0.5f, 1);
                mat.Shininess = 1.401298e-45f;
                scene.Materials.Add(mat);
            }
        }
Пример #4
0
        private int ConvertMaterial(Material material, MeshGeometry mesh)
        {
            var props = material.Props;

            // generate empty output material
            var outMat = new aiMaterial();
            this.MaterialsConverted[material] = this.Materials.Count;

            this.Materials.Add(outMat);

            // stip Material:: prefix
            string name = material.Name;
            if (name.Substring(0, 10) == "Material::")
            {
                name = name.Substring(10);
            }

            // set material name if not empty - this could happen
            // and there should be no key for it in this case.
            if (name.Length > 0)
            {
                outMat.Name = name;
            }

            // shading stuff and colors
            SetShadingPropertiesCommon(outMat, props);

            // texture assignments
            SetTextureProperties(outMat, material.Textures, mesh);
            SetTextureProperties(outMat, material.LayeredTextures, mesh);

            return this.Materials.Count - 1;
        }
Пример #5
0
        private void TrySetTextureProperties(aiMaterial outMat, Dictionary<string, LayeredTexture> layeredTextures,
            string propName,
            aiTextureType target, MeshGeometry mesh)
        {
            LayeredTexture it;
            if (!layeredTextures.TryGetValue(propName, out it))
            {
                return;
            }
            var tex = it.Texture;

            var path = tex.RelativeFilename;
            outMat.TextureSlotCollection[target].TextureBase = path;

            var uvTrafo = new AssimpSharp.UVTransform();
            uvTrafo.Scaling = tex.UVScaling;
            uvTrafo.Translation = tex.UVTranslation;
            outMat.TextureSlotCollection[target].UVTransformBase = uvTrafo;

            var props = tex.Props;
            var uvIndex = 0;
            bool ok;
            var uvSet = PropertyHelper.PropertyGet<string>(props, "UVSet", out ok);
            if (ok)
            {
                if (uvSet != "default" && !string.IsNullOrEmpty(uvSet))
                {
                    var matIndex = Materials.IndexOf(outMat);
                    uvIndex = -1;
                    if (mesh == null)
                    {
                        foreach (var v in MeshesConverted)
                        {
                            var mesh_ = v.Key as MeshGeometry;
                            if (mesh_ == null)
                            {
                                continue;
                            }
                            var mats = mesh_.MaterialIndices;
                            if (!mats.Contains(matIndex))
                            {
                                continue;
                            }
                            int index = -1;
                            for (int i = 0; i < aiMesh.AI_MAX_NUMBER_OF_TEXTURECOORDS; i++)
                            {
                                if (mesh.GetTextureCoords(i).Count == 0)
                                {
                                    break;
                                }
                                var name = mesh.GetTextureCoordChannelName(i);
                                if (name == uvSet)
                                {
                                    index = i;
                                    break;
                                }
                            }
                            if (index == -1)
                            {
                                FBXImporter.LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material");
                                continue;
                            }
                            if (uvIndex == -1)
                            {
                                uvIndex = index;
                            }
                            else
                            {
                                FBXImporter.LogWarn("the UV channel named " + uvSet +
                                " appears at different positions in meshes, results will be wrong");
                            }
                        }
                    }
                    else
                    {
                        int index = -1;
                        for (int i = 0; i < aiMesh.AI_MAX_NUMBER_OF_TEXTURECOORDS; i++)
                        {
                            if (mesh.GetTextureCoords(i).Count == 0)
                            {
                                break;
                            }
                            var name = mesh.GetTextureCoordChannelName(i);
                            if (name == uvSet)
                            {
                                index = i;
                                break;
                            }
                        }
                        if (index == -1)
                        {
                            FBXImporter.LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material");
                        }
                        if (uvIndex == -1)
                        {
                            uvIndex = index;
                        }
                    }
                    if (uvIndex == -1)
                    {
                        FBXImporter.LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel");
                        uvIndex = 0;
                    }
                }
            }
            outMat.TextureSlotCollection[target].UVWSrcBase = uvIndex;
        }
Пример #6
0
 private void SetTextureProperties(aiMaterial outMat, Dictionary<string, LayeredTexture> layeredTextures, MeshGeometry mesh)
 {
     TrySetTextureProperties(outMat, layeredTextures, "DiffuseColor", aiTextureType.Diffuse, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "AmbientColor", aiTextureType.Ambient, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "EmissiveColor", aiTextureType.Emissive, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "SpecularColor", aiTextureType.Specular, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "TransparentColor", aiTextureType.Opacity, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "ReflectionColor", aiTextureType.Reflection, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "DisplacementColor", aiTextureType.Displacement, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "NormalMap", aiTextureType.Normals, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "Bump", aiTextureType.Height, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "ShininessExponent", aiTextureType.Shininess, mesh);
 }
Пример #7
0
 private void SetShadingPropertiesCommon(aiMaterial outMat, PropertyTable props)
 {
     bool ok;
     var diffuse = GetColorPropertyFromMaterial(props, "Diffuse", out ok);
     if (ok)
     {
         outMat.ColorDiffuse = new Color4(diffuse, 1.0f);
     }
     var emissive = GetColorPropertyFromMaterial(props, "Emissive", out ok);
     if (ok)
     {
         outMat.ColorEmissive = new Color4(emissive, 1.0f);
     }
     var ambient = GetColorPropertyFromMaterial(props, "Ambient", out ok);
     if (ok)
     {
         outMat.ColorAmbient = new Color4(ambient, 1.0f);
     }
     var specular = GetColorPropertyFromMaterial(props, "Specular", out ok);
     if (ok)
     {
         outMat.ColorSpecular = new Color4(specular, 1.0f);
     }
     float opacity = PropertyHelper.PropertyGet<float>(props, "Opacity", out ok);
     if (ok)
     {
         outMat.Opacity = opacity;
     }
     float reflectivity = PropertyHelper.PropertyGet<float>(props, "Reflectivity", out ok);
     if (ok)
     {
         outMat.Reflectivity = reflectivity;
     }
     float shininess = PropertyHelper.PropertyGet<float>(props, "Shininess", out ok);
     if (ok)
     {
         outMat.Shininess = shininess;
     }
     float shininessExponent = PropertyHelper.PropertyGet<float>(props, "ShininessExponent", out ok);
     if (ok)
     {
         outMat.ShininessStrength = shininessExponent;
     }
 }
Пример #8
0
        private int GetDefaultMaterial()
        {
            if (DefaultMaterialIndex != 0)
            {
                return DefaultMaterialIndex - 1;
            }

            var outMat = new aiMaterial();
            Materials.Add(outMat);

            var diffuse = new Color(0.8f, 0.8f, 0.8f, 0f);
            outMat.ColorDiffuse = diffuse;
            outMat.Name = aiMaterial.AI_DEFAULT_MATERIAL_NAME;

            this.DefaultMaterialIndex = Materials.Count;
            return DefaultMaterialIndex - 1;
        }