コード例 #1
0
        internal (SCNVector3?, ARPlaneAnchor, Boolean) WorldPositionFromScreenPosition(CGPoint position, ARSCNView sceneView, SCNVector3?objectPos, bool infinitePlane = false)
        {
            var dragOnInfinitePlanesEnabled = AppSettings.DragOnInfinitePlanes;

            // -------------------------------------------------------------------------------
            // 1. Always do a hit test against exisiting plane anchors first.
            //    (If any such anchors exist & only within their extents.)
            var planeHitTestResults = sceneView.HitTest(position, ARHitTestResultType.ExistingPlaneUsingExtent);
            var result = planeHitTestResults.FirstOrDefault();

            if (result != null)
            {
                var planeHitTestPosition = result.WorldTransform.Translation();
                var planeAnchor          = result.Anchor;
                return(planeHitTestPosition, (ARPlaneAnchor)planeAnchor, true);
            }

            // -------------------------------------------------------------------------------
            // 2. Collect more information about the environment by hit testing against
            //    the feature point cloud, but do not return the result yet.
            SCNVector3?featureHitTestPosition          = null;
            var        highQualityFeatureHitTestResult = false;

            var highQualityfeatureHitTestResults = sceneView.HitTestWithFeatures(position, 18, 0.2, 2.0);

            if (highQualityfeatureHitTestResults.Count() > 0)
            {
                var highQualityFeatureHit = highQualityfeatureHitTestResults.First();
                featureHitTestPosition          = highQualityFeatureHit.Position;
                highQualityFeatureHitTestResult = true;
            }


            // -------------------------------------------------------------------------------
            // 3. If desired or necessary (no good feature hit test result): Hit test
            //    against an infinite, horizontal plane (ignoring the real world).
            if ((infinitePlane && dragOnInfinitePlanesEnabled) || !highQualityFeatureHitTestResult)
            {
                if (objectPos.HasValue)
                {
                    var pointOnInfinitePlane = sceneView.HitTestWithInfiniteHorizontalPlane(position, objectPos.Value);
                    if (pointOnInfinitePlane != null)
                    {
                        return(pointOnInfinitePlane, null, true);
                    }
                }
            }

            // -------------------------------------------------------------------------------
            // 4. If available, return the result of the hit test against high quality
            //    features if the hit tests against infinite planes were skipped or no
            //    infinite plane was hit.
            if (highQualityFeatureHitTestResult)
            {
                return(featureHitTestPosition, null, false);
            }

            // -------------------------------------------------------------------------------
            // 5. As a last resort, perform a second, unfiltered hit test against features.
            //    If there are no features in the scene, the result returned here will be nil.
            var unfilteredFeatureHitTestResults = sceneView.HitTestWithFeatures(position);

            if (unfilteredFeatureHitTestResults.Count() > 0)
            {
                var unfilteredFeaturesResult = unfilteredFeatureHitTestResults.First();
                return(unfilteredFeaturesResult.Position, null, false);
            }

            return(null, null, false);
        }
コード例 #2
0
ファイル: Utilities.cs プロジェクト: zain-tariq/ios-samples
        public static (SCNVector3?, ARPlaneAnchor, bool) WorldPositionFromScreenPosition(CGPoint position,
                                                                                         ARSCNView sceneView,
                                                                                         SCNVector3?objectPos,
                                                                                         bool infinitePlane = false)
        {
            // -------------------------------------------------------------------------------
            // 1. Always do a hit test against existing plane anchors first.
            //    (If any such anchors exist & only within their extents.)

            var result = sceneView.HitTest(position, ARHitTestResultType.ExistingPlaneUsingExtent)?.FirstOrDefault();

            if (result != null)
            {
                var planeHitTestPosition = result.WorldTransform.GetTranslation();
                var planeAnchor          = result.Anchor;

                // Return immediately - this is the best possible outcome.
                return(planeHitTestPosition, planeAnchor as ARPlaneAnchor, true);
            }

            // -------------------------------------------------------------------------------
            // 2. Collect more information about the environment by hit testing against
            //    the feature point cloud, but do not return the result yet.

            SCNVector3?featureHitTestPosition          = null;
            var        highQualityFeatureHitTestResult = false;

            var highQualityfeatureHitTestResults = sceneView.HitTestWithFeatures(position, 18f, 0.2f, 2f);

            if (highQualityfeatureHitTestResults.Any())
            {
                featureHitTestPosition          = highQualityfeatureHitTestResults[0].Position;
                highQualityFeatureHitTestResult = true;
            }

            // -------------------------------------------------------------------------------
            // 3. If desired or necessary (no good feature hit test result): Hit test
            //    against an infinite, horizontal plane (ignoring the real world).

            if (infinitePlane || !highQualityFeatureHitTestResult)
            {
                if (objectPos.HasValue)
                {
                    var pointOnInfinitePlane = sceneView.HitTestWithInfiniteHorizontalPlane(position, objectPos.Value);
                    if (pointOnInfinitePlane.HasValue)
                    {
                        return(pointOnInfinitePlane, null, true);
                    }
                }
            }

            // -------------------------------------------------------------------------------
            // 4. If available, return the result of the hit test against high quality
            //    features if the hit tests against infinite planes were skipped or no
            //    infinite plane was hit.

            if (highQualityFeatureHitTestResult)
            {
                return(featureHitTestPosition, null, false);
            }

            // -------------------------------------------------------------------------------
            // 5. As a last resort, perform a second, unfiltered hit test against features.
            //    If there are no features in the scene, the result returned here will be nil.

            var unfilteredFeatureHitTestResults = sceneView.HitTestWithFeatures(position);

            if (unfilteredFeatureHitTestResults.Any())
            {
                var first = unfilteredFeatureHitTestResults[0];
                return(first.Position, null, false);
            }

            return(null, null, false);
        }