protected override void Start()
        {
            base.Start();

            if (_deviceOffsetMode == DeviceOffsetMode.Transform && _deviceOrigin == null)
            {
                Debug.LogError("Cannot use the Transform device offset mode without " +
                               "specifying a Transform to use as the device origin.", this);
                _deviceOffsetMode = DeviceOffsetMode.Default;
            }

            if (Application.isPlaying && _mainCamera == null && _temporalWarpingMode != TemporalWarpingMode.Off)
            {
                Debug.LogError("Cannot perform temporal warping with no pre-cull camera.");
            }

            //Get the local tracked pose from the XR Headset so we can calculate the _trackingBaseDeltaPose from it
            var trackedPose = new Pose(XRSupportUtil.GetXRNodeCenterEyeLocalPosition(), XRSupportUtil.GetXRNodeCenterEyeLocalRotation());

            //Find the pose delta from the "local" tracked pose to the actual camera pose, we will use this later on to maintain offsets
            if (!_trackingBaseDeltaPose.HasValue)
            {
                _trackingBaseDeltaPose = _mainCamera.transform.ToLocalPose().mul(trackedPose.inverse());
            }
        }
示例#2
0
    // Update is called once per frame
    void Update()
    {
        _UpdateApplicationLifecycle();

        //If the y / cloud anchor is set, return
        if (m_IsStarted)
        {
            return;
        }

        if (auto_setup)
        {
            UI_Snackbar.text = "Initialize Settings Called";
            SetFloorY(-1f);
            FloorCaptureControl.SetFloorY(-1);
            WorldOriginHelp.SetNoPlanes(true);
            IllusionModeStart();
            m_IsStarted = true;
        }

        // If the player has not touched the screen, we are done with this update.
        Touch touch;

        if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
        {
            return;
        }

        // Should not handle input if the player is pointing on UI.
        if (EventSystem.current.IsPointerOverGameObject(touch.fingerId))
        {
            return;
        }

        // Raycast against the location the player touched to search for planes.
        TrackableHit arcoreHitResult = new TrackableHit();

        m_LastHitPose = null;
        if (WorldOriginHelp.Raycast(touch.position.x, touch.position.y,
                                    TrackableHitFlags.PlaneWithinPolygon, out arcoreHitResult))
        {
            m_LastHitPose = arcoreHitResult.Pose;
        }

        if (m_LastHitPose != null)
        {
            m_WorldOriginAnchor = arcoreHitResult.Trackable.CreateAnchor(arcoreHitResult.Pose);

            SetWorldOrigin(m_WorldOriginAnchor.transform);
            _InstantiateAnchor();


            WorldOriginHelp.SetNoPlanes(true);
            SetFloorY(arcoreHitResult.Pose.position.y);
            FloorCaptureControl.SetFloorY(arcoreHitResult.Pose.position.y);
            IllusionModeStart();
            // UI_Snackbar.text = "Take a picture of only your floor in the frame";
            m_IsStarted = true;
        }
    }
        private void FixedUpdate()
        {
            if (intObj.isActiveAndEnabled)
            {
                if (!_intObjPose0.HasValue)
                {
                    _intObjPose0 = pose;
                }
                else if (!_intObjPose1.HasValue)
                {
                    _intObjPose1 = pose;
                }
                else
                {
                    Utils.Swap(ref _intObjPose0, ref _intObjPose1);
                    _intObjPose1 = pose;
                }
            }
            else
            {
                _intObjPose0 = null;
                _intObjPose1 = null;
            }

            if (_intObjPose0.HasValue && _intObjPose1.HasValue)
            {
                var p0 = _intObjPose0.Value; var p1 = _intObjPose1.Value;
                _intObjDeltaPose
                    = new Pose(p1.position - p0.position,
                               Quaternion.Inverse(p0.rotation) * p1.rotation);
            }
        }
示例#4
0
        void OnPreCull()
        {
      #if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                return;
            }
#endif

            // Get most recent tracked pose.
            Pose trackedPose = new Pose(XRSupportUtil.GetXRNodeCenterEyeLocalPosition(),
                                        XRSupportUtil.GetXRNodeCenterEyeLocalRotation());
            // BEGIN EDIT YUJIN
            if (_useLocalTracking)
            {
                trackedPose = new Pose(transform.localPosition, transform.localRotation);
            }
            // END EDIT YUJIN

            // If we don't know of any pose offset yet, account for it by finding the pose
            // delta from the "local" tracked pose to the actual camera pose.
            if (!_trackingBaseDeltaPose.HasValue)
            {
                _trackingBaseDeltaPose = _cachedCamera.transform.ToLocalPose()
                                         * trackedPose.inverse;
            }

            // This way, we always track a scene-space tracked pose.
            Pose effTransformPose = _trackingBaseDeltaPose.Value * trackedPose;

            transformHistory.UpdateDelay(effTransformPose, _leapController.Now());

            OnPreCullHandTransforms(_cachedCamera);
        }
示例#5
0
    void AnchorButtonPressed()
    {
        TrackableHit arcoreHitResult = new TrackableHit();

        m_LastHitPose = null;
        if (WorldOriginHelp.Raycast(1300, 800,
                                    TrackableHitFlags.PlaneWithinPolygon, out arcoreHitResult))
        {
            m_LastHitPose = arcoreHitResult.Pose;
        }

        if (m_LastHitPose != null)
        {
            m_WorldOriginAnchor = arcoreHitResult.Trackable.CreateAnchor(arcoreHitResult.Pose);

            SetWorldOrigin(m_WorldOriginAnchor.transform);
            _InstantiateAnchor();


            //WorldOriginHelp.SetNoPlanes(true);
            SetFloorY(arcoreHitResult.Pose.position.y);
            IllusionModeStart();
            UI_Snackbar.text = "Take a picture of only your floor in the frame";
            m_IsStarted      = true;
        }
    }
示例#6
0
        /// <summary>
        /// The Unity OnEnable() method.
        /// </summary>
        public void OnEnable()
        {
            _timeSinceStart   = 0.0f;
            _isReturning      = false;
            _isHosting        = false;
            _hitPose          = null;
            _anchorComponent  = null;
            _qualityIndicator = null;
            _cachedComponents.Clear();

            InstructionBar.SetActive(true);
            NamePanel.SetActive(false);
            CopyPanel.SetActive(false);
            InputFieldWarning.SetActive(false);
            ShareButton.gameObject.SetActive(false);
            Controller.PlaneGenerator.SetActive(true);

            switch (Controller.Mode)
            {
            case PersistentCloudAnchorsController.ApplicationMode.Ready:
                ReturnToHomePage("Invalid application mode, returning to home page...");
                break;

            case PersistentCloudAnchorsController.ApplicationMode.Hosting:
            case PersistentCloudAnchorsController.ApplicationMode.Resolving:
                InstructionText.text = "Detecting flat surface...";
                DebugText.text       = "ARCore is preparing for " + Controller.Mode;
                break;
            }
        }
示例#7
0
        /// <summary>
        /// Update function - checks for user input and then creates a cloud anchor wherever the user tapped
        /// </summary>
        void Update()
        {
            Touch touch;

            // If the player has not touched the screen then the update is complete.
            if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
            {
                return;
            }

            // Ignore the touch if it's pointing on UI objects.
            if (EventSystem.current.IsPointerOverGameObject(touch.fingerId))
            {
                return;
            }


            Pose?m_LastHitPose = ASL.ARWorldOriginHelper.GetInstance().Raycast(Input.GetTouch(0).position);

            // If there was a successful hit
            //If we haven't set a cloud anchor yet && we are the Host -> then we can set a cloud anchor
            //Note: ASL does not prevent users from create unlimited cloud anchors, this means if two users create a cloud anchor at the same time
            //With the same ASL object, there is the chance things will become out of sync. This if statement is one way to avoid that synchronization problem
            if (m_LastHitPose != null && ASL.ASLHelper.m_CloudAnchors.Count <= 0 && ASL.GameLiftManager.GetInstance().AmLowestPeer())
            {
                m_ObjectToPairWithCloudAnchor.GetComponent <ASL.ASLObject>().SendAndSetClaim(() =>
                {
                    //Hit result, ASLObject to follow anchor (by becoming a child at (0,0,0), function to call after creation, sync start or not, set world origin or not
                    ASL.ASLHelper.CreateARCoreCloudAnchor(m_LastHitPose, m_ObjectToPairWithCloudAnchor.GetComponent <ASL.ASLObject>(), null, true, false);
                });
            }
        }
示例#8
0
            public ReflectorOptics(Vector3 pupilPosition,
                                   EllipsoidTransform ellipse,
                                   Transform Screen,
                                   Vector4 projectionParameters,
                                   Pose?headsetOrigin = null,
                                   Quaternion?optionalPupilRotation = null,
                                   bool updateEllipsoid             = true)
            {
                eyePosition = pupilPosition;

                bool didEllipsoidActuallyUpdate = false;

                if (updateEllipsoid)
                {
                    didEllipsoidActuallyUpdate = ellipse.UpdateEllipsoid();
                }
                sphereToWorldSpace = ellipse.sphereToWorldSpace;

                ellipseMajorAxis = ellipse.MajorAxis;
                ellipseMinorAxis = ellipse.MinorAxis;

                screenForward      = Screen.forward;
                screenPosition     = Screen.position;
                worldToScreenSpace = Screen.worldToLocalMatrix;
                cameraProjection   = projectionParameters;

                eyeRotation = Quaternion.identity;
                if (optionalPupilRotation.HasValue)
                {
                    var pupilRotation = optionalPupilRotation.Value;
                    if (optionalPupilRotation == default(Quaternion))
                    {
                        optionalPupilRotation = Quaternion.identity;
                    }
                    eyeRotation = pupilRotation;
                }

                if (headsetOrigin.HasValue)
                {
                    // If debugging this, helps to draw matrices with:
                    // var drawer = HyperMegaStuff.HyperMegaLines.drawer;
                    // (new Geometry.Sphere(radius)).DrawLines(
                    //   drawer.DrawLine,
                    //   overrideMatrix: aLocalToWorldMatrix);
                    var headsetWorldToLocal = headsetOrigin.Value.inverse.matrix;
                    eyePosition = headsetWorldToLocal.MultiplyPoint3x4(eyePosition);
                    eyeRotation = OpticalCalibrationManager.LossyMatrixMultQuaternion(
                        headsetWorldToLocal, eyeRotation
                        );
                    screenForward = headsetWorldToLocal.MultiplyVector(Screen.forward)
                                    .normalized;
                    screenPosition     = headsetWorldToLocal.MultiplyPoint3x4(Screen.position);
                    worldToScreenSpace = (headsetWorldToLocal * Screen.localToWorldMatrix)
                                         .inverse;
                    if (didEllipsoidActuallyUpdate)
                    {
                        sphereToWorldSpace = headsetWorldToLocal * sphereToWorldSpace;
                    }
                }
            }
示例#9
0
 private void addCloudAnchor()
 {
     // reset view after added cloud anchor
     _hitPose = null;
     OnDisable();
     OnEnable();
 }
示例#10
0
        public void setWorldOriginCloudAnchor()
        {
            TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon;
            TrackableHit      hit           = new TrackableHit();

            if (Application.platform != RuntimePlatform.IPhonePlayer)
            {
                if (ARCoreWorldOriginHelper.Raycast(Screen.width * 0.5f, Screen.height * 0.5f, raycastFilter, out hit))
                {
                    m_LastHitPose = hit.Pose;
                }
            }
            if (m_LastHitPose != null)
            {
                // The first touch on the Hosting mode will instantiate the origin anchor. Any
                // subsequent touch will instantiate a star, both in Hosting and Resolving modes.
                if (!IsOriginPlaced && m_CurrentMode == ApplicationMode.Hosting)   //原點錨
                {
                    if (Application.platform != RuntimePlatform.IPhonePlayer)
                    {
                        m_WorldOriginAnchor =
                            hit.Trackable.CreateAnchor(hit.Pose);
                    }

                    SetWorldOrigin(m_WorldOriginAnchor.transform);  //定義世界原點
                    _InstantiateAnchor();
                    OnAnchorInstantiated(true);
                    CloudAnchorSight.SetActive(false);
                }
            }
        }
示例#11
0
 /// <summary>
 /// Life-Cycle method.
 /// Called right before the objects are drawn.
 /// Ensures the hand is correctly visually attached to the snapped object.
 /// </summary>
 private void OnBeforeRender()
 {
     if (IsSnapping)
     {
         _prevOffset = this.transform.GetPose();
         this.puppet.LerpGripOffset(_grabPose.Pose, 1f, _grabSnap.RelativeTo);
     }
 }
示例#12
0
 /// <summary>
 /// Life-Cycle method.
 /// Called after rendering happens and before the next frame.
 /// For physics purposes, makes sure the hand stays at the user position before FixedUpdate
 /// gets called (first of the next frame).
 /// </summary>
 private void OnEndOfFrame()
 {
     if (_prevOffset.HasValue)
     {
         this.transform.SetPose(_prevOffset.Value);
         _prevOffset = null;
     }
 }
示例#13
0
        public override void SyncRemoveItem(ItemData item, int slotId, Pose?pose)
        {
            if (!pose.HasValue)
            {
                return;
            }
            var value = pose.Value;

            ItemInstance.transform.SetParent(null);
            ItemInstance.transform.SetPositionAndRotation(value.position, value.rotation);
        }
示例#14
0
        void OnMainUp()
        {
            startRemotePose = node.Transform.AsPose();
            startLocalPose  = controllerTransform.AsPose();
            Pose newRegTransform = startLocalPose.Multiply(startRemotePose.Inverse());

            //Pose newRegTransform = startRemotePose.Inverse().Multiply(startLocalPose);
            //newRegTransform.rotation = Quaternion.Euler(0, newRegTransform.rotation.eulerAngles.y, 0);

            regTransform = newRegTransform;
        }
示例#15
0
 public Plane(Vector3 center, Direction3 normal)
 {
     _cachedCenter          = null;
     _cachedNormal          = null;
     _cachedMatrix          = null;
     _cachedPose            = null;
     _cachedTransformMatrix = null;
     this.center            = center;
     this.normal            = normal;
     this.transform         = null;
 }
        private void processHand(Hand hand,
                                 ref Pose?maybeCurPose,
                                 ref Pose?maybePrevPose,
                                 ref float handAge)
        {
            if (hand == null)
            {
                // Clear state.
                maybeCurPose  = null;
                maybePrevPose = null;
                handAge       = 0f;
            }
            else
            {
                var framePose = hand.GetPalmPose();

                if (!maybeCurPose.HasValue)
                {
                    // The hand just started being tracked.
                    maybePrevPose = null;
                    maybeCurPose  = framePose;
                }
                else if (!maybePrevPose.HasValue)
                {
                    // Have current pose, lack previous pose, just get initial momentum.
                    maybePrevPose = maybeCurPose;
                    maybeCurPose  = framePose;
                }
                else
                {
                    // There's enough data to verlet-integrate.

                    // Calculate how much time has passed since we last received hand data.
                    //
                    // As a safety measure, we ensure deltaTime is positive before running our
                    // stateful filter to give the hand momentum. Any post-process could mess with
                    // the TimeVisible property, so we do this to minimize the chance of total
                    // havok.
                    var deltaTime = hand.TimeVisible - handAge;
                    if (deltaTime > 0)
                    {
                        handAge = hand.TimeVisible;

                        var curPose  = maybeCurPose.Value;
                        var prevPose = maybePrevPose.Value;
                        integratePose(ref curPose, ref prevPose,
                                      targetPose: framePose, deltaTime: deltaTime);
                        hand.SetPalmPose(curPose);
                        maybeCurPose  = curPose;
                        maybePrevPose = prevPose;
                    }
                }
            }
        }
示例#17
0
        // Mouse click selection
        void FingerSelect()
        {
            Touch touch;

            // If the player has not touched the screen then the update is complete.
            if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
            {
                return;
            }

            if (!EventSystem.current.IsPointerOverGameObject(touch.fingerId)) // check for GUI
            {
                //Ray cast to check hit location
                RaycastHit hitInfo = new RaycastHit();
                bool       hit     = Physics.Raycast(MainCamera.ScreenPointToRay(Input.GetTouch(0).position), out hitInfo, Mathf.Infinity, 1);

                if (hit)// if we hit a game object (does not detect if we hit a trackable plane to set cloud anchor)
                {
                    SelectObject(hitInfo.transform.gameObject);
                }
                else //if we did not hit a game object
                {
                    //If we haven't set a cloud anchor yet && we are the Host -> then we can set a cloud anchor
                    //Note: ASL does not prevent users from create unlimited cloud anchors, this means if two users create a cloud anchor at the same time
                    //With the same ASL object, there is the chance things will become out of sync. This if statement is one way to avoid that synchronization problem
                    if (ASL.ASLHelper.m_CloudAnchors.Count <= 0 && ASL.GameSparksManager.Instance().AmLowestPeer())
                    {
                        TrackableHit arcoreHitResult = new TrackableHit();
                        Pose?        m_LastHitPose   = null;

                        // Raycast against the location the player touched to search for planes. -> used for setting cloud anchor
                        if (ASL.ARWorldOriginHelper.Instance().Raycast(touch.position.x, touch.position.y,
                                                                       TrackableHitFlags.PlaneWithinPolygon, out arcoreHitResult))
                        {
                            m_LastHitPose = arcoreHitResult.Pose;
                        }

                        // If there was a successful hit on a trackable plane -> create a cloud anchor
                        if (m_LastHitPose != null)
                        {
                            DetermineCloudAnchorCreationStyle(arcoreHitResult);
                        }
                    }
                    else //If we haven't set a cloud anchor in the scene yet
                    {
                        m_CloudAnchorFeedback.text = "";
                        //if we have, then select nothing
                        SelectObject(null);
                    }
                }
            }
        }
示例#18
0
 public static InteractiveMarker Create(string name, Pose?pose = null, string description = "", float scale = 1,
                                        string frameId         = "", params InteractiveMarkerControl[] controls)
 {
     return(new()
     {
         Header = frameId,
         Name = name,
         Description = description,
         Pose = pose ?? Pose.Identity,
         Scale = scale,
         Controls = controls
     });
 }
示例#19
0
      public void FillPositions(List<Vector3> positions, Pose? pose) {
        positions.Clear();

        var effPose = pose.HasValue ? pose.Value : Pose.identity;

        var angle = 360f / numSegments;
        var rot = Quaternion.AngleAxis(angle, effPose.rotation.GetForward());
        var R = effPose.rotation.GetRight() * radius;
        for (int i = 0; i < numSegments; i++) {
          positions.Add(R + effPose.position);
          R = rot * R;
        }
      }
    private void ShowCursorAt(Vector3 cursorPos)
    {
        if (!_cursor.activeSelf)
        {
            _cursor.SetActive(true);
        }

        var cameraPos = CameraCache.Transform.position;

        _cursor.transform.position = cursorPos;
        _cursor.transform.LookAt(new Vector3(cameraPos.x, cursorPos.y, cameraPos.z));
        _pose = _cursor.transform.ToPose();
    }
 private void Update()
 {
     if (shakaGesture.isActive && pinchGesture.isActive)
     {
         if (_lastPose.HasValue)
         {
             moveTarget(_lastPose.Value, pinchGesture.pose);
         }
         _lastPose = pinchGesture.pose;
     }
     else
     {
         _lastPose = null;
     }
 }
        private void Update()
        {
            if (!calibrated)
            {
                calibrated = true;

                this.savedLeftController     = this.GetBeatSaberDevicePosition(this.leftController);
                this.savedLeftSaber.position = saberManager.leftSaber.transform.position;
                this.savedLeftSaber.rotation = saberManager.leftSaber.transform.rotation;

                this.savedRightController     = this.GetBeatSaberDevicePosition(this.rightController);
                this.savedRightSaber.position = saberManager.rightSaber.transform.position;
                this.savedRightSaber.rotation = saberManager.rightSaber.transform.rotation;
            }
        }
        public Pose GetRightSaberPose()
        {
            if (!calibrated || !this.rightController.isValid)
            {
                return(new Pose());
            }

            Pose?rightControllerPose = this.GetBeatSaberDevicePosition(this.rightController);

            if (rightControllerPose == null)
            {
                return(new Pose());
            }

            return(TrackedDeviceManager.GetTrackedObjectPose(this.savedRightSaber, this.savedRightController.Value, rightControllerPose.Value));
        }
示例#24
0
        protected virtual void onPreCull(Camera preCullingCamera)
        {
            if (preCullingCamera != preCullCamera)
            {
                return;
            }

      #if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                return;
            }
      #endif

            Pose trackedPose;
            if (_deviceOffsetMode == DeviceOffsetMode.Default ||
                _deviceOffsetMode == DeviceOffsetMode.ManualHeadOffset)
            {
                // Get most recent tracked pose from the XR subsystem.
                trackedPose = new Pose(XRSupportUtil.GetXRNodeCenterEyeLocalPosition(),
                                       XRSupportUtil.GetXRNodeCenterEyeLocalRotation());

                // If we don't know of any pose offset yet, account for it by finding
                // the pose delta from the "local" tracked pose to the actual camera
                // pose.
                if (!_trackingBaseDeltaPose.HasValue)
                {
                    _trackingBaseDeltaPose = _cachedCamera.transform.ToLocalPose()
                                             * trackedPose.inverse;
                }
                // This way, we always track a scene-space tracked pose.
                trackedPose = _trackingBaseDeltaPose.Value * trackedPose;
            }
            else if (_deviceOffsetMode == DeviceOffsetMode.Transform)
            {
                trackedPose = deviceOrigin.ToPose();
            }
            else
            {
                Debug.LogError("Unsupported DeviceOffsetMode: " + _deviceOffsetMode);
                return;
            }

            transformHistory.UpdateDelay(trackedPose, _leapController.Now());

            OnPreCullHandTransforms(_cachedCamera);
        }
示例#25
0
            public OpticalSystem(Camera eyePerspective,
                                 EllipsoidTransform ellipse,
                                 Transform Screen,
                                 Pose?headsetOrigin = null)
            {
                eyePosition = eyePerspective.transform.position;

                bool didEllipsoidActuallyUpdate = ellipse.UpdateEllipsoid(); // Sigh.

                sphereToWorldSpace = ellipse.sphereToWorldSpace;
                worldToSphereSpace = ellipse.worldToSphereSpace;

                ellipseMajorAxis   = ellipse.MajorAxis;
                ellipseMinorAxis   = ellipse.MinorAxis;
                screenForward      = Screen.forward;
                screenPosition     = Screen.position;
                worldToScreenSpace = Screen.worldToLocalMatrix;
                clipToWorld        = eyePerspective.cameraToWorldMatrix *
                                     eyePerspective.projectionMatrix.inverse;

                Debug.Log(eyePerspective.projectionMatrix);

                if (headsetOrigin.HasValue)
                {
                    // If debugging this, helps to draw matrices with:
                    // var drawer = HyperMegaStuff.HyperMegaLines.drawer;
                    // (new Geometry.Sphere(radius)).DrawLines(
                    //   drawer.DrawLine,
                    //   overrideMatrix: aLocalToWorldMatrix);
                    var headsetWorldToLocal = headsetOrigin.Value.inverse.matrix;
                    eyePosition = headsetWorldToLocal.MultiplyPoint3x4(eyePosition);

                    screenForward = headsetWorldToLocal.MultiplyVector(Screen.forward)
                                    .normalized;
                    screenPosition     = headsetWorldToLocal.MultiplyPoint3x4(Screen.position);
                    worldToScreenSpace = (headsetWorldToLocal * Screen.localToWorldMatrix)
                                         .inverse;
                    clipToWorld = headsetWorldToLocal * clipToWorld;

                    if (didEllipsoidActuallyUpdate)
                    {
                        sphereToWorldSpace = headsetWorldToLocal * sphereToWorldSpace;
                        worldToSphereSpace = sphereToWorldSpace.inverse;
                    }
                }
            }
示例#26
0
        public static bool TryFindDetectedPlane(Touch touch, Vector2 touchPosition, out Pose?hitPose)
        {
            if (IsUItouched(touch))
            {
                hitPose = null;
                return(false);
            }

            TrackableHit      hit;
            TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
                                              TrackableHitFlags.FeaturePointWithSurfaceNormal;

            if (Frame.Raycast(touchPosition.x, touchPosition.y, raycastFilter, out hit))
            {
                if ((hit.Trackable is DetectedPlane) &&
                    Vector3.Dot(Camera.main.transform.position - hit.Pose.position, hit.Pose.rotation * Vector3.up) < 0)
                {
                    Debug.Log("Hit at back of the current DetectedPlane");
                }
                else
                {
                    if (hit.Trackable is DetectedPlane)
                    {
                        DetectedPlane detectedPlane = hit.Trackable as DetectedPlane;
                        if (detectedPlane.PlaneType == DetectedPlaneType.Vertical)
                        {
                            hitPose = null;
                            return(true);
                        }
                        else
                        {
                            hitPose = new Pose(hit.Pose.position, hit.Pose.rotation);
                            return(true);
                        }
                    }
                    else
                    {
                        hitPose = null;
                        return(false);
                    }
                }
            }
            hitPose = null;
            return(false);
        }
示例#27
0
        void OnMainDown()
        {
            if (controller == null)
            {
                controller          = Instantiate(controllerTemplate);
                controllerTransform = controller.transform;
            }

            regTransform = null;

            controller.SetActive(true);

            Vector3 forward = Settings.MainCameraTransform.forward.WithY(0).normalized;

            controllerTransform.parent   = null;
            controllerTransform.position = Settings.MainCameraTransform.position + forward * 1 + Vector3.up * -0.3f;
            controllerTransform.rotation = Quaternion.Euler(0, Settings.MainCameraTransform.eulerAngles.y, 0);
        }
        /// <summary>
        /// Gets the position of the device but factors in the room rotation of Beat Saber into the return.
        /// It requires the <see cref="MainSettingsModelSO" /> which can be found by calling
        /// Resources.FindObjectsOfTypeAll<MainSettingsModelSO>().FirstOrDefault();
        /// </summary>
        private Pose?GetBeatSaberDevicePosition(InputDevice device)
        {
            Pose?devicePose = TrackedDeviceManager.GetDevicePose(device);

            if (devicePose == null)
            {
                return(null);
            }

            var roomCenter   = this.mainSettingsModel.roomCenter;
            var roomRotation = Quaternion.Euler(0, this.mainSettingsModel.roomRotation, 0);

            Pose newDevicePose = devicePose.Value;

            newDevicePose.position  = roomRotation * devicePose.Value.position;
            newDevicePose.position += roomCenter;
            newDevicePose.rotation  = roomRotation * devicePose.Value.rotation;
            return(newDevicePose);
        }
示例#29
0
    void Update()
    {
        if (!GameVariables.isRayCasting)
        {
            return;
        }

        if (Application.platform == RuntimePlatform.Android)
        {
            // Gets the touch position
            Pose?touchPose = GetTouch();

            // Updates level to touch position
            gameObject.GetComponent <ASL.ASLObject>().SendAndSetClaim(() =>
            {
                gameObject.GetComponent <ASL.ASLObject>().SendAndSetWorldPosition((Vector3)touchPose?.position);
            });
        }
    }
示例#30
0
        /// <summary>
        /// Creates an ARCore Cloud Anchor at the location the user tapped and passed into it. This function can be used to set the world origin or just a normal cloud anchor.
        /// It is advisable to only have 1 user in your application set cloud anchors.
        /// </summary>
        /// <param name="_hitResults">Holds information about where the user tapped on the screen. This variable should be created using the ARWorldOriginHelper Raycast method </param>
        /// <param name="_anchorObjectPrefab">The ASL object you want to have located at the cloud anchor. If you don't want any object to be located at the cloud anchor, you can pass in null.
        /// Doing so will create an empty gameobject - thus making it invisible to users</param>
        /// <param name="_myPostCreateCloudAnchorFunction">This is the function you want to call after a cloud anchor has successfully been created. Only the user that called this function
        /// will execute this function - it is not sent to other users. This is a good way to move or create objects after a cloud anchor has been created.</param>
        /// <param name="_waitForAllUsersToResolve">This determines if users should wait to setup (and if they are the caller of this function, to execute the _myPostCreateCloudAnchorFunction)
        /// the cloud anchor once they receive and find it, or if they should wait for all users to receive and find it first before executing anything. The default is to wait for all users
        /// and is the suggested value as not waiting as the potential to cause synchronization problems.</param>
        /// <param name="_setWorldOrigin">This determines if this cloud anchor should be used to set the world origin for all users or not. If you are setting the world origin, you should do
        /// so right away in your app and as the first (if you have more than 1) cloud anchor created. You should never set the world origin more than once.</param>
        public static void CreateARCoreCloudAnchor(Pose?_hitResults, ASLObject _anchorObjectPrefab = null, ASLObject.PostCreateCloudAnchorFunction _myPostCreateCloudAnchorFunction = null,
                                                   bool _waitForAllUsersToResolve = true, bool _setWorldOrigin = true)
        {
#if UNITY_ANDROID || UNITY_IOS
            if (m_ARCloudAnchor != null)
            {
                Debug.LogError("You can only resolve 1 Cloud Anchor at a time. " + m_ARCloudAnchor.name + " is currently being resolved...");
                return;
            }
            if (_anchorObjectPrefab != null)
            {
                if (!_anchorObjectPrefab.m_Mine)
                {
                    Debug.LogError("You must claim the ASL object before setting it as an anchor");
                    return;
                }
            }
            Debug.Log("Creating the cloud anchor now...");

            //Create local anchor at hit location
            ARAnchor localAnchor = ARWorldOriginHelper.GetInstance().m_ARAnchorManager.AddAnchor((Pose)_hitResults);
            localAnchor.name = "Local anchor created when creating cloud anchor";

            //Create CLoud anchor
            m_ARCloudAnchor = ARWorldOriginHelper.GetInstance().m_ARAnchorManager.HostCloudAnchor(localAnchor);

            if (m_ARCloudAnchor == null)
            {
                Debug.LogError("Failed to create a cloud anchor.");
                return;
            }

            ARWorldOriginHelper.GetInstance().StartCoroutine(ARWorldOriginHelper.GetInstance().WaitForCloudAnchorToBeCreated(m_ARCloudAnchor, (Pose)_hitResults,
                                                                                                                             _anchorObjectPrefab, _myPostCreateCloudAnchorFunction,
                                                                                                                             _waitForAllUsersToResolve, _setWorldOrigin));

            //Reset
            m_ARCloudAnchor = null;
#else
            Debug.LogError("Can only create cloud anchors on mobile devices.");
#endif
        }