using System.IO; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; namespace HexapodSim { // Batch-mode check of the OpenSCAD model in Main.unity, without entering // Play mode: builds the model from the DLL's geometry, poses the legs in // the firmware's standing pose and renders the main camera to PNGs. // Unity.exe -batchmode -projectPath . -executeMethod HexapodSim.OpenScadModelSnapshot.Run // -snapshotDir -quit public static class OpenScadModelSnapshot { public static void Run() { string dir = Arg("-snapshotDir") ?? Path.GetFullPath("Temp/OpenScadSnapshot"); Directory.CreateDirectory(dir); EditorSceneManager.OpenScene("Assets/Main.unity"); Transform chassis = null; foreach (var t in Object.FindObjectsByType()) if (t.name == "Leg" && t.Find("hip1") != null) { chassis = t.parent; break; } if (chassis == null) { Debug.LogError("[Snapshot] no leg rig in Main.unity"); EditorApplication.Exit(1); return; } string dll = Path.GetFullPath(Path.Combine(Application.dataPath, "..", "..", "sim", "build", "hexapod_sim.dll")); HxGeometry g; using (var native = HexapodSimNative.Load(dll)) g = native.Geometry; OpenScadModel.Build(chassis, g, ForwardAxis.NegativeX, 0.1f); // Firmware stance: coxa 0, femur -1.2, tibia -98.3 (HexapodSimulation.ApplyJoints). foreach (Transform leg in chassis) { if (leg.name != "Leg" || !leg.gameObject.activeSelf) continue; var hip2 = leg.Find("hip1/Hip2"); var knie = leg.Find("hip1/Hip2/Knie"); hip2.localRotation = Quaternion.Euler(1.2f, 0, 0); knie.localRotation = Quaternion.Euler(-(-98.3f + 90f), 0, 0); } var cam = Camera.main; if (cam == null) cam = new GameObject("SnapshotCamera").AddComponent(); Vector3 c = chassis.position; Shoot(cam, c + new Vector3(-30, 22, -38), c, Path.Combine(dir, "front_left.png")); Shoot(cam, c + new Vector3(42, 30, 20), c, Path.Combine(dir, "rear_right.png")); Shoot(cam, c + new Vector3(0.01f, 60, 0), c, Path.Combine(dir, "top.png")); Debug.Log("[Snapshot] wrote " + dir); EditorApplication.Exit(0); } static void Shoot(Camera cam, Vector3 pos, Vector3 target, string file) { cam.transform.position = pos; cam.transform.LookAt(target); cam.fieldOfView = 45; var rt = new RenderTexture(1280, 900, 24); cam.targetTexture = rt; cam.Render(); RenderTexture.active = rt; var tex = new Texture2D(rt.width, rt.height, TextureFormat.RGB24, false); tex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0); tex.Apply(); File.WriteAllBytes(file, tex.EncodeToPNG()); cam.targetTexture = null; RenderTexture.active = null; } static string Arg(string name) { var a = System.Environment.GetCommandLineArgs(); for (int i = 0; i < a.Length - 1; i++) if (a[i] == name) return a[i + 1]; return null; } } }