我如何在Lua中压缩三维数组?

问题描述 投票:2回答:1

所以,我在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) 
    }
  }
}
lua
1个回答
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可视化,每个方块显示一个体素立方体的切片。如果你看到一个黄点(代表一堆三个!),看看左边和右边的方形切片,在同一个位置,你会看到体素有零:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.