using GLTFast; using System; using System.Diagnostics; using System.IO; using System.Threading.Tasks; using UnityEngine; public class ModelGenerationUtils : MonoBehaviour { public static ModelGenerationUtils Instance { get; private set; } private void Awake() { Instance = this; } // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } /** * Generate model by starting a new Python subprocess * NOT USED IN LATEST VERSION **/ public async Task GenerateModelAsync(string inputPrompt) { return await Task.Run(() => { // Path to your virtual environment's python.exe string pythonExe = @"D:\users\henrisel\DeltaVR3DModelGeneration\3d-generation-pipeline\.venv\Scripts\python.exe"; // Path to your Python script string scriptPath = @"D:\users\henrisel\DeltaVR3DModelGeneration\3d-generation-pipeline\start_pipeline.py"; // Arguments to pass to the script string arguments = $"{scriptPath} --prompt \"{inputPrompt}\""; ProcessStartInfo psi = new ProcessStartInfo { FileName = pythonExe, Arguments = arguments, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true }; using (Process process = new Process()) { process.StartInfo = psi; process.OutputDataReceived += (sender, e) => UnityEngine.Debug.Log(e.Data); process.ErrorDataReceived += (sender, e) => UnityEngine.Debug.LogError(e.Data); process.Start(); string output = process.StandardOutput.ReadToEnd(); string error = process.StandardError.ReadToEnd(); process.WaitForExit(); // Extract model path from output foreach (string line in output.Split('\n')) { if (line.StartsWith("Generated 3D model file: ")) { return line.Replace("Generated 3D model file: ", "").Trim(); } } throw new System.Exception("Failed to generate 3D model!"); } }); } /** * Spawn model stored on disk * NOT USED IN LATEST VERSION * **/ public async Task SpawnModel(string modelPath) { var gltf = new GltfImport(); bool loadSuccess = await gltf.Load(modelPath); if (loadSuccess) { string objectName = Path.GetFileName(modelPath); return await SpawnModel(gltf, objectName); } throw new System.Exception("Failed to load GameObject from model" + modelPath); } public async Task SpawnModel(byte[] modelBinary) { var gltf = new GltfImport(); bool loadSuccess = await gltf.Load(modelBinary); if (loadSuccess) { return await SpawnModel(gltf, "GeneratedModel"); } throw new System.Exception("Failed to load GameObject from binary!"); } public async Task SpawnModel(GltfImport gltfImport, string objectName) { GameObject spawningParent = new GameObject("Parent-" + objectName); bool spawnSuccess = await gltfImport.InstantiateMainSceneAsync(spawningParent.transform); if (spawnSuccess) { Transform spawnedObjectWorldTransform = spawningParent.transform.GetChild(0).transform; GameObject spawnedObjectBody = spawnedObjectWorldTransform.GetChild(0).transform.gameObject; MeshCollider collider = spawnedObjectBody.AddComponent(); collider.convex = true; MeshRenderer renderer = spawnedObjectBody.GetComponent(); renderer.material.SetFloat("metallicFactor", 0); spawnedObjectBody.name = objectName; return spawnedObjectBody; } throw new System.Exception("Failed to spawn GameObject " + objectName); } public static Texture2D CreateTexture(byte[] imageBytes) { var tex = new Texture2D(2, 2, TextureFormat.RGBA32, false); // ImageConversion.LoadImage returns bool (true = success) if (!ImageConversion.LoadImage(tex, imageBytes, markNonReadable: false)) { Destroy(tex); throw new InvalidOperationException("Failed to decode image bytes into Texture2D."); } tex.filterMode = FilterMode.Bilinear; tex.wrapMode = TextureWrapMode.Clamp; return tex; } public static Sprite CreateSprite(Texture2D tex) { var sprite = Sprite.Create( tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f), pixelsPerUnit: 100f ); return sprite; } }