|
if FirstLoad then |
|
g_VSDbgVisModeThread = false |
|
restoreDbgValue = false |
|
g_VSDbgMode = false |
|
end |
|
|
|
function OnMsg.NewMapLoaded() |
|
g_VSDbgVisModeThread = false |
|
g_VSDbgMode = false |
|
end |
|
|
|
local dbgVectorsOffset = 200 |
|
local z_vector = point(0,0,3000) |
|
local vs_dbg_vis_voxel_range = 8 |
|
local last_cam, last_lookat, last_cursor_slab |
|
|
|
local function PlaceLitVector(pos) |
|
local v = GetVoxelStealthParams(pos) |
|
if band(v, const.vsFlagIlluminated) ~= 0 then |
|
DbgAddVector(pos:SetX(pos:x() - dbgVectorsOffset), z_vector, const.clrWhite) |
|
end |
|
if band(v, const.vsFlagTallGrass) ~= 0 then |
|
DbgAddVector(pos:SetX(pos:x() + dbgVectorsOffset), z_vector, const.clrGreen) |
|
end |
|
end |
|
|
|
local function PlaceCursorLitVectors(pos) |
|
if not pos then return end |
|
|
|
local _, overall_illum, lights, lights_illum = DebugGetVoxelStealthParams(pos) |
|
for idx, l in ipairs(lights) do |
|
if IsValid(l) then |
|
local l_pos = l:GetPos() |
|
DbgAddVector(l_pos, pos - l_pos, const.clrYellow) |
|
local text = string.format("%.2f / %.2f", lights_illum[idx], const.vsIlluminationThreshold) |
|
DbgAddText(text, (l_pos + pos) / 2, const.clrYellow, nil, const.clrBlack) |
|
end |
|
end |
|
local text = string.format("Overall: %.2f/%.2f", overall_illum, const.vsIlluminationThreshold) |
|
DbgAddText(text, pos, const.clrYellow, nil, const.clrBlack) |
|
end |
|
|
|
local function PlaceLitVectorsAround(pos_around) |
|
if not pos_around then return end |
|
|
|
DbgAddVector(pos_around, z_vector * 2, const.clrMagenta) |
|
local x, y, z = pos_around:xyz() |
|
local pt = point(x - vs_dbg_vis_voxel_range, y - vs_dbg_vis_voxel_range, z - vs_dbg_vis_voxel_range) |
|
for i = -vs_dbg_vis_voxel_range, vs_dbg_vis_voxel_range do |
|
for j = -vs_dbg_vis_voxel_range, vs_dbg_vis_voxel_range do |
|
for k = -2 * vs_dbg_vis_voxel_range, 2 * vs_dbg_vis_voxel_range do |
|
local pos = SnapToPassSlab(x + i * const.SlabSizeX, y + j * const.SlabSizeY, z + k * const.SlabSizeZ) |
|
if pos then |
|
PlaceLitVector(pos) |
|
end |
|
end |
|
end |
|
end |
|
end |
|
|
|
local function PlaceMapAreaLitVoxels() |
|
local sizex, sizey = terrain.GetMapSize() |
|
local bbox = box(0, 0, sizex, sizey) |
|
ForEachStealthParamVoxel(bbox, const.vsFlagIlluminated + const.vsFlagTallGrass, function(pos, stealth_mask) |
|
pos = pos:IsValidZ() and pos or pos:SetTerrainZ() |
|
if band(stealth_mask, const.vsFlagIlluminated) ~= 0 then |
|
DbgAddVector(pos:SetX(pos:x() - dbgVectorsOffset), z_vector, const.clrWhite) |
|
end |
|
if band(stealth_mask, const.vsFlagTallGrass) ~= 0 then |
|
DbgAddVector(pos:SetX(pos:x() + dbgVectorsOffset), z_vector, const.clrGreen) |
|
end |
|
end) |
|
end |
|
|
|
local function GetCursorSlabForLitCheck() |
|
local cursor_obj = GetPreciseCursorObj() |
|
local cursor_slab = cursor_obj and cursor_obj:GetPos() or GetCursorPos() |
|
local z = cursor_slab:z() |
|
local lit_check = point(VoxelToWorld(WorldToVoxel(cursor_slab))) |
|
|
|
return z and lit_check:SetZ(z) or lit_check |
|
end |
|
|
|
local function LightAroundCursor(cursor_slab) |
|
hr.VoxelStealthParamsDebugCacheCleared = false |
|
PlaceCursorLitVectors(cursor_slab) |
|
end |
|
|
|
local function IsLitChanged(cursor_slab) |
|
return last_cursor_slab ~= cursor_slab or hr.VoxelStealthParamsDebugCacheCleared |
|
end |
|
|
|
local function DrawCameraVectors(cursor_slab, cam, lookat) |
|
DbgClear() |
|
local box = GetVoxelBox(0, GetCameraLookatTerrainPos()) |
|
PlaceLitVectorsAround(box and box:Center() or GetCameraLookatTerrainPos()) |
|
LightAroundCursor(cursor_slab) |
|
last_cursor_slab = cursor_slab |
|
last_cam = cam |
|
last_lookat = lookat |
|
end |
|
|
|
local function DrawMapVectors(cursor_slab) |
|
DbgClear() |
|
LightAroundCursor(cursor_slab) |
|
PlaceMapAreaLitVoxels() |
|
last_cursor_slab = cursor_slab |
|
end |
|
|
|
function CycleVSDbgVisMode() |
|
g_VSDbgMode = (g_VSDbgMode or 0) + 1 |
|
if g_VSDbgMode == 3 then |
|
g_VSDbgMode = false |
|
end |
|
if g_VSDbgMode == 1 then |
|
print("Voxel Stealth Dbg Camera Look At is ON") |
|
ResetVoxelStealthParamsCache() |
|
ShowLightShadowsStats(1000) |
|
if g_VSDbgVisModeThread then return end |
|
if not hr.VoxelStealthParamsDebug then |
|
restoreDbgValue = true |
|
hr.VoxelStealthParamsDebug = true |
|
end |
|
g_VSDbgVisModeThread = CreateMapRealTimeThread(function() |
|
repeat |
|
local cam, lookat = GetCamera() |
|
local cursor_slab = GetCursorSlabForLitCheck() |
|
if IsLitChanged(cursor_slab) or cam ~= last_cam or lookat ~= last_lookat then |
|
DrawCameraVectors(cursor_slab, cam, lookat) |
|
end |
|
Sleep(500) |
|
until false |
|
end) |
|
elseif g_VSDbgMode == 2 then |
|
print("Voxel Stealth Dbg Whole Map ON") |
|
ResetVoxelStealthParamsCache() |
|
ShowLightShadowsStats(1000) |
|
DeleteThread(g_VSDbgVisModeThread) |
|
g_VSDbgVisModeThread = CreateMapRealTimeThread(function() |
|
repeat |
|
local cursor_slab = GetCursorSlabForLitCheck() |
|
if IsLitChanged(cursor_slab) then |
|
DrawMapVectors(cursor_slab) |
|
end |
|
Sleep(500) |
|
until false |
|
end) |
|
else |
|
print("Voxel Stealth Dbg OFF") |
|
DbgClear() |
|
if restoreDbgValue then |
|
restoreDbgValue = false |
|
hr.VoxelStealthParamsDebug = false |
|
end |
|
DeleteThread(g_VSDbgVisModeThread) |
|
HideLightShadowsStats() |
|
g_VSDbgVisModeThread = false |
|
end |
|
end |
|
|
|
local s_StealthCacheProperty = { |
|
["DetailClass"] = true, |
|
["Exterior"] = true, |
|
["Interior"] = true, |
|
["AttenuationRadius"] = true, |
|
["InteriorAndExteriorWhenHasShadowmap"] = true, |
|
["Intensity"] = true, |
|
["ConstantIntensity"] = true, |
|
["ConeInnerAngle"] = true, |
|
["ConeOuterAngle"] = true, |
|
} |
|
|
|
function OnMsg.GedPropertyEdited(_, obj, prop_id, old_value) |
|
if s_StealthCacheProperty[prop_id] and IsKindOf(obj, "Light") then |
|
Msg("LightsStateUpdated") |
|
end |
|
end |
|
|
|
local function check_light_objects(objects) |
|
local function is_light_edited(obj) |
|
if obj:IsKindOf("Light") then return true end |
|
|
|
local light_edited |
|
obj:ForEachAttach(function(attach) |
|
if is_light_edited(attach) then |
|
light_edited = true |
|
return "break" |
|
end |
|
end) |
|
|
|
return light_edited |
|
end |
|
|
|
for _, obj in ipairs(table.validate(objects)) do |
|
if is_light_edited(obj) then |
|
Msg("LightsStateUpdated") |
|
break |
|
end |
|
end |
|
end |
|
|
|
function OnMsg.EditorCallback(id, objects, ...) |
|
if id == "EditorCallbackRotate" or id == "EditorCallbackPlace" or id == "EditorCallbackMove" or id == "EditorCallbackDelete" then |
|
check_light_objects(objects) |
|
end |
|
end |
|
|
|
function OnMsg.EditorResetZ() |
|
local sel = editor.GetSel() |
|
if #(sel or empty_table) > 0 then |
|
check_light_objects(sel) |
|
end |
|
end |
|
|
|
|