Work on static lighting code
This commit is contained in:
parent
57e4544fee
commit
0e2a45665d
|
@ -325,6 +325,13 @@ function Box3.lerp(box, lerp)
|
||||||
return Vector3.lerp(box.min, box.max, lerp)
|
return Vector3.lerp(box.min, box.max, lerp)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Finds a lerp value, x, such that box:lerp(x) == pos
|
||||||
|
--- @function pos
|
||||||
|
--- @treturn Vector3
|
||||||
|
function Box3.unlerp(box, pos)
|
||||||
|
return (pos - box.min) / (box.max - box.min)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Linearly interpolates between the min and max of the box
|
--- Linearly interpolates between the min and max of the box
|
||||||
--- @function union
|
--- @function union
|
||||||
|
@ -436,6 +443,102 @@ local function isColor4(obj)
|
||||||
return type(obj) == 'table' and type(obj.r) == 'number' and type(obj.g) == 'number' and type(obj.b) == 'number' and type(obj.a) == 'number'
|
return type(obj) == 'table' and type(obj.r) == 'number' and type(obj.g) == 'number' and type(obj.b) == 'number' and type(obj.a) == 'number'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @type Color4
|
||||||
|
--- @tfield number r
|
||||||
|
--- @tfield number g
|
||||||
|
--- @tfield number b
|
||||||
|
--- @tfield number a
|
||||||
|
Color4.__index = Color4;
|
||||||
|
|
||||||
|
|
||||||
|
--- @function __eq
|
||||||
|
--- @tparam number|Color4 b
|
||||||
|
--- @treturn Color4
|
||||||
|
function Color4.__eq(a, b)
|
||||||
|
if (type(a) == 'number') then
|
||||||
|
return a == b.r and a == b.g and a == b.b and a == b.a
|
||||||
|
end
|
||||||
|
|
||||||
|
if (type(b) == 'number') then
|
||||||
|
return a.r == b and a.g == b and a.b + b and a.a == b
|
||||||
|
end
|
||||||
|
|
||||||
|
if (not isColor4(b)) then
|
||||||
|
error('Color4.__eq expected another vector as second operand', 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
return a.r == b.r and a.g == b.g and a.b == b.b and a.a == a.a
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @function __add
|
||||||
|
--- @tparam number|Color4 b
|
||||||
|
--- @treturn Color4
|
||||||
|
function Color4.__add(a, b)
|
||||||
|
if (type(a) == 'number') then
|
||||||
|
return color4(a + b.r, a + b.g, a + b.b, a + b.a)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (type(b) == 'number') then
|
||||||
|
return color4(a.r + b, a.g + b, a.b + b, a.a + b)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (not isColor4(b)) then
|
||||||
|
error('Color4.__add expected another vector as second operand got ' .. type(b), 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
return color4(a.r + b.r, a.g + b.g, a.b + b.b, a.a + b.a)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @function __sub
|
||||||
|
--- @tparam number|Color4 b
|
||||||
|
--- @treturn Color4
|
||||||
|
function Color4.__sub(a, b)
|
||||||
|
if (type(a) == 'number') then
|
||||||
|
return color4(a - b.r, a - b.g, a - b.b, a - b.a)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (type(b) == 'number') then
|
||||||
|
return color4(a.r - b, a.g - b, a.b - b, a.a - b)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (not isColor4(b)) then
|
||||||
|
error('Color4.__sub expected another vector as second operand', 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (a == nil) then
|
||||||
|
print(debug.traceback())
|
||||||
|
end
|
||||||
|
|
||||||
|
return color4(a.r - b.r, a.g - b.g, a.b - b.b, a.a - b.a)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @function __mul
|
||||||
|
--- @tparam number|Color4 b
|
||||||
|
--- @treturn Color4
|
||||||
|
function Color4.__mul(a, b)
|
||||||
|
if (type(a) == 'number') then
|
||||||
|
return color4(a * b.r, a * b.g, a * b.b, a * b.a)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (type(b) == 'number') then
|
||||||
|
return color4(a.r * b, a.g * b, a.b * b, a.a * b)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (not isColor4(b)) then
|
||||||
|
error('Color4.__mul expected another vector or number as second operand got ' .. type(b), 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
return color4(a.r * b.r, a.g * b.g, a.b * b.b, a.a * b.a)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Linearly interpolates between two points
|
||||||
|
--- @function lerp
|
||||||
|
--- @tparam Color4 b
|
||||||
|
--- @treturn Color4
|
||||||
|
function Color4.lerp(a, b, lerp)
|
||||||
|
return a * (1 - lerp) + b * lerp
|
||||||
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
vector3 = vector3,
|
vector3 = vector3,
|
||||||
Vector3 = Vector3,
|
Vector3 = Vector3,
|
||||||
|
|
|
@ -219,10 +219,17 @@ void meshToLua(lua_State* L, std::shared_ptr<ExtendedMesh> mesh) {
|
||||||
toLua(L, mesh->mMesh->mFaces, mesh->mMesh->mNumFaces);
|
toLua(L, mesh->mMesh->mFaces, mesh->mMesh->mNumFaces);
|
||||||
lua_setfield(L, -2, "faces");
|
lua_setfield(L, -2, "faces");
|
||||||
|
|
||||||
if (mesh->mMesh->mColors[0]) {
|
lua_createtable(L, AI_MAX_NUMBER_OF_COLOR_SETS, 0);
|
||||||
toLuaLazyArray<aiColor4D>(L, mesh->mMesh->mColors[0], mesh->mMesh->mNumVertices);
|
for (int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
|
||||||
} else {
|
if (!mesh->mMesh->mColors[i]) {
|
||||||
lua_pushnil(L);
|
mesh->mMesh->mColors[i] = new aiColor4D[mesh->mMesh->mNumVertices];
|
||||||
|
|
||||||
|
for (unsigned vertexIndex = 0; vertexIndex < mesh->mMesh->mNumVertices; ++vertexIndex) {
|
||||||
|
mesh->mMesh->mColors[i][vertexIndex] = aiColor4D(1.0, 1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toLuaLazyArray<aiColor4D>(L, mesh->mMesh->mColors[i], mesh->mMesh->mNumVertices);
|
||||||
|
lua_seti(L, -2, i + 1);
|
||||||
}
|
}
|
||||||
lua_setfield(L, -2, "colors");
|
lua_setfield(L, -2, "colors");
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ local entities = require('tools.level_scripts.entities')
|
||||||
local signals = require('tools.level_scripts.signals')
|
local signals = require('tools.level_scripts.signals')
|
||||||
local animation = require('tools.level_scripts.animation')
|
local animation = require('tools.level_scripts.animation')
|
||||||
local dynamic_collision = require('tools.level_scripts.dynamic_collision_export')
|
local dynamic_collision = require('tools.level_scripts.dynamic_collision_export')
|
||||||
|
local static_lighting = require('tools.level_scripts.static_lighting')
|
||||||
|
|
||||||
sk_definition_writer.add_definition("level", "struct LevelDefinition", "_geo", {
|
sk_definition_writer.add_definition("level", "struct LevelDefinition", "_geo", {
|
||||||
collisionQuads = sk_definition_writer.reference_to(collision_export.collision_objects, 1),
|
collisionQuads = sk_definition_writer.reference_to(collision_export.collision_objects, 1),
|
||||||
|
|
134
tools/level_scripts/static_lighting.lua
Normal file
134
tools/level_scripts/static_lighting.lua
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
|
||||||
|
local sk_scene = require('sk_scene')
|
||||||
|
local sk_math = require('sk_math');
|
||||||
|
|
||||||
|
local ambient_nodes = sk_scene.nodes_for_type('@ambient')
|
||||||
|
|
||||||
|
local ambient_blocks = {}
|
||||||
|
|
||||||
|
local function build_ambient_block(ambient_mesh)
|
||||||
|
local midpoint = sk_math.vector3(0, 0, 0)
|
||||||
|
local min = ambient_mesh.vertices[1]
|
||||||
|
local max = ambient_mesh.vertices[1]
|
||||||
|
|
||||||
|
for _, vector in pairs(ambient_mesh.vertices) do
|
||||||
|
midpoint = midpoint + vector
|
||||||
|
min = min:min(vector)
|
||||||
|
max = max:max(vector)
|
||||||
|
end
|
||||||
|
|
||||||
|
midpoint = midpoint * (1 / #ambient_mesh.vertices)
|
||||||
|
|
||||||
|
local colors = {}
|
||||||
|
|
||||||
|
for index, vector in pairs(ambient_mesh.vertices) do
|
||||||
|
local corner_index = 1
|
||||||
|
|
||||||
|
if (vector.x > midpoint.x) then
|
||||||
|
corner_index = corner_index + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if (vector.y > midpoint.y) then
|
||||||
|
corner_index = corner_index + 2
|
||||||
|
end
|
||||||
|
|
||||||
|
if (vector.z > midpoint.z) then
|
||||||
|
corner_index = corner_index + 4
|
||||||
|
end
|
||||||
|
|
||||||
|
colors[corner_index] = ambient_mesh.colors[1] and ambient_mesh.colors[1][index]
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
bb = sk_math.box3(min, max),
|
||||||
|
colors = colors,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function evaluate_ambient_block(block, pos, normal)
|
||||||
|
local lerp_values = block.bb:unlerp(pos)
|
||||||
|
|
||||||
|
local x0 = block.colors[1]:lerp(block.colors[2], lerp_values.x)
|
||||||
|
local x1 = block.colors[3]:lerp(block.colors[4], lerp_values.x)
|
||||||
|
local x2 = block.colors[5]:lerp(block.colors[6], lerp_values.x)
|
||||||
|
local x3 = block.colors[7]:lerp(block.colors[8], lerp_values.x)
|
||||||
|
|
||||||
|
local y0 = x0:lerp(x1, lerp_values.y)
|
||||||
|
local y1 = x2:lerp(x3, lerp_values.y)
|
||||||
|
|
||||||
|
return y0:lerp(y1, lerp_values.z)
|
||||||
|
end
|
||||||
|
|
||||||
|
for index, ambient_node in pairs(ambient_nodes) do
|
||||||
|
for _, mesh in pairs(ambient_node.node.meshes) do
|
||||||
|
local global_mesh = mesh:transform(ambient_node.node.full_transformation)
|
||||||
|
|
||||||
|
table.insert(ambient_blocks, build_ambient_block(global_mesh))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function find_nearest_ambient_boxes(pos, max_count)
|
||||||
|
local boxes = {};
|
||||||
|
local distances = {};
|
||||||
|
|
||||||
|
for _, ambient_block in pairs(ambient_blocks) do
|
||||||
|
local distance = ambient_block.bb:distance_to_point(pos)
|
||||||
|
|
||||||
|
-- if inside a block just return it
|
||||||
|
if distance <= 0 then
|
||||||
|
return {ambient_block}, {1}
|
||||||
|
end
|
||||||
|
|
||||||
|
local insert_index = #boxes + 1
|
||||||
|
|
||||||
|
for index, other_distance in pairs(distances) do
|
||||||
|
if distance < other_distance then
|
||||||
|
insert_index = index
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if insert_index < max_count then
|
||||||
|
table.insert(boxes, insert_index, ambient_block)
|
||||||
|
table.insert(distances, insert_index, distance)
|
||||||
|
|
||||||
|
if #boxes > max_count then
|
||||||
|
table.remove(boxes)
|
||||||
|
table.remove(distances)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local weights = {}
|
||||||
|
local total_weight = 0
|
||||||
|
|
||||||
|
for index, distance in pairs(distances) do
|
||||||
|
total_weight = total_weight + distance
|
||||||
|
weights[index] = distance
|
||||||
|
end
|
||||||
|
|
||||||
|
for index, _ in pairs(weights) do
|
||||||
|
weights[index] = 1 - weights[index] / total_weight
|
||||||
|
end
|
||||||
|
|
||||||
|
return boxes, weights
|
||||||
|
end
|
||||||
|
|
||||||
|
local function light_vertex(pos, normal)
|
||||||
|
local boxes, weights = find_nearest_ambient_boxes(pos, 2)
|
||||||
|
|
||||||
|
if #boxes == 0 then
|
||||||
|
return sk_math.color4(1, 1, 1, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local result = sk_math.color4(0, 0, 0, 0)
|
||||||
|
|
||||||
|
for index, block in pairs(boxes) do
|
||||||
|
result = result + evaluate_ambient_block(block, pos, normal) * weights[index]
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
light_vertex = light_vertex,
|
||||||
|
}
|
Loading…
Reference in a new issue