Reputation: 51
So, I have what is basically a three-dimensional array in Lua, really a voxel system. It looks like this:
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"
}
}
}
}
The Voxels are generated, and because of that I can't compress them manually. But without compression rendering lags the game down a lot.
What I want to do is if there are three grass blocks right above/below eachother with the same rotation value, I combine them into one voxel, with a size of Vector3.new(1,3,1), with the position of the middle voxel.
So
[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)
}
}
}
becomes
[1] = { --X
[6] = { --Y
[2] = { --Z
["Type"] = "Solid",
["Rotation"] = "InverseX",
["Material"] = "Grass",
["Size"] = Vector3.new(1,3,1)
}
}
}
Upvotes: 2
Views: 320
Reputation: 1671
Here’s a somewhat simplified example. I’ve created a 10 x 10 x 10 cube of voxels, giving each voxel a vec3 size attribute (as you have it) and a random letter attribute (a, b, or c). I then iterate over the voxels, looking up and down. If the voxel I’m on has the same letter attribute as the voxel above and below, then I set the above and below voxels to nil, and increase the size attribute of the middle voxel. I am sure this could all be optimized, and I’m sure more sophisticated logic could look for other voxel relationships besides this hard-coded stack-of-three identical voxels. But this is a start:
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
The above was written and tested (and visualized, shown below) in Codea. The vec3 construct is native to that environment and not to Lua in general, so keep that in mind.
Here’s a 2D visualization of the results, with each square showing a slice of the voxel cube. If you see a yellow point (representing a stack of three!), look at the square slice to the left and right, and at the same location you will see the voxels there are nil:
Upvotes: 1