;============================================================ ; 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