diff --git a/Visuo-haptic Toolkit/Assets/Visuo-Haptic Toolkit/Scripts/Redirection/World Redirection/Strategies.cs b/Visuo-haptic Toolkit/Assets/Visuo-Haptic Toolkit/Scripts/Redirection/World Redirection/Strategies.cs index 89ac43d5..752cf58a 100644 --- a/Visuo-haptic Toolkit/Assets/Visuo-Haptic Toolkit/Scripts/Redirection/World Redirection/Strategies.cs +++ b/Visuo-haptic Toolkit/Assets/Visuo-Haptic Toolkit/Scripts/Redirection/World Redirection/Strategies.cs @@ -65,18 +65,16 @@ class SteerInDirection : WorldRedirectionStrategy { public class APFP2R : WorldRedirectionStrategy { - List colliders; + public List colliders; - private Func RepulsiveFunction() { - if (colliders == null) - colliders = GameObject.FindGameObjectsWithTag("Obstacle").Select(o => o.GetComponent()).ToList(); - return MathTools.RepulsivePotential3D(colliders); + public APFP2R() : base() { + colliders = GameObject.FindGameObjectsWithTag("Obstacle").Select(o => o.GetComponent()).ToList(); } public override Vector3 SteerTo(Scene scene) => ComputeGradient(scene); private Vector2 ComputeGradient(Scene scene) => Vector3.ProjectOnPlane(MathTools.Gradient3( - RepulsiveFunction(), + MathTools.RepulsivePotential3D(colliders), MathTools.ProjectToHorizontalPlane(scene.physicalHead.position) ), Vector3.up); } diff --git a/Visuo-haptic Toolkit/Assets/Visuo-Haptic Toolkit/Scripts/Redirection/World Redirection/WorldRedirection.cs b/Visuo-haptic Toolkit/Assets/Visuo-Haptic Toolkit/Scripts/Redirection/World Redirection/WorldRedirection.cs index 9a247dff..36fb445a 100644 --- a/Visuo-haptic Toolkit/Assets/Visuo-Haptic Toolkit/Scripts/Redirection/World Redirection/WorldRedirection.cs +++ b/Visuo-haptic Toolkit/Assets/Visuo-Haptic Toolkit/Scripts/Redirection/World Redirection/WorldRedirection.cs @@ -34,6 +34,7 @@ private void UpdateTechnique() { _ => null }; + if (techniqueInstance is null) Debug.LogError("Error Unknown Redirection technique."); @@ -55,7 +56,7 @@ private void UpdateTechnique() { /// Start function called once when the game is starting. This function calls updateTechnique() to instantiate the technique class and /// initializes the previous head positions. /// - private void Start() { + private void OnEnable() { UpdateTechnique(); previousTechnique = Technique; diff --git a/Visuo-haptic Toolkit/Assets/Visuo-Haptic Toolkit/Scripts/Visualisation/APFGradientVisuals.cs b/Visuo-haptic Toolkit/Assets/Visuo-Haptic Toolkit/Scripts/Visualisation/APFGradientVisuals.cs index 926e1ee2..230d37a1 100644 --- a/Visuo-haptic Toolkit/Assets/Visuo-Haptic Toolkit/Scripts/Visualisation/APFGradientVisuals.cs +++ b/Visuo-haptic Toolkit/Assets/Visuo-Haptic Toolkit/Scripts/Visualisation/APFGradientVisuals.cs @@ -1,16 +1,11 @@ -using Meta.WitAi; -using Oculus.Interaction.Input; using System; -using System.Collections; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; -using System.Security.Cryptography; + using UnityEngine; using VHToolkit; -using VHToolkit.Redirection; -using static OVRPlugin; +using VHToolkit.Redirection.WorldRedirection; public class GradientVisuals : MonoBehaviour { @@ -53,6 +48,8 @@ public class GradientVisuals : MonoBehaviour private List vfVectors; + [SerializeField] private WorldRedirection script; + // FUNCS & SUBS // @@ -98,12 +95,12 @@ private void Checks() if (vfToggled) { - if (vectorsEnabled) { vectorsEnabled = InitVectorsField(); } - else { CloseVectorsField(); } + if (vectorsEnabled) { vectorsEnabled = InitVectorField(); } + else { CloseVectorField(); } } else if (updateVisuals && vfEnabledCurrentState) { - vectorsEnabled = InitVectorsField(); + vectorsEnabled = InitVectorField(); } // save state @@ -114,20 +111,15 @@ private void Checks() /// /// Updates the repulsive function used to calculate gradient. /// - private void UpdateRepulsiveFunc() - { + private void UpdateRepulsiveFunc() { // cancel invokes while repulsive function update is ongoing CancelInvoke(nameof(UpdateHeatmap)); - CancelInvoke(nameof(UpdateVectorsField)); + CancelInvoke(nameof(UpdateVectorField)); // get gameobjects with obstacle tag - obstaclesCollider = new(GameObject.FindGameObjectsWithTag(obstacleTag).Where(o => o.GetComponent() != null).Select(o => o.GetComponent())); - - //var allColliderBounds = FindObjectsOfType().Select(o => o.bounds).ToArray(); - //max = allColliderBounds.Select(b => b.max).Aggregate(Pointwise(Mathf.Max)); - //min = allColliderBounds.Select(b => b.min).Aggregate(Pointwise(Mathf.Min)); - //min.y = max.y = 0f; + obstaclesCollider = ((APFP2R)script.strategyInstance).colliders; + // Compute the bounding box and repulsive function for all colliders if (obstaclesCollider.Any()) { static Func Pointwise(Func f) => @@ -135,42 +127,26 @@ static Func Pointwise(Func f) => repulsiveFunction = MathTools.RepulsivePotential3D(obstaclesCollider); - var allColliderBounds = FindObjectsOfType().Select(o => o.bounds.max).ToArray(); - max = allColliderBounds.Aggregate(Pointwise(Mathf.Max)); - min = allColliderBounds.Aggregate(Pointwise(Mathf.Min)); + // var allColliderBounds = FindObjectsOfType().Select(o => o.bounds.max).ToArray(); + max = FindObjectsOfType().Select(o => o.bounds.max).ToArray().Aggregate(Pointwise(Mathf.Max)); + min = FindObjectsOfType().Select(o => o.bounds.min).ToArray().Aggregate(Pointwise(Mathf.Min)); min.y = max.y = 0f; width = max.x - min.x; depth = max.z - min.z; - - // Debug.Log($"Visuals init : X[{min.x}:{max.x}] Z[{min.z}:{max.z}]"); - // Debug.Log($"Visuals init : width:{width} height:{depth}"); - - } - else - { - repulsiveFunction = null; - // Debug.Log("No colliders detected, can't generate visuals."); + } else { + repulsiveFunction = (x) => 0; } } + // TODO : change to SceneUpdate and call it manually when scene is changed /// /// Checks for changes with gameobjects tagged as obstacles, and also for changes is scene area size. /// /// True if any change found private bool CheckForSceneUpdate() { - if (GameObject.FindGameObjectsWithTag(obstacleTag).Where(o => o.GetComponent() != null).Count() != obstaclesCollider.Count) return true; - - foreach (var objCol in FindObjectsOfType()) - { - if (objCol.bounds.max.x > max.x) return true; - if (objCol.bounds.min.x < min.x) return true; - if (objCol.bounds.max.z > max.z) return true; - if (objCol.bounds.min.z < min.z) return true; - } - - return false; + return true; } #endregion @@ -179,18 +155,13 @@ private bool CheckForSceneUpdate() #region "heatmap" + //TODO : always returns true, should be void? /// /// Init heatmap quad with shahder, and invokes update func. /// /// True if init ended sucessfully private bool InitHeatmap() { - if (repulsiveFunction == null) - { - Console.Write("APF visuals : cannot init heatmap, no repulsive function (is there any obstacle with collider ?)."); - CloseHeatmap(); - return false; - } if (hmEnabledCurrentState) { @@ -229,9 +200,8 @@ private void UpdateHeatmap() { Vector3 position = new Vector3(min.x + (x * hmStepX) + (hmStepX / 2), 0, min.z + (z * hmStepZ) + (hmStepZ / 2)); - Vector2 gradient = MathTools.Gradient3(repulsiveFunction, position); - float hmValue = gradient.magnitude; + float hmValue = ((Vector2)MathTools.Gradient3(repulsiveFunction, position)).magnitude; hmDensityTable[x + (z * heatmapMeshFineness)] = hmValue; // Debug.Log($"{hmStepX * x:0.0} - {hmStepZ * z:0.0} : {hmValue}"); @@ -265,18 +235,18 @@ private void CloseHeatmap() /// Init vectors field, and invokes update func. /// /// True if init ended sucessfully - private bool InitVectorsField() + private bool InitVectorField() { if (repulsiveFunction == null) { - Console.Write("APF visuals : cannot init vectors field, no repulsive function (is there any obstacle with collider ?)."); - CloseVectorsField(); + Debug.Log("APF visuals : cannot init vectors field, no repulsive function (is there any obstacle with collider ?)."); + CloseVectorField(); return false; } if (vfEnabledCurrentState) { - CloseVectorsField(); + CloseVectorField(); } int i = 0; @@ -295,11 +265,9 @@ private bool InitVectorsField() if (!float.IsNaN(gradient.x) && !float.IsNaN(gradient.y)) { - float angleRadian = Mathf.Atan2(gradient.y, gradient.x); - float angleEnDegres = angleRadian * Mathf.Rad2Deg; - Quaternion rotation = Quaternion.Euler(-90, 0, angleEnDegres); + float angleInDegrees = Mathf.Atan2(gradient.y, gradient.x) * Mathf.Rad2Deg; - vectorObj.transform.rotation = rotation; + vectorObj.transform.rotation = Quaternion.Euler(-90, 0, angleInDegrees); vectorObj.GetComponent().sprite = vfArrow; } @@ -314,8 +282,8 @@ private bool InitVectorsField() } - UpdateVectorsField(); - InvokeRepeating(nameof(UpdateVectorsField), 1f, refreshRate); + UpdateVectorField(); + InvokeRepeating(nameof(UpdateVectorField), 1f, refreshRate); return true; } @@ -323,7 +291,7 @@ private bool InitVectorsField() /// /// Vectors field update method. /// - private void UpdateVectorsField() + private void UpdateVectorField() { if (!vectorsEnabled) { return; } @@ -344,9 +312,9 @@ private void UpdateVectorsField() /// /// Handles the ending of the vector field. /// - private void CloseVectorsField() + private void CloseVectorField() { - CancelInvoke(nameof(UpdateVectorsField)); + CancelInvoke(nameof(UpdateVectorField)); //for (int i = vfVectors.Count - 1; i >= 0; i--) //{