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)); }
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)); }
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()); }
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(); }
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()); }