Files
mtgodot-poc/project/effect_scale_test.gd
T

82 lines
4.3 KiB
GDScript

extends SceneTree
const EffectPlayer = preload("res://fx/effect_player.gd")
var failures := 0
func check(ok: bool, label: String) -> void:
if not ok:
failures += 1
printerr("FAIL: " + label)
func _init() -> void:
var fx := EffectPlayer.new()
fx.build({"particles": [{"emitter": {"TimeEventSizeX": [[0, 10]], "TimeEventSizeY": [[0, 30]]},
"particle": {"TimeEventScaleX": [[0, 0], [1, 4]], "TimeEventScaleY": [[0, 3], [1, 1]]}},
{"emitter": {"TimeEventSizeX": [[0, 0]], "TimeEventSizeY": [[0, 0]]}, "particle": {}}]})
var g: GPUParticles3D = fx._emitters[0]
var pm: ParticleProcessMaterial = g.process_material
check(g.draw_pass_1.size.is_equal_approx(Vector2(0.2, 0.6)), "independent half-sizes become full metre dimensions")
check(pm.scale_min == 1.0 and pm.scale_max == 1.0, "no invented random size factor")
check(pm.scale_curve is CurveXYZTexture, "independent XYZ scale texture")
if pm.scale_curve is CurveXYZTexture:
var tex: CurveXYZTexture = pm.scale_curve
check(is_equal_approx(tex.curve_x.sample(0.25), 1.0), "X interpolates linearly")
check(is_equal_approx(tex.curve_y.sample(0.25), 2.5), "Y has independent interpolation")
check(is_equal_approx(tex.curve_x.sample(1.0), 4.0), "scale above two is retained")
check(is_equal_approx(tex.curve_z.sample(0.5), 1.0), "depth scale remains neutral")
var empty: GPUParticles3D = fx._emitters[1]
check(empty.draw_pass_1.size == Vector2.ZERO, "zero source size is not made visible")
var defaults: ParticleProcessMaterial = empty.process_material
if defaults.scale_curve is CurveXYZTexture:
check(defaults.scale_curve.curve_x.sample(1.0) == 1.0 and defaults.scale_curve.curve_y.sample(1.0) == 1.0,
"absent scale tracks stay constant instead of shrinking")
else:
check(false, "default independent curves")
fx.free()
real_resources()
print("effect_scale_test: failures=%d" % failures)
quit(1 if failures else 0)
func real_resources() -> void:
var count := 0
var samples := 0
for name in ["warrior/effect/palbang_4_sword.mse", "assassin/effect/beam_blow.mse",
"sura/effect/pabeopsul_4_blow.mse", "shaman/effect/noejeon_making_1.mse"]:
var path := AssetRoot.path().path_join("PC/ymir work/pc/" + name)
var spec: Dictionary = preload("res://fx/mse.gd").new().parse_file(path)
check(not spec.get("particles", []).is_empty(), "real size resource loaded: " + name)
for particle in spec.get("particles", []):
var fx := EffectPlayer.new()
# Only source size/scale tracks: not a full texture or emission test.
fx.build({"particles": [{"emitter": {
"TimeEventSizeX": particle.emitter.get("TimeEventSizeX", []),
"TimeEventSizeY": particle.emitter.get("TimeEventSizeY", [])}, "particle": {
"TimeEventScaleX": particle.particle.get("TimeEventScaleX", []),
"TimeEventScaleY": particle.particle.get("TimeEventScaleY", [])}}]})
var texture: Texture2D = fx._emitters[0].process_material.scale_curve
check(texture is CurveXYZTexture, "real XY texture " + name)
if texture is CurveXYZTexture:
for axis in range(2):
var key := "TimeEventScaleX" if axis == 0 else "TimeEventScaleY"
var curve: Curve = texture.curve_x if axis == 0 else texture.curve_y
var rows: Array = particle.particle.get(key, [])
for i in rows.size():
var time := float(rows[i][0])
var duplicate := i > 0 and float(rows[i - 1][0]) == time
if time >= 0.0 and time <= 1.0 and not duplicate:
check(is_equal_approx(curve.sample(time), float(rows[i][1])), "real scale key %s %s t=%f got=%f expected=%f" % [name, key, time, curve.sample(time), float(rows[i][1])])
samples += 1
if i > 0 and not duplicate:
var mid := (float(rows[i - 1][0]) + time) * 0.5
var value := (float(rows[i - 1][1]) + float(rows[i][1])) * 0.5
if mid >= 0.0 and mid <= 1.0:
# Duplicate-key jumps occupy 1e-4 of normalized age;
# permit the resulting small interpolation deviation.
var after_jump := i > 1 and float(rows[i - 2][0]) == float(rows[i - 1][0])
var matches := absf(curve.sample(mid) - value) < 0.001 if after_jump else is_equal_approx(curve.sample(mid), value)
check(matches, "real linear midpoint %s %s t=%f got=%f expected=%f" % [name, key, mid, curve.sample(mid), value])
samples += 1
count += 1
fx.free()
print("real scale tracks: particles=%d samples=%d" % [count, samples])