/// <summary>
    /// Raycasts from screen point or camera to the scene colliders.
    /// </summary>
    /// <returns><c>true</c>, if an object was hit, <c>false</c> otherwise.</returns>
    /// <param name="fromInputPos">Whether to use the last input position for the raycast, or not.</param>
    /// <param name="hit">Hit data.</param>
    public bool RaycastToScene(bool fromInputPos, out MultiARInterop.TrackableHit hit)
    {
        hit = new MultiARInterop.TrackableHit();
        if (!isInitialized)
        {
            return(false);
        }

        // ray-cast
        Vector2 screenPos = fromInputPos ? inputPos : new Vector2(Screen.width / 2f, Screen.height / 2f);
        Ray     screenRay = mainCamera.ScreenPointToRay(screenPos);

        hit.rayPos = screenRay.origin;
        hit.rayDir = screenRay.direction;

        RaycastHit rayHit;

        if (Physics.Raycast(screenRay, out rayHit, MultiARInterop.MAX_RAYCAST_DIST, Physics.DefaultRaycastLayers))
        {
            hit.point    = rayHit.point;
            hit.normal   = rayHit.normal;
            hit.distance = rayHit.distance;
            hit.rotation = Quaternion.FromToRotation(Vector3.up, rayHit.normal);

            hit.psObject = rayHit;

            return(true);
        }

        return(false);
    }
    /// <summary>
    /// Raycasts from screen point or camera to the scene colliders, and returns all hits.
    /// </summary>
    /// <returns><c>true</c>, if an object was hit, <c>false</c> otherwise.</returns>
    /// <param name="fromInputPos">Whether to use the last input position for the raycast, or not.</param>
    /// <param name="hits">Array of hit data.</param>
    public bool RaycastAllToScene(bool fromInputPos, out MultiARInterop.TrackableHit[] hits)
    {
        hits = new MultiARInterop.TrackableHit[0];
        if (!isInitialized)
        {
            return(false);
        }

        // ray-cast
        Vector2 screenPos = fromInputPos ? inputPos : new Vector2(Screen.width / 2f, Screen.height / 2f);
        Ray     screenRay = mainCamera.ScreenPointToRay(screenPos);

        RaycastHit[] rayHits = Physics.RaycastAll(screenRay, MultiARInterop.MAX_RAYCAST_DIST, Physics.DefaultRaycastLayers);
        hits = new MultiARInterop.TrackableHit[rayHits.Length];

        for (int i = 0; i < rayHits.Length; i++)
        {
            RaycastHit rayHit = rayHits[i];
            hits[i] = new MultiARInterop.TrackableHit();

            hits[i].rayPos = screenRay.origin;
            hits[i].rayDir = screenRay.direction;

            hits[i].point    = rayHit.point;
            hits[i].normal   = rayHit.normal;
            hits[i].distance = rayHit.distance;
            hits[i].rotation = Quaternion.FromToRotation(Vector3.up, rayHit.normal);

            hits[i].psObject = rayHit;
        }

        return(hits.Length > 0);
    }
    /// <summary>
    /// Raycasts from screen point or camera to the scene colliders, and returns all hits.
    /// </summary>
    /// <returns><c>true</c>, if an object was hit, <c>false</c> otherwise.</returns>
    /// <param name="fromInputPos">Whether to use the last input position for the raycast, or not.</param>
    /// <param name="hit">Array of hit data.</param>
    public bool RaycastAllToScene(bool fromInputPos, out MultiARInterop.TrackableHit[] hits)
    {
        hits = new MultiARInterop.TrackableHit[0];
        if (!isInitialized || !mainCamera)
        {
            return(false);
        }

        // ray-cast
        Ray camRay = GetCameraRay();

        RaycastHit[] rayHits = Physics.RaycastAll(camRay, MultiARInterop.MAX_RAYCAST_DIST, Physics.DefaultRaycastLayers);
        hits = new MultiARInterop.TrackableHit[rayHits.Length];

        for (int i = 0; i < rayHits.Length; i++)
        {
            RaycastHit rayHit = rayHits[i];
            hits[i] = new MultiARInterop.TrackableHit();

            hits[i].rayPos = camRay.origin;
            hits[i].rayDir = camRay.direction;

            hits[i].point    = rayHit.point;
            hits[i].normal   = rayHit.normal;
            hits[i].distance = rayHit.distance;
            hits[i].rotation = Quaternion.FromToRotation(Vector3.up, rayHit.normal);

            hits[i].psObject = rayHit;
        }

        return(hits.Length > 0);
    }
    /// <summary>
    /// Raycasts from screen point or camera to the scene colliders.
    /// </summary>
    /// <returns><c>true</c>, if an object was hit, <c>false</c> otherwise.</returns>
    /// <param name="fromInputPos">Whether to use the last input position for the raycast, or not.</param>
    /// <param name="hit">Hit data.</param>
    public bool RaycastToScene(bool fromInputPos, out MultiARInterop.TrackableHit hit)
    {
        hit = new MultiARInterop.TrackableHit();
        if (!isInitialized || !mainCamera)
        {
            return(false);
        }

        // ray-cast
        Ray camRay = GetCameraRay();

        hit.rayPos = camRay.origin;
        hit.rayDir = camRay.direction;

        RaycastHit rayHit;

        if (Physics.Raycast(camRay, out rayHit, MultiARInterop.MAX_RAYCAST_DIST, Physics.DefaultRaycastLayers))
        {
            hit.point    = rayHit.point;
            hit.normal   = rayHit.normal;
            hit.distance = rayHit.distance;
            hit.rotation = Quaternion.FromToRotation(Vector3.up, rayHit.normal);

            hit.psObject = rayHit;

            return(true);
        }

        return(false);
    }
    /// <summary>
    /// Raycasts from screen point or camera to the scene colliders.
    /// </summary>
    /// <returns><c>true</c>, if an object was hit, <c>false</c> otherwise.</returns>
    /// <param name="fromInputPos">Whether to use the last input position for the raycast, or not.</param>
    /// <param name="hit">Hit data.</param>
    public bool RaycastToScene(bool fromInputPos, out MultiARInterop.TrackableHit hit)
    {
        hit = new MultiARInterop.TrackableHit();
        if (!isInitialized || !mainCamera)
        {
            return(false);
        }

        // ray-cast
        Transform camTransform = mainCamera.transform;
        Ray       camRay       = new Ray(camTransform.position, camTransform.forward);

        hit.rayPos = camRay.origin;
        hit.rayDir = camRay.direction;

        RaycastHit rayHit;

        if (Physics.Raycast(camRay, out rayHit, MultiARInterop.MAX_RAYCAST_DIST, Physics.DefaultRaycastLayers))
        {
            hit.point    = rayHit.point;
            hit.normal   = rayHit.normal;
            hit.distance = rayHit.distance;

            hit.psObject = rayHit;

            return(true);
        }

        return(false);
    }
    /// <summary>
    /// Raycasts from screen point or camera to the world.
    /// </summary>
    /// <returns><c>true</c>, if a plane was hit, <c>false</c> otherwise.</returns>
    /// <param name="screenPos">Screen position.</param>
    /// <param name="hit">Hit data.</param>
    public bool RaycastToWorld(bool fromInputPos, out MultiARInterop.TrackableHit hit)
    {
        hit = new MultiARInterop.TrackableHit();
        if (!isInitialized)
        {
            return(false);
        }

        Vector2 screenPos = fromInputPos ? inputPos : new Vector2(Screen.width / 2f, Screen.height / 2f);
        Ray     screenRay = mainCamera.ScreenPointToRay(screenPos);

        hit.rayPos = screenRay.origin;
        hit.rayDir = screenRay.direction;

        Vector3 viewPos = mainCamera.ScreenToViewportPoint(screenPos);
        ARPoint point   = new ARPoint {
            x = viewPos.x,
            y = viewPos.y
        };

        // prioritize result types
        List <ARHitTestResultType> allowedResultTypes = new List <ARHitTestResultType>();

        allowedResultTypes.Add(ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent);
        //allowedResultTypes.Add(ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingGeometry);

        if (arManager && !arManager.hitTrackedSurfacesOnly)
        {
            allowedResultTypes.Add(ARHitTestResultType.ARHitTestResultTypeExistingPlane);              // infinite planes
            allowedResultTypes.Add(ARHitTestResultType.ARHitTestResultTypeEstimatedHorizontalPlane);
            allowedResultTypes.Add(ARHitTestResultType.ARHitTestResultTypeEstimatedVerticalPlane);
            allowedResultTypes.Add(ARHitTestResultType.ARHitTestResultTypeFeaturePoint);
        }

        foreach (ARHitTestResultType resultType in allowedResultTypes)
        {
            List <ARHitTestResult> hitResults = UnityARSessionNativeInterface.GetARSessionNativeInterface().HitTest(point, resultType);

            if (hitResults.Count > 0)
            {
                foreach (var hitResult in hitResults)
                {
                    if (hitResult.isValid)
                    {
                        hit.point    = UnityARMatrixOps.GetPosition(hitResult.worldTransform);
                        hit.normal   = UnityARMatrixOps.GetRotation(hitResult.worldTransform) * Vector3.up;
                        hit.distance = (float)hitResult.distance;
                        hit.rotation = UnityARMatrixOps.GetRotation(hitResult.worldTransform);
                        //hit.anchorId = hitResult.anchorIdentifier;

                        return(true);
                    }
                }
            }
        }

        return(false);
    }
Exemple #7
0
    /// <summary>
    /// Anchors the game object to world.
    /// </summary>
    /// <returns>The game object to world.</returns>
    /// <param name="gameObj">Game object.</param>
    /// <param name="hit">Trackable hit.</param>
    public string AnchorGameObjectToWorld(GameObject gameObj, MultiARInterop.TrackableHit hit)
    {
        if (arInterface != null)
        {
            return(arInterface.AnchorGameObjectToWorld(gameObj, hit));
        }

        return(string.Empty);
    }
Exemple #8
0
    /// <summary>
    /// Raycasts from screen point or camera to the world.
    /// </summary>
    /// <returns><c>true</c>, if a plane was hit, <c>false</c> otherwise.</returns>
    /// <param name="screenPos">Screen position.</param>
    /// <param name="hit">Hit data.</param>
    public bool RaycastToWorld(bool fromInputPos, out MultiARInterop.TrackableHit hit)
    {
        if (arInterface != null)
        {
            return(arInterface.RaycastToWorld(fromInputPos, out hit));
        }

        hit = new MultiARInterop.TrackableHit();
        return(false);
    }
Exemple #9
0
    /// <summary>
    /// Raycasts from screen point or camera to the scene colliders, and returns all hits.
    /// </summary>
    /// <returns><c>true</c>, if an object was hit, <c>false</c> otherwise.</returns>
    /// <param name="fromInputPos">Whether to use the last input position for the raycast, or not.</param>
    /// <param name="hits">Array of hit data.</param>
    public bool RaycastAllToScene(bool fromInputPos, out MultiARInterop.TrackableHit[] hits)
    {
        if (arInterface != null)
        {
            return(arInterface.RaycastAllToScene(fromInputPos, out hits));
        }

        hits = new MultiARInterop.TrackableHit[0];
        return(false);
    }
    /// <summary>
    /// Raycasts from screen point or camera to the world.
    /// </summary>
    /// <returns><c>true</c>, if a plane was hit, <c>false</c> otherwise.</returns>
    /// <param name="screenPos">Screen position.</param>
    /// <param name="hit">Hit data.</param>
    public bool RaycastToWorld(bool fromInputPos, out MultiARInterop.TrackableHit hit)
    {
        hit = new MultiARInterop.TrackableHit();
        if (!isInitialized || !mainCamera)
        {
            return(false);
        }

        // ray-cast
        Ray camRay = GetCameraRay();

        hit.rayPos = camRay.origin;
        hit.rayDir = camRay.direction;

        int surfaceLayer = MultiARInterop.GetSurfaceLayer();          // LayerMask.NameToLayer("SpatialSurface");
        //Debug.Log("SpatialSurfaceLayer: " + surfaceLayer);
        int layerMask = 1 << surfaceLayer;

        RaycastHit[] rayHits = Physics.RaycastAll(camRay, MultiARInterop.MAX_RAYCAST_DIST, layerMask);

        for (int i = 0; i < rayHits.Length; i++)
        {
            RaycastHit rayHit = rayHits[i];

            // check for child of SpatialMappingCollider
            //if(rayHit.transform.GetComponentInParent<SpatialMappingCollider>() != null)
            if (rayHit.collider != null)
            {
                hit.point    = rayHit.point;
                hit.normal   = rayHit.normal;
                hit.distance = rayHit.distance;
                hit.rotation = Quaternion.FromToRotation(Vector3.up, rayHit.normal);

                hit.psObject = rayHit;
                //Debug.Log(string.Format("Hit {0} at position {1}.", rayHit.collider.gameObject, rayHit.point));

                return(true);
            }
        }

        return(false);
    }
    // returns the model hit by the input ray, or current model if no other was hit
    private Transform GetModelHit()
    {
        MultiARInterop.TrackableHit[] hits;
        if (arManager.RaycastAllToScene(true, out hits))
        {
            MultiARInterop.TrackableHit hit = hits[0];
            RaycastHit rayHit = (RaycastHit)hit.psObject;

            // check for hitting the same model
            if (currentModel != null)
            {
                for (int i = hits.Length - 1; i >= 0; i--)
                {
                    hit    = hits[i];
                    rayHit = (RaycastHit)hit.psObject;

                    if (rayHit.transform == currentModel)
                    {
                        return(currentModel);
                    }
                }
            }

            // check for any of the models
            if (rayHit.transform == model1)
            {
                return(model1);
            }
            else if (rayHit.transform == model2)
            {
                return(model2);
            }
            else if (rayHit.transform == model3)
            {
                return(model3);
            }
        }

        return(currentModel);
    }
    /// <summary>
    /// Anchors the game object to world.
    /// </summary>
    /// <returns>The game object to world.</returns>
    /// <param name="gameObj">Game object.</param>
    /// <param name="hit">Trackable hit.</param>
    public string AnchorGameObjectToWorld(GameObject gameObj, MultiARInterop.TrackableHit hit)
    {
        string anchorId = string.Empty;

        if (hit.psObject != null && hit.psObject is TrackableHit)
        {
            // valid anchor - attach the tracked plane
            TrackableHit intHit = (TrackableHit)hit.psObject;
            Anchor       anchor = intHit.Trackable.CreateAnchor(intHit.Pose);
            if (anchor == null)
            {
                return(string.Empty);
            }

            anchorId = anchor.m_NativeHandle.ToString();
            DontDestroyOnLoad(anchor.gameObject);              // don't destroy it accross scenes

            if (gameObj)
            {
                gameObj.transform.SetParent(anchor.transform, true);
                gameObj.transform.localPosition = Vector3.zero;
                gameObj.transform.localRotation = Quaternion.identity;
            }

            MultiARInterop.MultiARData arData = arManager.GetARData();
            arData.allAnchorsDict[anchorId] = new List <GameObject>();

            if (gameObj)
            {
                arData.allAnchorsDict[anchorId].Add(gameObj);
            }
        }
        else
        {
            anchorId = AnchorGameObjectToWorld(gameObj, hit.point, hit.rotation);
        }

        return(anchorId);
    }
    /// <summary>
    /// Raycasts from screen point or camera to the world.
    /// </summary>
    /// <returns><c>true</c>, if a plane was hit, <c>false</c> otherwise.</returns>
    /// <param name="screenPos">Screen position.</param>
    /// <param name="hit">Hit data.</param>
    public bool RaycastToWorld(bool fromInputPos, out MultiARInterop.TrackableHit hit)
    {
        hit = new MultiARInterop.TrackableHit();
        if (!isInitialized || (cameraTrackingState == TrackingState.Stopped))
        {
            return(false);
        }

        TrackableHit      intHit;
        TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinBounds | TrackableHitFlags.PlaneWithinPolygon |
                                          TrackableHitFlags.FeaturePointWithSurfaceNormal;

        if (arManager && !arManager.hitTrackedSurfacesOnly)
        {
            raycastFilter |= TrackableHitFlags.PlaneWithinInfinity;
            raycastFilter |= TrackableHitFlags.FeaturePoint;
            raycastFilter |= TrackableHitFlags.FeaturePoint;
        }

        Vector2 screenPos = fromInputPos ? inputPos : new Vector2(Screen.width / 2f, Screen.height / 2f);
        Ray     screenRay = mainCamera.ScreenPointToRay(screenPos);

        hit.rayPos = screenRay.origin;
        hit.rayDir = screenRay.direction;

        if (Frame.Raycast(screenPos.x, screenPos.y, raycastFilter, out intHit))
        {
            hit.point    = intHit.Pose.position;
            hit.normal   = intHit.Pose.rotation * Vector3.up;
            hit.distance = intHit.Distance;
            hit.rotation = intHit.Pose.rotation;

            hit.psObject = intHit;

            return(true);
        }

        return(false);
    }
    /// <summary>
    /// Anchors the game object to world.
    /// </summary>
    /// <returns>The game object to world.</returns>
    /// <param name="gameObj">Game object.</param>
    /// <param name="hit">Trackable hit.</param>
    public string AnchorGameObjectToWorld(GameObject gameObj, MultiARInterop.TrackableHit hit)
    {
        string anchorId = AnchorGameObjectToWorld(gameObj, hit.point, Quaternion.identity);

        return(anchorId);
    }