From 3097c404ba7c917f3c33b0a609ed0cebe7479e6d Mon Sep 17 00:00:00 2001 From: henrisel Date: Tue, 13 Jan 2026 16:06:13 +0200 Subject: [PATCH] set up shape detection minigame pieces --- .../Components/Bow/Scripts/ArcheryRange.cs | 4 +- .../_PROJECT/Scenes/DeltaBuilding_base.unity | 4 +- .../ArcheryRangeModelGenerationController.cs | 34 +------- .../ModeGeneration/ImageGenerationBox.cs | 32 +------- .../ModeGeneration/ModelGenerationBox.cs | 2 +- ...lineManager.cs => ModelGenerationUtils.cs} | 38 ++++++++- ...r.cs.meta => ModelGenerationUtils.cs.meta} | 0 .../Scripts/ModeGeneration/PushableButton.cs | 14 +++- .../ShapeDetectionMinigameController.cs | 82 +++++++++++++++++++ .../ShapeDetectionMinigameController.cs.meta | 11 +++ .../ShapeDetection/ShapeScannerRay.cs | 3 +- 11 files changed, 149 insertions(+), 75 deletions(-) rename Assets/_PROJECT/Scripts/ModeGeneration/{PipelineManager.cs => ModelGenerationUtils.cs} (80%) rename Assets/_PROJECT/Scripts/ModeGeneration/{PipelineManager.cs.meta => ModelGenerationUtils.cs.meta} (100%) create mode 100644 Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeDetectionMinigameController.cs create mode 100644 Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeDetectionMinigameController.cs.meta diff --git a/Assets/_PROJECT/Components/Bow/Scripts/ArcheryRange.cs b/Assets/_PROJECT/Components/Bow/Scripts/ArcheryRange.cs index df3ab4c1..683b052d 100644 --- a/Assets/_PROJECT/Components/Bow/Scripts/ArcheryRange.cs +++ b/Assets/_PROJECT/Components/Bow/Scripts/ArcheryRange.cs @@ -147,7 +147,7 @@ public class ArcheryRange : NetworkBehaviour { // spawn generated model targetObject = Instantiate(modelGenerationController.GeneratedModel, randomPos, Quaternion.identity, null); - InitializeArcherytargetObject(targetObject); + InitializeArcheryTargetObject(targetObject); } ArcheryTarget target = targetObject.GetComponent(); @@ -157,7 +157,7 @@ public class ArcheryRange : NetworkBehaviour return target; } - private void InitializeArcherytargetObject(GameObject targetObject) + private void InitializeArcheryTargetObject(GameObject targetObject) { ArcheryTarget archeryTarget = targetObject.AddComponent(); archeryTarget.pointsText = archeryTargetPointsText; diff --git a/Assets/_PROJECT/Scenes/DeltaBuilding_base.unity b/Assets/_PROJECT/Scenes/DeltaBuilding_base.unity index cdd6110e..40f981bd 100644 --- a/Assets/_PROJECT/Scenes/DeltaBuilding_base.unity +++ b/Assets/_PROJECT/Scenes/DeltaBuilding_base.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:87ba06a69a9c94efc8ee642d451e242bb30efac4791a1f363b02e10f1ac0b8b6 -size 67826111 +oid sha256:df69226c542b8be3aa43214986e3e8ec4b8b0cb388cdc2b94d5854b7c70d738a +size 67859352 diff --git a/Assets/_PROJECT/Scripts/ModeGeneration/ArcheryRange/ArcheryRangeModelGenerationController.cs b/Assets/_PROJECT/Scripts/ModeGeneration/ArcheryRange/ArcheryRangeModelGenerationController.cs index be1eddd7..a720fff1 100644 --- a/Assets/_PROJECT/Scripts/ModeGeneration/ArcheryRange/ArcheryRangeModelGenerationController.cs +++ b/Assets/_PROJECT/Scripts/ModeGeneration/ArcheryRange/ArcheryRangeModelGenerationController.cs @@ -46,8 +46,8 @@ public class ArcheryRangeModelGenerationController : MonoBehaviour byte[] imageBytes = await InvokeAiClient.Instance.GenerateImage(refinedPrompt); - GeneratedTexture = CreateTexture(imageBytes); - Sprite sprite = CreateSprite(GeneratedTexture); + GeneratedTexture = ModelGenerationUtils.CreateTexture(imageBytes); + Sprite sprite = ModelGenerationUtils.CreateSprite(GeneratedTexture); imageDisplay.sprite = sprite; imageGenerationButton.Deactivate(); @@ -63,7 +63,7 @@ public class ArcheryRangeModelGenerationController : MonoBehaviour string encodedTexture = Convert.ToBase64String(GeneratedTexture.EncodeToJPG()); byte[] encodedModel = await TrellisClient.Instance.GenerateModel(encodedTexture); - GameObject spawnedObject = await PipelineManager.Instance.SpawnModel(encodedModel); + GameObject spawnedObject = await ModelGenerationUtils.Instance.SpawnModel(encodedModel); // Destroy previous generated object Destroy(GeneratedModel); spawnedObject.transform.parent = modelDisplay; @@ -75,34 +75,6 @@ public class ArcheryRangeModelGenerationController : MonoBehaviour modelGenerationInProgress = false; } - private 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; - } - - private 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; - } - private void OnModelReady() { foreach (MeshRenderer meshRenderer in wire.GetComponentsInChildren()) diff --git a/Assets/_PROJECT/Scripts/ModeGeneration/ImageGenerationBox.cs b/Assets/_PROJECT/Scripts/ModeGeneration/ImageGenerationBox.cs index a924f98a..ad91b4b2 100644 --- a/Assets/_PROJECT/Scripts/ModeGeneration/ImageGenerationBox.cs +++ b/Assets/_PROJECT/Scripts/ModeGeneration/ImageGenerationBox.cs @@ -44,40 +44,12 @@ void Start() meshRenderer.material = loadingMaterial; byte[] imageBytes = await InvokeAiClient.Instance.GenerateImage(refinedPrompt); - LastTexture = CreateTexture(imageBytes); - Sprite sprite = CreateSprite(LastTexture); + LastTexture = ModelGenerationUtils.CreateTexture(imageBytes); + Sprite sprite = ModelGenerationUtils.CreateSprite(LastTexture); imageDisplay.sprite = sprite; isLoading = false; meshRenderer.material = inactiveMaterial; } } - - private 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; - } - - private 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; - } } diff --git a/Assets/_PROJECT/Scripts/ModeGeneration/ModelGenerationBox.cs b/Assets/_PROJECT/Scripts/ModeGeneration/ModelGenerationBox.cs index 838eae47..8d55ca65 100644 --- a/Assets/_PROJECT/Scripts/ModeGeneration/ModelGenerationBox.cs +++ b/Assets/_PROJECT/Scripts/ModeGeneration/ModelGenerationBox.cs @@ -42,7 +42,7 @@ public class ModelGenerationBox : MonoBehaviour string encodedTexture = Convert.ToBase64String(inputTexture.EncodeToJPG()); byte[] encodedModel = await TrellisClient.Instance.GenerateModel(encodedTexture); - GameObject spawnedObject = await PipelineManager.Instance.SpawnModel(encodedModel); + GameObject spawnedObject = await ModelGenerationUtils.Instance.SpawnModel(encodedModel); spawnedObject.AddComponent(); spawnedObject.transform.parent = modelSpawnPoint; spawnedObject.transform.position = modelSpawnPoint.position; diff --git a/Assets/_PROJECT/Scripts/ModeGeneration/PipelineManager.cs b/Assets/_PROJECT/Scripts/ModeGeneration/ModelGenerationUtils.cs similarity index 80% rename from Assets/_PROJECT/Scripts/ModeGeneration/PipelineManager.cs rename to Assets/_PROJECT/Scripts/ModeGeneration/ModelGenerationUtils.cs index 868c5eb6..52bcd795 100644 --- a/Assets/_PROJECT/Scripts/ModeGeneration/PipelineManager.cs +++ b/Assets/_PROJECT/Scripts/ModeGeneration/ModelGenerationUtils.cs @@ -1,12 +1,13 @@ using GLTFast; +using System; using System.Diagnostics; using System.IO; using System.Threading.Tasks; using UnityEngine; -public class PipelineManager : MonoBehaviour +public class ModelGenerationUtils : MonoBehaviour { - public static PipelineManager Instance { get; private set; } + public static ModelGenerationUtils Instance { get; private set; } private void Awake() { @@ -27,7 +28,7 @@ public class PipelineManager : MonoBehaviour /** * Generate model by starting a new Python subprocess - * NOT USED ANYMORE + * NOT USED IN LATEST VERSION **/ public async Task GenerateModelAsync(string inputPrompt) { @@ -82,7 +83,7 @@ public class PipelineManager : MonoBehaviour /** * Spawn model stored on disk - * NOT USED ANYMORE + * NOT USED IN LATEST VERSION * **/ public async Task SpawnModel(string modelPath) @@ -130,4 +131,33 @@ public class PipelineManager : MonoBehaviour 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; + } } diff --git a/Assets/_PROJECT/Scripts/ModeGeneration/PipelineManager.cs.meta b/Assets/_PROJECT/Scripts/ModeGeneration/ModelGenerationUtils.cs.meta similarity index 100% rename from Assets/_PROJECT/Scripts/ModeGeneration/PipelineManager.cs.meta rename to Assets/_PROJECT/Scripts/ModeGeneration/ModelGenerationUtils.cs.meta diff --git a/Assets/_PROJECT/Scripts/ModeGeneration/PushableButton.cs b/Assets/_PROJECT/Scripts/ModeGeneration/PushableButton.cs index 555eb8df..76e0a182 100644 --- a/Assets/_PROJECT/Scripts/ModeGeneration/PushableButton.cs +++ b/Assets/_PROJECT/Scripts/ModeGeneration/PushableButton.cs @@ -58,9 +58,12 @@ public class PushableButton : MonoBehaviour movableParts.DOLocalMoveY(downPositionY, moveDuration); isButtonDown = true; - foreach (MeshRenderer meshRenderer in wire.GetComponentsInChildren()) + if (wire != null) { - meshRenderer.material = wireActiveMaterial; + foreach (MeshRenderer meshRenderer in wire.GetComponentsInChildren()) + { + meshRenderer.material = wireActiveMaterial; + } } } @@ -69,9 +72,12 @@ public class PushableButton : MonoBehaviour movableParts.DOLocalMoveY(upPositionY, moveDuration); isButtonDown = false; - foreach (MeshRenderer meshRenderer in wire.GetComponentsInChildren()) + if (wire != null) { - meshRenderer.material = wireInactiveMaterial; + foreach (MeshRenderer meshRenderer in wire.GetComponentsInChildren()) + { + meshRenderer.material = wireInactiveMaterial; + } } } } diff --git a/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeDetectionMinigameController.cs b/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeDetectionMinigameController.cs new file mode 100644 index 00000000..a141d557 --- /dev/null +++ b/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeDetectionMinigameController.cs @@ -0,0 +1,82 @@ +using FishNet.Component.Transforming; +using FishNet.Object; +using System; +using UnityEngine; +using UnityEngine.UI; + +public class ShapeDetectionMinigameController : MonoBehaviour +{ + public MicrophoneStand microphoneStand; + public PushableButton imageGenerationButton; + public PushableButton modelGenerationButton; + + public string imageGenerationPromptSuffix = ", single object, front and side fully visible, realistic style, plain neutral background, clear details, soft studio lighting, true-to-scale"; + public Texture2D GeneratedTexture { get; private set; } + public Image imageDisplay; + + public GameObject GeneratedModel { get; private set; } + public Transform modelSpawnPoint; + public string shapeScannerTag = "ShapeScannable"; + + private bool modelGenerationInProgress; + + // Start is called before the first frame update + void Start() + { + imageGenerationButton.OnButtonPressed += InvokeImageGeneration; + modelGenerationButton.OnButtonPressed += InvokeModelGeneration; + modelGenerationInProgress = false; + } + + // Update is called once per frame + void Update() + { + + } + + private async void InvokeImageGeneration() + { + string inputPrompt = microphoneStand.GetTextOutput(); + string refinedPrompt = inputPrompt + imageGenerationPromptSuffix; + + byte[] imageBytes = await InvokeAiClient.Instance.GenerateImage(refinedPrompt); + GeneratedTexture = ModelGenerationUtils.CreateTexture(imageBytes); + Sprite sprite = ModelGenerationUtils.CreateSprite(GeneratedTexture); + imageDisplay.sprite = sprite; + + imageGenerationButton.Deactivate(); + if (!modelGenerationInProgress) + { + modelGenerationButton.Deactivate(); + } + } + + private async void InvokeModelGeneration() + { + modelGenerationInProgress = true; + string encodedTexture = Convert.ToBase64String(GeneratedTexture.EncodeToJPG()); + byte[] encodedModel = await TrellisClient.Instance.GenerateModel(encodedTexture); + + GameObject spawnedObject = await ModelGenerationUtils.Instance.SpawnModel(encodedModel); + InitializeSpawnedObject(spawnedObject); + + // Destroy previous generated object + Destroy(GeneratedModel); + GeneratedModel = spawnedObject; + + modelGenerationButton.Deactivate(); + modelGenerationInProgress = false; + } + + private void InitializeSpawnedObject(GameObject spawnedObject) + { + Rigidbody rigidbody = spawnedObject.AddComponent(); + rigidbody.useGravity = false; + rigidbody.isKinematic = true; + spawnedObject.AddComponent(); + spawnedObject.AddComponent(); + spawnedObject.transform.parent = modelSpawnPoint; + spawnedObject.transform.position = modelSpawnPoint.position; + spawnedObject.tag = shapeScannerTag; + } +} diff --git a/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeDetectionMinigameController.cs.meta b/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeDetectionMinigameController.cs.meta new file mode 100644 index 00000000..917ad7c3 --- /dev/null +++ b/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeDetectionMinigameController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7000d3fd17422c74e9f86757bc8529f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeScannerRay.cs b/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeScannerRay.cs index b25cf291..7b5fda48 100644 --- a/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeScannerRay.cs +++ b/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeScannerRay.cs @@ -6,6 +6,7 @@ public class ShapeScannerRay : MonoBehaviour { public Material _activeMaterial; public Material _passiveMaterial; + public string scannableTag = "ShapeScannable"; private ShapeScanner _scanner; private MeshRenderer meshRenderer; @@ -33,7 +34,7 @@ public class ShapeScannerRay : MonoBehaviour private void OnTriggerEnter(Collider other) { - if (other.gameObject.tag == "ShapeScannable") + if (other.gameObject.tag == scannableTag) { meshRenderer.material = _activeMaterial; if (_collisionRequired)