我有一个体素引擎,我试图优化Don不重复自己。有没有办法解决这个长期存在的混乱局面?

时间:2014-04-13 14:40:56

标签: c# game-engine voxel

对于每个块类型,我必须重复一段代码,多次生成每个面。我知道必须有一个更好的方法,但是我确实尝试将这些部分放在每个面部的一个函数中,并且即使使用ref也会出现问题。

                    if (block.blockType == 1 && top == 0)
                {
                    vertexIndex = vertices.Count;
                    vertices.Add(new Vector3(x, y + 1, z));
                    vertices.Add(new Vector3(x, y + 1, z + 1));
                    vertices.Add(new Vector3(x + 1, y + 1, z + 1));
                    vertices.Add(new Vector3(x + 1, y + 1, z));
                    // first triangle for the block top
                    triangles.Add(vertexIndex);
                    triangles.Add(vertexIndex + 1);
                    triangles.Add(vertexIndex + 2);
                    // second triangle for the block top
                    triangles.Add(vertexIndex + 2);
                    triangles.Add(vertexIndex + 3);
                    triangles.Add(vertexIndex);
                    // add UV
                    uvs.Add(new Vector2 (0.125f, 0.0f));
                    uvs.Add(new Vector2 (0.25f, 0.0f));
                    uvs.Add(new Vector2 (0.25f, 0.125f));
                    uvs.Add(new Vector2 (0.125f, 0.125f));

                }

这是一个典型的部分(没有StackOverflow格式化) - 我能用它做什么?

2 个答案:

答案 0 :(得分:1)

  1. 您应该在单个平面阵列中处理3个阵列(顶点/顶点索引/ uv坐标),在填充实际值之前预先填充0。 表演会飙升。
  2. 我想知道你的顶点索引是否每次都不包含相同的序列。您只能存储一个vertexIndex而不是6个数字(+0 +1 +2 +2 +3 +0)。但也许你想要为webgl设置索引。
  3. 。 为了分解,我会做出像这样的6个函数:

    Vertices.prototype.AddVerticesUP = function(x, y, z) {
         var currIndex = this.lastIndex;
         var vertArr = this.verticeArray;
         vertArr[currIndex]=vertArr[currIndex+3]=
               vertArr[currIndex+6]=vertArr[currIndex+9] = x;
          vertArr[currIndex+1]=vertArr[currIndex+4]=
              vertArr[currIndex+7]=vertArr[currIndex+10] = y;
         vertArr[currIndex+2]=vertArr[currIndex+5]=
               vertArr[currIndex+8]=vertArr[currIndex+11] =z;      
         // first point
         vertArr[currIndex+1]++;
         // second
         vertArr[currIndex+4]++; vertArr[currIndex+5]++;
         // third
         vertArr[currIndex+6]++;vertArr[currIndex+7]++;vertArr[currIndex+8]++;
         // fourth
         vertArr[currIndex+9]++;vertArr[currIndex+10]++;    
         this.lastIndex +=12;     
    }
    

    然后从中构建一个数组:

    Vertices.prototype.AddVertices= [ Vertices.prototype.AddVerticesUP,
                                      Vertices.prototype.AddVerticesDOWN, 
                                      Vertices.prototype.AddVerticesLEFT,
                                      Vertices.prototype.AddVerticesRIGHT,
                                      Vertices.prototype.AddVerticesFRONT,
                                      Vertices.prototype.AddVerticesBACK] ;
    

    要使用该数组,如果dir是方向,只需执行:

    Vertices.AddVertices [dir] ( x,y,z );
    

    对于您的紫外坐标,您也可以简化,因为所有坐标都是轴对齐和方形。签名可以是:uvs.addSquareUVs(baseU,baseV,size)。但如果猜对了,坐标只取决于边+块类型。因此,您可以使用与上述相同的机制制作6个函数,签名将为uvs.addUV [dir] (block type)uvs.addUV [dir] [block type] ()

    现在每个6的if / else,乘以块类型的数量可以大大简化为这个代码:

    vertexIndex = vertices.Count;
    vertices.AddVertices [direction] ( x, y, z);
    triangles.AddSquareStartingAt(vertexIndex);
    uvs.addSquareUVs [direction] [block.blockType] ();
    

答案 1 :(得分:0)

对于顶点添加和uv坐标,您可以在某处定义静态集合:

public static readonly Vector3[] Corners = new Vector3[]{new Vector3(0, 1, 0), new Vector3(0, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 0)};
public static readonly Vector2[] UVCorners = new Vector2[]{new Vector2(0, 0), new Vector2(0.125f, 0), new Vector2(0.125f, 0.125f), new Vector2(0, 0.125f)};

然后你可以让这个部分更紧凑:

            if (block.blockType == 1 && top == 0)
            {
                vertexIndex = vertices.Count;
                Vector3 origin = new Vector3(x, y, z);
                foreach (Vector3 corner in Corners) vertices.Add(origin + corner);
                // first triangle for the block top
                triangles.Add(vertexIndex);
                triangles.Add(vertexIndex + 1);
                triangles.Add(vertexIndex + 2);
                // second triangle for the block top
                triangles.Add(vertexIndex + 2);
                triangles.Add(vertexIndex + 3);
                triangles.Add(vertexIndex);
                // add UV
                Vector2 uvOrigin = new Vector2(0.125f, 0);
                foreach (Vector2 uvCorner in UVCorners) uvs.Add(uvOrigin + uvCorner);
            }