Files
2026-10-06 22:25:34 -04:00

106 lines
5.0 KiB
Python

import unittest
from native_material_alpha import native_alpha_action, native_material_identity
class NativeMaterialAlphaTest(unittest.TestCase):
def setUp(self):
self.report = {
"sourceModel": r"model\dungeon\the_origin\act_precipice_02.ros",
"sourceResourceSha256": "a" * 64,
"materials": [
{
"name": "runewaker_material_2",
"sourceTexture": r"texture\dungeon\the_origin\gate_waterfall",
"stagedTexture": "textures/32435b59_gate_waterfall.dds",
"materialType": {"value": 0, "name": "standard"},
"lightingType": {"value": 0, "name": "standard"},
"sourceTextureChannels": [
{
"id": 1,
"name": "diffuse",
"texture": r"texture\dungeon\the_origin\gate_waterfall",
},
],
"alphaBlendParameters": [
{"name": "alphaTestMode", "value": 0},
{"name": "alphaTestValue", "value": 192},
{"name": "alphaMode", "value": 0},
{"name": "translucent", "value": True},
{"name": "alpha", "value": 1},
{"name": "alphaModifier", "value": 1},
],
},
],
}
def test_exact_resource_material_and_diffuse_identity_are_required(self):
identity = native_material_identity(
"runewaker_material_2",
r"C:\staging\textures\32435b59_gate_waterfall.png",
self.report,
)
self.assertIsNotNone(identity)
self.assertEqual(identity["materialIndex"], 2)
self.assertEqual(identity["sourceResourceSha256"], "a" * 64)
self.assertEqual(identity["sourceTexture"], r"texture\dungeon\the_origin\gate_waterfall")
self.assertEqual(native_material_identity(
"runewaker_material_3",
r"C:\staging\textures\32435b59_gate_waterfall.png",
self.report,
), None, "a name-only match is insufficient")
self.assertEqual(native_material_identity(
"runewaker_material_2",
r"C:\staging\textures\other.png",
self.report,
), None, "the staged diffuse basename must match")
invalid_provenance = {**self.report, "sourceResourceSha256": "not-a-hash"}
self.assertEqual(native_material_identity(
"runewaker_material_2",
r"C:\staging\textures\32435b59_gate_waterfall.png",
invalid_provenance,
), None, "source resource hash is mandatory")
def test_native_modes_distinguish_normal_blend_additive_and_opaque(self):
identity = native_material_identity(
"runewaker_material_2",
r"C:\staging\textures\32435b59_gate_waterfall.png",
self.report,
)
self.assertEqual(native_alpha_action(identity, "blend")["action"], "blend")
self.assertEqual(native_alpha_action(identity, "opaque")["action"], "opaque")
additive_parameters = dict(identity["alphaBlendParameters"], alphaMode=1)
additive = {**identity, "alphaBlendParameters": additive_parameters}
self.assertEqual(
native_alpha_action(additive, "blend"),
{"action": "additive", "reason": "native-srcalpha-one-additive"},
)
self.assertEqual(native_alpha_action(additive, "opaque")["action"], "additive")
additive_not_translucent = {**identity, "alphaBlendParameters": dict(additive_parameters, translucent=False)}
self.assertEqual(native_alpha_action(additive_not_translucent, "blend")["action"], "unsupported")
additive_alpha_tested = {**identity, "alphaBlendParameters": dict(additive_parameters, alphaTestMode=1)}
self.assertEqual(native_alpha_action(additive_alpha_tested, "blend")["action"], "unsupported")
additive_scaled = {**identity, "alphaBlendParameters": dict(additive_parameters, alpha=0.5)}
self.assertEqual(native_alpha_action(additive_scaled, "blend")["action"], "unsupported")
opaque_parameters = dict(identity["alphaBlendParameters"], translucent=False)
opaque_native = {**identity, "alphaBlendParameters": opaque_parameters}
self.assertEqual(native_alpha_action(opaque_native, "blend")["action"], "opaque")
def test_native_alpha_test_preserves_its_threshold(self):
identity = native_material_identity(
"runewaker_material_2",
r"C:\staging\textures\32435b59_gate_waterfall.png",
self.report,
)
parameters = dict(identity["alphaBlendParameters"], alphaTestMode=1, translucent=False, alphaTestValue=192)
decision = native_alpha_action({**identity, "alphaBlendParameters": parameters}, "cutout")
self.assertEqual(decision["action"], "mask")
self.assertAlmostEqual(decision["threshold"], 192 / 255)
if __name__ == "__main__":
unittest.main()