Dynamic Planet Mesh

Лучший способ помочь другим, поделиться своими находками.

Dynamic Planet Mesh

Сообщение Avatarchik 05 апр 2010, 22:51

Тема на оф форуме http://forum.unity3d.com/viewtopic.php?t=11848&highlight=gui+button+grid
Описание:Генерация планет на лету,генерируются не вся планета сразу,а только та часть которую видет камера
Синтаксис:
Используется javascript
// Based on code from the Procedural Examples project
// Feel free to use this code! (it even works now!)

var heightMap : Texture2D; // determines overal topography
var detailMap : Texture2D; // adds extra detail -- optional
var detailMapScale : float = 10;
var detailMapHeight : float = 0.2;
var material : Material;
var innerRadius : float = 400;
var outerRadius : float = 420; // determines maximum "height"
var patchFocus : Transform; // object whose POV determines portion of mesh to render
var minGridAngle : float = 1.0;
var xRes : int = 32; // mesh budget
var yRes : int = 16; // for rendering
var textureScale : float = 10; // number of times the material will be repeated if not a heightField
var textureIsHeightField : boolean = true; // material simply treated as vertical color bar
var updateOffsetThreshold : float = 2.0; // how far patchFocus has to move to force a redraw (also angular change that will force a redraw)
var showUI : boolean = false; // shows a simple UI to see performance impact

// private (or, it will be once I'm done debugging)
private var mesh : Mesh;
private var xGridSize : float;
private var yGridSize : float;
var gridCenter : Vector3;
var gridAngle : float;
private var gridDirty : boolean = true;
var latitude : float; // center of area
var longitude : float; // we need to render
var latStart : float = -90 * Mathf.Deg2Rad; // area
var latEnd : float = 90 * Mathf.Deg2Rad;  // we
var longStart : float = 0; // need
var longEnd : float = 360 * Mathf.Deg2Rad; // to render
private var angularQuantization : float = 0.1; // attempt to "stabilize" angles

// performance
private var worstTime = 0.0;

function Start(){
   UpdateGridCenter();
   BuildMesh();
   GenerateHeightmap();
}

function UpdateGridCenter() {
   if(patchFocus){
      minGridAngleRadians = minGridAngle * Mathf.Deg2Rad;
      var g = patchFocus.position - transform.position;
      var r = g.magnitude > outerRadius * 1.05 ? innerRadius / g.magnitude : innerRadius / (outerRadius * 1.05);
      var a = Mathf.Acos( r );
      g.Normalize();
      g = g * innerRadius;
     
      if( (g - gridCenter).magnitude > updateOffsetThreshold || Mathf.Abs(a - gridAngle) > updateOffsetThreshold * Mathf.Deg2Rad ){
         gridDirty = true;
         gridAngle = Mathf.Round(a / angularQuantization) * angularQuantization;
         gridCenter = g;
         
         g.Normalize();
         latitude = Mathf.Round(Mathf.Asin(g.y)/angularQuantization) * angularQuantization;
         g.y = 0;
         g.Normalize();
         longitude = g.z < 0 ? Mathf.PI - Mathf.Asin(g.x / g.magnitude) : Mathf.Asin(g.x / g.magnitude);
         longitude = Mathf.Round((longitude)/angularQuantization) * angularQuantization;
         latStart = Mathf.Clamp(latitude - gridAngle, -Mathf.PI * 0.5, Mathf.PI * 0.5);
         latEnd = Mathf.Clamp(latitude + gridAngle, -Mathf.PI * 0.5, Mathf.PI * 0.5);
         if(Mathf.Abs(latitude) + gridAngle > Mathf.PI * 0.5){
            longStart = longitude - Mathf.PI;
            longEnd = longitude + Mathf.PI;
         } else {
            longStart = longitude - gridAngle - Mathf.Abs(latitude);
            longEnd = longitude + gridAngle + Mathf.Abs(latitude);
         }
      }
   }
}

function OnGUI(){
   if( showUI ){
       GUI.Label (Rect (10, 10, 250, 20), "Dynamic Planet v0.1 ©2008 Tonio Loewald" );
      if( Time.deltaTime > worstTime ){
         worstTime = Time.deltaTime;
      }
      var fps = Mathf.Round(1.0 / worstTime).ToString();
       GUI.Label (Rect (10, 30, 100, 20), "Min FPS: " + fps );
       if ( GUI.Button (Rect (120, 30, 50, 20), "Reset" ) ){
          worstTime = 0;
       }
   }
}

function Update(){
   UpdateGridCenter();
   if( gridDirty ){
      GenerateHeightmap();
      gridDirty = false;
   }
}

function BuildMesh(){
   // Create the game object containing the renderer
   gameObject.AddComponent(MeshFilter);
   gameObject.AddComponent("MeshRenderer");
   if (material)
      renderer.material = material;
   else
      renderer.material.color = Color.white;

   // Retrieve a mesh instance
   mesh = GetComponent(MeshFilter).mesh;
}

function GenerateHeightmap() {  

   // Build vertices and UVs
   var vertices = new Vector3[xRes * yRes];
   var uv = new Vector2[xRes * yRes];
   var tangents = new Vector4[xRes * yRes];
   
   // Cached uv coords (in 0..1)
   var sx : float = 0;
   var sy : float = 0;
   
   // Cached uv coords (in texture dimension) for texture lookups, etc.
   var u : int = 0;
   var v : int = 0;
   
   var pixelHeight : float;
   var vertex : Vector3;
   var vertexL : Vector3;
   var vertexR : Vector3;
   
   // array element
   var i : int = 0;
   var y : int = 0;
   var x : int = 0;
   var latitude : float;
   var latInterval : float = (latEnd - latStart) / (yRes - 1);
   var longitude : float;
   var longInterval : float = (longEnd - longStart) / (xRes - 1);
   var ringRadius : float;
   var ringY : float;
   var maxHeight : float = outerRadius - innerRadius;
   for (y = 0; y < yRes; y++){
      latitude = latStart + y * latInterval;
      ringRadius = Mathf.Cos(latitude);
      ringY = Mathf.Sin(latitude);
      sy = latitude / Mathf.PI + 0.5;
     
      for (x = 0; x < xRes; x++){
         longitude = longStart + x * longInterval;
         
         i = y * xRes + x;
         sx = longitude / Mathf.PI * 0.5 + Mathf.PI * 2.0;
         u = Mathf.Floor(sx * heightMap.width) % heightMap.width;
         v = Mathf.Floor(sy * heightMap.height) % heightMap.height;
         pixelHeight = heightMap.GetPixel(u, v).grayscale;
         if( detailMap ){
            u = Mathf.Floor(sx * detailMap.width * detailMapScale);
            v = Mathf.Floor(sy * detailMap.height * detailMapScale);
            pixelHeight += detailMap.GetPixel(u, v).grayscale * detailMapHeight;
         }
         vertex = Vector3(ringRadius * Mathf.Sin(longitude), ringY, ringRadius * Mathf.Cos(longitude));
         vertices[i] = vertex * (innerRadius + pixelHeight * maxHeight); // Vector3.Scale(size, vertex);
         
         if( textureIsHeightField ){
            uv[i] = Vector2((sx + sy) * textureScale, pixelHeight);
         } else {
            uv[i] = Vector2(sx * textureScale, sy * textureScale);
         }
      }
   }
   
   for (y = 0; y < yRes; y++){
      for (x = 0; x < xRes; x++){
         // Calculate tangent vector: a vector that goes from previous vertex
         // to next along X direction. We need tangents if we intend to
         // use bumpmap shaders on the mesh.
         i = y * xRes + x;
         vertexL = x > 0 ? vertices[i-1] : vertices[i];
         vertexR = x < xRes - 1 ? vertices[i+1] : vertices[i];
         var tan = (vertexR - vertexL).normalized;
         tangents[i] = Vector4( tan.x, tan.y, tan.z, 1.0 );
      }
   }
   
   // Assign them to the mesh
   mesh.vertices = vertices;
   mesh.uv = uv;

   // Build triangle indices: 3 indices into vertex array for each triangle
   var triangles = new int[(yRes - 1) * (xRes - 1) * 6];
   i = 0;
   for (y = 0; y < yRes - 1; y++){
      for (x = 0; x < xRes - 1; x++){
         // For each grid cell output two triangles
         triangles[i++] = (y     * xRes) + x + 1;
         triangles[i++] = ((y+1) * xRes) + x;
         triangles[i++] = (y     * xRes) + x;

         triangles[i++] = (y     * xRes) + x + 1;
         triangles[i++] = ((y+1) * xRes) + x + 1;
         triangles[i++] = ((y+1) * xRes) + x;
      }
   }
   // And assign them to the mesh
   mesh.triangles = triangles;
   mesh.RecalculateBounds(); // fixes the problem
     
   // Auto-calculate vertex normals from the mesh
   mesh.RecalculateNormals();
   
   // Assign tangents after recalculating normals
   mesh.tangents = tangents;
   
   if(!gameObject.GetComponent(MeshCollider)){
      gameObject.AddComponent(MeshCollider);
   }
   gameObject.GetComponent(MeshCollider).sharedMesh = mesh;
}

// Draws a bounding box around where the terrain will end up.
function OnDrawGizmos (){  
   Gizmos.color = Color(0, 1, 1, 0.4);
   Gizmos.DrawWireSphere (transform.position, innerRadius);
   Gizmos.DrawWireSphere (transform.position, outerRadius);
   
   if(patchFocus){
      Gizmos.color = Color(1, 0, 0, 0.6);
      UpdateGridCenter();
      var d = Mathf.Sin( gridAngle ) * innerRadius;
      Gizmos.DrawWireSphere (transform.TransformPoint(gridCenter), d);
   }
}

HTML код для вашего блога :
Код: Выделить всё
<script language='javascript' type="text/javascript"> document.write("<iframe marginheight='0' src='http://unity3d.ru/distribution/player.php?url=http://www.ava.my3space.ru/planet.unity3d&w=600&h=450&t=false&preview=1' height='"+(450+30)+"' width='600' frameborder='0' scrolling='no'></iframe>"); </script>

Пакадж сценки
Planet.unitypackage
У вас нет доступа для просмотра вложений в этом сообщении.
Добавить ava-karaban в Skype
Аватара пользователя
Avatarchik
UNITрон
 
Сообщения: 274
Зарегистрирован: 04 апр 2009, 15:36
Откуда: Украина(Донецк)
  • ICQ

Re: Dynamic Planet Mesh

Сообщение Neodrop 05 апр 2010, 23:02

Это скорее астероид.
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт


Вернуться в Исходники (Копилка)

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3