private void SetDefaultsForRaycastMode(GvrBasePointer.RaycastMode raycastMode) { switch (raycastMode) { case GvrBasePointer.RaycastMode.Hybrid: mode.intValue = (int)raycastMode; rayIntersection.floatValue = GvrVRHelpers.GetRayIntersection(raycastMode); SetPropertiesForVisual(GvrVRHelpers.GetShrinkLaser(raycastMode), GvrVRHelpers.GetRecommendedMaxLaserDistance(raycastMode)); break; case GvrBasePointer.RaycastMode.Camera: mode.intValue = (int)raycastMode; rayIntersection.floatValue = GvrVRHelpers.GetRayIntersection(raycastMode); SetPropertiesForVisual(GvrVRHelpers.GetShrinkLaser(raycastMode), GvrVRHelpers.GetRecommendedMaxLaserDistance(raycastMode)); break; case GvrBasePointer.RaycastMode.Direct: mode.intValue = (int)raycastMode; rayIntersection.floatValue = GvrVRHelpers.GetRayIntersection(raycastMode); SetPropertiesForVisual(GvrVRHelpers.GetShrinkLaser(raycastMode), GvrVRHelpers.GetRecommendedMaxLaserDistance(raycastMode)); break; default: Debug.LogError("Trying to set defaults for invalid Raycast Mode: " + raycastMode); return; } }
private Quaternion GetYawCorrection() { Quaternion headRotation = GvrVRHelpers.GetHeadRotation(); Vector3 euler = headRotation.eulerAngles; return(lastAppliedYawCorrection * Quaternion.Euler(0.0f, euler.y, 0.0f)); }
/// <summary>Updates the arm model torso direction.</summary> /// <param name="forceImmediate"> /// If `true`, uses the gaze direction, otherwise uses slerp to update the direction smoothly. /// </param> protected virtual void UpdateTorsoDirection(bool forceImmediate) { // Determine the gaze direction horizontally. Vector3 gazeDirection = GvrVRHelpers.GetHeadForward(); gazeDirection.y = 0.0f; gazeDirection.Normalize(); // Use the gaze direction to update the forward direction. if (forceImmediate || (ControllerInputDevice != null && ControllerInputDevice.Recentered)) { torsoDirection = gazeDirection; } else { float angularVelocity = ControllerInputDevice != null ? ControllerInputDevice.Gyro.magnitude : 0; float gazeFilterStrength = Mathf.Clamp((angularVelocity - 0.2f) / 45.0f, 0.0f, 0.1f); torsoDirection = Vector3.Slerp(torsoDirection, gazeDirection, gazeFilterStrength); } // Calculate the torso rotation. torsoRotation = Quaternion.FromToRotation(Vector3.forward, torsoDirection); }
public void rotateToFrontOfView() { //Vector3 headDirection = cardboardHead.transform.forward; Vector3 headDirection = GvrVRHelpers.GetHeadForward(); Vector3 newDirection = new Vector3(headDirection.x, 0, headDirection.z).normalized; transform.rotation = Quaternion.LookRotation(newDirection, Vector3.up); }
private Vector3 CalculatArmRoot(Vector3 headPosition) { Matrix4x4 matrix = Matrix4x4.TRS(headPosition, Quaternion.Euler(0, GvrVRHelpers.GetHeadRotation().eulerAngles.y, 0), Vector3.one); //Quaternion headRotation = IVRManager.Instance.GetHeadRotation(); return(matrix.MultiplyPoint(Vector3.Scale(mArmRootPosition, handedMultiplier))); }
/*#if false * * public MinecraftVR controls; * * public float sensitivity = .55f; * public float inverted = -1f; * * private float headRotationX, headRotationY; * private readonly float headRotationLimit = 90f; * * void Start() * { * } * * protected void Awake() => controls = new MinecraftVR(); * protected void OnEnable() => controls.Enable(); * protected void OnDisable() => controls.Disable(); * * void Update() * { * Vector2 input = controls.Player.Look.ReadValue<Vector2>(); * float x = input.x * sensitivity; * float y = input.y * sensitivity * inverted; * * headRotationY += y; * headRotationX += x; * * headRotationY = Mathf.Clamp(headRotationY, -headRotationLimit, headRotationLimit); * Camera.main.transform.localEulerAngles = new Vector3(headRotationY, headRotationX, 0f); * } * #endif*/ public static Quaternion GetRotation() { #if UNITY_EDITOR return(Camera.main.transform.rotation); #else return(GvrVRHelpers.GetHeadRotation()); #endif }
/// Transform the head position into an approximate neck position. protected virtual Vector3 ApplyInverseNeckModel(Vector3 headPosition) { Quaternion headRotation = GvrVRHelpers.GetHeadRotation(); Vector3 rotatedNeckOffset = headRotation * NECK_OFFSET - NECK_OFFSET.y * Vector3.up; headPosition -= rotatedNeckOffset; return(headPosition); }
/// <summary> /// Controls the transparency of the controller to prevent the controller from clipping through /// the user's head. /// </summary> /// <remarks> /// Also controls the transparency of the tooltips so they are only visible when the controller /// is held up. /// </remarks> protected virtual void UpdateTransparency() { Vector3 controllerForward = controllerRotation * Vector3.forward; Vector3 offsetControllerPosition = controllerPosition + (controllerForward * fadeControllerOffset); Vector3 controllerRelativeToHead = offsetControllerPosition - neckPosition; Vector3 headForward = GvrVRHelpers.GetHeadForward(); float distanceToHeadForward = Vector3.Scale(controllerRelativeToHead, headForward).magnitude; Vector3 headRight = Vector3.Cross(headForward, Vector3.up); float distanceToHeadSide = Vector3.Scale(controllerRelativeToHead, headRight).magnitude; float distanceToHeadUp = Mathf.Abs(controllerRelativeToHead.y); bool shouldFadeController = distanceToHeadForward < fadeDistanceFromHeadForward && distanceToHeadUp < fadeDistanceFromHeadForward && distanceToHeadSide < fadeDistanceFromHeadSide; // Determine how vertical the controller is pointing. float animationDelta = DELTA_ALPHA * Time.unscaledDeltaTime; if (shouldFadeController) { preferredAlpha = Mathf.Max(0.0f, preferredAlpha - animationDelta); } else { preferredAlpha = Mathf.Min(1.0f, preferredAlpha + animationDelta); } float dot = Vector3.Dot(controllerRotation * Vector3.up, -controllerRelativeToHead.normalized); float minDot = (tooltipMaxAngleFromCamera - 90.0f) / -90.0f; float distToFace = Vector3.Distance(controllerRelativeToHead, Vector3.zero); if (shouldFadeController || distToFace > tooltipMinDistanceFromFace || dot < minDot) { tooltipAlphaValue = Mathf.Max(0.0f, tooltipAlphaValue - animationDelta); } else { tooltipAlphaValue = Mathf.Min(1.0f, tooltipAlphaValue + animationDelta); } }
private void UpdateTransparency() { Vector3 wristRelativeToHead = wristPosition - GvrVRHelpers.GetHeadPosition(); float animationDelta = DELTA_ALPHA * Time.deltaTime; float distToFace = Vector3.Distance(wristRelativeToHead, Vector3.zero); if (distToFace < fadeDistanceFromFaceToHand) { handAlpha = Mathf.Max(0.0f, handAlpha - animationDelta); } else { handAlpha = Mathf.Min(1.0f, handAlpha + animationDelta); } }
protected virtual void UpdateNeckPosition() { if (isLockedToNeck) { // Returns the center of the eyes. // However, we actually want to lock to the center of the head. neckPosition = GvrVRHelpers.GetHeadPosition(); // Find the approximate neck position by Applying an inverse neck model. // This transforms the head position to the center of the head and also accounts // for the head's rotation so that the motion feels more natural. neckPosition = ApplyInverseNeckModel(neckPosition); } else { neckPosition = Vector3.zero; } }
private void CastRay() { Vector2 currentPose = lastPose; if (IsPointerActiveAndAvailable()) { currentPose = GvrMathHelpers.NormalizedCartesianToSpherical(Pointer.PointerTransform.forward); } if (CurrentEventData == null) { CurrentEventData = new PointerEventData(ModuleController.eventSystem); lastPose = currentPose; } // Store the previous raycast result. RaycastResult previousRaycastResult = CurrentEventData.pointerCurrentRaycast; // The initial cast must use the enter radius. if (IsPointerActiveAndAvailable()) { Pointer.ShouldUseExitRadiusForRaycast = false; } // Cast a ray into the scene CurrentEventData.Reset(); // Set the position to the center of the camera. // This is only necessary if using the built-in Unity raycasters. RaycastResult raycastResult; CurrentEventData.position = GvrVRHelpers.GetViewportCenter(); bool isPointerActiveAndAvailable = IsPointerActiveAndAvailable(); if (isPointerActiveAndAvailable) { RaycastAll(); raycastResult = ModuleController.FindFirstRaycast(ModuleController.RaycastResultCache); } else { raycastResult = new RaycastResult(); raycastResult.Clear(); } // If we were already pointing at an object we must check that object against the exit radius // to make sure we are no longer pointing at it to prevent flicker. if (previousRaycastResult.gameObject != null && raycastResult.gameObject != previousRaycastResult.gameObject && isPointerActiveAndAvailable) { Pointer.ShouldUseExitRadiusForRaycast = true; RaycastAll(); RaycastResult firstResult = ModuleController.FindFirstRaycast(ModuleController.RaycastResultCache); if (firstResult.gameObject == previousRaycastResult.gameObject) { raycastResult = firstResult; } } if (raycastResult.gameObject != null && raycastResult.worldPosition == Vector3.zero) { raycastResult.worldPosition = GvrMathHelpers.GetIntersectionPosition(CurrentEventData.enterEventCamera, raycastResult); } CurrentEventData.pointerCurrentRaycast = raycastResult; // Find the real screen position associated with the raycast // Based on the results of the hit and the state of the pointerData. if (raycastResult.gameObject != null) { CurrentEventData.position = raycastResult.screenPosition; } else if (IsPointerActiveAndAvailable() && CurrentEventData.enterEventCamera != null) { Vector3 pointerPos = Pointer.MaxPointerEndPoint; CurrentEventData.position = CurrentEventData.enterEventCamera.WorldToScreenPoint(pointerPos); } ModuleController.RaycastResultCache.Clear(); CurrentEventData.delta = currentPose - lastPose; lastPose = currentPose; // Check to make sure the Raycaster being used is a GvrRaycaster. /*if (raycastResult.module != null * && !(raycastResult.module is GvrPointerGraphicRaycaster) * && !(raycastResult.module is GvrPointerPhysicsRaycaster)) { * Debug.LogWarning("Using Raycaster (Raycaster: " + raycastResult.module.GetType() + * ", Object: " + raycastResult.module.name + "). It is recommended to use " + * "GvrPointerPhysicsRaycaster or GvrPointerGrahpicRaycaster with GvrPointerInputModule."); * }*/ }
// Update is called once per frame void Update() { // Set opacities initially to 0 Color UnintrusiveLeftColor = UnintrusiveLeft.GetComponent <MeshRenderer>().material.color; UnintrusiveLeft.GetComponent <MeshRenderer>().material.color = new Color(UnintrusiveLeftColor.r, UnintrusiveLeftColor.g, UnintrusiveLeftColor.b, 0); Color LeftMaxColor = LeftMax.GetComponent <MeshRenderer>().material.color; LeftMax.GetComponent <MeshRenderer>().material.color = new Color(LeftMaxColor.r, LeftMaxColor.g, LeftMaxColor.b, 0); Color UnintrusiveRightColor = UnintrusiveRight.GetComponent <MeshRenderer>().material.color; UnintrusiveRight.GetComponent <MeshRenderer>().material.color = new Color(UnintrusiveRightColor.r, UnintrusiveRightColor.g, UnintrusiveRightColor.b, 0); Color RightMaxColor = RightMax.GetComponent <MeshRenderer>().material.color; RightMax.GetComponent <MeshRenderer>().material.color = new Color(RightMaxColor.r, RightMaxColor.g, RightMaxColor.b, 0); Color RotateLeftColor = RotateLeft.GetComponent <MeshRenderer>().material.color; RotateLeft.GetComponent <MeshRenderer>().material.color = new Color(RotateLeftColor.r, RotateLeftColor.g, RotateLeftColor.b, 0); Color RotateRightColor = RotateRight.GetComponent <MeshRenderer>().material.color; RotateRight.GetComponent <MeshRenderer>().material.color = new Color(RotateRightColor.r, RotateRightColor.g, RotateRightColor.b, 0); if (solution == Solution.Panels) { float reticleDistanceLeft = 1 - (Vector3.Distance(RotateLeft.transform.position, reticlePointer.PointerTransform.forward * reticlePointer.maxReticleDistance) - 1.75f); float reticleDistanceRight = 1 - (Vector3.Distance(RotateRight.transform.position, reticlePointer.PointerTransform.forward * reticlePointer.maxReticleDistance) - 1.75f); reticleDistanceLeft = Mathf.Clamp(reticleDistanceLeft, 0, 0.25f) * 4; reticleDistanceRight = Mathf.Clamp(reticleDistanceRight, 0, 0.25f) * 4; if (cameraControl.intrusivePanels) // Activate "intrusive" panels { Material[] leftMats = RotateLeft.GetComponent <Renderer>().materials; leftMats[0] = leftOpaquePanel; RotateLeft.GetComponent <Renderer>().materials = leftMats; RotateLeft.GetComponent <MeshRenderer>().material.color = new Color(RotateLeftColor.r, RotateLeftColor.g, RotateLeftColor.b, 0); Material[] rightMats = RotateRight.GetComponent <Renderer>().materials; rightMats[0] = rightOpaquePanel; RotateRight.GetComponent <Renderer>().materials = rightMats; RotateRight.GetComponent <MeshRenderer>().material.color = new Color(RotateRightColor.r, RotateRightColor.g, RotateRightColor.b, 0); } else { Material[] leftMats = RotateLeft.GetComponent <Renderer>().materials; leftMats[0] = leftPanel; RotateLeft.GetComponent <Renderer>().materials = leftMats; RotateLeft.GetComponent <MeshRenderer>().material.color = new Color(RotateLeftColor.r, RotateLeftColor.g, RotateLeftColor.b, 0); Material[] rightMats = RotateRight.GetComponent <Renderer>().materials; rightMats[0] = rightPanel; RotateRight.GetComponent <Renderer>().materials = rightMats; RotateRight.GetComponent <MeshRenderer>().material.color = new Color(RotateRightColor.r, RotateRightColor.g, RotateRightColor.b, 0); } if (GetComponent <CameraControl>().gradientsOn) { // Left side float LeftMaxOpacity = Mathf.Clamp(RotateLeft.GetComponent <PanelBehavior>().rotationSpeed, 3, 5) - 3; if (!greensOff) { UnintrusiveLeft.GetComponent <MeshRenderer>().material.color = new Color(UnintrusiveLeftColor.r, UnintrusiveLeftColor.g, UnintrusiveLeftColor.b, RotateLeft.GetComponent <PanelBehavior>().rotationSpeed * 0.2f); } LeftMax.GetComponent <MeshRenderer>().material.color = new Color(LeftMaxColor.r, LeftMaxColor.g, LeftMaxColor.b, LeftMaxOpacity); // Right side float RightMaxOpacity = Mathf.Clamp(RotateRight.GetComponent <PanelBehavior>().rotationSpeed, 3, 5) - 3; if (!greensOff) { UnintrusiveRight.GetComponent <MeshRenderer>().material.color = new Color(UnintrusiveRightColor.r, UnintrusiveRightColor.g, UnintrusiveRightColor.b, RotateRight.GetComponent <PanelBehavior>().rotationSpeed * 0.2f); } RightMax.GetComponent <MeshRenderer>().material.color = new Color(RightMaxColor.r, RightMaxColor.g, RightMaxColor.b, RightMaxOpacity); } if (visiblePanels) { RotateLeft.GetComponent <MeshRenderer>().material.color = new Color(RotateLeftColor.r, RotateLeftColor.g, RotateLeftColor.b, reticleDistanceLeft); RotateRight.GetComponent <MeshRenderer>().material.color = new Color(RotateRightColor.r, RotateRightColor.g, RotateRightColor.b, reticleDistanceRight); } } else if (solution == Solution.RotationMapping) { if (prevOrigin != orientation) { origin.transform.eulerAngles = new Vector3(origin.transform.eulerAngles.x, orientation, origin.transform.eulerAngles.z); transform.eulerAngles = new Vector3(transform.eulerAngles.x, orientation + Vector3.SignedAngle(transform.forward, origin.transform.forward, transform.up), transform.eulerAngles.z); forward = origin.transform.forward; } //Debug.Log("Head rotation: " + GvrVRHelpers.GetHeadRotation().y); Vector3 reticleDirection = Vector3.Normalize(transform.position + reticlePointer.MaxPointerEndPoint); float orientationAngle = Vector3.SignedAngle(forward, transform.forward, transform.up); float rotationDirection = Vector3.SignedAngle(prevOrientation, reticleDirection, transform.up); //Debug.Log("Orientation angle: " + orientationAngle); //Debug.Log("Angle: " + angle); //Debug.Log(transform.eulerAngles.y); if (orientationAngle > -rotationMappingAngle && rotationDirection < 0) { if (GvrVRHelpers.GetHeadRotation().y * 360 < rotationMappingAngle) { transform.eulerAngles = new Vector3(transform.eulerAngles.x, orientation + GvrVRHelpers.GetHeadRotation().y * 360, transform.eulerAngles.z); } } else if (orientationAngle < rotationMappingAngle && rotationDirection > 0) { if (GvrVRHelpers.GetHeadRotation().y * 360 > -rotationMappingAngle) { transform.eulerAngles = new Vector3(transform.eulerAngles.x, orientation + GvrVRHelpers.GetHeadRotation().y * 360, transform.eulerAngles.z); } } prevOrientation = reticleDirection; prevOrigin = orientation; } }