-- Buildat: builtin/ground_plane_lighting/client_lua/module.lua -- http://www.apache.org/licenses/LICENSE-2.0 -- Copyright 2014 Perttu Ahola local dump = buildat.dump local log = buildat.Logger("ground_plane_lighting") local magic = require("buildat/extension/urho3d") local replicate = require("buildat/extension/replicate") local cereal = require("buildat/extension/cereal") local voxelworld = require("buildat/module/voxelworld") local M = {} local ideal_zone_size = 16 M.sector_size = buildat.Vector2(0, 0) M.zone_div = buildat.Vector2(0, 0) M.zone_size = buildat.Vector2(0, 0) local function setup_sizes(sector_size) M.sector_size = sector_size M.zone_div = (M.sector_size / ideal_zone_size):floor() M.zone_size = buildat.Vector2(ideal_zone_size, ideal_zone_size) log:info("sector_size: "..M.sector_size:dump()) log:info("zone_div: "..M.zone_div:dump()) log:info("zone_size: "..M.zone_size:dump()) end buildat.sub_packet("ground_plane_lighting:init", function(data) local values = cereal.binary_input(data, {"object", {"sector_size", {"object", {"x", "int16_t"}, {"y", "int16_t"}, }}, }) log:info("ground_plane_lighting:init: "..dump(values)) setup_sizes(buildat.Vector2(values.sector_size)) end) local dark_zones = {} -- {sector_y: {sector_x: {zone nodes}}} local function get_sector_zones(x, y) local ytable = dark_zones[y] if ytable == nil then ytable = {} dark_zones[y] = ytable end local xtable = ytable[x] if xtable == nil then xtable = {} ytable[x] = xtable end return xtable end local function set_dark_zones(sector_p, yst_volume) log:verbose("set_dark_zones(): sector_p="..sector_p:dump()) local scene = replicate.main_scene -- TODO: More flexibility local sector_zones = get_sector_zones(sector_p.x, sector_p.y) local zone_i = 1 for y_div = 0, M.zone_div.y - 1 do for x_div = 0, M.zone_div.x - 1 do local zone_node = sector_zones[zone_i] if zone_node == nil then zone_node = scene:CreateChild("GPLZone") zone_node:CreateComponent("Zone") sector_zones[zone_i] = zone_node end local zone = zone_node:GetComponent("Zone") do local yst_min = 1000000 for x = 0, M.zone_size.x - 1 do for y = 0, M.zone_size.y - 1 do local x_in_sector = x + x_div * M.zone_size.x local y_in_sector = y + y_div * M.zone_size.y local v = yst_volume:get_voxel_at( x_in_sector, 0, y_in_sector) log:warning("v.int32="..v.int32) if v.int32 < yst_min then yst_min = v.int32 end end end local y_min = -10000 local y_max = yst_min local lc = magic.Vector3( sector_p.x * M.sector_size.x + x_div * M.zone_size.x, y_min, sector_p.y * M.sector_size.y + y_div * M.zone_size.y ) local uc = magic.Vector3( lc.x + M.zone_size.x, y_max, lc.z + M.zone_size.y ) log:verbose("Adding zone at lc=("..lc.x..", "..lc.y..", "..lc.z.. "), uc=("..uc.x..", "..uc.y..", "..uc.z..")") zone.boundingBox = magic.BoundingBox(lc, uc) zone.ambientColor = magic.Color(0, 0, 0) zone.fogColor = magic.Color(0.6, 0.7, 0.8) --zone.ambientColor = magic.Color( -- math.random(), math.random(), math.random()) --zone.fogEnd = 10 + math.random() * 50 zone.fogStart = 10 zone.fogEnd = voxelworld.camera_far_clip * 1.2 end zone_i = zone_i + 1 end end end buildat.sub_packet("ground_plane_lighting:update", function(data) log:debug("ground_plane_lighting:update: #data="..#data) local values = cereal.binary_input(data, {"object", {"p", {"object", {"x", "int16_t"}, {"y", "int16_t"}, }}, {"data", "string"}, }) --log:verbose("ground_plane_lighting:update: values="..dump(values)) log:verbose("ground_plane_lighting:update: #data="..#values.data.. ", p=("..values.p.x..", "..values.p.y..")") --log:verbose("values.data="..dump(buildat.bytes(values.data))) local volume = buildat.deserialize_volume_int32(values.data) local region = volume:get_enclosing_region() log:verbose("region: ("..region.x0..", "..region.y0..", "..region.z0..", ".. region.x1..", "..region.y1..", "..region.z1..")") local sector_p = buildat.Vector2(values.p) set_dark_zones(sector_p, volume) end) -- TODO: Remove voxelworld.sub_geometry_update(function(node) --[[ local cs = voxelworld.chunk_size_voxels local node_p = node:GetWorldPosition() local scene = node.scene local has_sunlight = false local zone_node = scene:CreateChild("Zone") local zone = zone_node:CreateComponent("Zone") zone.boundingBox = magic.BoundingBox( node_p - magic.Vector3(cs.x, cs.y, cs.z)/2, node_p + magic.Vector3(cs.x, cs.y, cs.z)/2 ) if has_sunlight then zone.ambientColor = magic.Color(0.1, 0.1, 0.1) zone.fogColor = magic.Color(0.6, 0.7, 0.8) else zone.ambientColor = magic.Color(0, 0, 0) --zone.fogColor = magic.Color(0, 0, 0) zone.fogColor = magic.Color(0.6, 0.7, 0.8) end --zone.ambientColor = magic.Color( -- math.random(), math.random(), math.random()) --zone.fogEnd = 10 + math.random() * 50 zone.fogStart = 10 zone.fogEnd = voxelworld.camera_far_clip * 1.2 --zone.ambientGradient = true --]] --[[ local yst_data = node:GetVar("gpl_voxel_yst_data"):GetBuffer() log:verbose("#yst_data="..yst_data:GetSize()) local yst_volume = buildat.deserialize_volume_8bit(yst_data) local cs = voxelworld.chunk_size_voxels local v_min = cs.y + 1 for x = 0, cs.x - 1 do for z = 0, cs.z - 1 do local v = yst_volume:get_voxel_at(x, 0, z) --log:verbose("voxel at ("..x..",0,"..z.."): "..v.id) if v.data < v_min then v_min = v.data end end end --local v_avg = v_sum / cs.x / cs.z --log:verbose("v_avg: "..v_avg) --local has_sunlight = buildat.voxel_heuristic_has_sunlight( -- data, voxel_reg) -- TODO: This is a hack that doesn't even work properly --local has_sunlight = (v_min < cs.y + 1) local has_sunlight = (v_min < cs.y + 0) local node_p = node:GetWorldPosition() local scene = node.scene local zone_node = scene:CreateChild("Zone") local zone = zone_node:CreateComponent("Zone") zone.boundingBox = magic.BoundingBox( node_p - magic.Vector3(cs.x, cs.y, cs.z)/2, node_p + magic.Vector3(cs.x, cs.y, cs.z)/2 ) if has_sunlight then zone.ambientColor = magic.Color(0.1, 0.1, 0.1) zone.fogColor = magic.Color(0.6, 0.7, 0.8) else zone.ambientColor = magic.Color(0, 0, 0) --zone.fogColor = magic.Color(0, 0, 0) zone.fogColor = magic.Color(0.6, 0.7, 0.8) end --zone.ambientColor = magic.Color( -- math.random(), math.random(), math.random()) --zone.fogEnd = 10 + math.random() * 50 zone.fogStart = 10 zone.fogEnd = voxelworld.camera_far_clip * 1.2 --zone.ambientGradient = true --]] end) return M -- vim: set noet ts=4 sw=4: