historical/toontown-classic.git/panda/include/frustum_src.I
2024-01-16 11:20:27 -06:00

262 lines
7.2 KiB
Text

/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file frustum_src.I
* @author mike
* @date 1997-01-09
*/
/**
*
*/
INLINE_MATHUTIL FLOATNAME(LFrustum)::
FLOATNAME(LFrustum)() {
_fnear = FLOATCONST(1.4142);
_ffar = FLOATCONST(10.0);
_l = -1.0f;
_r = 1.0f;
_t = 1.0f;
_b = -1.0f;
}
/**
* Sets up a two-dimensional orthographic frustum
*/
INLINE_MATHUTIL void FLOATNAME(LFrustum)::make_ortho_2D() {
make_ortho(-1.0f, 1.0f);
}
/**
* Sets up a two-dimensional orthographic frustum
*/
INLINE_MATHUTIL void FLOATNAME(LFrustum)::
make_ortho_2D(FLOATTYPE l, FLOATTYPE r, FLOATTYPE t, FLOATTYPE b) {
make_ortho(-1.0f, 1.0f, l, r, t, b);
}
/**
* Behaves like gluOrtho
*/
INLINE_MATHUTIL void FLOATNAME(LFrustum)::make_ortho(FLOATTYPE fnear, FLOATTYPE ffar) {
_fnear = fnear;
_ffar = ffar;
_l = -1.0f;
_r = 1.0f;
_t = 1.0f;
_b = -1.0f;
}
/**
* Behaves like gluOrtho
*/
INLINE_MATHUTIL void FLOATNAME(LFrustum)::
make_ortho(FLOATTYPE fnear, FLOATTYPE ffar, FLOATTYPE l, FLOATTYPE r,
FLOATTYPE t, FLOATTYPE b) {
_fnear = fnear;
_ffar = ffar;
_l = l;
_r = r;
_t = t;
_b = b;
}
/**
* Behaves like gluPerspective (Aspect = width/height, Yfov in degrees) aspect
* +------------+ | | 1 | | yfov | |
* +------------+
*
* -------+------ \ | \ | \ | \ | \ | \| W yfov
*
*/
INLINE_MATHUTIL void FLOATNAME(LFrustum)::
make_perspective_hfov(FLOATTYPE hfov, FLOATTYPE aspect, FLOATTYPE fnear,
FLOATTYPE ffar) {
_fnear = fnear;
_ffar = ffar;
_r = tan(deg_2_rad(hfov) * FLOATCONST(0.5)) * _fnear;
_l = -_r;
_t = _r / aspect;
_b = -_t;
}
INLINE_MATHUTIL void FLOATNAME(LFrustum)::
make_perspective_vfov(FLOATTYPE yfov, FLOATTYPE aspect, FLOATTYPE fnear,
FLOATTYPE ffar) {
_fnear = fnear;
_ffar = ffar;
_t = tan(deg_2_rad(yfov) * 0.5f) * _fnear;
_b = -_t;
_r = _t * aspect;
_l = -_r;
}
INLINE_MATHUTIL void FLOATNAME(LFrustum)::
make_perspective(FLOATTYPE xfov, FLOATTYPE yfov, FLOATTYPE fnear,
FLOATTYPE ffar) {
_fnear = fnear;
_ffar = ffar;
_t = tan(deg_2_rad(yfov) * 0.5f) * _fnear;
_b = -_t;
_r = tan(deg_2_rad(xfov) * 0.5f) * _fnear;
_l = -_r;
}
/**
*
*/
INLINE_MATHUTIL void FLOATNAME(LFrustum)::
get_perspective_params(FLOATTYPE& yfov, FLOATTYPE& aspect,
FLOATTYPE& fnear, FLOATTYPE& ffar) const {
yfov = rad_2_deg(atan(_t / _fnear)) * 2.0f;
aspect = _r / _t;
fnear = _fnear;
ffar = _ffar;
}
/**
*
*/
INLINE_MATHUTIL void FLOATNAME(LFrustum)::
get_perspective_params(FLOATTYPE& xfov, FLOATTYPE& yfov, FLOATTYPE& aspect,
FLOATTYPE& fnear, FLOATTYPE& ffar) const {
xfov = rad_2_deg(atan(_r / _fnear)) * 2.0f;
get_perspective_params(yfov, aspect, fnear, ffar);
}
/**
* This computes a transform matrix that performs the perspective transform
* defined by the frustum, accordinate to the indicated coordinate system.
*/
INLINE_MATHUTIL FLOATNAME(LMatrix4) FLOATNAME(LFrustum)::
get_perspective_projection_mat(CoordinateSystem cs) const {
if (cs == CS_default) {
cs = get_default_coordinate_system();
}
FLOATTYPE recip_r_minus_l = 1.0f/(_r - _l);
FLOATTYPE recip_t_minus_b = 1.0f/(_t - _b);
FLOATTYPE two_fnear = 2.0f*_fnear;
FLOATTYPE d = (_r + _l) * recip_r_minus_l;
FLOATTYPE a = two_fnear * recip_r_minus_l;
FLOATTYPE e = two_fnear * recip_t_minus_b;
FLOATTYPE b = (_t + _b) * recip_t_minus_b;
FLOATTYPE c, f;
// Take the limits if either near or far is infinite.
if (cinf(_ffar)) {
c = 1;
f = -2 * _fnear;
} else if (cinf(_fnear)) {
c = -1;
f = 2 * _ffar;
} else {
FLOATTYPE recip_far_minus_near = 1.0f / (_ffar - _fnear);
c = (_ffar + _fnear) * recip_far_minus_near;
f = -_ffar * two_fnear * recip_far_minus_near;
}
/*
FLOATTYPE a = (2.0f * _fnear) / (_r - _l);
FLOATTYPE b = (_t + _b) / (_t - _b);
FLOATTYPE c = (_ffar + _fnear) / (_ffar - _fnear);
FLOATTYPE d = (_r + _l) / (_r - _l);
FLOATTYPE e = (2.0f * _fnear) / (_t - _b);
FLOATTYPE f = (-2.0f * _ffar * _fnear) / (_ffar - _fnear);
*/
switch (cs) {
case CS_zup_right:
return FLOATNAME(LMatrix4)( a, 0.0f, 0.0f, 0.0f,
0.0f, -b, c, 1.0f,
d, e, 0.0f, 0.0f,
0.0f, 0.0f, f, 0.0f);
case CS_yup_right:
return FLOATNAME(LMatrix4)( a, 0.0f, 0.0f, 0.0f,
0.0f, e, 0.0f, 0.0f,
d, b, -c, -1.0f,
0.0f, 0.0f, f, 0.0f);
case CS_zup_left:
return FLOATNAME(LMatrix4)( a, 0.0f, 0.0f, 0.0f,
0.0f, b, -c, -1.0f,
d, e, 0.0f, 0.0f,
0.0f, 0.0f, f, 0.0f);
case CS_yup_left:
return FLOATNAME(LMatrix4)( a, 0.0f, 0.0f, 0.0f,
0.0f, e, 0.0f, 0.0f,
-d, -b, c, 1.0f,
0.0f, 0.0f, f, 0.0f);
default:
mathutil_cat.error()
<< "Invalid coordinate system!\n";
return FLOATNAME(LMatrix4)::ident_mat();
}
}
/**
* This computes a transform matrix that performs the orthographic transform
* defined by the frustum, accordinate to the indicated coordinate system.
*/
INLINE_MATHUTIL FLOATNAME(LMatrix4) FLOATNAME(LFrustum)::
get_ortho_projection_mat(CoordinateSystem cs) const {
if (cs == CS_default) {
cs = get_default_coordinate_system();
}
FLOATTYPE a = 2.0f / (_r - _l);
FLOATTYPE b = 2.0f / (_t - _b);
FLOATTYPE c = 2.0f / (_ffar - _fnear);
FLOATTYPE d = (_r + _l) * a * 0.5f;
FLOATTYPE e = (_t + _b) * b * 0.5f;
FLOATTYPE f = (_ffar + _fnear) * c * 0.5f;
/*
FLOATTYPE a = 2.0f / (_r - _l);
FLOATTYPE b = 2.0f / (_t - _b);
FLOATTYPE c = 2.0f / (_ffar - _fnear);
FLOATTYPE d = (_r + _l) / (_r + _l)
FLOATTYPE e = (_t + _b) / (_t - _b);
FLOATTYPE f = (_ffar + _fnear) / (_ffar - _fnear);
*/
switch (cs) {
case CS_zup_right:
return FLOATNAME(LMatrix4)( a, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, -c, 0.0f,
0.0f, -b, 0.0f, 0.0f,
-d, -e, -f, 1.0f);
case CS_yup_right:
return FLOATNAME(LMatrix4)( a, 0.0f, 0.0f, 0.0f,
0.0f, b, 0.0f, 0.0f,
0.0f, 0.0f, -c, 0.0f,
-d, -e, -f, 1.0f);
case CS_zup_left:
return FLOATNAME(LMatrix4)( a, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, -c, 0.0f,
0.0f, b, 0.0f, 0.0f,
-d, -e, -f, 1.0f);
case CS_yup_left:
return FLOATNAME(LMatrix4)( a, 0.0f, 0.0f, 0.0f,
0.0f, b, 0.0f, 0.0f,
0.0f, 0.0f, c, 0.0f,
-d, -e, -f, 1.0f);
default:
mathutil_cat.error()
<< "Invalid coordinate system!\n";
return FLOATNAME(LMatrix4)::ident_mat();
}
}