public void UpdateData() { #if UNITY_ANDROID && !UNITY_EDITOR // Running on Android device. // Update controller state. GvrBasePointer pointer = GvrPointerInputModule.Pointer; bool isPointerAvailable = pointer != null && pointer.IsAvailable; if (isPointerAvailable) { GvrControllerInputDevice controllerInputDevice = pointer.ControllerInputDevice; if (controllerInputDevice != null && controllerInputDevice.State == GvrConnectionState.Connected) { bool pressed = controllerInputDevice.GetButton(GvrControllerButton.TouchPadButton); gvr_keyboard_update_button_state(keyboard_context, kGvrControllerButtonClick, pressed); // Update touch state Vector2 touch_pos = controllerInputDevice.TouchPos; IntPtr touch_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(touch_pos)); Marshal.StructureToPtr(touch_pos, touch_ptr, true); bool isTouching = controllerInputDevice.GetButton(GvrControllerButton.TouchPadTouch); gvr_keyboard_update_controller_touch(keyboard_context, isTouching, touch_ptr); GvrBasePointer.PointerRay pointerRay = pointer.GetRayForDistance(currentDistance); Vector3 startPoint = pointerRay.ray.origin; // Need to flip Z for native library startPoint.z *= -1; IntPtr start_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(startPoint)); Marshal.StructureToPtr(startPoint, start_ptr, true); Vector3 endPoint = pointerRay.ray.GetPoint(pointerRay.distance); // Need to flip Z for native library endPoint.z *= -1; IntPtr end_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(endPoint)); Marshal.StructureToPtr(endPoint, end_ptr, true); Vector3 hit = Vector3.one; IntPtr hit_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(Vector3.zero)); Marshal.StructureToPtr(Vector3.zero, hit_ptr, true); gvr_keyboard_update_controller_ray(keyboard_context, start_ptr, end_ptr, hit_ptr); hit = (Vector3)Marshal.PtrToStructure(hit_ptr, typeof(Vector3)); hit.z *= -1; Marshal.FreeHGlobal(touch_ptr); Marshal.FreeHGlobal(hit_ptr); Marshal.FreeHGlobal(end_ptr); Marshal.FreeHGlobal(start_ptr); } } #endif // UNITY_ANDROID && !UNITY_EDITOR // Get time stamp. gvr_clock_time_point time = gvr_get_time_point_now(); time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; // Update frame data. GvrKeyboardSetFrameData(keyboard_context, time); GL.IssuePluginEvent(renderEventFunction, advanceID); }
private void RaycastDefault(GvrBasePointer pointer, PointerEventData eventData, List <RaycastResult> resultAppendList) { lastRay = GvrBasePointer.CalculateRay(pointer, pointer.raycastMode); float radius = pointer.CurrentPointerRadius; PerformRaycast(lastRay, radius, eventData, resultAppendList); }
private void RaycastHybrid(GvrBasePointer pointer, PointerEventData eventData, List <RaycastResult> resultAppendList) { CurrentRaycastModeForHybrid = GvrBasePointer.RaycastMode.Direct; lastRay = GvrBasePointer.CalculateHybridRay(pointer, CurrentRaycastModeForHybrid); float radius = pointer.CurrentPointerRadius; bool foundHit = PerformRaycast(lastRay, radius, eventData, resultAppendList); if (!foundHit) { CurrentRaycastModeForHybrid = GvrBasePointer.RaycastMode.Camera; lastRay = GvrBasePointer.CalculateHybridRay(pointer, CurrentRaycastModeForHybrid); PerformRaycast(lastRay, radius, eventData, resultAppendList); } }
protected abstract bool PerformRaycast(GvrBasePointer.PointerRay pointerRay, float radius, PointerEventData eventData, List <RaycastResult> resultAppendList);
protected override bool PerformRaycast(GvrBasePointer.PointerRay pointerRay, float radius, PointerEventData eventData, List <RaycastResult> resultAppendList) { if (canvas == null) { return(false); } if (eventCamera == null) { return(false); } if (canvas.renderMode != RenderMode.WorldSpace) { Debug.LogError("GvrPointerGraphicRaycaster requires that the canvas renderMode is set to WorldSpace."); return(false); } float hitDistance = float.MaxValue; if (blockingObjects != BlockingObjects.None) { float dist = pointerRay.distance; if (blockingObjects == BlockingObjects.ThreeD || blockingObjects == BlockingObjects.All) { RaycastHit hit; if (Physics.Raycast(pointerRay.ray, out hit, dist, blockingMask)) { hitDistance = hit.distance; } } if (blockingObjects == BlockingObjects.TwoD || blockingObjects == BlockingObjects.All) { RaycastHit2D hit = Physics2D.Raycast(pointerRay.ray.origin, pointerRay.ray.direction, dist, blockingMask); if (hit.collider != null) { hitDistance = hit.fraction * dist; } } } raycastResults.Clear(); Ray finalRay; Raycast(canvas, pointerRay.ray, eventCamera, pointerRay.distance, raycastResults, out finalRay); bool foundHit = false; for (int index = 0; index < raycastResults.Count; index++) { GameObject go = raycastResults[index].gameObject; bool appendGraphic = true; if (ignoreReversedGraphics) { // If we have a camera compare the direction against the cameras forward. Vector3 cameraFoward = eventCamera.transform.rotation * Vector3.forward; Vector3 dir = go.transform.rotation * Vector3.forward; appendGraphic = Vector3.Dot(cameraFoward, dir) > 0; } if (appendGraphic) { float resultDistance = 0; Transform trans = go.transform; Vector3 transForward = trans.forward; // http://geomalgorithms.com/a06-_intersect-2.html float transDot = Vector3.Dot(transForward, trans.position - pointerRay.ray.origin); float rayDot = Vector3.Dot(transForward, pointerRay.ray.direction); resultDistance = transDot / rayDot; Vector3 hitPosition = pointerRay.ray.origin + (pointerRay.ray.direction * resultDistance); resultDistance = resultDistance + pointerRay.distanceFromStart; // Check to see if the go is behind the camera. if (resultDistance < 0 || resultDistance >= hitDistance || resultDistance > pointerRay.distance) { continue; } Transform pointerTransform = GvrPointerInputModule.Pointer.PointerTransform; float delta = (hitPosition - pointerTransform.position).magnitude; if (delta < pointerRay.distanceFromStart) { continue; } RaycastResult castResult = new RaycastResult { gameObject = go, module = this, distance = resultDistance, worldPosition = hitPosition, worldNormal = pointerRay.ray.direction, screenPosition = eventCamera.WorldToScreenPoint(hitPosition), index = resultAppendList.Count, depth = raycastResults[index].depth, sortingLayer = canvas.sortingLayerID, sortingOrder = canvas.sortingOrder }; resultAppendList.Add(castResult); foundHit = true; } } return(foundHit); }
protected override bool PerformRaycast(GvrBasePointer.PointerRay pointerRay, float radius, PointerEventData eventData, List <RaycastResult> resultAppendList) { if (eventCamera == null) { return(false); } int numHits; if (radius > 0.0f) { numHits = Physics.SphereCastNonAlloc(pointerRay.ray, radius, hits, pointerRay.distance, finalEventMask); } else { numHits = Physics.RaycastNonAlloc(pointerRay.ray, hits, pointerRay.distance, finalEventMask); } if (numHits == 0) { return(false); } if (numHits == MaxRaycastHits) { MaxRaycastHits *= 2; Debug.LogWarningFormat("Physics Raycast/Spherecast returned {0} hits, which is the current " + "maximum and means that some hits may have been lost. Setting maxRaycastHits to {1}. " + "Please set maxRaycastHits to a sufficiently high value for your scene.", numHits, MaxRaycastHits); } Array.Sort(hits, 0, numHits, hitComparer); for (int i = 0; i < numHits; ++i) { Vector3 projection = Vector3.Project(hits[i].point - pointerRay.ray.origin, pointerRay.ray.direction); Vector3 hitPosition = projection + pointerRay.ray.origin; float resultDistance = hits[i].distance + pointerRay.distanceFromStart; Transform pointerTransform = GvrPointerInputModule.Pointer.PointerTransform; float delta = (hitPosition - pointerTransform.position).magnitude; if (delta < pointerRay.distanceFromStart) { continue; } RaycastResult result = new RaycastResult { gameObject = hits[i].collider.gameObject, module = this, distance = resultDistance, worldPosition = hitPosition, worldNormal = hits[i].normal, screenPosition = eventCamera.WorldToScreenPoint(hitPosition), index = resultAppendList.Count, sortingLayer = 0, sortingOrder = 0 }; resultAppendList.Add(result); } return(true); }