/** * Estimate the 3D position (in unity units) of a point on the camera feed, optionally filtering * the results by the source of information that is used to estimate the 3d position. If no * types are specified, all hit test results are returned. * * X and Y are specified as numbers between 0 and 1, where (0, 0) is the upper left corner and * (1, 1) is the lower right corner of the camera feed as rendered in the camera that was * specified with UpdateCameraProjectionMatrix. * * Mutltiple 3d position esitmates may be returned for a single hit test based on the source * of data being used to estimate the position. The data source that was used to estimate the * position is indicated by the XRHitTestResult.Type. * * Example usage: * * List<XRHitTestResult> hits = new List<XRHitTestResult>(); * List<XRHitTestResult.Type> types = new List<XRHitTestResult.Type>(); * types.Add(XRHitTestResult.Type.DETECTED_SURFACE); * if (Input.touchCount != 0) { * var t = Input.GetTouch(0); * if (t.phase == TouchPhase.Began) { * float x = t.position.x / Screen.width; * float y = (Screen.height - t.position.y) / Screen.height; * hits.AddRange(xr.HitTest(x, y, types)); * } * } */ public List <XRHitTestResult> HitTest(float x, float y, List <XRHitTestResult.Type> includedTypes) { MessageBuilder queryMessage = new MessageBuilder(); var query = queryMessage.initRoot(XrQueryRequest.factory); var ht = query.getHitTest(); ht.setX(x); ht.setY(y); if (includedTypes.Count > 0) { query.getHitTest().initIncludedTypes(includedTypes.Count); for (int i = 0; i < includedTypes.Count; ++i) { var type = includedTypes[i]; switch (type) { case XRHitTestResult.Type.FEATURE_POINT: ht.getIncludedTypes().set(i, XrHitTestResult.ResultType.FEATURE_POINT); break; case XRHitTestResult.Type.ESTIMATED_SURFACE: ht.getIncludedTypes().set(i, XrHitTestResult.ResultType.ESTIMATED_SURFACE); break; case XRHitTestResult.Type.DETECTED_SURFACE: ht.getIncludedTypes().set(i, XrHitTestResult.ResultType.DETECTED_SURFACE); break; default: // pass break; } } } var response = bridge.Query(queryMessage); List <XRHitTestResult> results = new List <XRHitTestResult>(); foreach (var hit in response.getHitTest().getHits()) { var type = XRHitTestResult.Type.UNSPECIFIED; switch (hit.getType()) { case XrHitTestResult.ResultType.FEATURE_POINT: type = XRHitTestResult.Type.FEATURE_POINT; break; case XrHitTestResult.ResultType.ESTIMATED_SURFACE: type = XRHitTestResult.Type.ESTIMATED_SURFACE; break; case XrHitTestResult.ResultType.DETECTED_SURFACE: type = XRHitTestResult.Type.DETECTED_SURFACE; break; default: type = XRHitTestResult.Type.UNSPECIFIED; break; } Vector3 position = new Vector3( hit.getPlace().getPosition().getX(), hit.getPlace().getPosition().getY(), hit.getPlace().getPosition().getZ()); Quaternion rotation = new Quaternion( hit.getPlace().getRotation().getX(), hit.getPlace().getRotation().getY(), hit.getPlace().getRotation().getZ(), hit.getPlace().getRotation().getW()); float distance = hit.getDistance(); results.Add(new XRHitTestResult(type, position, rotation, distance)); } return(results); }