现在的位置: 首页 > 综合 > 正文

【Unity】Mesh网格编程(三)万能网格几何形体

2018年04月22日 ⁄ 综合 ⁄ 共 6556字 ⁄ 字号 评论关闭

用一个通用代码,实现各种锥、柱、管状体的网格创建。

非原创的同系列。虽然总觉得代码上可以再优化,但是实现的功能已经超级屌了。

真是没有不能做的,只有想不到的。

原文:

Mesh网格编程(二) 万能网格几何体

http://blog.csdn.net/qq_18408937/article/details/44181489

by 涅凡尘

具体思路:

通过Mesh网格编程实现几何体的多种变化。以立体五角星为例,大边长和小边长分别设置长度为5的数组,数组控制几何体顶层空心,顶层大小,中间层大小,底层大小,底层空心。通过循环构建上层与下层之间的网格。

效果图:

实现代码:

[csharp] view
plain
copy

  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class Star3 : MonoBehaviour {  
  5.       
  6.     Mesh mesh;  
  7.   
  8.     public bool sophisticated = false;      //圆滑曲面  
  9.     public bool star = true;                //星形  
  10.     public int line = 5;                    //边数  
  11.     public float[] maxsize = {0,0,5,0,0};   //外角大小  
  12.     public float[] minSize = {0,0,1,0,0};   //内角大小  
  13.     public float high = 1;                  //高度  
  14.     public float low = -1;                  //低度  
  15.       
  16.     private Vector3[] vs;                   //顶点坐标  
  17.     private int[] ts;                       //顶点序列  
  18.     private Vector2[] newUVs;               //UV贴图  
  19.     private Vector3[] newNormals;           //法线  
  20.       
  21.     // Update is called once per frame  
  22.     void Update () {  
  23.         //变量约束  
  24.         line = Mathf.Clamp (line, 2, 300);  
  25.         high = Mathf.Clamp (high, low, high);  
  26.         low = Mathf.Clamp (low, low, high);  
  27.         if (!star) {  
  28.             for (int i = 0; i < 5; i++) {  
  29.                 minSize[i] = Mathf.Cos(Mathf.PI / line) * maxsize[i];  
  30.             }  
  31.         }  
  32.         for (int i = 1; i < 4; i++) {  
  33.             maxsize[i] = Mathf.Clamp (maxsize[i], 0, maxsize[i]);  
  34.             minSize[i] = Mathf.Clamp (minSize[i], 0, maxsize[i]);  
  35.         }  
  36.         maxsize[0] = Mathf.Clamp (maxsize[0], 0, maxsize[1]);  
  37.         minSize[0] = Mathf.Clamp (minSize[0], 0, minSize[1]);  
  38.         maxsize[4] = Mathf.Clamp (maxsize[4], 0, maxsize[3]);  
  39.         minSize[4] = Mathf.Clamp (minSize[4], 0, minSize[3]);  
  40.         //角度计算  
  41.         float corner = 2 * Mathf.PI / line;  
  42.         //确定顶点数量  
  43.         int temp = 5 * 4 * 3 * line;  
  44.           
  45.         vs = new Vector3[temp];  
  46.         ts = new int[temp];  
  47.         newUVs = new Vector2[temp];  
  48.         newNormals = new Vector3[temp];  
  49.   
  50.         int count = 0;  
  51.         float h = 0;  
  52.         float l = 0;  
  53.         for (int i = 0; i < 5; i++) {  
  54.             switch (i) {  
  55.             case 0:   
  56.                 h = high;  
  57.                 l = high;  
  58.                 break;  
  59.             case 1:  
  60.                 h = high;  
  61.                 l = 0;  
  62.                 break;  
  63.             case 2:  
  64.                 h = 0;  
  65.                 l = low;  
  66.                 break;  
  67.             case 3:  
  68.                 h = low;  
  69.                 l = low;  
  70.                 break;  
  71.             case 4:  
  72.                 h = low;  
  73.                 l = high;  
  74.                 break;  
  75.             }  
  76.             for (int k = 0; k < line; k++) {  
  77.                 //确定顶点坐标  
  78.                 vs[count] = new Vector3(Mathf.Sin(k * corner) * maxsize[i],Mathf.Cos(k * corner) * maxsize[i],h);  
  79.                 vs[count + 1] = new Vector3(Mathf.Sin((k + 0.5f) * corner) * minSize[(i + 1) % 5],Mathf.Cos((k + 0.5f) * corner) * minSize[(i + 1) % 5],l);  
  80.                 vs[count + 2] = new Vector3(Mathf.Sin(k * corner) * maxsize[(i + 1) % 5],Mathf.Cos(k * corner) * maxsize[(i + 1) % 5],l);  
  81.   
  82.                 vs[count + 3] = new Vector3(Mathf.Sin(k * corner) * maxsize[i],Mathf.Cos(k * corner) * maxsize[i],h);  
  83.                 vs[count + 4] = new Vector3(Mathf.Sin((k + 0.5f) * corner) * minSize[i],Mathf.Cos((k + 0.5f) * corner) * minSize[i],h);  
  84.                 vs[count + 5] = new Vector3(Mathf.Sin((k + 0.5f) * corner) * minSize[(i + 1) % 5],Mathf.Cos((k + 0.5f) * corner) * minSize[(i + 1) % 5],l);  
  85.   
  86.                 vs[count + 6] = new Vector3(Mathf.Sin(k * corner) * maxsize[i],Mathf.Cos(k * corner) * maxsize[i],h);  
  87.                 vs[count + 7] = new Vector3(Mathf.Sin(k * corner) * maxsize[(i + 1) % 5],Mathf.Cos(k * corner) * maxsize[(i + 1) % 5],l);  
  88.                 vs[count + 8] = new Vector3(Mathf.Sin((k - 0.5f) * corner) * minSize[(i + 1) % 5],Mathf.Cos((k - 0.5f) * corner) * minSize[(i + 1) % 5],l);  
  89.   
  90.                 vs[count + 9] = new Vector3(Mathf.Sin(k * corner) * maxsize[i],Mathf.Cos(k * corner) * maxsize[i],h);  
  91.                 vs[count + 10] = new Vector3(Mathf.Sin((k - 0.5f) * corner) * minSize[(i + 1) % 5],Mathf.Cos((k - 0.5f) * corner) * minSize[(i + 1) % 5],l);  
  92.                 vs[count + 11] = new Vector3(Mathf.Sin((k - 0.5f) * corner) * minSize[i],Mathf.Cos((k - 0.5f) * corner) * minSize[i],h);  
  93.                 //确定法线  
  94.                 if (sophisticated) {  
  95.                     newNormals[count] = Vector3.Normalize(vs[count] - new Vector3(0,0,h));  
  96.                     newNormals[count + 1] = Vector3.Normalize(vs[count + 1] - new Vector3(0,0,l));  
  97.                     newNormals[count + 2] = Vector3.Normalize(vs[count + 2] - new Vector3(0,0,l));  
  98.                     newNormals[count + 3] = Vector3.Normalize(vs[count + 3] - new Vector3(0,0,h));  
  99.                     newNormals[count + 4] = Vector3.Normalize(vs[count + 4] - new Vector3(0,0,h));  
  100.                     newNormals[count + 5] = Vector3.Normalize(vs[count + 5] - new Vector3(0,0,l));  
  101.                     newNormals[count + 6] = Vector3.Normalize(vs[count + 6] - new Vector3(0,0,h));  
  102.                     newNormals[count + 7] = Vector3.Normalize(vs[count + 7] - new Vector3(0,0,l));  
  103.                     newNormals[count + 8] = Vector3.Normalize(vs[count + 8] - new Vector3(0,0,l));  
  104.                     newNormals[count + 9] = Vector3.Normalize(vs[count + 9] - new Vector3(0,0,h));  
  105.                     newNormals[count + 10] = Vector3.Normalize(vs[count + 10] - new Vector3(0,0,l));  
  106.                     newNormals[count + 11] = Vector3.Normalize(vs[count + 11] - new Vector3(0,0,h));  
  107.                 } else {  
  108.                     for (int j = 0; j < 4; j++) {  
  109.                         Vector3 newNormal = Vector3.Cross(vs[count + 3 * j + 1] - vs[count + 3 * j + 0],vs[count + 3 * j + 2] - vs[count + 3 * j + 0]);  
  110.                         for (int z = 0; z < 3; z++) {  
  111.                             newNormals[count + 3 * j + z] = Vector3.Normalize(newNormal);  
  112.                         }  
  113.                     }  
  114.                 }  
  115.   
  116.                 count += 12;  
  117.                 }  
  118.         }  
  119.         //确定顶点序列  
  120.         for (int i = 0; i < ts.Length; i++) {  
  121.             ts[i] = i;  
  122.         }  
  123.         //创建网格  
  124.         mesh = new Mesh();  
  125.         GetComponent<MeshFilter>().mesh = mesh;  
  126.         mesh.vertices = vs;  
  127.         mesh.uv = newUVs;  
  128.         mesh.triangles = ts;  
  129.         mesh.normals = newNormals;  
  130.   
  131.     }  
  132. }  

通过调节变量图中几何体均可实现。Mesh编程步骤见

Mesh网格编程(一)

抱歉!评论已关闭.