Exemple #1
0
        // The following Get[Asset] functions will perform the following sequence:
        // 1. Determine if the unity asset is available, load it from Asset DB, then return a pointer to the asset
        // 2. If not present, create one from the corresponding rose files then place it in the same directory tree but GameData instead of 3DDATA
        // 3. Reload the asset from the Asset DB and return a pointer to it

        public static AnimationClip GetClip(string zmoPath, ZMD skeleton, string name)
        {
            DirectoryInfo zmoDir    = new DirectoryInfo(zmoPath);
            string        unityPath = zmoDir.FullName.Replace(zmoDir.Name, name) + ".anim";

            AnimationClip clip = (AnimationClip)Utils.LoadAsset(unityPath, ".anim");

            if (clip == null)
            {
                clip        = new ZMO(zmoPath).buildAnimationClip(skeleton);
                clip.name   = name;
                clip.legacy = true;
                clip        = (AnimationClip)Utils.SaveReloadAsset(clip, unityPath, ".anim");
            }

            return(clip);
        }
Exemple #2
0
        // The following Get[Asset] functions will perform the following sequence:
        // 1. Determine if the unity asset is available, load it from Asset DB, then return a pointer to the asset
        // 2. If not present, create one from the corresponding rose files then place it in the same directory tree but GameData instead of 3DDATA
        // 3. Reload the asset from the Asset DB and return a pointer to it
        public static AnimationClip GetClip(string zmoPath, ZMD skeleton, string name)
        {
            DirectoryInfo zmoDir = new DirectoryInfo(zmoPath);
            string unityPath = zmoDir.FullName.Replace(zmoDir.Name, name) + ".anim";

            AnimationClip clip = (AnimationClip)Utils.LoadAsset(unityPath, ".anim");

            if (clip == null)
            {
                clip = new ZMO(zmoPath).buildAnimationClip(skeleton);
                clip.name = name;
                clip.legacy = true;
                clip = (AnimationClip)Utils.SaveReloadAsset(clip, unityPath, ".anim");
            }

            return clip;
        }
Exemple #3
0
        public void LoadClips(GameObject skeleton, ZMD zmd, GenderType gender, RigType rig, Dictionary<String, String> zmoPaths)
        {
            List<AnimationClip> clips = new List<AnimationClip>();

            foreach (KeyValuePair<String, String> motion in zmoPaths)
            {
                string unityPath = "Assets/Resources/Animation/" + gender.ToString() + "/" + rig.ToString() + "/clips/" + motion.Key + ".anim";

                AnimationClip clip = new ZMO("Assets/" + motion.Value).buildAnimationClip(zmd);
                clip.name = motion.Key;
                clip.legacy = true;
                clip = (AnimationClip)Utils.SaveReloadAsset(clip, unityPath, ".anim");
                clips.Add(clip);
            }

            Animation animation = skeleton.AddComponent<Animation>();
            AnimationUtility.SetAnimationClips(animation, clips.ToArray());
        }
Exemple #4
0
        /// <summary>
        /// Loads all animations for given weapon type and gender. The clips are saved to Animation/{gender}/{weapon}/clips/{action}.anim 
        /// Used only in editor to generate prefabs
        /// </summary>
        /// <param name="skeleton"></param>
        /// <param name="weapon"></param>
        /// <param name="gender"></param>
        /// <returns></returns>
        public void LoadClips(GameObject skeleton, ZMD zmd, WeaponType weapon, GenderType gender)
        {
            List<AnimationClip> clips = new List<AnimationClip>();

            foreach (ActionType action in Enum.GetValues(typeof(ActionType)))
            {
                string zmoPath = Utils.FixPath(ResourceManager.Instance.GetZMOPath(weapon, action, gender));  // Assets/3ddata path
                string unityPath = "Assets/Resources/Animation/" + gender.ToString() + "/" + weapon.ToString() + "/clips/" + action.ToString() + ".anim";

                AnimationClip clip =  new ZMO("Assets/" + zmoPath).buildAnimationClip(zmd);
                clip.name = action.ToString();
                clip.legacy = true;
                clip = (AnimationClip)Utils.SaveReloadAsset(clip, unityPath, ".anim");
                clips.Add(clip);
            }

            Animation animation = skeleton.AddComponent<Animation> ();
            AnimationUtility.SetAnimationClips(animation, clips.ToArray());
        }
Exemple #5
0
        public bool Import(Transform terrainParent, Transform objectsParent, Texture2D atlas, Texture2D atlas_normal, Dictionary<string, Rect> atlasRectHash)
        {
            if (!m_isValid)
            {
                Debug.LogError("Cannot Import patch_" + this.m_name);
                return false;
            }

            // Begin the real work

            // Each 4 heights are connected together as a quad
            // Each * below is a datapoint from HIM file representing height z
            //       (0,0)    (1,0)    (2,0)
            //            *----*----*
            //            |    |    |
            //      (0,1) *----*----* (2,1)
            //            |    |    |
            //      (0,2) *----*----* (2,2)
            //

            // Mesh components
            // path = 16x16 tiles
            // tile = 4x4 quads
            // quad = 2 triangles
            // triangle = 3 vertices

            int nVertices = 64 * 64 * 4;
            Vector3[] vertices = new Vector3[nVertices];
            Vector2[] uvsBottom = new Vector2[nVertices];
            Vector2[] uvsTop = new Vector2[nVertices];
            Color[] uvsLight= new Color[nVertices];
            int[] triangles = new int[(m_HIM.Length-1)*(m_HIM.Width-1)*6];

            int i_v = 0;      // vertex index
            int i_t = 0;     // triangle index

            // TODO: move these hardcoded values to a more appropriate place
            float m_xStride = 2.5f;
            float m_yStride = 2.5f;
            float heightScaler = 300.0f / (m_xStride * 1.2f);
            float x_offset = this.m_Row * m_xStride * 64.0f;
            float y_offset = this.m_Col * m_yStride * 64.0f;
            center = new Vector2(x_offset + m_xStride * 32.0f, y_offset + m_yStride * 32.0f);

            m_mesh = new Mesh();

            //  Uv mapping for tiles
            //	x%5 =   0     1	     2	   3     4
            //   	 (0,1) (.25,1)(.5,1)(.75,1)(1,1)
            //		 	*-----*-----*-----*-----*
            //			|   / |   / |   / |   / |
            //		    | /   | /   | /   | /   |
            //  (0,.75)	*-----*-----*-----*-----*
            //			|   / |   / |   / |   / |
            //			| /   | /   | /   | /   |
            //	(0,.5)	*-----*-----*-----*-----*
            //			|   / |   / |   / |   / |
            //			| /   | /   | /   | /   |
            //	(0,.25)	*-----*-----*-----*-----*
            //			|   / |   / |   / |   / |
            //			| /   | /   | /   | /   |
            //  (0,0)	*-----*-----*-----*-----*
            //			   (.25,0)(.5,0)(.75,0)(1,0)

            Vector2[,] uvMatrix = new Vector2[5, 5];
            Vector2[,] uvMatrixLR = new Vector2[5, 5];
            Vector2[,] uvMatrixTB = new Vector2[5, 5];
            Vector2[,] uvMatrixLRTB = new Vector2[5, 5];
            Vector2[,] uvMatrixRotCW = new Vector2[5, 5];  // rotated 90 deg clockwise
            Vector2[,] uvMatrixRotCCW = new Vector2[5, 5];	// rotated 90 counter clockwise

            for (int uv_x = 0; uv_x < 5; uv_x++)
            {
                for (int uv_y = 0; uv_y < 5; uv_y++)
                {
                    uvMatrix[uv_y, uv_x] = new Vector2(0.25f * (float)uv_x, 1.0f - 0.25f * (float)uv_y);
                    uvMatrixLR[uv_y, uv_x] = new Vector2(1.0f - 0.25f * (float)uv_x, 1.0f - 0.25f * (float)uv_y);
                    uvMatrixTB[uv_y, uv_x] = new Vector2(0.25f * (float)uv_x, 0.25f * (float)uv_y);
                    uvMatrixLRTB[uv_y, uv_x] = new Vector2(1.0f - 0.25f * (float)uv_x, 0.25f * (float)uv_y);
                    uvMatrixRotCCW[uv_x, uv_y] = new Vector2(0.25f * (float)uv_x, 1.0f - 0.25f * (float)uv_y);
                    uvMatrixRotCW[uv_x, uv_y] = new Vector2(0.25f * (float)uv_y, 1.0f - 0.25f * (float)uv_x);
                }
            }

            m_tiles = new List<Tile>();

            // Populate tiles with texture references
            for (int t_x = 0; t_x < 16; t_x++)
            {
                for (int t_y = 0; t_y < 16; t_y++)
                {
                    Tile tile = new Tile( );
                    int tileID = m_TIL.Tiles[t_y, t_x].TileID;
                    string texPath1 = m_ZON.Textures[m_ZON.Tiles[tileID].ID1].TexPath;
                    string texPath2 = m_ZON.Textures[m_ZON.Tiles[tileID].ID2].TexPath;
                    tile.bottomTex = texPath1;
                    tile.topTex = texPath2;
                    m_tiles.Add(tile);

                }
            }

            //string lightTexPath = "Assets/3DDATA/MAPS/JUNON/JPT01/" + m_Col + "_" + m_Row + "/" + m_Col + "_" + m_Row + "_PLANELIGHTINGMAP.dds";
            Texture2D lightTex = Utils.loadTex( ref groundLight );// Resources.LoadAssetAtPath<Texture2D>(lightTexPath);  //Utils.loadTex(lightTexPath, "Assets/GameData/Textures/Lightmaps/");
            //Utils.convertTex( lightTexPath, "Assets/GameData/Textures/Lightmaps/", ref lightTex);

            // copy rects to tiles
            foreach(Tile tile in m_tiles)
            {
                tile.bottomRect = atlasRectHash[tile.bottomTex];
                tile.topRect = atlasRectHash[tile.topTex];
            }

            // Generate a material

            Material material = null;
            if(realTimeBaking)
            {
                material = (Material)AssetDatabase.LoadMainAssetAtPath("Assets/Materials/JPT01.mat"); // new Material(Shader.Find( "Custom/StandardTerrain"));
                //material.SetTexture("_MainTex", atlas);
                //material.SetTexture("_DetailAlbedoMap", atlas);
            }
            else
            {
                material = new Material(Shader.Find( "Custom/TerrainShader2"));
                material.SetTexture("_BottomTex", atlas);
                material.SetTexture("_TopTex", atlas);
                material.SetTexture("_LightTex", lightTex);
            }

            float l = m_HIM.Length - 1;
            float w = m_HIM.Width - 1;

            int triangleID = 0;
            // Generate vertices and triangles
            for (int x = 0; x < m_HIM.Length - 1; x++)
            {
                for (int y = 0; y < m_HIM.Width - 1; y++)
                {
                    //    Each quad will be split into two triangles:
                    //
                    //          a         b
                    //            *-----*
                    //            |   / |
                    //            |  /  |
                    //            | /   |
                    //          d *-----* c
                    //
                    //  The triangles used are: adb and bdc

                    int a = i_v++;
                    int b = i_v++;
                    int c = i_v++;
                    int d = i_v++;

                    // Calculate lightmap UV's (placed in color because mesh only has uv and uv2)
                    uvsLight[a] = new Color((float)y / w, 1.0f - (float)x / l, 0.0f);
                    uvsLight[b] = new Color((float)y / w, 1.0f - (float)(x + 1) / l, 0.0f);
                    uvsLight[c] = new Color((float)(y + 1) / w, 1.0f - (float)(x + 1) / l, 0.0f);
                    uvsLight[d] = new Color((float)(y + 1) / w, 1.0f - (float)(x) / l, 0.0f);

                    // Calculate vertices
                    vertices[a] = new Vector3(x * m_xStride + x_offset, m_HIM.Heights[x, y] / heightScaler, y * m_yStride + y_offset);
                    vertices[b] = new Vector3((x + 1) * m_xStride + x_offset, m_HIM.Heights[x + 1, y] / heightScaler, y * m_yStride + y_offset);
                    vertices[c] = new Vector3((x + 1) * m_xStride + x_offset, m_HIM.Heights[x + 1, y + 1] / heightScaler, (y + 1) * m_yStride + y_offset);
                    vertices[d] = new Vector3(x * m_xStride + x_offset, m_HIM.Heights[x, y + 1] / heightScaler, (y + 1) * m_yStride + y_offset);

                    if (y == 0)
                    {
                        Utils.addVertexToLookup(edgeVertexLookup, vertices[a].ToString(), a);
                        Utils.addVertexToLookup(edgeVertexLookup, vertices[a].ToString(), b);
                    }
                    if (y == m_HIM.Width - 1)
                    {
                        Utils.addVertexToLookup(edgeVertexLookup, vertices[a].ToString(), d);
                        Utils.addVertexToLookup(edgeVertexLookup, vertices[a].ToString(), c);
                    }
                    if (x == 0)
                    {
                        Utils.addVertexToLookup(edgeVertexLookup, vertices[a].ToString(), a);
                        Utils.addVertexToLookup(edgeVertexLookup, vertices[a].ToString(), d);
                    }
                    if (x == m_HIM.Length - 1)
                    {
                        Utils.addVertexToLookup(edgeVertexLookup, vertices[a].ToString(), b);
                        Utils.addVertexToLookup(edgeVertexLookup, vertices[a].ToString(), c);
                    }

                    int tileX = x / 4;
                    int tileY = y / 4;
                    int tileID = tileY * 16 + tileX;

                    // Apply UV's
                    ZON.RotationType rotation = m_ZON.Tiles[m_TIL.Tiles[tileX, tileY].TileID].Rotation;
                    Vector2[,] rotMatrix;
                    if (rotation == ZON.RotationType.Rotate90Clockwise || rotation == ZON.RotationType.Rotate90CounterClockwise)
                        Debug.Log("Rotation: " + (int)rotation);
                    switch (rotation)
                    {
                        case ZON.RotationType.Normal:
                            rotMatrix = uvMatrix;
                            break;
                        case ZON.RotationType.LeftRight:
                            rotMatrix = uvMatrixLR;
                            break;
                        case ZON.RotationType.LeftRightTopBottom:
                            rotMatrix = uvMatrixLRTB;
                            break;
                        case ZON.RotationType.Rotate90Clockwise:
                            rotMatrix = uvMatrixRotCW;
                            break;
                        case ZON.RotationType.Rotate90CounterClockwise:
                            rotMatrix = uvMatrixRotCCW;
                            break;
                        case ZON.RotationType.TopBottom:
                            rotMatrix = uvMatrixTB;
                            break;
                        default:
                            rotMatrix = uvMatrix;
                            break;
                    }

                    // Get top and bottom UV's using texture atlas and rotation adjustments
                    uvsTop[a] = m_tiles[tileID].GetUVTop(rotMatrix[x % 4, y % 4]);
                    uvsTop[b] = m_tiles[tileID].GetUVTop(rotMatrix[(x % 4 + 1) % 5, y % 4]);
                    uvsTop[c] = m_tiles[tileID].GetUVTop(rotMatrix[(x % 4 + 1) % 5, (y % 4 + 1) % 5]);
                    uvsTop[d] = m_tiles[tileID].GetUVTop(rotMatrix[x % 4, (y % 4 + 1) % 5]);

                    uvsBottom[a] = m_tiles[tileID].GetUVBottom(rotMatrix[x % 4, y % 4]);
                    uvsBottom[b] = m_tiles[tileID].GetUVBottom(rotMatrix[(x % 4 + 1) % 5, y % 4]);
                    uvsBottom[c] = m_tiles[tileID].GetUVBottom(rotMatrix[(x % 4 + 1) % 5, (y % 4 + 1) % 5]);
                    uvsBottom[d] = m_tiles[tileID].GetUVBottom(rotMatrix[x % 4, (y % 4 + 1) % 5]);

                    triangles[triangleID ++] = a;
                    triangles[triangleID ++] = d;
                    triangles[triangleID ++] = b;

                    triangles[triangleID ++] = b;
                    triangles[triangleID ++] = d;
                    triangles[triangleID ++] = c;

                }  // for y
            }    // for x

            m_mesh.vertices = vertices;
            m_mesh.triangles = triangles;
            m_mesh.uv = uvsBottom;
            m_mesh.uv2 = uvsTop;
            m_mesh.colors = uvsLight;

            m_mesh.RecalculateNormals();

            if(blendNormals)
            {
                // CalculateSharedNormals: fix all normals as follows:
                // Several triangles share same vertex, but it is duplicated
                // We want to:
                //	1. search the vertex array for shared vertices
                //	2. store each shared vertex id in a data structure comprising rows of shared vertices
                //  3. go through each row of shared vertices and calculate the average normal
                //	4. store the avg normal and all corresponding vertex id's in different data structure
                //	5. traverse the new data structure and assign the new normal to all the vertices it belongs to

                Vector3[] normals = new Vector3[m_mesh.vertexCount];
                Dictionary<String, List<int>> vertexLookup = new Dictionary<String, List<int>>();
                // 1. and 2.
                for (int i = 0; i < m_mesh.vertexCount; i++)
                    Utils.addVertexToLookup(vertexLookup, m_mesh.vertices[i].ToString(), i);

                // traverse the shared vertex list and calculate new normals

                foreach (KeyValuePair<String, List<int>> entry in vertexLookup)
                {
                    Vector3 avg = Vector3.zero;
                    foreach (int id in entry.Value)
                    {
                        avg += m_mesh.normals[id];
                    }

                    avg.Normalize();

                    foreach (int id in entry.Value)
                        normals[id] = avg;

                }

                m_mesh.normals = normals;
            }

            Utils.calculateMeshTangents(m_mesh);
            m_mesh.RecalculateBounds();
            m_mesh.Optimize();

            //AssetDatabase.CreateAsset( m_mesh, "Assets/patch_" + this.m_name + ".mesh");

            GameObject patchObject = new GameObject();
            patchObject.name = "patch_" + this.m_name;

            patchObject.AddComponent<MeshFilter>().mesh = m_mesh;
            patchObject.AddComponent<MeshRenderer>();
            patchObject.AddComponent<MeshCollider>();

            MeshRenderer patchRenderer = patchObject.GetComponent<MeshRenderer>();
            patchRenderer.material = material;
            //patchRenderer.castShadows = false;
            patchObject.transform.parent = terrainParent;
            patchObject.layer = LayerMask.NameToLayer("Floor");

            //================== TERRAIN OBJECTS==========================

            GameObject deco = new GameObject();
            deco.name = "deco_" + this.m_name;
            deco.transform.parent = objectsParent;
            deco.layer = LayerMask.NameToLayer("MapObjects");

            //================= DECORATION ======================
            for (int obj = 0; obj < m_IFO.Decoration.Count; obj++ )
            {
                IFO.BaseIFO ifo = m_IFO.Decoration[obj];
                GameObject terrainObject = new GameObject();
                terrainObject.layer = LayerMask.NameToLayer("MapObjects");
                terrainObject.name = "Deco_" + ifo.MapPosition.x + "_" + ifo.MapPosition.y;
                terrainObject.transform.parent = deco.transform;
                terrainObject.transform.localPosition = (ifo.Position / 100.0f);
                bool isAnimated = false;
                AnimationClip clip = new AnimationClip();
                clip.legacy = true;

                for (int part = 0; part < m_ZSC_Deco.Objects[ifo.ObjectID].Models.Count; part++ )
                {
                    ZSC.Object.Model model = m_ZSC_Deco.Objects[ifo.ObjectID].Models[part];
                    // load ZMS
                    string zmsPath = m_3dDataDir.Parent.FullName + "/" + m_ZSC_Deco.Models[model.ModelID].Replace("\\", "/");
                    string texPath = "Assets/" + m_ZSC_Deco.Textures[model.TextureID].Path;
                   	string lightPath = null;
                    ZMS zms = null;
                    lightPath = Utils.FixPath(this.m_assetDir.Parent.FullName + "\\" + this.m_name + "\\LIGHTMAP\\" + m_LIT_Deco.Objects[obj].Parts[part].DDSName);
                    LIT.Object.Part lmData = m_LIT_Deco.Objects[obj].Parts[part];

                    // Calculate light map UV offset and scale
                    float objScale = 1.0f / (float) lmData.ObjectsPerWidth;
                    float rowNum = (float) Math.Floor( (double)( (double)lmData.MapPosition / (double)lmData.ObjectsPerWidth) );
                    float colNum = (float) lmData.MapPosition % lmData.ObjectsPerWidth;

                    Vector2 lmOffset = new Vector2(colNum * objScale, rowNum * objScale);
                    Vector2 lmScale = new Vector2(objScale, objScale);

                    zms = new ZMS(zmsPath, lmScale, lmOffset);

                    // Create material
                    Texture2D mainTex = Utils.loadTex( ref texPath);

                    Material mat = null;
                    if(realTimeBaking)
                    {
                        Texture2D normalMap = Utils.generateNormalMap( texPath );
                        mat = new Material(Shader.Find("Standard"));
                        mat.SetFloat("_Mode", 1.0f);
                        mat.SetTexture("_MainTex", mainTex);
                        mat.SetTexture("_OcclusionMap", mainTex);
                        mat.SetTexture("_BumpMap", normalMap);
                        mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                        mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                        mat.SetInt("_ZWrite", 1);
                        mat.EnableKeyword("_ALPHATEST_ON");
                        mat.DisableKeyword("_ALPHABLEND_ON");
                        mat.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                        mat.SetFloat("_OcclusionStrength", 0.5f);
                        mat.SetFloat("_BumpScale", 0.8f);
                        mat.SetFloat("_Glossiness", 0.1f);
                        //mat.renderQueue = 2450;
                    }
                    else
                    {
                        mat = new Material(Shader.Find("Custom/ObjectShader"));
                        mat.SetTexture("_MainTex", mainTex);
                        Texture2D lightTexture = Utils.loadTex ( ref lightPath);
                        mat.SetTexture("_LightTex", lightTexture);
                    }

                    GameObject modelObject = new GameObject();
                    modelObject.layer = LayerMask.NameToLayer("MapObjects");
                    modelObject.transform.parent = terrainObject.transform;

                    modelObject.transform.localScale = model.Scale;
                    modelObject.transform.localPosition = (model.Position / 100.0f);
                    modelObject.transform.rotation = model.Rotation;

                    modelObject.AddComponent<MeshFilter>().mesh = zms.getMesh();
                    modelObject.AddComponent<MeshRenderer>();
                    modelObject.name = new DirectoryInfo(zmsPath).Name;
                    MeshRenderer renderer = modelObject.GetComponent<MeshRenderer>();
                    renderer.material = mat;
                    //renderer.castShadows = false;

                    if(model.CollisionLevel != ZSC.CollisionLevelType.None)
                        modelObject.AddComponent<MeshCollider>();

                    string zmoPath = model.Motion;
                    if (zmoPath!= null && zmoPath.ToLower().Contains("zmo"))
                    {
                        isAnimated = true;
                        ZMO zmo = new ZMO("assets/" + model.Motion, false, true);
                        clip = zmo.buildAnimationClip(modelObject.name, clip);
                    }
                    else
                        modelObject.isStatic = true;
                }

                terrainObject.transform.rotation = ifo.Rotation;
                terrainObject.transform.localScale = ifo.Scale;

               	if (isAnimated)
               	{
                    Animation animation = terrainObject.GetComponent<Animation>();
                    if (animation == null)
                        animation = terrainObject.AddComponent<Animation>();
                    clip.wrapMode = WrapMode.Loop;
                    animation.AddClip(clip, terrainObject.name);
                    animation.clip = clip;
                }
                else
                {
                    terrainObject.isStatic = true;
               			}

            }

            GameObject cnst = new GameObject();
            cnst.name = "cnst_" + this.m_name;
            cnst.transform.parent = objectsParent;
            cnst.layer = LayerMask.NameToLayer("MapObjects");
            //================= CONSTRUCTION ======================
            for (int obj = 0; obj < m_IFO.Construction.Count; obj++)
            {
                IFO.BaseIFO ifo = m_IFO.Construction[obj];
                GameObject terrainObject = new GameObject();
                terrainObject.layer = LayerMask.NameToLayer("MapObjects");
                terrainObject.name = "Const_" + ifo.MapPosition.x + "_" + ifo.MapPosition.y;
                terrainObject.transform.parent = deco.transform;
                terrainObject.transform.localPosition = (ifo.Position / 100.0f);
                bool isAnimated = false;
                AnimationClip clip = new AnimationClip();
                clip.legacy = true;
                for (int part = 0; part < m_ZSC_Cnst.Objects[ifo.ObjectID].Models.Count; part++)
                {
                    ZSC.Object.Model model = m_ZSC_Cnst.Objects[ifo.ObjectID].Models[part];
                    string zmsPath = m_3dDataDir.Parent.FullName + "/" + m_ZSC_Cnst.Models[model.ModelID].Replace("\\","/");
                    string texPath = "Assets/" + m_ZSC_Cnst.Textures[model.TextureID].Path;

                    string lightPath = null;
                    ZMS zms = null;

                    // load ZMS
                    lightPath = Utils.FixPath(this.m_assetDir.Parent.FullName + "\\" + this.m_name + "\\LIGHTMAP\\" + m_LIT_Cnst.Objects[obj].Parts[part].DDSName);
                    LIT.Object.Part lmData = m_LIT_Cnst.Objects[obj].Parts[part];

                    // Calculate light map UV offset and scale
                    float objScale = 1.0f / (float)lmData.ObjectsPerWidth;
                    float rowNum = (float)Math.Floor((double)((double)lmData.MapPosition / (double)lmData.ObjectsPerWidth));
                    float colNum = (float)lmData.MapPosition % lmData.ObjectsPerWidth;

                    Vector2 lmOffset = new Vector2(colNum * objScale, rowNum * objScale);
                    Vector2 lmScale = new Vector2(objScale, objScale);

                    zms = new ZMS(zmsPath, lmScale, lmOffset);

                    // Create material
                    Texture2D mainTex =  Utils.loadTex(ref texPath);

                    Material mat = null;
                    if(realTimeBaking)
                    {
                        Texture2D normalMap = Utils.generateNormalMap( texPath );
                        mat = new Material(Shader.Find("Standard"));
                        mat.SetFloat("_Mode", 1.0f);
                        mat.SetTexture("_MainTex", mainTex);
                        mat.SetTexture("_OcclusionMap", mainTex);
                        mat.SetTexture("_BumpMap", normalMap);
                        mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                        mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                        mat.SetInt("_ZWrite", 1);
                        mat.EnableKeyword("_ALPHATEST_ON");
                        mat.DisableKeyword("_ALPHABLEND_ON");
                        mat.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                        mat.SetFloat("_OcclusionStrength", 0.5f);
                        mat.SetFloat("_BumpScale", 0.8f);
                        mat.SetFloat("_Glossiness", 0.1f);
                        //mat.renderQueue = 2450;
                    }
                    else
                    {
                        mat = new Material(Shader.Find("Custom/ObjectShader"));
                        mat.SetTexture("_MainTex", mainTex);
                        Texture2D lightTexture =  Utils.loadTex(ref lightPath);
                        mat.SetTexture("_LightTex", lightTexture);

                    }

                    GameObject modelObject = new GameObject();
                    modelObject.layer = LayerMask.NameToLayer("MapObjects");
                    modelObject.transform.parent = terrainObject.transform;

                    modelObject.transform.localScale = model.Scale;
                    modelObject.transform.localPosition = (model.Position / 100.0f);
                    modelObject.transform.rotation = model.Rotation;

                    modelObject.AddComponent<MeshFilter>().mesh = zms.getMesh();
                    modelObject.AddComponent<MeshRenderer>();
                    modelObject.name = new DirectoryInfo(zmsPath).Name;
                    MeshRenderer renderer = modelObject.GetComponent<MeshRenderer>();
                    renderer.material = mat;
                    //renderer.castShadows = false;
                    modelObject.AddComponent<MeshCollider>();

                    string zmoPath = model.Motion;
                    if (zmoPath != null && zmoPath.ToLower().Contains("zmo"))
                    {
                        isAnimated = true;
                        ZMO zmo = new ZMO("assets/" + model.Motion, false, true);
                        clip = zmo.buildAnimationClip(modelObject.name, clip);
                    }
                    else
                        modelObject.isStatic = true;
                }

                terrainObject.transform.rotation = ifo.Rotation;
                terrainObject.transform.localScale = ifo.Scale;

                if (isAnimated)
               	{
                    Animation animation = terrainObject.GetComponent<Animation>();

                    if (animation == null)
                        animation = terrainObject.AddComponent<Animation>();

                    clip.wrapMode = WrapMode.Loop;
                    animation.AddClip(clip, terrainObject.name);
                    animation.clip = clip;
                }
                else
                    terrainObject.isStatic = false;

            }

            /*
            // TODO: add any extra components here
            AssetDatabase.CreateAsset( m_mesh, this.m_unityAssetDir.FullName);
            AssetDatabase.SaveAssets();
            */
            return true;
        }