Пример #1
0
 // Given a root (aa) and two adjacent vertices (bb, cc), computer the normal for aa
 private static OMV.Vector3 MakeNormal(Vert aa, Vert bb, Vert cc)
 {
     OMV.Vector3 mm        = aa.Position - bb.Position;
     OMV.Vector3 nn        = aa.Position - cc.Position;
     OMV.Vector3 theNormal = OMV.Vector3.Cross(mm, nn);
     theNormal.Normalize();
     return(theNormal);
 }
        private void UpdateRegionTerrainMesh(RegionContextBase rcontext, RegionRenderInfo rri)
        {
            TerrainInfoBase ti = rcontext.TerrainInfo;

            rri.terrainVertices = new float[3 * ti.HeightMapLength * ti.HeightMapWidth];
            rri.terrainTexCoord = new float[2 * ti.HeightMapLength * ti.HeightMapWidth];
            rri.terrainNormal   = new float[3 * ti.HeightMapLength * ti.HeightMapWidth];
            int nextVert = 0;
            int nextTex  = 0;
            int nextNorm = 0;

            for (int xx = 0; xx < ti.HeightMapLength; xx++)
            {
                for (int yy = 0; yy < ti.HeightMapWidth; yy++)
                {
                    rri.terrainVertices[nextVert + 0] = (float)xx / ti.HeightMapLength * rcontext.Size.X;
                    rri.terrainVertices[nextVert + 1] = (float)yy / ti.HeightMapWidth * rcontext.Size.Y;
                    rri.terrainVertices[nextVert + 2] = ti.HeightMap[xx, yy];
                    nextVert += 3;
                    rri.terrainTexCoord[nextTex + 0] = xx / ti.HeightMapLength;
                    rri.terrainTexCoord[nextTex + 1] = yy / ti.HeightMapWidth;
                    nextTex += 2;
                    rri.terrainNormal[nextNorm + 0] = 0f; // simple normal pointing up
                    rri.terrainNormal[nextNorm + 1] = 1f;
                    rri.terrainNormal[nextNorm + 2] = 0f;
                    nextNorm += 3;
                }
            }
            // Create the quads which make up the terrain
            rri.terrainIndices = new UInt16[4 * ti.HeightMapLength * ti.HeightMapWidth];
            int nextInd = 0;

            for (int xx = 0; xx < ti.HeightMapLength - 1; xx++)
            {
                for (int yy = 0; yy < ti.HeightMapWidth - 1; yy++)
                {
                    rri.terrainIndices[nextInd + 0] = (UInt16)((yy + 0) + (xx + 0) * ti.HeightMapLength);
                    rri.terrainIndices[nextInd + 1] = (UInt16)((yy + 1) + (xx + 0) * ti.HeightMapLength);
                    rri.terrainIndices[nextInd + 2] = (UInt16)((yy + 1) + (xx + 1) * ti.HeightMapLength);
                    rri.terrainIndices[nextInd + 3] = (UInt16)((yy + 0) + (xx + 1) * ti.HeightMapLength);
                    nextInd += 4;
                }
            }
            rri.terrainWidth  = ti.HeightMapWidth;
            rri.terrainLength = ti.HeightMapLength;

            // Calculate normals
            // Take three corners of each quad and calculate the normal for the vector
            //   a--b--e--...
            //   |  |  |
            //   d--c--h--...
            // The triangle a-b-d calculates the normal for a, etc
            int nextQuad = 0;
            int nextNrm  = 0;

            for (int xx = 0; xx < ti.HeightMapLength - 1; xx++)
            {
                for (int yy = 0; yy < ti.HeightMapWidth - 1; yy++)
                {
                    OMV.Vector3 aa, bb, cc;
                    int         offset = rri.terrainIndices[nextQuad + 0] * 3;
                    aa.X   = rri.terrainVertices[offset + 0];
                    aa.Y   = rri.terrainVertices[offset + 1];
                    aa.Z   = rri.terrainVertices[offset + 2];
                    offset = rri.terrainIndices[nextQuad + 1] * 3;
                    bb.X   = rri.terrainVertices[offset + 0];
                    bb.Y   = rri.terrainVertices[offset + 1];
                    bb.Z   = rri.terrainVertices[offset + 2];
                    offset = rri.terrainIndices[nextQuad + 3] * 3;
                    cc.X   = rri.terrainVertices[offset + 0];
                    cc.Y   = rri.terrainVertices[offset + 1];
                    cc.Z   = rri.terrainVertices[offset + 2];
                    OMV.Vector3 mm        = aa - bb;
                    OMV.Vector3 nn        = aa - cc;
                    OMV.Vector3 theNormal = -OMV.Vector3.Cross(mm, nn);
                    theNormal.Normalize();
                    rri.terrainNormal[nextNrm + 0] = theNormal.X; // simple normal pointing up
                    rri.terrainNormal[nextNrm + 1] = theNormal.Y;
                    rri.terrainNormal[nextNrm + 2] = theNormal.Z;
                    nextNrm  += 3;
                    nextQuad += 4;
                }
                rri.terrainNormal[nextNrm + 0] = 1.0f;
                rri.terrainNormal[nextNrm + 1] = 0.0f;
                rri.terrainNormal[nextNrm + 2] = 0.0f;
                nextNrm += 3;
            }
        }