From 99d285a24ffc53d7cc4b35ea8c68aae4f8282bcc Mon Sep 17 00:00:00 2001 From: Tim Date: Sun, 27 Apr 2025 06:22:02 +0200 Subject: [PATCH] add initial Model System (not fully operational) --- .gitignore | 3 +- .../Assets/Scenes/SampleScene.unity | 107 ++++++++++++++-- vr-configurator/Assets/Scripts/Models.meta | 8 ++ .../Assets/Scripts/Models/BaseModel.cs | 13 ++ .../Assets/Scripts/Models/BaseModel.cs.meta | 2 + .../Scripts/Models/BaseModelBehaviour.cs | 26 ++++ .../Scripts/Models/BaseModelBehaviour.cs.meta | 2 + .../Assets/Scripts/Models/ChildModel.cs | 14 ++ .../Assets/Scripts/Models/ChildModel.cs.meta | 2 + .../Scripts/Models/ChildModelBehaviour.cs | 31 +++++ .../Models/ChildModelBehaviour.cs.meta | 2 + .../Assets/Scripts/Models/Definitions.cs | 6 + .../Assets/Scripts/Models/Definitions.cs.meta | 3 + .../Assets/Scripts/Models/Model.cs | 76 +++++++++++ .../Assets/Scripts/Models/Model.cs.meta | 2 + .../Assets/Scripts/Models/ModelBehaviour.cs | 93 ++++++++++++++ .../Scripts/Models/ModelBehaviour.cs.meta | 3 + .../Assets/Scripts/Models/ModelList.cs | 120 ++++++++++++++++++ .../Assets/Scripts/Models/ModelList.cs.meta | 3 + .../Assets/Scripts/Models/ModelManager.cs | 96 ++++++++++++++ .../Scripts/Models/ModelManager.cs.meta | 2 + vr-configurator/Assets/Scripts/Models/Port.cs | 44 +++++++ .../Assets/Scripts/Models/Port.cs.meta | 2 + vr-configurator/Assets/Scripts/UI.meta | 8 ++ vr-configurator/Assets/Scripts/Util.meta | 3 + .../Assets/Scripts/Util/MathUtil.cs | 106 ++++++++++++++++ .../Assets/Scripts/Util/MathUtil.cs.meta | 3 + .../Assets/Scripts/Util/ModelLoader.cs | 24 ++++ .../Assets/Scripts/Util/ModelLoader.cs.meta | 3 + 29 files changed, 796 insertions(+), 11 deletions(-) create mode 100644 vr-configurator/Assets/Scripts/Models.meta create mode 100644 vr-configurator/Assets/Scripts/Models/BaseModel.cs create mode 100644 vr-configurator/Assets/Scripts/Models/BaseModel.cs.meta create mode 100644 vr-configurator/Assets/Scripts/Models/BaseModelBehaviour.cs create mode 100644 vr-configurator/Assets/Scripts/Models/BaseModelBehaviour.cs.meta create mode 100644 vr-configurator/Assets/Scripts/Models/ChildModel.cs create mode 100644 vr-configurator/Assets/Scripts/Models/ChildModel.cs.meta create mode 100644 vr-configurator/Assets/Scripts/Models/ChildModelBehaviour.cs create mode 100644 vr-configurator/Assets/Scripts/Models/ChildModelBehaviour.cs.meta create mode 100644 vr-configurator/Assets/Scripts/Models/Definitions.cs create mode 100644 vr-configurator/Assets/Scripts/Models/Definitions.cs.meta create mode 100644 vr-configurator/Assets/Scripts/Models/Model.cs create mode 100644 vr-configurator/Assets/Scripts/Models/Model.cs.meta create mode 100644 vr-configurator/Assets/Scripts/Models/ModelBehaviour.cs create mode 100644 vr-configurator/Assets/Scripts/Models/ModelBehaviour.cs.meta create mode 100644 vr-configurator/Assets/Scripts/Models/ModelList.cs create mode 100644 vr-configurator/Assets/Scripts/Models/ModelList.cs.meta create mode 100644 vr-configurator/Assets/Scripts/Models/ModelManager.cs create mode 100644 vr-configurator/Assets/Scripts/Models/ModelManager.cs.meta create mode 100644 vr-configurator/Assets/Scripts/Models/Port.cs create mode 100644 vr-configurator/Assets/Scripts/Models/Port.cs.meta create mode 100644 vr-configurator/Assets/Scripts/UI.meta create mode 100644 vr-configurator/Assets/Scripts/Util.meta create mode 100644 vr-configurator/Assets/Scripts/Util/MathUtil.cs create mode 100644 vr-configurator/Assets/Scripts/Util/MathUtil.cs.meta create mode 100644 vr-configurator/Assets/Scripts/Util/ModelLoader.cs create mode 100644 vr-configurator/Assets/Scripts/Util/ModelLoader.cs.meta diff --git a/.gitignore b/.gitignore index 37cfd73..b016bcd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /build/ .vs/ -.idea/ \ No newline at end of file +.idea/ +*.xlsx \ No newline at end of file diff --git a/vr-configurator/Assets/Scenes/SampleScene.unity b/vr-configurator/Assets/Scenes/SampleScene.unity index 2c41ea8..0cc9cc6 100644 --- a/vr-configurator/Assets/Scenes/SampleScene.unity +++ b/vr-configurator/Assets/Scenes/SampleScene.unity @@ -1757,7 +1757,7 @@ Canvas: m_OverridePixelPerfect: 0 m_SortingBucketNormalizedSize: 0 m_VertexColorAlwaysGammaSpace: 0 - m_AdditionalShaderChannelsFlag: 0 + m_AdditionalShaderChannelsFlag: 25 m_UpdateRectTransformForStandalone: 0 m_SortingLayerID: 0 m_SortingOrder: 0 @@ -9763,7 +9763,7 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_text: Button + m_text: Explode m_isRightToLeft: 0 m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} @@ -9790,10 +9790,10 @@ MonoBehaviour: m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_fontSize: 24 - m_fontSizeBase: 24 + m_fontSize: 67.1 + m_fontSizeBase: 45.5 m_fontWeight: 400 - m_enableAutoSizing: 0 + m_enableAutoSizing: 1 m_fontSizeMin: 18 m_fontSizeMax: 72 m_fontStyle: 0 @@ -19082,7 +19082,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d328782a7e1a9ff42a3c023ed7e0d15d, type: 3} m_Name: m_EditorClassIdentifier: - baseModel: {fileID: 0} + baseModel: {fileID: 635547659324016994} --- !u!4 &1519836176 Transform: m_ObjectHideFlags: 0 @@ -19189,7 +19189,7 @@ RectTransform: m_GameObject: {fileID: 1529339493} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 2.11, y: 1.39, z: 1} + m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: - {fileID: 692287308} @@ -19198,7 +19198,7 @@ RectTransform: m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} m_AnchoredPosition: {x: -50, y: -300} - m_SizeDelta: {x: 160, y: 30} + m_SizeDelta: {x: 300, y: 75} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &1529339495 MonoBehaviour: @@ -19269,7 +19269,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} - m_Color: {r: 0.96981126, g: 0.05672476, b: 0.05672476, a: 1} + m_Color: {r: 1, g: 0.49922913, b: 0.4481132, a: 1} m_RaycastTarget: 1 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 @@ -26730,7 +26730,7 @@ GameObject: - component: {fileID: 2570646523283659308} - component: {fileID: 5835772783336047337} m_Layer: 0 - m_Name: Body + m_Name: BaseModel m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -26796,6 +26796,14 @@ Transform: m_Children: [] m_Father: {fileID: 4167280744235935536} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &1286141610436487884 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6541453644100210917} + m_Mesh: {fileID: 1918613174686994728, guid: 0462c71270f87cd4ab04b49dc157d6ff, type: 3} --- !u!33 &1721698302579877505 MeshFilter: m_ObjectHideFlags: 0 @@ -26804,6 +26812,51 @@ MeshFilter: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 8761314634276183315} m_Mesh: {fileID: 3255905351707407981, guid: e3a436e0ac6013f41999e23f2cc91370, type: 3} +--- !u!23 &1896872467895719795 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6541453644100210917} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2215963099469334132, guid: 0462c71270f87cd4ab04b49dc157d6ff, type: 3} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!23 &1911111898470859288 MeshRenderer: m_ObjectHideFlags: 0 @@ -27085,6 +27138,21 @@ GameObject: m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 +--- !u!4 &4993107373397872358 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6541453644100210917} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0.9848078, z: -0.17364816, w: 0} + m_LocalPosition: {x: 0.11, y: 4.36, z: 6.6} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 20, y: 180, z: 0} --- !u!4 &5156012375493846295 Transform: m_ObjectHideFlags: 0 @@ -27188,6 +27256,24 @@ MeshFilter: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 36843658363099064} m_Mesh: {fileID: -1159910841360783040, guid: e3a436e0ac6013f41999e23f2cc91370, type: 3} +--- !u!1 &6541453644100210917 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4993107373397872358} + - component: {fileID: 1286141610436487884} + - component: {fileID: 1896872467895719795} + m_Layer: 0 + m_Name: Overseer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 --- !u!4 &7095972245112083558 Transform: m_ObjectHideFlags: 0 @@ -27315,4 +27401,5 @@ SceneRoots: - {fileID: 1307385173} - {fileID: 4127012} - {fileID: 2061244015} + - {fileID: 4993107373397872358} - {fileID: 1519836176} diff --git a/vr-configurator/Assets/Scripts/Models.meta b/vr-configurator/Assets/Scripts/Models.meta new file mode 100644 index 0000000..5c36dad --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a7633be36b6e2f3428bff1ec6077d3b1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/vr-configurator/Assets/Scripts/Models/BaseModel.cs b/vr-configurator/Assets/Scripts/Models/BaseModel.cs new file mode 100644 index 0000000..5b1b04c --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/BaseModel.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using UnityEngine; + +// Data definition of BaseModel +public class BaseModel : Model +{ + public BaseModel(string nameHuman, string nameId, Mesh mesh, Material material, List ports = null) + : base(nameHuman, nameId, mesh, material, ports) + { + + } +} + diff --git a/vr-configurator/Assets/Scripts/Models/BaseModel.cs.meta b/vr-configurator/Assets/Scripts/Models/BaseModel.cs.meta new file mode 100644 index 0000000..033080a --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/BaseModel.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a9533f9b2cc8153459eeb47fc2ab9cb1 \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/Models/BaseModelBehaviour.cs b/vr-configurator/Assets/Scripts/Models/BaseModelBehaviour.cs new file mode 100644 index 0000000..6355453 --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/BaseModelBehaviour.cs @@ -0,0 +1,26 @@ +using System; + +//Only one should exist at the same time +public class BaseModelBehaviour : ModelBehaviour +{ + BaseModel baseModel + { + get + { + if (model is BaseModel bModel) + { + return bModel; + } + throw new InvalidCastException("model needs to be of type BaseModel"); + } + set + { + model = value; + } + } + + public void UpdateChildPorts(BaseModel model) + { + base.UpdateModel(model); + } +} \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/Models/BaseModelBehaviour.cs.meta b/vr-configurator/Assets/Scripts/Models/BaseModelBehaviour.cs.meta new file mode 100644 index 0000000..712e271 --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/BaseModelBehaviour.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: fd4fcdc40e7716b4fb712ddf70bf60d0 \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/Models/ChildModel.cs b/vr-configurator/Assets/Scripts/Models/ChildModel.cs new file mode 100644 index 0000000..96c395f --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/ChildModel.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using UnityEngine; + +// Data definition of ChildModel +public class ChildModel : Model +{ + public string port { get; private set; } // port + + public ChildModel(string port, string nameHuman, string nameId, Mesh mesh, Material material, List ports = null) + : base(nameHuman, nameId, mesh, material, ports) + { + this.port = port; + } +} diff --git a/vr-configurator/Assets/Scripts/Models/ChildModel.cs.meta b/vr-configurator/Assets/Scripts/Models/ChildModel.cs.meta new file mode 100644 index 0000000..bf58e18 --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/ChildModel.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: bb45a1c1fd4ef514baa9ac88f0a14c8f \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/Models/ChildModelBehaviour.cs b/vr-configurator/Assets/Scripts/Models/ChildModelBehaviour.cs new file mode 100644 index 0000000..d28abe7 --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/ChildModelBehaviour.cs @@ -0,0 +1,31 @@ +using JetBrains.Annotations; +using System; +using UnityEngine; + +public class ChildModelBehaviour : ModelBehaviour +{ + public ChildModel childModel + { + get + { + if (model == null) + { + return null; + } + if (model is ChildModel cModel) + { + return cModel; + } + throw new InvalidCastException("ChildModelBehaviour needs to be of type ChildModel"); + } + internal set + { + model = value; + } + } + + public void UpdateModel(ChildModel model) + { + base.UpdateModel(model); + } +} \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/Models/ChildModelBehaviour.cs.meta b/vr-configurator/Assets/Scripts/Models/ChildModelBehaviour.cs.meta new file mode 100644 index 0000000..d07d462 --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/ChildModelBehaviour.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: e9105cf5e0ef6414eafbf5b9ae838cca \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/Models/Definitions.cs b/vr-configurator/Assets/Scripts/Models/Definitions.cs new file mode 100644 index 0000000..fca928c --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/Definitions.cs @@ -0,0 +1,6 @@ +using JetBrains.Annotations; + +public class Definitions +{ + public const string PORT_BIKE_WHEEL = "bikeWheel"; +} diff --git a/vr-configurator/Assets/Scripts/Models/Definitions.cs.meta b/vr-configurator/Assets/Scripts/Models/Definitions.cs.meta new file mode 100644 index 0000000..d0152df --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/Definitions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 67b196e6a7bf433181e531abd7728f03 +timeCreated: 1745723210 \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/Models/Model.cs b/vr-configurator/Assets/Scripts/Models/Model.cs new file mode 100644 index 0000000..5988aef --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/Model.cs @@ -0,0 +1,76 @@ +using UnityEngine; +using System.Collections.Generic; + +public class Model +{ + public string nameHuman { get; internal set; } // human-readable name + public string nameId { get; internal set; } // JSON export name, should be unique + public Mesh mesh { get; internal set; } // obj/fbx + public Material material { get; internal set; } // skin + + + public readonly List ports; + + public Model(string nameHuman, string nameId, Mesh mesh, Material material, List ports = null) + { + this.nameHuman = nameHuman; + this.nameId = nameId; + this.mesh = mesh; + this.material = material; + this.ports = ports; + } + + public bool hasPorts() + { + return ports != null && ports.Count > 0; + } + + public void addPort(Port port) + { + ports.Add(port); + } + + /// + /// Spawns all Port-GO's, should be called only once + /// + /// gameObject in the MonoBehaviour + /// All spawned GO's + public List spawnAllPorts(GameObject parent) + { + Debug.Log($"{this.nameId}: Spawning {parent.name} count of {ports.Count} Ports"); + List ret = new List(); + for (int i = 0; i < ports.Count; i++) + { + var port = ports[i]; + Debug.Log(i + ". Creating port " + port.port); + // bike:wheel:num + GameObject child = new GameObject(parent.name + ":" + port.port + ":" + i); + ChildModelBehaviour cmb = child.AddComponent(); + + var model = cmb.GetComponent().getById(port.defaultId); + + if (model.mesh == null) + { + Debug.LogError("Default Mesh Not Found, destoying child"); + Object.Destroy(child); + continue; + } + Debug.Log($"Loaded Default Mesh: {model.mesh.name}"); + //set mesh + var meshFilter = child.AddComponent(); + meshFilter.mesh = model.mesh; + meshFilter.sharedMesh = model.mesh; + //set material + var meshRenderer = child.AddComponent(); + meshRenderer.material = model.material; + + child.transform.SetParent(parent.transform); //makes this an actual child + port.apply(child.transform); // move to correct position + ret.Add(child); // i debugged 1.5 hours for this + } + + return ret; + } + + +} \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/Models/Model.cs.meta b/vr-configurator/Assets/Scripts/Models/Model.cs.meta new file mode 100644 index 0000000..29856d8 --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/Model.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: eff3a0c8d61143e43b6e1f29a79f36fd \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/Models/ModelBehaviour.cs b/vr-configurator/Assets/Scripts/Models/ModelBehaviour.cs new file mode 100644 index 0000000..0788f42 --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/ModelBehaviour.cs @@ -0,0 +1,93 @@ +using System.Collections.Generic; +using UnityEngine; + +/// +/// Base for BaseModelBehaviour and ChildModelBehaviour +/// +public class ModelBehaviour : MonoBehaviour +{ + internal Model model; //should be verified + internal List children; + internal MeshFilter meshFilter; + internal MeshRenderer meshRenderer; + + void Start() + { + var filter = gameObject.GetComponent(); + if (filter == null) + { + filter = gameObject.AddComponent(); + } + meshFilter = filter; + + var renderer = gameObject.GetComponent(); + if (renderer == null) + { + renderer = gameObject.AddComponent(); + } + meshRenderer = renderer; + } + + internal void UpdateModel(Model _model) + { + //kill old children + foreach (var go in GetComponentsInChildren()) + { + Debug.Log($"Destroying {go.name}"); + Destroy(go); // will be destroyed next frame + } + model = _model; + //spawn new childPorts + if (model.hasPorts()) + { + Debug.Log($"Spawning {gameObject.name}'s ports"); + children = model.spawnAllPorts(gameObject); + } + //change ourselves + meshFilter.mesh = _model.mesh; + meshFilter.sharedMesh = _model.mesh; + meshRenderer.material = _model.material; + meshRenderer.sharedMaterial = _model.material; + } + + public void UpdateChild(int childNum, string id) + { + var newChildModel = GetComponent().getById(id); + children[childNum].GetComponent().UpdateModel(newChildModel); + } + + public List getChildrenWithPort(string port) + { + List list = new List(); + for (int i = 0; i < children.Count; i++) + { + if (children[i].GetComponent().childModel.port == port) + { + list.Add(i); + } + } + return list; + } + + public bool setFirstWithPort(string port, ChildModel _childModel) + { + Debug.Log($"{this.name}: has {children.Count} children"); + for (int i = 0; i < children.Count; i++) + { + var cmb = children[i].GetComponent(); + Debug.Log($"{this.name}: {i} name {children[i].name} - port {cmb.childModel.port}"); + if(cmb.childModel.port == port) + { + if (_childModel == null) + { + Debug.LogWarning($"{this.name}: Cant replace port {port} with model, model is null"); + return false; + } + cmb.UpdateModel(model); + return true; + } + } + Debug.LogWarning($"{this.name}: Didnt find port {port}"); + return false; + } +} diff --git a/vr-configurator/Assets/Scripts/Models/ModelBehaviour.cs.meta b/vr-configurator/Assets/Scripts/Models/ModelBehaviour.cs.meta new file mode 100644 index 0000000..81624a3 --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/ModelBehaviour.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: aad4d1bbb92a4744abb7856750d481fa +timeCreated: 1745719350 \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/Models/ModelList.cs b/vr-configurator/Assets/Scripts/Models/ModelList.cs new file mode 100644 index 0000000..07e3e3b --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/ModelList.cs @@ -0,0 +1,120 @@ +using System.Collections.Generic; +using Unity.Mathematics; +using UnityEngine; + +public class ModelList +{ + public static readonly List BaseModels = new List() + { + new BaseModel( + "Fahrrad", "bike", + Resources.Load("Bicycle/Models/Low-Poly Bicycle # 5"), + new Material(Shader.Find("VR/SpatialMapping/Occlusion")), + new List + { + new Port(Definitions.PORT_BIKE_WHEEL, new Vector3(10,0,0), "bike30inchAlloy"), + new Port(Definitions.PORT_BIKE_WHEEL, new Vector3(-10,0,0), "bike30inchAlloy"), + new Port("bikePedalL", new Vector3(0,10,0), "bikePedalL"), + new Port("bikePedalR", new Vector3(0,-10,0), "bikePedalR"), + new Port("bikeB", new Vector3(0f,1f,0f), new Quaternion(0f,45f,0f,0f), "name1"), + new Port("driver", new Vector3(0f,1.6f,0f), "bacteria"), + } + ) + }; + public static readonly List ChildModels = new List() + { + new ChildModel( + "driver", "Bacteria", "bacteria", + Resources.Load("Plagues/Mesh/bacteria"), + new Material(Shader.Find("VR/SpatialMapping/Occlusion")), + null + ), + new ChildModel( + "driver", "Virus", "virus", + Resources.Load("Plagues/Mesh/Virus"), + new Material(Shader.Find("VR/SpatialMapping/Occlusion")), + null + ), + new ChildModel( + Definitions.PORT_BIKE_WHEEL, "30 Zoller MehrSpeicherFelge", "bike30inchAlloy", + Resources.Load("Plagues/Mesh/Hex"), + new Material(Shader.Find("VR/SpatialMapping/Occlusion")), + null + ), + new ChildModel( + "bikePedalR", "Pedal Rechts", "bikePedalR", + Resources.Load("Plagues/Mesh/Hex"), + new Material(Shader.Find("VR/SpatialMapping/Occlusion")), + null + ), + new ChildModel( + "bikePedalL", "Pedal Links", "bikePedalL", + Resources.Load("Plagues/Mesh/Hex"), + new Material(Shader.Find("VR/SpatialMapping/Occlusion")), + null + ) + }; + + static ModelList() + { + // i love importing .fbx, maybe refactor this function some day + ChildModels.AddRange(ModelLoader.LoadChildModels( + new string[] // port + { + "bikeB", + "bikeB", + "bikeB", + "bikeB", + "bikeB", + "bikeB", + "bikeB", + "bikeB" + }, + new string[] //human name + { + "name1", + "name2", + "name3", + "name4", + "name5", + "name6", + "name7", + "name8", + }, + new string[] //id + { + "id1", + "id2", + "id3", + "id4", + "id5", + "id6", + "id7", + "id8", + }, + Resources.LoadAll("Bicycle/Models/Low-Poly Bicycle # 5"), + new Material[] //mat + { + new Material(Shader.Find("VR/SpatialMapping/Occlusion")), + new Material(Shader.Find("VR/SpatialMapping/Occlusion")), + new Material(Shader.Find("VR/SpatialMapping/Occlusion")), + new Material(Shader.Find("VR/SpatialMapping/Occlusion")), + new Material(Shader.Find("VR/SpatialMapping/Occlusion")), + new Material(Shader.Find("VR/SpatialMapping/Occlusion")), + new Material(Shader.Find("VR/SpatialMapping/Occlusion")), + new Material(Shader.Find("VR/SpatialMapping/Occlusion")), + }, + new List[] // ports + { + null, + null, + null, + null, + null, + null, + null, + null, + } + )); + } +} \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/Models/ModelList.cs.meta b/vr-configurator/Assets/Scripts/Models/ModelList.cs.meta new file mode 100644 index 0000000..636cb43 --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/ModelList.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6c640286ce364177b45bc94e82049756 +timeCreated: 1745699997 \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/Models/ModelManager.cs b/vr-configurator/Assets/Scripts/Models/ModelManager.cs new file mode 100644 index 0000000..186e6b9 --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/ModelManager.cs @@ -0,0 +1,96 @@ +using UnityEngine; +using UnityEditor; +using System.Collections; +using System.Collections.Generic; +using Unity.VisualScripting; + +public class ModelManager : MonoBehaviour +{ + private Dictionary> portDict; //port mapped on + private Dictionary childModelDict; //childModels by their ID + + public List baseModelList; //available BaseModels + + public GameObject baseModel; //current baseModel + + HashSet.Enumerator enumerator; + + // Start is called once before the first execution of Update after the MonoBehaviour is created + void Start() + { + Debug.Log("ModelManager: " + this.gameObject.name); + portDict = new Dictionary>(); + childModelDict = new Dictionary(); + baseModelList = new List(); + foreach (var baseModel in ModelList.BaseModels) + { + registerBaseModel(baseModel); + } + foreach (var childModel in ModelList.ChildModels) + { + registerChildModel(childModel); + } + if (baseModel == null) //set in the editor + { + //TODO: send into model selection + Debug.LogError("baseModel is null, fix the configuration"); + } + baseModel.GetComponent().UpdateModel(baseModelList[0]); //TODO: change later when there is a model selection + + enumerator = getChildModelsForPort("bikeB").GetEnumerator(); //TODO: implement GUI later + } + + // Update is called once per frame + void Update() + { + if (Input.GetKeyDown(KeyCode.Space)) //TODO: remove after testing + { + Debug.Log($"Space key was pressed {enumerator.Current}"); + baseModel.GetComponent().setFirstWithPort("bikeB", enumerator.Current); + enumerator.MoveNext(); + } + } + + void registerChildModel(ChildModel model) + { + //childModelDict + if (childModelDict.ContainsKey(model.nameId)) + { + Debug.LogWarning("Model " + model.nameId + " already registered! [childModelDict] Skipping..."); + return; + } + childModelDict[model.nameId] = model; + + //portDict + if (!portDict.ContainsKey(model.port)) + { + portDict.Add(model.port, new HashSet()); + } + if (portDict[model.port].Contains(model)) + { + Debug.LogWarning("Model " + model.nameId + " already registered! [portDict] Skipping..."); + return; + } + portDict[model.port].Add(model); + } + + void registerBaseModel(BaseModel baseModel) + { + if (baseModel == null) + { + return; + } + baseModelList ??= new List(); + baseModelList.Add(baseModel); + } + + public HashSet getChildModelsForPort(string port) + { + return portDict[port]; + } + + public ChildModel getById(string id) + { + return childModelDict[id]; + } +} diff --git a/vr-configurator/Assets/Scripts/Models/ModelManager.cs.meta b/vr-configurator/Assets/Scripts/Models/ModelManager.cs.meta new file mode 100644 index 0000000..4f5a77d --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/ModelManager.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: d328782a7e1a9ff42a3c023ed7e0d15d \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/Models/Port.cs b/vr-configurator/Assets/Scripts/Models/Port.cs new file mode 100644 index 0000000..eb2132c --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/Port.cs @@ -0,0 +1,44 @@ +using UnityEngine; +public class Port +{ + Vector3 position; + Quaternion rotation; + Vector3 scale; + + public string port { private set; get; } // port name + public string defaultId { private set; get; } + + + public void apply(Transform target) + { + target.position = position; + target.rotation = rotation; + target.localScale = scale; + } + + public Port(string name, Vector3 position, string defaultId) + { + port = name; + this.position = position; + this.rotation = Quaternion.identity; + this.scale = new Vector3(1f,1f,1f); + this.defaultId = defaultId; + } + + public Port(string port, Vector3 position, Quaternion rotation, Vector3 scale, string defaultId) + { + this.port = port; + this.position = position; + this.rotation = rotation; + this.scale = scale; + this.defaultId = defaultId; + } + public Port(string port, Vector3 position, Quaternion rotation, string defaultId) + { + this.port = port; + this.position = position; + this.rotation = rotation; + this.scale = new Vector3(1f,1f,1f); + this.defaultId = defaultId; + } +} diff --git a/vr-configurator/Assets/Scripts/Models/Port.cs.meta b/vr-configurator/Assets/Scripts/Models/Port.cs.meta new file mode 100644 index 0000000..8787195 --- /dev/null +++ b/vr-configurator/Assets/Scripts/Models/Port.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a4361a8ac5cd5934fbb1b921f5a638f2 \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/UI.meta b/vr-configurator/Assets/Scripts/UI.meta new file mode 100644 index 0000000..7117c8a --- /dev/null +++ b/vr-configurator/Assets/Scripts/UI.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8ecb9c44392e3c84f8b31a712f42f911 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/vr-configurator/Assets/Scripts/Util.meta b/vr-configurator/Assets/Scripts/Util.meta new file mode 100644 index 0000000..75a7dc6 --- /dev/null +++ b/vr-configurator/Assets/Scripts/Util.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e9c3e587fb3e47969d0293aa9936c6a5 +timeCreated: 1745684855 \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/Util/MathUtil.cs b/vr-configurator/Assets/Scripts/Util/MathUtil.cs new file mode 100644 index 0000000..982df83 --- /dev/null +++ b/vr-configurator/Assets/Scripts/Util/MathUtil.cs @@ -0,0 +1,106 @@ +using System; +using UnityEngine; + +public static class MathUtil +{ + public static float EaseIn(float startNum, float endNum, float pct) + { + return startNum + (endNum - startNum) * (pct * pct); + } + + public static Vector3 EaseIn(Vector3 start, Vector3 end, float pct) + { + return start + (end - start) * (pct * pct); + } + + public static float EaseIn_Cube(float startNum, float endNum, float pct) + { + return startNum + (endNum - startNum) * (pct * pct * pct); + } + + public static float EaseIn_Pow(float startNum, float endNum, float pct, float pow) + { + return startNum + (endNum - startNum) * Mathf.Pow(pct, pow); + } + + public static float EaseOut(float startNum, float endNum, float pct) + { + return startNum + (endNum - startNum) * (1f - (1f - pct) * (1f - pct)); + } + + public static Vector3 EaseOut(Vector3 start, Vector3 end, float pct) + { + return start + (end - start) * (1f - (1f - pct) * (1f - pct)); + } + + public static float EaseOut_Cube(float startNum, float endNum, float pct) + { + return startNum + (endNum - startNum) * (1f - (1f - pct) * (1f - pct) * (1f - pct)); + } + + public static float EaseOut_Pow(float start, float end, float pct, float pow) + { + return start + (end - start) * (1f - Mathf.Pow(1f - pct, pow)); + } + + public static float EaseBoth(float startNum, float endNum, float pct) + { + if (pct < 0.5) + { + return MathUtil.EaseIn(startNum, (startNum + endNum) / 2f, pct * 2f); + } + return MathUtil.EaseOut((startNum + endNum) / 2f, endNum, (pct - 0.5f) * 2f); + } + + public static Vector3 EaseBoth(Vector3 start, Vector3 end, float pct) + { + if (pct < 0.5) + { + return MathUtil.EaseIn(start, (start + end) / 2f, pct * 2f); + } + return MathUtil.EaseOut((start + end) / 2f, end, (pct - 0.5f) * 2f); + } + + public static float EaseBoth_Cube(float startNum, float endNum, float pct) + { + if (pct < 0.5) + { + return MathUtil.EaseIn_Cube(startNum, (startNum + endNum) / 2f, pct * 2f); + } + return MathUtil.EaseOut_Cube((startNum + endNum) / 2f, endNum, (pct - 0.5f) * 2f); + } + + public static float Bump(float startNum, float bumpAmount, float pct) + { + if (pct < 0.5) + { + return MathUtil.EaseOut(startNum, startNum + bumpAmount, pct * 2f); + } + return MathUtil.EaseIn(startNum + bumpAmount, startNum, (pct - 0.5f) * 2f); + } + + public static float Linear(float startNum, float endNum, float pct) + { + return startNum + (endNum - startNum) * pct; + } + + public static Vector3 Linear(Vector3 start, Vector3 end, float pct) + { + return start + (end - start) * pct; + } + + public static float AvgAngle(float a, float b) + { + float num = Math.Abs(a - b); + float num2; + if (num < 180f) + { + num2 = (a + b) / 2f; + } + else + { + num2 = (a + b) / 2f + 180f; + } + return (num2 + 360f) % 360f; + } +} diff --git a/vr-configurator/Assets/Scripts/Util/MathUtil.cs.meta b/vr-configurator/Assets/Scripts/Util/MathUtil.cs.meta new file mode 100644 index 0000000..c2e492c --- /dev/null +++ b/vr-configurator/Assets/Scripts/Util/MathUtil.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 30833e992b1745fba88a04c077086e0d +timeCreated: 1745688502 \ No newline at end of file diff --git a/vr-configurator/Assets/Scripts/Util/ModelLoader.cs b/vr-configurator/Assets/Scripts/Util/ModelLoader.cs new file mode 100644 index 0000000..7130bf4 --- /dev/null +++ b/vr-configurator/Assets/Scripts/Util/ModelLoader.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using UnityEngine; + +/// +/// Util class for Loading Models +/// +public class ModelLoader +{ + public static List LoadChildModels(string[] port, string[] nameHuman, string[] nameId, Mesh[] meshes, Material[] mats, List[] ports, int fromMesh = 0, int toMesh = -1) + { + Debug.Log("LoadChildModels " + fromMesh + " to " + toMesh + " from " + mats.Length + " meshes"); + List models = new List(); + if (toMesh == -1) + { + toMesh = meshes.Length; + } + for (int i = 0; i < toMesh - fromMesh; i++) + { + Debug.Log($"{i}. {nameId[i]}:{nameHuman[i]} with {port.Length} ports"); + models.Add(new ChildModel(port[i], nameHuman[i], nameId[i], meshes[fromMesh + i], mats[i], ports[i])); + } + return models; + } +} diff --git a/vr-configurator/Assets/Scripts/Util/ModelLoader.cs.meta b/vr-configurator/Assets/Scripts/Util/ModelLoader.cs.meta new file mode 100644 index 0000000..5ace9cc --- /dev/null +++ b/vr-configurator/Assets/Scripts/Util/ModelLoader.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 34b438165d254e80a6c88a94ed7b0938 +timeCreated: 1745707627 \ No newline at end of file