1. 程式人生 > >Unity3D-Mesh建立中三角形索引的演算法

Unity3D-Mesh建立中三角形索引的演算法

解釋一下上一篇中Mesh的三角形索引演算法。

首先是要知道頂點陣列是如何產生的:


如此圖,一個大矩形,是由6個頂點,兩個矩形構成的。

一般來講,構建此矩形,需要知道每個頂點的位置,以及頂點和頂點之間的關係。

ok,

    // 初始化頂點位置
    private void initVertexPos()
    {
        int currentIndex = 0;

        for (int i = 0; i < ConstNumber.YLength; i++)
        {
            for (int j = 0; j < ConstNumber.XLength; j++)
            {
                vertices[currentIndex] = new Vector3(j, 0, i);
                currentIndex++;
            }
        }
    }

這一步,就是講頂點的位置按一定的次序排列進陣列


那麼,索引陣列就是存這些0,1,2,3...這些頂點陣列索引值。

已知,三角形有3個頂點,所以每3個為一組,構造一個三角形。

矩形由兩個三角形產生,可以如圖劃分,也可以垂直於黃線

那麼,我們規定按順時針方向構造(注意,要麼全順時針,要麼全逆時針)

得到 0,3,4,0,4,1,1,4,5,1,5,2


實現的演算法就是

    // 初始化三角形索引
    private void initTriangles()
    {
        // 代表triangl陣列當前索引值,每放入陣列中一個值,currentIndex都增1
        int currentIndex = 0;
        
        for (int i = 0; i < ConstNumber.YLength - 1; i++)
        {
            for (int j = 0; j < ConstNumber.XLength - 1; j++)
            {
                // 順時針畫左上角三角形
                triangles[currentIndex++] = (i + 0) * ConstNumber.XLength + (j + 0);
                triangles[currentIndex++] = (i + 1) * ConstNumber.XLength + (j + 0);
                triangles[currentIndex++] = (i + 1) * ConstNumber.XLength + (j + 1);

                // 順時針畫右下角三角形
                triangles[currentIndex++] = (i + 0) * ConstNumber.XLength + (j + 0);
                triangles[currentIndex++] = (i + 1) * ConstNumber.XLength + (j + 1);
                triangles[currentIndex++] = (i + 0) * ConstNumber.XLength + (j + 1);

            }
        }
         
    }


這是一種實現方式,是以整體的矩形來分析。

我自己還寫了另外一種索引演算法,是以矩形左下角為基準,表達整個矩形。

因為你知道了矩形的一個點,矩形單位長度為1,你就可以知道其他點的位置。

ok,看演算法

    // 初始化三角形索引
    private void initTriangles()
    {
        float xdelta = 1.0f / (float)(ConstNumber.XLength - 1);
        float ydelta = 1.0f / (float)(ConstNumber.YLength - 1);
        int currentPosNum = 0;
        for (int i = 0; i < ConstNumber.YLength; i++)
        {
            for (int j = 0; j < ConstNumber.XLength; j++)
            {
                vertices[currentPosNum] = new Vector3(j * xdelta, 0, i * ydelta);
                currentPosNum++;
            }
        }
         
    }


這個樣,只需要遍歷一遍所有的頂點(而且有些頂點無需遍歷)只有一層for就OK了。

不過它的缺點也和它的優點一樣明顯,就是長必須大於寬。

其實,是可以彌補的,不過今天事情太多了,我只做記錄了~~~~