Example #1
0
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value.GetType() == typeof(string))
            {
                string val = (string)value;

                SEGM segment = (SEGM)context.Instance;

                if (segment.Owner != null)
                {
                    return(segment.Owner.Materials.Find(mat => mat.Name.Equals(val)));
                }
                else
                {
                    return(base.ConvertFrom(context, culture, value));
                }
            }
            else
            {
                return(base.ConvertFrom(context, culture, value));
            }
        }
    public static GameObject ImportMSH(string path)
    {
        FileInfo mshFile = new FileInfo(path);

        if (mshFile.Exists)
        {
            MSH msh;

            try {
                msh = MSH.LoadFromFile(mshFile.FullName);
            } catch {
                return(null);
            }

            string fileName = mshFile.Name.Replace(".msh", "");

            if (CREATE_ASSETS && File.Exists("Assets/Resources/Prefabs/" + WORLD + fileName + ".prefab"))
            {
                return(UnityEngine.Object.Instantiate(Resources.Load("Prefabs/" + WORLD + fileName)) as GameObject);
            }

            if (!Directory.Exists(ASSET_PATH + "/Resources/Prefabs") && CREATE_ASSETS)
            {
                AssetDatabase.CreateFolder(@"Assets\Resources", "Prefabs");
            }

            GameObject rootObj = new GameObject(fileName);

            foreach (MODL mdl in msh.Models)
            {
                if (CREATE_ASSETS && !Directory.Exists(@"Assets\Resources\Meshes\" + fileName))
                {
                    AssetDatabase.CreateFolder(@"Assets\Resources\Meshes", fileName);
                }

                if (!Array.Exists(LEGAL_TYPES, t => t == mdl.Type))
                {
                    continue;
                }

                if (!Array.Exists(LEGAL_MODELS, t => t == mdl.Tag))
                {
                    continue;
                }

                if (mdl.Geometry == null || mdl.Geometry.Segments.Count == 0)
                {
                    continue;
                }

                GameObject modelObj = new GameObject(mdl.Name);
                modelObj.transform.SetParent(rootObj.transform);
                modelObj.transform.position   = Vector2Unity(mdl.Translation);
                modelObj.transform.rotation   = Quaternion.Euler(Vector2Unity(mdl.Rotation));
                modelObj.transform.localScale = Vector2Unity(mdl.Scale);

                List <Vector3>  vertices  = new List <Vector3>();
                List <Vector3>  normals   = new List <Vector3>();
                List <Vector2>  uvs       = new List <Vector2>();
                List <Material> materials = new List <Material>();

                //each segment contains its own list of triangles
                List <int>[] triangles = new List <int> [mdl.Geometry.Segments.Count];

                //since each Segment acts as its own object (vertices, normals, triangles...) and we want to
                //merge all vertices into one array (as Unity expects it) but preserve our Segment Materials,
                //we have to set a sub mesh for each Segment, containing a list of vertex indices (of the now global vertex list).
                //so we have to store a offset
                int vertexOffset = 0;

                Mesh mesh = new Mesh();
                mesh.name         = mdl.Name;
                mesh.subMeshCount = mdl.Geometry.Segments.Count;

                Debug.Log("Sub Mesh Count set to: " + mesh.subMeshCount);

                for (int si = 0; si < mdl.Geometry.Segments.Count; si++)
                {
                    Debug.Log("Segment No: " + si);
                    SEGM segm = mdl.Geometry.Segments[si];

                    triangles[si] = new List <int>();

                    foreach (Vertex vert in segm.Vertices)
                    {
                        vertices.Add(new Vector3(-vert.position.X, vert.position.Y, vert.position.Z));
                        normals.Add(new Vector3(vert.normal.X, vert.normal.Y, vert.normal.Z));
                        uvs.Add(new Vector2(vert.uvCoordinate.X, vert.uvCoordinate.Y));
                    }

                    for (int pi = 0; pi < segm.Polygons.Length; pi++)
                    {
                        Polygon poly = segm.Polygons[pi];

                        int        triCount = 0;
                        List <int> tris     = new List <int>();

                        //in MSH, polygons are defined as triangle strips.
                        //since unity expects just triangles, we have to strip them ourselfs
                        for (int vi = 0; vi < poly.VertexIndices.Count; vi++)
                        {
                            if (triCount == 3)
                            {
                                vi      -= 2;
                                triCount = 0;
                            }

                            tris.Add(poly.VertexIndices[vi] + vertexOffset);
                            triCount++;
                        }

                        //triangles are listed CW CCW CW CCW...
                        bool flip = true;
                        for (int j = 0; j < tris.Count; j += 3)
                        {
                            if (flip)
                            {
                                int tmp = tris[j];
                                tris[j]     = tris[j + 2];
                                tris[j + 2] = tmp;
                            }

                            flip = !flip;
                        }

                        triangles[si].AddRange(tris);
                    }

                    //Add Segment Material to overall Material List
                    if (DEFAULT_MATERIAL != null)
                    {
                        materials.Add(ChangeMaterial(segm.Material, new Material(DEFAULT_MATERIAL)));
                    }
                    else
                    {
                        materials.Add(Material2Unity(segm.Material));
                    }

                    //don't forget to increase our vertex offset
                    vertexOffset += segm.Vertices.Length;
                }

                mesh.vertices = vertices.ToArray();
                mesh.normals  = normals.ToArray();
                mesh.uv       = uvs.ToArray();

                //set triangles AFTER vertices to avoid out of bounds errors
                for (int si = 0; si < triangles.Length; si++)
                {
                    mesh.SetTriangles(triangles[si], si);
                }

                //Interpret Common and Lowrez as Geometry
                if (mdl.Tag == ModelTag.Common || mdl.Tag == ModelTag.Lowrez)
                {
                    MeshFilter filter = modelObj.AddComponent <MeshFilter>();
                    filter.mesh = mesh;

                    MeshRenderer renderer = modelObj.AddComponent <MeshRenderer>();
                    renderer.materials = materials.ToArray();
                }

                //and everything else as collision / trigger
                else
                {
                    MeshCollider collider = modelObj.AddComponent <MeshCollider>();
                    collider.sharedMesh = mesh;

                    if (mdl.Tag != ModelTag.Collision && mdl.Tag != ModelTag.VehicleCollision)
                    {
                        collider.convex    = true;
                        collider.isTrigger = true;
                    }
                }

                if (CREATE_ASSETS && !File.Exists(@"Assets\Resources\Meshes\" + fileName + @"\" + mdl.Name))
                {
                    AssetDatabase.CreateAsset(mesh, @"Assets\Resources\Meshes\" + fileName + @"\" + mdl.Name);
                }
            }

            if (CREATE_ASSETS && !File.Exists("Assets/Resources/Prefabs/" + WORLD + fileName + ".prefab"))
            {
                if (!Directory.Exists("Assets/Resources/Prefabs/" + WORLD))
                {
                    Directory.CreateDirectory("Assets/Resources/Prefabs/" + WORLD);
                }
                PrefabUtility.CreatePrefab("Assets/Resources/Prefabs/" + WORLD + fileName + ".prefab", rootObj, ReplacePrefabOptions.ConnectToPrefab);
            }

            return(rootObj);
        }

        return(null);
    }
Example #3
0
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            SEGM segment = (SEGM)context.Instance;

            return(new StandardValuesCollection(segment.Owner.Materials));
        }
Example #4
0
    public static GameObject ImportMSH(string path, string[] additionalTextureSearchPaths = null, bool bCheckEditorExistence = false)
    {
        if (string.IsNullOrEmpty(path))
        {
            Debug.LogError("Tried to call ImportMSH with an empty path!");
            return(null);
        }

        if (PrefabMap.TryGetValue(path, out GameObject prefab))
        {
            GameObject instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
            return(instance);
        }

        FileInfo mshFile = new FileInfo(path);

        if (mshFile.Exists)
        {
            MSH msh;

            try {
                msh = MSH.LoadFromFile(mshFile.FullName);
            } catch {
                return(null);
            }

            string fileName = mshFile.Name.Replace(".msh", "");

            if (CREATE_ASSETS)
            {
                if (!AssetDatabase.IsValidFolder("Assets" + MODELS_FOLDER))
                {
                    AssetDatabase.CreateFolder("Assets", MODELS_FOLDER.Remove(0, 1));
                }

                if (!AssetDatabase.IsValidFolder("Assets" + MODELS_FOLDER + "/" + fileName))
                {
                    AssetDatabase.CreateFolder("Assets" + MODELS_FOLDER, fileName);
                }

                if (!AssetDatabase.IsValidFolder("Assets" + MODELS_FOLDER + "/" + fileName + "/MeshData"))
                {
                    AssetDatabase.CreateFolder("Assets" + MODELS_FOLDER + "/" + fileName, "MeshData");
                }
            }

            GameObject rootObj = new GameObject(fileName);

            Dictionary <MODL, GameObject> alreadyLoaded = new Dictionary <MODL, GameObject>();
            GameObject LoadMODL(MODL mdl, GameObject currentParent)
            {
                if (mdl == null)
                {
                    Debug.LogError("MODL was NULL!");
                    return(null);
                }
                if (currentParent == null)
                {
                    Debug.LogError("currentParent was NULL!");
                    return(null);
                }

                if (alreadyLoaded.TryGetValue(mdl, out GameObject obj))
                {
                    return(obj);
                }

                GameObject modelObj = new GameObject(mdl.Name);

                if (mdl.Parent != null)
                {
                    modelObj.transform.SetParent(LoadMODL(mdl.Parent, modelObj).transform);
                }
                else
                {
                    modelObj.transform.SetParent(currentParent.transform);
                }

                modelObj.transform.position   = Vector2Unity(mdl.Translation);
                modelObj.transform.rotation   = Quaternion.Euler(Vector2Unity(mdl.Rotation));
                modelObj.transform.localScale = Vector2Unity(mdl.Scale);

                if (!Array.Exists(LEGAL_TYPES, t => t == mdl.Type))
                {
                    return(modelObj);
                }

                if (!Array.Exists(LEGAL_MODELS, t => t == mdl.Tag))
                {
                    return(modelObj);
                }

                if (mdl.Geometry == null || mdl.Geometry.Segments == null)
                {
                    return(modelObj);
                }

                // TODO: use arrays instead of lists
                List <Vector3>  vertices  = new List <Vector3>();
                List <Vector3>  normals   = new List <Vector3>();
                List <Vector2>  uvs       = new List <Vector2>();
                List <Material> materials = new List <Material>();

                //each segment contains its own list of triangles
                List <int>[] triangles = new List <int> [mdl.Geometry.Segments.Count];

                //since each Segment acts as its own object (vertices, normals, triangles...) and we want to
                //merge all vertices into one array (as Unity expects it) but preserve our Segment Materials,
                //we have to set a sub mesh for each Segment, containing a list of vertex indices (of the now global vertex list).
                //so we have to store an offset
                int vertexOffset = 0;

                Mesh mesh = new Mesh();

                mesh.name         = mdl.Name;
                mesh.subMeshCount = mdl.Geometry.Segments.Count;

                //Debug.Log("Sub Mesh Count set to: " + mesh.subMeshCount);

                for (int si = 0; si < mdl.Geometry.Segments.Count; si++)
                {
                    //Debug.Log("Segment No: " + si);
                    SEGM segm = mdl.Geometry.Segments[si];

                    triangles[si] = new List <int>();

                    foreach (Vertex vert in segm.Vertices)
                    {
                        vertices.Add(new Vector3(-vert.position.X, vert.position.Y, vert.position.Z));
                        normals.Add(new Vector3(vert.normal.X, vert.normal.Y, vert.normal.Z));
                        uvs.Add(new Vector2(vert.uvCoordinate.X, vert.uvCoordinate.Y));
                    }

                    for (int pi = 0; pi < segm.Polygons.Length; pi++)
                    {
                        Polygon poly = segm.Polygons[pi];

                        int        triCount = 0;
                        List <int> tris     = new List <int>();

                        //in MSH, polygons are defined as triangle strips.
                        //since unity expects just triangles, we have to strip them ourselfs
                        for (int vi = 0; vi < poly.VertexIndices.Count; vi++)
                        {
                            if (triCount == 3)
                            {
                                vi      -= 2;
                                triCount = 0;
                            }

                            tris.Add(poly.VertexIndices[vi] + vertexOffset);
                            triCount++;
                        }

                        //triangles are listed CW CCW CW CCW...
                        bool flip = true;
                        for (int j = 0; j < tris.Count; j += 3)
                        {
                            if (flip)
                            {
                                int tmp = tris[j];
                                tris[j]     = tris[j + 2];
                                tris[j + 2] = tmp;
                            }

                            flip = !flip;
                        }

                        triangles[si].AddRange(tris);
                    }

                    string[] textureDirs = new string[1] {
                        mshFile.Directory.FullName
                    };
                    if (additionalTextureSearchPaths != null)
                    {
                        textureDirs = new string[additionalTextureSearchPaths.Length + 1];
                        additionalTextureSearchPaths[0] = mshFile.Directory.FullName;
                        Array.Copy(additionalTextureSearchPaths, 0, textureDirs, 1, additionalTextureSearchPaths.Length);
                    }

                    //Add Segment Material to overall Material List
                    materials.Add(Material2Unity(textureDirs, fileName, segm.Material, DEFAULT_MATERIAL));

                    //don't forget to increase our vertex offset
                    vertexOffset += segm.Vertices.Length;
                }

                mesh.vertices = vertices.ToArray();
                mesh.normals  = normals.ToArray();
                mesh.uv       = uvs.ToArray();

                //set triangles AFTER vertices to avoid out of bounds errors
                for (int si = 0; si < triangles.Length; si++)
                {
                    mesh.SetTriangles(triangles[si], si);
                }

                //Interpret Common and Lowrez as Geometry
                if (mdl.Tag == ModelTag.Common || mdl.Tag == ModelTag.Lowrez)
                {
                    MeshFilter filter = modelObj.AddComponent <MeshFilter>();
                    filter.mesh = mesh;

                    MeshRenderer renderer = modelObj.AddComponent <MeshRenderer>();
                    renderer.materials       = materials.ToArray();
                    renderer.sharedMaterials = materials.ToArray();
                }

                //and everything else as collision / trigger
                else
                {
                    MeshCollider collider = modelObj.AddComponent <MeshCollider>();
                    collider.sharedMesh = mesh;

                    if (mdl.Tag != ModelTag.Collision && mdl.Tag != ModelTag.VehicleCollision)
                    {
                        collider.convex    = true;
                        collider.isTrigger = true;
                    }
                }

                if (CREATE_ASSETS)
                {
                    AssetDatabase.CreateAsset(mesh, "Assets" + MODELS_FOLDER + "/" + fileName + "/MeshData/" + mesh.name + ".unitymesh");
                }

                alreadyLoaded.Add(mdl, modelObj);
                return(modelObj);
            }

            foreach (MODL mdl in msh.Models)
            {
                LoadMODL(mdl, rootObj);
            }

            if (CREATE_ASSETS)
            {
                string     prefabPath = "Assets" + MODELS_FOLDER + "/" + fileName + "/" + fileName + ".prefab";
                GameObject newPrefab  = PrefabUtility.SaveAsPrefabAssetAndConnect(rootObj, prefabPath, InteractionMode.AutomatedAction);
                PrefabUtility.ApplyPrefabInstance(rootObj, InteractionMode.AutomatedAction);
                PrefabMap.Add(path, newPrefab);
            }

            return(rootObj);
        }

        return(null);
    }