|
@@ -207,3 +207,54 @@ void OpenXRCompositionLayerEquirect::set_fallback_segments(uint32_t p_fallback_s
|
|
|
uint32_t OpenXRCompositionLayerEquirect::get_fallback_segments() const {
|
|
|
return fallback_segments;
|
|
|
}
|
|
|
+
|
|
|
+Vector2 OpenXRCompositionLayerEquirect::intersects_ray(const Vector3 &p_origin, const Vector3 &p_direction) const {
|
|
|
+ Transform3D equirect_transform = get_global_transform();
|
|
|
+
|
|
|
+ Vector3 offset = p_origin - equirect_transform.origin;
|
|
|
+ float a = p_direction.dot(p_direction);
|
|
|
+ float b = 2.0 * offset.dot(p_direction);
|
|
|
+ float c = offset.dot(offset) - (radius * radius);
|
|
|
+
|
|
|
+ float discriminant = b * b - 4.0 * a * c;
|
|
|
+ if (discriminant < 0.0) {
|
|
|
+ return Vector2(-1.0, -1.0);
|
|
|
+ }
|
|
|
+
|
|
|
+ float t0 = (-b - Math::sqrt(discriminant)) / (2.0 * a);
|
|
|
+ float t1 = (-b + Math::sqrt(discriminant)) / (2.0 * a);
|
|
|
+ float t = MAX(t0, t1);
|
|
|
+
|
|
|
+ if (t < 0.0) {
|
|
|
+ return Vector2(-1.0, -1.0);
|
|
|
+ }
|
|
|
+ Vector3 intersection = p_origin + p_direction * t;
|
|
|
+
|
|
|
+ Basis correction = equirect_transform.basis.inverse();
|
|
|
+ correction.rotate(Vector3(0.0, 1.0, 0.0), -Math_PI / 2.0);
|
|
|
+ Vector3 relative_point = correction.xform(intersection - equirect_transform.origin);
|
|
|
+
|
|
|
+ float horizontal_intersection_angle = Math::atan2(relative_point.z, relative_point.x);
|
|
|
+ if (Math::abs(horizontal_intersection_angle) > central_horizontal_angle / 2.0) {
|
|
|
+ return Vector2(-1.0, -1.0);
|
|
|
+ }
|
|
|
+
|
|
|
+ float vertical_intersection_angle = Math::acos(relative_point.y / radius) - (Math_PI / 2.0);
|
|
|
+ if (vertical_intersection_angle < 0) {
|
|
|
+ if (Math::abs(vertical_intersection_angle) > upper_vertical_angle) {
|
|
|
+ return Vector2(-1.0, -1.0);
|
|
|
+ }
|
|
|
+ } else if (vertical_intersection_angle > lower_vertical_angle) {
|
|
|
+ return Vector2(-1.0, -1.0);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Re-center the intersection angle if the vertical angle is uneven between upper and lower.
|
|
|
+ if (upper_vertical_angle != lower_vertical_angle) {
|
|
|
+ vertical_intersection_angle -= (-upper_vertical_angle + lower_vertical_angle) / 2.0;
|
|
|
+ }
|
|
|
+
|
|
|
+ float u = 0.5 + (horizontal_intersection_angle / central_horizontal_angle);
|
|
|
+ float v = 0.5 + (vertical_intersection_angle / (upper_vertical_angle + lower_vertical_angle));
|
|
|
+
|
|
|
+ return Vector2(u, v);
|
|
|
+}
|