diff --git a/Frontend/VIAProMa/Assets/Materials/DeleteCube.mat b/Frontend/VIAProMa/Assets/Materials/DeleteCube.mat
new file mode 100644
index 000000000..b15c0ae56
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Materials/DeleteCube.mat
@@ -0,0 +1,86 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+ serializedVersion: 6
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_Name: DeleteCube
+ m_Shader: {fileID: 4800000, guid: 65c40aa30dd2b704bac7512a200022e1, type: 3}
+ m_ShaderKeywords:
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _BumpMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailAlbedoMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailMask:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailNormalMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _EmissionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MainTex:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MetallicGlossMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _OcclusionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _ParallaxMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Floats:
+ - _BumpScale: 1
+ - _CellHeight: 0.5
+ - _CellWidth: 0.5
+ - _Cutoff: 0.5
+ - _DetailNormalMapScale: 1
+ - _DstBlend: 0
+ - _GlossMapScale: 1
+ - _Glossiness: 0.5
+ - _GlossyReflections: 1
+ - _Metallic: 0
+ - _Mode: 0
+ - _OcclusionStrength: 1
+ - _OffsetX: 0
+ - _OffsetY: 0
+ - _Parallax: 0.02
+ - _SmoothnessTextureChannel: 0
+ - _SpecularHighlights: 1
+ - _SrcBlend: 1
+ - _UVSec: 0
+ - _WireThickness: 0.01
+ - _WireThicknessX: 0.1
+ - _WireThicknessY: 0.1
+ - _ZWrite: 1
+ m_Colors:
+ - _BackgroundColor: {r: 0, g: 0, b: 0, a: 0}
+ - _Color: {r: 1, g: 1, b: 1, a: 1}
+ - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+ - _WireColor: {r: 1, g: 0.023584902, b: 0.023584902, a: 0.53333336}
diff --git a/Frontend/VIAProMa/Assets/Materials/DeleteCube.mat.meta b/Frontend/VIAProMa/Assets/Materials/DeleteCube.mat.meta
new file mode 100644
index 000000000..bd9558824
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Materials/DeleteCube.mat.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: c594ae7608980c2418edc75926ef0cc5
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/NuGet.config b/Frontend/VIAProMa/Assets/NuGet.config
new file mode 100644
index 000000000..8bc9cce12
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/NuGet.config
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Frontend/VIAProMa/Assets/NuGet.config.meta b/Frontend/VIAProMa/Assets/NuGet.config.meta
new file mode 100644
index 000000000..3bbe32b2b
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/NuGet.config.meta
@@ -0,0 +1,32 @@
+fileFormatVersion: 2
+guid: ec02f06961e372847b764cbf3e8de00e
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 0
+ isExplicitlyReferenced: 0
+ validateReferences: 1
+ platformData:
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ DefaultValueInitialized: true
+ - first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 1
+ settings: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/NuGet.meta b/Frontend/VIAProMa/Assets/NuGet.meta
new file mode 100644
index 000000000..260915e87
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/NuGet.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 217cb7caed5f7fb49b339428b1d80974
+folderAsset: yes
+timeCreated: 1510280316
+licenseType: Free
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/NuGet/Editor.meta b/Frontend/VIAProMa/Assets/NuGet/Editor.meta
new file mode 100644
index 000000000..3b6fd6bc4
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/NuGet/Editor.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: b3fad56c531ac5a4db190a745f589a8e
+folderAsset: yes
+timeCreated: 1510280304
+licenseType: Free
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/NuGet/Editor/DotNetZip.dll b/Frontend/VIAProMa/Assets/NuGet/Editor/DotNetZip.dll
new file mode 100644
index 000000000..f135bc049
Binary files /dev/null and b/Frontend/VIAProMa/Assets/NuGet/Editor/DotNetZip.dll differ
diff --git a/Frontend/VIAProMa/Assets/NuGet/Editor/DotNetZip.dll.meta b/Frontend/VIAProMa/Assets/NuGet/Editor/DotNetZip.dll.meta
new file mode 100644
index 000000000..b2576f0b8
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/NuGet/Editor/DotNetZip.dll.meta
@@ -0,0 +1,33 @@
+fileFormatVersion: 2
+guid: a8e8091a1f84e704a9f4d4abd2e15f8b
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 0
+ isExplicitlyReferenced: 0
+ validateReferences: 1
+ platformData:
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 1
+ settings:
+ DefaultValueInitialized: true
+ - first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/NuGet/Editor/NugetForUnity.dll b/Frontend/VIAProMa/Assets/NuGet/Editor/NugetForUnity.dll
new file mode 100644
index 000000000..4aa8e78a4
Binary files /dev/null and b/Frontend/VIAProMa/Assets/NuGet/Editor/NugetForUnity.dll differ
diff --git a/Frontend/VIAProMa/Assets/NuGet/Editor/NugetForUnity.dll.meta b/Frontend/VIAProMa/Assets/NuGet/Editor/NugetForUnity.dll.meta
new file mode 100644
index 000000000..833aac7d1
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/NuGet/Editor/NugetForUnity.dll.meta
@@ -0,0 +1,33 @@
+fileFormatVersion: 2
+guid: 8dc1be91775c4bb469f6b74cef450eaa
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 0
+ isExplicitlyReferenced: 0
+ validateReferences: 1
+ platformData:
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 1
+ settings:
+ DefaultValueInitialized: true
+ - first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/NuGet/LICENSE b/Frontend/VIAProMa/Assets/NuGet/LICENSE
new file mode 100644
index 000000000..e5e721045
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/NuGet/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 Patrick McCarthy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Frontend/VIAProMa/Assets/NuGet/LICENSE.meta b/Frontend/VIAProMa/Assets/NuGet/LICENSE.meta
new file mode 100644
index 000000000..9de0ac8de
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/NuGet/LICENSE.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 1d9014b99ad06af428514a5902d29ff3
+timeCreated: 1573248500
+licenseType: Pro
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/NuGet/README.pdf b/Frontend/VIAProMa/Assets/NuGet/README.pdf
new file mode 100644
index 000000000..e67f9fa59
Binary files /dev/null and b/Frontend/VIAProMa/Assets/NuGet/README.pdf differ
diff --git a/Frontend/VIAProMa/Assets/NuGet/README.pdf.meta b/Frontend/VIAProMa/Assets/NuGet/README.pdf.meta
new file mode 100644
index 000000000..e95001a02
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/NuGet/README.pdf.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 83c5d2001771f15429a88d67e81366d6
+timeCreated: 1517876157
+licenseType: Free
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/NuGet/Resources.meta b/Frontend/VIAProMa/Assets/NuGet/Resources.meta
new file mode 100644
index 000000000..49a5e3b4f
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/NuGet/Resources.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 1738075a39a390447b7a620ca6962142
+folderAsset: yes
+timeCreated: 1510280362
+licenseType: Free
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/NuGet/Resources/defaultIcon.png b/Frontend/VIAProMa/Assets/NuGet/Resources/defaultIcon.png
new file mode 100644
index 000000000..a16cc1989
Binary files /dev/null and b/Frontend/VIAProMa/Assets/NuGet/Resources/defaultIcon.png differ
diff --git a/Frontend/VIAProMa/Assets/NuGet/Resources/defaultIcon.png.meta b/Frontend/VIAProMa/Assets/NuGet/Resources/defaultIcon.png.meta
new file mode 100644
index 000000000..40842f8b3
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/NuGet/Resources/defaultIcon.png.meta
@@ -0,0 +1,88 @@
+fileFormatVersion: 2
+guid: eec19781926cd2248b7c9abfde8db555
+TextureImporter:
+ fileIDToRecycleName: {}
+ externalObjects: {}
+ serializedVersion: 9
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: -1
+ aniso: -1
+ mipBias: -100
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 1
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 1
+ spriteTessellationDetail: -1
+ textureType: 8
+ textureShape: 1
+ singleChannelComponent: 0
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ platformSettings:
+ - serializedVersion: 2
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ androidETC2FallbackOverride: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ physicsShape: []
+ bones: []
+ spriteID: 869a9d81f85fd30489f414b17b296d51
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ spritePackingTag:
+ pSDRemoveMatte: 0
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Packages.meta b/Frontend/VIAProMa/Assets/Packages.meta
new file mode 100644
index 000000000..913ce3b47
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Packages.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: d0884cd15b248df4eb91ccdcd62b853d
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0.meta b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0.meta
new file mode 100644
index 000000000..c2fb54b6c
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e941162b85e2b724a9826d19d4e61c3d
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/.signature.p7s b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/.signature.p7s
new file mode 100644
index 000000000..78569dac4
Binary files /dev/null and b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/.signature.p7s differ
diff --git a/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/OptimizedPriorityQueue.4.2.0.nupkg b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/OptimizedPriorityQueue.4.2.0.nupkg
new file mode 100644
index 000000000..32b34a59d
Binary files /dev/null and b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/OptimizedPriorityQueue.4.2.0.nupkg differ
diff --git a/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/OptimizedPriorityQueue.4.2.0.nupkg.meta b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/OptimizedPriorityQueue.4.2.0.nupkg.meta
new file mode 100644
index 000000000..54ba856ab
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/OptimizedPriorityQueue.4.2.0.nupkg.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 487d15f0e614e6b41ac427d03357c402
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib.meta b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib.meta
new file mode 100644
index 000000000..7e5bc03e8
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 24e9eff5c27a86e4abb836f8bf82c871
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib/net45.meta b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib/net45.meta
new file mode 100644
index 000000000..131814e18
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib/net45.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: eb1ce838d749e3f419294e9d974c23e1
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib/net45/Priority Queue.dll b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib/net45/Priority Queue.dll
new file mode 100644
index 000000000..3c28d3454
Binary files /dev/null and b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib/net45/Priority Queue.dll differ
diff --git a/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib/net45/Priority Queue.dll.meta b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib/net45/Priority Queue.dll.meta
new file mode 100644
index 000000000..7574e88fa
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib/net45/Priority Queue.dll.meta
@@ -0,0 +1,33 @@
+fileFormatVersion: 2
+guid: a296dc103fc62d943a7db8178d0a2d38
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 0
+ isExplicitlyReferenced: 0
+ validateReferences: 1
+ platformData:
+ - first:
+ Any:
+ second:
+ enabled: 1
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ DefaultValueInitialized: true
+ - first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib/net45/Priority Queue.xml b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib/net45/Priority Queue.xml
new file mode 100644
index 000000000..8e4ee37a8
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib/net45/Priority Queue.xml
@@ -0,0 +1,651 @@
+
+
+
+ Priority Queue
+
+
+
+
+ A copy of StablePriorityQueue which also has generic priority-type
+
+ The values in the queue. Must extend the GenericPriorityQueueNode class
+ The priority-type. Must extend IComparable<TPriority>
+
+
+
+ Instantiate a new Priority Queue
+
+ The max nodes ever allowed to be enqueued (going over this will cause undefined behavior)
+
+
+
+ Instantiate a new Priority Queue
+
+ The max nodes ever allowed to be enqueued (going over this will cause undefined behavior)
+ The comparer used to compare TPriority values.
+
+
+
+ Instantiate a new Priority Queue
+
+ The max nodes ever allowed to be enqueued (going over this will cause undefined behavior)
+ The comparison function to use to compare TPriority values
+
+
+
+ Returns the number of nodes in the queue.
+ O(1)
+
+
+
+
+ Returns the maximum number of items that can be enqueued at once in this queue. Once you hit this number (ie. once Count == MaxSize),
+ attempting to enqueue another item will cause undefined behavior. O(1)
+
+
+
+
+ Removes every node from the queue.
+ O(n) (So, don't do this often!)
+
+
+
+
+ Returns (in O(1)!) whether the given node is in the queue.
+ If node is or has been previously added to another queue, the result is undefined unless oldQueue.ResetNode(node) has been called
+ O(1)
+
+
+
+
+ Enqueue a node to the priority queue. Lower values are placed in front. Ties are broken by first-in-first-out.
+ If the queue is full, the result is undefined.
+ If the node is already enqueued, the result is undefined.
+ If node is or has been previously added to another queue, the result is undefined unless oldQueue.ResetNode(node) has been called
+ O(log n)
+
+
+
+
+ Returns true if 'higher' has higher priority than 'lower', false otherwise.
+ Note that calling HasHigherPriority(node, node) (ie. both arguments the same node) will return false
+
+
+
+
+ Removes the head of the queue (node with minimum priority; ties are broken by order of insertion), and returns it.
+ If queue is empty, result is undefined
+ O(log n)
+
+
+
+
+ Resize the queue so it can accept more nodes. All currently enqueued nodes are remain.
+ Attempting to decrease the queue size to a size too small to hold the existing nodes results in undefined behavior
+ O(n)
+
+
+
+
+ Returns the head of the queue, without removing it (use Dequeue() for that).
+ If the queue is empty, behavior is undefined.
+ O(1)
+
+
+
+
+ This method must be called on a node every time its priority changes while it is in the queue.
+ Forgetting to call this method will result in a corrupted queue!
+ Calling this method on a node not in the queue results in undefined behavior
+ O(log n)
+
+
+
+
+ Removes a node from the queue. The node does not need to be the head of the queue.
+ If the node is not in the queue, the result is undefined. If unsure, check Contains() first
+ O(log n)
+
+
+
+
+ By default, nodes that have been previously added to one queue cannot be added to another queue.
+ If you need to do this, please call originalQueue.ResetNode(node) before attempting to add it in the new queue
+
+
+
+
+ Should not be called in production code.
+ Checks to make sure the queue is still in a valid state. Used for testing/debugging the queue.
+
+
+
+
+ The Priority to insert this node at. Must be set BEFORE adding a node to the queue (ideally just once, in the node's constructor).
+ Should not be manually edited once the node has been enqueued - use queue.UpdatePriority() instead
+
+
+
+
+ Represents the current position in the queue
+
+
+
+
+ Represents the order the node was inserted in
+
+
+
+
+ A helper-interface only needed to make writing unit tests a bit easier (hence the 'internal' access modifier)
+
+
+
+
+ Resize the queue so it can accept more nodes. All currently enqueued nodes are remain.
+ Attempting to decrease the queue size to a size too small to hold the existing nodes results in undefined behavior
+
+
+
+
+ Returns the maximum number of items that can be enqueued at once in this queue. Once you hit this number (ie. once Count == MaxSize),
+ attempting to enqueue another item will cause undefined behavior.
+
+
+
+
+ By default, nodes that have been previously added to one queue cannot be added to another queue.
+ If you need to do this, please call originalQueue.ResetNode(node) before attempting to add it in the new queue
+
+
+
+
+ A copy of FastPriorityQueue which is also stable - that is, when two nodes are enqueued with the same priority, they
+ are always dequeued in the same order.
+ See https://github.com/BlueRaja/High-Speed-Priority-Queue-for-C-Sharp/wiki/Getting-Started for more information
+
+ The values in the queue. Must extend the StablePriorityQueueNode class
+
+
+
+ Instantiate a new Priority Queue
+
+ The max nodes ever allowed to be enqueued (going over this will cause undefined behavior)
+
+
+
+ Returns the number of nodes in the queue.
+ O(1)
+
+
+
+
+ Returns the maximum number of items that can be enqueued at once in this queue. Once you hit this number (ie. once Count == MaxSize),
+ attempting to enqueue another item will cause undefined behavior. O(1)
+
+
+
+
+ Removes every node from the queue.
+ O(n) (So, don't do this often!)
+
+
+
+
+ Returns (in O(1)!) whether the given node is in the queue.
+ If node is or has been previously added to another queue, the result is undefined unless oldQueue.ResetNode(node) has been called
+ O(1)
+
+
+
+
+ Enqueue a node to the priority queue. Lower values are placed in front. Ties are broken by first-in-first-out.
+ If the queue is full, the result is undefined.
+ If the node is already enqueued, the result is undefined.
+ If node is or has been previously added to another queue, the result is undefined unless oldQueue.ResetNode(node) has been called
+ O(log n)
+
+
+
+
+ Returns true if 'higher' has higher priority than 'lower', false otherwise.
+ Note that calling HasHigherPriority(node, node) (ie. both arguments the same node) will return false
+
+
+
+
+ Removes the head of the queue (node with minimum priority; ties are broken by order of insertion), and returns it.
+ If queue is empty, result is undefined
+ O(log n)
+
+
+
+
+ Resize the queue so it can accept more nodes. All currently enqueued nodes are remain.
+ Attempting to decrease the queue size to a size too small to hold the existing nodes results in undefined behavior
+ O(n)
+
+
+
+
+ Returns the head of the queue, without removing it (use Dequeue() for that).
+ If the queue is empty, behavior is undefined.
+ O(1)
+
+
+
+
+ This method must be called on a node every time its priority changes while it is in the queue.
+ Forgetting to call this method will result in a corrupted queue!
+ Calling this method on a node not in the queue results in undefined behavior
+ O(log n)
+
+
+
+
+ Removes a node from the queue. The node does not need to be the head of the queue.
+ If the node is not in the queue, the result is undefined. If unsure, check Contains() first
+ O(log n)
+
+
+
+
+ By default, nodes that have been previously added to one queue cannot be added to another queue.
+ If you need to do this, please call originalQueue.ResetNode(node) before attempting to add it in the new queue
+
+
+
+
+ Should not be called in production code.
+ Checks to make sure the queue is still in a valid state. Used for testing/debugging the queue.
+
+
+
+
+ An implementation of a min-Priority Queue using a heap. Has O(1) .Contains()!
+ See https://github.com/BlueRaja/High-Speed-Priority-Queue-for-C-Sharp/wiki/Getting-Started for more information
+
+ The values in the queue. Must extend the FastPriorityQueueNode class
+
+
+
+ Instantiate a new Priority Queue
+
+ The max nodes ever allowed to be enqueued (going over this will cause undefined behavior)
+
+
+
+ Returns the number of nodes in the queue.
+ O(1)
+
+
+
+
+ Returns the maximum number of items that can be enqueued at once in this queue. Once you hit this number (ie. once Count == MaxSize),
+ attempting to enqueue another item will cause undefined behavior. O(1)
+
+
+
+
+ Removes every node from the queue.
+ O(n) (So, don't do this often!)
+
+
+
+
+ Returns (in O(1)!) whether the given node is in the queue.
+ If node is or has been previously added to another queue, the result is undefined unless oldQueue.ResetNode(node) has been called
+ O(1)
+
+
+
+
+ Enqueue a node to the priority queue. Lower values are placed in front. Ties are broken arbitrarily.
+ If the queue is full, the result is undefined.
+ If the node is already enqueued, the result is undefined.
+ If node is or has been previously added to another queue, the result is undefined unless oldQueue.ResetNode(node) has been called
+ O(log n)
+
+
+
+
+ Returns true if 'higher' has higher priority than 'lower', false otherwise.
+ Note that calling HasHigherPriority(node, node) (ie. both arguments the same node) will return false
+
+
+
+
+ Returns true if 'higher' has higher priority than 'lower', false otherwise.
+ Note that calling HasHigherOrEqualPriority(node, node) (ie. both arguments the same node) will return true
+
+
+
+
+ Removes the head of the queue and returns it.
+ If queue is empty, result is undefined
+ O(log n)
+
+
+
+
+ Resize the queue so it can accept more nodes. All currently enqueued nodes are remain.
+ Attempting to decrease the queue size to a size too small to hold the existing nodes results in undefined behavior
+ O(n)
+
+
+
+
+ Returns the head of the queue, without removing it (use Dequeue() for that).
+ If the queue is empty, behavior is undefined.
+ O(1)
+
+
+
+
+ This method must be called on a node every time its priority changes while it is in the queue.
+ Forgetting to call this method will result in a corrupted queue!
+ Calling this method on a node not in the queue results in undefined behavior
+ O(log n)
+
+
+
+
+ Removes a node from the queue. The node does not need to be the head of the queue.
+ If the node is not in the queue, the result is undefined. If unsure, check Contains() first
+ O(log n)
+
+
+
+
+ By default, nodes that have been previously added to one queue cannot be added to another queue.
+ If you need to do this, please call originalQueue.ResetNode(node) before attempting to add it in the new queue
+ If the node is currently in the queue or belongs to another queue, the result is undefined
+
+
+
+
+ Should not be called in production code.
+ Checks to make sure the queue is still in a valid state. Used for testing/debugging the queue.
+
+
+
+
+ Represents the order the node was inserted in
+
+
+
+
+ The IPriorityQueue interface. This is mainly here for purists, and in case I decide to add more implementations later.
+ For speed purposes, it is actually recommended that you *don't* access the priority queue through this interface, since the JIT can
+ (theoretically?) optimize method calls from concrete-types slightly better.
+
+
+
+
+ Enqueue a node to the priority queue. Lower values are placed in front. Ties are broken by first-in-first-out.
+ See implementation for how duplicates are handled.
+
+
+
+
+ Removes the head of the queue (node with minimum priority; ties are broken by order of insertion), and returns it.
+
+
+
+
+ Removes every node from the queue.
+
+
+
+
+ Returns whether the given node is in the queue.
+
+
+
+
+ Removes a node from the queue. The node does not need to be the head of the queue.
+
+
+
+
+ Call this method to change the priority of a node.
+
+
+
+
+ Returns the head of the queue, without removing it (use Dequeue() for that).
+
+
+
+
+ Returns the number of nodes in the queue.
+
+
+
+
+ The Priority to insert this node at. Must be set BEFORE adding a node to the queue (ideally just once, in the node's constructor).
+ Should not be manually edited once the node has been enqueued - use queue.UpdatePriority() instead
+
+
+
+
+ Represents the current position in the queue
+
+
+
+
+ A simplified priority queue implementation. Is stable, auto-resizes, and thread-safe, at the cost of being slightly slower than
+ FastPriorityQueue
+ Methods tagged as O(1) or O(log n) are assuming there are no duplicates. Duplicates may increase the algorithmic complexity.
+
+ The type to enqueue
+ The priority-type to use for nodes. Must extend IComparable<TPriority>
+
+
+
+ Instantiate a new Priority Queue
+
+
+
+
+ Instantiate a new Priority Queue
+
+ The comparer used to compare TPriority values. Defaults to Comparer<TPriority>.default
+
+
+
+ Instantiate a new Priority Queue
+
+ The comparison function to use to compare TPriority values
+
+
+
+ Instantiate a new Priority Queue
+
+ The equality comparison function to use to compare TItem values
+
+
+
+ Instantiate a new Priority Queue
+
+ The comparer used to compare TPriority values. Defaults to Comparer<TPriority>.default
+ The equality comparison function to use to compare TItem values
+
+
+
+ Instantiate a new Priority Queue
+
+ The comparison function to use to compare TPriority values
+ The equality comparison function to use to compare TItem values
+
+
+
+ Given an item of type T, returns the existing SimpleNode in the queue
+
+
+
+
+ Adds an item to the Node-cache to allow for many methods to be O(1) or O(log n)
+
+
+
+
+ Removes an item to the Node-cache to allow for many methods to be O(1) or O(log n) (assuming no duplicates)
+
+
+
+
+ Returns the number of nodes in the queue.
+ O(1)
+
+
+
+
+ Returns the head of the queue, without removing it (use Dequeue() for that).
+ Throws an exception when the queue is empty.
+ O(1)
+
+
+
+
+ Removes every node from the queue.
+ O(n)
+
+
+
+
+ Returns whether the given item is in the queue.
+ O(1)
+
+
+
+
+ Removes the head of the queue (node with minimum priority; ties are broken by order of insertion), and returns it.
+ If queue is empty, throws an exception
+ O(log n)
+
+
+
+
+ Enqueue the item with the given priority, without calling lock(_queue) or AddToNodeCache(node)
+
+
+
+
+
+
+
+ Enqueue a node to the priority queue. Lower values are placed in front. Ties are broken by first-in-first-out.
+ This queue automatically resizes itself, so there's no concern of the queue becoming 'full'.
+ Duplicates and null-values are allowed.
+ O(log n)
+
+
+
+
+ Enqueue a node to the priority queue if it doesn't already exist. Lower values are placed in front. Ties are broken by first-in-first-out.
+ This queue automatically resizes itself, so there's no concern of the queue becoming 'full'. Null values are allowed.
+ Returns true if the node was successfully enqueued; false if it already exists.
+ O(log n)
+
+
+
+
+ Removes an item from the queue. The item does not need to be the head of the queue.
+ If the item is not in the queue, an exception is thrown. If unsure, check Contains() first.
+ If multiple copies of the item are enqueued, only the first one is removed.
+ O(log n)
+
+
+
+
+ Call this method to change the priority of an item.
+ Calling this method on a item not in the queue will throw an exception.
+ If the item is enqueued multiple times, only the first one will be updated.
+ (If your requirements are complex enough that you need to enqueue the same item multiple times and be able
+ to update all of them, please wrap your items in a wrapper class so they can be distinguished).
+ O(log n)
+
+
+
+
+ Returns the priority of the given item.
+ Calling this method on a item not in the queue will throw an exception.
+ If the item is enqueued multiple times, only the priority of the first will be returned.
+ (If your requirements are complex enough that you need to enqueue the same item multiple times and be able
+ to query all their priorities, please wrap your items in a wrapper class so they can be distinguished).
+ O(1)
+
+
+
+ Get the head of the queue, without removing it (use TryDequeue() for that).
+ Useful for multi-threading, where the queue may become empty between calls to Contains() and First
+ Returns true if successful, false otherwise
+ O(1)
+
+
+
+ Removes the head of the queue (node with minimum priority; ties are broken by order of insertion), and sets it to first.
+ Useful for multi-threading, where the queue may become empty between calls to Contains() and Dequeue()
+ Returns true if successful; false if queue was empty
+ O(log n)
+
+
+
+
+ Attempts to remove an item from the queue. The item does not need to be the head of the queue.
+ Useful for multi-threading, where the queue may become empty between calls to Contains() and Remove()
+ Returns true if the item was successfully removed, false if it wasn't in the queue.
+ If multiple copies of the item are enqueued, only the first one is removed.
+ O(log n)
+
+
+
+
+ Call this method to change the priority of an item.
+ Useful for multi-threading, where the queue may become empty between calls to Contains() and UpdatePriority()
+ If the item is enqueued multiple times, only the first one will be updated.
+ (If your requirements are complex enough that you need to enqueue the same item multiple times and be able
+ to update all of them, please wrap your items in a wrapper class so they can be distinguished).
+ Returns true if the item priority was updated, false otherwise.
+ O(log n)
+
+
+
+
+ Attempt to get the priority of the given item.
+ Useful for multi-threading, where the queue may become empty between calls to Contains() and GetPriority()
+ If the item is enqueued multiple times, only the priority of the first will be returned.
+ (If your requirements are complex enough that you need to enqueue the same item multiple times and be able
+ to query all their priorities, please wrap your items in a wrapper class so they can be distinguished).
+ Returns true if the item was found in the queue, false otherwise
+ O(1)
+
+
+
+
+ A simplified priority queue implementation. Is stable, auto-resizes, and thread-safe, at the cost of being slightly slower than
+ FastPriorityQueue
+ This class is kept here for backwards compatibility. It's recommended you use SimplePriorityQueue<TItem, TPriority>
+
+ The type to enqueue
+
+
+
+ Instantiate a new Priority Queue
+
+
+
+
+ Instantiate a new Priority Queue
+
+ The comparer used to compare priority values. Defaults to Comparer<float>.default
+
+
+
+ Instantiate a new Priority Queue
+
+ The comparison function to use to compare priority values
+
+
+
diff --git a/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib/net45/Priority Queue.xml.meta b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib/net45/Priority Queue.xml.meta
new file mode 100644
index 000000000..381202c26
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Packages/OptimizedPriorityQueue.4.2.0/lib/net45/Priority Queue.xml.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 54f591086fcd1f0479f214770ae1b9f8
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Prefabs/Curve Connect.meta b/Frontend/VIAProMa/Assets/Prefabs/Curve Connect.meta
new file mode 100644
index 000000000..7f57350d3
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Prefabs/Curve Connect.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: db53d517e0c21ed4a8c9cec7f66016c3
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/DeleteCube.prefab b/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/DeleteCube.prefab
new file mode 100644
index 000000000..21cdd0f7d
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/DeleteCube.prefab
@@ -0,0 +1,93 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &2220996382331764046
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2220996382331764050}
+ - component: {fileID: 2220996382331764049}
+ - component: {fileID: 2220996382331764048}
+ - component: {fileID: 2220996382331764047}
+ m_Layer: 8
+ m_Name: DeleteCube
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &2220996382331764050
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2220996382331764046}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 0.1, y: 0.1, z: 0.4}
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!33 &2220996382331764049
+MeshFilter:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2220996382331764046}
+ m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!23 &2220996382331764048
+MeshRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2220996382331764046}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RenderingLayerMask: 1
+ m_RendererPriority: 0
+ m_Materials:
+ - {fileID: 2100000, guid: c594ae7608980c2418edc75926ef0cc5, type: 2}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ m_StaticBatchRoot: {fileID: 0}
+ m_ProbeAnchor: {fileID: 0}
+ m_LightProbeVolumeOverride: {fileID: 0}
+ m_ScaleInLightmap: 1
+ m_PreserveUVs: 0
+ m_IgnoreNormalsForChartDetection: 0
+ m_ImportantGI: 0
+ m_StitchLightmapSeams: 0
+ 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
+--- !u!65 &2220996382331764047
+BoxCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2220996382331764046}
+ m_Material: {fileID: 0}
+ m_IsTrigger: 0
+ m_Enabled: 1
+ serializedVersion: 2
+ m_Size: {x: 1, y: 1, z: 1}
+ m_Center: {x: 0, y: 0, z: 0}
diff --git a/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/DeleteCube.prefab.meta b/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/DeleteCube.prefab.meta
new file mode 100644
index 000000000..fd0d5c75c
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/DeleteCube.prefab.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: f83c378f309a12d468b5b52eb52f9002
+PrefabImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/GridShaderDeleteCube.shader b/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/GridShaderDeleteCube.shader
new file mode 100644
index 000000000..d9041138b
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/GridShaderDeleteCube.shader
@@ -0,0 +1,77 @@
+Shader "Custom/Grid Shader"
+{
+ Properties
+ {
+ _WireThicknessX("Wire Thickness X", Float) = 0.01
+ _WireThicknessY("Wire Thickness Y", Float) = 0.01
+ _CellWidth("Cell Width", Float) = 1
+ _CellHeight("Cell Height", Float) = 1
+ _OffsetX("Offset X", Float) = 0
+ _OffsetY("Offset Y", Float) = 0
+ _BackgroundColor("Background Color", Color) = (0, 0, 0, 0)
+ _WireColor("Wire Color", Color) = (1, 1, 1, 1)
+ }
+
+ SubShader
+ {
+ Tags {"Queue" = "Transparent"}
+
+ Pass
+ {
+ ZWrite Off
+ Blend SrcAlpha OneMinusSrcAlpha
+
+ CGPROGRAM
+
+ #pragma vertex vert
+ #pragma fragment frag
+
+ #include "UnityCG.cginc"
+
+ uniform float _WireThicknessX;
+ uniform float _WireThicknessY;
+ uniform float _CellWidth;
+ uniform float _CellHeight;
+ uniform float _OffsetX;
+ uniform float _OffsetY;
+ uniform float4 _BackgroundColor;
+ uniform float4 _WireColor;
+
+ struct vertexData
+ {
+ float4 position : POSITION;
+ float2 uv : TEXCOORD0;
+ };
+
+ struct v2f
+ {
+ float4 position : SV_POSITION;
+ float2 uv : TEXCOORD0;
+ };
+
+
+ v2f vert(vertexData input)
+ {
+ v2f o;
+ o.position = UnityObjectToClipPos(input.position);
+ o.uv = input.uv;
+ return o;
+ }
+
+ float4 frag(v2f input) : SV_TARGET
+ {
+ if (frac((input.uv.x + _OffsetX + _WireThicknessX / 2.0) / _CellWidth) < (_WireThicknessX / _CellWidth)
+ || frac((input.uv.y + _OffsetY + _WireThicknessY / 2.0) / _CellHeight) < (_WireThicknessY / _CellHeight))
+ {
+ return _WireColor;
+ }
+ else
+ {
+ return _BackgroundColor;
+ }
+ }
+
+ ENDCG
+ }
+ }
+}
\ No newline at end of file
diff --git a/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/GridShaderDeleteCube.shader.meta b/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/GridShaderDeleteCube.shader.meta
new file mode 100644
index 000000000..272d68a44
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/GridShaderDeleteCube.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: ea2a8cea0d3907c4881bf63215e9e52d
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/LineController.prefab b/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/LineController.prefab
new file mode 100644
index 000000000..2be0295a0
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/LineController.prefab
@@ -0,0 +1,187 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &8246175140109700422
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 8246175140109700420}
+ - component: {fileID: 8246175140109700421}
+ - component: {fileID: 8963296643016330286}
+ - component: {fileID: 3233973695741448572}
+ m_Layer: 0
+ m_Name: LineController
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &8246175140109700420
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8246175140109700422}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: -22.796469, y: -52.452057, z: 128.06271}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &8246175140109700421
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8246175140109700422}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d723b4c0c823c864fafaa520a546fb4d, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ Sequence: 0
+ SpawnPoints:
+ - {fileID: 0}
+ UseRandomOffset: 1
+ RandomOffset: 2
+ ClampY: 1
+ PrefabsToInstantiate:
+ - {fileID: 0}
+ AutoSpawnObjects: 1
+ DeleteCube: {fileID: 2220996382331764046, guid: f83c378f309a12d468b5b52eb52f9002,
+ type: 3}
+ currState: 0
+ curveConnectPrefab: {fileID: 7853647021840196732, guid: e948fd42ac79ada4e89e5e4087102753,
+ type: 3}
+ tempGoalPrefab: {fileID: 174366279205162471, guid: 2b63e6948ce245a40b1aa66eedd57c81,
+ type: 3}
+ defaultColour:
+ serializedVersion: 2
+ key0: {r: 1, g: 1, b: 1, a: 1}
+ key1: {r: 1, g: 1, b: 1, a: 1}
+ key2: {r: 0, g: 0, b: 0, a: 0}
+ key3: {r: 0, g: 0, b: 0, a: 0}
+ key4: {r: 0, g: 0, b: 0, a: 0}
+ key5: {r: 0, g: 0, b: 0, a: 0}
+ key6: {r: 0, g: 0, b: 0, a: 0}
+ key7: {r: 0, g: 0, b: 0, a: 0}
+ ctime0: 0
+ ctime1: 65535
+ ctime2: 0
+ ctime3: 0
+ ctime4: 0
+ ctime5: 0
+ ctime6: 0
+ ctime7: 0
+ atime0: 0
+ atime1: 65535
+ atime2: 0
+ atime3: 0
+ atime4: 0
+ atime5: 0
+ atime6: 0
+ atime7: 0
+ m_Mode: 0
+ m_NumColorKeys: 2
+ m_NumAlphaKeys: 2
+ deletColour:
+ serializedVersion: 2
+ key0: {r: 1, g: 1, b: 1, a: 1}
+ key1: {r: 1, g: 1, b: 1, a: 1}
+ key2: {r: 0, g: 0, b: 0, a: 0}
+ key3: {r: 0, g: 0, b: 0, a: 0}
+ key4: {r: 0, g: 0, b: 0, a: 0}
+ key5: {r: 0, g: 0, b: 0, a: 0}
+ key6: {r: 0, g: 0, b: 0, a: 0}
+ key7: {r: 0, g: 0, b: 0, a: 0}
+ ctime0: 0
+ ctime1: 65535
+ ctime2: 0
+ ctime3: 0
+ ctime4: 0
+ ctime5: 0
+ ctime6: 0
+ ctime7: 0
+ atime0: 0
+ atime1: 65535
+ atime2: 0
+ atime3: 0
+ atime4: 0
+ atime5: 0
+ atime6: 0
+ atime7: 0
+ m_Mode: 0
+ m_NumColorKeys: 2
+ m_NumAlphaKeys: 2
+ connectColour:
+ serializedVersion: 2
+ key0: {r: 1, g: 1, b: 1, a: 1}
+ key1: {r: 1, g: 1, b: 1, a: 1}
+ key2: {r: 0, g: 0, b: 0, a: 0}
+ key3: {r: 0, g: 0, b: 0, a: 0}
+ key4: {r: 0, g: 0, b: 0, a: 0}
+ key5: {r: 0, g: 0, b: 0, a: 0}
+ key6: {r: 0, g: 0, b: 0, a: 0}
+ key7: {r: 0, g: 0, b: 0, a: 0}
+ ctime0: 0
+ ctime1: 65535
+ ctime2: 0
+ ctime3: 0
+ ctime4: 0
+ ctime5: 0
+ ctime6: 0
+ ctime7: 0
+ atime0: 0
+ atime1: 65535
+ atime2: 0
+ atime3: 0
+ atime4: 0
+ atime5: 0
+ atime6: 0
+ atime7: 0
+ m_Mode: 0
+ m_NumColorKeys: 2
+ m_NumAlphaKeys: 2
+ startTest: {fileID: 0}
+ goalTest: {fileID: 0}
+--- !u!114 &8963296643016330286
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8246175140109700422}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 37e76559dd3d342489e206e4eee342ad, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ standartHeight: 0.2
+--- !u!114 &3233973695741448572
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8246175140109700422}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: aa584fbee541324448dd18d8409c7a41, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ ObservedComponentsFoldoutOpen: 1
+ Group: 0
+ prefixField: -1
+ observableSearch: 2
+ Synchronization: 0
+ OwnershipTransfer: 0
+ ObservedComponents: []
+ viewIdField: 0
+ InstantiationId: 0
+ isRuntimeInstantiated: 0
diff --git a/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/LineController.prefab.meta b/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/LineController.prefab.meta
new file mode 100644
index 000000000..88e813a0b
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Prefabs/Curve Connect/LineController.prefab.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 8231cf347b64d3e4499b64b783604e88
+PrefabImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Prefabs/Managers.prefab b/Frontend/VIAProMa/Assets/Prefabs/Managers.prefab
index 0b5c85047..eb33be79c 100644
--- a/Frontend/VIAProMa/Assets/Prefabs/Managers.prefab
+++ b/Frontend/VIAProMa/Assets/Prefabs/Managers.prefab
@@ -104,6 +104,7 @@ MonoBehaviour:
ObservedComponentsFoldoutOpen: 1
Group: 0
prefixField: -1
+ observableSearch: 0
Synchronization: 0
OwnershipTransfer: 0
ObservedComponents:
@@ -143,6 +144,10 @@ MonoBehaviour:
runInBackground: 1
statsResetInterval: 1000
speakerPrefab: {fileID: 0}
+ primaryRecorder: {fileID: 4191421764473793288}
+ globalRecordersLogLevel: 3
+ globalSpeakersLogLevel: 3
+ globalPlaybackDelay: 200
Settings:
AppIdRealtime:
AppIdChat:
@@ -152,14 +157,18 @@ MonoBehaviour:
FixedRegion:
Server:
Port: 0
+ ProxyServer:
Protocol: 0
+ EnableProtocolFallback: 1
+ AuthMode: 0
EnableLobbyStatistics: 0
NetworkLogging: 1
ShowSettings: 0
- PrimaryRecorder: {fileID: 4191421764473793288}
+ MinimalTimeScaleToDispatchInFixedUpdate: -1
+ AutoCreateSpeakerIfNotFound: 1
AutoConnectAndJoin: 1
AutoLeaveAndDisconnect: 1
- AutoCreateSpeakerIfNotFound: 1
+ WorkInOfflineMode: 1
usePunAppSettings: 1
--- !u!114 &4191421764473793288
MonoBehaviour:
@@ -174,6 +183,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
logLevel: 1
+ ignoreGlobalLogLevel: 0
voiceDetection: 1
voiceDetectionThreshold: 0.01
voiceDetectionDelayMs: 500
@@ -193,6 +203,11 @@ MonoBehaviour:
loopAudioClip: 1
reactOnSystemChanges: 0
autoStart: 1
+ recordOnlyWhenEnabled: 0
+ skipDeviceChangeChecks: 0
+ stopRecordingWhenPaused: 0
+ useOnAudioFilterRead: 0
+ trySamplingRateMatch: 0
--- !u!114 &4885869589891658483
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -411,8 +426,6 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
- m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
- Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_text: Sample text
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: afc8299d5d5bbd440a0616c8ecbc7217, type: 2}
@@ -450,7 +463,6 @@ MonoBehaviour:
m_fontSizeMax: 72
m_fontStyle: 0
m_textAlignment: 257
- m_isAlignmentEnumConverted: 1
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
@@ -477,6 +489,7 @@ MonoBehaviour:
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
+ m_VertexBufferAutoSizeReduction: 1
m_firstVisibleCharacter: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
@@ -491,12 +504,9 @@ MonoBehaviour:
lineCount: 1
pageCount: 1
materialCount: 1
- m_havePropertiesChanged: 0
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_spriteAnimator: {fileID: 0}
- m_isInputParsingRequired: 0
- m_inputSource: 0
m_hasFontAssetChanged: 0
m_renderer: {fileID: 5305607723554815313}
m_subTextObjects:
@@ -590,6 +600,7 @@ Transform:
- {fileID: 6150657374833339444}
- {fileID: 7550514611414572532}
- {fileID: 8835965036498097119}
+ - {fileID: 3821765825008361390}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@@ -811,6 +822,7 @@ MonoBehaviour:
ObservedComponentsFoldoutOpen: 1
Group: 0
prefixField: -1
+ observableSearch: 0
Synchronization: 0
OwnershipTransfer: 0
ObservedComponents:
@@ -818,3 +830,92 @@ MonoBehaviour:
viewIdField: 0
InstantiationId: 2
isRuntimeInstantiated: 0
+--- !u!1 &7218249420463830240
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 3821765825008361390}
+ - component: {fileID: 7870068159882936511}
+ - component: {fileID: 5650007671030586223}
+ - component: {fileID: 5548909068171291084}
+ m_Layer: 0
+ m_Name: ConnectionCurve Manager
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &3821765825008361390
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7218249420463830240}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: -0.012125015, y: -0.009320948, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children: []
+ m_Father: {fileID: 3215894185288659648}
+ m_RootOrder: 7
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &7870068159882936511
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7218249420463830240}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d723b4c0c823c864fafaa520a546fb4d, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ onlineTestMode: 0
+ DeleteCube: {fileID: 2220996382331764046, guid: f83c378f309a12d468b5b52eb52f9002,
+ type: 3}
+ curves: []
+ currState: 0
+ curveConnectPrefab: {fileID: 7853647021840196732, guid: e948fd42ac79ada4e89e5e4087102753,
+ type: 3}
+ tempGoalPrefab: {fileID: 174366279205162471, guid: 2b63e6948ce245a40b1aa66eedd57c81,
+ type: 3}
+--- !u!114 &5650007671030586223
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7218249420463830240}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: aa584fbee541324448dd18d8409c7a41, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ ObservedComponentsFoldoutOpen: 1
+ Group: 0
+ prefixField: -1
+ observableSearch: 2
+ Synchronization: 0
+ OwnershipTransfer: 0
+ ObservedComponents: []
+ viewIdField: 0
+ InstantiationId: 0
+ isRuntimeInstantiated: 0
+--- !u!114 &5548909068171291084
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7218249420463830240}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 37e76559dd3d342489e206e4eee342ad, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ standartHeight: 0.2
diff --git a/Frontend/VIAProMa/Assets/Prefabs/Shelves/Resources/IssueShelf.prefab b/Frontend/VIAProMa/Assets/Prefabs/Shelves/Resources/IssueShelf.prefab
index cc543d961..8d8634f1f 100644
--- a/Frontend/VIAProMa/Assets/Prefabs/Shelves/Resources/IssueShelf.prefab
+++ b/Frontend/VIAProMa/Assets/Prefabs/Shelves/Resources/IssueShelf.prefab
@@ -548,7 +548,7 @@ MonoBehaviour:
m_Calls: []
m_text: Category
m_isRightToLeft: 0
- m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
+ m_fontAsset: {fileID: 0}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
diff --git a/Frontend/VIAProMa/Assets/Prefabs/UI/App Bar/App Bar Configurable.prefab b/Frontend/VIAProMa/Assets/Prefabs/UI/App Bar/App Bar Configurable.prefab
index 1ec8b3bbb..0c95e33ce 100644
--- a/Frontend/VIAProMa/Assets/Prefabs/UI/App Bar/App Bar Configurable.prefab
+++ b/Frontend/VIAProMa/Assets/Prefabs/UI/App Bar/App Bar Configurable.prefab
@@ -79,25 +79,60 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- - target: {fileID: 2854956418753788980, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ - target: {fileID: 5073087414149207293, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
type: 3}
- propertyPath: m_Mesh
- value:
+ propertyPath: m_IsActive
+ value: 1
objectReference: {fileID: 0}
- - target: {fileID: 4596712779539249596, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ - target: {fileID: 7958515997744685342, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
type: 3}
- propertyPath: m_Mesh
- value:
+ propertyPath: m_IsActive
+ value: 0
objectReference: {fileID: 0}
- target: {fileID: 117210883681737375, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
type: 3}
propertyPath: m_LocalScale.x
- value: 0.208
+ value: 0.30804
objectReference: {fileID: 0}
- target: {fileID: 3361800236042063618, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
type: 3}
propertyPath: m_LocalPosition.x
- value: -0.07903
+ value: -0.12902
+ objectReference: {fileID: 0}
+ - target: {fileID: 5790070783517185443, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ type: 3}
+ propertyPath: m_LocalPosition.x
+ value: -0.07902
+ objectReference: {fileID: 0}
+ - target: {fileID: 5524453724328992038, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ type: 3}
+ propertyPath: m_LocalPosition.x
+ value: 0.12902
+ objectReference: {fileID: 0}
+ - target: {fileID: 3515993982177029129, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ type: 3}
+ propertyPath: m_RootOrder
+ value: 5
+ objectReference: {fileID: 0}
+ - target: {fileID: 3515993982177029129, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ type: 3}
+ propertyPath: m_LocalPosition.x
+ value: 0.02098
+ objectReference: {fileID: 0}
+ - target: {fileID: 2964961762303939846, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ type: 3}
+ propertyPath: m_LocalPosition.x
+ value: 0.07098
+ objectReference: {fileID: 0}
+ - target: {fileID: 4596712779539249596, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ type: 3}
+ propertyPath: m_Mesh
+ value:
+ objectReference: {fileID: 0}
+ - target: {fileID: 8022226399187307763, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ type: 3}
+ propertyPath: m_Mesh
+ value:
objectReference: {fileID: 0}
- target: {fileID: 5058010974960551313, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
type: 3}
@@ -109,32 +144,47 @@ PrefabInstance:
propertyPath: m_isInputParsingRequired
value: 1
objectReference: {fileID: 0}
- - target: {fileID: 5790070783517185443, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ - target: {fileID: 7554373769959085815, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
type: 3}
- propertyPath: m_LocalPosition.x
- value: -0.02903
+ propertyPath: m_Mesh
+ value:
objectReference: {fileID: 0}
- - target: {fileID: 4092750741418630960, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ - target: {fileID: 8158409320092676088, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ type: 3}
+ propertyPath: m_Mesh
+ value:
+ objectReference: {fileID: 0}
+ - target: {fileID: 2854956418753788980, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ type: 3}
+ propertyPath: m_Mesh
+ value:
+ objectReference: {fileID: 0}
+ - target: {fileID: 962049089513987799, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ type: 3}
+ propertyPath: m_Mesh
+ value:
+ objectReference: {fileID: 0}
+ - target: {fileID: 2611213441731860405, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
type: 3}
propertyPath: m_havePropertiesChanged
value: 1
objectReference: {fileID: 0}
- - target: {fileID: 4092750741418630960, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ - target: {fileID: 2611213441731860405, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
type: 3}
propertyPath: m_isInputParsingRequired
value: 1
objectReference: {fileID: 0}
- - target: {fileID: 5524453724328992038, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ - target: {fileID: 1272646619630032466, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
type: 3}
- propertyPath: m_LocalPosition.x
- value: 0.07897
+ propertyPath: m_Mesh
+ value:
objectReference: {fileID: 0}
- - target: {fileID: 2611213441731860405, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ - target: {fileID: 4092750741418630960, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
type: 3}
propertyPath: m_havePropertiesChanged
value: 1
objectReference: {fileID: 0}
- - target: {fileID: 2611213441731860405, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ - target: {fileID: 4092750741418630960, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
type: 3}
propertyPath: m_isInputParsingRequired
value: 1
@@ -180,7 +230,7 @@ PrefabInstance:
- target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
type: 3}
propertyPath: m_LocalPosition.x
- value: 0.02093
+ value: -0.02902
objectReference: {fileID: 0}
- target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
type: 3}
@@ -318,5 +368,10 @@ PrefabInstance:
propertyPath: m_isInputParsingRequired
value: 1
objectReference: {fileID: 0}
+ - target: {fileID: 2083865205732806215, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_Mesh
+ value:
+ objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: c4e709f8a15434946bb54263fe6e9bf1, type: 3}
diff --git a/Frontend/VIAProMa/Assets/Prefabs/UI/App Bar/App Bar No Delete.prefab b/Frontend/VIAProMa/Assets/Prefabs/UI/App Bar/App Bar No Delete.prefab
index 4f18a320a..e36fd8168 100644
--- a/Frontend/VIAProMa/Assets/Prefabs/UI/App Bar/App Bar No Delete.prefab
+++ b/Frontend/VIAProMa/Assets/Prefabs/UI/App Bar/App Bar No Delete.prefab
@@ -87,6 +87,16 @@ PrefabInstance:
propertyPath: m_LocalPosition.x
value: 0.025
objectReference: {fileID: 0}
+ - target: {fileID: 2770254726373678493, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ type: 3}
+ propertyPath: m_IsActive
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 4584403945735398546, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ type: 3}
+ propertyPath: m_IsActive
+ value: 0
+ objectReference: {fileID: 0}
- target: {fileID: 4899511331797931453, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
type: 3}
propertyPath: m_IsActive
@@ -162,10 +172,20 @@ PrefabInstance:
propertyPath: m_isInputParsingRequired
value: 0
objectReference: {fileID: 0}
+ - target: {fileID: 7554373769959085815, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ type: 3}
+ propertyPath: m_Mesh
+ value:
+ objectReference: {fileID: 0}
- target: {fileID: 8022226399187307763, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
type: 3}
propertyPath: m_Mesh
value:
objectReference: {fileID: 0}
+ - target: {fileID: 8158409320092676088, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37,
+ type: 3}
+ propertyPath: m_Mesh
+ value:
+ objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: cbf1dc7c99d3ea44dba7eb02f2c08b37, type: 3}
diff --git a/Frontend/VIAProMa/Assets/Prefabs/UI/App Bar/App Bar.prefab b/Frontend/VIAProMa/Assets/Prefabs/UI/App Bar/App Bar.prefab
index 23aa54c89..86ac18396 100644
--- a/Frontend/VIAProMa/Assets/Prefabs/UI/App Bar/App Bar.prefab
+++ b/Frontend/VIAProMa/Assets/Prefabs/UI/App Bar/App Bar.prefab
@@ -30,6 +30,8 @@ Transform:
- {fileID: 3361800236042063618}
- {fileID: 5790070783517185443}
- {fileID: 5524453724328992038}
+ - {fileID: 3515993982177029129}
+ - {fileID: 2964961762303939846}
m_Father: {fileID: 3015370290085581028}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@@ -265,8 +267,6 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
- m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
- Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_text: '...'
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: afc8299d5d5bbd440a0616c8ecbc7217, type: 2}
@@ -304,7 +304,6 @@ MonoBehaviour:
m_fontSizeMax: 72
m_fontStyle: 0
m_textAlignment: 514
- m_isAlignmentEnumConverted: 1
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
@@ -331,6 +330,7 @@ MonoBehaviour:
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
+ m_VertexBufferAutoSizeReduction: 1
m_firstVisibleCharacter: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
@@ -345,12 +345,9 @@ MonoBehaviour:
lineCount: 1
pageCount: 1
materialCount: 1
- m_havePropertiesChanged: 0
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_spriteAnimator: {fileID: 0}
- m_isInputParsingRequired: 0
- m_inputSource: 0
m_hasFontAssetChanged: 0
m_renderer: {fileID: 8129690116143705549}
m_subTextObjects:
@@ -537,6 +534,10 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 2643668230aba8b4592de6756012b725, type: 3}
m_Name:
m_EditorClassIdentifier:
+ lineControllerPrefab: {fileID: 8246175140109700422, guid: 8231cf347b64d3e4499b64b783604e88,
+ type: 3}
+ test1: {fileID: 0}
+ test2: {fileID: 0}
--- !u!1 &5365872765720426043
GameObject:
m_ObjectHideFlags: 0
@@ -656,7 +657,7 @@ Transform:
m_GameObject: {fileID: 7409039082933876621}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
- m_LocalScale: {x: 0.158, y: 0.05, z: 0.005}
+ m_LocalScale: {x: 0.25804, y: 0.05, z: 0.005}
m_Children: []
m_Father: {fileID: 3015370290085581028}
m_RootOrder: 0
@@ -766,7 +767,7 @@ PrefabInstance:
- target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
type: 3}
propertyPath: m_LocalPosition.x
- value: -0.00403
+ value: -0.05402
objectReference: {fileID: 0}
- target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
type: 3}
@@ -917,7 +918,7 @@ PrefabInstance:
- target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
type: 3}
propertyPath: m_LocalPosition.x
- value: 0.05397
+ value: 0.10402
objectReference: {fileID: 0}
- target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
type: 3}
@@ -1206,6 +1207,11 @@ PrefabInstance:
propertyPath: m_Name
value: Expand Button
objectReference: {fileID: 0}
+ - target: {fileID: 5930129418263004461, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_IsActive
+ value: 1
+ objectReference: {fileID: 0}
- target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
type: 3}
propertyPath: m_LocalPosition.x
@@ -1456,6 +1462,197 @@ Transform:
type: 3}
m_PrefabInstance: {fileID: 5709965140786206178}
m_PrefabAsset: {fileID: 0}
+--- !u!1001 &7913702299499504063
+PrefabInstance:
+ m_ObjectHideFlags: 0
+ serializedVersion: 2
+ m_Modification:
+ m_TransformParent: {fileID: 8733304401739041720}
+ m_Modifications:
+ - target: {fileID: 5930129418263004461, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_Name
+ value: Connect Button
+ objectReference: {fileID: 0}
+ - target: {fileID: 5930129418263004461, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_IsActive
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalPosition.x
+ value: -0.00402
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalPosition.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalPosition.z
+ value: -0.005
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalRotation.x
+ value: -0
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalRotation.y
+ value: -0
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalRotation.z
+ value: -0
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalRotation.w
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_RootOrder
+ value: 3
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalEulerAnglesHint.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalEulerAnglesHint.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalEulerAnglesHint.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.size
+ value: 2
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: VoiceCommand
+ value: Connect
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Mode
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_CallState
+ value: 2
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Target
+ value:
+ objectReference: {fileID: 5230637767879531230}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_MethodName
+ value: Connect
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Arguments.m_ObjectArgumentAssemblyTypeName
+ value: UnityEngine.Object, UnityEngine
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_Enabled
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[1].m_Mode
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[1].m_CallState
+ value: 2
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[1].m_Target
+ value:
+ objectReference: {fileID: 4935565329374930599}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[1].m_MethodName
+ value: InvokeConnect
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[1].m_Arguments.m_ObjectArgumentAssemblyTypeName
+ value: UnityEngine.Object, UnityEngine
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[2].m_Mode
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[2].m_CallState
+ value: 2
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[2].m_Target
+ value:
+ objectReference: {fileID: 4935565329374930599}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[2].m_MethodName
+ value: InvokeConnect
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[2].m_Arguments.m_ObjectArgumentAssemblyTypeName
+ value: UnityEngine.Object, UnityEngine
+ objectReference: {fileID: 0}
+ - target: {fileID: 7833925320009080169, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_Sprite
+ value:
+ objectReference: {fileID: 21300000, guid: d73af7eefe8164c4caf08742075c9331,
+ type: 3}
+ - target: {fileID: 3859134200147805989, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_text
+ value: Say "Connect"
+ objectReference: {fileID: 0}
+ - target: {fileID: 3859134200147805989, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_textInfo.characterCount
+ value: 13
+ objectReference: {fileID: 0}
+ - target: {fileID: 2083865205732806215, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_Mesh
+ value:
+ objectReference: {fileID: 0}
+ m_RemovedComponents: []
+ m_SourcePrefab: {fileID: 100100000, guid: c4e709f8a15434946bb54263fe6e9bf1, type: 3}
+--- !u!4 &3515993982177029129 stripped
+Transform:
+ m_CorrespondingSourceObject: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ m_PrefabInstance: {fileID: 7913702299499504063}
+ m_PrefabAsset: {fileID: 0}
--- !u!1001 &8340609563670741684
PrefabInstance:
m_ObjectHideFlags: 0
@@ -1471,7 +1668,7 @@ PrefabInstance:
- target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
type: 3}
propertyPath: m_LocalPosition.x
- value: -0.05403
+ value: -0.10402
objectReference: {fileID: 0}
- target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
type: 3}
@@ -1587,3 +1784,169 @@ Transform:
type: 3}
m_PrefabInstance: {fileID: 8340609563670741684}
m_PrefabAsset: {fileID: 0}
+--- !u!1001 &8376104552972196016
+PrefabInstance:
+ m_ObjectHideFlags: 0
+ serializedVersion: 2
+ m_Modification:
+ m_TransformParent: {fileID: 8733304401739041720}
+ m_Modifications:
+ - target: {fileID: 5930129418263004461, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_Name
+ value: Disconnect Button
+ objectReference: {fileID: 0}
+ - target: {fileID: 5930129418263004461, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_IsActive
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalPosition.x
+ value: 0.04598
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalPosition.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalPosition.z
+ value: -0.005
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalRotation.x
+ value: -0
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalRotation.y
+ value: -0
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalRotation.z
+ value: -0
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalRotation.w
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_RootOrder
+ value: 4
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalEulerAnglesHint.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalEulerAnglesHint.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_LocalEulerAnglesHint.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.size
+ value: 2
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: VoiceCommand
+ value: Disconnect
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Mode
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_CallState
+ value: 2
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Target
+ value:
+ objectReference: {fileID: 5230637767879531230}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_MethodName
+ value: Disconnect
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Arguments.m_ObjectArgumentAssemblyTypeName
+ value: UnityEngine.Object, UnityEngine
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_Enabled
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[1].m_Mode
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[1].m_CallState
+ value: 2
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[1].m_Target
+ value:
+ objectReference: {fileID: 4935565329374930599}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[1].m_MethodName
+ value: Collapse
+ objectReference: {fileID: 0}
+ - target: {fileID: 924064247416018914, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: OnClick.m_PersistentCalls.m_Calls.Array.data[1].m_Arguments.m_ObjectArgumentAssemblyTypeName
+ value: UnityEngine.Object, UnityEngine
+ objectReference: {fileID: 0}
+ - target: {fileID: 7833925320009080169, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_Sprite
+ value:
+ objectReference: {fileID: 21300000, guid: c2ed3404e0b10d24a832ff89d567de63,
+ type: 3}
+ - target: {fileID: 3859134200147805989, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_text
+ value: Say "Disconnect"
+ objectReference: {fileID: 0}
+ - target: {fileID: 3859134200147805989, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_textInfo.characterCount
+ value: 13
+ objectReference: {fileID: 0}
+ - target: {fileID: 2083865205732806215, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ propertyPath: m_Mesh
+ value:
+ objectReference: {fileID: 0}
+ m_RemovedComponents: []
+ m_SourcePrefab: {fileID: 100100000, guid: c4e709f8a15434946bb54263fe6e9bf1, type: 3}
+--- !u!4 &2964961762303939846 stripped
+Transform:
+ m_CorrespondingSourceObject: {fileID: 6708199287665102262, guid: c4e709f8a15434946bb54263fe6e9bf1,
+ type: 3}
+ m_PrefabInstance: {fileID: 8376104552972196016}
+ m_PrefabAsset: {fileID: 0}
diff --git a/Frontend/VIAProMa/Assets/Prefabs/Visualizations/BuildingProgress Bar/Resources/Building Progress Bar.prefab b/Frontend/VIAProMa/Assets/Prefabs/Visualizations/BuildingProgress Bar/Resources/Building Progress Bar.prefab
index 35b0aff5b..f04b58268 100644
--- a/Frontend/VIAProMa/Assets/Prefabs/Visualizations/BuildingProgress Bar/Resources/Building Progress Bar.prefab
+++ b/Frontend/VIAProMa/Assets/Prefabs/Visualizations/BuildingProgress Bar/Resources/Building Progress Bar.prefab
@@ -853,6 +853,11 @@ PrefabInstance:
m_Modification:
m_TransformParent: {fileID: 513762739022804669}
m_Modifications:
+ - target: {fileID: 702864726260061843, guid: 7c8aa50a2b06a494999c1bd85d537e82,
+ type: 3}
+ propertyPath: m_Name
+ value: Scaffolding
+ objectReference: {fileID: 0}
- target: {fileID: 702864726260061842, guid: 7c8aa50a2b06a494999c1bd85d537e82,
type: 3}
propertyPath: m_RootOrder
@@ -908,11 +913,6 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- - target: {fileID: 702864726260061843, guid: 7c8aa50a2b06a494999c1bd85d537e82,
- type: 3}
- propertyPath: m_Name
- value: Scaffolding
- objectReference: {fileID: 0}
- target: {fileID: 702864727490690431, guid: 7c8aa50a2b06a494999c1bd85d537e82,
type: 3}
propertyPath: m_IsActive
@@ -1188,6 +1188,26 @@ PrefabInstance:
propertyPath: m_Mesh
value:
objectReference: {fileID: 0}
+ - target: {fileID: 8362453174100900500, guid: 171f717c846f82349ae46e1af72a2966,
+ type: 3}
+ propertyPath: m_havePropertiesChanged
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 8362453174100900500, guid: 171f717c846f82349ae46e1af72a2966,
+ type: 3}
+ propertyPath: m_isInputParsingRequired
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 8362453174100900500, guid: 171f717c846f82349ae46e1af72a2966,
+ type: 3}
+ propertyPath: m_fontSize
+ value: 0.75
+ objectReference: {fileID: 0}
+ - target: {fileID: 8362453174100900500, guid: 171f717c846f82349ae46e1af72a2966,
+ type: 3}
+ propertyPath: m_textInfo.characterCount
+ value: 14
+ objectReference: {fileID: 0}
- target: {fileID: 8362453174225159361, guid: 171f717c846f82349ae46e1af72a2966,
type: 3}
propertyPath: m_RootOrder
diff --git a/Frontend/VIAProMa/Assets/Prefabs/Visualizations/Competence Display/Resources/CompetenceDisplay.prefab b/Frontend/VIAProMa/Assets/Prefabs/Visualizations/Competence Display/Resources/CompetenceDisplay.prefab
index 244949f88..c6274fca6 100644
--- a/Frontend/VIAProMa/Assets/Prefabs/Visualizations/Competence Display/Resources/CompetenceDisplay.prefab
+++ b/Frontend/VIAProMa/Assets/Prefabs/Visualizations/Competence Display/Resources/CompetenceDisplay.prefab
@@ -738,11 +738,6 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- - target: {fileID: 2856050035318534277, guid: 25f1f23bea0e91d4e83e7115be403bf9,
- type: 3}
- propertyPath: m_Name
- value: Competence Display Configuration Window
- objectReference: {fileID: 0}
- target: {fileID: 4775622285331820077, guid: 25f1f23bea0e91d4e83e7115be403bf9,
type: 3}
propertyPath: appBarSpawner
diff --git a/Frontend/VIAProMa/Assets/Resources/Connection Curve.prefab b/Frontend/VIAProMa/Assets/Resources/Connection Curve.prefab
new file mode 100644
index 000000000..423d643a9
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Resources/Connection Curve.prefab
@@ -0,0 +1,208 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &7853647021840196732
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 7334090912813246917}
+ - component: {fileID: 6506161665542237601}
+ - component: {fileID: 1698826534377868237}
+ - component: {fileID: 5477821616535701297}
+ - component: {fileID: 3901515601592956747}
+ - component: {fileID: 6236956108489000634}
+ - component: {fileID: 8688853414020156703}
+ m_Layer: 0
+ m_Name: Connection Curve
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &7334090912813246917
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7853647021840196732}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!120 &6506161665542237601
+LineRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7853647021840196732}
+ m_Enabled: 1
+ m_CastShadows: 1
+ m_ReceiveShadows: 1
+ m_DynamicOccludee: 1
+ m_MotionVectors: 0
+ m_LightProbeUsage: 0
+ m_ReflectionProbeUsage: 0
+ m_RenderingLayerMask: 1
+ m_RendererPriority: 0
+ m_Materials:
+ - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ m_StaticBatchRoot: {fileID: 0}
+ m_ProbeAnchor: {fileID: 0}
+ m_LightProbeVolumeOverride: {fileID: 0}
+ m_ScaleInLightmap: 1
+ m_PreserveUVs: 0
+ m_IgnoreNormalsForChartDetection: 0
+ m_ImportantGI: 0
+ m_StitchLightmapSeams: 0
+ 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_Positions:
+ - {x: 0, y: 0, z: 0}
+ - {x: 0, y: 0, z: 1}
+ m_Parameters:
+ serializedVersion: 3
+ widthMultiplier: 1
+ widthCurve:
+ serializedVersion: 2
+ m_Curve:
+ - serializedVersion: 3
+ time: 0
+ value: 0.046676636
+ inSlope: 0
+ outSlope: 0
+ tangentMode: 0
+ weightedMode: 0
+ inWeight: 0.33333334
+ outWeight: 0.33333334
+ m_PreInfinity: 2
+ m_PostInfinity: 2
+ m_RotationOrder: 4
+ colorGradient:
+ serializedVersion: 2
+ key0: {r: 0.33463618, g: 0.8962264, b: 0.13105197, a: 1}
+ key1: {r: 0.33463618, g: 0.8962264, b: 0.13105197, a: 1}
+ key2: {r: 0, g: 0, b: 0, a: 0}
+ key3: {r: 0, g: 0, b: 0, a: 0}
+ key4: {r: 0, g: 0, b: 0, a: 0}
+ key5: {r: 0, g: 0, b: 0, a: 0}
+ key6: {r: 0, g: 0, b: 0, a: 0}
+ key7: {r: 0, g: 0, b: 0, a: 0}
+ ctime0: 0
+ ctime1: 65535
+ ctime2: 0
+ ctime3: 0
+ ctime4: 0
+ ctime5: 0
+ ctime6: 0
+ ctime7: 0
+ atime0: 0
+ atime1: 58403
+ atime2: 0
+ atime3: 0
+ atime4: 0
+ atime5: 0
+ atime6: 0
+ atime7: 0
+ m_Mode: 0
+ m_NumColorKeys: 2
+ m_NumAlphaKeys: 2
+ numCornerVertices: 0
+ numCapVertices: 0
+ alignment: 0
+ textureMode: 0
+ shadowBias: 0.5
+ generateLightingData: 0
+ m_UseWorldSpace: 1
+ m_Loop: 0
+--- !u!114 &1698826534377868237
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7853647021840196732}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: aa584fbee541324448dd18d8409c7a41, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ ObservedComponentsFoldoutOpen: 1
+ Group: 0
+ prefixField: -1
+ observableSearch: 2
+ Synchronization: 0
+ OwnershipTransfer: 2
+ ObservedComponents: []
+ viewIdField: 0
+ InstantiationId: 0
+ isRuntimeInstantiated: 0
+--- !u!114 &5477821616535701297
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7853647021840196732}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 889cf250a9686284fa48bde7f9f5fac1, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+--- !u!114 &3901515601592956747
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7853647021840196732}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: ff3b7d7201cbbe44c99cc52688e3bac8, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ start: {fileID: 0}
+ goal: {fileID: 0}
+ startID:
+ goalID:
+ lineRenderer: {fileID: 6506161665542237601}
+--- !u!114 &6236956108489000634
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7853647021840196732}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d0a09596fd3f25c47b2f3d7bbfd6c024, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+--- !u!114 &8688853414020156703
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7853647021840196732}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: c0d7a2ad11c845a4a8a16ae1c6f40076, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
diff --git a/Frontend/VIAProMa/Assets/Resources/Connection Curve.prefab.meta b/Frontend/VIAProMa/Assets/Resources/Connection Curve.prefab.meta
new file mode 100644
index 000000000..05b38c432
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Resources/Connection Curve.prefab.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: e948fd42ac79ada4e89e5e4087102753
+PrefabImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Resources/Temp Goal.prefab b/Frontend/VIAProMa/Assets/Resources/Temp Goal.prefab
new file mode 100644
index 000000000..76b075f81
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Resources/Temp Goal.prefab
@@ -0,0 +1,72 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &174366279205162471
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 171562966599788573}
+ - component: {fileID: 2968300826686824084}
+ - component: {fileID: 565687123747021719}
+ m_Layer: 0
+ m_Name: Temp Goal
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &171562966599788573
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 174366279205162471}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &2968300826686824084
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 174366279205162471}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: aa584fbee541324448dd18d8409c7a41, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ ObservedComponentsFoldoutOpen: 1
+ Group: 0
+ prefixField: -1
+ observableSearch: 0
+ Synchronization: 3
+ OwnershipTransfer: 2
+ ObservedComponents:
+ - {fileID: 565687123747021719}
+ viewIdField: 0
+ InstantiationId: 0
+ isRuntimeInstantiated: 0
+--- !u!114 &565687123747021719
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 174366279205162471}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 627855c7f81362d41938ffe0b1475957, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_SynchronizePosition: 1
+ m_SynchronizeRotation: 0
+ m_SynchronizeScale: 0
diff --git a/Frontend/VIAProMa/Assets/Resources/Temp Goal.prefab.meta b/Frontend/VIAProMa/Assets/Resources/Temp Goal.prefab.meta
new file mode 100644
index 000000000..6f07096bf
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Resources/Temp Goal.prefab.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 2b63e6948ce245a40b1aa66eedd57c81
+PrefabImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Scenes/MainScene.unity b/Frontend/VIAProMa/Assets/Scenes/MainScene.unity
index 04316cfb8..eee8a9f44 100644
--- a/Frontend/VIAProMa/Assets/Scenes/MainScene.unity
+++ b/Frontend/VIAProMa/Assets/Scenes/MainScene.unity
@@ -4181,6 +4181,11 @@ PrefabInstance:
propertyPath: m_isInputParsingRequired
value: 1
objectReference: {fileID: 0}
+ - target: {fileID: 5650007671030586223, guid: 6580c13df571c9242b86ffe5fe901102,
+ type: 3}
+ propertyPath: viewIdField
+ value: 4
+ objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 6580c13df571c9242b86ffe5fe901102, type: 3}
--- !u!1 &2038167400
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves.meta b/Frontend/VIAProMa/Assets/Scripts/Connection Curves.meta
new file mode 100644
index 000000000..cac8352fa
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 580a3d03bfa28c34ebd9b9e6d9f14b4a
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/ConnectionCurve.cs b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/ConnectionCurve.cs
new file mode 100644
index 000000000..fa89260eb
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/ConnectionCurve.cs
@@ -0,0 +1,125 @@
+using UnityEngine;
+using Photon.Pun;
+using System.Threading.Tasks;
+using i5.VIAProMa.SaveLoadSystem.Core;
+using i5.VIAProMa.ResourceManagagement;
+
+///
+/// An object to display and manage 3D curves.
+///
+public class ConnectionCurve : MonoBehaviour
+{
+
+ public GameObject start;
+ public GameObject goal;
+
+ //Serializer IDs. When the curve was not instatiated through the save laod manager, they are always empty.
+ public string startID = "";
+ public string goalID = "";
+
+ //True, when the curve has another color than the default color
+ public bool isMarked { get; set; }
+
+ public LineRenderer lineRenderer;
+ Gradient defaultColor;
+
+ void Start()
+ {
+ //When the IDs are empty, the curve was not instantiated through the SaveLoadManager.
+ if (startID == "" && goalID == "")
+ {
+ var view = GetComponent();
+ //When the client is in a room, the instatiation data is not null and start and goal is not set yet, the curve was instantiated with the Photon Instantiation and the instantiation data has to be resolved
+ if (PhotonNetwork.InRoom && view.InstantiationData != null && start == null && goal == null)
+ {
+ int startID = (int)view.InstantiationData[0];
+ int goalID = (int)view.InstantiationData[1];
+ start = PhotonNetwork.GetPhotonView(startID).transform.gameObject;
+ goal = PhotonNetwork.GetPhotonView(goalID).transform.gameObject;
+ }
+ defaultColor = lineRenderer.colorGradient;
+ ConnectionCurveManager.Instance.curves.Add(this);
+ }
+ else
+ {
+ ResolveSerializerID();
+ }
+ }
+
+ ///
+ /// Resolves the saved serializer IDs into a start and goal object. It then creates a new curve with the correct objects as instantiation data and then destroyes itself.
+ ///
+ private async void ResolveSerializerID()
+ {
+ GameObject startObject;
+ GameObject goalObject;
+ bool resolved = false;
+ //It can take some time, until the save load manager can resolve the IDs
+ do
+ {
+ startObject = SaveLoadManager.Instance.GetRegisterdGameobject(startID);
+ goalObject = SaveLoadManager.Instance.GetRegisterdGameobject(goalID);
+ if (startObject == null || goalObject == null)
+ {
+ await Task.Yield();
+ }
+ else
+ {
+ resolved = true;
+ }
+ }
+ while (!resolved);
+ object[] data = new object[2];
+ data[0] = startObject.GetComponent().ViewID;
+ data[1] = goalObject.GetComponent().ViewID;
+ ResourceManager.Instance.SceneNetworkInstantiate(ConnectionCurveManager.Instance.curveConnectPrefab, Vector3.zero, Quaternion.identity, (x) => { }, data);
+ PhotonNetwork.Destroy(GetComponent());
+ }
+
+ ///
+ /// Sets the color gradient of the line renderer to a gradient from color1Arr to color2Arr. Both need to be provided in the format: (r,g,b,a).
+ ///
+ /// The RGBA values for the first color
+ /// The RGBA values for the second color
+ [PunRPC]
+ public void SetColor(float[] color1Arr, float[] color2Arr)
+ {
+ //Using the Color class for color1Arr and color2Arr is not possible, because Color is not supported by photon.
+ Color color1 = new Color(color1Arr[0], color1Arr[1], color1Arr[2], color1Arr[3]);
+ Color color2 = new Color(color2Arr[0], color2Arr[1], color2Arr[2], color2Arr[3]);
+ float alpha = 1.0f;
+ Gradient gradient = new Gradient();
+ gradient.SetKeys(
+ new GradientColorKey[] { new GradientColorKey(color1, 0.0f), new GradientColorKey(color2, 1.0f) },
+ new GradientAlphaKey[] { new GradientAlphaKey(alpha, 0.0f), new GradientAlphaKey(alpha, 1.0f) }
+ );
+ lineRenderer.colorGradient = gradient;
+ }
+
+ ///
+ /// Sets the color gradient of the line renderer to the default color gradient. The default color gradient is the gradient, the curve was initalised with.
+ ///
+ [PunRPC]
+ public void ResetColor()
+ {
+ lineRenderer.colorGradient = defaultColor;
+ }
+
+ ///
+ /// Sets the goal the object with the Photon ID viewID.
+ ///
+ /// The Photon ID of the new goal
+ [PunRPC]
+ public void SetGoal(int viewID)
+ {
+ goal = PhotonNetwork.GetPhotonView(viewID).gameObject;
+ }
+
+ ///
+ /// Removes the curve from the watchlist
+ ///
+ private void OnDestroy()
+ {
+ ConnectionCurveManager.Instance?.curves.Remove(this);
+ }
+}
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/ConnectionCurve.cs.meta b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/ConnectionCurve.cs.meta
new file mode 100644
index 000000000..3d998ac4a
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/ConnectionCurve.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ff3b7d7201cbbe44c99cc52688e3bac8
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/ConnectionCurveManager.cs b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/ConnectionCurveManager.cs
new file mode 100644
index 000000000..1f436d2e6
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/ConnectionCurveManager.cs
@@ -0,0 +1,545 @@
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using Microsoft.MixedReality.Toolkit;
+using Microsoft.MixedReality.Toolkit.Input;
+using Photon.Pun;
+using System.Threading.Tasks;
+using HoloToolkit.Unity;
+using i5.VIAProMa.UI.AppBar;
+using i5.VIAProMa.ResourceManagagement;
+
+///
+/// Manages the connect and disconnect process of Connection Curves and provides functions to manage curves.
+///
+public class ConnectionCurveManager : Singleton
+{
+ public bool onlineTestMode;
+ static float stepSize = 0.5f;
+ public static int curveSegmentCount = 60;
+ public GameObject DeleteCube;
+ GameObject instantiatedDeletCube;
+ public List curves;
+ IMixedRealityPointer mainPointer = null;
+ JoinedCurveGeneration curveGenerator;
+ public enum State
+ {
+ defaultMode,
+ connecting,
+ disconnecting
+ }
+
+ public State currState = State.defaultMode;
+ public GameObject curveConnectPrefab;
+ public GameObject tempGoalPrefab;
+ AppBarStateController caller;
+ bool lastFrameClicked = false;
+ bool deletedSomething = false;
+ bool startedDeletion = false;
+
+ //Temp Curve
+ ConnectionCurve tempCurve;
+ DateTime clickTimeStamp;
+
+ List test;
+
+
+ GameObject tempGoal = null;
+
+ ///
+ /// Starts the JoinedCurveGeneration
+ ///
+ void Start()
+ {
+ clickTimeStamp = DateTime.Now;
+ JoinedCurveGeneration.Instance.UpdateAsyc(curves,stepSize);
+ }
+
+ ///
+ /// Manages connecting and deleting of curves
+ ///
+ void Update()
+ {
+ bool thisFrameClicked = false;
+ bool pointerValid = false;
+ //Check, if there is a valid pointer in the scene.
+ pointerValid = mainPointer?.BaseCursor != null && mainPointer.BaseCursor is AnimatedCursor;
+
+ if (pointerValid)
+ {
+ thisFrameClicked = ((AnimatedCursor)mainPointer.BaseCursor).CursorState == CursorStateEnum.Select && (DateTime.Now - clickTimeStamp).TotalMilliseconds > 30;
+ }
+ switch (currState)
+ {
+ case State.connecting:
+ GameObject target;
+ if (pointerValid)
+ {
+ if (tempCurve.goal != null && tempCurve.start != null)
+ {
+ target = GetParentWithPhotonView(mainPointer.Result?.CurrentPointerTarget);
+ var view = tempCurve.GetComponent();
+ var goalView = target?.GetComponent();
+ //Is the coursor pointing on a valid target?
+ if (target != null && target != tempCurve.start)
+ {
+ //Set the goal of the temp curve to the temp goal
+ if (tempCurve.goal != target)
+ {
+ if (PhotonNetwork.InRoom)
+ {
+ view.RPC("SetGoal", RpcTarget.All, goalView.ViewID);
+ }
+ else
+ {
+ tempCurve.goal = target;
+ }
+ }
+ }
+ else
+ {
+ //Restore the normal temp curve
+ if (tempCurve.goal != tempGoal)
+ {
+ if (PhotonNetwork.InRoom)
+ {
+ view.RPC("SetGoal", RpcTarget.All, tempGoal.GetComponent().ViewID);
+ }
+ else
+ {
+ tempCurve.goal = tempGoal;
+ }
+ }
+ tempGoal.transform.position = mainPointer.Position;
+ }
+ var cursor = (AnimatedCursor)mainPointer.BaseCursor;
+ if (thisFrameClicked)
+ {
+ if (target != null && target != tempCurve.start)
+ CreateConnectionCurveScene(tempCurve.start, target);
+ ChangeState(State.defaultMode);
+ }
+ }
+ }
+ else
+ {
+ ChangeState(State.defaultMode);
+ }
+ break;
+
+ case State.disconnecting:
+ if (pointerValid)
+ {
+ //Update Delete Cube transform
+ var ray = mainPointer.Rays[0];
+ instantiatedDeletCube.transform.position = ray.Origin + ray.Direction.normalized * 0.5f;
+ instantiatedDeletCube.transform.rotation = mainPointer.Rotation;
+
+ //Necassrary because you shouldn't delete an object from a list, while iterating over it
+ List curvesToDelete = new List();
+ //Check which curves colide with the delete cube
+ foreach (ConnectionCurve connectionCurve in curves)
+ {
+ Vector3[] curve = new Vector3[connectionCurve.lineRenderer.positionCount];
+ connectionCurve.lineRenderer.GetPositions(curve);
+ var view = connectionCurve.GetComponent();
+ if (CurveGenerator.CurveCollsionCheck(curve, connectionCurve.start, connectionCurve.goal, 0b100000000, false, 0.05f))
+ {
+ connectionCurve.isMarked = true;
+ //TODO is marked is not used properly
+ if (PhotonNetwork.InRoom)
+ {
+ view.RPC("SetColor", RpcTarget.All, ColorPhoton(Color.red), ColorPhoton(Color.yellow));
+ }
+ else
+ {
+ connectionCurve.SetColor(ColorPhoton(Color.red), ColorPhoton(Color.yellow));
+ }
+
+ if (thisFrameClicked)
+ {
+ curvesToDelete.Add(connectionCurve);
+ }
+ }
+ else if(connectionCurve.isMarked)
+ {
+ connectionCurve.isMarked = false;
+ if (PhotonNetwork.InRoom)
+ {
+ view.RPC("ResetColor", RpcTarget.All);
+ }
+ else
+ {
+ connectionCurve.ResetColor();
+ }
+ }
+ }
+
+ foreach (ConnectionCurve connectionCurve in curvesToDelete)
+ {
+ DeleteConnectionCurve(connectionCurve);
+ deletedSomething = true;
+ }
+
+ //When the user clicked and enough time passed since starting the delete mode, then stopped clicking and if that wasn't the click that started the disconnect mode and it
+ //was nothing disconnected while in disconnect mode, go back to default mode
+ if (lastFrameClicked && !thisFrameClicked && curvesToDelete.Count == 0 && !deletedSomething && !startedDeletion)
+ {
+ ChangeState(State.defaultMode);
+ }
+
+ if (lastFrameClicked && !thisFrameClicked)
+ {
+ deletedSomething = false;
+ }
+ startedDeletion = false;
+ }
+ else
+ {
+ ChangeState(State.defaultMode);
+ }
+ break;
+ }
+ lastFrameClicked = thisFrameClicked;
+ }
+
+ ///
+ /// Change the state of the Connection Curve Manager. The function automaticly ends all effects from the old state.
+ ///
+ /// The state the manger should switch to
+ /// Only needed when switching to connecting. Specifies the start object of the connection
+ /// Only needed when switching to connecting. Specifies the app bar on which the connecting was invoked
+ public void ChangeState(State state , GameObject caller = null, GameObject start = null)
+ {
+
+ if (state == currState)
+ return;
+
+ //End the effects from the old state
+ switch (currState)
+ {
+ case State.disconnecting:
+ StopDisconnect();
+ break;
+ case State.connecting:
+ StopConnect();
+ break;
+ }
+
+ //Initalise the new state
+ switch (state)
+ {
+ case State.defaultMode:
+ currState = State.defaultMode;
+ break;
+ case State.disconnecting:
+ StartDisconnect(caller);
+ currState = State.disconnecting;
+ break;
+ case State.connecting:
+ StartConnecting(start, caller);
+ currState = State.connecting;
+ break;
+ }
+ clickTimeStamp = DateTime.Now;
+ }
+
+ ///
+ /// Destroys a Connection Curve while resepecting that it can be networked and the the requestimg client may not have the ownership at the moment.
+ ///
+ /// The curve that should be destroyed
+ async void DeleteConnectionCurve(ConnectionCurve connectionCurve)
+ {
+ if (PhotonNetwork.InRoom)
+ {
+ var view = connectionCurve.GetComponent();
+ view.RequestOwnership();
+ //Curves remove them selfe from the list. This is done here again, so a client doesn't queu a curve multiple times for deletion
+ curves.Remove(connectionCurve);
+ while (view.Owner != PhotonNetwork.LocalPlayer)
+ {
+ await Task.Yield();
+ }
+ PhotonNetwork.Destroy(view);
+ }
+ else
+ {
+ Destroy(connectionCurve.gameObject);
+ }
+ }
+
+ ///
+ /// Creates a Connection Curve from start to goal. When the user is in a room, the curve is instantiated as photon scene object. Otherwise it is instantiated normally.
+ ///
+ /// The start object of the curve
+ /// The goal object of the curve
+ public void CreateConnectionCurveScene(GameObject start, GameObject goal)
+ {
+ if (PhotonNetwork.InRoom)
+ {
+ object[] data = new object[2];
+ data[0] = start.GetComponent().ViewID;
+ data[1] = goal.GetComponent().ViewID;
+ ResourceManager.Instance.SceneNetworkInstantiate(curveConnectPrefab, Vector3.zero, Quaternion.identity, (x) => {}, data);
+ }
+ else
+ {
+ ConnectionCurve curve = Instantiate(curveConnectPrefab).GetComponent();
+ curve.start = start;
+ curve.goal = goal;
+ }
+ }
+
+ ///
+ /// Creates a Connection Curve from start to goal. When the user is in a room, the curve is instantiated as photon object, with the creator as owner and creator. Otherwise it is instantiated normally.
+ ///
+ /// The start object of the curve
+ /// The goal object of the curve
+ public ConnectionCurve CreateConnectionCurveOwn(GameObject start, GameObject goal)
+ {
+ ConnectionCurve curve;
+ if (PhotonNetwork.InRoom)
+ {
+ object[] data = new object[2];
+ data[0] = start.GetComponent().ViewID;
+ data[1] = goal.GetComponent().ViewID;
+ curve = PhotonNetwork.Instantiate("Connection Curve", Vector3.zero, Quaternion.identity, 0, data).GetComponent();
+ }
+ else
+ {
+ curve = Instantiate(curveConnectPrefab).GetComponent();
+ curve.start = start;
+ curve.goal = goal;
+ }
+ return curve;
+ }
+
+ ///
+ /// Starts the connect process.
+ ///
+ /// The start object of the connection
+ /// The app bar on which the connecting was invoked
+ void StartConnecting(GameObject start, GameObject caller)
+ {
+ RefreshPointer(caller.gameObject);
+ this.caller = caller.GetComponent();
+ if (PhotonNetwork.InRoom)
+ {
+ tempGoal = PhotonNetwork.Instantiate("Temp Goal", mainPointer.Position, Quaternion.identity);
+ tempCurve = CreateConnectionCurveOwn(start, tempGoal);
+ tempCurve.GetComponent().RPC("SetColor", RpcTarget.All, ColorPhoton(Color.yellow), ColorPhoton(Color.yellow));
+ }
+ else
+ {
+ tempGoal = Instantiate(tempGoalPrefab);
+ tempCurve = CreateConnectionCurveOwn(start, tempGoal);
+ tempCurve.SetColor(ColorPhoton(Color.yellow), ColorPhoton(Color.yellow));
+ }
+ }
+
+ ///
+ /// Stops the connect process.
+ ///
+ void StopConnect()
+ {
+ caller.Collapse();
+ if (PhotonNetwork.InRoom)
+ {
+ PhotonNetwork.Destroy(tempGoal);
+ }
+ else
+ {
+ Destroy(tempGoal);
+ }
+ DeleteConnectionCurve(tempCurve);
+ startedDeletion = false;
+ }
+
+ ///
+ /// Start the disconnect process.
+ ///
+ void StartDisconnect(GameObject caller)
+ {
+ if (currState != State.disconnecting)
+ {
+ currState = State.disconnecting;
+ RefreshPointer(caller);
+ instantiatedDeletCube = Instantiate(DeleteCube);
+ }
+ startedDeletion = true;
+ }
+
+ ///
+ /// Stop the disconnect process.
+ ///
+ void StopDisconnect()
+ {
+ Destroy(instantiatedDeletCube);
+ foreach (ConnectionCurve curve in curves)
+ {
+ if (curve.isMarked)
+ {
+ if (PhotonNetwork.InRoom)
+ {
+ curve.GetComponent().RPC("ResetColor", RpcTarget.All);
+ }
+ else
+ {
+ curve.ResetColor();
+ }
+ }
+ }
+ deletedSomething = false;
+ }
+
+ ///
+ /// Delet all Connection Curves connected to a GameObject
+ ///
+ /// The object from which all curves should be deleted
+ public void DeleteAllCurvesFromObject(GameObject startOrEndPoint)
+ {
+ List curvesToDelete = new List();
+ foreach (ConnectionCurve connectionCurve in curves)
+ {
+ if (connectionCurve.start == startOrEndPoint || connectionCurve.goal == startOrEndPoint)
+ {
+ curvesToDelete.Add(connectionCurve);
+ }
+ }
+ foreach (ConnectionCurve connectionCurve in curvesToDelete)
+ {
+ DeleteConnectionCurve(connectionCurve);
+ }
+
+ }
+
+ ///
+ /// Delet all Connection Curves managed by the ConnectionCurveManager
+ ///
+ public void DeleteAllCurves()
+ {
+ var curvesToDelete = new List(curves);
+ foreach (ConnectionCurve connectionCurve in curvesToDelete)
+ {
+ DeleteConnectionCurve(connectionCurve);
+ }
+ }
+
+ ///
+ /// Recalculate the MRTK pointer. This is necassary in regular intervalls, because user can connect or disconnect input sources at any time.
+ ///
+ public void RefreshPointer(GameObject caller)
+ {
+ foreach (var source in CoreServices.InputSystem.DetectedInputSources)
+ {
+ foreach (var p in source.Pointers)
+ {
+ if (p is IMixedRealityNearPointer)
+ {
+ // Ignore near pointers, we only want the rays
+ continue;
+ }
+ if (p.Result?.CurrentPointerTarget != null)
+ {
+ GameObject target = GetGameobjectOfTypeFromHirachy(p.Result.CurrentPointerTarget, typeof(AppBarStateController), null, true);
+ if (target == caller)
+ {
+ mainPointer = p;
+ return;
+ }
+ }
+
+ }
+ }
+ }
+
+ ///
+ /// Converts a color object to a RGBA float array, in order to make it possible to tranmit it witch photon.
+ ///
+ ///
+ ///
+ public float[] ColorPhoton(Color color)
+ {
+ float[] arr = new float[4];
+ arr[0] = color.r;
+ arr[1] = color.g;
+ arr[2] = color.b;
+ arr[3] = color.a;
+ return arr;
+ }
+
+ ///
+ /// Return the closest object in the hirachy above the provided gameObject that has a PhotonView. If such an object doesn't exist, null is returned.
+ ///
+ ///
+ ///
+ public static GameObject GetParentWithPhotonView(GameObject gameObject)
+ {
+ if (gameObject == null)
+ {
+ return null;
+ }
+ var view = gameObject.GetComponent();
+ var parent = gameObject.transform.parent?.gameObject;
+ if (view != null)
+ {
+ return gameObject;
+ }
+ else if (parent != null)
+ {
+ return GetParentWithPhotonView(parent);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ ///
+ /// Iterates upwards in the hirachy of gameObject and returns the first GameObject that has the Visualization script attached. Returns null if nothing is found.
+ ///
+ /// The gameObject on which the search should start
+ /// Can be used as a filter. A GameObject can be ignored if it has a object contianed in typesToExclude above or below it
+ /// Check above in the hirachy for filterd types
+ /// Check below in the hirachy for filterd types
+ ///
+ public static GameObject GetGameobjectOfTypeFromHirachy(GameObject gameObject, Type typeToSearch, Type[] typesToExclude = null, bool checkAbove = false, bool checkBelow = false)
+ {
+ //If wished, check if any of the children of the target is of a type that should be excluded
+ if (typesToExclude != null && checkBelow)
+ {
+ foreach (Type type in typesToExclude)
+ {
+ if (gameObject.GetComponentInChildren(type, true) != null)
+ {
+ return null;
+ }
+ }
+ }
+
+ if (gameObject != null)
+ {
+ while (gameObject != null && gameObject.GetComponent(typeToSearch) == null)
+ {
+ //If wished, check if the current object (i.e. a object above in the hirachy of the original target) is of a type that should be excluded
+ if (typesToExclude != null && checkAbove)
+ {
+ foreach (Type type in typesToExclude)
+ {
+ if (gameObject.GetComponent(type) != null)
+ {
+ return null;
+ }
+ }
+ }
+
+ gameObject = gameObject.transform.parent?.gameObject;
+ }
+ if (gameObject != null && gameObject.GetComponent(typeToSearch) != null)
+ {
+ return gameObject;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/ConnectionCurveManager.cs.meta b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/ConnectionCurveManager.cs.meta
new file mode 100644
index 000000000..8e9ab2d89
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/ConnectionCurveManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d723b4c0c823c864fafaa520a546fb4d
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Curve.cs b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Curve.cs
new file mode 100644
index 000000000..e83a35a7d
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Curve.cs
@@ -0,0 +1,228 @@
+using System;
+using UnityEngine;
+using System.Collections.Generic;
+
+///
+/// Contains functions for generating and analyzing 3D curves.
+///
+public abstract class CurveGenerator
+{
+ ///
+ /// Calculates a 3D Bezier curve with the given control points and segmentCount segments.
+ ///
+ public static Vector3[] CalculateBezierCurve(Vector3[] controlPoints, int segmentCount)
+ {
+ Vector3[] points = new Vector3[segmentCount];
+ for (int i = 0; i < segmentCount; i++)
+ {
+ float t = (float)i / (segmentCount-1);
+ points[i] = CalculateBezierPoint(controlPoints,t);
+ }
+ return points;
+ }
+
+ ///
+ /// Calculates the point at t on a 3D Bezier curve with the given control points and 0 <= t <= 1.
+ ///
+ static Vector3 CalculateBezierPoint(Vector3[] controlPoints, float t)
+ {
+ Vector3 result = Vector3.zero;
+ for (int i = 0; i < controlPoints.Length; i++)
+ {
+ result += (float)(BinomCoefficient(controlPoints.Length-1, i) * Math.Pow(1 - t, controlPoints.Length-1 - i) * Math.Pow(t, i)) * controlPoints[i];
+ }
+ return result;
+ }
+
+ ///
+ /// Calculates the binomoial coefficient.
+ ///
+ public static long BinomCoefficient(long n, long k)
+ {
+ if (k > n) { return 0; }
+ if (n == k) { return 1; } // only one way to chose when n == k
+ if (k > n - k) { k = n - k; } // Everything is symmetric around n-k, so it is quicker to iterate over a smaller k than a larger one.
+ long c = 1;
+ for (long i = 1; i <= k; i++)
+ {
+ c *= n--;
+ c /= i;
+ }
+ return c;
+ }
+
+ ///
+ /// Calculates, if a curve has a collision. The curve gets approimated with up to 60 sphere colliders for that.
+ ///
+ public static bool CurveCollsionCheck(Vector3[] curve, GameObject startObject, GameObject goalObject, int layermask = 0b1111111, bool checkEndCollision = true , float distanceToObstacle = 0.2f)
+ {
+ int curveIncrement = (curve.Length - 2) / 60;
+ if (curveIncrement < 1)
+ curveIncrement = 1;
+ int lastChecked = 0;
+
+ //Check from start to the first. This has to be done seperatly, because otherwise the sphere around start would detect collisions behind the object.
+ Collider[] potentialColliders = Physics.OverlapCapsule(curve[0] + (curve[curveIncrement] - curve[0]).normalized * distanceToObstacle, curve[curveIncrement], distanceToObstacle, layermask);
+ foreach (Collider coll in potentialColliders)
+ {
+ if (IsValidCollider(coll, startObject, goalObject, checkEndCollision))
+ return true;
+ }
+
+ for (int i = curveIncrement; i < curve.Length - 1 - curveIncrement; i += curveIncrement)
+ {
+ potentialColliders = Physics.OverlapCapsule(curve[i], curve[i+curveIncrement],distanceToObstacle, layermask);
+ foreach (Collider coll in potentialColliders)
+ {
+ if (IsValidCollider(coll, startObject, goalObject, checkEndCollision))
+ return true;
+ }
+ lastChecked = i + curveIncrement;
+ }
+
+ //Check form the last checked to the end
+ potentialColliders = Physics.OverlapCapsule(curve[lastChecked] , curve[curve.Length - 1] +(curve[lastChecked] - curve[curve.Length - 1]).normalized * distanceToObstacle, distanceToObstacle, layermask);
+ foreach (Collider coll in potentialColliders)
+ {
+ if (IsValidCollider(coll, startObject, goalObject, checkEndCollision))
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Counts the number of collisions a curve has.
+ ///
+ public static int CurveCollsionCount(Vector3[] curve, GameObject start, GameObject goal)
+ {
+ int collisionCount = 0;
+ for (int i = 0; i <= curve.Length - 2; i++)
+ {
+ Vector3 checkDirection = curve[i + 1] - curve[i];
+ float checkLength = Vector3.Distance(curve[i], curve[i + 1]);
+ checkDirection.Normalize();
+
+ Vector3 center = curve[i] + checkDirection * checkLength / 2;
+
+ if (collisonWithObstacle(center, new Vector3(0.2f, 0.2f, checkLength), Quaternion.LookRotation(checkDirection, new Vector3(0, 1, 0)), start, goal))
+ {
+ collisionCount++;
+ }
+ }
+ return collisionCount;
+ }
+
+ ///
+ /// Calculates the length of a curve.
+ ///
+ public static float CurveLength(Vector3[] path)
+ {
+ float length = 0;
+ for (int i = 0; i <= path.Length - 2; i++)
+ {
+ length += Vector3.Distance(path[i], path[i + 1]);
+ }
+ return length;
+ }
+
+ public static Vector3[] IntTripleArrayToCurve(List path, Vector3 start, Vector3 goal, float stepSize)
+ {
+ Vector3[] curve = new Vector3[path.Count + 2];
+ curve[0] = start;
+ for (int i = 1; i < path.Count + 1; i++)
+ {
+ curve[i] = IntTriple.CellToVector(path[i - 1], stepSize);
+ }
+ curve[path.Count + 1] = goal;
+ return curve;
+ }
+
+ ///
+ /// Checks, if a box alligned with the world axis collides with an obstacle
+ ///
+ public static bool collisonWithObstacle(Vector3 center, Vector3 halfExtends, GameObject startObject, GameObject goalObject)
+ {
+ return collisonWithObstacle(center, halfExtends, Quaternion.identity, startObject, goalObject);
+ }
+
+ ///
+ /// Checks, if a box collides with an obstacle. If check end collision is true, a collision with start or goal doesn't count.
+ ///
+ public static bool collisonWithObstacle(Vector3 center, Vector3 halfExtends, Quaternion orientaton, GameObject startObject, GameObject goalObject, int layermask = 0b11111111, bool checkEndCollision = true)
+ {
+ Collider[] potentialColliders = Physics.OverlapBox(center, halfExtends, orientaton, layermask);
+ List actuallColliders = new List();
+
+ //Does the cell collide with the start or goal boundingbox (which is on layer 6)?
+ foreach (Collider collider in potentialColliders)
+ {
+ if (IsValidCollider(collider, startObject, goalObject, checkEndCollision))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ ///
+ /// Gets all valid colliders in the box defined by its center, halfextend and orientation
+ ///
+ public static Collider[] GetCollidorsInBox(Vector3 center, Vector3 halfExtends, Quaternion orientaton, GameObject startObject, GameObject goalObject, int layermask = 0b11111111, bool checkEndCollision = true)
+ {
+ Collider[] potentialColliders = Physics.OverlapBox(center, halfExtends, orientaton, layermask);
+ List actuallColliders = new List();
+
+ //Does the cell collide with the start or goal boundingbox (which is on layer 6)?
+ foreach (Collider collider in potentialColliders)
+ {
+ if (IsValidCollider(collider, startObject, goalObject))
+ {
+ actuallColliders.Add(collider);
+ }
+ }
+ return actuallColliders.ToArray();
+ }
+
+ ///
+ /// Checks if a collider isn't attached to: start or goal, the app bar or an avatar. If checkEndCollision is true it is also checked if it doesn't collide with the start or goal object.
+ ///
+ static private bool IsValidCollider(Collider collider, GameObject startObject, GameObject goalObject, bool checkEndCollision = true)
+ {
+ GameObject root = collider.transform.root.gameObject;
+ if (root != startObject.transform.root.gameObject && root != goalObject.transform.root.gameObject && (root.name.Length < 8 || root.name.Substring(0,7) != "App Bar") && (root.name.Length < 7 || root.name.Substring(0,6) != "Avatar"))
+ {
+ bool collidesWithStart = false;
+ bool collidesWithGoal = false;
+
+ if (checkEndCollision)
+ {
+
+ if (collider is BoxCollider || collider is SphereCollider || collider is CapsuleCollider)
+ {
+ collidesWithStart = (collider.ClosestPoint(startObject.transform.position) - startObject.transform.position).magnitude < 0.1;
+
+ if (!collidesWithStart)
+ {
+ collidesWithGoal = (collider.ClosestPoint(goalObject.transform.position) - goalObject.transform.position).magnitude < 0.1;
+ }
+
+ if (!collidesWithStart && !collidesWithGoal)
+ {
+ return true;
+ }
+ }
+ else
+ {
+ return true;
+ }
+ }
+ else
+ return true;
+
+
+ }
+ return false;
+ }
+
+}
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Curve.cs.meta b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Curve.cs.meta
new file mode 100644
index 000000000..0c7a84ae8
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Curve.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ce7791ebf2929234d91fa9ac834c34a3
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/JoinedCurveGeneration.cs b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/JoinedCurveGeneration.cs
new file mode 100644
index 000000000..176c2bddb
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/JoinedCurveGeneration.cs
@@ -0,0 +1,188 @@
+using System.Collections.Generic;
+using UnityEngine;
+using System;
+using System.Threading.Tasks;
+using Unity.Jobs;
+using HoloToolkit.Unity;
+
+///
+/// Performs the actual calculations for the curves that are managed by the ConnectionCurveManager
+///
+public class JoinedCurveGeneration : Singleton
+{
+ public float standartHeight = 0.2f;
+ SimpleCurveGenerationJob jobData;
+
+
+ ///
+ /// Updates the curves that are provided through the curves list. Can't be a normal update fuction, because it can yield when calculation take too long. Is invoked by the ConnectionCurveManager.
+ ///
+ /// The curve list managed by the ConnectionCurveManager
+ /// The size of the cells for the grid for A* and greedy
+ public async void UpdateAsyc(List curves, float stepSize)
+ {
+ //Specifies, for how many curves memory is alllocated (memory for nativ arrrays has to be manged by hand and UnityJobs require nativ arrays).
+ //If more curves are used than memory is allocated for, the number of allocated curves get increased by allocationSteps.
+ //If there are less curves than curveCountEstimate-1.5*allocationSteps, memory for allocationSteps curves gets freed again.
+ int allocationSteps = 5;
+ int curveCountEstimate = allocationSteps;
+ jobData = new SimpleCurveGenerationJob();
+ jobData.InitialiseArrays(curveCountEstimate);
+
+ try
+ {
+ while (true)
+ {
+ //Check the standart curve and calculate the boundingboxes on the main thread
+ List boxList = new List();
+
+ for (int i = 0; i < curves.Count; i++)
+ {
+ if (curves[i] != null)
+ {
+ //Try to use the standart curve
+ Vector3[] standartCurve = SimpleCurveGerneration.TryToUseStandartCurve(curves[i].start, curves[i].goal, 60);
+ if (standartCurve != null)
+ {
+ curves[i].lineRenderer.positionCount = standartCurve.Length;
+ curves[i].lineRenderer.SetPositions(standartCurve);
+ }
+ else
+ {
+ BoundingBoxes box = SimpleCurveGerneration.CalculateBoundingBoxes(curves[i].start, curves[i].goal);
+ box.curveIndex = i;
+ boxList.Add(box);
+ }
+ }
+ }
+
+ int count = boxList.Count;
+
+ //Are there curently more curves than memory was allocated for?
+ if (count > curveCountEstimate)
+ {
+ jobData.DisposeArrays();
+ curveCountEstimate += allocationSteps;
+ jobData.InitialiseArrays(curveCountEstimate);
+ }
+ //Are there much less curves than memory was allocated for?
+ else if (count < curveCountEstimate - 1.5 * allocationSteps)
+ {
+ jobData.DisposeArrays();
+ curveCountEstimate -= allocationSteps;
+ jobData.InitialiseArrays(curveCountEstimate);
+ }
+
+ //Setup the job, to perform the simple curve calculation multithreaded
+ for (int i = 0; i < count; i++)
+ {
+ int curveIndex = boxList[i].curveIndex;
+ jobData.start[i] = curves[curveIndex].start.transform.position;
+ jobData.goal[i] = curves[curveIndex].goal.transform.position;
+ //The normal copy function is not possible, because boxes and boxList may have diffent lenghtes
+ jobData.boxes[i] = boxList[i];
+ }
+
+
+
+ JobHandle handel = jobData.Schedule(count, 32);
+ handel.Complete();
+
+
+ var tasks = new Dictionary, ConnectionCurve>();
+ //Fetch the results
+ for (int i = 0; i < count; i++)
+ {
+ if (curves[i] != null)
+ {
+ Vector3[] simpleCurve = jobData.ReadResult(i);
+ ConnectionCurve curve = curves[jobData.boxes[i].curveIndex];
+ tasks.Add(JoinedCurve(curve,simpleCurve,stepSize), curve);
+ }
+ }
+
+ //The following actions can't be done in a Unity job, because they are not thread safe.
+ while (tasks.Count > 0)
+ {
+ Task finishedTask = await Task.WhenAny(tasks.Keys);
+ ConnectionCurve connectionCurve = tasks[finishedTask];
+ //connectionCurve can somehow be null here
+ if (connectionCurve != null)
+ {
+ connectionCurve.lineRenderer.positionCount = finishedTask.Result.Length;
+ connectionCurve.lineRenderer.SetPositions(finishedTask.Result);
+ }
+ tasks.Remove(finishedTask);
+ }
+ await Task.Yield();
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.LogError(e.InnerException);
+ }
+ }
+
+ ///
+ /// Calculates a joined curve.
+ ///
+ /// The curve object for which a curve needs to be calculated
+ /// The previosly calculated simple curve
+ /// The size of the cells for the grid for A* and greedy
+ /// The number of segements for the curve
+ ///
+ static async Task JoinedCurve(ConnectionCurve connectionCurve, Vector3[] simpleCurve , float stepSize, int segmentCount = 60)
+ {
+ try
+ {
+ //Check, if the simple curve is collision free
+ if (simpleCurve != null && !CurveGenerator.CurveCollsionCheck(simpleCurve, connectionCurve.start, connectionCurve.goal))
+ {
+ return simpleCurve;
+ }
+ //If not, use A* or Greedy
+ Vector3[] curve;
+ IntTriple startCell = IntTriple.VectorToCell(connectionCurve.start.transform.position, stepSize);
+ IntTriple goalCell = IntTriple.VectorToCell(connectionCurve.goal.transform.position, stepSize);
+ Task> astarTask = AStar.AStarGridSearchAsync(startCell, goalCell, stepSize, connectionCurve.start, connectionCurve.goal);
+ //The A* task can yield its execution, if it takes too long
+ await astarTask;
+ if (astarTask.Result.path != null)
+ {
+ //A* was successful
+ curve = CurveGenerator.IntTripleArrayToCurve(astarTask.Result.path, connectionCurve.start.transform.position, connectionCurve.goal.transform.position, stepSize);
+ }
+ else
+ {
+ Task> greedyTask = Greedy.GreedyGridSearchAsync(startCell, goalCell, stepSize, connectionCurve.start, connectionCurve.goal);
+ await greedyTask;
+ if (greedyTask.Result.path != null)
+ {
+ //Greedy search was successful
+ curve = CurveGenerator.IntTripleArrayToCurve(greedyTask.Result.path, connectionCurve.start.transform.position, connectionCurve.goal.transform.position, stepSize);
+ }
+ else
+ {
+ //All methods failed. Just connect start and goal with the standart curve and accept that it's going to have collisions.
+ curve = SimpleCurveGerneration.StandartCurve(connectionCurve.start.transform.position, connectionCurve.goal.transform.position, segmentCount, 0.5f);
+ }
+ }
+
+ return curve;
+ }
+ catch (Exception e)
+ {
+ Debug.LogError(e.InnerException);
+ return null;
+ }
+ }
+
+ ///
+ /// Disposes the native arrays that were used for the UnityJob, to prevent memory leaks. Native arrays are not cleaned up by the garbage collector.
+ ///
+ private void OnApplicationQuit()
+ {
+ jobData.DisposeArrays();
+ }
+
+}
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/JoinedCurveGeneration.cs.meta b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/JoinedCurveGeneration.cs.meta
new file mode 100644
index 000000000..98bc930e1
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/JoinedCurveGeneration.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 37e76559dd3d342489e206e4eee342ad
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/LineSerialiser.cs b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/LineSerialiser.cs
new file mode 100644
index 000000000..d3db9521f
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/LineSerialiser.cs
@@ -0,0 +1,30 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using i5.VIAProMa.SaveLoadSystem.Core;
+
+public class LineSerialiser : MonoBehaviour, ISerializable
+{
+ ConnectionCurve curve;
+
+ private void Awake()
+ {
+ curve = GetComponent();
+ }
+
+ public void Deserialize(SerializedObject serializedObject)
+ {
+ curve.startID = serializedObject.Strings["startID"];
+ curve.goalID = serializedObject.Strings["goalID"];
+ }
+
+ public SerializedObject Serialize()
+ {
+ SerializedObject serializedObject = new SerializedObject();
+ string startID = curve.start.GetComponent().Id;
+ string goalID = curve.goal.GetComponent().Id;
+ serializedObject.Strings.Add("startID", startID);
+ serializedObject.Strings.Add("goalID",goalID);
+ return serializedObject;
+ }
+}
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/LineSerialiser.cs.meta b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/LineSerialiser.cs.meta
new file mode 100644
index 000000000..325ffc2b8
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/LineSerialiser.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c0d7a2ad11c845a4a8a16ae1c6f40076
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms.meta b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms.meta
new file mode 100644
index 000000000..3f0eac29e
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 51aff82623b2b5440834fcd5af374cc6
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/AStar.cs b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/AStar.cs
new file mode 100644
index 000000000..3f1dace0f
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/AStar.cs
@@ -0,0 +1,176 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using Priority_Queue;
+using System.Threading.Tasks;
+
+///
+/// A class for AStar search that is independent from the graph implementation. Contains an implementation specialised for grid search.
+///
+public class AStar : GridSearch
+{
+ ///
+ /// Starts an AStar search. The graph needs to be provided through the GetNeighbors function.
+ ///
+ public static SearchResult AStarSearch(T start, T goal, Func> GetNeighbors, Func GoalTest, Func Heuristic, Func CostsBetween, bool calculatePath = true)
+ {
+
+
+ SimplePriorityQueue openSet = new SimplePriorityQueue();
+ Dictionary cameFrom = new Dictionary();
+ Dictionary gScore = new Dictionary();
+ openSet.Enqueue(start, 0);
+ gScore.Add(start, Heuristic(start));
+ T current;
+
+ while (openSet.Count != 0)
+ {
+ current = openSet.Dequeue();
+ if (GoalTest(current,goal))
+ {
+ List optimalPath = null;
+ if (calculatePath)
+ optimalPath = ReconstructPath(cameFrom, current);
+
+ return new SearchResult(optimalPath, gScore[current]);
+ }
+
+ List neighbors = GetNeighbors(current);
+
+ foreach (T neighbor in neighbors)
+ {
+ float h = Heuristic(neighbor);
+ float tentative_gScore = gScore[current] + CostsBetween(current,neighbor);
+ float neighboreGScore;
+ if (gScore.TryGetValue(neighbor, out neighboreGScore))
+ {
+ if (tentative_gScore < neighboreGScore)
+ {
+ cameFrom[neighbor] = current;
+ gScore[neighbor] = tentative_gScore;
+ openSet.EnqueueWithoutDuplicates(neighbor, neighboreGScore + h);
+ }
+ }
+ //if neighbore dosn't have a gScore then it's infinit and therefore bigger than tentative_gScore
+ else
+ {
+ cameFrom[neighbor] = current;
+ gScore[neighbor] = tentative_gScore;
+ openSet.EnqueueWithoutDuplicates(neighbor, tentative_gScore + h);
+ }
+ }
+ }
+ if (openSet.Count == 0)
+ {
+ //open set is empty and goal is never reached => no possible path
+ return new SearchResult(new List(), float.PositiveInfinity);
+ }
+ return new SearchResult(null, float.PositiveInfinity);
+ }
+
+ ///
+ /// Starts an AStar search on a 3D grid.
+ ///
+ public static SearchResult AStarGridSearch(IntTriple startCell, IntTriple goalCell, float stepSize, Vector3 goalPosition, GameObject startObject, GameObject goalObject)
+ {
+ return AStarSearch(startCell, goalCell, GetNeighborsGeneratorGrid(stepSize,startObject, goalObject), (x, y) => x == y, HeuristicGeneratorGrid(goalPosition, stepSize), CostsBetweenGeneratorGrid(stepSize));
+ }
+
+ ///
+ /// Starts an async AStar search. The graph needs to be provided through the GetNeighbors function. The search waits a frame, when it needed more than 7 ms and cancels the search if it needs more than 10 frames.
+ ///
+ public static async Task> AStarSearchAsync(T start, T goal, Func> GetNeighbors, Func GoalTest, Func Heuristic, Func CostsBetween, bool calculatePath = true)
+ {
+ SimplePriorityQueue openSet = new SimplePriorityQueue();
+ Dictionary cameFrom = new Dictionary();
+ Dictionary gScore = new Dictionary();
+ openSet.Enqueue(start, 0);
+ gScore.Add(start, Heuristic(start));
+ T current;
+ int frameCount = 0;
+ DateTime timeAtBeginOfFrame = DateTime.Now; ;
+
+ while (openSet.Count != 0)
+ {
+ if ((DateTime.Now - timeAtBeginOfFrame).TotalMilliseconds > 7)
+ {
+ frameCount++;
+ if (frameCount > 10)
+ {
+ Debug.Log("Too Long");
+ return new SearchResult(null,float.NaN);
+ }
+ await Task.Yield();
+ timeAtBeginOfFrame = DateTime.Now;
+ }
+
+ current = openSet.Dequeue();
+ if (GoalTest(current, goal))
+ {
+ List optimalPath = null;
+ if (calculatePath)
+ optimalPath = ReconstructPath(cameFrom, current);
+
+ return new SearchResult(optimalPath, gScore[current]);
+ }
+
+ List neighbors = GetNeighbors(current);
+
+ foreach (T neighbor in neighbors)
+ {
+ float h = Heuristic(neighbor);
+ float tentative_gScore = gScore[current] + CostsBetween(current, neighbor);
+ float neighboreGScore;
+ if (gScore.TryGetValue(neighbor, out neighboreGScore))
+ {
+ if (tentative_gScore < neighboreGScore)
+ {
+ cameFrom[neighbor] = current;
+ gScore[neighbor] = tentative_gScore;
+ openSet.EnqueueWithoutDuplicates(neighbor, neighboreGScore + h);
+ }
+ }
+ //if neighbore dosn't have a gScore then it's infinit and therefore bigger than tentative_gScore
+ else
+ {
+ cameFrom[neighbor] = current;
+ gScore[neighbor] = tentative_gScore;
+ openSet.EnqueueWithoutDuplicates(neighbor, tentative_gScore + h);
+ }
+ }
+ }
+ if (openSet.Count == 0)
+ {
+ //open set is empty and goal is never reached => no possible path
+ return new SearchResult(new List(), float.PositiveInfinity);
+ }
+ return new SearchResult(null, float.PositiveInfinity);
+ }
+
+ ///
+ /// Starts an async AStar search on a 3D grid. The search waits a frame, when it needed more than 7 ms and cancels the search if it needs more than 10 frames.
+ ///
+ public static Task> AStarGridSearchAsync(IntTriple startCell, IntTriple goalCell, float stepSize, GameObject startObject, GameObject goalObject)
+ {
+ return AStarSearchAsync(startCell, goalCell, GetNeighborsGeneratorGrid(stepSize, startObject, goalObject), (x, y) => x == y, HeuristicGeneratorGrid(goalObject.transform.position, stepSize), CostsBetweenGeneratorGrid(stepSize));
+ }
+
+ ///
+ /// Generates the path from cameFrom dictonary and the last visited node.
+ ///
+ private static List ReconstructPath(Dictionary cameFrom, T current)
+ {
+ List totalPath = new List();
+ totalPath.Add(current);
+
+ T ancestor;
+ while (cameFrom.TryGetValue(current, out ancestor))
+ {
+ totalPath.Add(ancestor);
+ current = ancestor;
+ }
+ totalPath.Reverse();
+ return totalPath;
+ }
+}
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/AStar.cs.meta b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/AStar.cs.meta
new file mode 100644
index 000000000..b9eead9d9
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/AStar.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 88da9baf762891a4e83b264117ef1ec5
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/GreedySearch.cs b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/GreedySearch.cs
new file mode 100644
index 000000000..6ec4c2163
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/GreedySearch.cs
@@ -0,0 +1,139 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using Priority_Queue;
+using System.Threading.Tasks;
+
+///
+/// A class for greedy search that is independent from the graph implementation. Contains an implementation specialised for grid search.
+///
+public class Greedy : GridSearch
+{
+ ///
+ /// Starts an greedy search. The graph needs to be provided through the GetNeighbors function.
+ ///
+ public static SearchResult GreedySearch(T start, T goal, Func> GetNeighbors, Func GoalTest, Func Heuristic, Func CostsBetween)
+ {
+ int count = 0;
+ float pathCosts = 0;
+ List path = new List();
+ path.Add(start);
+ T current = start;
+ T cheapestNeigbor = start;
+ float lowestCosts = float.PositiveInfinity;
+
+ while (!GoalTest(current, goal) && count < 300)
+ {
+ List neigbors = GetNeighbors(current);
+ foreach (T neighbor in neigbors)
+ {
+ float costs = Heuristic(neighbor);
+ if (costs < lowestCosts && !path.Contains(neighbor))
+ {
+ cheapestNeigbor = neighbor;
+ lowestCosts = costs;
+ }
+ }
+ lowestCosts = float.PositiveInfinity;
+ pathCosts += CostsBetween(current, cheapestNeigbor);
+ current = cheapestNeigbor;
+ path.Add(current);
+ count++;
+ }
+ return new SearchResult(path, pathCosts);
+ }
+
+ ///
+ /// Starts an greedy search on a 3D grid.
+ ///
+ public static SearchResult GreedyGridSearch(IntTriple startCell, IntTriple goalCell, float stepSize, Vector3 goalPosition, GameObject startObject, GameObject goalObject)
+ {
+ return GreedySearch(startCell, goalCell, GetNeighborsGeneratorGrid(stepSize, startObject, goalObject), (x, y) => x == y, HeuristicGeneratorGrid(goalPosition, stepSize), CostsBetweenGeneratorGrid(stepSize));
+ }
+
+ ///
+ /// Starts an async greedy search. The graph needs to be provided through the GetNeighbors function. The search waits a frame, when it needed more than 7 ms and cancels the search if it needs more than 10 frames.
+ ///
+ public static async Task> GreedySearchAsync(T start, T goal, Func> GetNeighbors, Func GoalTest, Func Heuristic, Func CostsBetween, bool calculatePath = true)
+ {
+ float pathCosts = 0;
+ List path = new List();
+ path.Add(start);
+ T current = start;
+ T cheapestNeigbor = start;
+ float lowestCosts = float.PositiveInfinity;
+ int frameCount = 0;
+ DateTime timeAtBeginOfFrame = DateTime.Now;
+
+ while (!GoalTest(current, goal))
+ {
+ if ((DateTime.Now - timeAtBeginOfFrame).TotalMilliseconds > 7)
+ {
+ frameCount++;
+ if (frameCount > 3)
+ {
+ Debug.Log("Too Long");
+ return new SearchResult(null, float.NaN);
+ }
+ await Task.Yield();
+ timeAtBeginOfFrame = DateTime.Now;
+ }
+
+ List neigbors = GetNeighbors(current);
+ foreach (T neighbor in neigbors)
+ {
+ float costs = Heuristic(neighbor);
+ if (costs < lowestCosts && !path.Contains(neighbor))
+ {
+ cheapestNeigbor = neighbor;
+ lowestCosts = costs;
+ }
+ }
+ lowestCosts = float.PositiveInfinity;
+ pathCosts += CostsBetween(current, cheapestNeigbor);
+ current = cheapestNeigbor;
+ path.Add(current);
+ }
+ return new SearchResult(path, pathCosts);
+ }
+
+ ///
+ /// Starts an async greedy search on a 3D grid. The search waits a frame, when it needed more than 7 ms and cancels the search if it needs more than 10 frames.
+ ///
+ public static Task> GreedyGridSearchAsync(IntTriple startCell, IntTriple goalCell, float stepSize, GameObject startObject, GameObject goalObject)
+ {
+ return GreedySearchAsync(startCell, goalCell, GetNeighborsGeneratorGrid(stepSize, startObject, goalObject), (x, y) => x == y, HeuristicGeneratorGrid(goalObject.transform.position, stepSize), CostsBetweenGeneratorGrid(stepSize));
+ }
+
+ ///
+ /// Removes parts with high point density.
+ ///
+ public static Vector3[] PostProcessing(Vector3[] path, float scanCubeSize)
+ {
+ List refinedPath = new List();
+
+ Vector3 lowerLeftCorner = new Vector3();
+ Vector3 upperRigthCorner = new Vector3();
+
+ foreach (Vector3 point in path)
+ {
+ lowerLeftCorner = new Vector3(point.x - scanCubeSize / 2, point.y - scanCubeSize / 2, point.z);
+ upperRigthCorner = lowerLeftCorner + new Vector3(scanCubeSize, scanCubeSize, scanCubeSize);
+
+ int pointCount = 0;
+ foreach (Vector3 point2 in path)
+ {
+ if (point2.x >= lowerLeftCorner.x && point2.y >= lowerLeftCorner.y && point2.z >= lowerLeftCorner.z
+ && point2.x <= upperRigthCorner.x && point2.y <= upperRigthCorner.y && point2.z <= upperRigthCorner.z)
+ pointCount++;
+ }
+ if (pointCount <= 3)
+ {
+ refinedPath.Add(point);
+ }
+ pointCount = 0;
+ }
+
+ return refinedPath.ToArray();
+ }
+}
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/GreedySearch.cs.meta b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/GreedySearch.cs.meta
new file mode 100644
index 000000000..d13fed5bf
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/GreedySearch.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 89ba56be972fb744bbc6e92a213adfe6
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/GridSearchInterface.cs b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/GridSearchInterface.cs
new file mode 100644
index 000000000..6b0ab92a3
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/GridSearchInterface.cs
@@ -0,0 +1,97 @@
+using System.Collections.Generic;
+using UnityEngine;
+using static IntTriple;
+using System;
+
+///
+/// Provides methods for classes that search pathes in the continuous world by using a 3D grid.
+///
+public abstract class GridSearch : CurveGenerator
+{
+ ///
+ /// The result of a grid search operation. Contains the path and the path length.
+ ///
+ public struct GridSearchResult
+ {
+ public List path { get; set; }
+ public float costs { get; set; }
+
+ public GridSearchResult(List path, float length)
+ {
+ this.path = path;
+ this.costs = length;
+ }
+ }
+
+ ///
+ /// The result of a graph search operation. Contains the path and the path length.
+ ///
+ public struct SearchResult
+ {
+ public List path { get; set; }
+ public float costs { get; set; }
+
+ public SearchResult(List path, float length)
+ {
+ this.path = path;
+ this.costs = length;
+ }
+ }
+
+ ///
+ /// Generates a function that only takes a cell and then gets the neighbors of it by projecting a cube with the length stepSize to every side and then checks for collisions.
+ ///
+ public static Func> GetNeighborsGeneratorGrid(float stepSize, GameObject startObject, GameObject goalObject)
+ {
+ List GetNeighbors(IntTriple node)
+ {
+ List neighbors = new List();
+
+ for (int x = -1; x <= 1; x += 1)
+ {
+ for (int y = -1; y <= 1; y += 1)
+ {
+ for (int z = -1; z <= 1; z += 1)
+ {
+ if ((x != 0 || y != 0 || z != 0)) //dont return the node as its own neighbor
+ //&& (node.y + y >= 0)) //dont bent the path below the ground
+ {
+ IntTriple cell = new IntTriple(node.x + x, node.y + y, node.z + z);
+
+ if (!collisonWithObstacle(CellToVector(cell, stepSize), new Vector3(stepSize / 2, stepSize / 2, stepSize / 2), startObject, goalObject))
+ {
+ neighbors.Add(cell);
+ }
+ }
+ }
+ }
+ }
+ return neighbors;
+ }
+ return GetNeighbors;
+ }
+
+ ///
+ /// Generates a heuristic function for the search on a grid with the cell size stepSize.
+ ///
+ public static Func HeuristicGeneratorGrid(Vector3 goal, float stepSize)
+ {
+ float Heuristic(IntTriple cell)
+ {
+ return Vector3.Distance(CellToVector(cell, stepSize), goal);
+ }
+ return Heuristic;
+ }
+
+ ///
+ /// Generates a function that calculates the cost between two adjacent cells.
+ ///
+ public static Func CostsBetweenGeneratorGrid(float stepSize)
+ {
+ float CostsBetween(IntTriple cell1, IntTriple cell2)
+ {
+ return Vector3.Distance(CellToVector(cell1, stepSize), CellToVector(cell2, stepSize));
+ }
+ return CostsBetween;
+ }
+}
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/GridSearchInterface.cs.meta b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/GridSearchInterface.cs.meta
new file mode 100644
index 000000000..716021d3f
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/GridSearchInterface.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f977f87699393e2408334fdee7b0dc43
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/intTriple.cs b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/intTriple.cs
new file mode 100644
index 000000000..88c3b354f
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/intTriple.cs
@@ -0,0 +1,86 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+///
+/// A triple of type int. Contains functions to use it to store and manage cells for a 3D grid.
+///
+public class IntTriple
+{
+ public int x;
+ public int y;
+ public int z;
+
+ public IntTriple(int int1, int int2, int int3)
+ {
+ x = int1;
+ y = int2;
+ z = int3;
+ }
+
+ public IntTriple(IntTriple triple)
+ {
+ x = triple.x;
+ y = triple.y;
+ z = triple.z;
+ }
+
+ public static IntTriple operator +(IntTriple triple1, IntTriple triple2)
+ {
+ return new IntTriple(triple1.x + triple2.x, triple1.y + triple2.y, triple1.z + triple2.z);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj == null || (obj as IntTriple) == null) //if the object is null or the cast fails
+ return false;
+ else
+ {
+ IntTriple triple = (IntTriple)obj;
+ return x == triple.x && y == triple.y && z == triple.z;
+ }
+ }
+ public static bool operator ==(IntTriple triple1, IntTriple triple2)
+ {
+ return triple1.Equals(triple2);
+ }
+
+ public static bool operator !=(IntTriple triple1, IntTriple triple2)
+ {
+ return !(triple1.Equals(triple2));
+ }
+ public override int GetHashCode()
+ {
+ return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode();
+ }
+
+ public static IntTriple operator *(IntTriple triple, int scalar)
+ {
+ return new IntTriple(triple.x * scalar, triple.y * scalar , triple.z * scalar);
+ }
+
+ public static IntTriple operator /(IntTriple triple, int scalar)
+ {
+ return new IntTriple(triple.x / scalar, triple.y / scalar, triple.z / scalar);
+ }
+
+ ///
+ /// All conversion between cells(IntTriples) and other search related types
+ ///
+ public static Vector3 CellToVector(IntTriple triple, float stepSize)
+ {
+ return new Vector3(triple.x, triple.y, triple.z) *stepSize + new Vector3(stepSize/2,stepSize/2,stepSize/2);
+ }
+
+ ///
+ /// Calculates the corresponding cell on the grid
+ ///
+ public static IntTriple VectorToCell(Vector3 vector, float stepSize)
+ {
+ Vector3 inverseVector = vector /stepSize;
+ //Negativ values have to be floored instead of just casted because otherwise (-0.9,0,0) -> (0,0,0) and (0.9,0,0) -> (0,0,0) for example
+ return new IntTriple( inverseVector.x >= 0 ? (int)inverseVector.x : Mathf.FloorToInt(inverseVector.x),
+ inverseVector.y >= 0 ? (int)inverseVector.y : Mathf.FloorToInt(inverseVector.y),
+ inverseVector.z >= 0 ? (int)inverseVector.z : Mathf.FloorToInt(inverseVector.z));
+ }
+}
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/intTriple.cs.meta b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/intTriple.cs.meta
new file mode 100644
index 000000000..82fc57cc5
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/Search Algorithms/intTriple.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: aa151362f6f9ed745a2bf41e34cc7df5
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Frontend/VIAProMa/Assets/Scripts/Connection Curves/SimpleCurveGeneration.cs b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/SimpleCurveGeneration.cs
new file mode 100644
index 000000000..590b7618f
--- /dev/null
+++ b/Frontend/VIAProMa/Assets/Scripts/Connection Curves/SimpleCurveGeneration.cs
@@ -0,0 +1,1145 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using System.Threading.Tasks;
+using Unity.Jobs;
+using Unity.Collections;
+
+public struct BoundingBoxes
+{
+ public Vector3 minPointAbove;
+ public Vector3 maxPointAbove;
+ public Vector3 minPointSide;
+ public Vector3 maxPointSide;
+ public int curveIndex;
+}
+
+
+public class SimpleCurveGerneration : CurveGenerator
+{
+ public static float distanceToObstacle = 0.2f;
+
+ ///
+ /// Generates a Bézier curve from start to goal, with two additional controllpoints.
+ ///
+ public static Vector3[] StandartCurve(Vector3 start, Vector3 goal, int segmentCount, float height)
+ {
+ float higherOne = start.y > goal.y ? start.y : goal.y;
+
+ Vector3 startAdjusted = new Vector3(start.x, higherOne, start.z);
+ Vector3 goalAdjusted = new Vector3(goal.x, higherOne, goal.z);
+ Vector3 direction = goalAdjusted - startAdjusted;
+ direction.Normalize();
+ float distance = Vector3.Distance(startAdjusted, goalAdjusted);
+ Vector3 center = startAdjusted + direction * distance / 2;
+
+ return CalculateBezierCurve(new Vector3[] { start, startAdjusted + direction * distance / 2.5f + new Vector3(0, height, 0), goalAdjusted - direction * distance / 2.5f + new Vector3(0, height, 0), goal }, 50);
+ }
+
+ ///
+ /// Generates a standart curve. If it is collision free, it gets returned. If not, null is returned
+ ///
+ public static Vector3[] TryToUseStandartCurve(GameObject startObject, GameObject goalObject, int curveSegmentCount)
+ {
+ //Priority 1: Try to draw the standart curve
+ Vector3 start = startObject.transform.position;
+ Vector3 goal = goalObject.transform.position;
+ Vector3[] standartCurve = StandartCurve(start, goal, curveSegmentCount, 0.5f);
+ if (!CurveCollsionCheck(standartCurve, startObject, goalObject))
+ {
+ return standartCurve;
+ }
+ return null;
+ }
+
+ ///
+ /// Calculates two boundingboxes for a curve from start to goal: one for an curve that goes over the box and one that goes around it
+ ///
+ public static BoundingBoxes CalculateBoundingBoxes(GameObject startObject, GameObject goalObject)
+ {
+ Vector3 start = startObject.transform.position;
+ Vector3 goal = goalObject.transform.position;
+
+ //float higherOne = start.y > goal.y ? start.y : goal.y;
+
+
+
+ Vector3 direction = goal - start;
+ direction.Normalize();
+
+ float distance = Vector3.Distance(start, goal);
+
+ Vector3 center = start + direction * distance / 2;
+
+ //TODO put in parameter
+ float standartHeight = 0.5f;
+
+ //Genenerating the standart curve didn't work due to collsions. Try to set the controllpoints so, that no collisions occure
+
+ //Sets min and max in such a way that they include as many of the obstacles as possible but never start or goal
+ void SetMinMax(Collider[] colliders, ref Vector3 min, ref Vector3 max)
+ {
+ foreach (Collider collider in colliders)
+ {
+ min = Vector3.Min(min, collider.bounds.min);
+ max = Vector3.Max(max, collider.bounds.max);
+ float correctionOffset = distance * 0.1f;
+
+ if (start.x >= min.x && start.z >= min.z && start.x <= max.x && start.z <= max.z)
+ {
+ Vector3 startGoal = goal - start;
+ Vector2 correction = new Vector2(startGoal.x, startGoal.z);
+ correction.Normalize();
+ if (Mathf.Abs(correction.x) > Mathf.Abs(correction.y))
+ correction = new Vector2(Mathf.Sign(correction.x), 0);
+ else
+ correction = new Vector2(0, Mathf.Sign(correction.y));
+ if (correction.x < 0)
+ max.x = start.x - correctionOffset;
+ else if (correction.y < 0)
+ max.z = start.z - correctionOffset;
+ else if (correction.x > 0)
+ min.x = start.x + correctionOffset;
+ else
+ min.z = start.z + correctionOffset;
+ }
+ if (goal.x >= min.x && goal.z >= min.z && goal.x <= max.x && goal.z <= max.z)
+ {
+ Vector3 goalStart = start - goal;
+ Vector2 correction = new Vector2(goalStart.x, goalStart.z);
+ correction.Normalize();
+ if (Mathf.Abs(correction.x) > Mathf.Abs(correction.y))
+ correction = new Vector2(Mathf.Sign(correction.x), 0);
+ else
+ correction = new Vector2(0, Mathf.Sign(correction.y));
+ if (correction.x < 0)
+ max.x = goal.x - correctionOffset;
+ else if (correction.y < 0)
+ max.z = goal.z - correctionOffset;
+ else if (correction.x > 0)
+ min.x = goal.x + correctionOffset;
+ else
+ min.z = goal.z + correctionOffset;
+ }
+ }
+ }
+ void ScanForObstaclesAbove(ref Vector3 min, ref Vector3 max)
+ {
+ float lowerY = start.y < goal.y ? start.y : goal.y;
+ Vector3 directionAdjusted = new Vector3(direction.x, 0, direction.z);
+ directionAdjusted.Normalize();
+ float distanceAdjusted = (new Vector3(start.x, 0, start.z) - new Vector3(goal.x, 0, goal.z)).magnitude;
+ Vector3 centerAdjusted = new Vector3(start.x, lowerY, start.z) + directionAdjusted * distanceAdjusted / 2;
+ Vector3 startBoxHalfExtend = new Vector3(1.1f * distanceToObstacle, (Math.Abs(start.y - goal.y) + standartHeight + distanceToObstacle * 3) / 2, distance / 2.1f);
+
+ Collider[] ReScancolliders = GetCollidorsInBox(centerAdjusted + new Vector3(0, startBoxHalfExtend.y, 0),
+ startBoxHalfExtend, Quaternion.LookRotation(directionAdjusted, Vector3.up), startObject, goalObject);
+ SetMinMax(ReScancolliders, ref min, ref max);
+ int oldLength = ReScancolliders.Length;
+ int i = 1;
+ bool newObstacles = false;
+ do
+ {
+ newObstacles = false;
+ startBoxHalfExtend.y = (max.y + 3 * distanceToObstacle) / 2;
+ ReScancolliders = GetCollidorsInBox(centerAdjusted + new Vector3(0, startBoxHalfExtend.y, 0),
+ startBoxHalfExtend, Quaternion.LookRotation(directionAdjusted, Vector3.up), startObject, goalObject);
+ ReScancolliders = GetCollidorsInBox(centerAdjusted + new Vector3(0, startBoxHalfExtend.y, 0), startBoxHalfExtend, Quaternion.LookRotation(directionAdjusted, Vector3.up), startObject, goalObject);
+ if (ReScancolliders.Length > oldLength)
+ {
+ SetMinMax(ReScancolliders, ref min, ref max);
+ newObstacles = true;
+ }
+ oldLength = ReScancolliders.Length;
+ i++;
+ } while (i <= 100 && newObstacles);
+
+ }
+ void ScanForObstaclesSide(ref Vector3 min, ref Vector3 max)
+ {
+ Vector3 normal = Vector3.Cross(direction, Vector3.up);
+ normal.Normalize();
+ Vector3 up = Vector3.Cross(direction, normal);
+ if (up.y < 0)
+ up *= -1;
+ Vector3 startBoxHalfExtend = new Vector3(distanceToObstacle, (standartHeight + distanceToObstacle) / 2, distance / 2.1f);
+
+ //Scan with the starting box
+ Collider[] ReScancolliders = GetCollidorsInBox(center + up * startBoxHalfExtend.y, startBoxHalfExtend, Quaternion.LookRotation(direction, up), startObject, goalObject);
+ SetMinMax(ReScancolliders, ref min, ref max);
+
+ //Rescan as long as new collider show up or the maximal number of scans is reached
+ int oldLength = ReScancolliders.Length;
+ int i = 1;
+ bool newObstacles = false;
+ do
+ {
+ newObstacles = false;
+ Vector3 boxCenter = min + (max - min) * 0.5f;
+ Vector3 halfExtend = max - min + new Vector3(10 * distanceToObstacle, 0, 10 * distanceToObstacle);
+ halfExtend.y = standartHeight + distanceToObstacle;
+ halfExtend /= 2;
+ boxCenter.y = halfExtend.y;
+ ReScancolliders = GetCollidorsInBox(boxCenter, halfExtend, Quaternion.identity, startObject, goalObject);
+ if (ReScancolliders.Length > oldLength)
+ {
+ SetMinMax(ReScancolliders, ref min, ref max);
+ newObstacles = true;
+ }
+ oldLength = ReScancolliders.Length;
+ i++;
+ }
+ while (i <= 100 && newObstacles);
+ }
+ //Generate bounding box for above:
+ Vector3 minPointAbove = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
+ Vector3 maxPointAbove = new Vector3(float.MinValue, float.MinValue, float.MinValue);
+
+ ScanForObstaclesAbove(ref minPointAbove, ref maxPointAbove);
+ Vector3 extendVector = new Vector3(distanceToObstacle, distanceToObstacle, distanceToObstacle);
+ minPointAbove -= extendVector;
+ maxPointAbove += extendVector;
+
+ //Generate bounding box for the sides:
+ Vector3 minPointSide = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
+ Vector3 maxPointSide = new Vector3(float.MinValue, float.MinValue, float.MinValue);
+
+ ScanForObstaclesSide(ref minPointSide, ref maxPointSide);
+ minPointSide -= extendVector;
+ maxPointSide += extendVector;
+ BoundingBoxes result = new BoundingBoxes();
+ result.minPointAbove = minPointAbove;
+ result.maxPointAbove = maxPointAbove;
+ result.minPointSide = minPointSide;
+ result.maxPointSide = maxPointSide;
+ return result;
+ }
+
+ ///
+ /// Calculates a simple curve from start to goal with the given bounding boxes.
+ ///
+ public static Vector3[] StartGeneration(Vector3 start, Vector3 goal, BoundingBoxes boundingBoxes , int curveSegmentCount)
+ {
+ float standartHeight = 0.5f;
+
+ Vector3[] intersectionPointsAbove = calculateControllpointsAbove(start,goal, boundingBoxes.minPointAbove, boundingBoxes.maxPointAbove);
+ Vector3[] intersectionPointsSide = calculateIntersectionSide(start,goal, boundingBoxes.minPointSide, boundingBoxes.maxPointSide,standartHeight);
+
+
+
+ float distanceAbove = CurveLength(new Vector3[] { start, intersectionPointsAbove[0], intersectionPointsAbove[1], goal});
+ float distanceSide;
+ if (intersectionPointsSide.Length == 1)
+ distanceSide = CurveLength(new Vector3[] { start, intersectionPointsSide[0], goal });
+ else if(intersectionPointsSide.Length == 2)
+ distanceSide = CurveLength(new Vector3[] { start, intersectionPointsSide[0], intersectionPointsSide[1], goal });
+ else
+ return StandartCurve(start,goal,curveSegmentCount,standartHeight);
+
+ Vector3[] controllPoints = new Vector3[0];
+ if (distanceAbove < 1.5 * distanceSide)
+ {
+ return CalculateJoinedBezierCurve(start, intersectionPointsAbove, goal, curveSegmentCount);
+ }
+ else
+ {
+ return CalculateJoinedBezierCurve(start, intersectionPointsSide, goal, curveSegmentCount);
+ }
+
+ }
+
+ ///
+ /// Calculates the additional control points for a curve that goes from start to goal over the bounding box defined by min and max
+ ///
+ public static Vector3[] calculateControllpointsAbove(Vector3 start, Vector3 goal, Vector3 minPoint, Vector3 maxPoint)
+ {
+ Vector3 startOnMaxHeight = new Vector3(start.x, maxPoint.y, start.z);
+ Vector3 direction = goal - start;
+ Vector3 directionAdjusted = new Vector3(direction.x, 0, direction.z);
+ directionAdjusted.Normalize();
+ //Calculate the controll points for the way above
+ //calculate the potential intersections from the line spanned by startOnMaxHeight+l*direction with the 4 lines that form the rectangle spanned by min and max
+ Vector3[] potentialPoints = new Vector3[4];
+
+ potentialPoints[0] = startOnMaxHeight + (minPoint.z - start.z) / directionAdjusted.z * directionAdjusted;
+ potentialPoints[1] = startOnMaxHeight + (minPoint.x - start.x) / directionAdjusted.x * directionAdjusted;
+
+ potentialPoints[2] = startOnMaxHeight + (maxPoint.z - start.z) / directionAdjusted.z * directionAdjusted;
+ potentialPoints[3] = startOnMaxHeight + (maxPoint.x - start.x) / directionAdjusted.x * directionAdjusted;
+
+
+
+ bool differentValue = true;
+
+ //Check if there is more than one valid intersection
+ foreach (Vector3 point in potentialPoints)
+ {
+ Vector3 firstReal = new Vector3(float.NaN, float.NaN, float.NaN);
+
+ if (!float.IsNaN(point.x))
+ {
+ if (!float.IsNaN(firstReal.x))
+ {
+ firstReal = point;
+ }
+ else
+ {
+ differentValue &= VecEqVec(point, firstReal);
+ }
+ }
+ }
+
+ Vector3[] intersectionPointsAbove = new Vector3[2];
+ intersectionPointsAbove[0] = new Vector3(float.NaN, float.NaN, float.NaN);
+ intersectionPointsAbove[1] = new Vector3(float.NaN, float.NaN, float.NaN);
+
+ foreach (Vector3 point in potentialPoints)
+ {
+ //Is the vec not NaN and inside the rectangle?
+ if (!float.IsNaN(point.x) && VecGreaterEqVec(point, minPoint) && VecSmallerEqVec(point, maxPoint))
+ {
+ if (float.IsNaN(intersectionPointsAbove[0].x))
+ {
+ intersectionPointsAbove[0] = point;
+ }
+ else if (!differentValue || !VecEqVec(point, intersectionPointsAbove[0]))
+ {
+ intersectionPointsAbove[1] = point;
+ }
+ }
+ }
+
+
+
+ //cp1 has to be the one that is closer to start
+ if (Vector3.Distance(start, intersectionPointsAbove[0]) > Vector3.Distance(start, intersectionPointsAbove[1]))
+ {
+ Vector3 temp = intersectionPointsAbove[0];
+ intersectionPointsAbove[0] = intersectionPointsAbove[1];
+ intersectionPointsAbove[1] = temp;
+ }
+
+ return intersectionPointsAbove;
+ }
+
+ ///
+ /// Calculates the additional control points for a curve that goes from start to goal around the bounding box defined by min and max
+ ///
+ public static Vector3[] calculateIntersectionSide(Vector3 start, Vector3 goal, Vector3 minPoint, Vector3 maxPoint, float standartHeight)
+ {
+ Vector2 CalculatePlacmentToBoundingbox(Vector3 point, Vector3 min, Vector3 max)
+ {
+ Vector3 extendVector = new Vector3(distanceToObstacle, distanceToObstacle, distanceToObstacle);
+ min += extendVector;
+ max -= extendVector;
+
+ Vector2 pointVec2 = new Vector2(point.x, point.z);
+ Vector2 minVec2 = new Vector2(min.x, min.z);
+ Vector2 maxVec2 = new Vector2(max.x, max.z);
+
+ Vector2 placment = new Vector2();
+ if (pointVec2.x < minVec2.x)
+ placment.x = 0;
+ else
+ {
+ if (pointVec2.x < maxVec2.x)
+ placment.x = 1;
+ else
+ placment.x = 2;
+ }
+
+ if (pointVec2.y < minVec2.y)
+ placment.y = 0;
+ else
+ {
+ if (pointVec2.y < maxVec2.y)
+ placment.y = 1;
+ else
+ placment.y = 2;
+ }
+ return placment;
+ }
+
+
+ //Calculate the controll points at the left/right
+
+ float higherY = Mathf.Max(start.y , goal.y);
+
+ //Determine the collsion points for left/right
+ Vector3[,] edgePoints = new Vector3[3,3];
+ edgePoints[0,0] = new Vector3(minPoint.x, higherY + standartHeight, minPoint.z);
+ edgePoints[0,2] = new Vector3(minPoint.x, higherY + standartHeight, maxPoint.z);
+ edgePoints[2,0] = new Vector3(maxPoint.x, higherY + standartHeight, minPoint.z);
+ edgePoints[2,2] = new Vector3(maxPoint.x, higherY + standartHeight, maxPoint.z);
+
+
+
+ Dictionary> edgesSorted = new Dictionary>(); //edgesSorted[false] yields all edges left from the line between start and goal and edgesSorted[true] all right
+ edgesSorted.Add(false, new List());
+ edgesSorted.Add(true, new List());
+
+ List intersectionPointsSide = new List();
+
+ Vector2 startPlacment = CalculatePlacmentToBoundingbox(start, minPoint, maxPoint);
+ Vector2 goalPlacment = CalculatePlacmentToBoundingbox(goal, minPoint, maxPoint);
+ Vector2 currentPosition = startPlacment;
+
+ Vector2 TryDirection(Vector2 curr, Vector2 dir)
+ {
+ curr += dir;
+ if (curr.x < 0 || curr.x > 2 || curr.y < 0 || curr.y > 2 || (curr.x == 1 && curr.y == 1))
+ {
+ return new Vector2(float.NaN, float.NaN);
+ }
+ else
+ {
+ return curr;
+ }
+ }
+ Vector2 NextDirection(Vector2 dir)
+ {
+ if (dir.x == -1)
+ return new Vector2(0, 1);
+ else if (dir.y == 1)
+ return new Vector2(1, 0);
+ else if (dir.x == 1)
+ return new Vector2(0, -1);
+ else
+ return new Vector2(float.NaN,float.NaN);
+ }
+
+ //Is one of them inside the box?
+ if (startPlacment == new Vector2(1, 1) || goalPlacment == new Vector2(1, 1))
+ return new Vector3[0];
+
+ Vector2 oldPosition = currentPosition;
+ Vector2 nextPosition = currentPosition;
+ for (Vector2 dir = new Vector2(-1, 0); !float.IsNaN(dir.x); dir = NextDirection(dir))
+ {
+ nextPosition = TryDirection(currentPosition, dir);
+ if (!float.IsNaN(nextPosition.x))
+ {
+ currentPosition = nextPosition;
+ //Path 1
+ Vector2 oldDir = dir;
+ Vector2 nextDir = new Vector2(-1, 0);
+ while (currentPosition != goalPlacment)
+ {
+ for (nextDir = new Vector2(-1, 0); !float.IsNaN(nextDir.x); nextDir = NextDirection(nextDir))
+ {
+ nextPosition = TryDirection(currentPosition,nextDir);
+ if (!float.IsNaN(nextPosition.x) && nextPosition != oldPosition)
+ {
+ oldPosition = currentPosition;
+ currentPosition = nextPosition;
+ if (oldDir != nextDir)
+ {
+ edgesSorted[false].Add(edgePoints[(int)oldPosition.x, (int)oldPosition.y]);
+ }
+ oldDir = nextDir;
+ break;
+ }
+ }
+ }
+
+ //Path 2
+ //find new start direction
+
+ for (nextDir = new Vector2(-1, 0); !float.IsNaN(nextDir.x); nextDir = NextDirection(nextDir))
+ {
+ if (!float.IsNaN(TryDirection(startPlacment, nextDir).x) && nextDir != dir)
+ {
+ break;
+ }
+ }
+ //go path 2
+ currentPosition = TryDirection(startPlacment, nextDir);
+ oldDir = nextDir;
+ oldPosition = startPlacment;
+ while (currentPosition != goalPlacment)
+ {
+ for (nextDir = new Vector2(-1, 0); !float.IsNaN(nextDir.x); nextDir = NextDirection(nextDir))
+ {
+ nextPosition = TryDirection(currentPosition, nextDir);
+ if (!float.IsNaN(nextPosition.x) && nextPosition != oldPosition)
+ {
+ oldPosition = currentPosition;
+ currentPosition = nextPosition;
+ if (oldDir != nextDir)
+ {
+ edgesSorted[true].Add(edgePoints[(int)oldPosition.x, (int)oldPosition.y]);
+ }
+ oldDir = nextDir;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ if (edgesSorted[false].Count != edgesSorted[true].Count)
+ {
+ if (edgesSorted[false].Count < edgesSorted[true].Count)
+ return edgesSorted[false].ToArray();
+ else
+ return edgesSorted[true].ToArray();
+ }
+ else
+ {
+ float approximateWayLeft;
+ float approximateWayRight;
+ if (edgesSorted[false].Count == 2)
+ {
+ approximateWayLeft = Vector3.Distance(start, edgesSorted[false][0]) + Vector3.Distance(goal, edgesSorted[false][1]);
+ approximateWayRight = Vector3.Distance(start, edgesSorted[true][0]) + Vector3.Distance(goal, edgesSorted[true][1]);
+ }
+ else
+ {
+ approximateWayLeft = Vector3.Distance(start, edgesSorted[false][0]) + Vector3.Distance(edgesSorted[false][0], goal);
+ approximateWayRight = Vector3.Distance(start, edgesSorted[true][0]) + Vector3.Distance(edgesSorted[true][0], goal);
+ }
+ return edgesSorted[approximateWayLeft > approximateWayRight].ToArray();
+ }
+ }
+
+ ///
+ /// Determines if every element of vec1 is less equal vec2
+ ///
+ static bool VecSmallerEqVec(Vector3 vec1, Vector3 vec2)
+ {
+ return (vec1.x < vec2.x || FloatEq(vec1.x,vec2.x)) && (vec1.y < vec2.y || FloatEq(vec1.y, vec2.y)) && (vec1.z < vec2.z || FloatEq(vec1.z, vec2.z));
+ }
+
+ ///
+ /// Determines if every element of vec1 is greater equal vec2
+ ///
+ static bool VecGreaterEqVec(Vector3 vec1, Vector3 vec2)
+ {
+ return (vec1.x > vec2.x || FloatEq(vec1.x, vec2.x)) && (vec1.y > vec2.y || FloatEq(vec1.y, vec2.y)) && (vec1.z > vec2.z || FloatEq(vec1.z, vec2.z));
+ }
+
+ ///
+ /// Checks if two floatsare nearly the same
+ ///
+ static bool FloatEq(float x, float y)
+ {
+ return Math.Abs(x - y) < 0.1f;
+ }
+
+ ///
+ /// Checks if two vectors are nearly the same
+ ///
+ static bool VecEqVec(Vector3 vec1, Vector3 vec2)
+ {
+ return FloatEq(vec1.x, vec2.x) && FloatEq(vec1.y, vec2.y) && FloatEq(vec1.z, vec2.z);
+ }
+
+ ///
+ /// calculates the centroid of the triangle formed by p0, p1 and p2
+ ///
+ static Vector2 CalculateCentroid(Vector2 p0, Vector2 p1, Vector2 p2)
+ {
+ Vector2 p01 = p1 + (p0 - p1) / 2;
+ Vector2 p12 = p2 + (p1 - p2) / 2;
+ Vector2 d1 = p2 - p01;
+ Vector2 d2 = p0 - p12;
+
+ return CalculateLineIntersection(p01, d1, p12, d2);
+ }
+
+ ///
+ /// Calculates the interstion point for two lines defined by a start point and a direction vector. Returns (NaN,NaN) when no intersection exists
+ ///
+ static Vector2 CalculateLineIntersection(Vector2 startPoint1, Vector2 direction1, Vector2 startPoint2, Vector2 direction2)
+ {
+ float r = float.NaN;
+ float l = float.NaN;
+ if (direction1.x == 0 && direction2.x != 0)
+ {
+ r = (startPoint1.x - startPoint2.x) / direction2.x;
+ }
+ else if (direction1.y == 0 && direction2.y != 0)
+ {
+ r = (startPoint1.y - startPoint2.y) / direction2.y;
+ }
+ else if (direction2.x == 0 && direction1.x != 0)
+ {
+ l = (startPoint2.x - startPoint1.x) / direction1.x;
+ }
+ else if (direction2.y == 0 && direction1.y != 0)
+ {
+ l = (startPoint2.y - startPoint1.y) / direction1.y;
+ }
+ else if (direction1.x == 0 && direction2.x == 0 || direction1.y == 0 && direction2.y == 0)
+ {
+ return startPoint1;
+ }
+ else
+ {
+ r = (startPoint2.y - startPoint1.y - (direction1.y * (startPoint2.x - startPoint1.x) / (direction1.x))) / ((direction1.y * direction2.x) / (direction1.x) - direction2.y);
+ }
+ if (!float.IsNaN(r))
+ return startPoint2 + r * direction2;
+ else
+ return startPoint1 + l * direction1;
+ }
+
+ ///
+ /// Generates the missing controllpoints for the Bezier curves and joins them to a single one
+ ///
+ public static Vector3[] CalculateJoinedBezierCurve(Vector3 start, Vector3[] middlePoints, Vector3 goal, int segmentCount)
+ {
+ if (middlePoints.Length == 0)
+ {
+ return StandartCurve(start, goal, 50, 4);
+ }
+
+ Vector3[] controllPointsCurve1 = new Vector3[3];
+ Vector3[] controllPointsCurve2 = new Vector3[4];
+ Vector3[] controllPointsCurve3 = new Vector3[3];
+ int higherOne = start.y > goal.y ? 0 : 1;
+
+ Vector3 direction = goal - start;
+ direction.Normalize();
+ Vector3 normal;
+ //Calculate the normal from the plane P spanned by start, the middle point at the higher one and goal
+ if (middlePoints.Length == 2)
+ {
+ normal = Vector3.Cross(middlePoints[higherOne] - start, direction);
+ }
+ else
+ normal = Vector3.Cross(middlePoints[0] - start, direction);
+
+ normal.Normalize();
+ Vector3 up = Vector3.Cross(direction, normal);
+ up.Normalize();
+ //(direction, normal, up) is now an orthonormal basis for P
+
+ //When there are two middle points, shift the middle point that wasn't used to create P down on P
+ if (middlePoints.Length == 2)
+ {
+ float coordinateForm = start.x * normal.x + start.y * normal.y + start.z * normal.z - middlePoints[1 - higherOne].x * normal.x - middlePoints[1 - higherOne].y * normal.y - middlePoints[1 - higherOne].z * normal.z;
+ if (!FloatEq(coordinateForm, 0))
+ {
+ float l = coordinateForm / normal.y;
+ middlePoints[1 - higherOne] = middlePoints[1 - higherOne] + l * Vector3.up;
+ }
+ }
+
+
+ //Set the base transform matrixes
+ Matrix4x4 planeToStandart = new Matrix4x4(direction,up,normal, new Vector4(0,0,0,1));
+ Matrix4x4 standartToPlane = planeToStandart.inverse;
+
+ //Transform the points into the new basis
+ start = standartToPlane * new Vector4(start.x,start.y,start.z,1);
+ goal = standartToPlane * new Vector4(goal.x, goal.y, goal.z, 1);
+ for(int i = 0; i < middlePoints.Length; i++)
+ middlePoints[i] = standartToPlane * new Vector4(middlePoints[i].x, middlePoints[i].y, middlePoints[i].z, 1);
+
+ Vector3[] curve = null;
+
+
+
+ if (middlePoints.Length == 2)
+ {
+ curve = CurveWithTwoPoints(start,goal, planeToStandart, middlePoints, segmentCount);
+ }
+ else
+ {
+ curve = CurveWithOnePoint(start, goal, planeToStandart, middlePoints[0], segmentCount);
+ }
+
+ return curve;
+ }
+
+ ///
+ /// Generates a Bezier curve consiting out of three curves
+ ///
+ static Vector3[] CurveWithTwoPoints(Vector3 start, Vector3 goal, Matrix4x4 planeToStandart, Vector3[] middlePoints, int segmentCount)
+ {
+ Vector3[] controllPointsCurve1 = new Vector3[3];
+ Vector3[] controllPointsCurve2 = new Vector3[4];
+ Vector3[] controllPointsCurve3 = new Vector3[3];
+ //Curve 1
+ controllPointsCurve1[0] = planeToStandart * start;
+ controllPointsCurve1[2] = planeToStandart * middlePoints[0];
+
+ Vector2 p1;
+ if (start.x < middlePoints[0].x)
+ p1 = new Vector2(start.x, middlePoints[0].y);
+ else
+ p1 = new Vector2(middlePoints[0].x, start.y);
+
+ p1 = CalculateCentroid(start, p1, middlePoints[0]);
+ controllPointsCurve1[1] = planeToStandart * new Vector3(p1.x, p1.y, start.z);
+
+ //Curve 3
+ controllPointsCurve3[0] = planeToStandart * middlePoints[1];
+ controllPointsCurve3[2] = planeToStandart * goal;
+
+ Vector2 p2;
+ if (goal.x > middlePoints[1].x)
+ p2 = new Vector2(goal.x, middlePoints[1].y);
+ else
+ p2 = new Vector2(middlePoints[1].x, goal.y);
+ p2 = CalculateCentroid(goal, p2, middlePoints[1]);
+ controllPointsCurve3[1] = planeToStandart * new Vector3(p2.x, p2.y, start.z);
+
+ //Curve 2 that connects Curve 1 and 3
+ controllPointsCurve2[0] = controllPointsCurve1[2];
+ controllPointsCurve2[3] = controllPointsCurve3[0];
+
+ Vector2 aboveMiddle = CalculateLineIntersection(p1, (Vector2)middlePoints[0] - p1, p2, (Vector2)middlePoints[1] - p2);
+ Vector2 aboveMiddleP1;
+ Vector2 aboveMiddleP2;
+ Vector3[] curve;
+ if (aboveMiddle.y < middlePoints[0].y || aboveMiddle.y < middlePoints[1].y)
+ {
+ return CurveWithOnePoint(start, goal, planeToStandart, middlePoints[0].y > middlePoints[1].y ? middlePoints[0] : middlePoints[1], segmentCount);
+ }
+ aboveMiddleP1 = (Vector2)middlePoints[0] + (aboveMiddle - (Vector2)middlePoints[0]) / 2;
+ controllPointsCurve2[1] = planeToStandart * new Vector3(aboveMiddleP1.x, aboveMiddleP1.y, start.z);
+
+ aboveMiddleP2 = (Vector2)middlePoints[1] + (aboveMiddle - (Vector2)middlePoints[1]) / 2;
+ controllPointsCurve2[2] = planeToStandart * new Vector3(aboveMiddleP2.x, aboveMiddleP2.y, start.z);
+
+ Vector3[] curve1 = CurveGenerator.CalculateBezierCurve(controllPointsCurve1, segmentCount / 3);
+ Vector3[] curve2 = CurveGenerator.CalculateBezierCurve(controllPointsCurve2, segmentCount / 3);
+ Vector3[] curve3 = CurveGenerator.CalculateBezierCurve(controllPointsCurve3, segmentCount / 3);
+ curve = new Vector3[curve1.Length + curve2.Length + curve3.Length];
+ curve1.CopyTo(curve, 0);
+ curve2.CopyTo(curve, curve1.Length);
+ curve3.CopyTo(curve, curve1.Length + curve2.Length);
+ return curve;
+ }
+
+ ///
+ /// Generates a Bezier curve consiting out of two curves
+ ///
+ static Vector3[] CurveWithOnePoint(Vector3 start, Vector3 goal, Matrix4x4 planeToStandart, Vector3 middlePoint, int segmentCount)
+ {
+ Vector3[] controllPointsCurve1 = new Vector3[3];
+ Vector3[] ControllPointsCurve2 = new Vector3[3];
+ Vector3[] curve;
+
+ //Curve 1
+ controllPointsCurve1[0] = planeToStandart * start;
+ controllPointsCurve1[2] = planeToStandart * middlePoint;
+ Vector2 p1 = new Vector2(start.x, middlePoint.y);
+ controllPointsCurve1[1] = planeToStandart * new Vector3(p1.x, p1.y, start.z);
+
+ //Curve 2
+ ControllPointsCurve2[0] = planeToStandart * middlePoint;
+ ControllPointsCurve2[2] = planeToStandart * goal;
+ p1 = new Vector2(goal.x, middlePoint.y);
+ ControllPointsCurve2[1] = planeToStandart * new Vector3(p1.x, p1.y, start.z);
+
+
+ Vector3[] curve1 = CurveGenerator.CalculateBezierCurve(controllPointsCurve1, segmentCount / 2);
+ Vector3[] curve3 = CurveGenerator.CalculateBezierCurve(ControllPointsCurve2, segmentCount / 2);
+
+ curve = new Vector3[curve1.Length + curve3.Length];
+ curve1.CopyTo(curve, 0);
+ curve3.CopyTo(curve, curve1.Length);
+ return curve;
+ }
+}
+
+
+struct SimpleCurveGenerationJob : IJobParallelFor
+{
+ [ReadOnly]
+ public NativeArray boxes;
+ [ReadOnly]
+ public NativeArray start;
+ [ReadOnly]
+ public NativeArray goal;
+
+ //I am truly sorry for this, but Unity 2018.4 doesn't allow any form of sane managment of two dimensional native data. If the unity Version ever gets Updated, this can all be replaced by a single native hashmap
+
+ public NativeArray curvePoint0;
+ public NativeArray curvePoint1;
+ public NativeArray curvePoint2;
+ public NativeArray curvePoint3;
+ public NativeArray curvePoint4;
+ public NativeArray curvePoint5;
+ public NativeArray curvePoint6;
+ public NativeArray curvePoint7;
+ public NativeArray curvePoint8;
+ public NativeArray curvePoint9;
+ public NativeArray curvePoint10;
+ public NativeArray curvePoint11;
+ public NativeArray curvePoint12;
+ public NativeArray curvePoint13;
+ public NativeArray curvePoint14;
+ public NativeArray curvePoint15;
+ public NativeArray curvePoint16;
+ public NativeArray curvePoint17;
+ public NativeArray curvePoint18;
+ public NativeArray curvePoint19;
+ public NativeArray curvePoint20;
+ public NativeArray curvePoint21;
+ public NativeArray curvePoint22;
+ public NativeArray curvePoint23;
+ public NativeArray curvePoint24;
+ public NativeArray curvePoint25;
+ public NativeArray curvePoint26;
+ public NativeArray curvePoint27;
+ public NativeArray curvePoint28;
+ public NativeArray curvePoint29;
+ public NativeArray curvePoint30;
+ public NativeArray curvePoint31;
+ public NativeArray curvePoint32;
+ public NativeArray curvePoint33;
+ public NativeArray curvePoint34;
+ public NativeArray curvePoint35;
+ public NativeArray curvePoint36;
+ public NativeArray curvePoint37;
+ public NativeArray curvePoint38;
+ public NativeArray curvePoint39;
+ public NativeArray curvePoint40;
+ public NativeArray curvePoint41;
+ public NativeArray curvePoint42;
+ public NativeArray curvePoint43;
+ public NativeArray curvePoint44;
+ public NativeArray curvePoint45;
+ public NativeArray curvePoint46;
+ public NativeArray curvePoint47;
+ public NativeArray curvePoint48;
+ public NativeArray curvePoint49;
+ public NativeArray curvePoint50;
+ public NativeArray curvePoint51;
+ public NativeArray curvePoint52;
+ public NativeArray curvePoint53;
+ public NativeArray curvePoint54;
+ public NativeArray curvePoint55;
+ public NativeArray curvePoint56;
+ public NativeArray curvePoint57;
+ public NativeArray curvePoint58;
+ public NativeArray curvePoint59;
+
+ public NativeArray isValid;
+
+ public void Execute(int index)
+ {
+ float standartHeight = 0.5f;
+ Vector3[] curve;
+
+ Vector3[] intersectionPointsAbove = SimpleCurveGerneration.calculateControllpointsAbove(start[index], goal[index], boxes[index].minPointAbove, boxes[index].maxPointAbove);
+ Vector3[] intersectionPointsSide = SimpleCurveGerneration.calculateIntersectionSide(start[index], goal[index], boxes[index].minPointSide, boxes[index].maxPointSide, standartHeight);
+
+
+
+ float distanceAbove = CurveGenerator.CurveLength(new Vector3[] { start[index], intersectionPointsAbove[0], intersectionPointsAbove[1], goal[index] });
+ float distanceSide;
+ if (intersectionPointsSide.Length == 1)
+ distanceSide = CurveGenerator.CurveLength(new Vector3[] { start[index], intersectionPointsSide[0], goal[index] });
+ else if (intersectionPointsSide.Length == 2)
+ distanceSide = CurveGenerator.CurveLength(new Vector3[] { start[index], intersectionPointsSide[0], intersectionPointsSide[1], goal[index] });
+ else
+ {
+ curve = SimpleCurveGerneration.StandartCurve(start[index], goal[index], 60, standartHeight);
+ SetResult(curve, index);
+ return;
+ }
+
+
+ Vector3[] controllPoints = new Vector3[0];
+
+ if (distanceAbove < 1.1*distanceSide)
+ {
+ curve = SimpleCurveGerneration.CalculateJoinedBezierCurve(start[index], intersectionPointsAbove, goal[index], 60);
+ SetResult(curve, index);
+ return;
+ }
+ else
+ {
+ curve = SimpleCurveGerneration.CalculateJoinedBezierCurve(start[index], intersectionPointsSide, goal[index], 60);
+ SetResult(curve, index);
+ return;
+ }
+ }
+
+ private void SetResult(Vector3[] curve, int index)
+ {
+ if (curve.Length == 60)
+ {
+ isValid[index] = 1;
+ curvePoint0[index] = curve[0];
+ curvePoint1[index] = curve[1];
+ curvePoint2[index] = curve[2];
+ curvePoint3[index] = curve[3];
+ curvePoint4[index] = curve[4];
+ curvePoint5[index] = curve[5];
+ curvePoint6[index] = curve[6];
+ curvePoint7[index] = curve[7];
+ curvePoint8[index] = curve[8];
+ curvePoint9[index] = curve[9];
+ curvePoint10[index] = curve[10];
+ curvePoint11[index] = curve[11];
+ curvePoint12[index] = curve[12];
+ curvePoint13[index] = curve[13];
+ curvePoint14[index] = curve[14];
+ curvePoint15[index] = curve[15];
+ curvePoint16[index] = curve[16];
+ curvePoint17[index] = curve[17];
+ curvePoint18[index] = curve[18];
+ curvePoint19[index] = curve[19];
+ curvePoint20[index] = curve[20];
+ curvePoint21[index] = curve[21];
+ curvePoint22[index] = curve[22];
+ curvePoint23[index] = curve[23];
+ curvePoint24[index] = curve[24];
+ curvePoint25[index] = curve[25];
+ curvePoint26[index] = curve[26];
+ curvePoint27[index] = curve[27];
+ curvePoint28[index] = curve[28];
+ curvePoint29[index] = curve[29];
+ curvePoint30[index] = curve[30];
+ curvePoint31[index] = curve[31];
+ curvePoint32[index] = curve[32];
+ curvePoint33[index] = curve[33];
+ curvePoint34[index] = curve[34];
+ curvePoint35[index] = curve[35];
+ curvePoint36[index] = curve[36];
+ curvePoint37[index] = curve[37];
+ curvePoint38[index] = curve[38];
+ curvePoint39[index] = curve[39];
+ curvePoint40[index] = curve[40];
+ curvePoint41[index] = curve[41];
+ curvePoint42[index] = curve[42];
+ curvePoint43[index] = curve[43];
+ curvePoint44[index] = curve[44];
+ curvePoint45[index] = curve[45];
+ curvePoint46[index] = curve[46];
+ curvePoint47[index] = curve[47];
+ curvePoint48[index] = curve[48];
+ curvePoint49[index] = curve[49];
+ curvePoint50[index] = curve[50];
+ curvePoint51[index] = curve[51];
+ curvePoint52[index] = curve[52];
+ curvePoint53[index] = curve[53];
+ curvePoint54[index] = curve[54];
+ curvePoint55[index] = curve[55];
+ curvePoint56[index] = curve[56];
+ curvePoint57[index] = curve[57];
+ curvePoint58[index] = curve[58];
+ curvePoint59[index] = curve[59];
+ }
+ else
+ {
+ isValid[index] = 0;
+ }
+ }
+
+ public Vector3[] ReadResult(int index)
+ {
+ if ( isValid[index] == 0)
+ {
+ return null;
+ }
+ Vector3[] curve = new Vector3[60];
+ curve[0] = curvePoint0[index];
+ curve[1] = curvePoint1[index];
+ curve[2] = curvePoint2[index];
+ curve[3] = curvePoint3[index];
+ curve[4] = curvePoint4[index];
+ curve[5] = curvePoint5[index];
+ curve[6] = curvePoint6[index];
+ curve[7] = curvePoint7[index];
+ curve[8] = curvePoint8[index];
+ curve[9] = curvePoint9[index];
+ curve[10] = curvePoint10[index];
+ curve[11] = curvePoint11[index];
+ curve[12] = curvePoint12[index];
+ curve[13] = curvePoint13[index];
+ curve[14] = curvePoint14[index];
+ curve[15] = curvePoint15[index];
+ curve[16] = curvePoint16[index];
+ curve[17] = curvePoint17[index];
+ curve[18] = curvePoint18[index];
+ curve[19] = curvePoint19[index];
+ curve[20] = curvePoint20[index];
+ curve[21] = curvePoint21[index];
+ curve[22] = curvePoint22[index];
+ curve[23] = curvePoint23[index];
+ curve[24] = curvePoint24[index];
+ curve[25] = curvePoint25[index];
+ curve[26] = curvePoint26[index];
+ curve[27] = curvePoint27[index];
+ curve[28] = curvePoint28[index];
+ curve[29] = curvePoint29[index];
+ curve[30] = curvePoint30[index];
+ curve[31] = curvePoint31[index];
+ curve[32] = curvePoint32[index];
+ curve[33] = curvePoint33[index];
+ curve[34] = curvePoint34[index];
+ curve[35] = curvePoint35[index];
+ curve[36] = curvePoint36[index];
+ curve[37] = curvePoint37[index];
+ curve[38] = curvePoint38[index];
+ curve[39] = curvePoint39[index];
+ curve[40] = curvePoint40[index];
+ curve[41] = curvePoint41[index];
+ curve[42] = curvePoint42[index];
+ curve[43] = curvePoint43[index];
+ curve[44] = curvePoint44[index];
+ curve[45] = curvePoint45[index];
+ curve[46] = curvePoint46[index];
+ curve[47] = curvePoint47[index];
+ curve[48] = curvePoint48[index];
+ curve[49] = curvePoint49[index];
+ curve[50] = curvePoint50[index];
+ curve[51] = curvePoint51[index];
+ curve[52] = curvePoint52[index];
+ curve[53] = curvePoint53[index];
+ curve[54] = curvePoint54[index];
+ curve[55] = curvePoint55[index];
+ curve[56] = curvePoint56[index];
+ curve[57] = curvePoint57[index];
+ curve[58] = curvePoint58[index];
+ curve[59] = curvePoint59[index];
+ return curve;
+ }
+
+ public void InitialiseArrays(int length)
+ {
+ //These arrays need to be allocated persitent, because allocating and disposing them each frame needs too long.
+ curvePoint0 = new NativeArray(length, Allocator.Persistent);
+ curvePoint1 = new NativeArray(length, Allocator.Persistent);
+ curvePoint2 = new NativeArray(length, Allocator.Persistent);
+ curvePoint3 = new NativeArray(length, Allocator.Persistent);
+ curvePoint4 = new NativeArray(length, Allocator.Persistent);
+ curvePoint5 = new NativeArray(length, Allocator.Persistent);
+ curvePoint6 = new NativeArray(length, Allocator.Persistent);
+ curvePoint7 = new NativeArray(length, Allocator.Persistent);
+ curvePoint8 = new NativeArray(length, Allocator.Persistent);
+ curvePoint9 = new NativeArray(length, Allocator.Persistent);
+ curvePoint10 = new NativeArray(length, Allocator.Persistent);
+ curvePoint11 = new NativeArray(length, Allocator.Persistent);
+ curvePoint12 = new NativeArray(length, Allocator.Persistent);
+ curvePoint13 = new NativeArray(length, Allocator.Persistent);
+ curvePoint14 = new NativeArray(length, Allocator.Persistent);
+ curvePoint15 = new NativeArray(length, Allocator.Persistent);
+ curvePoint16 = new NativeArray(length, Allocator.Persistent);
+ curvePoint17 = new NativeArray(length, Allocator.Persistent);
+ curvePoint18 = new NativeArray(length, Allocator.Persistent);
+ curvePoint19 = new NativeArray(length, Allocator.Persistent);
+ curvePoint20 = new NativeArray(length, Allocator.Persistent);
+ curvePoint21 = new NativeArray(length, Allocator.Persistent);
+ curvePoint22 = new NativeArray(length, Allocator.Persistent);
+ curvePoint23 = new NativeArray(length, Allocator.Persistent);
+ curvePoint24 = new NativeArray(length, Allocator.Persistent);
+ curvePoint25 = new NativeArray(length, Allocator.Persistent);
+ curvePoint26 = new NativeArray(length, Allocator.Persistent);
+ curvePoint27 = new NativeArray(length, Allocator.Persistent);
+ curvePoint28 = new NativeArray(length, Allocator.Persistent);
+ curvePoint29 = new NativeArray(length, Allocator.Persistent);
+ curvePoint30 = new NativeArray(length, Allocator.Persistent);
+ curvePoint31 = new NativeArray(length, Allocator.Persistent);
+ curvePoint32 = new NativeArray(length, Allocator.Persistent);
+ curvePoint33 = new NativeArray(length, Allocator.Persistent);
+ curvePoint34 = new NativeArray(length, Allocator.Persistent);
+ curvePoint35 = new NativeArray(length, Allocator.Persistent);
+ curvePoint36 = new NativeArray(length, Allocator.Persistent);
+ curvePoint37 = new NativeArray(length, Allocator.Persistent);
+ curvePoint38 = new NativeArray(length, Allocator.Persistent);
+ curvePoint39 = new NativeArray(length, Allocator.Persistent);
+ curvePoint40 = new NativeArray(length, Allocator.Persistent);
+ curvePoint41 = new NativeArray(length, Allocator.Persistent);
+ curvePoint42 = new NativeArray(length, Allocator.Persistent);
+ curvePoint43 = new NativeArray(length, Allocator.Persistent);
+ curvePoint44 = new NativeArray(length, Allocator.Persistent);
+ curvePoint45 = new NativeArray(length, Allocator.Persistent);
+ curvePoint46 = new NativeArray(length, Allocator.Persistent);
+ curvePoint47 = new NativeArray(length, Allocator.Persistent);
+ curvePoint48 = new NativeArray(length, Allocator.Persistent);
+ curvePoint49 = new NativeArray(length, Allocator.Persistent);
+ curvePoint50 = new NativeArray(length, Allocator.Persistent);
+ curvePoint51 = new NativeArray(length, Allocator.Persistent);
+ curvePoint52 = new NativeArray(length, Allocator.Persistent);
+ curvePoint53 = new NativeArray(length, Allocator.Persistent);
+ curvePoint54 = new NativeArray(length, Allocator.Persistent);
+ curvePoint55 = new NativeArray