如何在Lua中压缩3维数组?

时间:2019-04-05 21:48:18

标签: lua

所以,在Lua中,我基本上是三维数组,实际上是体素系统。看起来像这样:

  local VoxelTable = {
    [1] = { --X
      [5] = { --Y
        [2] = { --Z
          ["Type"] = "Solid",
          ["Rotation"] = "InverseX",
          ["Material"] = "Grass",
          ["Size"]     = Vector3.new(1,1,1) 
          --A 1x1x1 Solid grass block with rotation "InverseX"
        }
      }
    }
}

生成了体素,因此无法手动压缩它们。但是,如果没有压缩渲染,游戏的性能将大大下降。

我想做的是,如果在彼此之间的上/下有三个草块具有相同的旋转值,我将它们组合为一个体素,其大小为Vector3.new(1,3,1),并且中间体素的位置。

所以

[1] = { --X
  [5] = { --Y
    [2] = { --Z
      ["Type"] = "Solid",
      ["Rotation"] = "InverseX",
      ["Material"] = "Grass",
      ["Size"]     = Vector3.new(1,1,1) 
    }
  },
  [6] = { --Y
    [2] = { --Z
      ["Type"] = "Solid",
      ["Rotation"] = "InverseX",
      ["Material"] = "Grass",
      ["Size"]     = Vector3.new(1,1,1) 
    }
  },
  [7] = { --Y
    [2] = { --Z
      ["Type"] = "Solid",
      ["Rotation"] = "InverseX",
      ["Material"] = "Grass",
      ["Size"]     = Vector3.new(1,1,1) 
    }
  }
}

成为

[1] = { --X
  [6] = { --Y
    [2] = { --Z
      ["Type"] = "Solid",
      ["Rotation"] = "InverseX",
      ["Material"] = "Grass",
      ["Size"]     = Vector3.new(1,3,1) 
    }
  }
}

1 个答案:

答案 0 :(得分:1)

这是一个稍微简化的示例。我创建了一个10 x 10 x 10的体素立方体,为每个体素赋予vec3大小属性(如您所愿)和一个随机字母属性(a,b或c)。然后,我遍历体素,上下查找。如果我所在的体素具有与上方和下方的体素相同的字母属性,则将上方和下方的体素设置为nil,并增加中间体素的大小属性。我敢肯定,这一切都可以进行优化,而且我敢肯定,除了这种硬编码的三个相同的体素堆栈之外,更复杂的逻辑还可以寻找其他体素关系。但这是一个开始:

local world = {}
local letters = {"a", "b", "c"}

function setup()    
    -- Create simplified test data
    for x = 1, 10 do
        world[x] = {}

        for y = 1, 10 do
            world[x][y] = {}

            for z = 1, 10 do    
                world[x][y][z] = {}

                local randomIndex = math.random(1, 3)
                world[x][y][z].letter = letters[randomIndex]
                world[x][y][z].size = vec3(1, 1, 1)  
            end
        end
    end

    -- Combine common stacks of three
    for x = 1, 10 do
        for y = 2, 9 do -- Ensure there is at least a level below (y == 1) or above (y == 10)
            for z = 1, 10 do
                combineStacks(x, y, z)
            end
        end
    end
end
function combineStacks(x, y, z)
    local low = world[x][y - 1][z]
    local mid = world[x][y][z]
    local high = world[x][y + 1][z]

    if low ~= nil and mid ~= nil and high ~= nil then
        if low.letter == mid.letter and mid.letter == high.letter then
            world[x][y - 1][z] = nil -- low
            world[x][y + 1][z] = nil -- high

            mid.size = vec3(1, 3, 1)
            print("Stack of three identical voxels found!")
        end
    end
end

以上内容是在Codea中编写和测试的(并可视化,如下所示)。 vec3构造是该环境的本机,而不是Lua的本机,因此请记住这一点。

这是结果的2D可视化,每个正方形显示一个体素立方体的一部分。如果您看到一个黄色的点(代表三个堆栈!),请查看左侧和右侧的正方形切片,并在同一位置看到体素为nil:

enter image description here