Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Source Code - Using 64k NASA Earth Texture (65536 x 32768 pixel)

Discussion in 'Scripting' started by apple_motion, Apr 26, 2011.

  1. apple_motion

    apple_motion

    Joined:
    Jul 2, 2009
    Posts:
    169
    Remember back to the mid of 2009, when I study the unity in the first time, I did the following conceptual demo.
    http://www.youtube.com/watch?v=Wlxp7mBIh4c

    As I mentioned in the youtube, that was in the 'early' stage of development. Until now. that still in the 'early' stage since I don't have time to touch them.... :p. Anyway, from the following are the complete source code for the demo and that have been rewritten for unity 3.x free version (and iOS basic). The performance are not great yet, but at least that is without any memory leak even to load-in and out thousands of images.

    [web-player demo]
    http://homepage.mac.com/antonioh/unity3d/build/MapObject_v009_web/MapObject_v009_web.html

    Startup.Js // the only script to attach to a empty gameObject
    Code (csharp):
    1. #pragma strict
    2. #pragma implicit
    3. #pragma downcast
    4.  
    5. var debug:boolean    = false;
    6. var animated:boolean = true;
    7.  
    8. private var gBank:int = 0;
    9. private var ws_rot:Vector4 = Vector4(0,0,0);
    10.  
    11. function Start()
    12. {  
    13.     build_map(transform, 0, "A1", Vector3(3,0,0));
    14.     build_map(transform, 2, "B1", Vector3(0,0,0));
    15.     build_map(transform, 4, "C1", Vector3(1,0,0));
    16.     build_map(transform, 6, "D1", Vector3(2,0,0));
    17.    
    18.     build_map(transform, 1, "A2", Vector3(3,1,0));
    19.     build_map(transform, 3, "B2", Vector3(0,1,0));
    20.     build_map(transform, 5, "C2", Vector3(1,1,0));
    21.     build_map(transform, 7, "D2", Vector3(2,1,0));
    22. }
    23. function build_map(parent:Transform, bank:int, name:String, pos:Vector3):GameObject
    24. {
    25.     var p = new GameObject();
    26.     p.name = name;
    27.     p.transform.parent = parent;
    28.     p.transform.localPosition = pos;
    29.     //new MapObject(g.transform, "seed", bank, 0, 0, 0, 0);
    30.    
    31.     return MapObject.create_cell(p.transform, "seed", bank, 0, 0, 0, 0);
    32. }
    33. function FixedUpdate()
    34. {
    35.     if(animated)
    36.     {
    37.         var t: float = Time.time;
    38.         var ct = Camera.main.transform;    
    39.         ct.position.z = -cos(t/27)/1.5 -0.7;
    40.         ct.position.x = -cos(t/19*ct.position.z) +2;
    41.         ct.position.y = sin(t/31*ct.position.z)/2 +1;
    42.        
    43.         Camera.main.farClipPlane = -ct.position.z+0.01;
    44.     }
    45.    
    46.     MapObject.debug = debug;
    47. }
    48. //----- helper
    49. private var  _log   = Debug().Log;
    50. private var sin     = Mathf().Sin;
    51. private var cos     = Mathf().Cos;
    52. private var pow     = Mathf().Pow;
    MapObject.js // The main class
    Code (csharp):
    1. #pragma strict
    2. #pragma implicit
    3. #pragma downcast
    4.  
    5. class MapObject
    6. {
    7.     //----- setup
    8.     var gameObject:GameObject;  // MUST
    9.     var parent:Transform;       // MUST
    10.     var gType:  String;         // MUST
    11.     var gBank:  int;            // MUST
    12.     var gLevel: int;            // MUST
    13.     var gX:     int;            // MUST
    14.     var gY:     int;            // MUST
    15.     var gZ:     int;            // MUST            
    16.     //------ zone
    17.     var gDim:   float; 
    18.     var max_level:int;
    19.     var max_length:int;
    20.     var camRect: Vector2[];
    21.     var camDist: float;    
    22.     //----- static 
    23.     static var debug:boolean;
    24.     static var ref:float = 724.0773439;     // 1to1 pixel scaling  
    25.     private static var born :int = 0;
    26.     private static var obj = new Array();      
    27.     private static var who = new Array();      
    28.     private var gID:    int;                //---- ID of clones
    29.    
    30.     static function create_cell(t:Transform, gT:String, gB:int, gL:int, gX:int, gY:int, gZ:int):GameObject
    31.     {
    32.         return MapSub2.create_cell(t, gT, gB, gL, gX, gY, gZ);
    33.     }  
    34.     function Born()
    35.     {
    36.         this.gDim       = pow(2, gLevel);
    37.         this.camRect    = new Vector2[4];
    38.         this.camDist    = 0.001;
    39.         this.max_level  = 6;
    40.         this.max_length = 999;
    41.         gameObject.transform.parent     = parent;
    42.         gameObject.name                 = "c."+gBank+"."+gLevel+"."+gX+"."+gY+"."+gZ;
    43.         Push();
    44.         Init();
    45.     }
    46.     static function getCell(i:int):GameObject
    47.     {      
    48.         return (i < obj.length) ? obj[i]: null;
    49.     }  
    50.     private function Push()
    51.     {
    52.         born++;
    53.         gID = born;
    54.         obj.Push(gameObject);
    55.         who.Push(born);    
    56.     }  
    57.     function selfID():int { return gID; }
    58.     static function length():int { return obj.length; }
    59.    
    60.     private function Init()
    61.     {                      
    62.         MapSub2.init(gameObject);
    63.         MapSub2.setup_texture(gameObject, "MapUpdate2", debug);
    64.     }
    65.     //------ kill_cell()   
    66.     static function kill_cell(g:GameObject)
    67.     {
    68.         var map:_mapObject = g.GetComponent("_mapObject");
    69.        
    70.         var gID = map.cell.gID;
    71.         for(var i=obj.length-1; i>=0;i--)
    72.         {
    73.             if (who[i] == gID)
    74.             {              
    75.                 UnityEngine.Object.Destroy(g);
    76.                 obj[i]=null;
    77.                 who[i]=null;
    78.                 obj.RemoveAt(i);
    79.                 who.RemoveAt(i);
    80.                 break;
    81.             }
    82.         }      
    83.     }
    84.     //----- helper
    85.     private static var _log     = Debug().Log;
    86.     private static var pow      = Mathf().Pow;
    87. }
    88.  
    _mapObject.js
    Code (csharp):
    1. var cell:MapObject = new MapObject();
     
    Last edited: Apr 26, 2011
  2. apple_motion

    apple_motion

    Joined:
    Jul 2, 2009
    Posts:
    169
    MapSub2.js // A static class that served as a helper for the main class
    Code (csharp):
    1. #pragma strict
    2. #pragma implicit
    3. #pragma downcast
    4.        
    5. class MapSub2
    6. {  
    7.     static var tMan:_tManager = _tManager.tManager();  
    8.     private static var cell_mesh:Mesh; 
    9.    
    10.     static function init(g:GameObject)
    11.     {
    12.         var map:_mapObject = g.GetComponent("_mapObject"); 
    13.         //----- mesh       
    14.         var mesh = build_mesh();
    15.         g.AddComponent(MeshFilter);
    16.         var m:MeshFilter = g.GetComponent(MeshFilter);
    17.         m.mesh = mesh;
    18.         g.AddComponent("MeshRenderer");        
    19.        
    20.         var ie:float = 1/map.cell.gDim;    
    21.         var t = g.transform;
    22.         t.localPosition = Vector3(map.cell.gX*ie ,map.cell.gY*ie ,ie/256);
    23.         t.localScale    = Vector3(ie, ie, 1);
    24.     }  
    25.     static function build_mesh():Mesh
    26.     {
    27.         if(cell_mesh) { return cell_mesh; }    
    28.         _log("---> cell_mesh");    
    29.         var v = new Vector3[9];
    30.         v[6]=Vector3(0,   1); v[7]=Vector3(0.5,   1); v[8]=Vector3(1,   1);
    31.         v[3]=Vector3(0, 0.5); v[4]=Vector3(0.5, 0.5); v[5]=Vector3(1, 0.5);
    32.         v[0]=Vector3(0,   0); v[1]=Vector3(0.5,   0); v[2]=Vector3(1,   0);    
    33.         var uv = new Vector2[9];
    34.         for(var i=0;i<9;i++)
    35.         {
    36.             uv[i] = Vector2(v[i].x, v[i].y);
    37.         }      
    38.         var uv2 = new Vector2[9];      
    39.         uv2[0] = uv[6]; uv2[1] = uv[7]; uv2[2] = uv[8];
    40.         uv2[3] = uv[3]; uv2[4] = uv[4]; uv2[5] = uv[5];
    41.         uv2[6] = uv[0]; uv2[7] = uv[1]; uv2[8] = uv[2];
    42.        
    43.         var t = new int[24];
    44.         t = [   0,3,1, 1,3,4,
    45.                 1,4,2, 2,4,5,
    46.                 3,6,4, 4,6,7,
    47.                 4,7,5, 5,7,8  ];
    48.            
    49.         var c = new Color[9];  
    50.         c = [   Color(  1, 1, 0), Color(  1, 0.5, 0), Color(  1, 0, 0),
    51.                 Color(0.5, 1, 0), Color(0.5, 0.5, 0), Color(0.5, 0, 0),
    52.                 Color(  0, 1, 0), Color(  0, 0.5, 0), Color(  0, 0, 0)   ];                
    53.         var mesh = new Mesh();
    54.         mesh.vertices   = v;
    55.         mesh.triangles  = t;
    56.         mesh.uv         = uv2;
    57.         mesh.colors     = c;
    58.         mesh.RecalculateNormals();
    59.         cell_mesh = mesh;      
    60.         return mesh;       
    61.     }
    62.     static function check_res(g:GameObject):float
    63.     {
    64.         var map:_mapObject = g.GetComponent("_mapObject");
    65.        
    66.         var w2s = Camera().main.WorldToScreenPoint;        
    67.         var m:MeshFilter = g.GetComponent(MeshFilter);     
    68.         var mv:Vector3[] = m.mesh.vertices;    
    69.         var t   = g.transform.position;    
    70.         var d   = Vector3.Distance(w2s(mv[0]+t), w2s(mv[8]+t));
    71.             d  += Vector3.Distance(w2s(mv[2]+t), w2s(mv[6]+t));
    72.         return d;
    73.     }
    74.     static function unit_res(c:Camera, z:float):float
    75.     {
    76.         var w2s = c.WorldToScreenPoint;    
    77.         var p3  = Vector3(0,1,z); var p2 = Vector3(1,1,z);
    78.         var p0  = Vector3(0,0,z); var p1 = Vector3(1,0,z);     
    79.         var d   = Vector3.Distance(w2s(p3), w2s(p2));
    80.             d  += Vector3.Distance(w2s(p0), w2s(p1));
    81.         return d;
    82.     }      
    83.     static function clone(g:GameObject, type:String, level:int, gX:int, gY:int, gZ:int)
    84.     {                              
    85.         var map:_mapObject = g.GetComponent("_mapObject");
    86.         if (level < 0 || map.cell.max_level < level)    { return; }    
    87.         var str:String = "c."+map.cell.gBank+"."+level+"."+gX+"."+gY+"."+gZ;   
    88.         for(var i=map.cell.length()-1;i>=0;i--)
    89.         {          
    90.             if( map.cell.getCell(i) != null)
    91.             {
    92.                 if(map.cell.getCell(i).gameObject.name == str) { return; }
    93.             }
    94.         }      
    95.         create_cell(map.cell.parent, type, map.cell.gBank, level, gX, gY, 0);
    96.     }
    97.     static function create_cell(t:Transform, gT:String, gB:int, gL:int, gX:int, gY:int, gZ:int):GameObject
    98.     {
    99.         var g = new GameObject();  
    100.         g.AddComponent("_mapObject");
    101.         var map:_mapObject = g.GetComponent("_mapObject");
    102.         map.cell.gameObject = g;
    103.         map.cell.parent = t;   
    104.         map.cell.gType  = gT;                          
    105.         map.cell.gBank  = gB;                              
    106.         map.cell.gLevel = gL;                              
    107.         map.cell.gX     = gX;                              
    108.         map.cell.gY     = gY;                              
    109.         map.cell.gZ     = gZ;  
    110.         map.cell.Born();
    111.        
    112.         return g;
    113.     }
    114.     static function cloneXY( g:GameObject, type:String, level:int, gX:int, gY:int, gZ:int,
    115.                             gR:Vector2[], cR:Vector2[])
    116.     {
    117.         var map:_mapObject = g.GetComponent("_mapObject");
    118.        
    119.         if (rc_poly(gR,cR) == 0)    { return; }    
    120.         if (gX < 0 || map.cell.gDim <= gX)  { return; }
    121.         if (gY < 0 || map.cell.gDim <= gY)  { return; }
    122.         clone(g, type, level, gX, gY, gZ);
    123.     }  
    124.     static function camRect(c:Camera, gz:float):Vector2[]
    125.     {
    126.         var v2w =  c.ScreenToWorldPoint;               
    127.         var cx  =  c.pixelWidth;
    128.         var cy  =  c.pixelHeight;
    129.         var cz  = -c.transform.position.z +gz;     
    130.         var vp = new Vector3[4];   
    131.         vp[3] = v2w(Vector3(0,cy,cz)); vp[2] = v2w(Vector3(cx,cy,cz));
    132.         vp[0] = v2w(Vector3(0, 0,cz)); vp[1] = v2w(Vector3(cx, 0,cz));             
    133.         var v:Vector2[] =  rect(vp[1].x-vp[0].x, vp[2].y-vp[0].y, vp[0].x, vp[0].y);
    134.         System.Array.Clear(vp, 0, vp.length);      
    135.         return v;
    136.     }
    137.     static function camCL(c:Camera, gz:float):Vector3
    138.     {
    139.         var v2w =  c.ScreenToWorldPoint;
    140.         var cx  =  c.pixelWidth  /2.0;
    141.         var cy  =  c.pixelHeight /2.0;
    142.         var cz  = -c.transform.position.z +gz;     
    143.         var CL:Vector3= v2w(Vector3(cx, cy, cz));      
    144.         Debug.DrawLine(CL, c.transform.position, Color.red);    // debug
    145.         return CL;
    146.     }
    147.     static function rect(x:float, y:float, dx:float, dy:float):Vector2[]
    148.     {
    149.         var x0 = dx;
    150.         var y0 = dy;
    151.         x += x0;
    152.         y += y0;
    153.         var sq = new Vector2[4];
    154.         sq = [ Vector2(x0,y0),  Vector2(x,y0), Vector2(x,y), Vector2(x0,y) ];
    155.         return sq;
    156.     }  
    157.     static function rc_poly(p:Vector2[], m:Vector2[]):int
    158.     {
    159.         var i:int = 0; var c:int = 0;
    160.         for(i=0;i<p.length;i++) { c = rc_point(p[i], m); if(c) { return c;; } }    
    161.         for(i=0;i<m.length;i++) { c = rc_point(m[i], p); if(c) { return c;; } }    
    162.         return c;
    163.     }  
    164.     static function rc_point(p:Vector2, m:Vector2[]):int
    165.     {
    166.         var i:int;
    167.         var j:int = m.length -1;
    168.         var c:int = -1;    
    169.         for(i=0;i<m.length;i++)
    170.         {
    171.             if( m[i].y<p.y  m[j].y>=p.y || m[j].y<p.y  m[i].y>=p.y )
    172.             {
    173.                 if (m[i].x+(p.y-m[i].y)/(m[j].y-m[i].y)*(m[j].x-m[i].x)<p.x)
    174.                 {
    175.                     c = -c;
    176.                 }
    177.             }
    178.             j=i;
    179.         }
    180.         return (c==1)? 1:0;
    181.     }
    182.     static function born_XY(g:GameObject, v:Vector2[])
    183.     {
    184.         var map:_mapObject = g.GetComponent("_mapObject");
    185.        
    186.         var res:float = check_res(g);
    187.        
    188.         if( res > (MapObject.ref*0.7)*map.cell.gDim  res < (MapObject.ref*2.6)*map.cell.gDim)
    189.         {
    190.             var p: Vector2 = g.transform.position; 
    191.             var s: float = 1.0/map.cell.gDim;
    192.            
    193.             if(map.cell.gType == "x" || map.cell.gType == "seed")
    194.             {      
    195.                 cloneXY(g,"y",map.cell.gLevel, map.cell.gX +1, map.cell.gY, 0, rect(s,s,p.x+s,p.y),v);
    196.                 cloneXY(g,"y",map.cell.gLevel, map.cell.gX -1, map.cell.gY, 0, rect(s,s,p.x-s,p.y),v);
    197.             }                      
    198.             if(map.cell.gType == "y")
    199.             {
    200.                 cloneXY(g,"x",map.cell.gLevel, map.cell.gX, map.cell.gY +1, 0, rect(s,s,p.x,p.y+s),v);
    201.                 cloneXY(g,"x",map.cell.gLevel, map.cell.gX, map.cell.gY -1, 0, rect(s,s,p.x,p.y-s),v);
    202.             }
    203.         }
    204.     }
    205.     static function map_level(c:Camera, z:float):int
    206.     {
    207.         var r:int = parseInt(unit_res(c, z)/MapObject.ref);
    208.         for(var i=0;i<=32;i++)
    209.         {      
    210.             if (r < 2) { break; }
    211.             r /= 2;
    212.         }      
    213.         return i;
    214.     }
    215.     static function check_gView(g:GameObject, v:Camera):boolean
    216.     {
    217.         var map:_mapObject = g.GetComponent("_mapObject");
    218.        
    219.         var p: Vector3 = g.transform.position; 
    220.         var s: float = 1.0/map.cell.gDim;  
    221.         var gRect:Vector2[] = rect(s,s,p.x,p.y);   
    222.         var cRect:Vector2[] = camRect(v, p.z);
    223.         return (rc_poly(gRect, cRect))? true: false;
    224.     }
    225.     //------ auto_seed()   
    226.     static function auto_seed(g:GameObject)
    227.     {
    228.         var level = map_level(Camera().main, g.transform.position.z);
    229.         var cp: Vector3 = camCL(Camera().main, g.transform.position.z);    
    230.         cp.x -= g.transform.position.x;
    231.         cp.y -= g.transform.position.y;    
    232.         var res = level+1;
    233.         var e   = pow(2, res);
    234.         var cx:int  = e*cp.x;
    235.         var cy:int  = e*cp.y;
    236.        
    237.         cx = (cx < 0)?   0:cx;
    238.         cx = (cx >=e)? e-1:cx;
    239.         cy = (cy < 0)?   0:cy;
    240.         cy = (cy >=e)? e-1:cy;
    241.    
    242.         seeding(g, "auto", res, cx, cy, 0);    
    243.     }  
    244.     static function seeding(g:GameObject, type:String, res:int, cx:int , cy:int, _t:int)
    245.     {
    246.         var e = pow(2, res);
    247.         if (cx < 0 || cx >= e) { return; }
    248.         if (cy < 0 || cy >= e) { return; } 
    249.        
    250.         if (type == "auto") type = (cx&cy) ? "x" : "y";        
    251.         clone(g, type, res, cx, cy, 0);
    252.     }  
    253.     static function setup_texture(g:GameObject, update:String, debug:boolean)
    254.     {
    255.         var map:_mapObject = g.GetComponent("_mapObject"); 
    256.         g.AddComponent(update);    
    257.         var updater:MapUpdate2 = g.GetComponent(update);       
    258.         updater.g = g;
    259.         if(debug)
    260.         {
    261.             g.renderer.material.color = text_color(map.cell.gType, map.cell.gLevel);
    262.         }
    263.         else
    264.         {
    265.             var ref:Hashtable = {
    266.                                     "position"  :g.transform.localPosition,
    267.                                     "slice"     :0,
    268.                                     "bank"      :map.cell.gBank,
    269.                                     "level"     :map.cell.gLevel
    270.                                 };
    271.             updater.textureURL = MapSrc.url(ref);          
    272.             AddTexture(g, updater.textureURL);
    273.         }
    274.     }
    275.     private static function AddTexture(g:GameObject, url:String)
    276.     {
    277.         g.renderer.enabled = false;        
    278.         tMan.texture_request(g, url);
    279.     }
    280.     private static function text_color(type:String, level:int)
    281.     {
    282.         var c:Color = Color.blue;
    283.         if      (type == "x") c = Color.red;
    284.         else if (type == "y") c = Color.green;
    285.         c.b = (level%6)/5*0.4+0.6;
    286.         return c;  
    287.     }
    288.     //----- helper
    289.     private static var _log     = Debug().Log;
    290.     private static var floor    = Mathf().Floor;
    291.     private static var pow      = Mathf().Pow;
    292. }
     
  3. apple_motion

    apple_motion

    Joined:
    Jul 2, 2009
    Posts:
    169
    MapUpdate2.js
    Code (csharp):
    1. #pragma strict
    2. #pragma implicit
    3. #pragma downcast
    4.  
    5. var g:GameObject;
    6. var textureURL:String;
    7. var live:int = 64;
    8.  
    9. function FixedUpdate ()
    10. {  
    11.     if (!g) { return; }
    12.     var map:_mapObject = g.GetComponent("_mapObject"); 
    13.    
    14.     if (map.cell.gType == "seed") { MapSub2.auto_seed(g); }
    15.  
    16.     //------ born and dead 
    17.     if(map.cell.gLevel <=  map.cell.max_level  map.cell.length() <  map.cell.max_length)
    18.     {      
    19.         var v:Vector2[] = MapSub2.camRect(Camera.main, g.gameObject.transform.position.z); 
    20.         var update = 0;            
    21.  
    22.         if (map.cell.camRect[0] != v[0])
    23.         {
    24.             var d1 = Vector3.Distance(map.cell.camRect[0], v[0]);
    25.             if(d1 > 0.4/map.cell.gDim)
    26.             {
    27.                 map.cell.camRect[0] = v[0];
    28.                 update =1;
    29.             }
    30.         }  
    31.         var cpos:Vector3    = Camera.main.transform.position;
    32.         var gpos:Vector3    = g.gameObject.transform.position;
    33.         var d2:float        = Vector3.Distance(cpos, gpos);    
    34.         if(map.cell.camDist != d2)
    35.         {
    36.             map.cell.camDist = d2;
    37.             update =1;
    38.         }
    39.         if(update)
    40.         {          
    41.             //------ born
    42.             MapSub2.born_XY(g, v); 
    43.             //------ kill
    44.             if (map.cell.gType != "seed")
    45.             {
    46.                 var level:int   = map.cell.gLevel;
    47.                 var res:int     = MapSub2.map_level(Camera().main, gpos.z);
    48.                 var visiable:boolean = MapSub2.check_gView(g, Camera.main);
    49.                 if (!visiable || level < res-1 || level > res+1)
    50.                     live--;
    51.                 else   
    52.                     live = 64;
    53.                 if(!live)
    54.                 {
    55.                      MapObject.kill_cell(g);
    56.                 }
    57.             }
    58.         }                  
    59.     }
    60.  
    61. }
    62. function OnDestroy()
    63. {  
    64.     var gid:String = g.gameObject.GetInstanceID().ToString();
    65.     var url:String = this.textureURL;
    66.     MapSub2.tMan.texture_remove(gid, url);
    67.    
    68.     var m:MeshFilter    = g.gameObject.GetComponent(MeshFilter);   
    69.     var r:MeshRenderer  = g.gameObject.GetComponent(MeshRenderer);
    70.     Destroy(m.mesh);
    71.     Destroy(r.material);
    72. }
    73. //----- helper
    74. private static var _log     = Debug().Log;
    75. private static var floor    = Mathf().Floor;
    _tManager.js // Texture Loader
    Code (csharp):
    1. #pragma strict
    2. #pragma implicit
    3. #pragma downcast
    4.  
    5. private static var busy:int = 0;
    6. private static var proxy_texture:Texture2D;
    7.  
    8. private static var Request_Queue0:Array = new Array();
    9. private static var Request_Queue1:Array = new Array();
    10. private static var Remove_Queue:Array = new Array();
    11. private static var texHash:Hashtable = new Hashtable();
    12. private static var wwwHash:Hashtable = new Hashtable();
    13.  
    14. function OnGUI()
    15. {
    16.     var i:int = 0;
    17.     var j:int = 0;
    18.     for(th in texHash.Keys)
    19.     {      
    20.         j++; //GUILayout.Box(th.ToString());
    21.         var h:Hashtable = texHash[th]; 
    22.         if(h.ContainsKey("target"))
    23.         {
    24.             var t:Hashtable = h["target"];
    25.             for(k in t.Keys) {  i++; /*GUILayout.Box(k.ToString());*/ }
    26.         }
    27.     }
    28.     var str:String = "";
    29.     str += Request_Queue0.length +"/r";
    30.     str += Remove_Queue.length + "/r";
    31.     str += j + "/r";
    32.     str += i;
    33.     GUILayout.Box(" Request Queue : "+Request_Queue0.length);  
    34.     GUILayout.Box(" Remove Queue : "+Remove_Queue.length);
    35.     GUILayout.Box(" Texture Buffered : "+j);
    36.     GUILayout.Box(" Active Object : "+i);
    37. }
    38. function FixedUpdate()
    39. {
    40.     if(Request_Queue0.length  busy < 8)     {   Run();  }  
    41.     if(Request_Queue0.length > 8)          
    42.     {  
    43.         var n:int = Request_Queue0.length-8;
    44.         for(var i:int=0;i<n;i++)
    45.         {      
    46.             CleanUp();
    47.         }
    48.     }
    49.     if( Remove_Queue.length > 32)           {   Kill(); }
    50. }
    51. static function texture_request(g:GameObject, url:String)
    52. {
    53.     Request_Queue0.Push(g);
    54.     Request_Queue1.Push(url);
    55. }
    56. private function Run()
    57. {
    58.     var g:GameObject    = Request_Queue0.Shift();
    59.     var url:String      = Request_Queue1.Shift();
    60.     if(!g || !url) return;
    61.     _texture_request(g, url);
    62. }
    63. private function _texture_request(g:GameObject, url:String)
    64. {      
    65.     g.renderer.material.mainTexture = pTex();
    66.    
    67.     var gid:String = g.GetInstanceID().ToString();
    68.     if(texHash.ContainsKey(url))
    69.     {
    70.         var h2:Hashtable = texHash[url];
    71.         var t2:Hashtable = h2["target"];
    72.         t2[gid] = g;
    73.        
    74.         if(h2.ContainsKey("texture"))
    75.         {
    76.             g.renderer.material.mainTexture = h2["texture"]; //Debug.Log("reused");
    77.             g.renderer.material.mainTexture.wrapMode = TextureWrapMode.Clamp;
    78.             g.renderer.enabled = true;
    79.         }      
    80.     }
    81.     else
    82.     {
    83.         busy++;
    84.         texHash[url] = new Hashtable();    
    85.         var h:Hashtable = texHash[url];
    86.         h["target"] = new Hashtable(); 
    87.         var t:Hashtable = h["target"];
    88.         t[gid] = g;
    89.    
    90.         var www : WWW = new WWW (url);      //Debug.Log("request --> " + url);             
    91.         wwwHash[url] = null;
    92.         yield www; 
    93.        
    94.         if(wwwHash.ContainsKey(url))
    95.         {  
    96.             wwwHash.Remove(url);
    97.                    
    98.             var _temp:Texture2D =   www.texture;
    99.             _temp.name = url;
    100.             _temp.wrapMode = TextureWrapMode.Clamp;
    101.             h["texture"] = _temp ; 
    102.             for(k in t.Keys)
    103.             {
    104.                 var g2:GameObject = t[k];
    105.                 if(!g2)
    106.                 {  
    107.                     Debug.Log("skip");
    108.                     continue;
    109.                 }
    110.                 g2.renderer.material.mainTexture = h["texture"];    //Debug.Log("loaded");
    111.                 g2.renderer.material.mainTexture.wrapMode = TextureWrapMode.Clamp;
    112.                 g2.renderer.enabled = true;
    113.             }
    114.         }
    115.         else
    116.         {
    117.             www.Dispose();
    118.         }
    119.         busy--;
    120.     }  
    121. }
    122. static function texture_remove(gid:String, url:String)
    123. {  
    124.     if(!url || url == "") return;
    125.  
    126.     if(texHash.ContainsKey(url))
    127.     {      
    128.         var h:Hashtable = texHash[url];            
    129.         var t:Hashtable = h["target"];
    130.         if(t.Count == 1  wwwHash.ContainsKey(url))
    131.         {
    132.             wwwHash.Remove(url);        //Debug.Log("Disposed --> "+url);      
    133.         }          
    134.         if(t.ContainsKey(gid))
    135.         {          
    136.             t.Remove(gid);              //Debug.Log("unloaded:"+gid);
    137.         }
    138.         if(t.Count == 0)
    139.         {
    140.             for(var i:int = 0; i<Remove_Queue.length;i++)
    141.             {
    142.                 var str:String = Remove_Queue[i];              
    143.                 if(str == url) return;         
    144.             }          
    145.             Remove_Queue.Push(url);
    146.         }  
    147.     }
    148. }
    149. private static function Kill()
    150. {
    151.     var url:String = Remove_Queue.Shift();
    152.    
    153.     var h:Hashtable = texHash[url];
    154.     var t:Hashtable = h["target"];
    155.     if(!t.Count)
    156.     {
    157.         Destroy(h["texture"]);
    158.         texHash.Remove(url);    //Debug.Log("killed --> "+url);
    159.     }
    160. }
    161. private static function CleanUp()
    162. {
    163.     var g:GameObject = Request_Queue0[0];  
    164.     if (!g)
    165.     {
    166.         Request_Queue0.Shift();
    167.         Request_Queue1.Shift();
    168.     }
    169. }
    170. private static function pTex():Texture2D
    171. {
    172.     if(proxy_texture) return proxy_texture;
    173.    
    174.     var t = new Texture2D(32, 32);
    175.     for (var y : int = 0; y < t.height; ++y)
    176.     {
    177.         for (var x : int = 0; x < t.width; ++x)
    178.         {
    179.             t.SetPixel (x, y, Color.red);
    180.         }
    181.     }
    182.     t.Apply();
    183.     t.name = "_proxy";
    184.     proxy_texture = t;
    185.     return proxy_texture;
    186. }
    187. static function tManager():_tManager
    188. {
    189.     var tman:GameObject = GameObject.Find("tManager");
    190.     if(!tman)
    191.     {
    192.         tman = new GameObject("tManager");
    193.         tman.AddComponent("_tManager");    
    194.     }
    195.     return tman.GetComponent("_tManager");
    196. }
    MapSrc.js // Convert from position to file name for map tiles
    Code (csharp):
    1. #pragma strict
    2. #pragma implicit
    3. #pragma downcast
    4.  
    5. class MapSrc
    6. {
    7.     private static var path_00:String = "http://127.0.0.1/~antonioh/Map_NASA_200407/"; 
    8.     private static var path_01:String = "http://homepage.mac.com/antonioh/dev/Map_NASA_200407/";
    9.  
    10.     static function url(h:Hashtable):String
    11.     {
    12.         return url(h["position"], h["slice"], h["bank"], h["level"], pow(2, h["level"]));
    13.     }  
    14.     private static function url(pos:Vector3, slice:int, bank:int, level:int, scaler:int):String
    15.     {
    16.         var p:int[] = calc_file(pos, slice, level, scaler);
    17.        
    18.         var path:String     = path_01;
    19.         var file: String    = p[2] +"-"+p[0] +"-"+p[1];    
    20.         var bank2: String   = calc_bank(bank);
    21.         var log:String      = calc_log(p[2], p[0], p[1]);
    22.         var ext:String      = ".jpg";
    23.        
    24.         return path+bank2+log+file+ext;
    25.     }
    26.     private static function calc_log(level:int, x:int, y:int):String
    27.     {
    28.         var cid = cell_id(level, x, y);
    29.         if(cid < 1) { return "ERR/"; }
    30.         return "TileGroup"+(cid-1)/256 +"/";
    31.     }
    32.     private static function cell_id(level:int, x:int, y:int):int
    33.     {
    34.         var pL:int = parseInt(pow(2, level));              
    35.         var a: int = 1;
    36.         for(var i=1; i<=level; i++)
    37.         {
    38.             var p:int= parseInt(pow(2, i-1));
    39.             a += p*p;
    40.         }
    41.         a += x + y *pL;
    42.         return a;
    43.     }  
    44.     private static function calc_bank(i:int):String
    45.     {
    46.         var bank:String[] = ["A1", "A2","B1", "B2", "C1", "C2", "D1", "D2" ];
    47.         return bank[i%8] +"/";
    48.     }  
    49.     private static function calc_file(pos:Vector3, slice:int, level:int, scaler:int ):int[]
    50.     {
    51.         pos *= scaler;     
    52.         var px:int = floor(pos.x);
    53.         var py:int = floor(pos.y);
    54.            
    55.         var c:int = slice % 4;
    56.         var cx:int;
    57.         var cy:int;
    58.         if      (c==0) { cx=0; cy=0; }
    59.         else if (c==1) { cx=1; cy=0; }
    60.         else if (c==2) { cx=0; cy=1; }
    61.         else if (c==3) { cx=1; cy=1; }
    62.        
    63.         return [px+cx, py+cy, level];
    64.     }  
    65.     //----- helper
    66.     private static var _log     = Debug().Log;
    67.     private static var floor    = Mathf().Floor;
    68.     private static var pow      = Mathf().Pow;
    69. }
     
  4. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Very interesting. Have you tried this with the maps applied to a sphere?
     
  5. apple_motion

    apple_motion

    Joined:
    Jul 2, 2009
    Posts:
    169
    Not yet.

    because, on MapSub2.js....
    static function rc_point(p:Vector2, m:Vector2[]):int
    ... the ray-casting routine are only for 2D detection only currently (plane not volume).

    But sure, I will make it work on any shape when I have free time again :)
     
    Last edited: Apr 26, 2011
  6. apple_motion

    apple_motion

    Joined:
    Jul 2, 2009
    Posts:
    169
    Yeah ! I made it run on my iPod now :cool:
    http://www.youtube.com/watch?v=oeS-AihiQpM



    The sample project and the source code will be posted in here, if someone interested ;)

    We should make our Earth better :)
     
  7. Afisicos

    Afisicos

    Joined:
    Nov 13, 2010
    Posts:
    326
    very nice proyect!
     
  8. cr0ybot

    cr0ybot

    Joined:
    Apr 29, 2011
    Posts:
    7
    Wow, that is simply amazing. Any chance we'll get to see the source code for the spherical earth?
     
  9. diablo

    diablo

    Joined:
    Jan 3, 2011
    Posts:
    736
    Hey apple_motion,

    Do you have an email address? I would like to email you regarding a paid shader conversion. Let me know the best way of contacting you.

    Thanks!

    El Diablo
     
  10. apple_motion

    apple_motion

    Joined:
    Jul 2, 2009
    Posts:
    169
    well, sorry that, the completed project source may not be available in the short time, since I am changing the internal logic for the map tile creation at the moment...
    http://www.youtube.com/watch?v=HWl2mOhziP8
    Yeah... I made it work as a skybox too :p

    However, I could show you the main class of the earth demo that deform the sub-divided cube onto a sphere.

    Please see the lines followed by "//----- build mesh" that's do the magic :cool:

    Code (csharp):
    1. #pragma strict
    2. #pragma downcast
    3.  
    4. class LiveCycle
    5. {
    6.     static var debug = false;
    7.     static var Born_Queue:Hashtable = {};  
    8.    
    9.     static var born_request:int     = 0;   
    10.     static var last_frameCount:int  = 0;
    11.    
    12.     private static var tMan:TextureMan = TextureMan.host();
    13.     private static var mesh_hash:Hashtable = {};
    14.    
    15.     private static var reject_name:long = 0;
    16.     private static var reject_visible:long = 0;
    17.     private static var reject_normal:long = 0;
    18.     private static var reject_fit:long = 0;
    19.    
    20.     static function create( bank:int, level:int, x:int, y:int, type:String, parent:Transform, isSky:int)
    21.     {  
    22.         if(last_frameCount != Time.frameCount)
    23.         {
    24.             last_frameCount = Time.frameCount;
    25.             TestNode.node("mesh_request", born_request+"/frame");
    26.             born_request = 0;      
    27.         }
    28.         born_request++;
    29.         //----- born
    30.         var face:String[] = ["front","right","back","left","top","bottom"];
    31.         var gName = face[bank%6]+"-"+level+"-"+x+"-"+y;
    32.         if(Born_Queue.ContainsKey(gName))
    33.         {
    34.             //_log("reject_name : "+gName);
    35.             TestNode.node("mesh_rejected_name", (reject_name++)/Time.frameCount+"/sec");
    36.             return;
    37.         }
    38.         Born_Queue[gName] = null;      
    39.         //----- build mesh
    40.         var n:float = pow(2,level);
    41.         var w:float = 1.0/n;
    42.         var m:Mesh = build_mesh(17-level*4);
    43.         var v0:Vector3[] = m.vertices;
    44.         var v1:Vector3[] = new Vector3[v0.length];
    45.         var N:Vector3[] = new Vector3[v0.length];  
    46.         var q:Quaternion = face_rotation(bank);
    47.         for (var i:int=0;i<v0.length;i++)
    48.         {      
    49.             var v:Vector3 = v0[i];
    50.             v *= w;
    51.             v.x += parseFloat(x)*w;
    52.             v.y += parseFloat(y)*w;    
    53.             v += Vector3(-0.5, -0.5, -0.5);        
    54.              N[i] = q*v.normalized;
    55.             v1[i] = N[i]*0.5;
    56.         }
    57.         System.Array.Clear(v0, 0, v0.length);
    58.         //----- Visible Test
    59.         var reject:boolean = false;
    60.         if(type != "seed")
    61.         {
    62.             if(!Visible.isVisible(v1, Camera.main))
    63.             {
    64.                 //_log("reject_visible : "+gName);
    65.                 TestNode.node("mesh_rejected_visible", (reject_visible++)/Time.frameCount+"/sec");
    66.                 reject = true;
    67.             }
    68.             else if(!Visible.isFaced(v1, N, Camera.main.transform.position))
    69.             {      
    70.                 //_log("reject_normal : "+gName);
    71.                 TestNode.node("mesh_rejected_normal", (reject_normal++)/Time.frameCount+"/sec");
    72.                 reject = true;
    73.             }
    74.             else if(!Visible.isFit(v1, N, Camera.main, Visible.reference, level))
    75.             {
    76.                 //_log("reject_size : "+gName);
    77.                 TestNode.node("mesh_rejected_fit", (reject_fit++)/Time.frameCount+"/sec");
    78.                 reject = true;
    79.             }
    80.         }
    81.         System.Array.Clear(N, 0, N.length);
    82.         if(reject)
    83.         {
    84.             System.Array.Clear(v1, 0, v1.length);
    85.             LiveCycle.Born_Queue.Remove(gName);
    86.             return;
    87.         }
    88.         //----- create host
    89.         var g:GameObject = new GameObject(gName);
    90.         if(parent) g.transform.parent = parent;
    91.         g.AddComponent(MeshFilter);
    92.         g.AddComponent(MeshRenderer);      
    93.         //----- assign mesh
    94.         var c:MeshFilter = g.GetComponent(MeshFilter); 
    95.         c.mesh = m;
    96.         c.mesh.vertices = v1;
    97.         c.mesh.name = "mesh-"+x+"-"+y;
    98.         c.mesh.RecalculateNormals();
    99.         c.mesh.RecalculateBounds();
    100.         System.Array.Clear(v1, 0, v1.length);      
    101.         //----- texture request    
    102.         if(debug)
    103.         {
    104.             var col:float = 0.5/parseFloat(level+1)+0.5;
    105.             g.renderer.material.color = ((x+y)%2)? Color.red*col:Color.green*col;
    106.         }
    107.         else
    108.         {
    109.             var pos:Vector3 = Vector3(parseFloat(x)/n, parseFloat(y)/n, 0);     // gPos
    110.             var ref:Hashtable = {
    111.                                     "position"  :pos,
    112.                                     "slice"     :0,
    113.                                     "bank"      :bank,
    114.                                     "level"     :level
    115.                                 };
    116.             g.renderer.enabled = false;
    117.             var url:String = MapSrc.url(ref);
    118.             if(!tMan) tMan = TextureMan.host();
    119.             tMan.texture_request(g, url);
    120.             TestNode.node("map_path",MapSrc.path_url);
    121.             TestNode.node("map_tile",url.Substring(MapSrc.path_url.length));   
    122.         }
    123.         //---------- properties
    124.         g.AddComponent("_properties"); 
    125.         var par:_properties = g.GetComponent("_properties");   
    126.         var h:Hashtable     = par.properties;      
    127.         //Born_Queue[gName] = h;       
    128.         //h["g"]            = g;       
    129.         h["gid"]        = g.GetInstanceID().ToString();    
    130.         h["gBank"]      = bank;
    131.         h["gLevel"]     = level;
    132.         h["gX"]         = x;
    133.         h["gY"]         = y;
    134.         h["gType"]      = (type=="auto")?(((x+y)%2)?"x":"y"):type;     
    135.         h["gWidth"]     = pow(2,level);
    136.         h["camera"]         = Camera.main;     
    137.         h["mesh"]           = c.mesh;
    138.         h["mesh_normal"]    = c.mesh.normals;
    139.         h["mesh_vertices"]  = c.mesh.vertices;
    140.         h["mesh_uv"]        = c.mesh.uv;           
    141.         h["texture_url"]    = url;
    142.         h["face_rotation"]  = q;
    143.        
    144.         if(debug)
    145.         {
    146.             h["texture_state"] = "debug";
    147.         }
    148.        
    149.         //---------- updater
    150.         g.AddComponent("_updater");
    151.     }
    152.     static function face_rotation(f:int):Quaternion
    153.     {
    154.         var q:Quaternion;  
    155.         var a:float = Mathf.Cos(Mathf.PI/4.0); 
    156.         switch(f%6)
    157.         {
    158.             case 1:  q = Quaternion( 0,-a, 0, a);break;     // right
    159.             case 2:  q = Quaternion( 0, 1, 0, 0);break;     // back
    160.             case 3:  q = Quaternion( 0, a, 0, a);break;     // left
    161.             case 4:  q = Quaternion( a, 0, 0, a);break;     // top;
    162.             case 5:  q = Quaternion(-a, 0, 0, a);break;     // bottom;
    163.             default: q = Quaternion( 0, 0, 0, 1);           // front
    164.         }  
    165.         return q;
    166.     }  
    167.     static function build_mesh(n:int):Mesh
    168.     {
    169.         n = (n<3)?3:n;
    170.         if(mesh_hash.ContainsKey(n))
    171.         {
    172.             return mesh_hash[n];
    173.         }      
    174.         _log((n-1)+" x "+(n-1) +" mesh created");              
    175.         var n2:int = n*n;  
    176.         var v:Vector3[] = new Vector3[n2]; 
    177.         var i:int; 
    178.         for(i=0;i<n2;i++)
    179.         {
    180.             var x:float = parseFloat(i%n)/parseFloat(n-1);
    181.             var y:float = parseFloat(i/n)/parseFloat(n-1); 
    182.             v[i]=Vector3(x,y,0);
    183.         }
    184.         var uv = new Vector2[n2];
    185.         for(i=0;i<n2;i++)
    186.         {
    187.             uv[i] = Vector2(v[i].x, v[i].y);
    188.         }  
    189.         var m:int  = n-1;
    190.         var m2:int = m*m;
    191.         var t = new int[m2*6];
    192.         for (i=0;i<m2;i++)
    193.         {          
    194.             var a = i%m+(i/m)*n;
    195.             t[  i*6] = a;
    196.             t[1+i*6] = a+n;
    197.             t[2+i*6] = a+1;
    198.             t[3+i*6] = a+1;
    199.             t[4+i*6] = a+n;
    200.             t[5+i*6] = a+n+1;
    201.         }          
    202.         var mesh        = new Mesh();
    203.         mesh.vertices   = v;
    204.         mesh.triangles  = t;
    205.         mesh.uv         = uv;
    206.         mesh_hash[n] = mesh;     
    207.         return mesh;       
    208.     }
    209.     //----- shorthand
    210.     private static var _log = Debug.Log;
    211.     private static var pow  = Mathf().Pow;
    212. }
     
  11. bigSky

    bigSky

    Joined:
    Jan 31, 2011
    Posts:
    114
    This is a great project - and the demo on ios is impressive and something that other virtual texturing stuff does not do - any news?
     
  12. apple_motion

    apple_motion

    Joined:
    Jul 2, 2009
    Posts:
    169
    Do you think, is it OK to put all the source code onto our Unify Community Wiki, even that is not finished yet and part of code are still on the conceptual state ? or should I simply posted the code onto the GitHub, which one is better ??
     
  13. koen.pis

    koen.pis

    Joined:
    Mar 24, 2011
    Posts:
    66
    Ofc it is, just add words wip and you might even get some feedback as how to improve on it ;)
     
  14. cr0ybot

    cr0ybot

    Joined:
    Apr 29, 2011
    Posts:
    7
    If you're interested in allowing others to collaborate with you and improve your code, GitHub is the way to go. It's way too clunky to post code, receive feedback, change it, repost, etc. etc...
     
  15. goat

    goat

    Joined:
    Aug 24, 2009
    Posts:
    5,182
    Wow, beautiful.

    I always though it would be nice to import topographic maps at run time into a game from openstreet.org or somewhere...
     
  16. Sergiof

    Sergiof

    Joined:
    Aug 10, 2011
    Posts:
    17
    Can you put the code in GitHub?
    I've been working on a similar project, but if I could I would actually prefer to use yours and help you improve it :)
     
  17. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    1,882
    A zoomable 3d earth would be a good Asset for the store!
    Only thing with those satellite photos is they lack the arctic ice coverage.
     
  18. e10101

    e10101

    Joined:
    Nov 15, 2011
    Posts:
    1
    Very great work, keep up~
    can you show us your ref website, or tell us about the technologies about your code.
    so we can learn better~
     
  19. tarakerat

    tarakerat

    Joined:
    Nov 12, 2012
    Posts:
    1
    Could you explain how you make it?

    I have some questions
    1. Did you extract NASA image to many small piece? If so, how you do that? any tools? How you structure those files? Can we just extract image from NASA image in realtime?
    2. Did you programmatically create the big sphere also?
    3. Did you create new model for each new tile? If it's true, how you create new model that look like it's the same as globe model? the big sphere should have some triangle corner, if it's not high polygon model.
     
    Last edited: Nov 15, 2012
  20. mwharton

    mwharton

    Joined:
    Jan 21, 2014
    Posts:
    9
    Hi apple_motion,

    Really impressive getting that to run on an iPod. Have you made any more progress on this?

    I'd be really interested to see the project. Have you thought about putting it on the Unity Store?
     
unityunity