コード例 #1
0
        public static SCNVector3?HitTestWithInfiniteHorizontalPlane(this ARSCNView sceneView, CGPoint point, SCNVector3 pointOnPlane)
        {
            //if (sceneView.Session == null || ARGamePlay.CurrentFrame == null)
            //{
            //    return null;
            //}
            //
            //var currentFrame = ARGamePlay.CurrentFrame;

            var ray = sceneView.HitTestRayFromScreenPos(point);

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

            // Do not intersect with planes above the camera or if the ray is almost parallel to the plane.
            if (ray.Direction.Y > -0.03f)
            {
                return(null);
            }

            return(ray.IntersectionWithHorizontalPlane(pointOnPlane.Y));
        }
コード例 #2
0
        public static SCNVector3?HitTestWithInfiniteHorizontalPlane(this ARSCNView self, CGPoint point, SCNVector3 pointOnPlane)
        {
            if (self.Session == null || ViewController.CurrentFrame == null)
            {
                return(null);
            }

            var currentFrame = ViewController.CurrentFrame;

            var ray = self.HitTestRayFromScreenPos(point);

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

            // Do not intersect with planes above the camera or if the ray is almost parallel to the plane.
            if (ray.Direction.Y > -0.03f)
            {
                return(null);
            }

            return(Utilities.RayIntersectionWithHorizontalPlane(ray.Origin, ray.Direction, pointOnPlane.Y));
        }
コード例 #3
0
        public static FeatureHitTestResult[] HitTestWithFeatures(this ARSCNView self, CGPoint pt)
        {
            var results = new List <FeatureHitTestResult>();
            var ray     = self.HitTestRayFromScreenPos(pt);

            if (ray == null)
            {
                return(results.ToArray());
            }
            var result = self.HitTestFromOrigin(ray.Origin, ray.Direction);

            if (result != null)
            {
                results.Add(result);
            }
            return(results.ToArray());
        }
コード例 #4
0
        private static SCNVector3?HitTestPointCloud(CGPoint point, ARSCNView sceneView, double coneOpeningAngleInDegrees, double minDistance = 0, double maxDistance = Double.MaxValue)
        {
            //var results = new List<FeatureHitTestResult>();
            var minHitTestResultDistance = float.MaxValue;
            //FeatureHitTestResult closestFeauture = null;
            SCNVector3?closestFeauturePosition = null;

            if (sceneView.Session == null || ARGamePlay.CurrentFrame == null)
            {
                return(null); //results.ToArray();
            }
            var features = ARGamePlay.CurrentFrame.RawFeaturePoints;

            if (features == null)
            {
                return(null); //results.ToArray();
            }

            var ray = sceneView.HitTestRayFromScreenPos(point);

            if (ray == null)
            {
                return(null); //results.ToArray();
            }

            var maxAngleInDeg = Math.Min(coneOpeningAngleInDegrees, 360) / 2.0;
            var maxAngle      = (maxAngleInDeg / 180) * Math.PI;

            foreach (var featurePos in features.Points)
            {
                var scnFeaturePos   = new SCNVector3(featurePos.X, featurePos.Y, featurePos.Z);
                var originToFeature = scnFeaturePos - ray.Origin;
                //var crossProduct = originToFeature.Cross(ray.Direction);
                //var featureDistanceFromResult = crossProduct.LengthFast;

                var hitTestResult         = ray.Origin + (ray.Direction * (ray.Direction.Dot(originToFeature)));
                var hitTestResultDistance = (hitTestResult - ray.Origin).LengthFast;

                if (hitTestResultDistance < minDistance || hitTestResultDistance > maxDistance)
                {
                    // Skip this feature -- it's too close or too far
                    continue;
                }

                var originToFeatureNormalized = originToFeature.Normalized();
                var angleBetweenRayAndFeature = Math.Acos(ray.Direction.Dot(originToFeatureNormalized));

                if (angleBetweenRayAndFeature > maxAngle)
                {
                    // Skip this feature -- it's outside the cone
                    continue;
                }

                if (hitTestResultDistance < minHitTestResultDistance)
                {
                    minHitTestResultDistance = hitTestResultDistance;
                    closestFeauturePosition  = hitTestResult; //new FeatureHitTestResult(hitTestResult); //, hitTestResultDistance, scnFeaturePos, featureDistanceFromResult);
                }

                // All tests passed: Add the hit against this feature to the results.
                //results.Add(new FeatureHitTestResult(hitTestResult, hitTestResultDistance, scnFeaturePos, featureDistanceFromResult));
            }

            return(closestFeauturePosition);

            //         if(closestFeauture != null)
            //         {
            //             results.Add(closestFeauture);
            //         }

            ////// Sort the results by feature distance to the ray.
            ////results.Sort((a, b) => a.DistanceToRayOrigin.CompareTo(b.DistanceToRayOrigin));

            ////// Cap the list to maxResults.
            ////results.GetRange(0, Math.Min(results.Count(), maxResults));
            //return results.ToArray();
        }
コード例 #5
0
        public static FeatureHitTestResult[] HitTestWithFeatures(this ARSCNView self, CGPoint point, double coneOpeningAngleInDegrees, double minDistance = 0, double maxDistance = Double.MaxValue, int maxResults = 1)
        {
            var results = new List <FeatureHitTestResult>();

            if (self.Session == null || ViewController.CurrentFrame == null)
            {
                return(results.ToArray());
            }
            var features = ViewController.CurrentFrame.RawFeaturePoints;

            if (features == null)
            {
                return(results.ToArray());
            }

            var ray = self.HitTestRayFromScreenPos(point);

            if (ray == null)
            {
                return(results.ToArray());
            }

            var maxAngleInDeg = Math.Min(coneOpeningAngleInDegrees, 360) / 2.0;
            var maxAngle      = (maxAngleInDeg / 180) * Math.PI;

            foreach (var featurePos in features.Points)
            {
                var scnFeaturePos             = new SCNVector3(featurePos.X, featurePos.Y, featurePos.Z);
                var originToFeature           = scnFeaturePos - ray.Origin;
                var crossProduct              = originToFeature.Cross(ray.Direction);
                var featureDistanceFromResult = crossProduct.LengthFast;

                var hitTestResult         = ray.Origin + (ray.Direction * (ray.Direction.Dot(originToFeature)));
                var hitTestResultDistance = (hitTestResult - ray.Origin).LengthFast;

                if (hitTestResultDistance < minDistance || hitTestResultDistance > maxDistance)
                {
                    // Skip this feature -- it's too close or too far
                    continue;
                }

                var originToFeatureNormalized = originToFeature.Normalized();
                var angleBetweenRayAndFeature = Math.Acos(ray.Direction.Dot(originToFeatureNormalized));

                if (angleBetweenRayAndFeature > maxAngle)
                {
                    // Skip this feature -- it's outside the cone
                    continue;
                }

                // All tests passed: Add the hit against this feature to the results.
                results.Add(new FeatureHitTestResult(hitTestResult, hitTestResultDistance, scnFeaturePos, featureDistanceFromResult));
            }

            // Sort the results by feature distance to the ray.
            results.Sort((a, b) => a.DistanceToRayOrigin.CompareTo(b.DistanceToRayOrigin));

            // Cap the list to maxResults.
            results.GetRange(0, Math.Min(results.Count(), maxResults));
            return(results.ToArray());
        }