82 lines
4.3 KiB
GDScript
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])
|