From 13cd05327973405667aea2f9923581c7a1f36f74 Mon Sep 17 00:00:00 2001 From: Thorbjoern Date: Wed, 16 Jul 2025 23:45:04 +0200 Subject: [PATCH] Optimized FOV Representation --- .../Props/Electronics/Monitor_Apt_01.prefab | 4 +- Assets/_Materials/Overlays/Foveal FOV.mat | 4 +- Assets/_Materials/Overlays/Peripheric FOV.mat | 4 +- Assets/_Scenes/CQB/Room 4.unity | 47 +++++++++----- Assets/_Scenes/TrainingObserverMeta.unity | 2 + Assets/_Scripts/Eye-Tracking/FieldOfView.cs | 64 ++++++++++++++++++- 6 files changed, 103 insertions(+), 22 deletions(-) diff --git a/Assets/Brick Project Studio/Apartment Kit/_Prefabs/Props/Electronics/Monitor_Apt_01.prefab b/Assets/Brick Project Studio/Apartment Kit/_Prefabs/Props/Electronics/Monitor_Apt_01.prefab index 7021863..833cee3 100644 --- a/Assets/Brick Project Studio/Apartment Kit/_Prefabs/Props/Electronics/Monitor_Apt_01.prefab +++ b/Assets/Brick Project Studio/Apartment Kit/_Prefabs/Props/Electronics/Monitor_Apt_01.prefab @@ -107,8 +107,8 @@ BoxCollider: m_ProvidesContacts: 0 m_Enabled: 1 serializedVersion: 3 - m_Size: {x: 0.23145308, y: 0.68612796, z: 0.96159303} - m_Center: {x: -0.000000007450581, y: 0.343064, z: -0.000000014901161} + m_Size: {x: 0.011152873, y: 0.600559, z: 0.96159303} + m_Center: {x: -0.005014687, y: 0.38584858, z: 4.7072856e-11} --- !u!1 &4155092160825153246 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/_Materials/Overlays/Foveal FOV.mat b/Assets/_Materials/Overlays/Foveal FOV.mat index 3a94263..e6174d9 100644 --- a/Assets/_Materials/Overlays/Foveal FOV.mat +++ b/Assets/_Materials/Overlays/Foveal FOV.mat @@ -133,8 +133,8 @@ Material: - _WorkflowMode: 1 - _ZWrite: 0 m_Colors: - - _BaseColor: {r: 1, g: 0.9263606, b: 0, a: 0.5176471} - - _Color: {r: 1, g: 0.9263606, b: 0, a: 0.5176471} + - _BaseColor: {r: 0, g: 0.98978424, b: 1, a: 0.5176471} + - _Color: {r: 0, g: 0.9897842, b: 1, a: 0.5176471} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} m_BuildTextureStacks: [] diff --git a/Assets/_Materials/Overlays/Peripheric FOV.mat b/Assets/_Materials/Overlays/Peripheric FOV.mat index b18f089..15ee5a7 100644 --- a/Assets/_Materials/Overlays/Peripheric FOV.mat +++ b/Assets/_Materials/Overlays/Peripheric FOV.mat @@ -133,8 +133,8 @@ Material: - _WorkflowMode: 1 - _ZWrite: 0 m_Colors: - - _BaseColor: {r: 0.16981131, g: 0.16981131, b: 0.16981131, a: 0.38431373} - - _Color: {r: 0.16981128, g: 0.16981128, b: 0.16981128, a: 0.38431373} + - _BaseColor: {r: 0.25725347, g: 0.32291484, b: 0.4433962, a: 0.54509807} + - _Color: {r: 0.25725344, g: 0.3229148, b: 0.44339618, a: 0.54509807} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} m_BuildTextureStacks: [] diff --git a/Assets/_Scenes/CQB/Room 4.unity b/Assets/_Scenes/CQB/Room 4.unity index 29f4fd5..95cb814 100644 --- a/Assets/_Scenes/CQB/Room 4.unity +++ b/Assets/_Scenes/CQB/Room 4.unity @@ -2318,6 +2318,11 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 0} m_Modifications: + - target: {fileID: 371530555270464198, guid: f8664cb3766e172489bbf61fe9b6e97f, + type: 3} + propertyPath: m_Name + value: Stroke Shaking Head + objectReference: {fileID: 0} - target: {fileID: 1039242717309819004, guid: f8664cb3766e172489bbf61fe9b6e97f, type: 3} propertyPath: m_LocalPosition.x @@ -2368,11 +2373,6 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 371530555270464198, guid: f8664cb3766e172489bbf61fe9b6e97f, - type: 3} - propertyPath: m_Name - value: Stroke Shaking Head - objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] @@ -2482,6 +2482,11 @@ PrefabInstance: propertyPath: m_Layer value: 8 objectReference: {fileID: 0} + - target: {fileID: 340776636867993726, guid: aead8749028d8524d9ad48de9b617ce5, + type: 3} + propertyPath: m_IsActive + value: 0 + objectReference: {fileID: 0} - target: {fileID: 939250457142095474, guid: aead8749028d8524d9ad48de9b617ce5, type: 3} propertyPath: m_Layer @@ -2572,6 +2577,11 @@ PrefabInstance: propertyPath: m_Layer value: 8 objectReference: {fileID: 0} + - target: {fileID: 8755661309293617259, guid: aead8749028d8524d9ad48de9b617ce5, + type: 3} + propertyPath: _rigidbody + value: + objectReference: {fileID: 0} - target: {fileID: 8775526385439166814, guid: aead8749028d8524d9ad48de9b617ce5, type: 3} propertyPath: m_Layer @@ -2582,6 +2592,12 @@ PrefabInstance: m_AddedGameObjects: [] m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: aead8749028d8524d9ad48de9b617ce5, type: 3} +--- !u!1 &324282320 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 340776636867993726, guid: aead8749028d8524d9ad48de9b617ce5, + type: 3} + m_PrefabInstance: {fileID: 324282319} + m_PrefabAsset: {fileID: 0} --- !u!1001 &325619619 PrefabInstance: m_ObjectHideFlags: 0 @@ -3212,6 +3228,11 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 657874277} m_Modifications: + - target: {fileID: 5165458861040981103, guid: 21a133bccb7244245a1c90c15ac4066a, + type: 3} + propertyPath: m_Name + value: rubber_duck_toy_2k + objectReference: {fileID: 0} - target: {fileID: 5540753397945044693, guid: 21a133bccb7244245a1c90c15ac4066a, type: 3} propertyPath: m_LocalPosition.x @@ -3262,11 +3283,6 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 5165458861040981103, guid: 21a133bccb7244245a1c90c15ac4066a, - type: 3} - propertyPath: m_Name - value: rubber_duck_toy_2k - objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] @@ -3774,6 +3790,7 @@ MonoBehaviour: sceneId: Room4 doors: - {fileID: 480176047} + - {fileID: 324282320} furnitures: [] portals: [] enemies: [] @@ -8581,6 +8598,11 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 657874277} m_Modifications: + - target: {fileID: 5165458861040981103, guid: 21a133bccb7244245a1c90c15ac4066a, + type: 3} + propertyPath: m_Name + value: rubber_duck_toy_2k (1) + objectReference: {fileID: 0} - target: {fileID: 5540753397945044693, guid: 21a133bccb7244245a1c90c15ac4066a, type: 3} propertyPath: m_LocalPosition.x @@ -8631,11 +8653,6 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 5165458861040981103, guid: 21a133bccb7244245a1c90c15ac4066a, - type: 3} - propertyPath: m_Name - value: rubber_duck_toy_2k (1) - objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] diff --git a/Assets/_Scenes/TrainingObserverMeta.unity b/Assets/_Scenes/TrainingObserverMeta.unity index a384bbb..44a2b39 100644 --- a/Assets/_Scenes/TrainingObserverMeta.unity +++ b/Assets/_Scenes/TrainingObserverMeta.unity @@ -15840,6 +15840,8 @@ MonoBehaviour: serializedVersion: 2 m_Bits: 1280 meshResolution: 1 + edgeResolveIterations: 10 + edgeDistanceThreshold: 0.1 periMeshFilter: {fileID: 787758211} foveaMeshFilter: {fileID: 368662930} --- !u!1 &1171312281 diff --git a/Assets/_Scripts/Eye-Tracking/FieldOfView.cs b/Assets/_Scripts/Eye-Tracking/FieldOfView.cs index df53e4e..c32a558 100644 --- a/Assets/_Scripts/Eye-Tracking/FieldOfView.cs +++ b/Assets/_Scripts/Eye-Tracking/FieldOfView.cs @@ -18,6 +18,9 @@ public class FieldOfView : MonoBehaviour public LayerMask obstacleMask; public float meshResolution; + public int edgeResolveIterations; + public float edgeDistanceThreshold; + public MeshFilter periMeshFilter; public MeshFilter foveaMeshFilter; private Mesh periMesh; @@ -73,9 +76,10 @@ public class FieldOfView : MonoBehaviour void DrawFOV(float startAngle, Mesh viewMesh, float viewAngle) { - int stepCount = Mathf.RoundToInt(foveaAngle * meshResolution); + int stepCount = Mathf.RoundToInt(viewAngle * meshResolution); float stepAngleSize = viewAngle / stepCount; List viewPoints = new List(); + ViewCastInfo oldViewCast = new ViewCastInfo(); for (int i = 0; i <= stepCount; i++) { @@ -84,7 +88,25 @@ public class FieldOfView : MonoBehaviour Debug.DrawLine(transform.position, transform.position + DirFromAngle(angle, true) * viewRadius, Color.red); ViewCastInfo newViewCast = ViewCast(angle); + + if (i > 0) + { + bool edgeDistThresholdExeeded = Mathf.Abs(oldViewCast.distance - newViewCast.distance) > edgeDistanceThreshold; + if (oldViewCast.didHit != newViewCast.didHit || (oldViewCast.didHit && newViewCast.didHit && edgeDistThresholdExeeded)) + { + EdgeInfo edge = FingEdge(oldViewCast, newViewCast); + if (edge.pointmin != Vector3.zero) + { + viewPoints.Add(edge.pointmin); + } + if (edge.pointmax != Vector3.zero) + { + viewPoints.Add(edge.pointmax); + } + } + } viewPoints.Add(newViewCast.hitPoint); + oldViewCast = newViewCast; } int vertexcount = viewPoints.Count + 1; @@ -141,4 +163,44 @@ public class FieldOfView : MonoBehaviour angle = _angle; } } + + public struct EdgeInfo + { + public Vector3 pointmin; + public Vector3 pointmax; + + public EdgeInfo(Vector3 _pointmin, Vector3 _pointmax) + { + pointmin = _pointmin; + pointmax = _pointmax; + } + } + + EdgeInfo FingEdge(ViewCastInfo minViewCast, ViewCastInfo maxViewCast) + { + float minAngle = minViewCast.angle; + float maxAngle = maxViewCast.angle; + Vector3 minPoint = Vector3.zero; + Vector3 maxPoint = Vector3.zero; + + for (int i = 0; i < edgeResolveIterations; i++) + { + float angle = (minAngle + maxAngle) / 2; + ViewCastInfo newViewCast = ViewCast(angle); + + bool edgeDistThresholdExeeded = Mathf.Abs(minViewCast.distance - newViewCast.distance) > edgeDistanceThreshold; + if (newViewCast.didHit == minViewCast.didHit && !edgeDistThresholdExeeded) + { + minAngle = angle; + minPoint = newViewCast.hitPoint; + } + else + { + maxAngle = angle; + maxPoint = newViewCast.hitPoint; + } + } + + return new EdgeInfo(minPoint, maxPoint); + } }