Measure the 3D library and open the model review scorecard
Full build / Import + headless tests (push) Successful in 43s
Full build / Full desktop build + optional release (push) Skipped

This commit is contained in:
zwitschi committed 2026-11-03 10:39:45 +01:00
1 parent 2443343f2b
commit 2d67e14e52
8 files changed
+413 -13

No files matched your search

+31
View File
@@ -95,6 +95,37 @@ class BuiltAssetTests(unittest.TestCase):
self.assertTrue((ba.SRC_DIR / ".gdignore").is_file())
@unittest.skipUnless(ba.MANIFEST.is_file(), "Blender assets not built")
class TexelDensityTests(unittest.TestCase):
def test_character_slots_report_density_and_area(self):
report = ba.texel_density("npc_casual")
self.assertEqual(report["resolution"], 256)
self.assertEqual(set(report["slots"]), set(ba.SLOTS) | {"eye_white", "rubber"})
for slot in ba.SLOTS:
row = report["slots"][slot]
self.assertGreater(row["triangles"], 0, slot)
self.assertGreater(row["world_area_m2"], 0.0, slot)
self.assertGreater(row["td_px_per_m"], 30.0, slot)
self.assertGreater(report["total_world_area_m2"], 1.0)
self.assertLess(report["total_world_area_m2"], 6.0)
def test_fabric_slots_apply_the_runtime_uv_repeat(self):
report = ba.texel_density("npc_casual")
for slot, factor in ba.TEXEL_RUNTIME_UV_SCALE.items():
row = report["slots"][slot]
self.assertAlmostEqual(row["td_runtime_px_per_m"],
row["td_px_per_m"] * factor, places=0)
skin = report["slots"]["skin"]
self.assertEqual(skin["td_px_per_m"], skin["td_runtime_px_per_m"])
def test_base_fallback_is_measurable_from_its_own_path(self):
from pathlib import Path
path = ba.ROOT / "assets" / "models" / "generated" / "npc_base.glb"
report = ba.texel_density("npc_base", path)
self.assertIsNotNone(report)
self.assertGreater(report["min_td"], 30.0)
class InspectionTests(unittest.TestCase):
"""`inspect` reports on imported GLBs; the contract logic is pure and tested
here with synthetic measurements so Blender is not a test dependency."""