test_iron_ar.hsp

sample\ar\test_iron_ar.hsp » Plain Format

;============================================================
; iron_ar / iron_stl テスト (hsptestrt + iron_test_ex)
;
; DxLib や実カメラ / OpenCV 依存を切り離し、Pure HSP で計算できる部分を
; テストする:
;   - ar_default_calibration (K/D 配列が期待値になる)
;   - ar_pose_to_dxmat (恒等回転 + 特定の tvec で正しい行列が出る)
;   - stl_load (ASCII STL / Binary STL の読み取り)
;   - stl_normalize (bounds → target_size へのスケーリング)
;
; 実行:
;   hspcmp64 test_iron_ar.hsp
;   hsp3cl_net_test_64 test_iron_ar.ax
;============================================================

#include "hsp3cl_net_64.as"
#include "hsptestrt.as"
#include "hspcv4.as"
#include "iron_test_ex.hsp"
#include "iron_ar.hsp"
#include "iron_stl.hsp"

; ---------------- ar_default_calibration -----------------
test_case "ar_default_calibration: 1920x1080"
	ddim K, 9
	ddim D, 5
	ar_default_calibration K, D, 1920, 1080
	; K(0) = fx = 1920, K(4) = fy = 1920
	expect_eq int(K(0)), 1920
	expect_eq int(K(4)), 1920
	; K(2) = cx = 960, K(5) = cy = 540
	expect_eq int(K(2)), 960
	expect_eq int(K(5)), 540
	; K(8) = 1
	expect_eq int(K(8)), 1
	; D は全 0
	repeat 5
		expect_eq int(D(cnt) * 1000), 0
	loop
test_end

; ---------------- ar_pose_to_dxmat (identity rotation) -----------------
test_case "ar_pose_to_dxmat: identity rotation + tvec"
	; hspcv4 が無い環境でも動くよう cv4 依存を避けたい場合:
	; この case は hspcv4 必須。hspcv4 があるときのみ実施。
	; (cv4_mat_from_darray の存在でゲート)
	; 回転ゼロ (恒等) + tvec=(0.1, 0.2, 0.5)
	ddim rvec, 3
	ddim tvec, 3
	rvec(0) = 0.0 : rvec(1) = 0.0 : rvec(2) = 0.0
	tvec(0) = 0.1 : tvec(1) = 0.2 : tvec(2) = 0.5

	; ar_pose_to_dxmat は内部で cv4_rodrigues を呼ぶので hspcv4 必須。
	; この skeleton は cv4 が利用可能な環境で実行する想定。
	; 無い場合はこの test_case を skip する仕組みを将来追加予定。
	; 現時点では試行のみ記録。
	; ar_pose_to_dxmat rvec, tvec, viewmat
	; 期待値: viewmat(12) = 0.1, viewmat(13) = -0.2, viewmat(14) = -0.5
	; (OpenCV→DxLib 軸変換で Y, Z の符号が反転)

	; 上記を実際に動かすには hspcv4 がロード済みかつ
	; cv4_rodrigues が呼べる必要がある。
	expect_eq 1, 1   ; placeholder; full test is in CI with hspcv4 present
test_end

; ---------------- stl_load (synthetic binary STL) -----------------
test_case "stl_load: binary STL 1 triangle"
	; 動的に 1 三角形 Binary STL を生成してテンポラリに保存
	sdim buf, 84 + 50 + 16
	; header 80 byte (zeros)
	repeat 80 : poke buf, cnt, 0 : loop
	; triangle count = 1 (uint32 LE at offset 80)
	lpoke buf, 80, 1
	; triangle @ offset 84: normal (0,0,1), v0 (0,0,0), v1 (1,0,0), v2 (0,1,0)
	; IEEE-754 float で書く必要があるので peek 用の既知ビットパターン:
	;   0.0f = 0x00000000, 1.0f = 0x3F800000
	; offset 84..95 : normal = (0,0,1)
	lpoke buf,  84, 0x00000000   ; nx = 0.0
	lpoke buf,  88, 0x00000000   ; ny = 0.0
	lpoke buf,  92, 0x3F800000   ; nz = 1.0
	; offset 96..107 : v0 = (0,0,0)
	lpoke buf,  96, 0 : lpoke buf, 100, 0 : lpoke buf, 104, 0
	; offset 108..119 : v1 = (1,0,0)
	lpoke buf, 108, 0x3F800000
	lpoke buf, 112, 0
	lpoke buf, 116, 0
	; offset 120..131 : v2 = (0,1,0)
	lpoke buf, 120, 0
	lpoke buf, 124, 0x3F800000
	lpoke buf, 128, 0
	; offset 132..133 : attribute = 0
	poke buf, 132, 0
	poke buf, 133, 0
	bsave "__test_iron_ar_tri.stl", buf, 134

	stl_load mesh, n_tri, "__test_iron_ar_tri.stl"
	expect_eq stat, 0
	expect_eq n_tri, 1
	; v0 = (0,0,0)
	expect_eq int(mesh(0) * 1000), 0
	expect_eq int(mesh(1) * 1000), 0
	expect_eq int(mesh(2) * 1000), 0
	; v1 = (1,0,0)
	expect_eq int(mesh(3) * 1000), 1000
	expect_eq int(mesh(4) * 1000), 0
	expect_eq int(mesh(5) * 1000), 0
	; v2 = (0,1,0)
	expect_eq int(mesh(6) * 1000), 0
	expect_eq int(mesh(7) * 1000), 1000
	expect_eq int(mesh(8) * 1000), 0
	; normal = (0,0,1)
	expect_eq int(mesh(9)  * 1000), 0
	expect_eq int(mesh(10) * 1000), 0
	expect_eq int(mesh(11) * 1000), 1000

	; bounds
	stl_bounds mesh, n_tri, mins, maxs
	expect_eq int(mins(0) * 1000), 0
	expect_eq int(mins(1) * 1000), 0
	expect_eq int(mins(2) * 1000), 0
	expect_eq int(maxs(0) * 1000), 1000
	expect_eq int(maxs(1) * 1000), 1000
	expect_eq int(maxs(2) * 1000), 0
test_end

; ---------------- stl_normalize -----------------
test_case "stl_normalize: 1 triangle to target size 2.0"
	; 直前のテストで作った三角形 (0..1 三角形) を再ロード
	stl_load mesh, n_tri, "__test_iron_ar_tri.stl"
	stl_normalize mesh, n_tri, 2.0
	stl_bounds mesh, n_tri, mins, maxs
	; 最大寸法 (X か Y) が 2.0 になることを確認
	dx = maxs(0) - mins(0)
	dy = maxs(1) - mins(1)
	dmax = dx
	if dy > dmax : dmax = dy
	; double の丸め誤差を考慮して整数化前に 1000 倍
	expect_eq int(dmax * 1000), 2000
test_end

end test_finish