您的位置:首页 > 移动开发 > Unity3D

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

2015-03-14 19:54 453 查看
用一个通用代码,实现各种锥、柱、管状体的网格创建。

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

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

原文:

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


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

by 涅凡尘

具体思路:

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

效果图:



实现代码:

[csharp] view
plaincopy

using UnityEngine;  

using System.Collections;  

  

public class Star3 : MonoBehaviour {  

      

    Mesh mesh;  

  

    public bool sophisticated = false;      //圆滑曲面  

    public bool star = true;                //星形  

    public int line = 5;                    //边数  

    public float[] maxsize = {0,0,5,0,0};   //外角大小  

    public float[] minSize = {0,0,1,0,0};   //内角大小  

    public float high = 1;                  //高度  

    public float low = -1;                  //低度  

      

    private Vector3[] vs;                   //顶点坐标  

    private int[] ts;                       //顶点序列  

    private Vector2[] newUVs;               //UV贴图  

    private Vector3[] newNormals;           //法线  

      

    // Update is called once per frame  

    void Update () {  

        //变量约束  

        line = Mathf.Clamp (line, 2, 300);  

        high = Mathf.Clamp (high, low, high);  

        low = Mathf.Clamp (low, low, high);  

        if (!star) {  

            for (int i = 0; i < 5; i++) {  

                minSize[i] = Mathf.Cos(Mathf.PI / line) * maxsize[i];  

            }  

        }  

        for (int i = 1; i < 4; i++) {  

            maxsize[i] = Mathf.Clamp (maxsize[i], 0, maxsize[i]);  

            minSize[i] = Mathf.Clamp (minSize[i], 0, maxsize[i]);  

        }  

        maxsize[0] = Mathf.Clamp (maxsize[0], 0, maxsize[1]);  

        minSize[0] = Mathf.Clamp (minSize[0], 0, minSize[1]);  

        maxsize[4] = Mathf.Clamp (maxsize[4], 0, maxsize[3]);  

        minSize[4] = Mathf.Clamp (minSize[4], 0, minSize[3]);  

        //角度计算  

        float corner = 2 * Mathf.PI / line;  

        //确定顶点数量  

        int temp = 5 * 4 * 3 * line;  

          

        vs = new Vector3[temp];  

        ts = new int[temp];  

        newUVs = new Vector2[temp];  

        newNormals = new Vector3[temp];  

  

        int count = 0;  

        float h = 0;  

        float l = 0;  

        for (int i = 0; i < 5; i++) {  

            switch (i) {  

            case 0:   

                h = high;  

                l = high;  

                break;  

            case 1:  

                h = high;  

                l = 0;  

                break;  

            case 2:  

                h = 0;  

                l = low;  

                break;  

            case 3:  

                h = low;  

                l = low;  

                break;  

            case 4:  

                h = low;  

                l = high;  

                break;  

            }  

            for (int k = 0; k < line; k++) {  

                //确定顶点坐标  

                vs[count] = new Vector3(Mathf.Sin(k * corner) * maxsize[i],Mathf.Cos(k * corner) * maxsize[i],h);  

                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);  

                vs[count + 2] = new Vector3(Mathf.Sin(k * corner) * maxsize[(i + 1) % 5],Mathf.Cos(k * corner) * maxsize[(i + 1) % 5],l);  

  

                vs[count + 3] = new Vector3(Mathf.Sin(k * corner) * maxsize[i],Mathf.Cos(k * corner) * maxsize[i],h);  

                vs[count + 4] = new Vector3(Mathf.Sin((k + 0.5f) * corner) * minSize[i],Mathf.Cos((k + 0.5f) * corner) * minSize[i],h);  

                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);  

  

                vs[count + 6] = new Vector3(Mathf.Sin(k * corner) * maxsize[i],Mathf.Cos(k * corner) * maxsize[i],h);  

                vs[count + 7] = new Vector3(Mathf.Sin(k * corner) * maxsize[(i + 1) % 5],Mathf.Cos(k * corner) * maxsize[(i + 1) % 5],l);  

                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);  

  

                vs[count + 9] = new Vector3(Mathf.Sin(k * corner) * maxsize[i],Mathf.Cos(k * corner) * maxsize[i],h);  

                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);  

                vs[count + 11] = new Vector3(Mathf.Sin((k - 0.5f) * corner) * minSize[i],Mathf.Cos((k - 0.5f) * corner) * minSize[i],h);  

                //确定法线  

                if (sophisticated) {  

                    newNormals[count] = Vector3.Normalize(vs[count] - new Vector3(0,0,h));  

                    newNormals[count + 1] = Vector3.Normalize(vs[count + 1] - new Vector3(0,0,l));  

                    newNormals[count + 2] = Vector3.Normalize(vs[count + 2] - new Vector3(0,0,l));  

                    newNormals[count + 3] = Vector3.Normalize(vs[count + 3] - new Vector3(0,0,h));  

                    newNormals[count + 4] = Vector3.Normalize(vs[count + 4] - new Vector3(0,0,h));  

                    newNormals[count + 5] = Vector3.Normalize(vs[count + 5] - new Vector3(0,0,l));  

                    newNormals[count + 6] = Vector3.Normalize(vs[count + 6] - new Vector3(0,0,h));  

                    newNormals[count + 7] = Vector3.Normalize(vs[count + 7] - new Vector3(0,0,l));  

                    newNormals[count + 8] = Vector3.Normalize(vs[count + 8] - new Vector3(0,0,l));  

                    newNormals[count + 9] = Vector3.Normalize(vs[count + 9] - new Vector3(0,0,h));  

                    newNormals[count + 10] = Vector3.Normalize(vs[count + 10] - new Vector3(0,0,l));  

                    newNormals[count + 11] = Vector3.Normalize(vs[count + 11] - new Vector3(0,0,h));  

                } else {  

                    for (int j = 0; j < 4; j++) {  

                        Vector3 newNormal = Vector3.Cross(vs[count + 3 * j + 1] - vs[count + 3 * j + 0],vs[count + 3 * j + 2] - vs[count + 3 * j + 0]);  

                        for (int z = 0; z < 3; z++) {  

                            newNormals[count + 3 * j + z] = Vector3.Normalize(newNormal);  

                        }  

                    }  

                }  

  

                count += 12;  

                }  

        }  

        //确定顶点序列  

        for (int i = 0; i < ts.Length; i++) {  

            ts[i] = i;  

        }  

        //创建网格  

        mesh = new Mesh();  

        GetComponent<MeshFilter>().mesh = mesh;  

        mesh.vertices = vs;  

        mesh.uv = newUVs;  

        mesh.triangles = ts;  

        mesh.normals = newNormals;  

  

    }  

}  

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

Mesh网格编程(一)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: