/// <inheritdoc /> public override void OnPostSceneQuery() { base.OnPostSceneQuery(); LineBase.enabled = IsInteractionEnabled; BaseCursor?.SetVisibility(IsInteractionEnabled); if (!LineBase.enabled) { return; } // The distance the ray travels through the world before it hits something. Measured in world-units (as opposed to normalized distance). float clearWorldLength; Gradient lineColor = LineColorNoTarget; if (Result?.CurrentPointerTarget != null) { // We hit something clearWorldLength = Result.Details.RayDistance; lineColor = LineColorValid; } else { clearWorldLength = DefaultPointerExtent; lineColor = IsSelectPressed ? LineColorSelected : LineColorNoTarget; } if (IsFocusLocked) { lineColor = LineColorLockFocus; } int maxClampLineSteps = LineCastResolution; foreach (BaseMixedRealityLineRenderer lineRenderer in lineRenderers) { // Renderers are enabled by default if line is enabled maxClampLineSteps = Mathf.Max(maxClampLineSteps, lineRenderer.LineStepCount); lineRenderer.LineColor = lineColor; } // Used to ensure the line doesn't extend beyond the cursor float cursorOffsetWorldLength = (BaseCursor != null) ? BaseCursor.SurfaceCursorDistance : 0; // If focus is locked, we're sticking to the target // So don't clamp the world length if (IsFocusLocked && IsTargetPositionLockedOnFocusLock) { float cursorOffsetLocalLength = LineBase.GetNormalizedLengthFromWorldLength(cursorOffsetWorldLength); LineBase.LineEndClamp = 1 - cursorOffsetLocalLength; } else { // Otherwise clamp the line end by the clear distance float clearLocalLength = lineBase.GetNormalizedLengthFromWorldLength(clearWorldLength - cursorOffsetWorldLength, maxClampLineSteps); LineBase.LineEndClamp = clearLocalLength; } }
/// <inheritdoc /> public override void OnPostSceneQuery() { if (IsSelectPressed) { MixedRealityToolkit.InputSystem.RaisePointerDragged(this, MixedRealityInputAction.None, Handedness); } Gradient lineColor = LineColorNoTarget; BaseMixedRealityLineRenderer contextRenderer = null; if (!IsActive) { LineBase.enabled = false; BaseCursor?.SetVisibility(false); return; } contextRenderer = lineRendererNoTarget; LineBase.enabled = true; BaseCursor?.SetVisibility(true); float clearWorldLength; float cursorOffsetWorldLength = (BaseCursor != null) ? BaseCursor.SurfaceCursorDistance : 0; // If we hit something if (Result?.CurrentPointerTarget != null) { clearWorldLength = Result.Details.RayDistance; lineColor = LineColorValid; contextRenderer = lineRendererSelected; } else { clearWorldLength = DefaultPointerExtent; lineColor = IsSelectPressed ? LineColorSelected : LineColorNoTarget; contextRenderer = IsSelectPressed ? lineRendererSelected : lineRendererNoTarget; } if (IsFocusLocked) { lineColor = LineColorLockFocus; contextRenderer = lineRendererSelected; } int maxClampLineSteps = LineCastResolution; foreach (BaseMixedRealityLineRenderer lineRenderer in LineRenderers) { // Otherwise, enable the renderer we chose if (lineRenderer == contextRenderer) { lineRenderer.enabled = true; maxClampLineSteps = Mathf.Max(maxClampLineSteps, lineRenderer.LineStepCount); } else { lineRenderer.enabled = false; } // Set colors on all line renderers regardless of context lineRenderer.LineColor = lineColor; } // If focus and target point is locked, we're sticking to the target // So don't clamp the world length if (IsFocusLocked && IsTargetPositionLockedOnFocusLock) { float cursorOffsetLocalLength = LineBase.GetNormalizedLengthFromWorldLength(cursorOffsetWorldLength); LineBase.LineEndClamp = 1 - cursorOffsetLocalLength; } else { // Otherwise clamp the line end by the clear distance float clearLocalLength = LineBase.GetNormalizedLengthFromWorldLength(clearWorldLength - cursorOffsetWorldLength, maxClampLineSteps); LineBase.LineEndClamp = clearLocalLength; } }
public override void OnPostRaycast() { // Use the results from the last update to set our NavigationResult float clearWorldLength = 0f; TeleportSurfaceResult = TeleportSurfaceResult.None; GravityDistorter.enabled = false; if (IsInteractionEnabled) { LineBase.enabled = true; // If we hit something if (Result.CurrentPointerTarget != null) { // Check if it's in our valid layers if (((1 << Result.CurrentPointerTarget.layer) & ValidLayers.value) != 0) { // See if it's a hot spot if (TeleportHotSpot != null && TeleportHotSpot.IsActive) { TeleportSurfaceResult = TeleportSurfaceResult.HotSpot; // Turn on gravity, point it at hotspot GravityDistorter.WorldCenterOfGravity = TeleportHotSpot.Position; GravityDistorter.enabled = true; } else { // If it's NOT a hotspot, check if the hit normal is too steep // (Hotspots override dot requirements) TeleportSurfaceResult = Vector3.Dot(Result.Details.LastRaycastHit.normal, Vector3.up) > upDirectionThreshold ? TeleportSurfaceResult.Valid : TeleportSurfaceResult.Invalid; } } else if (((1 << Result.CurrentPointerTarget.layer) & InvalidLayers) != 0) { TeleportSurfaceResult = TeleportSurfaceResult.Invalid; } else { TeleportSurfaceResult = TeleportSurfaceResult.None; } // Use the step index to determine the length of the hit for (int i = 0; i <= Result.RayStepIndex; i++) { if (i == Result.RayStepIndex) { if (MixedRealityRaycaster.DebugEnabled) { Color debugColor = TeleportSurfaceResult != TeleportSurfaceResult.None ? Color.yellow : Color.cyan; Debug.DrawLine(Result.StartPoint + Vector3.up * 0.1f, Result.StartPoint + Vector3.up * 0.1f, debugColor); } // Only add the distance between the start point and the hit clearWorldLength += Vector3.Distance(Result.StartPoint, Result.Details.Point); } else if (i < Result.RayStepIndex) { // Add the full length of the step to our total distance clearWorldLength += Rays[i].Length; } } // Clamp the end of the parabola to the result hit's point LineBase.LineEndClamp = LineBase.GetNormalizedLengthFromWorldLength(clearWorldLength, LineCastResolution); BaseCursor?.SetVisibility(TeleportSurfaceResult == TeleportSurfaceResult.Valid || TeleportSurfaceResult == TeleportSurfaceResult.HotSpot); } else { BaseCursor?.SetVisibility(false); LineBase.LineEndClamp = 1f; } // Set the line color for (int i = 0; i < LineRenderers.Length; i++) { LineRenderers[i].LineColor = GetLineGradient(TeleportSurfaceResult); } } else { LineBase.enabled = false; } }
public override void OnPostSceneQuery() { // Use the results from the last update to set our NavigationResult float clearWorldLength = 0f; TeleportSurfaceResult = TeleportSurfaceResult.None; GravityDistorter.enabled = false; if (IsInteractionEnabled) { LineBase.enabled = true; // If we hit something if (Result.CurrentPointerTarget != null) { // Check if it's in our valid layers if (((1 << Result.CurrentPointerTarget.layer) & ValidLayers.value) != 0) { // See if it's a hot spot if (TeleportHotSpot != null && TeleportHotSpot.IsActive) { TeleportSurfaceResult = TeleportSurfaceResult.HotSpot; // Turn on gravity, point it at hotspot GravityDistorter.WorldCenterOfGravity = TeleportHotSpot.Position; GravityDistorter.enabled = true; } else { // If it's NOT a hotspot, check if the hit normal is too steep // (Hotspots override dot requirements) TeleportSurfaceResult = Vector3.Dot(Result.Details.LastRaycastHit.normal, Vector3.up) > upDirectionThreshold ? TeleportSurfaceResult.Valid : TeleportSurfaceResult.Invalid; } } else if (((1 << Result.CurrentPointerTarget.layer) & InvalidLayers) != 0) { TeleportSurfaceResult = TeleportSurfaceResult.Invalid; } else { TeleportSurfaceResult = TeleportSurfaceResult.None; } clearWorldLength = Result.Details.RayDistance; // Clamp the end of the parabola to the result hit's point LineBase.LineEndClamp = LineBase.GetNormalizedLengthFromWorldLength(clearWorldLength, LineCastResolution); BaseCursor?.SetVisibility(TeleportSurfaceResult == TeleportSurfaceResult.Valid || TeleportSurfaceResult == TeleportSurfaceResult.HotSpot); } else { BaseCursor?.SetVisibility(false); LineBase.LineEndClamp = 1f; } // Set the line color for (int i = 0; i < LineRenderers.Length; i++) { LineRenderers[i].LineColor = GetLineGradient(TeleportSurfaceResult); } } else { LineBase.enabled = false; } }