From 4f493209e4e943ad99cdd8fc905efbfedc1bc5b5 Mon Sep 17 00:00:00 2001 From: Basilisk3 <126026384+Basilisk3@users.noreply.github.com> Date: Sat, 16 Aug 2025 11:38:49 +0200 Subject: [PATCH 01/14] Add support for props to skip the automatic computation of LODs --- engine/Core/Categories.lua | 1 + lua/system/blueprints-props.lua | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/engine/Core/Categories.lua b/engine/Core/Categories.lua index f385be163fd..9b0ed85211d 100644 --- a/engine/Core/Categories.lua +++ b/engine/Core/Categories.lua @@ -463,6 +463,7 @@ categories = { ---| "UNSELECTABLE" ---| "UNSPAWNABLE" ---| "UNTARGETABLE" +---| "USEBLUEPRINTLOD" ---| "USEBUILDPRESETS" ---| "VERIFYMISSILEUI" ---| "VISIBLETORECON" diff --git a/lua/system/blueprints-props.lua b/lua/system/blueprints-props.lua index 2923cbcda8b..2e1da3de232 100644 --- a/lua/system/blueprints-props.lua +++ b/lua/system/blueprints-props.lua @@ -121,7 +121,9 @@ local function ProcessLOD(prop) -- https://www.desmos.com/calculator (0.9 * sqrt(100 * 500 * x)) local lod = 0.9 * MathSqrt(100 * 500 * weighted) - if prop.Display and prop.Display.Mesh and prop.Display.Mesh.LODs then + -- If the prop has the 'USEBLUEPRINTLOD' category, the LODs defined in its blueprint take precedent + local useBlueprintLOD = TableFind(prop.Categories, 'USEBLUEPRINTLOD') + if prop.Display and prop.Display.Mesh and prop.Display.Mesh.LODs and not useBlueprintLOD then local n = TableGetn(prop.Display.Mesh.LODs) for k = 1, n do local data = prop.Display.Mesh.LODs[k] From 7da084914157aafd9ed489fbab1d1d7087598e08 Mon Sep 17 00:00:00 2001 From: Basilisk3 <126026384+Basilisk3@users.noreply.github.com> Date: Sat, 16 Aug 2025 12:04:45 +0200 Subject: [PATCH 02/14] Create feature.6906.md --- changelog/snippets/feature.6906.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/snippets/feature.6906.md diff --git a/changelog/snippets/feature.6906.md b/changelog/snippets/feature.6906.md new file mode 100644 index 00000000000..e890e4ed677 --- /dev/null +++ b/changelog/snippets/feature.6906.md @@ -0,0 +1 @@ +- (#6906) Add support for props to skip the automatic computation of LODs via the `USEBLUEPRINTLOD` category. From c40619328540431f7e0908e4777af9e2dea99c05 Mon Sep 17 00:00:00 2001 From: Basilisk3 <126026384+Basilisk3@users.noreply.github.com> Date: Sun, 17 Aug 2025 23:43:47 +0200 Subject: [PATCH 03/14] Apply feedback --- lua/system/blueprints-props.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lua/system/blueprints-props.lua b/lua/system/blueprints-props.lua index 2e1da3de232..c5b8b6c7bcb 100644 --- a/lua/system/blueprints-props.lua +++ b/lua/system/blueprints-props.lua @@ -128,12 +128,12 @@ local function ProcessLOD(prop) for k = 1, n do local data = prop.Display.Mesh.LODs[k] - -- https://www.desmos.com/calculator (x * x) - local factor = (k / n) * (k / n) + -- https://www.desmos.com/calculator (x ^ 4) + local factor = (k / n) * (k / n) * (k / n) * (k / n) local LODCutoff = factor * lod - -- sanitize the value - data.LODCutoff = MathFloor(LODCutoff / 10 + 1) * 10 + -- Sanitize the value and add a flat value of 30 to each level to prevent some LODCutoffs from becoming to small + data.LODCutoff = 30 + MathFloor(LODCutoff / 10 + 1) * 10 end end end From 6d2bf4b6bd0bb9c4e4e955d6fc1bdbca23ab683f Mon Sep 17 00:00:00 2001 From: Basilisk3 <126026384+Basilisk3@users.noreply.github.com> Date: Fri, 28 Nov 2025 11:42:00 +0100 Subject: [PATCH 04/14] Remove the new category --- changelog/snippets/feature.6906.md | 2 +- engine/Core/Categories.lua | 1 - lua/system/blueprints-props.lua | 6 ++---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/changelog/snippets/feature.6906.md b/changelog/snippets/feature.6906.md index e890e4ed677..e879484275f 100644 --- a/changelog/snippets/feature.6906.md +++ b/changelog/snippets/feature.6906.md @@ -1 +1 @@ -- (#6906) Add support for props to skip the automatic computation of LODs via the `USEBLUEPRINTLOD` category. +- (#6906) Tweak the formula used to calculate the level of detail (LOD) for props. diff --git a/engine/Core/Categories.lua b/engine/Core/Categories.lua index 9b0ed85211d..f385be163fd 100644 --- a/engine/Core/Categories.lua +++ b/engine/Core/Categories.lua @@ -463,7 +463,6 @@ categories = { ---| "UNSELECTABLE" ---| "UNSPAWNABLE" ---| "UNTARGETABLE" ----| "USEBLUEPRINTLOD" ---| "USEBUILDPRESETS" ---| "VERIFYMISSILEUI" ---| "VISIBLETORECON" diff --git a/lua/system/blueprints-props.lua b/lua/system/blueprints-props.lua index c5b8b6c7bcb..422556b5389 100644 --- a/lua/system/blueprints-props.lua +++ b/lua/system/blueprints-props.lua @@ -121,9 +121,7 @@ local function ProcessLOD(prop) -- https://www.desmos.com/calculator (0.9 * sqrt(100 * 500 * x)) local lod = 0.9 * MathSqrt(100 * 500 * weighted) - -- If the prop has the 'USEBLUEPRINTLOD' category, the LODs defined in its blueprint take precedent - local useBlueprintLOD = TableFind(prop.Categories, 'USEBLUEPRINTLOD') - if prop.Display and prop.Display.Mesh and prop.Display.Mesh.LODs and not useBlueprintLOD then + if prop.Display and prop.Display.Mesh and prop.Display.Mesh.LODs then local n = TableGetn(prop.Display.Mesh.LODs) for k = 1, n do local data = prop.Display.Mesh.LODs[k] @@ -132,7 +130,7 @@ local function ProcessLOD(prop) local factor = (k / n) * (k / n) * (k / n) * (k / n) local LODCutoff = factor * lod - -- Sanitize the value and add a flat value of 30 to each level to prevent some LODCutoffs from becoming to small + -- Sanitize the value and add a flat value of 30 to each level to prevent some LODCutoffs from becoming too small data.LODCutoff = 30 + MathFloor(LODCutoff / 10 + 1) * 10 end end From b54ed8c3b071614fea54b9dea4788312db57c329 Mon Sep 17 00:00:00 2001 From: BlackYps Date: Fri, 28 Nov 2025 17:43:37 +0100 Subject: [PATCH 05/14] Allow explicit control over tree lods --- lua/system/blueprints-props.lua | 49 ++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/lua/system/blueprints-props.lua b/lua/system/blueprints-props.lua index 422556b5389..00021f4e97d 100644 --- a/lua/system/blueprints-props.lua +++ b/lua/system/blueprints-props.lua @@ -107,31 +107,36 @@ end --- - https://github.com/FAForever/fa/pull/4675 ---@param prop PropBlueprint local function ProcessLOD(prop) - - local sx = prop.SizeX or 1 - local sy = prop.SizeY or 1 - local sz = prop.SizeZ or 1 - - -- give more emphasis to the x / z value as that is easier to see in the average camera angle - local weighted = 0.40 * sx + 0.2 * sy + 0.4 * sz - if prop.ScriptClass == 'Tree' or prop.ScriptClass == 'TreeGroup' then - weighted = 10.0 - end - - -- https://www.desmos.com/calculator (0.9 * sqrt(100 * 500 * x)) - local lod = 0.9 * MathSqrt(100 * 500 * weighted) - if prop.Display and prop.Display.Mesh and prop.Display.Mesh.LODs then - local n = TableGetn(prop.Display.Mesh.LODs) - for k = 1, n do - local data = prop.Display.Mesh.LODs[k] - -- https://www.desmos.com/calculator (x ^ 4) - local factor = (k / n) * (k / n) * (k / n) * (k / n) - local LODCutoff = factor * lod + local sx = prop.SizeX or 1 + local sy = prop.SizeY or 1 + local sz = prop.SizeZ or 1 + + -- give more emphasis to the x / z value as that is easier to see in the average camera angle + local weightedLodSize = MathSqrt(sx + 0.5 * sy + sz) + local maxLod = 130 * weightedLodSize + + if (prop.ScriptClass == 'Tree' or prop.ScriptClass == 'TreeGroup') + then + if TableGetn(prop.Display.Mesh.LODs) == 3 then + prop.Display.Mesh.LODs[1].LODCutoff = 40 + prop.Display.Mesh.LODs[2].LODCutoff = 150 + prop.Display.Mesh.LODs[3].LODCutoff = 640 + return + else + maxLod = 640 + end + end + + local levels = TableGetn(prop.Display.Mesh.LODs) + for n = 1, levels do + local data = prop.Display.Mesh.LODs[n] + local factor = (n / levels) + local LODCutoff = factor * maxLod - -- Sanitize the value and add a flat value of 30 to each level to prevent some LODCutoffs from becoming too small - data.LODCutoff = 30 + MathFloor(LODCutoff / 10 + 1) * 10 + -- round the value + data.LODCutoff = MathFloor((LODCutoff + 5) / 10) * 10 end end end From 89f6c0adedc91c1e1d5924dcad0febdbc2a23ae0 Mon Sep 17 00:00:00 2001 From: BlackYps Date: Fri, 28 Nov 2025 16:49:04 +0100 Subject: [PATCH 06/14] Change weighted size calculation --- lua/system/blueprints-props.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/system/blueprints-props.lua b/lua/system/blueprints-props.lua index 00021f4e97d..9e38b78ddcc 100644 --- a/lua/system/blueprints-props.lua +++ b/lua/system/blueprints-props.lua @@ -114,8 +114,8 @@ local function ProcessLOD(prop) local sz = prop.SizeZ or 1 -- give more emphasis to the x / z value as that is easier to see in the average camera angle - local weightedLodSize = MathSqrt(sx + 0.5 * sy + sz) - local maxLod = 130 * weightedLodSize + local weightedLodSize = MathSqrt(sx * sx + 0.5 * sy * sy + sz * sz) + local maxLod = 180 * weightedLodSize if (prop.ScriptClass == 'Tree' or prop.ScriptClass == 'TreeGroup') then From 884e37cbe106fbba5575d642eddd95558e620216 Mon Sep 17 00:00:00 2001 From: BlackYps Date: Fri, 28 Nov 2025 17:41:30 +0100 Subject: [PATCH 07/14] Skip second lod for tree groups --- lua/system/blueprints-props.lua | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/lua/system/blueprints-props.lua b/lua/system/blueprints-props.lua index 9e38b78ddcc..29d2a385f39 100644 --- a/lua/system/blueprints-props.lua +++ b/lua/system/blueprints-props.lua @@ -117,16 +117,18 @@ local function ProcessLOD(prop) local weightedLodSize = MathSqrt(sx * sx + 0.5 * sy * sy + sz * sz) local maxLod = 180 * weightedLodSize - if (prop.ScriptClass == 'Tree' or prop.ScriptClass == 'TreeGroup') - then - if TableGetn(prop.Display.Mesh.LODs) == 3 then - prop.Display.Mesh.LODs[1].LODCutoff = 40 - prop.Display.Mesh.LODs[2].LODCutoff = 150 - prop.Display.Mesh.LODs[3].LODCutoff = 640 - return - else - maxLod = 640 - end + if (prop.ScriptClass == 'Tree' and TableGetn(prop.Display.Mesh.LODs) == 3) then + prop.Display.Mesh.LODs[1].LODCutoff = 40 + prop.Display.Mesh.LODs[2].LODCutoff = 200 + prop.Display.Mesh.LODs[3].LODCutoff = 640 + return + elseif (prop.ScriptClass == 'TreeGroup' and TableGetn(prop.Display.Mesh.LODs) == 3) then + prop.Display.Mesh.LODs[1].LODCutoff = 200 + prop.Display.Mesh.LODs[2].LODCutoff = 200 + prop.Display.Mesh.LODs[3].LODCutoff = 640 + return + elseif (prop.ScriptClass == 'Tree' or prop.ScriptClass == 'TreeGroup') then + maxLod = 640 end local levels = TableGetn(prop.Display.Mesh.LODs) From 384a3b1d21ce86624846390746e282d34c7519f9 Mon Sep 17 00:00:00 2001 From: BlackYps Date: Fri, 28 Nov 2025 19:49:53 +0100 Subject: [PATCH 08/14] Revert "Skip second lod for tree groups" This reverts commit 884e37cbe106fbba5575d642eddd95558e620216. --- lua/system/blueprints-props.lua | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/lua/system/blueprints-props.lua b/lua/system/blueprints-props.lua index 29d2a385f39..9e38b78ddcc 100644 --- a/lua/system/blueprints-props.lua +++ b/lua/system/blueprints-props.lua @@ -117,18 +117,16 @@ local function ProcessLOD(prop) local weightedLodSize = MathSqrt(sx * sx + 0.5 * sy * sy + sz * sz) local maxLod = 180 * weightedLodSize - if (prop.ScriptClass == 'Tree' and TableGetn(prop.Display.Mesh.LODs) == 3) then - prop.Display.Mesh.LODs[1].LODCutoff = 40 - prop.Display.Mesh.LODs[2].LODCutoff = 200 - prop.Display.Mesh.LODs[3].LODCutoff = 640 - return - elseif (prop.ScriptClass == 'TreeGroup' and TableGetn(prop.Display.Mesh.LODs) == 3) then - prop.Display.Mesh.LODs[1].LODCutoff = 200 - prop.Display.Mesh.LODs[2].LODCutoff = 200 - prop.Display.Mesh.LODs[3].LODCutoff = 640 - return - elseif (prop.ScriptClass == 'Tree' or prop.ScriptClass == 'TreeGroup') then - maxLod = 640 + if (prop.ScriptClass == 'Tree' or prop.ScriptClass == 'TreeGroup') + then + if TableGetn(prop.Display.Mesh.LODs) == 3 then + prop.Display.Mesh.LODs[1].LODCutoff = 40 + prop.Display.Mesh.LODs[2].LODCutoff = 150 + prop.Display.Mesh.LODs[3].LODCutoff = 640 + return + else + maxLod = 640 + end end local levels = TableGetn(prop.Display.Mesh.LODs) From 34d08b18a7b511daf2077e3491e02ca76fbff071 Mon Sep 17 00:00:00 2001 From: BlackYps Date: Fri, 28 Nov 2025 19:52:49 +0100 Subject: [PATCH 09/14] Increase lod values a bit --- lua/system/blueprints-props.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/system/blueprints-props.lua b/lua/system/blueprints-props.lua index 9e38b78ddcc..8f25c893887 100644 --- a/lua/system/blueprints-props.lua +++ b/lua/system/blueprints-props.lua @@ -115,13 +115,13 @@ local function ProcessLOD(prop) -- give more emphasis to the x / z value as that is easier to see in the average camera angle local weightedLodSize = MathSqrt(sx * sx + 0.5 * sy * sy + sz * sz) - local maxLod = 180 * weightedLodSize + local maxLod = 200 * weightedLodSize if (prop.ScriptClass == 'Tree' or prop.ScriptClass == 'TreeGroup') then if TableGetn(prop.Display.Mesh.LODs) == 3 then prop.Display.Mesh.LODs[1].LODCutoff = 40 - prop.Display.Mesh.LODs[2].LODCutoff = 150 + prop.Display.Mesh.LODs[2].LODCutoff = 180 prop.Display.Mesh.LODs[3].LODCutoff = 640 return else From 9dbddc3911886d5b266f4b5d34ac42f95989c83d Mon Sep 17 00:00:00 2001 From: BlackYps Date: Sun, 30 Nov 2025 21:14:01 +0100 Subject: [PATCH 10/14] Don't use else after return --- lua/system/blueprints-props.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lua/system/blueprints-props.lua b/lua/system/blueprints-props.lua index 8f25c893887..5094d53f346 100644 --- a/lua/system/blueprints-props.lua +++ b/lua/system/blueprints-props.lua @@ -124,9 +124,8 @@ local function ProcessLOD(prop) prop.Display.Mesh.LODs[2].LODCutoff = 180 prop.Display.Mesh.LODs[3].LODCutoff = 640 return - else - maxLod = 640 end + maxLod = 640 end local levels = TableGetn(prop.Display.Mesh.LODs) From 03e94f3c58e1fc1e675f19ed3379afcefdda7e4c Mon Sep 17 00:00:00 2001 From: BlackYps Date: Sun, 7 Dec 2025 19:40:54 +0100 Subject: [PATCH 11/14] Adjust the values a bit again --- lua/system/blueprints-props.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/system/blueprints-props.lua b/lua/system/blueprints-props.lua index 5094d53f346..685f0a05eb9 100644 --- a/lua/system/blueprints-props.lua +++ b/lua/system/blueprints-props.lua @@ -115,13 +115,13 @@ local function ProcessLOD(prop) -- give more emphasis to the x / z value as that is easier to see in the average camera angle local weightedLodSize = MathSqrt(sx * sx + 0.5 * sy * sy + sz * sz) - local maxLod = 200 * weightedLodSize + local maxLod = 180 * weightedLodSize if (prop.ScriptClass == 'Tree' or prop.ScriptClass == 'TreeGroup') then if TableGetn(prop.Display.Mesh.LODs) == 3 then prop.Display.Mesh.LODs[1].LODCutoff = 40 - prop.Display.Mesh.LODs[2].LODCutoff = 180 + prop.Display.Mesh.LODs[2].LODCutoff = 165 prop.Display.Mesh.LODs[3].LODCutoff = 640 return end From c5f94823654dead935d045e574147ae39197e2fe Mon Sep 17 00:00:00 2001 From: BlackYps Date: Sun, 7 Dec 2025 19:45:57 +0100 Subject: [PATCH 12/14] Update snippet --- changelog/snippets/feature.6906.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog/snippets/feature.6906.md b/changelog/snippets/feature.6906.md index e879484275f..83046940d6c 100644 --- a/changelog/snippets/feature.6906.md +++ b/changelog/snippets/feature.6906.md @@ -1 +1,2 @@ - (#6906) Tweak the formula used to calculate the level of detail (LOD) for props. +Large props are visible for longer, and it should now be easier again to spot broken tree groups. From 63c8e790a06bdbf35fdf525ed0f1d387562d9dcc Mon Sep 17 00:00:00 2001 From: Basilisk3 <126026384+Basilisk3@users.noreply.github.com> Date: Thu, 11 Dec 2025 17:26:04 +0100 Subject: [PATCH 13/14] Fix changelog indentation --- changelog/snippets/feature.6906.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog/snippets/feature.6906.md b/changelog/snippets/feature.6906.md index 83046940d6c..9101a4a0d67 100644 --- a/changelog/snippets/feature.6906.md +++ b/changelog/snippets/feature.6906.md @@ -1,2 +1,3 @@ - (#6906) Tweak the formula used to calculate the level of detail (LOD) for props. -Large props are visible for longer, and it should now be easier again to spot broken tree groups. + + Large props are visible for longer, and it should now be easier again to spot broken tree groups. From e888cf7f14708f4866512391000cd595bfc06e24 Mon Sep 17 00:00:00 2001 From: BlackYps Date: Mon, 15 Dec 2025 16:05:30 +0100 Subject: [PATCH 14/14] Make resource deposit meshes visible for longer --- env/Common/Props/hydrocarbonDeposit01_prop.bp | 6 +++--- env/Common/Props/massDeposit01_prop.bp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/env/Common/Props/hydrocarbonDeposit01_prop.bp b/env/Common/Props/hydrocarbonDeposit01_prop.bp index 35668bd670e..0c52e7847d5 100644 --- a/env/Common/Props/hydrocarbonDeposit01_prop.bp +++ b/env/Common/Props/hydrocarbonDeposit01_prop.bp @@ -28,7 +28,7 @@ PropBlueprint{ CollisionOffsetX = 0, CollisionOffsetY = 0, CollisionOffsetZ = 0, - SizeX = 0.1, - SizeY = 0.1, - SizeZ = 0.1, + SizeX = 1.0, + SizeY = 0.2, + SizeZ = 1.0, } \ No newline at end of file diff --git a/env/Common/Props/massDeposit01_prop.bp b/env/Common/Props/massDeposit01_prop.bp index f9a1bd5fa2f..77d6e15951b 100644 --- a/env/Common/Props/massDeposit01_prop.bp +++ b/env/Common/Props/massDeposit01_prop.bp @@ -25,7 +25,7 @@ PropBlueprint{ Physics = { BlockPath = false }, ScriptClass = "PropInvulnerable", ScriptModule = "/lua/sim/prop.lua", - SizeX = 0.1, + SizeX = 0.9, SizeY = 0.1, - SizeZ = 0.1, + SizeZ = 0.9, } \ No newline at end of file