/// <inheritdoc /> public bool SphereCast(RayStep step, float radius, LayerMask[] prioritizedLayerMasks, bool focusIndividualCompoundCollider, out MixedRealityRaycastHit hitInfo) { var result = MixedRealityRaycaster.RaycastSpherePhysicsStep(step, radius, step.Length, prioritizedLayerMasks, focusIndividualCompoundCollider, out RaycastHit physicsHit); hitInfo = new MixedRealityRaycastHit(result, physicsHit); return(result); }
private void SphereRaycastStepUpdate(RayStep rayStep) { bool isHit; float scaleOverride = ScaleOverride; // Do the cast! float size = scaleOverride > 0 ? scaleOverride : transform.lossyScale.x * sphereSize; isHit = MixedRealityRaycaster.RaycastSpherePhysicsStep(rayStep, size, maxDistance, magneticSurfaces, out RaycastHit result); OnSurface = isHit; // Enforce CloseDistance Vector3 hitDelta = result.point - rayStep.Origin; float length = hitDelta.magnitude; if (length < closeDistance) { result.point = rayStep.Origin + rayStep.Direction * closeDistance; } // Apply results if (isHit) { GoalPosition = result.point + surfaceNormalOffset * result.normal + surfaceRayOffset * rayStep.Direction; GoalRotation = CalculateMagnetismOrientation(rayStep.Direction, result.normal); } }
/// <summary> /// Perform a Unity physics Raycast to determine which scene objects with a collider is currently being gazed at, if any. /// </summary> /// <param name="pointer"></param> /// <param name="prioritizedLayerMasks"></param> private static void RaycastPhysics(PointerData pointer, LayerMask[] prioritizedLayerMasks) { bool isHit = false; int rayStepIndex = 0; RayStep rayStep = default(RayStep); RaycastHit physicsHit = default(RaycastHit); Debug.Assert(pointer.Pointer.Rays != null, "No valid rays for pointer"); Debug.Assert(pointer.Pointer.Rays.Length > 0, "No valid rays for pointer"); // Check raycast for each step in the pointing source for (int i = 0; i < pointer.Pointer.Rays.Length; i++) { switch (pointer.Pointer.RaycastMode) { case RaycastModeType.Simple: if (MixedRealityRaycaster.RaycastSimplePhysicsStep(pointer.Pointer.Rays[i], prioritizedLayerMasks, out physicsHit)) { // Set the pointer source's origin ray to this step isHit = true; rayStep = pointer.Pointer.Rays[i]; rayStepIndex = i; } break; case RaycastModeType.Box: Debug.LogWarning("Box Raycasting Mode not supported for pointers."); break; case RaycastModeType.Sphere: if (MixedRealityRaycaster.RaycastSpherePhysicsStep(pointer.Pointer.Rays[i], pointer.Pointer.SphereCastRadius, prioritizedLayerMasks, out physicsHit)) { // Set the pointer source's origin ray to this step isHit = true; rayStep = pointer.Pointer.Rays[i]; rayStepIndex = i; } break; default: throw new ArgumentOutOfRangeException(); } if (isHit) { break; } } if (isHit) { pointer.UpdateHit(physicsHit, rayStep, rayStepIndex); } else { pointer.UpdateHit(); } }
/// <summary> /// Perform a Unity physics Raycast to determine which scene objects with a collider is currently being gazed at, if any. /// </summary> /// <param name="pointer"></param> /// <param name="prioritizedLayerMasks"></param> /// <param name="hitResult"></param> private static void RaycastPhysics(IMixedRealityPointer pointer, LayerMask[] prioritizedLayerMasks, PointerHitResult hitResult) { float rayStartDistance = 0; var pointerRays = pointer.Rays; if (pointerRays == null) { Debug.LogError($"No valid rays for {pointer.PointerName} pointer."); return; } if (pointerRays.Length <= 0) { Debug.LogError($"No valid rays for {pointer.PointerName} pointer"); return; } // Check raycast for each step in the pointing source for (int i = 0; i < pointerRays.Length; i++) { switch (pointer.RaycastMode) { case RaycastMode.Simple: if (MixedRealityRaycaster.RaycastSimplePhysicsStep(pointerRays[i], prioritizedLayerMasks, out var simplePhysicsHit) && simplePhysicsHit.collider != pointer.NearInteractionCollider) { // Set the pointer source's origin ray to this step UpdatePointerRayOnHit(pointerRays, simplePhysicsHit, i, rayStartDistance, hitResult); return; } break; case RaycastMode.Box: // TODO box raycast mode Debug.LogWarning("Box Raycasting Mode not supported for pointers."); break; case RaycastMode.Sphere: if (MixedRealityRaycaster.RaycastSpherePhysicsStep(pointerRays[i], pointer.SphereCastRadius, prioritizedLayerMasks, out var spherePhysicsHit) && spherePhysicsHit.collider != pointer.NearInteractionCollider) { // Set the pointer source's origin ray to this step UpdatePointerRayOnHit(pointerRays, spherePhysicsHit, i, rayStartDistance, hitResult); return; } break; // TODO Sphere Overlap default: Debug.LogError($"Invalid raycast mode {pointer.RaycastMode} for {pointer.PointerName} pointer."); break; } rayStartDistance += pointer.Rays[i].Length; } }
/// <inheritdoc /> public bool SphereCast(RayStep step, float radius, LayerMask[] prioritizedLayerMasks, bool focusIndividualCompoundCollider, out MixedRealityRaycastHit hitInfo) { Profiler.BeginSample("[MRTK] DefaultRaycastProvider.SphereCast"); var result = MixedRealityRaycaster.RaycastSpherePhysicsStep(step, radius, step.Length, prioritizedLayerMasks, focusIndividualCompoundCollider, out RaycastHit physicsHit); hitInfo = new MixedRealityRaycastHit(result, physicsHit); Profiler.EndSample(); // SphereCast return(result); }
/// <summary> /// Perform a Unity physics Raycast to determine which scene objects with a collider is currently being gazed at, if any. /// </summary> /// <param name="pointerData"></param> /// <param name="prioritizedLayerMasks"></param> private static void RaycastPhysics(PointerData pointerData, LayerMask[] prioritizedLayerMasks) { RayStep[] pointerRays = pointerData.Pointer.Rays; if (pointerRays == null) { Debug.LogError($"No valid rays for {pointerData.Pointer.PointerName} pointer."); return; } if (pointerRays.Length <= 0) { Debug.LogError($"No valid rays for {pointerData.Pointer.PointerName} pointer"); return; } // Check raycast for each step in the pointing source for (int i = 0; i < pointerRays.Length; i++) { RaycastHit physicsHit; switch (pointerData.Pointer.RaycastMode) { case RaycastMode.Simple: if (MixedRealityRaycaster.RaycastSimplePhysicsStep(pointerRays[i], prioritizedLayerMasks, out physicsHit)) { // Set the pointer source's origin ray to this step UpdatePointerRayOnHit(pointerData, pointerRays, in physicsHit, i); return; } break; case RaycastMode.Box: Debug.LogWarning("Box Raycasting Mode not supported for pointers."); break; case RaycastMode.Sphere: if (MixedRealityRaycaster.RaycastSpherePhysicsStep(pointerRays[i], pointerData.Pointer.SphereCastRadius, prioritizedLayerMasks, out physicsHit)) { // Set the pointer source's origin ray to this step UpdatePointerRayOnHit(pointerData, pointerRays, in physicsHit, i); return; } break; default: Debug.LogError($"Invalid raycast mode {pointerData.Pointer.RaycastMode} for {pointerData.Pointer.PointerName} pointer."); break; } } pointerData.UpdateHit(); }
public bool SphereCast( RayStep step, float radius, LayerMask[] prioritizedLayerMasks, bool focusIndividualCompoundCollider, out MixedRealityRaycastHit hitInfo) { // For now, this is just using the default behavior for sphere cast. // Leaving MapRenderer integration for a future change. var result = MixedRealityRaycaster.RaycastSpherePhysicsStep( step, radius, step.Length, prioritizedLayerMasks, focusIndividualCompoundCollider, out RaycastHit physicsHit); hitInfo = new MixedRealityRaycastHit(result, physicsHit); return(result); }
/// <summary> /// Perform a Unity physics Raycast to determine which scene objects with a collider is currently being gazed at, if any. /// </summary> /// <param name="pointerData"></param> /// <param name="prioritizedLayerMasks"></param> private static void RaycastPhysics(PointerData pointerData, LayerMask[] prioritizedLayerMasks) { bool isHit = false; int rayStepIndex = 0; RayStep rayStep = default; RaycastHit physicsHit = default; if (pointerData.Pointer.Rays == null) { Debug.LogError($"No valid rays for {pointerData.Pointer.PointerName} pointer."); return; } if (pointerData.Pointer.Rays.Length <= 0) { Debug.LogError($"No valid rays for {pointerData.Pointer.PointerName} pointer"); return; } // Check raycast for each step in the pointing source for (int i = 0; i < pointerData.Pointer.Rays.Length; i++) { switch (pointerData.Pointer.RaycastMode) { case RaycastModeType.Simple: if (MixedRealityRaycaster.RaycastSimplePhysicsStep(pointerData.Pointer.Rays[i], prioritizedLayerMasks, out physicsHit)) { // Set the pointer source's origin ray to this step isHit = true; rayStep = pointerData.Pointer.Rays[i]; rayStepIndex = i; } break; case RaycastModeType.Box: Debug.LogWarning("Box Raycasting Mode not supported for pointers."); break; case RaycastModeType.Sphere: if (MixedRealityRaycaster.RaycastSpherePhysicsStep(pointerData.Pointer.Rays[i], pointerData.Pointer.SphereCastRadius, prioritizedLayerMasks, out physicsHit)) { // Set the pointer source's origin ray to this step isHit = true; rayStep = pointerData.Pointer.Rays[i]; rayStepIndex = i; } break; default: Debug.LogError($"Invalid raycast mode {pointerData.Pointer.RaycastMode} for {pointerData.Pointer.PointerName} pointer."); break; } if (isHit) { break; } } if (isHit) { pointerData.UpdateHit(physicsHit, rayStep, rayStepIndex); } else { pointerData.UpdateHit(); } }
/// <summary> /// Perform a scene query to determine which scene objects with a collider is currently being gazed at, if any. /// </summary> /// <param name="pointerData"></param> /// <param name="prioritizedLayerMasks"></param> private static void QueryScene(IMixedRealityPointer pointer, LayerMask[] prioritizedLayerMasks, PointerHitResult hit) { float rayStartDistance = 0; RaycastHit physicsHit; RayStep[] pointerRays = pointer.Rays; if (pointerRays == null) { Debug.LogError($"No valid rays for {pointer.PointerName} pointer."); return; } if (pointerRays.Length <= 0) { Debug.LogError($"No valid rays for {pointer.PointerName} pointer"); return; } // Perform query for each step in the pointing source for (int i = 0; i < pointerRays.Length; i++) { switch (pointer.SceneQueryType) { case SceneQueryType.SimpleRaycast: if (MixedRealityRaycaster.RaycastSimplePhysicsStep(pointerRays[i], prioritizedLayerMasks, out physicsHit)) { UpdatePointerRayOnHit(pointerRays, physicsHit, i, rayStartDistance, hit); return; } break; case SceneQueryType.BoxRaycast: Debug.LogWarning("Box Raycasting Mode not supported for pointers."); break; case SceneQueryType.SphereCast: if (MixedRealityRaycaster.RaycastSpherePhysicsStep(pointerRays[i], pointer.SphereCastRadius, prioritizedLayerMasks, out physicsHit)) { UpdatePointerRayOnHit(pointerRays, physicsHit, i, rayStartDistance, hit); return; } break; case SceneQueryType.SphereOverlap: Collider[] colliders = UnityEngine.Physics.OverlapSphere(pointer.Rays[i].Origin, pointer.SphereCastRadius, ~UnityEngine.Physics.IgnoreRaycastLayer); if (colliders.Length > 0) { Vector3 testPoint = pointer.Rays[i].Origin; GameObject closest = null; float closestDistance = Mathf.Infinity; Vector3 objectHitPoint = testPoint; foreach (Collider collider in colliders) { // Policy: in order for an collider to be near interactable it must have // a NearInteractionGrabbable component on it. // FIXME: This is assuming only the grab pointer is using SceneQueryType.SphereOverlap, // but there may be other pointers using the same query type which have different semantics. if (collider.GetComponent <NearInteractionGrabbable>() == null) { continue; } // From https://docs.unity3d.com/ScriptReference/Collider.ClosestPoint.html // If location is in the collider the closestPoint will be inside. Vector3 closestPointToCollider = collider.ClosestPoint(testPoint); float distance = (testPoint - closestPointToCollider).sqrMagnitude; if (distance < closestDistance) { closestDistance = distance; closest = collider.gameObject; objectHitPoint = closestPointToCollider; } } if (closest != null) { hit.Set(closest, objectHitPoint, Vector3.zero, pointer.Rays[i], 0, closestDistance); return; } } break; default: Debug.LogError($"Invalid raycast mode {pointer.SceneQueryType} for {pointer.PointerName} pointer."); break; } rayStartDistance += pointer.Rays[i].Length; } }