示例#1
0
        public static COLLADA Load(string fileName)
        {
            FileStream fileStream = new FileStream(fileName, FileMode.Open);

            try
            {
                return(COLLADA.Load((Stream)fileStream));
            }
            finally
            {
                fileStream.Close();
            }
        }
示例#2
0
        public GameObject Load(string inputFile)
        {
            COLLADA model = COLLADA.Load(inputFile);

            // parent directory
            string parentDir = Directory.GetParent(inputFile).FullName;

            // (image id, texture)
            Dictionary <string, Texture2D> textureDict = new Dictionary <string, Texture2D>();
            // (effect id, material)
            Dictionary <string, Material> effectDict = new Dictionary <string, Material>();
            // (material id, effect id)
            Dictionary <string, string> materialDict = new Dictionary <string, string>();

            // (geom id, mesh)
            Dictionary <string, Mesh> geomDict = new Dictionary <string, Mesh>();
            // (geom id, materilas)
            Dictionary <string, List <string> > geomMatDict = new Dictionary <string, List <string> >();

            // root game object for mesh file
            GameObject unityObj = new GameObject("mesh");

            // Iterate on libraries
            foreach (var item in model.Items)
            {
                if (item is library_images)
                {
                    // image libraries -> effectDict
                    var lib_image = item as library_images;
                    if (lib_image == null || lib_image.image == null)
                    {
                        continue;
                    }

                    foreach (var image in lib_image.image)
                    {
                        var imagePath = Path.Combine(parentDir, image.Item as string);

                        // load image
                        byte[]    byteArray = File.ReadAllBytes(imagePath);
                        Texture2D texture   = new Texture2D(2, 2);
                        bool      isLoaded  = texture.LoadImage(byteArray);
                        if (!isLoaded)
                        {
                            // TODO error
                        }
                        textureDict.Add(image.id, texture);
                    }
                }
                else if (item is library_effects)
                {
                    // effect libraries -> effectDict
                    var lib_effect = item as library_effects;
                    if (lib_effect == null || lib_effect.effect == null)
                    {
                        continue;
                    }

                    foreach (var eff in lib_effect.effect)
                    {
                        var name = eff.id;
                        if (eff.Items == null)
                        {
                            continue;
                        }

                        foreach (var it in eff.Items)
                        {
                            var profile = it as effectFx_profile_abstractProfile_COMMON;

                            Dictionary <string, string> surfaceDict = new Dictionary <string, string>();
                            Dictionary <string, string> samplerDict = new Dictionary <string, string>();

                            if (it.Items != null)
                            {
                                foreach (var it2 in it.Items)
                                {
                                    var newparam = it2 as common_newparam_type;
                                    if (newparam.Item is fx_surface_common)
                                    {
                                        var surface = newparam.Item as fx_surface_common;
                                        surfaceDict.Add(newparam.sid, surface.init_from[0].Value);
                                    }
                                    else if (newparam.Item is fx_sampler2D_common)
                                    {
                                        var sampler = newparam.Item as fx_sampler2D_common;
                                        samplerDict.Add(newparam.sid, sampler.source);
                                    }
                                }
                            }

                            var phong = profile.technique.Item as effectFx_profile_abstractProfile_COMMONTechniquePhong;
                            if (phong.diffuse.Item is common_color_or_texture_typeColor)
                            {
                                // color
                                var diffuse = phong.diffuse.Item as common_color_or_texture_typeColor;

                                if (diffuse != null)
                                {
                                    Material material = new Material(Shader.Find("Standard"));
                                    Color    color    = new Color(
                                        (float)diffuse.Values[0],
                                        (float)diffuse.Values[1],
                                        (float)diffuse.Values[2],
                                        (float)diffuse.Values[3]
                                        );
                                    material.color = color;

                                    effectDict.Add(name, material);
                                }
                            }
                            else if (phong.diffuse.Item is common_color_or_texture_typeTexture)
                            {
                                // texture
                                var diffuse = phong.diffuse.Item as common_color_or_texture_typeTexture;

                                if (diffuse != null)
                                {
                                    var texture = diffuse.texture;

                                    if (samplerDict.ContainsKey(texture))
                                    {
                                        var surface = samplerDict[texture];
                                        if (surfaceDict.ContainsKey(surface))
                                        {
                                            var textureName = surfaceDict[surface];
                                            if (textureDict.ContainsKey(textureName))
                                            {
                                                Material material = new Material(Shader.Find("Standard"));
                                                material.SetTexture("_MainTex", textureDict[textureName]);
                                                effectDict.Add(name, material);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else if (item is library_materials)
                {
                    // material libraries -> materialDict
                    var material = item as library_materials;
                    if (material == null || material.material == null)
                    {
                        continue;
                    }

                    foreach (var mat in material.material)
                    {
                        materialDict.Add(mat.id, mat.instance_effect.url.Substring(1));
                    }
                }
                else if (item is library_geometries)
                {
                    // geometry libraries -> geomDict
                    var geometries = item as library_geometries;
                    if (geometries == null || geometries.geometry == null)
                    {
                        continue;
                    }

                    // Dictionary stores source arrays
                    Dictionary <string, double[]>      sourceDict       = new Dictionary <string, double[]>();
                    Dictionary <string, VertexSources> vertexSourceDict = new Dictionary <string, VertexSources>();

                    // Iterate on geomerty in library_geometries
                    foreach (var geom in geometries.geometry)
                    {
                        // converted as vector3
                        List <Vector3> vertexList = new List <Vector3>();
                        List <Vector3> normalList = new List <Vector3>();
                        List <Vector2> uvList     = new List <Vector2>();
                        List <int[]>   idxList    = new List <int[]>();

                        // submesh
                        int           numSubmesh   = 0;
                        List <string> subMaterials = new List <string>();

                        var mesh = geom.Item as mesh;
                        if (mesh == null)
                        {
                            continue;
                        }

                        foreach (var source in mesh.source)
                        {
                            var float_array = source.Item as float_array;
                            if (float_array == null)
                            {
                                continue;
                            }

                            sourceDict.Add(source.id, float_array.Values);
                        }

                        // Add vertex of mesh to list
                        foreach (var input in mesh.vertices.input)
                        {
                            if (input.semantic == "POSITION")
                            {
                                VertexSources vs = new VertexSources();
                                vs.positionId = input.source.Substring(1);
                                vertexSourceDict.Add(mesh.vertices.id, vs);
                            }
                            else if (input.semantic == "NORMAL")
                            {
                                VertexSources vs = new VertexSources();
                                vs.normalId = input.source.Substring(1);
                                vertexSourceDict.Add(mesh.vertices.id, vs);
                            }
                        }

                        if (mesh.Items == null)
                        {
                            continue;
                        }

                        // triangle or polylist
                        foreach (var meshItem in mesh.Items)
                        {
                            int indexStride   = 1;
                            int posOffset     = 0;
                            int normalOffset  = 0;
                            int uvOffset      = 0;
                            int numIndices    = 0;
                            int curNumIndices = 0;

                            // source name
                            string positionSourceName = "";
                            string normalSourceName   = "";
                            string uvSourceName       = "";

                            // current indices
                            List <int> currIdxList = new List <int>();

                            // triangles
                            if (meshItem is triangles)
                            {
                                var triangles = meshItem as triangles;
                                var inputs    = triangles.input;

                                int count = (int)triangles.count;

                                foreach (var input in inputs)
                                {
                                    // offset
                                    int offset = (int)input.offset;
                                    if (offset + 1 > indexStride)
                                    {
                                        indexStride = offset + 1;
                                    }

                                    // source
                                    string sourceName = input.source.Substring(1);

                                    if (input.semantic == "VERTEX")
                                    {
                                        VertexSources vs = vertexSourceDict[sourceName];
                                        if (!string.IsNullOrEmpty(vs.positionId))
                                        {
                                            positionSourceName = vs.positionId;
                                            posOffset          = offset;
                                        }
                                        else if (string.IsNullOrEmpty(vs.normalId))
                                        {
                                            normalSourceName = vs.normalId;
                                            normalOffset     = offset;
                                        }
                                    }
                                    else if (input.semantic == "NORMAL")
                                    {
                                        normalSourceName = sourceName;
                                        normalOffset     = offset;
                                    }
                                    else if (input.semantic == "TEXCOORD")
                                    {
                                        uvSourceName = sourceName;
                                        uvOffset     = offset;
                                    }
                                }

                                numIndices = count * 3;

                                // parse index from p
                                currIdxList = triangles.p.Split(' ').Select(Int32.Parse).ToList();

                                // material
                                string materialName = triangles.material;
                                if (!string.IsNullOrEmpty(materialName) && materialDict.ContainsKey(materialName))
                                {
                                    subMaterials.Add(materialName);
                                }

                                // Increment submesh count
                                numSubmesh += 1;
                            }

                            // vertex
                            List <double> positionFloatArray = new List <double>();
                            if (sourceDict.ContainsKey(positionSourceName))
                            {
                                positionFloatArray = sourceDict[positionSourceName].ToList();
                            }

                            // normal
                            List <double> normalFloatArray = new List <double>();
                            if (sourceDict.ContainsKey(normalSourceName))
                            {
                                normalFloatArray = sourceDict[normalSourceName].ToList();
                            }

                            // uv
                            List <double> uvFloatArray = new List <double>();
                            if (sourceDict.ContainsKey(uvSourceName))
                            {
                                uvFloatArray = sourceDict[uvSourceName].ToList();
                            }

                            // add to list
                            int indexOffset = vertexList.Count;

                            for (int i = 0; i < (int)numIndices; i++)
                            {
                                int posIndex    = currIdxList[i * indexStride + posOffset];
                                int normalIndex = currIdxList[i * indexStride + normalOffset];
                                int uvIndex     = currIdxList[i * indexStride + uvOffset];

                                if (model.asset.up_axis == UpAxisType.Y_UP)
                                {
                                    vertexList.Add(new Vector3(
                                                       -(float)positionFloatArray[posIndex * 3],
                                                       (float)positionFloatArray[posIndex * 3 + 1],
                                                       (float)positionFloatArray[posIndex * 3 + 2]
                                                       ));

                                    if (normalFloatArray.Count > 0 && (normalFloatArray.Count > normalIndex))
                                    {
                                        normalList.Add(new Vector3(
                                                           -(float)normalFloatArray[normalIndex * 3],
                                                           (float)normalFloatArray[normalIndex * 3 + 1],
                                                           (float)normalFloatArray[normalIndex * 3 + 2]
                                                           ));
                                    }
                                    else
                                    {
                                        // Add dummy normal for debugging
                                        normalList.Add(new Vector3(
                                                           0,
                                                           0,
                                                           0
                                                           ));
                                    }
                                }
                                else if (model.asset.up_axis == UpAxisType.Z_UP)
                                {
                                    vertexList.Add(new Vector3(
                                                       -(float)positionFloatArray[posIndex * 3],
                                                       (float)positionFloatArray[posIndex * 3 + 2],
                                                       -(float)positionFloatArray[posIndex * 3 + 1]
                                                       ));

                                    if (normalFloatArray.Count > 0 && (normalFloatArray.Count > normalIndex))
                                    {
                                        normalList.Add(new Vector3(
                                                           -(float)normalFloatArray[normalIndex * 3],
                                                           (float)normalFloatArray[normalIndex * 3 + 2],
                                                           -(float)normalFloatArray[normalIndex * 3 + 1]
                                                           ));
                                    }
                                    else
                                    {
                                        // Add dummy normal for debugging
                                        normalList.Add(new Vector3(
                                                           0,
                                                           0,
                                                           0
                                                           ));
                                    }
                                }

                                if (uvFloatArray.Count > 0)
                                {
                                    uvList.Add(new Vector2(
                                                   (float)uvFloatArray[uvIndex * 2],
                                                   (float)uvFloatArray[uvIndex * 2 + 1]
                                                   ));
                                }
                            }

                            // indices
                            int[] currIndices = new int[numIndices];
                            for (int i = 0; i < numIndices; i += 3)
                            {
                                currIndices[i + 0] = i + 2 + indexOffset;
                                currIndices[i + 1] = i + 1 + indexOffset;
                                currIndices[i + 2] = i + 0 + indexOffset;
                            }

                            if (numIndices != 0)
                            {
                                idxList.Add(currIndices);
                            }
                            curNumIndices += numIndices;
                        }

                        // Add mesh to sub-gameobject
                        Mesh unityMesh = new Mesh();
                        unityMesh.vertices     = vertexList.ToArray();
                        unityMesh.normals      = normalList.ToArray();
                        unityMesh.subMeshCount = numSubmesh;
                        for (int i = 0; i < idxList.Count; i++)
                        {
                            unityMesh.SetTriangles(idxList[i], i);
                        }

                        if (uvList.Count > 0)
                        {
                            unityMesh.uv = uvList.ToArray();
                        }

                        geomDict.Add(geom.id, unityMesh);
                        geomMatDict.Add(geom.id, subMaterials);
                    }
                }
                else if (item is library_visual_scenes)
                {
                    var visual_scenes = item as library_visual_scenes;
                    if (visual_scenes == null)
                    {
                        continue;
                    }

                    foreach (var vis in visual_scenes.visual_scene)
                    {
                        foreach (var node in vis.node)
                        {
                            if (node.instance_geometry == null)
                            {
                                continue;
                            }

                            Quaternion quat = Quaternion.identity;
                            Vector3    pos  = Vector3.zero;

                            if (node.Items != null)
                            {
                                foreach (var item2 in node.Items)
                                {
                                    var matrix = item2 as matrix;
                                    if (matrix == null)
                                    {
                                        continue;
                                    }

                                    Matrix4x4 unityMatrix = new Matrix4x4();
                                    unityMatrix.SetColumn(0, new Vector4(
                                                              (float)matrix.Values[0],
                                                              (float)matrix.Values[4],
                                                              (float)matrix.Values[8],
                                                              (float)matrix.Values[12]
                                                              ));
                                    unityMatrix.SetColumn(1, new Vector4(
                                                              (float)matrix.Values[1],
                                                              (float)matrix.Values[5],
                                                              (float)matrix.Values[9],
                                                              (float)matrix.Values[13]
                                                              ));
                                    unityMatrix.SetColumn(2, new Vector4(
                                                              (float)matrix.Values[2],
                                                              (float)matrix.Values[6],
                                                              (float)matrix.Values[10],
                                                              (float)matrix.Values[14]
                                                              ));
                                    unityMatrix.SetColumn(3, new Vector4(
                                                              (float)matrix.Values[3],
                                                              (float)matrix.Values[7],
                                                              (float)matrix.Values[11],
                                                              (float)matrix.Values[15]
                                                              ));

                                    quat = Quaternion.LookRotation(unityMatrix.GetColumn(2), unityMatrix.GetColumn(1));
                                    pos  = unityMatrix.GetColumn(3);
                                }
                            }

                            foreach (var geom in node.instance_geometry)
                            {
                                var url = geom.url.Substring(1);

                                if (geomDict.ContainsKey(url))
                                {
                                    var unityMesh = geomDict[url];

                                    // Create sub-gameobject
                                    var unitySubObj = new GameObject(geom.name);
                                    unitySubObj.AddComponent <MeshFilter>();
                                    unitySubObj.AddComponent <MeshRenderer>();
                                    unitySubObj.AddComponent <MeshCollider>();
                                    unitySubObj.GetComponent <MeshFilter>().mesh = unityMesh;

                                    // local transform
                                    unitySubObj.transform.SetParent(unityObj.transform, true);
                                    if (model.asset.up_axis == UpAxisType.Z_UP)
                                    {
                                        unitySubObj.transform.localRotation = new Quaternion(0.7071f, 0, 0, 0.7071f);
                                    }
                                    ObjectController.SetTransform(unitySubObj, pos, quat);

                                    // material
                                    var materials = geomMatDict[url];
                                    if (materials.Count > 0)
                                    {
                                        List <Material> unityMaterials = new List <Material>();
                                        foreach (var mat in materials)
                                        {
                                            if (!materialDict.ContainsKey(mat))
                                            {
                                                continue;
                                            }

                                            var eff = materialDict[mat];
                                            if (effectDict.ContainsKey(eff))
                                            {
                                                unityMaterials.Add(effectDict[eff]);
                                            }
                                        }
                                        unitySubObj.GetComponent <Renderer>().materials = unityMaterials.ToArray();
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(unityObj);
        }