Пример #1
0
        public static ARHitTestResult SmartHitTest(this ARSCNView self, CGPoint point)
        {
            // Perform the hit test.
            var results = self.HitTest(point, ARHitTestResultType.ExistingPlaneUsingGeometry);

            // 1. Check for a result on an existing plane using geometry.
            var existingPlaneUsingGeometryResult = results.FirstOrDefault(result => result.Type == ARHitTestResultType.ExistingPlaneUsingGeometry);

            if (existingPlaneUsingGeometryResult != null)
            {
                return(existingPlaneUsingGeometryResult);
            }

            // 2. Check for a result on an existing plane, assuming its dimensions are infinite.
            var infinitePlaneResults = self.HitTest(point, ARHitTestResultType.ExistingPlane);

            var infinitePlaneResult = infinitePlaneResults.FirstOrDefault();

            if (infinitePlaneResult != null)
            {
                return(infinitePlaneResult);
            }

            // 3. As a final fallback, check for a result on estimated planes.
            return(results.FirstOrDefault(result => result.Type == ARHitTestResultType.EstimatedHorizontalPlane));
        }
Пример #2
0
        public void TapAction(UITapGestureRecognizer gestureRecognizer)
        {
            var location = gestureRecognizer.LocationOfTouch(0, scnView);
            var hits     = scnView.HitTest(location, new SCNHitTestOptions());

            if (hits.Count() != 0)
            {
                var tappedNodeName = hits.FirstOrDefault().Node.Name;

                UIAlertView alert = new UIAlertView()
                {
                    Title   = tappedNodeName,
                    Message = "You found a " + tappedNodeName
                };
                alert.AddButton("OK");
                alert.Show();
            }
        }
Пример #3
0
        private static SCNVector3?HitTestExistingPlanes(CGPoint point, ARSCNView sceneView)
        {
            var hitResult = sceneView.HitTest(point, ARHitTestResultType.ExistingPlaneUsingExtent);

            if (hitResult.Count() > 0)
            {
                var xPos = hitResult[0].WorldTransform.Column3.X;
                var yPos = hitResult[0].WorldTransform.Column3.Y;
                var zPos = hitResult[0].WorldTransform.Column3.Z;

                return(new SCNVector3(xPos, yPos, zPos));
            }

            return(null);
        }
Пример #4
0
        //Getting world position from touch hit
        Tuple <SCNVector3?, ARAnchor> WorldPositionFromHitTest(CGPoint pt)
        {
            //Hit test against existing anchors
            var hits = scnView.HitTest(pt, ARHitTestResultType.ExistingPlaneUsingExtent);

            if (hits != null && hits.Length > 0)
            {
                var anchors = hits.Where(r => r.Anchor is ARPlaneAnchor);
                if (anchors.Count() > 0)
                {
                    var first = anchors.First();
                    var pos   = PositionFromTransform(first.WorldTransform);
                    return(new Tuple <SCNVector3?, ARAnchor>(pos, (ARPlaneAnchor)first.Anchor));
                }
            }
            return(new Tuple <SCNVector3?, ARAnchor>(null, null));
        }
Пример #5
0
        internal static ARHitTestResult SmartHitTest(this ARSCNView self, CGPoint point)
        {
            var hitTestResults = self.HitTest(point, ARHitTestResultType.FeaturePoint);

            if (hitTestResults == null || hitTestResults.Length == 0)
            {
                return(null);
            }

            foreach (var result in hitTestResults)
            {
                // Return the first result which is between 20 cm and 3 m away from the user.
                if (result.Distance > 0.2 && result.Distance < 3)
                {
                    return(result);
                }
            }
            return(null);
        }
        private void HandleTap(UITapGestureRecognizer recognizer)
        {
            var tapLocation    = recognizer.LocationInView(sceneView);
            var hitTestResults = sceneView.HitTest(tapLocation, ARHitTestResultType.ExistingPlaneUsingExtent);

            if (hitTestResults != null && hitTestResults.Length > 0)
            {
                var hitTestResult = hitTestResults[0];
                var translation   = PositionFromTransform(hitTestResult.WorldTransform);

                var x = translation.X;
                var y = translation.Y;
                var z = translation.Z;

                var shipScene = SCNScene.FromFile("Sprites/ship.scn");
                var shipNode  = shipScene.RootNode.FindChildNode("ship", false);

                shipNode.Position = new SCNVector3(x, y, z);
                sceneView.Scene.RootNode.AddChildNode(shipNode);
            }
        }
        public override void TouchesBegan(Foundation.NSSet touches, UIEvent evt)
        {
            if (touches.Count != 0)
            {
                var touch    = touches.ToArray <UITouch>()[0];
                var location = touch.LocationInView(sceneView);

                var hitList = sceneView.HitTest(location, new SCNHitTestOptions());

                if (hitList.Length > 0)
                {
                    var hitObject = hitList[0];

                    if (hitObject.Node.Name == "ARShip")
                    {
                        hitObject.Node.RemoveFromParentNode();

                        AddObject();
                    }
                }
            }
        }
        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);
        }
Пример #9
0
        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);
        }