Paste2 Logo
  1. import System.IO;
  2. //import System.Drawing.Imaging;
  3.  
  4. //**************************************************************************************************
  5. //************************************ The Whirld Project ******************************************
  6. //******************** http://www.unifycommunity.com/wiki/index.php?title=Whirld *******************
  7. //**************************************************************************************************
  8.  
  9. class WhirldUTW extends System.Object {
  10.         var whirld : Whirld;
  11.         var objects : Hashtable = new Hashtable();
  12.         var txts : Hashtable = new Hashtable();
  13.         var txtArr : Array = new Array();
  14.         var mshArr : Array = new Array();
  15.         var trnArr : Array = new Array();
  16.         var readChr = 0;
  17.         var whirldBuffer : GameObject;
  18.         var materials : Hashtable = new Hashtable();
  19.         var prefabs : Array;
  20.        
  21.         function WhirldUTW(lnk : Whirld) {
  22.                 whirld = lnk;
  23.         }
  24.        
  25.         //function Load() {
  26.                 //Load();
  27.                 //Game.Controller.StartCoroutine("Load");
  28.         //}
  29.        
  30.         //function Cancel() {
  31.                 //Game.Controller.StopCoroutine("Load");
  32.         //}
  33.        
  34.         function Load() {
  35.                 if(Game && Game.Controller) prefabs = new Array (Game.Controller.prefabs);
  36.  
  37.                 if(whirld.data[0] != "[" && whirld.data[0] != "{") {
  38.                         whirld.status = WorldLoadCode.SyntaxError;
  39.                         return;
  40.                 }
  41.                
  42.                 //Create Buffer Object
  43.                 whirldBuffer = new GameObject("WhirldBuffer");
  44.                
  45.                 //Read headers
  46.                 while(true) {
  47.                         s = whirld.data[readChr];
  48.                         readChr += 1;
  49.                         if(readChr >= whirld.data.length) {
  50.                                 whirld.status = WorldLoadCode.SyntaxError;
  51.                                 return;
  52.                         }
  53.                         else if(s == "{") break;                //Finished reading headers
  54.                         else if(s == "[") {                             //Beginning new header
  55.                                 var n = "";
  56.                                 var v = "";
  57.                         }
  58.                         else if(s == ":" && n == "") {  //Header name read, read value
  59.                                 n = v;
  60.                                 v = "";
  61.                         }
  62.                         else if(s == "]") {                             //Header ended
  63.                                 var vS = v.Split(","[0]);
  64.                                 if(n == "txt") txtArr.Add(v);
  65.                                 else if(n == "msh") mshArr.Add(v);
  66.                                 else if(n == "trn") trnArr.Add(v);
  67.                                 //else if(n == "rndFogColor") RenderSettings.fogColor = Color(parseFloat(vS[0]), parseFloat(vS[1]), parseFloat(vS[2]), 1);
  68.                                 else if(n == "rndFogDensity") RenderSettings.fogDensity = parseFloat(v);
  69.                                 else if(n == "rndAmbientLight") RenderSettings.ambientLight = Color(parseFloat(vS[0]), parseFloat(vS[1]), parseFloat(vS[2]), parseFloat(vS[3]));
  70.                                 else whirld.worldParams.Add(n, v);
  71.                         }
  72.                         else v += s;                                    //Header char read
  73.                 }
  74.                
  75.                 //Download texture assets referenced in headers
  76.                 i = 1;
  77.                 for(var v : String in txtArr) {         //[txt:name,url,wrapMode,anisoLevel]
  78.                         vS = v.Split(","[0]);
  79.                         whirld.statusTxt = "Downloading Texture " + i + " of " + txtArr.length + " (" + vS[0] + "): " + vS[1];
  80.                         var www : WWW = new WWW(vS[1]);
  81.                         while(!www.isDone) {
  82.                                 whirld.progress = www.progress;
  83.                                 yield new WaitForSeconds(.1);
  84.                         }
  85.                         if (www.error != null) whirld.info += "\nTexture Undownloadable: " + vS[0] + " " + vS[1] + " (" + www.error + ")";
  86.                         else {
  87.                                 var txt = www.texture;
  88.                                 if(!vS[0] || vS[0] == 0)        txt.wrapMode = TextureWrapMode.Clamp;
  89.                                 else                                            txt.wrapMode = TextureWrapMode.Repeat;
  90.                                 txt.anisoLevel = (vS[3] ? vS[3] : 1);
  91.                                 //txt.Apply(true);
  92.                                 //txt.Compress(true);
  93.                                 txts.Add(vS[0], txt);
  94.                                 whirld.statusTxt = "";
  95.                         }
  96.                         i++;
  97.                 }
  98.                
  99.                 //Download mesh assets referenced in headers
  100.                 var meshesDown : int;
  101.                 var meshMaterials : Hashtable = new Hashtable();
  102.                 var meshMatLibs : Hashtable = new Hashtable();
  103.                
  104.                 for(var v : String in mshArr) {         //[msh:name,url]
  105.                         vS = v.Split(","[0]);
  106.                         var hasCollider = (vS.length > 2 ? parseInt(vS[2]) : 0);
  107.                         meshesDown++;
  108.                         whirld.statusTxt = "Downloading Mesh " + meshesDown + " of " + mshArr.length + " (" + vS[0] + "): " + vS[1];
  109.                         www = new WWW(whirld.getURL(vS[1]));
  110.                         while(!www.isDone) {
  111.                                 whirld.progress = www.progress;
  112.                                 yield new WaitForSeconds(.1);
  113.                         }
  114.                         if (www.error != null) whirld.info += "\nMesh Undownloadable: " + vS[0] + " " + vS[1] + " (" + www.error + ")";
  115.                         else {
  116.                                 whirld.statusTxt = "Initializing " + vS[0] + "...";
  117.                                 whirld.progress = 0;
  118.                                 if(Application.isPlaying) yield;
  119.                                
  120.                                 //Uncompress as necessary...
  121.                                 var lastDot : int = vS[1].LastIndexOf(".");
  122.                                 if(vS[1].Substring(lastDot + 1) == "gz") {
  123.                                         var data : String = new Ionic.Zlib.GZipStream(new MemoryStream(), Ionic.Zlib.CompressionMode.Decompress).UncompressString(www.bytes);
  124.                                         vS[1] = vS[1].Substring(0, lastDot);
  125.                                 }
  126.  
  127.                                 lastDot = vS[1].LastIndexOf(".");
  128.                                 var ext : String = vS[1].Substring(lastDot + 1);
  129.                                
  130.                                 //Binary UniTyMesh Object
  131.                                 if(ext == "utm") {
  132.                                         var msh : Mesh = MeshSerializer.ReadMesh(www.bytes);
  133.                                 }
  134.                                
  135.                                 //.obj File
  136.                                 else if(ext == "obj") {
  137.                                         msh = new Mesh();
  138.                                         var verts = new Array();
  139.                                         var norms = new Array();
  140.                                         var uvs = new Array();
  141.                                         var tris = new Array();
  142.                                         var triangles = new Array();
  143.                                         var mats = new Array();
  144.                                        
  145.                                         var file : String[] = data.Split("\n"[0]);
  146.                                         for (var str : String in file) {
  147.                                                 if(str == "") continue;
  148.                                                 var l : String[] = str.Split(" "[0]);
  149.                                                 if(l[0] == "v") verts.Add(Vector3(-parseFloat(l[1]), parseFloat(l[2]), parseFloat(l[3])));
  150.                                                 else if(l[0] == "vn") norms.Add(Vector3(parseFloat(l[1]), parseFloat(l[2]), parseFloat(l[3])));
  151.                                                 else if(l[0] == "vt") uvs.Add(Vector2(parseFloat(l[1]), parseFloat(l[2])));
  152.                                                 else if(l[0] == "f") {
  153.                                                         tris.Add(parseInt(l[2].Substring(0, l[2].IndexOf("/"))) - 1);
  154.                                                         tris.Add(parseInt(l[1].Substring(0, l[1].IndexOf("/"))) - 1);
  155.                                                         tris.Add(parseInt(l[3].Substring(0, l[3].IndexOf("/"))) - 1);
  156.                                                 }
  157.                                                 else if(l[0] == "usemtl") {
  158.                                                         if(meshMaterials.ContainsKey(l[1])) mats.Add(meshMaterials[l[1]]);
  159.                                                         else mats.Add(null);
  160.                                                         if(tris.length > 0) {
  161.                                                                 triangles.Add(tris);
  162.                                                                 tris = new Array();
  163.                                                         }
  164.                                                 }
  165.                                                 else if(l[0] == "mtllib") { //Time to load a material library!
  166.                                                         if(!meshMatLibs.ContainsKey(l[1])) {
  167.                                                                 meshMatLibs.Add(l[1], true); //Only load a material library once, even if it is referenced by multiple meshes
  168.                                                                 whirld.statusTxt = "Downloading Mesh Material Library: " + l[1];
  169.                                                                 www = new WWW(whirld.getURL(l[1]));
  170.                                                                 while(!www.isDone) {
  171.                                                                         whirld.progress = www.progress;
  172.                                                                         yield new WaitForSeconds(.1);
  173.                                                                 }
  174.                                                                 if (www.error != null) whirld.info += "\nMesh Material Library Undownloadable: " + l[1] + " (" + www.error + ")";
  175.                                                                 else {
  176.                                                                         whirld.statusTxt = "Initializing " + vS[0] + "...";
  177.                                                                         whirld.progress = 0;
  178.                                                                         yield;
  179.                                                                         var meshlib : String[] = www.data.Split("\n"[0]);
  180.                                                                         var curMat : Material;
  181.                                                                         var meshTxtsDown : int = 0;
  182.                                                                         var meshTxts : int = 0;
  183.                                                                     var offset : int = -1;
  184.                                                                     while(true) {
  185.                                                                         offset = www.data.IndexOf("map_Ka", offset + 1);
  186.                                                                         if(offset == -1) break;
  187.                                                                         meshTxts++;
  188.                                                                     }
  189.                                                                         for (var meshline : String in meshlib) {
  190.                                                                                 var ml : String[] = meshline.Split(" "[0]);
  191.                                                                                 if(ml[0] == "newmtl") { //Beginning of new material
  192.                                                                                         if(curMat) { //Save current material
  193.                                                                                                 meshMaterials.Add(curMat.name, curMat);
  194.                                                                                         }
  195.                                                                                         curMat = new Material(Shader.Find("VertexLit"));
  196.                                                                                         curMat.name = ml[1];
  197.                                                                                 }
  198.                                                                                 else if(ml[0] == "#Shader") { //Set shader of current material
  199.                                                                                         var shdr = meshline.Substring(8).Replace("Diffuse", "VertexLit");
  200.                                                                                         if(shdr != "VertexLit" && shdr != "VertexLit Fast") curMat.shader = Shader.Find(shdr);
  201.                                                                                 }
  202.                                                                                 else if(ml[0] == "Ka") { //Set color of current material
  203.                                                                                         curMat.color = Color(parseFloat(ml[1]), parseFloat(ml[2]), parseFloat(ml[3]), 1);
  204.                                                                                 }
  205.                                                                                 else if(ml[0] == "Kd") {
  206.                                                                                         curMat.SetColor("_Emission", Color(parseFloat(ml[1]), parseFloat(ml[2]), parseFloat(ml[3]), 1));
  207.                                                                                 }
  208.                                                                                 else if(ml[0] == "Ks") {
  209.                                                                                         curMat.SetColor("_SpecColor", Color(parseFloat(ml[1]), parseFloat(ml[2]), parseFloat(ml[3]), 1));
  210.                                                                                 }
  211.                                                                                 else if(ml[0] == "Ns") {
  212.                                                                                         curMat.SetFloat("_Shininess", parseFloat(ml[1]));
  213.                                                                                 }
  214.                                                                                 else if(ml[0] == "map_Ka") { //Set texture of current material
  215.                                                                                         meshTxtsDown += 1;
  216.                                                                                         whirld.statusTxt = "Downloading Mesh Texture " + meshTxtsDown + " of " + meshTxts + " (" + ml[7] + ")";
  217.                                                                                         www = new WWW(whirld.getURL(ml[7]));
  218.                                                                                         while(!www.isDone) {
  219.                                                                                                 whirld.progress = www.progress;
  220.                                                                                                 yield new WaitForSeconds(.1);
  221.                                                                                         }
  222.                                                                                         if (www.error != null) whirld.info += "\nMesh Texture Undownloadable: " + ml[7];
  223.                                                                                         else {
  224.                                                                                                 whirld.statusTxt = "Initializing " + vS[0] + "...";
  225.                                                                                                 whirld.progress = 0;
  226.                                                                                                 yield;
  227.                                                                                                 var mshTxt : Texture2D = new Texture2D(4, 4, TextureFormat.DXT1, true);
  228.                                                                                                 www.LoadImageIntoTexture(mshTxt);
  229.                                                                                                 mshTxt.Apply(true);
  230.                                                                                                 mshTxt.Compress(true);
  231.                                                                                                 curMat.mainTexture = mshTxt;
  232.                                                                                                 curMat.mainTextureOffset = Vector2(parseFloat(ml[2]), parseFloat(ml[3]));
  233.                                                                                                 curMat.mainTextureScale = Vector2(parseFloat(ml[5]), parseFloat(ml[6]));
  234.                                                                                         }
  235.                                                                                 }
  236.                                                                                 else if(ml[0] == "d") { //Set alpha cutoff of current material
  237.                                                                                         //curMat.shader = Shader.Find("Transparent/Cutout/VertexLit");
  238.                                                                                         //curMat.SetFloat("_Cutoff", parseFloat(ml[1]));
  239.                                                                                 }
  240.                                                                         }
  241.                                                                         if(curMat) { //Save last material (others get saves as file is read)
  242.                                                                                 meshMaterials.Add(curMat.name, curMat);
  243.                                                                         }
  244.                                                                 }
  245.                                                         }
  246.                                                 }
  247.                                         }
  248.                                         msh.vertices = verts.ToBuiltin(Vector3);
  249.                                         msh.normals = norms.ToBuiltin(Vector3);
  250.                                         msh.uv = uvs.ToBuiltin(Vector2);
  251.                                         if(triangles.length > 0) {
  252.                                                 triangles.Add(tris);
  253.                                                 msh.subMeshCount = triangles.length;
  254.                                                 for(i=0; i < triangles.length; i++) msh.SetTriangles(triangles[i].ToBuiltin(int), i);
  255.                                         }
  256.                                         else msh.triangles = tris.ToBuiltin(int);
  257.                                 }
  258.                                
  259.                                 //Unknown File Type
  260.                                 else  whirld.info += "\nMesh Type Unrecognized: " + vS[0] + " " + vS[1] + " (." + ext + ")";
  261.                                
  262.                                 msh.Optimize();
  263.                                
  264.                                 if(hasCollider != 1) { //This mesh is being created, and it has a renderer
  265.                                         var mshObj : GameObject = new GameObject(vS[0]);
  266.                                         mshObj.AddComponent(MeshFilter);
  267.                                         mshObj.GetComponent(MeshFilter).mesh = msh;
  268.                                         mshObj.AddComponent(MeshRenderer);
  269.                                         mshObj.GetComponent(MeshRenderer).materials = mats.ToBuiltin(Material);
  270.                                         if(hasCollider != -1) { //This mesh has a collider, and it is the same as it's rendered mesh
  271.                                                 mshObj.AddComponent(MeshCollider);
  272.                                                 mshObj.GetComponent(MeshCollider).mesh = msh;
  273.                                         }
  274.                                         if(msh.uv.length < 1) whirld.TextureGO(mshObj);
  275.                                         objects.Add(vS[0], mshObj);
  276.                                         mshObj.transform.parent = whirldBuffer.transform;
  277.                                 }
  278.                                 else {  //This mesh has a custom collider
  279.                                         if(objects.ContainsKey(vS[0])) {        //This mesh already exists, add a custom collider to it
  280.                                                 mshObj = objects[vS[0]];
  281.                                                 mshObj.AddComponent(MeshCollider);
  282.                                                 mshObj.GetComponent(MeshCollider).mesh = msh;
  283.                                         }
  284.                                         else {          //This mesh is just a collider. It hasn't been created already, so we need to do that.
  285.                                                 mshObj = new GameObject(vS[0]);
  286.                                                 mshObj.AddComponent(MeshCollider);
  287.                                                 mshObj.GetComponent(MeshCollider).mesh = msh;
  288.                                                 objects.Add(vS[0], mshObj);
  289.                                                 mshObj.transform.parent = whirldBuffer.transform;
  290.                                         }
  291.                                 }
  292.                                 whirld.statusTxt = "";
  293.                         }
  294.                         i++;
  295.                 }
  296.                
  297.                 //Download terrain assets referenced in headers
  298.                 i = 1;
  299.                 for(var v : String in trnArr) {
  300.                         //v = "name;r:width,height,length,heightmapResolution //,detailResolution,controlResolution,textureResolution;h:heightMapUrl";
  301.                         var vS2 : String[] = v.Split(";"[0]);
  302.                         var tName = vS2[0];
  303.                         for(i2 = 1; i2<vS2.length; i2++) {
  304.                                 var str : String[] = vS2[i2].Split(":"[0]);
  305.                                 if(str[0] == "r") var tRes : String[] = str[1].Split(","[0]);
  306.                                 else if(str[0] == "h") var tHtmp : String = whirld.getURL(str[1]);
  307.                                 else if(str[0] == "l") var tLtmp : String = whirld.getURL(str[1]);
  308.                                 else if(str[0] == "s") var tSpmp : String = whirld.getURL(str[1]);
  309.                                 else if(str[0] == "s2") var tSpmp2 : String = whirld.getURL(str[1]);
  310.                                 else if(str[0] == "t") var tTxts : String[] = str[1].Split(","[0]);
  311.                                 else if(str[0] == "d") var tDtmp : String = whirld.getURL(str[1]);
  312.                         }
  313.                         whirld.statusTxt = "Downloading Terrain " + i + " of " + trnArr.length + " (" + tName + "): " + tHtmp;
  314.                         www = new WWW(tHtmp);
  315.                         while(!www.isDone) {
  316.                                 whirld.progress = www.progress;
  317.                                 yield new WaitForSeconds(.1);
  318.                         }
  319.                         if (www.error != null) whirld.info += "\nTerrain Undownloadable: " + tName + " " + tHtmp + " (" + www.error + ")";
  320.                         else {
  321.                                 whirld.statusTxt = "Initializing " + tName + "...";
  322.                                 whirld.progress = 0;
  323.                                 if(Application.isPlaying) yield;
  324.                                
  325.                                 var tWidth : int = parseInt(tRes[0]);
  326.                                 var tHeight : int = parseInt(tRes[1]);
  327.                                 var tLength : int = parseInt(tRes[2]);
  328.                                 var tHRes : int = parseInt(tRes[3]);
  329.                                 //var tDRes : int = parseInt(tRes[4]);
  330.                                 //var tCRes : int = parseInt(tRes[5]);
  331.                                 //var tBRes : int = parseInt(tRes[6]);
  332.                                 var trnDat : TerrainData = new TerrainData();
  333.                                
  334.                                 //Heights
  335.                                 trnDat.heightmapResolution = tHRes;
  336.                                 //trnDat.Init(tCRes, tDRes, tBRes);
  337.                                 var hmap = trnDat.GetHeights(0, 0, tHRes, tHRes);
  338.                                 var br : BinaryReader;
  339.                                 if(true) { //Terrain RAW file is compressed
  340.                                         /*var stream = new DeflateStream(new MemoryStream(www.bytes), CompressionMode.Decompress);
  341.                                         var buffer : byte[] = new byte[4096];
  342.                                 var ms : MemoryStream = new MemoryStream();
  343.                                         var bytesRead : int = 0;
  344.                                         while (bytesRead > 0) {
  345.                                 bytesRead = stream.Read(buffer, 0, buffer.Length);
  346.                                 if (bytesRead > 0) ms.Write(buffer, 0, bytesRead);
  347.                                 }
  348.                                         br = new BinaryReader(ms);*/
  349.                                     br = new BinaryReader(new MemoryStream(new Ionic.Zlib.GZipStream(new MemoryStream(), Ionic.Zlib.CompressionMode.Decompress).UncompressBuffer(www.bytes)));
  350.                                 }
  351.                                 else br = new BinaryReader(new MemoryStream(www.bytes));
  352.                                 for (var x : int = 0; x < tHRes; x++) for (var y : int = 0; y < tHRes; y++) hmap[x, y] = br.ReadUInt16() / 65535.00000000;
  353.                                 trnDat.SetHeights(0, 0, hmap);
  354.                                 trnDat.size = Vector3(tWidth, tHeight, tLength);                               
  355.                                
  356.                                 //Textures
  357.                                 if(tTxts) {
  358.                                         var splatPrototypes : SplatPrototype[] = new SplatPrototype[tTxts.length];
  359.                                         for(i=0; i < tTxts.length; i++) {
  360.                                                 var splatTxt : String[] = tTxts[i].Split("="[0]);
  361.                                                 var splatTxtSize : String[] = splatTxt[1].Split("x"[0]);
  362.                                                 whirld.statusTxt = "Downloading Terrain Texture " + (i + 1) + " of " + tTxts.length + " (" + splatTxt[0] + ")";
  363.                                                 www = new WWW(whirld.getURL(splatTxt[0]));
  364.                                                 while(!www.isDone) {
  365.                                                         whirld.progress = www.progress;
  366.                                                         yield new WaitForSeconds(.1);
  367.                                                 }
  368.                                                 if (www.error != null) whirld.info += "\nTerrain Texture Undownloadable: #" + (i + 1) + " (" + splatTxt[0] + ")";
  369.                                                 else {
  370.                                                         whirld.statusTxt = "Initializing Terrain Texture " + (i + 1) + " of " + tTxts.length + "...";
  371.                                                         yield;
  372.                                                         splatPrototypes[i] = new SplatPrototype();
  373.                                                         splatPrototypes[i].texture = new Texture2D(4, 4, TextureFormat.DXT1, true);
  374.                                                         www.LoadImageIntoTexture(splatPrototypes[i].texture);
  375.                                                         splatPrototypes[i].texture.Apply(true);
  376.                                                         splatPrototypes[i].texture.Compress(true);
  377.                                                         splatPrototypes[i].tileSize = Vector2(parseInt(splatTxtSize[0]), parseInt(splatTxtSize[1]));
  378.                                                 }
  379.                                         }
  380.                                 }
  381.                                 else {
  382.                                         splatPrototypes = new SplatPrototype[whirld.worldTerrainTextures.length];
  383.                                         for(i=0; i < whirld.worldTerrainTextures.length; i++) {
  384.                                                 splatPrototypes[i] = new SplatPrototype();
  385.                                                 splatPrototypes[i].texture = whirld.worldTerrainTextures[i];
  386.                                                 splatPrototypes[i].tileSize = Vector2(15, 15);
  387.                                         }
  388.                                 }
  389.                                 trnDat.splatPrototypes = splatPrototypes;
  390.                                
  391.                                 //Lightmap
  392.                                 if(tLtmp) {
  393.                                         whirld.statusTxt = "Downloading Terrain Lightmap (" + tName + ")";
  394.                                         www = new WWW(tLtmp);
  395.                                         while(!www.isDone) {
  396.                                                 whirld.progress = www.progress;
  397.                                                 yield new WaitForSeconds(.1);
  398.                                         }
  399.                                         if (www.error != null) whirld.info += "\nTerrain Lightmap Undownloadable: " + tName + " " + tLtmp + " (" + www.error + ")";
  400.                                         else {
  401.                                                 trnDat.lightmap = www.texture;
  402.                                         }
  403.                                 }
  404.                                
  405.                                 //Splatmap
  406.                                 if(tSpmp) {
  407.                                         if(tSpmp2) {
  408.                                                 whirld.statusTxt = "Downloading Augmentative Terrain Texturemap (" + tName + ")";
  409.                                                 www = new WWW(tSpmp2);
  410.                                                 while(!www.isDone) {
  411.                                                         whirld.progress = www.progress;
  412.                                                         yield new WaitForSeconds(.1);
  413.                                                 }
  414.                                                 var mapColors2 = www.texture.GetPixels();
  415.                                         }
  416.                                         whirld.statusTxt = "Downloading Terrain Texturemap (" + tName + ")";
  417.                                         www = new WWW(tSpmp);
  418.                                         while(!www.isDone) {
  419.                                                 whirld.progress = www.progress;
  420.                                                 yield new WaitForSeconds(.1);
  421.                                         }
  422.                                         whirld.progress = 0;
  423.                                         whirld.statusTxt = "Mapping Terrain Textures...";
  424.                                         yield;
  425.                                         if (www.error != null) whirld.info += "\nTerrain Texturemap Undownloadable: " + tName + " " + tLtmp + " (" + www.error + ")";
  426.                                         else {
  427.                                                 if (www.texture.format != TextureFormat.ARGB32 || www.texture.width != www.texture.height || Mathf.ClosestPowerOfTwo(www.texture.width) != www.texture.width) {
  428.                                                         whirld.info += "\nTerrain Splatmap Unusable: Splatmap must be in RGBA 32 bit format, square, and it's size a power of 2";
  429.                                                 }
  430.                                                 else {
  431.                                                         trnDat.alphamapResolution = www.texture.width;
  432.                                                         var splatmapData = trnDat.GetAlphamaps(0, 0, www.texture.width, www.texture.width);
  433.                                                         var mapColors = www.texture.GetPixels();
  434.                                                         var ht : int = www.texture.height;
  435.                                                         var wd : int = www.texture.width;
  436.                                                         for (y = 0; y < ht; y++) for (x = 0; x < wd; x++) for (z = 0; z < trnDat.alphamapLayers; z++) {
  437.                                                                 if(z < 4) splatmapData[x,y,z] = mapColors[x * wd + y][z];
  438.                                                                 else splatmapData[x,y,z] = mapColors2[x * wd + y][z-4];
  439.                                                         }
  440.                                                         trnDat.SetAlphamaps(0, 0, splatmapData);
  441.                                                 }
  442.                                         }
  443.                                 }
  444.                                
  445.                                 //Details (rocks, trees, grass, etc)
  446.                                 if(tDtmp) {
  447.                                         whirld.statusTxt = "Downloading Terrain Details (" + tDtmp + ")";
  448.                                         www = new WWW(tDtmp);
  449.                                         while(!www.isDone) {
  450.                                                 whirld.progress = www.progress;
  451.                                                 yield new WaitForSeconds(.1);
  452.                                         }
  453.                                         if (www.error != null) whirld.info += "\nTerrain Details Undownloadable: " + tName + " " + tDtmp + " (" + www.error + ")";
  454.                                         else {
  455.                                                 var treePrototypes : Array = new Array();
  456.                                                 var treeInstances : Array = new Array();
  457.                                                 var treeProto : TreePrototype;
  458.                                                 var detailProto : DetailPrototype;
  459.                                                 var detailPrototypes : Array = new Array();
  460.                                                 file = new Ionic.Zlib.GZipStream(new MemoryStream(), Ionic.Zlib.CompressionMode.Decompress).UncompressString(www.bytes).Split("\n"[0]);
  461.                                                 for (i=0; i < file.length; i++) {
  462.                                                         if(file[i] == "" || i == file.length - 1) { //Apply Existing Trees
  463.                                                                 if(treeProto) {
  464.                                                                         treePrototypes.Add(treeProto);
  465.                                                                         treeProto = null;
  466.                                                                         //continue;
  467.                                                                 }
  468.                                                                 if(detailProto) {
  469.                                                                         detailPrototypes.Add(detailProto);
  470.                                                                         detailProto = null;
  471.                                                                         //continue;
  472.                                                                 }
  473.                                                         }
  474.                                                         if(file[i].length > 10 && file[i].Substring(0, 10) == "detailmap2") {
  475.                                                                 whirld.statusTxt = "Downloading Augmentative Terrain Detail Map (" + whirld.getURL(file[i].Substring(11)) + ")";
  476.                                                                 www = new WWW(whirld.getURL(file[i].Substring(11)));
  477.                                                                 while(!www.isDone) {
  478.                                                                         whirld.progress = www.progress;
  479.                                                                         yield new WaitForSeconds(.1);
  480.                                                                 }
  481.                                                                 if (www.error != null) whirld.info += "\nAugmentative Terrain Detail Map Undownloadable: " + tName + " " + file[i].Substring(11) + " (" + www.error + ")";
  482.                                                                 else {
  483.                                                                         tex = www.texture;
  484.                                                                         pixels = www.texture.GetPixels();
  485.                                                                         if(detailPrototypes.length > 4) var detLayer4 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 4);
  486.                                                                         if(detailPrototypes.length > 5) var detLayer5 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 5);
  487.                                                                         if(detailPrototypes.length > 6) var detLayer6 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 6);
  488.                                                                         if(detailPrototypes.length > 7) var detLayer7 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 7);
  489.                                                                         i2 = 0;
  490.                                                                         for(iY = 0; iY < trnDat.detailResolution; iY++) {
  491.                                                                                 for(iX = 0; iX < trnDat.detailResolution; iX++) {
  492.                                                                                         if(detailPrototypes.length > 4) detLayer4[iX, iY] = Mathf.RoundToInt(pixels[i2].r * 16);
  493.                                                                                         if(detailPrototypes.length > 5) detLayer5[iX, iY] = Mathf.RoundToInt(pixels[i2].g * 16);
  494.                                                                                         if(detailPrototypes.length > 6) detLayer6[iX, iY] = Mathf.RoundToInt(pixels[i2].b * 16);
  495.                                                                                         if(detailPrototypes.length > 7) detLayer7[iX, iY] = Mathf.RoundToInt(pixels[i2].a * 16);
  496.                                                                                         i2 += 1;
  497.                                                                                 }
  498.                                                                         }
  499.                                                                 }
  500.                                                         }
  501.                                                         else if(file[i].length > 10 && file[i].Substring(0, 9) == "detailmap") {
  502.                                                                 whirld.statusTxt = "Downloading Terrain Detail Map (" + whirld.getURL(file[i].Substring(10)) + ")";
  503.                                                                 www = new WWW(whirld.getURL(file[i].Substring(10)));
  504.                                                                 while(!www.isDone) {
  505.                                                                         whirld.progress = www.progress;
  506.                                                                         yield new WaitForSeconds(.1);
  507.                                                                 }
  508.                                                                 if (www.error != null) whirld.info += "\nTerrain Detail Map Undownloadable: " + tName + " " + file[i].Substring(10) + " (" + www.error + ")";
  509.                                                                 else {
  510.                                                                         tex = www.texture;
  511.                                                                         pixels = www.texture.GetPixels();
  512.                                                                         trnDat.detailResolution = www.texture.width;
  513.                                                                         if(detailPrototypes.length > 0) var detLayer0 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 0);
  514.                                                                         if(detailPrototypes.length > 1) var detLayer1 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 1);
  515.                                                                         if(detailPrototypes.length > 2) var detLayer2 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 2);
  516.                                                                         if(detailPrototypes.length > 3) var detLayer3 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 3);
  517.                                                                         i2 = 0;
  518.                                                                         for(iY = 0; iY < trnDat.detailResolution; iY++) {
  519.                                                                                 for(iX = 0; iX < trnDat.detailResolution; iX++) {
  520.                                                                                         if(detailPrototypes.length > 0) detLayer0[iX, iY] = Mathf.RoundToInt(pixels[i2].r * 16);
  521.                                                                                         if(detailPrototypes.length > 1) detLayer1[iX, iY] = Mathf.RoundToInt(pixels[i2].g * 16);
  522.                                                                                         if(detailPrototypes.length > 2) detLayer2[iX, iY] = Mathf.RoundToInt(pixels[i2].b * 16);
  523.                                                                                         if(detailPrototypes.length > 3) detLayer3[iX, iY] = Mathf.RoundToInt(pixels[i2].a * 16);
  524.                                                                                         i2 += 1;
  525.                                                                                 }
  526.                                                                         }
  527.                                                                 }
  528.                                                         }
  529.                                                         else if(file[i] == "tree") { //Create new tree prototype
  530.                                                                 treeProto = new TreePrototype();
  531.                                                         }
  532.                                                         else if(file[i] == "detail") {
  533.                                                                 detailProto = new DetailPrototype();
  534.                                                         }
  535.                                                         else if(treeProto) {
  536.                                                                 if(file[i].Substring(0, 1) == "m") {
  537.                                                                         //treeProto.prefab = Resources.Load(file[i].Substring(2));
  538.                                                                         //treeProto.prefab = Game.Controller.prefab;
  539.                                                                         //prefab.AddComponent(MeshFilter);
  540.                                                                         //prefab.AddComponent(MeshRenderer);
  541.                                                                         if(objects.ContainsKey(file[i].Substring(2))) {
  542.                                                                                 treeProto.prefab = prefabs.Pop();
  543.                                                                                 treeProto.prefab.name = file[i].Substring(2);
  544.                                                                                 if(!treeProto.prefab.GetComponent(MeshFilter)) treeProto.prefab.AddComponent(MeshFilter);
  545.                                                                                 treeProto.prefab.GetComponent(MeshFilter).mesh = objects[file[i].Substring(2)].GetComponent(MeshFilter).mesh;
  546.                                                                                 if(!treeProto.prefab.GetComponent(MeshRenderer)) treeProto.prefab.AddComponent(MeshRenderer);
  547.                                                                                 treeProto.prefab.GetComponent(MeshRenderer).materials = objects[file[i].Substring(2)].GetComponent(MeshRenderer).materials;
  548.                                                                                 //treeProto.prefab = objects[file[i].Substring(2)];
  549.                                                                         }
  550.                                                                         else whirld.info += "\nTerrain Detail Mesh not found: " + file[i].Substring(2);
  551.                                                                 }
  552.                                                                 else if(file[i].Substring(0, 1) == "b") treeProto.bendFactor = parseFloat(file[i].Substring(2));
  553.                                                                 else if(file[i+1] == "") { //Read detail objects
  554.                                                                         var treedat : String[] = file[i].Split(";"[0]);
  555.                                                                         for(var tr : String in treedat) {
  556.                                                                                 if(!tr) continue;
  557.                                                                                 var tree = tr.Split(","[0]);
  558.                                                                                 if(!tree[0] || tree[0] == "") continue;
  559.                                                                                 var treeInstance = new TreeInstance();
  560.                                                                                 treeInstance.prototypeIndex = treePrototypes.length;
  561.                                                                                 treeInstance.position = Vector3(parseFloat(tree[0]), parseFloat(tree[1]), parseFloat(tree[2]));
  562.                                                                                 treeInstance.widthScale = parseFloat(tree[3]);
  563.                                                                                 treeInstance.heightScale = parseFloat(tree[4]);
  564.                                                                                 var c : float = Random.Range(.6, .7);
  565.                                                                                 treeInstance.color = Color(c - .15, c - .15, c - .15, 1);
  566.                                                                                 treeInstance.lightmapColor = Color(c + .15, c + .15, c + .15, 0);
  567.                                                                                 treeInstances.Add(treeInstance);
  568.                                                                         }
  569.                                                                 }
  570.                                                         }
  571.                                                         else if(detailProto) {
  572.                                                                 l = file[i].Split(" "[0]);
  573.                                                                 if(l[0] == "pO") {
  574.                                                                         if(objects.ContainsKey(l[1])) {
  575.                                                                                 //detailProto.prototype = objects[l[1]];
  576.                                                                                 detailProto.prototype = prefabs.Pop();
  577.                                                                                 detailProto.prototype.name = l[1];
  578.                                                                                 if(!detailProto.prototype.GetComponent(MeshFilter)) detailProto.prototype.AddComponent(MeshFilter);
  579.                                                                                 detailProto.prototype.GetComponent(MeshFilter).mesh = objects[l[1]].GetComponent(MeshFilter).mesh;
  580.                                                                                 if(!detailProto.prototype.GetComponent(MeshRenderer)) detailProto.prototype.AddComponent(MeshRenderer);
  581.                                                                                 detailProto.prototype.GetComponent(MeshRenderer).material = objects[l[1]].GetComponent(MeshRenderer).material;
  582.                                                                         }
  583.                                                                         else whirld.info += "\nTerrain Detail Mesh not found: " + l[1];
  584.                                                                 }
  585.                                                                 else if(l[0] == "pT") {
  586.                                                                         l[1] = whirld.getURL(l[1]);
  587.                                                                         whirld.statusTxt = "Downloading Terrain Detail Texture (" + l[1] + ")";
  588.                                                                         www = new WWW(l[1]);
  589.                                                                         while(!www.isDone) {
  590.                                                                                 whirld.progress = www.progress;
  591.                                                                                 yield new WaitForSeconds(.1);
  592.                                                                         }
  593.                                                                         if (www.error != null) whirld.info += "\nTerrain Detail Texture Undownloadable: " + l[1];
  594.                                                                         else {
  595.                                                                                 whirld.statusTxt = "Initializing " + vS[0] + "...";
  596.                                                                                 whirld.progress = 0;
  597.                                                                                 yield;
  598.                                                                                 mshTxt = new Texture2D(4, 4, TextureFormat.DXT5, true);
  599.                                                                                 www.LoadImageIntoTexture(mshTxt);
  600.                                                                                 mshTxt.Apply(true);
  601.                                                                                 mshTxt.Compress(true);
  602.                                                                                 mshTxt.wrapMode = TextureWrapMode.Clamp;
  603.                                                                                 detailProto.prototypeTexture = mshTxt;
  604.                                                                         }
  605.                                                                 }
  606.                                                                 else if(l[0] == "minW") detailProto.minWidth = parseFloat(l[1]);
  607.                                                                 else if(l[0] == "maxW") detailProto.maxWidth = parseFloat(l[1]);
  608.                                                                 else if(l[0] == "minH") detailProto.minHeight = parseFloat(l[1]);
  609.                                                                 else if(l[0] == "maxH") detailProto.maxHeight = parseFloat(l[1]);
  610.                                                                 else if(l[0] == "nS") detailProto.noiseSpread = parseFloat(l[1]);
  611.                                                                 else if(l[0] == "bF") detailProto.bendFactor = parseFloat(l[1]);
  612.                                                                 else if(l[0] == "hC") detailProto.healthyColor = Color(parseFloat(l[1]), parseFloat(l[2]), parseFloat(l[3]));
  613.                                                                 else if(l[0] == "dC") detailProto.dryColor = Color(parseFloat(l[1]), parseFloat(l[2]), parseFloat(l[3]));
  614.                                                                 else if(l[0] == "lF") detailProto.lightmapFactor = parseFloat(l[1]);
  615.                                                                 else if(l[0] == "gL") detailProto.grayscaleLighting = (l[1] == "1" ? true : false);
  616.                                                                 else if(l[0] == "rM") {
  617.                                                                         if(l[1] == "GrassBillboard") detailProto.renderMode = DetailRenderMode.GrassBillboard;
  618.                                                                         else if(l[1] == "VertexLit") detailProto.renderMode = DetailRenderMode.VertexLit;
  619.                                                                         else detailProto.renderMode = DetailRenderMode.Grass;
  620.                                                                 }
  621.                                                                 else if(l[0] == "uM") detailProto.usePrototypeMesh = (l[1] == "1" ? true : false);
  622.                                                         }
  623.                                                 }
  624.                                                 trnDat.treePrototypes = treePrototypes.ToBuiltin(TreePrototype);
  625.                                                 trnDat.treeInstances = treeInstances.ToBuiltin(TreeInstance);
  626.                                                 trnDat.detailPrototypes = detailPrototypes.ToBuiltin(DetailPrototype);
  627.                                                 if(detailPrototypes.length > 0) trnDat.SetDetailLayer(0, 0, 0, detLayer0);
  628.                                                 if(detailPrototypes.length > 1) trnDat.SetDetailLayer(0, 0, 1, detLayer1);
  629.                                                 if(detailPrototypes.length > 2) trnDat.SetDetailLayer(0, 0, 2, detLayer2);
  630.                                                 if(detailPrototypes.length > 3) trnDat.SetDetailLayer(0, 0, 3, detLayer3);
  631.                                                 if(detailPrototypes.length > 4) trnDat.SetDetailLayer(0, 0, 4, detLayer4);
  632.                                                 if(detailPrototypes.length > 5) trnDat.SetDetailLayer(0, 0, 5, detLayer5);
  633.                                                 if(detailPrototypes.length > 6) trnDat.SetDetailLayer(0, 0, 6, detLayer6);
  634.                                                 if(detailPrototypes.length > 7) trnDat.SetDetailLayer(0, 0, 7, detLayer7);
  635.                                                 //trnDat.RefreshPrototypes();
  636.                                                 //trnDat.RecalculateTreePositions();
  637.                                         }
  638.                                         /*for(i=0; i<trnDat.treePrototypes.length; i++) {
  639.                                                 trnDat.treePrototypes[i].prefab.name = trnDat.treePrototypes[i].prefab.name.Replace(" ", "_");
  640.                                                 MeshWriteObj(trnDat.treePrototypes[i].prefab.GetComponent(MeshFilter), trnDat.treePrototypes[i].prefab.name);
  641.                                                 whirld.data = "[msh:" + trnDat.treePrototypes[i].prefab.name + "," + trnDat.treePrototypes[i].prefab.name + ".obj.gz]" + whirld.data;
  642.                                                 trnV += (trnV != "" ? "\n\n" : "") + "tree\nm:" + trnDat.treePrototypes[i].prefab.name + "\nb:" + trnDat.treePrototypes[i].bendFactor + "\n";
  643.                                                 for(var tree : TreeInstance in trnDat.treeInstances) {
  644.                                                         if(tree.prototypeIndex != i) continue;
  645.                                                         trnV += tree.position.x.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "," + tree.position.y.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "," + tree.position.z.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "," + tree.widthScale.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "," + tree.heightScale.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + ";";
  646.                                                 }
  647.                                         }*/
  648.                                 }
  649.                                
  650.                                 //Go!
  651.                                 var trnObj : GameObject = new GameObject(tName);
  652.                                 trnObj.AddComponent(Terrain);
  653.                                 trnObj.GetComponent(Terrain).terrainData = trnDat;
  654.                                 trnObj.AddComponent(TerrainCollider);
  655.                                 trnObj.GetComponent(TerrainCollider).terrainData = trnDat;
  656.                                
  657.                                 objects.Add(tName, trnObj);
  658.                                 GameObject.Destroy(trnObj);
  659.                                 whirld.statusTxt = "";
  660.                         }
  661.                         i++;
  662.                 }
  663.                
  664.                 //Begin reading first object
  665.                 readObject(whirld.world.transform);
  666.                
  667.                 //Trash buffer objects
  668.                 GameObject.Destroy(whirldBuffer);
  669.                
  670.                 //Success!
  671.                 //whirld.info = "World Loaded";
  672.                 whirld.status = WorldLoadCode.Success;
  673.         }
  674.        
  675.         function readObject(parent : Transform) {
  676.                 var c : String;                                 //Character
  677.                 var i : int = 0;                                //Index of param
  678.                 var n : String = "";                    //Param name we are reading data for
  679.                 var v : String = "";                    //Value we are building
  680.                 var d : Array = new Array();    //Array of all values in current param data
  681.                 var obj : GameObject;                   //Object we have created
  682.                
  683.                 while(true) {
  684.                         if(readChr >= whirld.data.length) return;
  685.                        
  686.                         //Get Char
  687.                         s = whirld.data[readChr];
  688.                        
  689.                         //We just attempted to read past the end of the world data - the world file must have been malformed
  690.                         /*if(s == "") {
  691.                                 whirld.info = "Malformed World File";
  692.                                 whirld.status = WorldLoadCode.SyntaxError;
  693.                         }*/
  694.                        
  695.                         //Ignore spaces
  696.                         if(s == " " && false) { }
  697.                        
  698.                         //Name fully read, begin collecting param value(s)
  699.                         else if(s == ":") {
  700.                                 n = v;
  701.                                 v = "";
  702.                         }
  703.                        
  704.                         //Move to next section of value
  705.                         else if(s == ",") {
  706.                                 d.Add(v);
  707.                                 v = "";
  708.                         }
  709.                        
  710.                         //Begin recursively reading child object
  711.                         else if(s == "{") {
  712.                                 readChr += 1;
  713.                                 readObject(obj.transform);
  714.                                 continue;       //Continue to next obj once the child "thread" we just launched has finished parsing objects at it's level
  715.                         }
  716.                        
  717.                         //Assign current value to object, Begin reading new value
  718.                         else if(s == ";" || s == "}") {
  719.                        
  720.                                 //Object name just read, create object
  721.                                 if(!obj) {
  722.                                         if(objects.ContainsKey(v)) {
  723.                                                 if(objects[v] != null) var goP : GameObject = objects[v];
  724.                                                 else Debug.Log("Whirld: Objects[" + v + "] is null");
  725.                                                 //else goP = gameObject.Find();
  726.                                         }
  727.                                         else {
  728.                                                 goP = Resources.Load(v);
  729.                                                 if(goP) objects.Add(v, goP);
  730.                                         }
  731.                                         if(goP) {
  732.                                                 obj = GameObject.Instantiate(goP);
  733.                                                 obj.name = v;
  734.                                         }
  735.                                         else {
  736.                                                 obj = new GameObject(v);
  737.                                                 objects.Add(v, obj);
  738.                                         }
  739.                                         obj.transform.parent = parent;
  740.                                         var whirldObject : WhirldObject = obj.GetComponent(WhirldObject);
  741.                                         if(whirldObject) whirldObject.params = new Hashtable();
  742.                                         var lightSource : Light = obj.GetComponent(Light);
  743.                                 }
  744.                                
  745.                                 //Object already created, assign property to object
  746.                                 else {
  747.                                         if(n == "p" || (n == "" && i == 1)) obj.transform.localPosition = Vector3(parseFloat(d[0]), parseFloat(d[1]), parseFloat(v));
  748.                                         else if((n == "r" || (n == "" && i == 2)) && d.length == 3) obj.transform.rotation = Quaternion(parseFloat(d[0]), parseFloat(d[1]), parseFloat(d[2]), parseFloat(v));
  749.                                         else if((n == "r" || (n == "" && i == 2)) && d.length == 2) obj.transform.rotation = Quaternion.Euler(parseFloat(d[0]), parseFloat(d[1]), parseFloat(v));
  750.                                         else if((n == "r" || (n == "" && i == 2)) && d.length == 0) obj.transform.rotation = Quaternion.identity;
  751.                                         else if((n == "s" || (n == "" && i == 3)) && d.length == 0) obj.transform.localScale = Vector3.one * parseFloat(v);
  752.                                         else if(n == "s" || (n == "" && i == 3)) obj.transform.localScale = Vector3(parseFloat(d[0]), parseFloat(d[1]), parseFloat(v));
  753.                                         else if(n == "cc") {
  754.                                                 obj.AddComponent(CombineChildren);
  755.                                                 whirld.worldParams["ccc"] = 1;
  756.                                                 //if(!whirld.worldParams.ContainsKey("cc")) whirld.worldParams.Add("cc", 0);
  757.                                         }
  758.                                         else if(n == "m") {
  759.                                                 d.Add(v);
  760.                                                 MeshRead(obj, d);
  761.                                         }
  762.                                         else if(lightSource && n == "color") {
  763.                                                 lightSource.color.r = parseFloat(d[0]);
  764.                                                 lightSource.color.g = parseFloat(d[1]);
  765.                                                 lightSource.color.b = parseFloat(v);
  766.                                         }
  767.                                         else if(lightSource && n == "intensity") lightSource.intensity = parseFloat(v);
  768.                                         else {
  769.                                                 if(whirldObject) whirldObject.params.Add(n, v);
  770.                                         }
  771.                                 }
  772.                                                                
  773.                                 //Reset properties
  774.                                 v = "";
  775.                                 n = "";
  776.                                 if(d.length > 0) d = new Array();
  777.                                 i += 1;
  778.                                
  779.                                 //Done reading this object
  780.                                 if(s == "}") {
  781.                                         //Finish up this object
  782.                                         if(obj.name == "cube" || obj.name == "pyramid" || obj.name == "cone" || obj.name == "mesh") {
  783.                                                 whirld.TextureGO(obj);
  784.                                         }
  785.                                         var renderer : MeshRenderer = obj.GetComponent(MeshRenderer);
  786.                                         if(renderer && (renderer.material == null || renderer.material.name == "Default-Diffuse (Instance)")) renderer.material = whirld.defaultMaterial;
  787.                                         //Debug.Log(renderer.material);
  788.                                        
  789.                                         //Increment ReadChar
  790.                                         readChr += 1;
  791.                                        
  792.                                         //Read the next object
  793.                                         if(readChr < whirld.data.length && whirld.data[readChr] == "{") {
  794.                                                 readChr += 1;
  795.                                                 readObject(parent);
  796.                                                 return;
  797.                                         }
  798.                                        
  799.                                         //Done reading objects at this level of recursion
  800.                                         else {
  801.                                                 return;
  802.                                         }
  803.                                 }
  804.                         }
  805.                        
  806.                         //Assign char to property we are reading
  807.                         else {
  808.                                 if(n) v += s;   //Building value
  809.                                 else n += s;    //Building name
  810.                         }
  811.                         readChr += 1;
  812.                 }
  813.         }
  814.        
  815.         function Save() {
  816.                 whirld.data += "[rndFogColor:" + RenderSettings.fogColor.r + "," + RenderSettings.fogColor.g + "," + RenderSettings.fogColor.b + "]";
  817.                 whirld.data += "[rndFogDensity:" + RenderSettings.fogDensity + "]";
  818.                 whirld.data += "[rndAmbientLight:" + RenderSettings.ambientLight.r + "," + RenderSettings.ambientLight.g + "," + RenderSettings.ambientLight.b + "," + RenderSettings.ambientLight.a + "]";
  819.                
  820.                 //This thing has WorldData - grab it!
  821.                 var whirldObject : WhirldObject = whirld.world.GetComponent(WhirldObject);
  822.                 if(whirldObject) for (var dat : WhirldData in whirldObject.data) {
  823.                         whirld.data += "[" + dat.n + ":" + dat.v + "]";
  824.                 }
  825.                
  826.                 var objects : Hashtable = new Hashtable();
  827.                 Save(null);
  828.                
  829.                 var t : String = "";
  830.                 for(var de : DictionaryEntry in materials) {
  831.                         var mat : Material = de.Value;
  832.                         t += "\n\nnewmtl " + mat.name + "\nKa " + mat.color.r + " " + mat.color.g + " " + mat.color.b;
  833.                         if(mat.HasProperty("_Emission")) {
  834.                                 var col : Color = mat.GetColor("_Emission");
  835.                                 t += "\nKd " + col.r + " " + col.g + " " + col.b;
  836.                         }
  837.                         if(mat.HasProperty("_SpecColor")) {
  838.                                 col = mat.GetColor("_SpecColor");
  839.                                 t += "\nKs " + col.r + " " + col.g + " " + col.b;
  840.                         }
  841.                         if(mat.HasProperty("_Shininess")) t += "\nNs " + mat.GetFloat("_Shininess");
  842.                         if(mat.mainTexture) {
  843.                                 //var file : String = EditorUtility.GetAssetPath(mat.mainTexture);
  844.                                 //var fName : String = file.Substring(file.LastIndexOf("/") + 1);
  845.                                 //File.Copy(file, whirld.path + fName);
  846.                                 File.WriteAllBytes(whirld.path + mat.name + ".png", mat.mainTexture.EncodeToPNG());
  847.                                 t += "\nmap_Ka -o " + mat.mainTextureOffset.x + " " + mat.mainTextureOffset.y + " -s " + mat.mainTextureScale.x + " " + mat.mainTextureScale.y + " " + mat.name + /*(mat.mainTexture.format == TextureFormat.ARGB32 ? ".png" : ".jpg")*/ ".jpg";
  848.                         }
  849.                         t += "\n#Shader " + mat.shader.name;
  850.                         if(mat.HasProperty("_BaseLight")) t += "\n#BaseLight " + mat.GetFloat("_BaseLight");
  851.                         if(mat.HasProperty("_AO")) t += "\n#AO " + mat.GetFloat("_AO");
  852.                         if(mat.HasProperty("_Occlusion")) t += "\n#Occlusion " + mat.GetFloat("_Occlusion");
  853.                         if(mat.HasProperty("_Cutoff")) t += "\n#Cutoff " + mat.GetFloat("_Cutoff");
  854.                         //t += "\nillum " + (mat.HasProperty("_SpecColor") ? 2 : 1);
  855.                 }
  856.                 if(t != "") System.IO.File.WriteAllText(whirld.path + "Whirld.mtl", "#Unity3D Whirld Materials" + t);
  857.         }
  858.        
  859.         function Save(trobj : Transform) {
  860.                 for (var tr : Transform in (trobj == null ? whirld.world.transform : trobj)) {
  861.                         //Sanitize Names
  862.                         tr.gameObject.name = tr.gameObject.name.Replace(" ","_");
  863.                         var light : Light = tr.gameObject.GetComponent(Light);
  864.                         if(light) tr.gameObject.name = "Light";
  865.                        
  866.                         //Save boilerplate object data
  867.                     whirld.data += "{" + tr.gameObject.name + ";" + tr.localPosition.x.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + "," + tr.localPosition.y.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + "," + tr.localPosition.z.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + ";" + (tr.rotation == Quaternion.identity ? "0" : tr.rotation.eulerAngles.x.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + "," + tr.rotation.eulerAngles.y.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + "," + tr.rotation.eulerAngles.z.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) /*+ "," + tr.rotation.w*/) + ";" + (tr.localScale == Vector3.one ? 1 : tr.localScale.x.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + "," + tr.localScale.y.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + "," + tr.localScale.z.ToString("F3", System.Globalization.CultureInfo.InvariantCulture));
  868.                    
  869.                     //This thing hasn't been previously encountered
  870.                     if(!objects.ContainsKey(tr.gameObject.name)) {
  871.                        
  872.                         //Check for CombineChildren
  873.                         var combineChildren : CombineChildren = tr.gameObject.GetComponent(CombineChildren);
  874.                                 if(CombineChildren) whirld.data += ";cc:1";
  875.                        
  876.                         //This thing has WorldData - grab it!
  877.                                 var whirldObject : WhirldObject = tr.gameObject.GetComponent(WhirldObject);
  878.                                 if(whirldObject) for (var dat : WhirldData in whirldObject.data) {
  879.                                         whirld.data += ";" + dat.n + ":" + dat.v;
  880.                                 }
  881.                                
  882.                                 //This thing is a light source - save it's properties!
  883.                                 if(light) {
  884.                                         whirld.data += ";color:" + light.color.r + "," + light.color.g + "," + light.color.b + ";intensity:" + light.intensity;
  885.                                 }
  886.  
  887.                                 //This thing is not a defined resource
  888.                                 goP = Resources.Load(tr.gameObject.name);
  889.                                 if(!goP) {
  890.                                                                                
  891.                                         //This thing has a mesh - include it!
  892.                                         var mF : MeshFilter = tr.gameObject.GetComponent(MeshFilter);
  893.                                         var mR : MeshRenderer = tr.gameObject.GetComponent(MeshRenderer);
  894.                                     var mC : MeshCollider = tr.gameObject.GetComponent(MeshCollider);
  895.                                         if(mF && mR.enabled) {
  896.                                                 //whirld.data += ";m:" + MeshWrite(mF);
  897.                                                 //whirld.data += ";ms:/" + tr.gameObject.name;
  898.                                         //whirld.data += ";ms:" + String(System.Text.Encoding.ASCII.GetChars(MeshSerializer.WriteMesh(mF.mesh, false)));
  899.                                         /*whirld.data = "[msh:" + tr.gameObject.name + ",http://domain.com/" + tr.gameObject.name + ".utm]" + whirld.data;
  900.                                                 MeshSerializer.WriteMeshToFileForWeb(mF.mesh, tr.gameObject.name + ".utm", false);*/
  901.                                                 MeshWriteObj(mF, tr.gameObject.name);
  902.                                                 whirld.data = "[msh:" + tr.gameObject.name + "," + tr.gameObject.name + ".obj.gz" + ((!mC || !mC.sharedMesh) ? ",-1" : "") + "]" + whirld.data;
  903.                                     }
  904.                                    
  905.                                         if(mC && mC.sharedMesh) {
  906.                                                 if(!mF || !mR.enabled || mC.sharedMesh != mF.sharedMesh) {
  907.                                                         m = mC.sharedMesh;
  908.                                                         mD = "#Unity3D Whirld Collider\n\ng " + m.name + "\n";
  909.                                                         for(var v : Vector3 in m.vertices) mD += "v " + (-v.x).ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + " " + v.y.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + " " + v.z.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + "\n";
  910.                                                         mD += "\n";
  911.                                                         for(var v : Vector3 in m.normals) mD += "vn " + (-v.x).ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + " " + v.y.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + " " + v.z.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + "\n";
  912.                                                         mD += "\n";
  913.                                                         for(var v : Vector3 in m.uv) mD += "vt " + v.x.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + " " + v.y.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + "\n";
  914.                                                         mD += "\n";
  915.                                                         for (i=0; i<m.triangles.Length; i+=3) mD += "f " + (m.triangles[i+1]+1) + "/" + (m.triangles[i+1]+1) + "/" + (m.triangles[i+1]+1) + " " + (m.triangles[i]+1) + "/" + (m.triangles[i]+1) + "/" + (m.triangles[i]+1) + " " + (m.triangles[i+2]+1) + "/" + (m.triangles[i+2]+1) + "/" + (m.triangles[i+2]+1) + "\n";
  916.                                                         File.WriteAllBytes(whirld.path + tr.gameObject.name + "cldr.obj.gz", new Ionic.Zlib.GZipStream(new MemoryStream(), Ionic.Zlib.CompressionMode.Compress, 9).CompressString(mD));
  917.                                                         whirld.data = "[msh:" + tr.gameObject.name + "," + tr.gameObject.name + "cldr.obj.gz,1]" + whirld.data;
  918.                                                 }
  919.                                         }
  920.                                    
  921.                                     //This is a terrain object! Save it's heightmap, lightmap, and splatmap
  922.                                     var trn : Terrain = tr.gameObject.GetComponent(Terrain);
  923.                                         if(trn) {
  924.                                                 var trnRes : String;
  925.                                                 var trnDat : TerrainData = trn.terrainData;
  926.                                                 //Save Heightmap
  927.                                                 var hmap = trnDat.GetHeights(0, 0, trnDat.heightmapWidth, trnDat.heightmapHeight);
  928.                                                 ms = new MemoryStream();
  929.                                                 var br : BinaryWriter = new BinaryWriter(ms);
  930.                                         for (var x : int = 0; x < trnDat.heightmapWidth; x++) for (var y : int = 0; y < trnDat.heightmapHeight; y++) {
  931.                                                 var val : System.UInt16 = hmap[x, y] * 65535;
  932.                                                 br.Write(val);
  933.                                         }
  934.                                         var buffer : byte[] = ms.ToArray();
  935.                                         File.WriteAllBytes(whirld.path + tr.gameObject.name + ".gz", new Ionic.Zlib.GZipStream(ms, Ionic.Zlib.CompressionMode.Compress, 9).CompressBuffer(buffer));
  936.                                         trnRes += ";h:" + tr.gameObject.name + ".gz";
  937.                                                 //Save Lightmap
  938.                                                 if(trnDat.lightmap) {
  939.                                                         File.WriteAllBytes(whirld.path + tr.gameObject.name + "l.png", trnDat.lightmap.EncodeToPNG());
  940.                                                         trnRes += ";l:" + tr.gameObject.name + "l.png";
  941.                                                 }
  942.                                                 //Save Splatmap
  943.                                                 var sMap = trnDat.GetAlphamaps(0, 0, trnDat.alphamapWidth, trnDat.alphamapHeight);
  944.                                                 var sTxt : Texture2D = new Texture2D(trnDat.alphamapWidth, trnDat.alphamapHeight, TextureFormat.ARGB32, false);
  945.                                                 for (y = 0; y < trnDat.alphamapWidth; y++) for (x = 0; x < trnDat.alphamapHeight; x++) sTxt.SetPixel(y, x, Vector4((trnDat.alphamapLayers > 0 ? sMap[x,y,0] : 0), (trnDat.alphamapLayers > 1 ? sMap[x,y,1] : 0), (trnDat.alphamapLayers > 2 ? sMap[x,y,2] : 0), (trnDat.alphamapLayers > 3 ? sMap[x,y,3] : 0)));
  946.                                                 sTxt.Apply(false);
  947.                                                 File.WriteAllBytes(whirld.path + tr.gameObject.name + "s.png", sTxt.EncodeToPNG());
  948.                                                 trnRes += ";s:" + tr.gameObject.name + "s.png";
  949.                                                 if(trnDat.alphamapLayers > 4) { //Save Second Splat Map if there are more than 4 textures applied to this terrain
  950.                                                         sTxt = new Texture2D(trnDat.alphamapWidth, trnDat.alphamapHeight, TextureFormat.ARGB32, false);
  951.                                                         for (y = 0; y < trnDat.alphamapWidth; y++) for (x = 0; x < trnDat.alphamapHeight; x++) sTxt.SetPixel(y, x, Vector4((trnDat.alphamapLayers > 4 ? sMap[x,y,4] : 0), (trnDat.alphamapLayers > 5 ? sMap[x,y,5] : 0), (trnDat.alphamapLayers > 6 ? sMap[x,y,6] : 0), (trnDat.alphamapLayers > 7 ? sMap[x,y,7] : 0)));
  952.                                                         sTxt.Apply(false);
  953.                                                         File.WriteAllBytes(whirld.path + tr.gameObject.name + "s2.png", sTxt.EncodeToPNG());
  954.                                                         trnRes += ";s2:" + tr.gameObject.name + "s2.png";
  955.                                                 }
  956.                                                 //if(trnDat.splatPrototypes[0].texture.format == TextureFormat.RGB24) {
  957.                                                         trnRes += ";t:";
  958.                                                         for(i=0; i < trnDat.alphamapLayers; i++) {
  959.                                                                 trnRes += (i > 0 ? "," : "") + tr.gameObject.name + "" + i + ".jpg=" + trnDat.splatPrototypes[i].tileSize.x + "x" + trnDat.splatPrototypes[i].tileSize.y;
  960.                                                                 if(trnDat.splatPrototypes[0].texture.format == TextureFormat.RGB24) File.WriteAllBytes(whirld.path + tr.gameObject.name + "" + i + ".png", trnDat.splatPrototypes[i].texture.EncodeToPNG());
  961.                                                                 /*image = Image.FromFile(whirld.path + tr.gameObject.name + "" + i + "o.png");
  962.                                                                 foreach (var info : ImageCodecInfo in ImageCodecInfo.GetImageEncoders()) if (info.FormatDescription == "JPEG") {
  963.                                                                         var encoder = info;
  964.                                                                         break;
  965.                                                                 }
  966.                                                                 var parms : EncoderParameters = new EncoderParameters(1);
  967.                                                                 parms.Param[0] = new EncoderParameter(Encoder.Compression, 40);
  968.                                                                 image.Save(whirld.path + tr.gameObject.name + "" + i + ".png", jpegEncoder, parms);*/
  969.                                                         }
  970.                                                 //}
  971.                                                 //Save Trees
  972.                                                 var trnV = "";
  973.                                                 for(i=0; i<trnDat.treePrototypes.length; i++) {
  974.                                                         trnDat.treePrototypes[i].prefab.name = trnDat.treePrototypes[i].prefab.name.Replace(" ", "_");
  975.                                                         MeshWriteObj(trnDat.treePrototypes[i].prefab.GetComponent(MeshFilter), trnDat.treePrototypes[i].prefab.name);
  976.                                                         whirld.data = "[msh:" + trnDat.treePrototypes[i].prefab.name + "," + trnDat.treePrototypes[i].prefab.name + ".obj.gz]" + whirld.data;
  977.                                                         trnV += (trnV != "" ? "\n\n" : "") + "tree\nm:" + trnDat.treePrototypes[i].prefab.name + "\nb:" + trnDat.treePrototypes[i].bendFactor + "\n";
  978.                                                         for(var tree : TreeInstance in trnDat.treeInstances) {
  979.                                                                 if(tree.prototypeIndex != i) continue;
  980.                                                                 trnV += tree.position.x.ToString("F6", System.Globalization.CultureInfo.InvariantCulture) + "," + tree.position.y.ToString("F6", System.Globalization.CultureInfo.InvariantCulture) + "," + tree.position.z.ToString("F6", System.Globalization.CultureInfo.InvariantCulture) + "," + tree.widthScale.ToString("F6", System.Globalization.CultureInfo.InvariantCulture) + "," + tree.heightScale.ToString("F6", System.Globalization.CultureInfo.InvariantCulture) + ";";
  981.                                                         }
  982.                                                 }
  983.                                                 //Save Details
  984.                                                 if(trnDat.detailPrototypes.length > 0) {
  985.                                                         for(i=0; i<trnDat.detailPrototypes.length; i++) {
  986.                                                                 var dP : DetailPrototype = trnDat.detailPrototypes[i];
  987.                                                                 if(dP.prototype) dP.prototype.name = dP.prototype.name.Replace(" ", "_");
  988.                                                                 trnV += (trnV != "" ? "\n\n" : "") + "detail";
  989.                                                                 if(dP.prototype) {
  990.                                                                         trnV += "\npO " + dP.prototype.name;
  991.                                                                         MeshWriteObj(dP.prototype.GetComponent(MeshFilter), dP.prototype.name);
  992.                                                                         whirld.data = "[msh:" + dP.prototype.name + "," + dP.prototype.name + ".obj.gz]" + whirld.data;
  993.                                                                 }
  994.                                                                 else {
  995.                                                                         trnV += "\npT " + dP.prototypeTexture.name + ".png";
  996.                                                                         if(dP.prototypeTexture.format == TextureFormat.ARGB32) File.WriteAllBytes(whirld.path + dP.prototypeTexture.name + ".png", dP.prototypeTexture.EncodeToPNG());
  997.                                                                 }
  998.                                                                 trnV += "\nminW " + dP.minWidth;
  999.                                                                 trnV += "\nmaxW " + dP.maxWidth;
  1000.                                                                 trnV += "\nminH " + dP.minHeight;
  1001.                                                                 trnV += "\nmaxH " + dP.maxHeight;
  1002.                                                                 trnV += "\nnS" + dP.noiseSpread;
  1003.                                                                 trnV += "\nbF " + dP.bendFactor;
  1004.                                                                 trnV += "\nhC " + dP.healthyColor.r + " " + dP.healthyColor.g + " " + dP.healthyColor.b;
  1005.                                                                 trnV += "\ndC " + dP.dryColor.r + " " + dP.dryColor.g + " " + dP.dryColor.b;
  1006.                                                                 trnV += "\nlF " + dP.lightmapFactor;
  1007.                                                                 trnV += "\ngL " + (dP.grayscaleLighting ? 1 : 0);
  1008.                                                                 trnV += "\nrM " + dP.renderMode;
  1009.                                                                 trnV += "\nuM " + (dP.usePrototypeMesh ? 1 : 0);
  1010.                                                         }
  1011.                                                         var detLayer0 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 0);
  1012.                                                         if(trnDat.detailPrototypes.length > 1) var detLayer1 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 1);
  1013.                                                         if(trnDat.detailPrototypes.length > 2) var detLayer2 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 2);
  1014.                                                         if(trnDat.detailPrototypes.length > 3) var detLayer3 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 3);
  1015.                                                         if(trnDat.detailPrototypes.length > 4) var detLayer4 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 4);
  1016.                                                         if(trnDat.detailPrototypes.length > 5) var detLayer5 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 5);
  1017.                                                         if(trnDat.detailPrototypes.length > 6) var detLayer6 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 6);
  1018.                                                         if(trnDat.detailPrototypes.length > 7) var detLayer7 = trnDat.GetDetailLayer(0, 0, trnDat.detailResolution, trnDat.detailResolution, 7);
  1019.                                                        
  1020.                                                         //Save DetailMap
  1021.                                                         var pixels : Array = new Array();
  1022.                                                         for(var iY : int = 0; iY < trnDat.detailResolution; iY++) {
  1023.                                                                 for(var iX : int = 0; iX < trnDat.detailResolution; iX++) {
  1024.                                                                         var r : float = (trnDat.detailPrototypes.length > 0 ? detLayer0[iX, iY] : 0);
  1025.                                                                         var g : float = (trnDat.detailPrototypes.length > 1 ? detLayer1[iX, iY] : 0);
  1026.                                                                         var b : float = (trnDat.detailPrototypes.length > 2 ? detLayer2[iX, iY] : 0);
  1027.                                                                         var a : float = (trnDat.detailPrototypes.length > 3 ? detLayer3[iX, iY] : 0);
  1028.                                                                         pixels.Add(new Color(r / 16, g / 16, b / 16, a / 16));
  1029.                                                                 }
  1030.                                                         }
  1031.                                                         var tex : Texture2D = new Texture2D (trnDat.detailResolution, trnDat.detailResolution, TextureFormat.ARGB32, false);
  1032.                                                         tex.SetPixels(pixels.ToBuiltin(Color),0);
  1033.                                                         tex.Apply(false);
  1034.                                                         File.WriteAllBytes(whirld.path + tr.gameObject.name + "d.png", tex.EncodeToPNG());
  1035.                                                         trnV += "\n\ndetailmap " + tr.gameObject.name + "d.png";
  1036.                                                        
  1037.                                                         //Save 2nd DetailMap
  1038.                                                         if(trnDat.detailPrototypes.length > 4) {
  1039.                                                                 pixels = new Array();
  1040.                                                                 for(iY = 0; iY < trnDat.detailResolution; iY++) {
  1041.                                                                         for(iX = 0; iX < trnDat.detailResolution; iX++) {
  1042.                                                                                 r = (trnDat.detailPrototypes.length > 4 ? detLayer4[iX, iY] : 0);
  1043.                                                                                 g = (trnDat.detailPrototypes.length > 5 ? detLayer5[iX, iY] : 0);
  1044.                                                                                 b = (trnDat.detailPrototypes.length > 6 ? detLayer6[iX, iY] : 0);
  1045.                                                                                 a = (trnDat.detailPrototypes.length > 7 ? detLayer7[iX, iY] : 0);
  1046.                                                                                 pixels.Add(new Color(r / 16, g / 16, b / 16, a / 16));
  1047.                                                                         }
  1048.                                                                 }
  1049.                                                                 tex = new Texture2D (trnDat.detailResolution, trnDat.detailResolution, TextureFormat.ARGB32, false);
  1050.                                                                 tex.SetPixels(pixels.ToBuiltin(Color),0);
  1051.                                                                 tex.Apply(false);
  1052.                                                                 File.WriteAllBytes(whirld.path + tr.gameObject.name + "d2.png", tex.EncodeToPNG());
  1053.                                                                 trnV += "\n\ndetailmap2 " + tr.gameObject.name + "d2.png";
  1054.                                                         }
  1055.                                                        
  1056.                                                         //Save Detail File
  1057.                                                         File.WriteAllBytes(whirld.path + tr.gameObject.name + ".utd.gz", new Ionic.Zlib.GZipStream(ms, Ionic.Zlib.CompressionMode.Compress, 9).CompressString(trnV));
  1058.                                                         trnRes += ";d:" + tr.gameObject.name + ".utd.gz";
  1059.                                                 }
  1060.                                                 //Add terrain resource to world assets list
  1061.                                                 whirld.data = "[trn:" + tr.gameObject.name + ";r:" + trnDat.size.x + "," + trnDat.size.y + "," + trnDat.size.z + "," + trnDat.heightmapWidth + trnRes + "]" + whirld.data;
  1062.                                         }
  1063.                                    
  1064.                                     //Look for children objects to save
  1065.                                         Save(tr);
  1066.                                 }
  1067.                                 objects.Add(tr.gameObject.name, goP);
  1068.                         }
  1069.                     whirld.data += "}";
  1070.                 }
  1071.                
  1072.                 if(trobj == null) {
  1073.                         whirld.info = "World Saved";
  1074.                         whirld.status = WorldLoadCode.Success;
  1075.                 }
  1076.         }
  1077. }
  1078.  
  1079. function MeshRead(o : GameObject, dat : Array) {
  1080.         var m : Mesh = new Mesh();
  1081.         var vertices : Array = new Array();
  1082.         var normals : Array = new Array();
  1083.         var uv : Array = new Array();
  1084.         for(var str : String in dat) {
  1085.                 var s = str.Split(" "[0]);
  1086.                 if(s[0] == "v")                 vertices.Add(Vector3(parseFloat(s[1]), parseFloat(s[2]), parseFloat(s[3])));
  1087.                 else if(s[0] == "n")    normals.Add(Vector3(parseFloat(s[1]), parseFloat(s[2]), parseFloat(s[3])));
  1088.                 else if(s[0] == "u")    uv.Add(Vector2(parseFloat(s[1]), parseFloat(s[2])));
  1089.                 else if(s[0] == "t") {
  1090.                         var i = 1;
  1091.                         var triangles : int[] = new int[s.length - 1];
  1092.                         while(i < s.length) {
  1093.                                 triangles[i - 1] = parseInt(s[i]);
  1094.                                 i++;
  1095.                         }
  1096.                 }
  1097.         }
  1098.        
  1099.         m.vertices = vertices;
  1100.         m.normals = normals;
  1101.         m.uv = uv;
  1102.         m.triangles = triangles;
  1103.        
  1104.         //m.RecalculateBounds();
  1105.         //m.RecalculateNormals();
  1106.         //m.Optimize();
  1107.        
  1108.         o.AddComponent(MeshFilter);
  1109.         o.GetComponent(MeshFilter).mesh = m;
  1110.         o.AddComponent(MeshRenderer);
  1111.         o.AddComponent(MeshCollider);
  1112.         o.GetComponent(MeshCollider).mesh = m; 
  1113. }
  1114.  
  1115. function MeshWrite(mf : MeshFilter) {
  1116.         var m : Mesh = mf.mesh;
  1117.         var mats : Material[] = mf.renderer.sharedMaterials;
  1118.         var s : String = "";
  1119.        
  1120.         for(var v : Vector3 in m.vertices)      s += "v " + v.x + " " + v.y + " " + v.z + ",";
  1121.         for(var v : Vector3 in m.normals)       s += "n " + v.x + " " + v.y + " " + v.z + ",";
  1122.         for(var v : Vector3 in m.uv)            s += "u " + v.x + " " + v.y + " " + v.z + ",";
  1123.         s += "t";
  1124.         for(var t : int in m.triangles)         s += " " + t;
  1125.        
  1126.         /*
  1127.         for(int material=0; material < m.subMeshCount; material ++) {
  1128.                 s += "m " + mats[material].name + ",";
  1129.             int[] triangles = m.GetTriangles(material);
  1130.             for (int i=0;i<triangles.Length;i+=3) {
  1131.                 sb.Append(string.Format("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}\n",
  1132.                     triangles[i]+1, triangles[i+1]+1, triangles[i+2]+1));
  1133.             }
  1134.         }*/
  1135.        
  1136.         return s;
  1137. }
  1138.  
  1139. function MeshWriteObj(mF : MeshFilter, name : String) {
  1140.         var m : Mesh = mF.sharedMesh;
  1141.         var mats : Material[]  = mF.renderer.sharedMaterials;
  1142.         var mD : String = "#Unity3D Whirld Object\n\nmtllib Whirld.mtl\n\ng " + mF.name + "\n";
  1143.         for(var v : Vector3 in m.vertices) mD += "v " + (-v.x).ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + " " + v.y.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + " " + v.z.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + "\n";
  1144.         mD += "\n";
  1145.         for(var v : Vector3 in m.normals) mD += "vn " + (-v.x).ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + " " + v.y.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + " " + v.z.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + "\n";
  1146.         mD += "\n";
  1147.         for(var v : Vector3 in m.uv) mD += "vt " + v.x.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + " " + v.y.ToString("F3", System.Globalization.CultureInfo.InvariantCulture) + "\n";
  1148.         for (var material : int = 0; material < m.subMeshCount; material ++) {
  1149.                 if(!materials.ContainsKey(mats[material].name)) materials.Add(mats[material].name, mats[material]);
  1150.             mD += "\nusemtl " + mats[material].name + "\n";
  1151.             var triangles : int[]  = m.GetTriangles(material);
  1152.             for (i=0; i<triangles.Length; i+=3) mD += "f " + (triangles[i+1]+1) + "/" + (triangles[i+1]+1) + "/" + (triangles[i+1]+1) + " " + (triangles[i]+1) + "/" + (triangles[i]+1) + "/" + (triangles[i]+1) + " " + (triangles[i+2]+1) + "/" + (triangles[i+2]+1) + "/" + (triangles[i+2]+1) + "\n";
  1153.         }
  1154.         var ms : MemoryStream = new MemoryStream();
  1155.         File.WriteAllBytes(whirld.path + name + ".obj.gz", new Ionic.Zlib.GZipStream(ms, Ionic.Zlib.CompressionMode.Compress, 9).CompressString(mD));
  1156. }
  1157.  
  1158. function ReadWWW(www : WWW) {
  1159.         /*if(Application.isPlaying) {
  1160.                 whirldCoroutine = whirld.world.GetComponent(WhirldCoroutine);
  1161.                 if(!whirldCoroutine) {  //Create a MonoBehaviour which we can use to yield stuff
  1162.                         whirld.world.AddComponent(WhirldCoroutine);
  1163.                         whirldCoroutine = whirld.world.GetComponent(WhirldCoroutine);
  1164.                 }
  1165.                 //whirldCoroutine.StartCoroutine(whirldCoroutine.WWWLoad(www, whirld));
  1166.                 whirldCoroutine.WWWLoad(www, whirld);
  1167.         }
  1168.         else {
  1169.                 while(!www.isDone) whirld.progress = www.progress;
  1170.                 //while(!www.isDone) EditorUtility.DisplayProgressBar("Loading UTW World", whirld.statusTxt, www.progress);
  1171.                 //EditorUtility.ClearProgressBar();
  1172.         }*/
  1173.         while(!www.isDone) {
  1174.                 whirld.progress = www.progress;
  1175.                 yield new WaitForSeconds(.1);
  1176.         }
  1177. }

Whirld 2

by Aubrey Falconer