@@ -402,82 +402,35 @@ void Projection::set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, r
402402}
403403
404404real_t Projection::get_z_far () const {
405- const real_t *matrix = (const real_t *)columns;
406- Plane new_plane = Plane (matrix[3 ] - matrix[2 ],
407- matrix[7 ] - matrix[6 ],
408- matrix[11 ] - matrix[10 ],
409- matrix[15 ] - matrix[14 ]);
410-
411- new_plane.normalize ();
412-
413- return new_plane.d ;
405+ // NOTE: This assumes z-facing near and far planes, i.e. that :
406+ // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
407+ // - near and far planes are z-facing (i.e. columns[0][2] and [1][2] == 0)
408+ return (columns[3 ][3 ] - columns[3 ][2 ]) / (columns[2 ][3 ] - columns[2 ][2 ]);
414409}
415410
416411real_t Projection::get_z_near () const {
417- const real_t *matrix = (const real_t *)columns;
418- Plane new_plane = Plane (matrix[3 ] + matrix[2 ],
419- matrix[7 ] + matrix[6 ],
420- matrix[11 ] + matrix[10 ],
421- -matrix[15 ] - matrix[14 ]);
422-
423- new_plane.normalize ();
424- return new_plane.d ;
412+ // NOTE: This assumes z-facing near and far planes, i.e. that :
413+ // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
414+ // - near and far planes are z-facing (i.e. columns[0][2] and [1][2] == 0)
415+ return (columns[3 ][3 ] + columns[3 ][2 ]) / (columns[2 ][3 ] + columns[2 ][2 ]);
425416}
426417
427418Vector2 Projection::get_viewport_half_extents () const {
428- const real_t *matrix = (const real_t *)columns;
429- // /////--- Near Plane ---///////
430- Plane near_plane = Plane (matrix[3 ] + matrix[2 ],
431- matrix[7 ] + matrix[6 ],
432- matrix[11 ] + matrix[10 ],
433- -matrix[15 ] - matrix[14 ]);
434- near_plane.normalize ();
435-
436- // /////--- Right Plane ---///////
437- Plane right_plane = Plane (matrix[3 ] - matrix[0 ],
438- matrix[7 ] - matrix[4 ],
439- matrix[11 ] - matrix[8 ],
440- -matrix[15 ] + matrix[12 ]);
441- right_plane.normalize ();
442-
443- Plane top_plane = Plane (matrix[3 ] - matrix[1 ],
444- matrix[7 ] - matrix[5 ],
445- matrix[11 ] - matrix[9 ],
446- -matrix[15 ] + matrix[13 ]);
447- top_plane.normalize ();
448-
449- Vector3 res;
450- near_plane.intersect_3 (right_plane, top_plane, &res);
451-
452- return Vector2 (res.x , res.y );
419+ // NOTE: This assumes a symmetrical frustum, i.e. that :
420+ // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
421+ // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0)
422+ // - there is no offset / skew (i.e. columns[2][0] == columns[2][1] == 0)
423+ real_t w = -get_z_near () * columns[2 ][3 ] + columns[3 ][3 ];
424+ return Vector2 (w / columns[0 ][0 ], w / columns[1 ][1 ]);
453425}
454426
455427Vector2 Projection::get_far_plane_half_extents () const {
456- const real_t *matrix = (const real_t *)columns;
457- // /////--- Far Plane ---///////
458- Plane far_plane = Plane (matrix[3 ] - matrix[2 ],
459- matrix[7 ] - matrix[6 ],
460- matrix[11 ] - matrix[10 ],
461- -matrix[15 ] + matrix[14 ]);
462- far_plane.normalize ();
463-
464- // /////--- Right Plane ---///////
465- Plane right_plane = Plane (matrix[3 ] - matrix[0 ],
466- matrix[7 ] - matrix[4 ],
467- matrix[11 ] - matrix[8 ],
468- -matrix[15 ] + matrix[12 ]);
469- right_plane.normalize ();
470-
471- Plane top_plane = Plane (matrix[3 ] - matrix[1 ],
472- matrix[7 ] - matrix[5 ],
473- matrix[11 ] - matrix[9 ],
474- -matrix[15 ] + matrix[13 ]);
475- top_plane.normalize ();
476-
477- Vector3 res;
478- far_plane.intersect_3 (right_plane, top_plane, &res);
479-
480- return Vector2 (res.x , res.y );
428+ // NOTE: This assumes a symmetrical frustum, i.e. that :
429+ // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
430+ // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0)
431+ // - there is no offset / skew (i.e. columns[2][0] == columns[2][1] == 0)
432+ real_t w = -get_z_far () * columns[2 ][3 ] + columns[3 ][3 ];
433+ return Vector2 (w / columns[0 ][0 ], w / columns[1 ][1 ]);
481434}
482435
483436bool Projection::get_endpoints (const Transform3D &p_transform, Vector3 *p_8points) const {
@@ -919,53 +872,45 @@ Projection::operator String() const {
919872}
920873
921874real_t Projection::get_aspect () const {
922- Vector2 vp_he = get_viewport_half_extents ();
923- return vp_he.x / vp_he.y ;
875+ // NOTE: This assumes a rectangular projection plane, i.e. that :
876+ // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
877+ // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0)
878+ return columns[1 ][1 ] / columns[0 ][0 ];
924879}
925880
926881int Projection::get_pixels_per_meter (int p_for_pixel_width) const {
927- Vector3 result = xform (Vector3 (1 , 0 , -1 ));
928-
929- return int ((result.x * 0.5 + 0.5 ) * p_for_pixel_width);
882+ // NOTE: This assumes a rectangular projection plane, i.e. that :
883+ // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
884+ // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0)
885+ real_t width = 2 * (-get_z_near () * columns[2 ][3 ] + columns[3 ][3 ]) / columns[0 ][0 ];
886+ return p_for_pixel_width / width; // Note : return type should be real_t (kept as int for compatibility for now).
930887}
931888
932889bool Projection::is_orthogonal () const {
933- return columns[3 ][3 ] == 1.0 ;
890+ // NOTE: This assumes that the matrix is a projection across z-axis
891+ // i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0
892+ return columns[2 ][3 ] == 0.0 ;
934893}
935894
936895real_t Projection::get_fov () const {
937- const real_t *matrix = (const real_t *)columns;
938-
939- Plane right_plane = Plane (matrix[3 ] - matrix[0 ],
940- matrix[7 ] - matrix[4 ],
941- matrix[11 ] - matrix[8 ],
942- -matrix[15 ] + matrix[12 ]);
943- right_plane.normalize ();
944-
945- if ((matrix[8 ] == 0 ) && (matrix[9 ] == 0 )) {
946- return Math::rad_to_deg (Math::acos (Math::abs (right_plane.normal .x ))) * 2.0 ;
896+ // NOTE: This assumes a rectangular projection plane, i.e. that :
897+ // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
898+ // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0)
899+ if (columns[2 ][0 ] == 0 ) {
900+ return Math::rad_to_deg (2 * Math::atan2 (1 , columns[0 ][0 ]));
947901 } else {
948- // our frustum is asymmetrical need to calculate the left planes angle separately..
949- Plane left_plane = Plane (matrix[3 ] + matrix[0 ],
950- matrix[7 ] + matrix[4 ],
951- matrix[11 ] + matrix[8 ],
952- matrix[15 ] + matrix[12 ]);
953- left_plane.normalize ();
954-
955- return Math::rad_to_deg (Math::acos (Math::abs (left_plane.normal .x ))) + Math::rad_to_deg (Math::acos (Math::abs (right_plane.normal .x )));
902+ // The frustum is asymmetrical so we need to calculate the left and right angles separately.
903+ real_t right = Math::atan2 (columns[2 ][0 ] + 1 , columns[0 ][0 ]);
904+ real_t left = Math::atan2 (columns[2 ][0 ] - 1 , columns[0 ][0 ]);
905+ return Math::rad_to_deg (right - left);
956906 }
957907}
958908
959909real_t Projection::get_lod_multiplier () const {
960- if (is_orthogonal ()) {
961- return get_viewport_half_extents ().x ;
962- } else {
963- const real_t zn = get_z_near ();
964- const real_t width = get_viewport_half_extents ().x * 2 .0f ;
965- return 1 .0f / (zn / width);
966- }
967-
968- // Usage is lod_size / (lod_distance * multiplier) < threshold
910+ // NOTE: This assumes a rectangular projection plane, i.e. that :
911+ // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
912+ // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0)
913+ return 2 / columns[0 ][0 ];
969914}
970915
971916void Projection::make_scale (const Vector3 &p_scale) {
0 commit comments