1
0
forked from cgvr/DeltaVR
Files
DeltaVR3DModelGeneration/Assets/_PROJECT/Scripts/ModeGeneration/ModelGenerationUtils.cs

164 lines
5.0 KiB
C#

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<string> 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<GameObject> 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<GameObject> 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<GameObject> 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<MeshCollider>();
collider.convex = true;
MeshRenderer renderer = spawnedObjectBody.GetComponent<MeshRenderer>();
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;
}
}