diff --git a/panda/src/linmath/Sources.pp b/panda/src/linmath/Sources.pp index 2180a6bc1d..b47d1b7a8a 100644 --- a/panda/src/linmath/Sources.pp +++ b/panda/src/linmath/Sources.pp @@ -12,22 +12,13 @@ coordinateSystem.h deg_2_rad.h \ ioPtaDatagramLinMath.I ioPtaDatagramLinMath.cxx \ ioPtaDatagramLinMath.h lmatrix.cxx lmatrix.h \ - lmatrix3.I lmatrix3.h lmatrix3.cxx lmatrix3_src.I \ - lmatrix4.I lmatrix4.h lmatrix4.cxx lmatrix4_src.I \ - luse.I luse.cxx \ - luse.h lquaternion.I lquaternion.h lquaternion.cxx lquaternion_src.I \ - lrotation.I lrotation.h lrotation.cxx lrotation_src.I \ - lorientation.I lorientation.h lorientation.cxx lorientation_src.I \ - lpoint2.I lpoint2.h lpoint2.cxx lpoint2_src.I \ - lpoint3.I lpoint3.h lpoint3.cxx lpoint3_src.I \ - lpoint4.I lpoint4.h lpoint4.cxx lpoint4_src.I \ - lvec2_ops.I lvec2_ops.h lvec3_ops.I lvec3_ops.h lvec4_ops.I lvec4_ops.h \ - lvecBase2.I lvecBase2.h lvecBase2.cxx lvecBase2_src.I \ - lvecBase3.I lvecBase3.h lvecBase3.cxx lvecBase3_src.I \ - lvecBase4.I lvecBase4.h lvecBase4.cxx lvecBase4_src.I \ - lvector2.I lvector2.h lvector2.cxx lvector2_src.I \ - lvector3.I lvector3.h lvector3.cxx lvector3_src.I \ - lvector4.I lvector4.h lvector4.cxx lvector4_src.I luse.N\ + lmatrix3.I lmatrix3.h lmatrix4.I lmatrix4.h \ + luse.I luse.N luse.cxx \ + luse.h lquaternion.I lquaternion.h lrotation.I lrotation.h \ + lvec2_ops.I lvec2_ops.h lvec3_ops.I lvec3_ops.h lvec4_ops.I \ + lvec4_ops.h lvecBase2.I lvecBase2.h lvecBase3.I lvecBase3.h \ + lvecBase4.I lvecBase4.h lvector2.I lvector2.h lvector3.I lvector3.h \ + lvector4.I lvector4.h \ mathNumbers.cxx mathNumbers.h nearly_zero.h \ pta_Colorf.cxx pta_Colorf.h \ pta_Normalf.cxx pta_Normalf.h pta_TexCoordf.cxx pta_TexCoordf.h \ @@ -43,8 +34,7 @@ ioPtaDatagramLinMath.h lmat_ops.I lmat_ops.h lmatrix.h lmatrix3.I \ lmatrix3.h lmatrix4.I lmatrix4.h lorientation.I lorientation.h \ lpoint2.I lpoint2.h lpoint3.I lpoint3.h lpoint4.I lpoint4.h \ - lquaternion.I lquaternion.h \ - lrotation.I lrotation.h luse.I luse.h \ + lquaternion.I lquaternion.h lrotation.I lrotation.h luse.I luse.h \ lvec2_ops.I lvec2_ops.h lvec3_ops.I lvec3_ops.h lvec4_ops.I \ lvec4_ops.h lvecBase2.I lvecBase2.h lvecBase3.I lvecBase3.h \ lvecBase4.I lvecBase4.h lvector2.I lvector2.h lvector3.I lvector3.h \ @@ -52,8 +42,7 @@ pta_Normalf.h pta_TexCoordf.h pta_Vertexf.h vector_Colorf.h \ vector_LPoint2f.h vector_LVecBase3f.h \ vector_Normalf.h vector_TexCoordf.h \ - vector_Vertexf.h \ - fltnames.I dblnames.I + vector_Vertexf.h #define IGATESCAN all diff --git a/panda/src/linmath/cast_to_double.I b/panda/src/linmath/cast_to_double.I index b4fa0e443e..352cfb196a 100644 --- a/panda/src/linmath/cast_to_double.I +++ b/panda/src/linmath/cast_to_double.I @@ -3,47 +3,47 @@ // //////////////////////////////////////////////////////////////////// -INLINE LVecBase2d cast_to_double(const LVecBase2f &source) { +INLINE LVecBase2 cast_to_double(const LVecBase2 &source) { return LCAST(double, source); } -INLINE LVecBase3d cast_to_double(const LVecBase3f &source) { +INLINE LVecBase3 cast_to_double(const LVecBase3 &source) { return LCAST(double, source); } -INLINE LVecBase4d cast_to_double(const LVecBase4f &source) { +INLINE LVecBase4 cast_to_double(const LVecBase4 &source) { return LCAST(double, source); } -INLINE LVector2d cast_to_double(const LVector2f &source) { +INLINE LVector2 cast_to_double(const LVector2 &source) { return LCAST(double, source); } -INLINE LVector3d cast_to_double(const LVector3f &source) { +INLINE LVector3 cast_to_double(const LVector3 &source) { return LCAST(double, source); } -INLINE LVector4d cast_to_double(const LVector4f &source) { +INLINE LVector4 cast_to_double(const LVector4 &source) { return LCAST(double, source); } -INLINE LPoint2d cast_to_double(const LPoint2f &source) { +INLINE LPoint2 cast_to_double(const LPoint2 &source) { return LCAST(double, source); } -INLINE LPoint3d cast_to_double(const LPoint3f &source) { +INLINE LPoint3 cast_to_double(const LPoint3 &source) { return LCAST(double, source); } -INLINE LPoint4d cast_to_double(const LPoint4f &source) { +INLINE LPoint4 cast_to_double(const LPoint4 &source) { return LCAST(double, source); } -INLINE LMatrix3d cast_to_double(const LMatrix3f &source) { +INLINE LMatrix3 cast_to_double(const LMatrix3 &source) { return LCAST(double, source); } -INLINE LMatrix4d cast_to_double(const LMatrix4f &source) { +INLINE LMatrix4 cast_to_double(const LMatrix4 &source) { return LCAST(double, source); } diff --git a/panda/src/linmath/cast_to_double.h b/panda/src/linmath/cast_to_double.h index bc6f4c7ad6..fd22d87951 100644 --- a/panda/src/linmath/cast_to_double.h +++ b/panda/src/linmath/cast_to_double.h @@ -13,17 +13,17 @@ // These are a number of functions that convert our various math // objects between floats and doubles. -INLINE LVecBase2d cast_to_double(const LVecBase2f &source); -INLINE LVecBase3d cast_to_double(const LVecBase3f &source); -INLINE LVecBase4d cast_to_double(const LVecBase4f &source); -INLINE LVector2d cast_to_double(const LVector2f &source); -INLINE LVector3d cast_to_double(const LVector3f &source); -INLINE LVector4d cast_to_double(const LVector4f &source); -INLINE LPoint2d cast_to_double(const LPoint2f &source); -INLINE LPoint3d cast_to_double(const LPoint3f &source); -INLINE LPoint4d cast_to_double(const LPoint4f &source); -INLINE LMatrix3d cast_to_double(const LMatrix3f &source); -INLINE LMatrix4d cast_to_double(const LMatrix4f &source); +INLINE LVecBase2 cast_to_double(const LVecBase2 &source); +INLINE LVecBase3 cast_to_double(const LVecBase3 &source); +INLINE LVecBase4 cast_to_double(const LVecBase4 &source); +INLINE LVector2 cast_to_double(const LVector2 &source); +INLINE LVector3 cast_to_double(const LVector3 &source); +INLINE LVector4 cast_to_double(const LVector4 &source); +INLINE LPoint2 cast_to_double(const LPoint2 &source); +INLINE LPoint3 cast_to_double(const LPoint3 &source); +INLINE LPoint4 cast_to_double(const LPoint4 &source); +INLINE LMatrix3 cast_to_double(const LMatrix3 &source); +INLINE LMatrix4 cast_to_double(const LMatrix4 &source); #include "cast_to_double.I" diff --git a/panda/src/linmath/cast_to_float.I b/panda/src/linmath/cast_to_float.I index 50ceabe700..980c3dde28 100644 --- a/panda/src/linmath/cast_to_float.I +++ b/panda/src/linmath/cast_to_float.I @@ -3,47 +3,47 @@ // //////////////////////////////////////////////////////////////////// -INLINE LVecBase2f cast_to_float(const LVecBase2d &source) { +INLINE LVecBase2 cast_to_float(const LVecBase2 &source) { return LCAST(float, source); } -INLINE LVecBase3f cast_to_float(const LVecBase3d &source) { +INLINE LVecBase3 cast_to_float(const LVecBase3 &source) { return LCAST(float, source); } -INLINE LVecBase4f cast_to_float(const LVecBase4d &source) { +INLINE LVecBase4 cast_to_float(const LVecBase4 &source) { return LCAST(float, source); } -INLINE LVector2f cast_to_float(const LVector2d &source) { +INLINE LVector2 cast_to_float(const LVector2 &source) { return LCAST(float, source); } -INLINE LVector3f cast_to_float(const LVector3d &source) { +INLINE LVector3 cast_to_float(const LVector3 &source) { return LCAST(float, source); } -INLINE LVector4f cast_to_float(const LVector4d &source) { +INLINE LVector4 cast_to_float(const LVector4 &source) { return LCAST(float, source); } -INLINE LPoint2f cast_to_float(const LPoint2d &source) { +INLINE LPoint2 cast_to_float(const LPoint2 &source) { return LCAST(float, source); } -INLINE LPoint3f cast_to_float(const LPoint3d &source) { +INLINE LPoint3 cast_to_float(const LPoint3 &source) { return LCAST(float, source); } -INLINE LPoint4f cast_to_float(const LPoint4d &source) { +INLINE LPoint4 cast_to_float(const LPoint4 &source) { return LCAST(float, source); } -INLINE LMatrix3f cast_to_float(const LMatrix3d &source) { +INLINE LMatrix3 cast_to_float(const LMatrix3 &source) { return LCAST(float, source); } -INLINE LMatrix4f cast_to_float(const LMatrix4d &source) { +INLINE LMatrix4 cast_to_float(const LMatrix4 &source) { return LCAST(float, source); } diff --git a/panda/src/linmath/cast_to_float.h b/panda/src/linmath/cast_to_float.h index 64a4c9e0d7..c8a6cbf5c5 100644 --- a/panda/src/linmath/cast_to_float.h +++ b/panda/src/linmath/cast_to_float.h @@ -13,17 +13,17 @@ // These are a number of functions that convert our various math // objects between floats and doubles. -INLINE LVecBase2f cast_to_float(const LVecBase2d &source); -INLINE LVecBase3f cast_to_float(const LVecBase3d &source); -INLINE LVecBase4f cast_to_float(const LVecBase4d &source); -INLINE LVector2f cast_to_float(const LVector2d &source); -INLINE LVector3f cast_to_float(const LVector3d &source); -INLINE LVector4f cast_to_float(const LVector4d &source); -INLINE LPoint2f cast_to_float(const LPoint2d &source); -INLINE LPoint3f cast_to_float(const LPoint3d &source); -INLINE LPoint4f cast_to_float(const LPoint4d &source); -INLINE LMatrix3f cast_to_float(const LMatrix3d &source); -INLINE LMatrix4f cast_to_float(const LMatrix4d &source); +INLINE LVecBase2 cast_to_float(const LVecBase2 &source); +INLINE LVecBase3 cast_to_float(const LVecBase3 &source); +INLINE LVecBase4 cast_to_float(const LVecBase4 &source); +INLINE LVector2 cast_to_float(const LVector2 &source); +INLINE LVector3 cast_to_float(const LVector3 &source); +INLINE LVector4 cast_to_float(const LVector4 &source); +INLINE LPoint2 cast_to_float(const LPoint2 &source); +INLINE LPoint3 cast_to_float(const LPoint3 &source); +INLINE LPoint4 cast_to_float(const LPoint4 &source); +INLINE LMatrix3 cast_to_float(const LMatrix3 &source); +INLINE LMatrix4 cast_to_float(const LMatrix4 &source); #include "cast_to_float.I" diff --git a/panda/src/linmath/compose_matrix.I b/panda/src/linmath/compose_matrix.I index 84ea795049..b0c6c1f5e5 100644 --- a/panda/src/linmath/compose_matrix.I +++ b/panda/src/linmath/compose_matrix.I @@ -1,127 +1,77 @@ -//////////////////////////////////////////////////////////////////// // Filename: compose_matrix.I // Created by: drose (21Feb99) // //////////////////////////////////////////////////////////////////// -BEGIN_PUBLISH - -EXPCL_PANDA INLINE void -compose_matrix(FLOATNAME(LMatrix3) &mat, - const FLOATNAME(LVecBase3) &scale, - const FLOATNAME(LVecBase3) &hpr, - CoordinateSystem cs = CS_default); - -EXPCL_PANDA INLINE void -compose_matrix(FLOATNAME(LMatrix4) &mat, - const FLOATNAME(LVecBase3) &scale, - const FLOATNAME(LVecBase3) &hpr, - const FLOATNAME(LVecBase3) &translate, - CoordinateSystem cs = CS_default); - -INLINE void -compose_matrix(FLOATNAME(LMatrix4) &mat, const float components[9], - CoordinateSystem cs = CS_default); - -EXPCL_PANDA bool -decompose_matrix(const FLOATNAME(LMatrix3) &mat, - FLOATNAME(LVecBase3) &scale, - FLOATNAME(LVecBase3) &hpr, - CoordinateSystem cs = CS_default); - -EXPCL_PANDA bool -decompose_matrix(const FLOATNAME(LMatrix3) &mat, - FLOATNAME(LVecBase3) &scale, - FLOATNAME(LVecBase3) &hpr, - float roll, - CoordinateSystem cs = CS_default); - -EXPCL_PANDA bool -decompose_matrix(const FLOATNAME(LMatrix4) &mat, - FLOATNAME(LVecBase3) &scale, - FLOATNAME(LVecBase3) &hpr, - FLOATNAME(LVecBase3) &translate, - CoordinateSystem cs = CS_default); - -EXPCL_PANDA bool -decompose_matrix(const FLOATNAME(LMatrix4) &mat, - FLOATNAME(LVecBase3) &scale, - FLOATNAME(LVecBase3) &hpr, - FLOATNAME(LVecBase3) &translate, - float roll, - CoordinateSystem cs = CS_default); - -INLINE bool -decompose_matrix(const FLOATNAME(LMatrix4) &mat, float components[9], - CoordinateSystem CS = CS_default); - -END_PUBLISH - - -//////////////////////////////////////////////////////////////////// -// Function: compose_matrix -// Description: Computes the 3x3 matrix from scale and rotation. -//////////////////////////////////////////////////////////////////// - INLINE void -_compose_matrix(FLOATNAME(LMatrix3) &mat, - const FLOATNAME(LVecBase3) &scale, - const FLOATNAME(LVecBase3) &hpr, - CoordinateSystem cs) { - mat = - FLOATNAME(LMatrix3)::scale_mat(scale) * - FLOATNAME(LMatrix3)::rotate_mat(hpr[1], FLOATNAME(LVector3)::right(cs), cs) * - FLOATNAME(LMatrix3)::rotate_mat(hpr[0], FLOATNAME(LVector3)::up(cs), cs) * - FLOATNAME(LMatrix3)::rotate_mat(hpr[2], FLOATNAME(LVector3)::back(cs), cs); -} - -//////////////////////////////////////////////////////////////////// -// Function: compose_matrix -// Description: Computes the 4x4 matrix according to scale, rotation, -// and translation. -//////////////////////////////////////////////////////////////////// - -INLINE void -_compose_matrix(FLOATNAME(LMatrix4) &mat, - const FLOATNAME(LVecBase3) &scale, - const FLOATNAME(LVecBase3) &hpr, - const FLOATNAME(LVecBase3) &translate, - CoordinateSystem cs) { - FLOATNAME(LMatrix3) upper3; - _compose_matrix(upper3, scale, hpr, cs); - mat = FLOATNAME(LMatrix4)(upper3, translate); -} - -INLINE void -compose_matrix(FLOATNAME(LMatrix4) &mat, - const FLOATTYPE1 components[9], +compose_matrix(LMatrix4f &mat, + const float components[9], CoordinateSystem cs) { - FLOATNAME(LVector3) scale(components[0], + LVector3f scale(components[0], components[1], components[2]); - FLOATNAME(LVector3) hpr(components[3], + LVector3f hpr(components[3], components[4], components[5]); - FLOATNAME(LVector3) translate(components[6], + LVector3f translate(components[6], components[7], components[8]); - _compose_matrix(mat, scale, hpr, translate, cs); + compose_matrix(mat, scale, hpr, translate, cs); } -EXPCL_PANDA INLINE void -compose_matrix(FLOATNAME(LMatrix3) &mat, - const FLOATNAME(LVecBase3) &scale, - const FLOATNAME(LVecBase3) &hpr, +INLINE bool +decompose_matrix(const LMatrix4f &mat, + float components[9], + CoordinateSystem cs) { + LVector3f scale, hpr, translate; + if (!decompose_matrix(mat, scale, hpr, translate, cs)) { + return false; + } + components[0] = scale[0]; + components[1] = scale[1]; + components[2] = scale[2]; + components[3] = hpr[0]; + components[4] = hpr[1]; + components[5] = hpr[2]; + components[6] = translate[0]; + components[7] = translate[1]; + components[8] = translate[2]; + return true; +} + +INLINE void +compose_matrix(LMatrix4d &mat, + const double components[9], CoordinateSystem cs) { - _compose_matrix(mat, scale, hpr, cs); + LVector3d scale(components[0], + components[1], + components[2]); + LVector3d hpr(components[3], + components[4], + components[5]); + LVector3d translate(components[6], + components[7], + components[8]); + compose_matrix(mat, scale, hpr, translate, cs); } -EXPCL_PANDA INLINE void -compose_matrix(FLOATNAME(LMatrix4) &mat, - const FLOATNAME(LVecBase3) &scale, - const FLOATNAME(LVecBase3) &hpr, - const FLOATNAME(LVecBase3) &translate, - CoordinateSystem cs) { - _compose_matrix(mat, scale, hpr, translate, cs); -} +INLINE bool +decompose_matrix(const LMatrix4d &mat, + double components[9], + CoordinateSystem cs) { + LVector3d scale, hpr, translate; + if (!decompose_matrix(mat, scale, hpr, translate, cs)) { + return false; + } + components[0] = scale[0]; + components[1] = scale[1]; + components[2] = scale[2]; + components[3] = hpr[0]; + components[4] = hpr[1]; + components[5] = hpr[2]; + components[6] = translate[0]; + components[7] = translate[1]; + components[8] = translate[2]; + return true; +} diff --git a/panda/src/linmath/compose_matrix.cxx b/panda/src/linmath/compose_matrix.cxx index a96f734ba5..6b5dcb84b9 100644 --- a/panda/src/linmath/compose_matrix.cxx +++ b/panda/src/linmath/compose_matrix.cxx @@ -3,15 +3,706 @@ // //////////////////////////////////////////////////////////////////// +#include "compose_matrix.h" #include "deg_2_rad.h" #include "config_linmath.h" -#include "compose_matrix.h" -#include "fltnames.I" -#include "compose_matrix_src.I" +#include -#include "dblnames.I" -#include "compose_matrix_src.I" +//////////////////////////////////////////////////////////////////// +// Function: compose_matrix +// Description: Computes the 3x3 matrix from scale and rotation. +//////////////////////////////////////////////////////////////////// +template +INLINE void +_compose_matrix(LMatrix3 &mat, + const LVecBase3 &scale, + const LVecBase3 &hpr, + CoordinateSystem cs) { + mat = + LMatrix3::scale_mat(scale) * + LMatrix3::rotate_mat(hpr[1], LVector3::right(cs), cs) * + LMatrix3::rotate_mat(hpr[0], LVector3::up(cs), cs) * + LMatrix3::rotate_mat(hpr[2], LVector3::back(cs), cs); +} + +//////////////////////////////////////////////////////////////////// +// Function: compose_matrix +// Description: Computes the 4x4 matrix according to scale, rotation, +// and translation. +//////////////////////////////////////////////////////////////////// +template +INLINE void +_compose_matrix(LMatrix4 &mat, + const LVecBase3 &scale, + const LVecBase3 &hpr, + const LVecBase3 &translate, + CoordinateSystem cs) { + LMatrix3 upper3; + _compose_matrix(upper3, scale, hpr, cs); + mat = LMatrix4(upper3, translate); +} +//////////////////////////////////////////////////////////////////// +// Function: unwind_yup_rotation +// Description: Extracts the rotation about the x, y, and z axes from +// the given hpr & scale matrix. Adjusts the matrix +// to eliminate the rotation. +// +// This function assumes the matrix is stored in a +// right-handed Y-up coordinate system. +//////////////////////////////////////////////////////////////////// +template +static void +unwind_yup_rotation(LMatrix3 &mat, LVecBase3 &hpr) { + typedef LMatrix3 Matrix; + + // Extract the axes from the matrix. + LVector3 x, y, z; + x = mat.get_row(0); + y = mat.get_row(1); + z = mat.get_row(2); + + // Project X onto the XY plane. + LVector2 xy(x[0], x[1]); + xy = normalize(xy); + + // Compute the rotation about the +Z (back) axis. This is roll. + NumType roll = rad_2_deg(atan2(xy[1], xy[0])); + + // Unwind the roll from the axes, and continue. + Matrix rot_z; + rot_z = Matrix::rotate_mat(-roll, LVector3(0.0, 0.0, 1.0), + CS_yup_right); + + x = x * rot_z; + y = y * rot_z; + z = z * rot_z; + + // Project the rotated X into the XZ plane. + LVector2 xz(x[0], x[2]); + xz = normalize(xz); + + // Compute the rotation about the +Y (up) axis. This is yaw, or + // "heading". + NumType heading = rad_2_deg(-atan2(xz[1], xz[0])); + + // Unwind the heading, and continue. + Matrix rot_y; + rot_y = Matrix::rotate_mat(-heading, LVector3(0.0, 1.0, 0.0), + CS_yup_right); + + x = x * rot_y; + y = y * rot_y; + z = z * rot_y; + + // Project the rotated Z into the YZ plane. + LVector2 yz(z[1], z[2]); + yz = normalize(yz); + + // Compute the rotation about the +X (right) axis. This is pitch. + NumType pitch = rad_2_deg(-atan2(yz[0], yz[1])); + + // Unwind the pitch. + Matrix rot_x; + rot_x = Matrix::rotate_mat(-pitch, LVector3(1.0, 0.0, 0.0), + CS_yup_right); + + x = x * rot_x; + y = y * rot_x; + z = z * rot_x; + + // Reset the matrix to reflect the unwinding. + mat.set_row(0, x); + mat.set_row(1, y); + mat.set_row(2, z); + + // Return the three rotation components. + hpr[0] = heading; + hpr[1] = pitch; + hpr[2] = roll; +} + +//////////////////////////////////////////////////////////////////// +// Function: unwind_yup_rotation +// Description: Extracts the rotation about the x, y, and z axes from +// the given hpr & scale matrix, given the indicated +// roll amount as a hint. Adjusts the matrix to +// eliminate the rotation. +// +// This function assumes the matrix is stored in a +// right-handed Y-up coordinate system. +//////////////////////////////////////////////////////////////////// +template +static void +unwind_yup_rotation(LMatrix3 &mat, LVecBase3 &hpr, + NumType roll) { + typedef LMatrix3 Matrix; + + // Extract the axes from the matrix. + LVector3 x, y, z; + x = mat.get_row(0); + y = mat.get_row(1); + z = mat.get_row(2); + + // Unwind the roll from the axes, and continue. + Matrix rot_z; + rot_z = Matrix::rotate_mat(-roll, LVector3(0.0, 0.0, 1.0), + CS_yup_right); + + x = x * rot_z; + y = y * rot_z; + z = z * rot_z; + + // Project the rotated X into the XZ plane. + LVector2 xz(x[0], x[2]); + xz = normalize(xz); + + // Compute the rotation about the +Y (up) axis. This is yaw, or + // "heading". + NumType heading = rad_2_deg(-atan2(xz[1], xz[0])); + + // Unwind the heading, and continue. + Matrix rot_y; + rot_y = Matrix::rotate_mat(-heading, LVector3(0.0, 1.0, 0.0), + CS_yup_right); + + x = x * rot_y; + y = y * rot_y; + z = z * rot_y; + + // Project the rotated Z into the YZ plane. + LVector2 yz(z[1], z[2]); + yz = normalize(yz); + + // Compute the rotation about the +X (right) axis. This is pitch. + NumType pitch = rad_2_deg(-atan2(yz[0], yz[1])); + + // Unwind the pitch. + Matrix rot_x; + rot_x = Matrix::rotate_mat(-pitch, LVector3(1.0, 0.0, 0.0), + CS_yup_right); + + x = x * rot_x; + y = y * rot_x; + z = z * rot_x; + + // Reset the matrix to reflect the unwinding. + mat.set_row(0, x); + mat.set_row(1, y); + mat.set_row(2, z); + + // Return the three rotation components. + hpr[0] = heading; + hpr[1] = pitch; + hpr[2] = roll; +} + +//////////////////////////////////////////////////////////////////// +// Function: unwind_zup_rotation +// Description: Extracts the rotation about the x, y, and z axes from +// the given hpr & scale matrix. Adjusts the matrix +// to eliminate the rotation. +// +// This function assumes the matrix is stored in a +// right-handed Z-up coordinate system. +//////////////////////////////////////////////////////////////////// +template +static void +unwind_zup_rotation(LMatrix3 &mat, LVecBase3 &hpr) { + typedef LMatrix3 Matrix; + + // Extract the axes from the matrix. + LVector3 x, y, z; + x = mat.get_row(0); + y = mat.get_row(1); + z = mat.get_row(2); + + + // Project X into the XZ plane. + LVector2 xz(x[0], x[2]); + xz = normalize(xz); + + // Compute the rotation about the -Y (back) axis. This is roll. + NumType roll = rad_2_deg(atan2(xz[1], xz[0])); + + if (y[1] < 0.0) { + if (roll < 0.0) { + roll += 180.0; + } else { + roll -= 180.0; + } + } + + // Unwind the roll from the axes, and continue. + Matrix rot_y; + rot_y = Matrix::rotate_mat(roll, LVector3(0.0, 1.0, 0.0), + CS_zup_right); + + x = x * rot_y; + y = y * rot_y; + z = z * rot_y; + + // Project the rotated X into the XY plane. + LVector2 xy(x[0], x[1]); + xy = normalize(xy); + + // Compute the rotation about the +Z (up) axis. This is yaw, or + // "heading". + NumType heading = rad_2_deg(atan2(xy[1], xy[0])); + + // Unwind the heading, and continue. + Matrix rot_z; + rot_z = Matrix::rotate_mat(-heading, LVector3(0.0, 0.0, 1.0), + CS_zup_right); + + x = x * rot_z; + y = y * rot_z; + z = z * rot_z; + + // Project the rotated Y into the YZ plane. + LVector2 yz(y[1], y[2]); + yz = normalize(yz); + + // Compute the rotation about the +X (right) axis. This is pitch. + NumType pitch = rad_2_deg(atan2(yz[1], yz[0])); + + // Unwind the pitch. + Matrix rot_x; + rot_x = Matrix::rotate_mat(-pitch, LVector3(1.0, 0.0, 0.0), + CS_zup_right); + + x = x * rot_x; + y = y * rot_x; + z = z * rot_x; + + // Reset the matrix to reflect the unwinding. + mat.set_row(0, x); + mat.set_row(1, y); + mat.set_row(2, z); + + // Return the three rotation components. + hpr[0] = heading; + hpr[1] = pitch; + hpr[2] = roll; +} + +//////////////////////////////////////////////////////////////////// +// Function: unwind_zup_rotation +// Description: Extracts the rotation about the x, y, and z axes from +// the given hpr & scale matrix, given the indicated +// roll amount as a hint. Adjusts the matrix to +// eliminate the rotation. +// +// This function assumes the matrix is stored in a +// right-handed Z-up coordinate system. +//////////////////////////////////////////////////////////////////// +template +static void +unwind_zup_rotation(LMatrix3 &mat, LVecBase3 &hpr, + NumType roll) { + typedef LMatrix3 Matrix; + + // Extract the axes from the matrix. + LVector3 x, y, z; + x = mat.get_row(0); + y = mat.get_row(1); + z = mat.get_row(2); + + // Unwind the roll from the axes, and continue. + Matrix rot_y; + rot_y = Matrix::rotate_mat(roll, LVector3(0.0, 1.0, 0.0), + CS_zup_right); + + x = x * rot_y; + y = y * rot_y; + z = z * rot_y; + + // Project the rotated X into the XY plane. + LVector2 xy(x[0], x[1]); + xy = normalize(xy); + + // Compute the rotation about the +Z (up) axis. This is yaw, or + // "heading". + NumType heading = rad_2_deg(atan2(xy[1], xy[0])); + + // Unwind the heading, and continue. + Matrix rot_z; + rot_z = Matrix::rotate_mat(-heading, LVector3(0.0, 0.0, 1.0), + CS_zup_right); + + x = x * rot_z; + y = y * rot_z; + z = z * rot_z; + + // Project the rotated Y into the YZ plane. + LVector2 yz(y[1], y[2]); + yz = normalize(yz); + + // Compute the rotation about the +X (right) axis. This is pitch. + NumType pitch = rad_2_deg(atan2(yz[1], yz[0])); + + // Unwind the pitch. + Matrix rot_x; + rot_x = Matrix::rotate_mat(-pitch, LVector3(1.0, 0.0, 0.0), + CS_zup_right); + + x = x * rot_x; + y = y * rot_x; + z = z * rot_x; + + // Reset the matrix to reflect the unwinding. + mat.set_row(0, x); + mat.set_row(1, y); + mat.set_row(2, z); + + // Return the three rotation components. + hpr[0] = heading; + hpr[1] = pitch; + hpr[2] = roll; +} + +//////////////////////////////////////////////////////////////////// +// Function: decompose_matrix +// Description: Extracts out the components of a 3x3 rotation matrix. +// Returns true if the scale and hpr completely describe +// the matrix, or false if there is also a shear +// component or if the matrix is not affine. +//////////////////////////////////////////////////////////////////// +template +static bool +_decompose_matrix(const LMatrix3 &mat, + LVecBase3 &scale, + LVecBase3 &hpr, + CoordinateSystem cs) { + if (cs == CS_default) { + cs = default_coordinate_system; + } + + // Extract the rotation and scale, according to the coordinate + // system of choice. + bool shear; + + switch (cs) { + case CS_zup_right: + { + LMatrix3 rm(mat); + unwind_zup_rotation(rm, hpr); + scale[0] = rm(0, 0); + scale[1] = rm(1, 1); + scale[2] = rm(2, 2); + shear = + (fabs(rm(0, 1)) + fabs(rm(0, 2)) + + fabs(rm(1, 0)) + fabs(rm(1, 2)) + + fabs(rm(2, 0)) + fabs(rm(2, 1))) >= 0.0001; + } + break; + + case CS_yup_right: + { + LMatrix3 rm(mat); + unwind_yup_rotation(rm, hpr); + scale[0] = rm(0, 0); + scale[1] = rm(1, 1); + scale[2] = rm(2, 2); + shear = + (fabs(rm(0, 1)) + fabs(rm(0, 2)) + + fabs(rm(1, 0)) + fabs(rm(1, 2)) + + fabs(rm(2, 0)) + fabs(rm(2, 1))) >= 0.0001; + } + break; + + case CS_zup_left: + { + LMatrix3 lm(mat(0, 0), mat(0, 1), -mat(0, 2), + mat(1, 0), mat(1, 1), -mat(1, 2), + -mat(2, 0), -mat(2, 1), mat(2, 2)); + unwind_zup_rotation(lm, hpr); + scale[0] = -lm(0, 0); + scale[1] = -lm(1, 1); + scale[2] = lm(2, 2); + shear = + (fabs(lm(0, 1)) + fabs(lm(0, 2)) + + fabs(lm(1, 0)) + fabs(lm(1, 2)) + + fabs(lm(2, 0)) + fabs(lm(2, 1))) >= 0.0001; + } + break; + + case CS_yup_left: + { + LMatrix3 lm(mat(0, 0), mat(0, 1), -mat(0, 2), + mat(1, 0), mat(1, 1), -mat(1, 2), + -mat(2, 0), -mat(2, 1), mat(2, 2)); + unwind_yup_rotation(lm, hpr); + scale[0] = -lm(0, 0); + scale[1] = -lm(1, 1); + scale[2] = lm(2, 2); + shear = + (fabs(lm(0, 1)) + fabs(lm(0, 2)) + + fabs(lm(1, 0)) + fabs(lm(1, 2)) + + fabs(lm(2, 0)) + fabs(lm(2, 1))) >= 0.0001; + } + break; + + default: + linmath_cat.error() + << "Unexpected coordinate system: " << (int)cs << "\n"; + return false; + } + + return !shear; +} + +//////////////////////////////////////////////////////////////////// +// Function: decompose_matrix +// Description: Extracts out the components of a 3x3 rotation matrix. +// Returns true if the scale and hpr completely describe +// the matrix, or false if there is also a shear +// component or if the matrix is not affine. +// +// This flavor of the function accepts an expected roll +// amount. This amount will be used as the roll +// component, rather than attempting to determine roll +// by examining the matrix; this helps alleviate roll +// instability due to roundoff errors or gimbal lock. +//////////////////////////////////////////////////////////////////// +template +static bool +_decompose_matrix(const LMatrix3 &mat, + LVecBase3 &scale, + LVecBase3 &hpr, + NumType roll, + CoordinateSystem cs) { + if (cs == CS_default) { + cs = default_coordinate_system; + } + + // Extract the rotation and scale, according to the coordinate + // system of choice. + bool shear; + + switch (cs) { + case CS_zup_right: + { + LMatrix3 rm(mat); + unwind_zup_rotation(rm, hpr, roll); + scale[0] = rm(0, 0); + scale[1] = rm(1, 1); + scale[2] = rm(2, 2); + shear = + (fabs(rm(0, 1)) + fabs(rm(0, 2)) + + fabs(rm(1, 0)) + fabs(rm(1, 2)) + + fabs(rm(2, 0)) + fabs(rm(2, 1))) >= 0.0001; + } + break; + + case CS_yup_right: + { + LMatrix3 rm(mat); + unwind_yup_rotation(rm, hpr, roll); + scale[0] = rm(0, 0); + scale[1] = rm(1, 1); + scale[2] = rm(2, 2); + shear = + (fabs(rm(0, 1)) + fabs(rm(0, 2)) + + fabs(rm(1, 0)) + fabs(rm(1, 2)) + + fabs(rm(2, 0)) + fabs(rm(2, 1))) >= 0.0001; + } + break; + + case CS_zup_left: + { + LMatrix3 lm(mat(0, 0), mat(0, 1), -mat(0, 2), + mat(1, 0), mat(1, 1), -mat(1, 2), + -mat(2, 0), -mat(2, 1), mat(2, 2)); + unwind_zup_rotation(lm, hpr, roll); + scale[0] = -lm(0, 0); + scale[1] = -lm(1, 1); + scale[2] = lm(2, 2); + shear = + (fabs(lm(0, 1)) + fabs(lm(0, 2)) + + fabs(lm(1, 0)) + fabs(lm(1, 2)) + + fabs(lm(2, 0)) + fabs(lm(2, 1))) >= 0.0001; + } + break; + + case CS_yup_left: + { + LMatrix3 lm(mat(0, 0), mat(0, 1), -mat(0, 2), + mat(1, 0), mat(1, 1), -mat(1, 2), + -mat(2, 0), -mat(2, 1), mat(2, 2)); + unwind_yup_rotation(lm, hpr, roll); + scale[0] = -lm(0, 0); + scale[1] = -lm(1, 1); + scale[2] = lm(2, 2); + shear = + (fabs(lm(0, 1)) + fabs(lm(0, 2)) + + fabs(lm(1, 0)) + fabs(lm(1, 2)) + + fabs(lm(2, 0)) + fabs(lm(2, 1))) >= 0.0001; + } + break; + + default: + linmath_cat.error() + << "Unexpected coordinate system: " << (int)cs << "\n"; + return false; + } + + return !shear; +} + +//////////////////////////////////////////////////////////////////// +// Function: decompose_matrix +// Description: Extracts out the components of an affine matrix. +// Returns true if the scale, hpr, translate +// completely describe the matrix, or false if there is +// also a shear component or if the matrix is not +// affine. +//////////////////////////////////////////////////////////////////// +template +INLINE bool +_decompose_matrix(const LMatrix4 &mat, + LVecBase3 &scale, + LVecBase3 &hpr, + LVecBase3 &translate, + CoordinateSystem cs) { + // Get the translation first. + translate = mat.get_row3(3); + return _decompose_matrix(mat.get_upper_3(), scale, hpr, cs); +} + +//////////////////////////////////////////////////////////////////// +// Function: decompose_matrix +// Description: Extracts out the components of an affine matrix. +// Returns true if the scale, hpr, translate +// completely describe the matrix, or false if there is +// also a shear component or if the matrix is not +// affine. +// +// This flavor of the function accepts an expected roll +// amount. This amount will be used as the roll +// component, rather than attempting to determine roll +// by examining the matrix; this helps alleviate roll +// instability due to roundoff errors or gimbal lock. +//////////////////////////////////////////////////////////////////// +template +INLINE bool +_decompose_matrix(const LMatrix4 &mat, + LVecBase3 &scale, + LVecBase3 &hpr, + LVecBase3 &translate, + NumType roll, + CoordinateSystem cs) { + // Get the translation first. + translate = mat.get_row3(3); + return _decompose_matrix(mat.get_upper_3(), scale, hpr, roll, cs); +} + +void +compose_matrix(LMatrix3f &mat, + const LVecBase3f &scale, + const LVecBase3f &hpr, + CoordinateSystem cs) { + _compose_matrix(mat, scale, hpr, cs); +} + +bool +decompose_matrix(const LMatrix3f &mat, + LVecBase3f &scale, + LVecBase3f &hpr, + CoordinateSystem cs) { + return _decompose_matrix(mat, scale, hpr, cs); +} + +bool +decompose_matrix(const LMatrix3f &mat, + LVecBase3f &scale, + LVecBase3f &hpr, + float roll, + CoordinateSystem cs) { + return _decompose_matrix(mat, scale, hpr, roll, cs); +} + +void +compose_matrix(LMatrix3d &mat, + const LVecBase3d &scale, + const LVecBase3d &hpr, + CoordinateSystem cs) { + _compose_matrix(mat, scale, hpr, cs); +} + +bool +decompose_matrix(const LMatrix3d &mat, + LVecBase3d &scale, + LVecBase3d &hpr, + CoordinateSystem cs) { + return _decompose_matrix(mat, scale, hpr, cs); +} + +bool +decompose_matrix(const LMatrix3d &mat, + LVecBase3d &scale, + LVecBase3d &hpr, + double roll, + CoordinateSystem cs) { + return _decompose_matrix(mat, scale, hpr, roll, cs); +} + +void +compose_matrix(LMatrix4f &mat, + const LVecBase3f &scale, + const LVecBase3f &hpr, + const LVecBase3f &translate, + CoordinateSystem cs) { + _compose_matrix(mat, scale, hpr, translate, cs); +} + +bool +decompose_matrix(const LMatrix4f &mat, + LVecBase3f &scale, + LVecBase3f &hpr, + LVecBase3f &translate, + CoordinateSystem cs) { + return _decompose_matrix(mat, scale, hpr, translate, cs); +} + +bool +decompose_matrix(const LMatrix4f &mat, + LVecBase3f &scale, + LVecBase3f &hpr, + LVecBase3f &translate, + float roll, + CoordinateSystem cs) { + return _decompose_matrix(mat, scale, hpr, translate, roll, cs); +} + +void +compose_matrix(LMatrix4d &mat, + const LVecBase3d &scale, + const LVecBase3d &hpr, + const LVecBase3d &translate, + CoordinateSystem cs) { + _compose_matrix(mat, scale, hpr, translate, cs); +} + +bool +decompose_matrix(const LMatrix4d &mat, + LVecBase3d &scale, + LVecBase3d &hpr, + LVecBase3d &translate, + CoordinateSystem cs) { + return _decompose_matrix(mat, scale, hpr, translate, cs); +} + +bool +decompose_matrix(const LMatrix4d &mat, + LVecBase3d &scale, + LVecBase3d &hpr, + LVecBase3d &translate, + double roll, + CoordinateSystem cs) { + return _decompose_matrix(mat, scale, hpr, translate, roll, cs); +} + diff --git a/panda/src/linmath/compose_matrix.h b/panda/src/linmath/compose_matrix.h index a30c9a7c1f..014e3499c8 100644 --- a/panda/src/linmath/compose_matrix.h +++ b/panda/src/linmath/compose_matrix.h @@ -26,14 +26,98 @@ //////////////////////////////////////////////////////////////////// #include -#include + #include "lmatrix.h" #include "luse.h" -#include "fltnames.I" -#include "compose_matrix.I" +BEGIN_PUBLISH + +EXPCL_PANDA void +compose_matrix(LMatrix3f &mat, + const LVecBase3f &scale, + const LVecBase3f &hpr, + CoordinateSystem cs = CS_default); +EXPCL_PANDA bool +decompose_matrix(const LMatrix3f &mat, + LVecBase3f &scale, + LVecBase3f &hpr, + CoordinateSystem cs = CS_default); +EXPCL_PANDA bool +decompose_matrix(const LMatrix3f &mat, + LVecBase3f &scale, + LVecBase3f &hpr, + float roll, + CoordinateSystem cs = CS_default); + +EXPCL_PANDA void +compose_matrix(LMatrix3d &mat, + const LVecBase3d &scale, + const LVecBase3d &hpr, + CoordinateSystem cs = CS_default); +EXPCL_PANDA bool +decompose_matrix(const LMatrix3d &mat, + LVecBase3d &scale, + LVecBase3d &hpr, + CoordinateSystem cs = CS_default); +EXPCL_PANDA bool +decompose_matrix(const LMatrix3d &mat, + LVecBase3d &scale, + LVecBase3d &hpr, + double roll, + CoordinateSystem cs = CS_default); + +EXPCL_PANDA void +compose_matrix(LMatrix4f &mat, + const LVecBase3f &scale, + const LVecBase3f &hpr, + const LVecBase3f &translate, + CoordinateSystem cs = CS_default); +INLINE void compose_matrix(LMatrix4f &mat, const float components[9], + CoordinateSystem cs = CS_default); + +EXPCL_PANDA bool +decompose_matrix(const LMatrix4f &mat, + LVecBase3f &scale, + LVecBase3f &hpr, + LVecBase3f &translate, + CoordinateSystem cs = CS_default); +EXPCL_PANDA bool +decompose_matrix(const LMatrix4f &mat, + LVecBase3f &scale, + LVecBase3f &hpr, + LVecBase3f &translate, + float roll, + CoordinateSystem cs = CS_default); +INLINE bool decompose_matrix(const LMatrix4f &mat, float components[9], + CoordinateSystem CS = CS_default); + +EXPCL_PANDA void +compose_matrix(LMatrix4d &mat, + const LVecBase3d &scale, + const LVecBase3d &hpr, + const LVecBase3d &translate, + CoordinateSystem cs = CS_default); +INLINE void compose_matrix(LMatrix4d &mat, const double components[9], + CoordinateSystem cs = CS_default); + +bool EXPCL_PANDA +decompose_matrix(const LMatrix4d &mat, + LVecBase3d &scale, + LVecBase3d &hpr, + LVecBase3d &translate, + CoordinateSystem cs = CS_default); +bool EXPCL_PANDA +decompose_matrix(const LMatrix4d &mat, + LVecBase3d &scale, + LVecBase3d &hpr, + LVecBase3d &translate, + double roll, + CoordinateSystem cs = CS_default); +INLINE bool decompose_matrix(const LMatrix4d &mat, double components[9], + CoordinateSystem cs = CS_default); + +END_PUBLISH -#include "dblnames.I" #include "compose_matrix.I" #endif diff --git a/panda/src/linmath/lmat_ops.I b/panda/src/linmath/lmat_ops.I index 2b521355d0..802ebec4c2 100644 --- a/panda/src/linmath/lmat_ops.I +++ b/panda/src/linmath/lmat_ops.I @@ -3,90 +3,13 @@ // //////////////////////////////////////////////////////////////////// -/* -// vector times matrix3 - -INLINE FLOATNAME(LVecBase3) -operator * (const FLOATNAME(LVecBase3) &v, const FLOATNAME(LMatrix3) &m); - - -INLINE FLOATNAME(LVector2) -operator * (const FLOATNAME(LVector2) &v, const FLOATNAME(LMatrix3) &m); - - -INLINE FLOATNAME(LPoint2) -operator * (const FLOATNAME(LPoint2) &v, const FLOATNAME(LMatrix3) &m); - - -// vector times matrix4 - -INLINE FLOATNAME(LVecBase4) -operator * (const FLOATNAME(LVecBase4) &v, const FLOATNAME(LMatrix4) &m); - - -INLINE FLOATNAME(LVector3) -operator * (const FLOATNAME(LVector3) &v, const FLOATNAME(LMatrix4) &m); - - -INLINE FLOATNAME(LPoint3) -operator * (const FLOATNAME(LPoint3) &v, const FLOATNAME(LMatrix4) &m); -*/ -#ifdef CPPPARSER -// Strictly for the benefit of interrogate, we'll define explicit -// 'instantiations' of the above template functions on types float and -// double. - -BEGIN_PUBLISH - -INLINE FLOATNAME(LVecBase3) -operator * (const FLOATNAME(LVecBase3) &v, const FLOATNAME(LMatrix3) &m); -INLINE FLOATNAME(LVector2) -operator * (const FLOATNAME(LVector2) &v, const FLOATNAME(LMatrix3) &m); -INLINE FLOATNAME(LPoint2) -operator * (const FLOATNAME(LPoint2) &v, const FLOATNAME(LMatrix3) &m); -INLINE FLOATNAME(LVecBase4) -operator * (const FLOATNAME(LVecBase4) &v, const FLOATNAME(LMatrix4) &m); -INLINE FLOATNAME(LVector3) -operator * (const FLOATNAME(LVector3) &v, const FLOATNAME(LMatrix4) &m); -INLINE FLOATNAME(LPoint3) -operator * (const FLOATNAME(LPoint3) &v, const FLOATNAME(LMatrix4) &m); - -/* -INLINE LVecBase3 -operator * (const LVecBase3 &v, const LMatrix3 &m); -INLINE LVector2 -operator * (const LVector2 &v, const LMatrix3 &m); -INLINE LPoint2 -operator * (const LPoint2 &v, const LMatrix3 &m); -INLINE LVecBase4 -operator * (const LVecBase4 &v, const LMatrix4 &m); -INLINE LVector3 -operator * (const LVector3 &v, const LMatrix4 &m); -INLINE LPoint3 -operator * (const LPoint3 &v, const LMatrix4 &m); -*/ - -END_PUBLISH - -#endif // CPPPARSER - //////////////////////////////////////////////////////////////////// // Function: LVecBase3 times LMatrix3 // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) -operator * (const FLOATNAME(LVecBase3) &v, const FLOATNAME(LMatrix3) &m) { - return m.xform(v); -} - -INLINE FLOATNAME(LVector3) -operator * (const FLOATNAME(LVector3) &v, const FLOATNAME(LMatrix3) &m) { - return m.xform(v); -} - -INLINE FLOATNAME(LPoint3) -operator * (const FLOATNAME(LPoint3) &v, const FLOATNAME(LMatrix3) &m) { +template +INLINE LVecBase3 +operator * (const LVecBase3 &v, const LMatrix3 &m) { return m.xform(v); } @@ -94,9 +17,9 @@ operator * (const FLOATNAME(LPoint3) &v, const FLOATNAME(LMatrix3) &m) { // Function: LVector2 times LMatrix3 // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2) -operator * (const FLOATNAME(LVector2) &v, const FLOATNAME(LMatrix3) &m) { +template +INLINE LVector2 +operator * (const LVector2 &v, const LMatrix3 &m) { return m.xform_vec(v); } @@ -104,9 +27,9 @@ operator * (const FLOATNAME(LVector2) &v, const FLOATNAME(LMatrix3) &m) { // Function: LPoint2 times LMatrix3 // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint2) -operator * (const FLOATNAME(LPoint2) &v, const FLOATNAME(LMatrix3) &m) { +template +INLINE LPoint2 +operator * (const LPoint2 &v, const LMatrix3 &m) { return m.xform_point(v); } @@ -115,30 +38,19 @@ operator * (const FLOATNAME(LPoint2) &v, const FLOATNAME(LMatrix3) &m) { // Function: LVecBase4 times LMatrix4 // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) -operator * (const FLOATNAME(LVecBase4) &v, const FLOATNAME(LMatrix4) &m) { +template +INLINE LVecBase4 +operator * (const LVecBase4 &v, const LMatrix4 &m) { return m.xform(v); } -INLINE FLOATNAME(LVector4) -operator * (const FLOATNAME(LVector4) &v, const FLOATNAME(LMatrix4) &m) { - return m.xform(v); -} - -INLINE FLOATNAME(LPoint4) -operator * (const FLOATNAME(LPoint4) &v, const FLOATNAME(LMatrix4) &m) { - return m.xform(v); -} - - //////////////////////////////////////////////////////////////////// // Function: LVector3 times LMatrix4 // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) -operator * (const FLOATNAME(LVector3) &v, const FLOATNAME(LMatrix4) &m) { +template +INLINE LVector3 +operator * (const LVector3 &v, const LMatrix4 &m) { return m.xform_vec(v); } @@ -146,9 +58,9 @@ operator * (const FLOATNAME(LVector3) &v, const FLOATNAME(LMatrix4) &m) { // Function: LPoint3 times LMatrix4 // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) -operator * (const FLOATNAME(LPoint3) &v, const FLOATNAME(LMatrix4) &m) { +template +INLINE LPoint3 +operator * (const LPoint3 &v, const LMatrix4 &m) { return m.xform_point(v); } diff --git a/panda/src/linmath/lmat_ops.h b/panda/src/linmath/lmat_ops.h index c29e779b1b..1703b1ac56 100644 --- a/panda/src/linmath/lmat_ops.h +++ b/panda/src/linmath/lmat_ops.h @@ -15,11 +15,71 @@ #include "lmatrix3.h" #include "lmatrix4.h" -#include "fltnames.I" -#include "lmat_ops.I" -#include "dblnames.I" -#include "lmat_ops.I" +// vector times matrix3 +template +INLINE LVecBase3 +operator * (const LVecBase3 &v, const LMatrix3 &m); +template +INLINE LVector2 +operator * (const LVector2 &v, const LMatrix3 &m); + +template +INLINE LPoint2 +operator * (const LPoint2 &v, const LMatrix3 &m); + + +// vector times matrix4 +template +INLINE LVecBase4 +operator * (const LVecBase4 &v, const LMatrix4 &m); + +template +INLINE LVector3 +operator * (const LVector3 &v, const LMatrix4 &m); + +template +INLINE LPoint3 +operator * (const LPoint3 &v, const LMatrix4 &m); + +#ifdef CPPPARSER +// Strictly for the benefit of interrogate, we'll define explicit +// 'instantiations' of the above template functions on types float and +// double. + +BEGIN_PUBLISH + +INLINE LVecBase3 +operator * (const LVecBase3 &v, const LMatrix3 &m); +INLINE LVector2 +operator * (const LVector2 &v, const LMatrix3 &m); +INLINE LPoint2 +operator * (const LPoint2 &v, const LMatrix3 &m); +INLINE LVecBase4 +operator * (const LVecBase4 &v, const LMatrix4 &m); +INLINE LVector3 +operator * (const LVector3 &v, const LMatrix4 &m); +INLINE LPoint3 +operator * (const LPoint3 &v, const LMatrix4 &m); + +INLINE LVecBase3 +operator * (const LVecBase3 &v, const LMatrix3 &m); +INLINE LVector2 +operator * (const LVector2 &v, const LMatrix3 &m); +INLINE LPoint2 +operator * (const LPoint2 &v, const LMatrix3 &m); +INLINE LVecBase4 +operator * (const LVecBase4 &v, const LMatrix4 &m); +INLINE LVector3 +operator * (const LVector3 &v, const LMatrix4 &m); +INLINE LPoint3 +operator * (const LPoint3 &v, const LMatrix4 &m); + +END_PUBLISH + +#endif // CPPPARSER + +#include "lmat_ops.I" #endif diff --git a/panda/src/linmath/lmatrix.h b/panda/src/linmath/lmatrix.h index 9e68db8ec8..d56cbf2a5a 100644 --- a/panda/src/linmath/lmatrix.h +++ b/panda/src/linmath/lmatrix.h @@ -7,18 +7,15 @@ #define LMATRIX_H #include -#include "config_linmath.h" #include "lmatrix3.h" #include "lmatrix4.h" -/* typedef LMatrix3 LMatrix3f; typedef LMatrix4 LMatrix4f; typedef LMatrix3 LMatrix3d; typedef LMatrix4 LMatrix4d; -*/ // Tell GCC that we'll take care of the instantiation explicitly here. #ifdef __GNUC__ diff --git a/panda/src/linmath/lmatrix3.I b/panda/src/linmath/lmatrix3.I index 3222b283a7..d39aa4f972 100644 --- a/panda/src/linmath/lmatrix3.I +++ b/panda/src/linmath/lmatrix3.I @@ -3,177 +3,27 @@ // //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Class : LMatrix3 -// Description : This is a 3-by-3 transform matrix. It typically will -// represent either a rotation-and-scale (no -// translation) matrix in 3-d, or a full affine matrix -// (rotation, scale, translation) in 2-d, e.g. for a -// texture matrix. -//////////////////////////////////////////////////////////////////// +#include -class EXPCL_PANDA FLOATNAME(LMatrix3) { -PUBLISHED: - typedef const FLOATTYPE1 *iterator; - typedef const FLOATTYPE1 *const_iterator; +#include "deg_2_rad.h" +#include "nearly_zero.h" - INLINE FLOATNAME(LMatrix3)(); - INLINE FLOATNAME(LMatrix3)(const FLOATNAME(LMatrix3) &other); - INLINE FLOATNAME(LMatrix3) &operator = (const FLOATNAME(LMatrix3) &other); - INLINE FLOATNAME(LMatrix3) &operator = (FLOATTYPE1 fill_value); - INLINE FLOATNAME(LMatrix3)(FLOATTYPE1 e00, FLOATTYPE1 e01, FLOATTYPE1 e02, - FLOATTYPE1 e10, FLOATTYPE1 e11, FLOATTYPE1 e12, - FLOATTYPE1 e20, FLOATTYPE1 e21, FLOATTYPE1 e22); +#include +#include - void fill(FLOATTYPE1 fill_value); - INLINE void set(FLOATTYPE1 e00, FLOATTYPE1 e01, FLOATTYPE1 e02, - FLOATTYPE1 e10, FLOATTYPE1 e11, FLOATTYPE1 e12, - FLOATTYPE1 e20, FLOATTYPE1 e21, FLOATTYPE1 e22); +#include - INLINE void set_row(int row, const FLOATNAME(LVecBase3) &v); - INLINE void set_col(int col, const FLOATNAME(LVecBase3) &v); - - INLINE void set_row(int row, const FLOATNAME(LVecBase2) &v); - INLINE void set_col(int col, const FLOATNAME(LVecBase2) &v); - - INLINE FLOATNAME(LVecBase3) get_row(int row) const; - INLINE FLOATNAME(LVecBase3) get_col(int col) const; - - INLINE FLOATNAME(LVecBase2) get_row2(int row) const; - INLINE FLOATNAME(LVecBase2) get_col2(int col) const; - - INLINE FLOATTYPE1 &operator () (int row, int col); - INLINE FLOATTYPE1 operator () (int row, int col) const; - - INLINE bool is_nan() const; - - INLINE FLOATTYPE1 get_cell(int row, int col) const; - INLINE void set_cell(int row, int col, FLOATTYPE1 value); - - INLINE const FLOATTYPE1 *get_data() const; - INLINE int get_num_components() const; - -public: - INLINE iterator begin(); - INLINE iterator end(); - - INLINE const_iterator begin() const; - INLINE const_iterator end() const; - -PUBLISHED: - bool operator == (const FLOATNAME(LMatrix3) &other) const; - INLINE bool operator != (const FLOATNAME(LMatrix3) &other) const; - - INLINE int compare_to(const FLOATNAME(LMatrix3) &other) const; - int compare_to(const FLOATNAME(LMatrix3) &other, FLOATTYPE1 threshold) const; - - INLINE FLOATNAME(LVecBase3) - xform(const FLOATNAME(LVecBase3) &v) const; - - INLINE FLOATNAME(LVecBase2) - xform_point(const FLOATNAME(LVecBase2) &v) const; - - INLINE FLOATNAME(LVecBase2) - xform_vec(const FLOATNAME(LVecBase2) &v) const; - - INLINE FLOATNAME(LMatrix3) operator * (const FLOATNAME(LMatrix3) &other) const; - INLINE FLOATNAME(LMatrix3) operator * (FLOATTYPE1 scalar) const; - INLINE FLOATNAME(LMatrix3) operator / (FLOATTYPE1 scalar) const; - - INLINE FLOATNAME(LMatrix3) &operator += (const FLOATNAME(LMatrix3) &other); - INLINE FLOATNAME(LMatrix3) &operator -= (const FLOATNAME(LMatrix3) &other); - - INLINE FLOATNAME(LMatrix3) &operator *= (const FLOATNAME(LMatrix3) &other); - - INLINE FLOATNAME(LMatrix3) &operator *= (FLOATTYPE1 scalar); - INLINE FLOATNAME(LMatrix3) &operator /= (FLOATTYPE1 scalar); - - INLINE FLOATTYPE1 determinant() const; - - INLINE void transpose_from(const FLOATNAME(LMatrix3) &other); - INLINE void transpose_in_place(); - - INLINE bool invert_from(const FLOATNAME(LMatrix3) &other); - INLINE bool invert_in_place(); - - static INLINE const FLOATNAME(LMatrix3) &ident_mat(); - - // A 3x3 matrix is likely to be used for one of two purposes. In - // 2-d coordinate space (e.g. texture or surface coordinates), it - // can contain a full affine transform, with scale, rotate, - // translate. In 3-d coordinate space, it can contain only scale - // and/or rotate; e.g., the upper 3x3 rectangle of a full 4x4 - // matrix. - - // The following named constructors return 3x3 matrices suitable for - // affine transforms in 2-d coordinate space. - - static INLINE FLOATNAME(LMatrix3) translate_mat(const FLOATNAME(LVecBase2) &trans); - static INLINE FLOATNAME(LMatrix3) translate_mat(FLOATTYPE1 tx, FLOATTYPE1 ty); - static INLINE FLOATNAME(LMatrix3) rotate_mat(FLOATTYPE1 angle); - static INLINE FLOATNAME(LMatrix3) scale_mat(const FLOATNAME(LVecBase2) &scale); - static INLINE FLOATNAME(LMatrix3) scale_mat(FLOATTYPE1 sx, FLOATTYPE1 sy); - - // The following named constructors return 3x3 matrices suitable for - // scale/rotate transforms in 3-d coordinate space. - static INLINE FLOATNAME(LMatrix3) rotate_mat(FLOATTYPE1 angle, - FLOATNAME(LVecBase3) axis, - CoordinateSystem cs = CS_default); - static INLINE FLOATNAME(LMatrix3) scale_mat(const FLOATNAME(LVecBase3) &scale); - static INLINE FLOATNAME(LMatrix3) scale_mat(FLOATTYPE1 sx, FLOATTYPE1 sy, FLOATTYPE1 sz); - - // We don't have a scale_mat() that takes a single uniform scale - // parameter, because it would be ambiguous whether we mean a 2-d or - // a 3-d scale. - - bool almost_equal(const FLOATNAME(LMatrix3) &other, - FLOATTYPE1 threshold) const; - - INLINE bool almost_equal(const FLOATNAME(LMatrix3) &other) const; - - INLINE void output(ostream &out) const; - INLINE void write(ostream &out, int indent_level = 0) const; - -private: - INLINE FLOATTYPE1 mult_cel(const FLOATNAME(LMatrix3) &other, int x, int y) const; - INLINE FLOATTYPE1 det2(FLOATTYPE1 e00, FLOATTYPE1 e01, FLOATTYPE1 e10, FLOATTYPE1 e11) const; - - FLOATTYPE1 _data[3 * 3]; - - //Functionality for reading and writing from/to a binary source -public: - void write_datagram(Datagram& destination) const; - void read_datagram(DatagramIterator& scan); - -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type(); - -private: - static TypeHandle _type_handle; -}; - - -INLINE ostream &operator << (ostream &out, const FLOATNAME(LMatrix3) &mat) { - mat.output(out); - return out; -} - - -INLINE FLOATNAME(LMatrix3) transpose(const FLOATNAME(LMatrix3) &a); - -INLINE FLOATNAME(LMatrix3) invert(const FLOATNAME(LMatrix3) &a); +template +TypeHandle LMatrix3::_type_handle; //////////////////////////////////////////////////////////////////// // Function: LMatrix3::Default Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3):: -FLOATNAME(LMatrix3)() { +template +INLINE LMatrix3:: +LMatrix3() { } //////////////////////////////////////////////////////////////////// @@ -181,22 +31,22 @@ FLOATNAME(LMatrix3)() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3):: -FLOATNAME(LMatrix3)(const FLOATNAME(LMatrix3) ©) { +template +INLINE LMatrix3:: +LMatrix3(const LMatrix3 ©) { (*this) = copy; } //////////////////////////////////////////////////////////////////// -// Function: LMatrix4::Copy Assignment Operator +// Function: LMatrix3::Copy Assignment Operator // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) &FLOATNAME(LMatrix3):: -operator = (const FLOATNAME(LMatrix3) ©) { - set(copy(0, 0), copy(0, 1), copy(0, 2), - copy(1, 0), copy(1, 1), copy(1, 2), +template +LMatrix3 &LMatrix3:: +operator = (const LMatrix3 ©) { + set(copy(0, 0), copy(0, 1), copy(0, 2), + copy(1, 0), copy(1, 1), copy(1, 2), copy(2, 0), copy(2, 1), copy(2, 2)); return *this; } @@ -206,9 +56,9 @@ operator = (const FLOATNAME(LMatrix3) ©) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) &FLOATNAME(LMatrix3):: -operator = (FLOATTYPE1 fill_value) { +template +INLINE LMatrix3 &LMatrix3:: +operator = (NumType fill_value) { fill(fill_value); return *this; } @@ -218,26 +68,41 @@ operator = (FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3):: -FLOATNAME(LMatrix3)(FLOATTYPE1 e00, FLOATTYPE1 e01, FLOATTYPE1 e02, - FLOATTYPE1 e10, FLOATTYPE1 e11, FLOATTYPE1 e12, - FLOATTYPE1 e20, FLOATTYPE1 e21, FLOATTYPE1 e22) { +template +INLINE LMatrix3:: +LMatrix3(NumType e00, NumType e01, NumType e02, + NumType e10, NumType e11, NumType e12, + NumType e20, NumType e21, NumType e22) { set(e00, e01, e02, e10, e11, e12, e20, e21, e22); } +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::fill +// Access: Public +// Description: Sets each element of the matrix to the indicated +// fill_value. This is of questionable value, but is +// sometimes useful when initializing to zero. +//////////////////////////////////////////////////////////////////// +template +void LMatrix3:: +fill(NumType fill_value) { + set(fill_value, fill_value, fill_value, + fill_value, fill_value, fill_value, + fill_value, fill_value, fill_value); +} + //////////////////////////////////////////////////////////////////// // Function: LMatrix3::set // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix3):: -set(FLOATTYPE1 e00, FLOATTYPE1 e01, FLOATTYPE1 e02, - FLOATTYPE1 e10, FLOATTYPE1 e11, FLOATTYPE1 e12, - FLOATTYPE1 e20, FLOATTYPE1 e21, FLOATTYPE1 e22) { +template +INLINE void LMatrix3:: +set(NumType e00, NumType e01, NumType e02, + NumType e10, NumType e11, NumType e12, + NumType e20, NumType e21, NumType e22) { (*this)(0, 0) = e00; (*this)(0, 1) = e01; (*this)(0, 2) = e02; @@ -255,9 +120,9 @@ set(FLOATTYPE1 e00, FLOATTYPE1 e01, FLOATTYPE1 e02, // Description: Replaces the indicated row of the matrix from a // three-component vector. //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix3):: -set_row(int row, const FLOATNAME(LVecBase3) &v) { +template +INLINE void LMatrix3:: +set_row(int row, const LVecBase3 &v) { (*this)(row, 0) = v[0]; (*this)(row, 1) = v[1]; (*this)(row, 2) = v[2]; @@ -269,9 +134,9 @@ set_row(int row, const FLOATNAME(LVecBase3) &v) { // Description: Replaces the indicated column of the matrix from a // three-component vector. //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix3):: -set_col(int col, const FLOATNAME(LVecBase3) &v) { +template +INLINE void LMatrix3:: +set_col(int col, const LVecBase3 &v) { (*this)(0, col) = v[0]; (*this)(1, col) = v[1]; (*this)(2, col) = v[2]; @@ -283,9 +148,9 @@ set_col(int col, const FLOATNAME(LVecBase3) &v) { // Description: Replaces the indicated row of the matrix from a // two-component vector, ignoring the last column. //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix3):: -set_row(int row, const FLOATNAME(LVecBase2) &v) { +template +INLINE void LMatrix3:: +set_row(int row, const LVecBase2 &v) { (*this)(row, 0) = v[0]; (*this)(row, 1) = v[1]; } @@ -296,9 +161,9 @@ set_row(int row, const FLOATNAME(LVecBase2) &v) { // Description: Replaces the indicated column of the matrix from a // two-component vector, ignoring the last row. //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix3):: -set_col(int col, const FLOATNAME(LVecBase2) &v) { +template +INLINE void LMatrix3:: +set_col(int col, const LVecBase2 &v) { (*this)(0, col) = v[0]; (*this)(1, col) = v[1]; } @@ -309,10 +174,10 @@ set_col(int col, const FLOATNAME(LVecBase2) &v) { // Description: Returns the indicated row of the matrix as a // three-component vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LMatrix3):: +template +INLINE LVecBase3 LMatrix3:: get_row(int row) const { - return FLOATNAME(LVecBase3)((*this)(row, 0), (*this)(row, 1), (*this)(row, 2)); + return LVecBase3((*this)(row, 0), (*this)(row, 1), (*this)(row, 2)); } //////////////////////////////////////////////////////////////////// @@ -321,10 +186,10 @@ get_row(int row) const { // Description: Returns the indicated column of the matrix as a // three-component vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LMatrix3):: +template +INLINE LVecBase3 LMatrix3:: get_col(int col) const { - return FLOATNAME(LVecBase3)((*this)(0, col), (*this)(1, col), (*this)(2, col)); + return LVecBase3((*this)(0, col), (*this)(1, col), (*this)(2, col)); } //////////////////////////////////////////////////////////////////// @@ -333,10 +198,10 @@ get_col(int col) const { // Description: Returns the indicated row of the matrix as a // two-component vector, ignoring the last column. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LMatrix3):: +template +INLINE LVecBase2 LMatrix3:: get_row2(int row) const { - return FLOATNAME(LVecBase2)((*this)(row, 0), (*this)(row, 1)); + return LVecBase2((*this)(row, 0), (*this)(row, 1)); } //////////////////////////////////////////////////////////////////// @@ -345,10 +210,10 @@ get_row2(int row) const { // Description: Returns the indicated column of the matrix as a // two-component vector, ignoring the last row. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LMatrix3):: +template +INLINE LVecBase2 LMatrix3:: get_col2(int col) const { - return FLOATNAME(LVecBase2)((*this)(0, col), (*this)(1, col)); + return LVecBase2((*this)(0, col), (*this)(1, col)); } //////////////////////////////////////////////////////////////////// @@ -356,8 +221,8 @@ get_col2(int col) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 &FLOATNAME(LMatrix3):: +template +INLINE NumType &LMatrix3:: operator () (int row, int col) { nassertr(row >= 0 && row < 3, _data[0]); nassertr(col >= 0 && col < 3, _data[0]); @@ -369,8 +234,8 @@ operator () (int row, int col) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LMatrix3):: +template +INLINE NumType LMatrix3:: operator () (int row, int col) const { nassertr(row >= 0 && row < 3, 0.0); nassertr(col >= 0 && col < 3, 0.0); @@ -383,8 +248,8 @@ operator () (int row, int col) const { // Description: Returns true if any component of the matrix is // not-a-number, false otherwise. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LMatrix3):: +template +INLINE bool LMatrix3:: is_nan() const { return cnan(_data[0]) || cnan(_data[1]) || cnan(_data[2]) || @@ -397,8 +262,8 @@ is_nan() const { // Access: Public // Description: Returns a particular element of the matrix. //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LMatrix3):: +template +INLINE NumType LMatrix3:: get_cell(int row, int col) const { nassertr(row >= 0 && row < 3, 0.0); nassertr(col >= 0 && col < 3, 0.0); @@ -410,9 +275,9 @@ get_cell(int row, int col) const { // Access: Public // Description: Changes a particular element of the matrix. //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix3):: -set_cell(int row, int col, FLOATTYPE1 value) { +template +INLINE void LMatrix3:: +set_cell(int row, int col, NumType value) { nassertv(row >= 0 && row < 3); nassertv(col >= 0 && col < 3); _data[row * 3 + col] = value; @@ -425,8 +290,8 @@ set_cell(int row, int col, FLOATTYPE1 value) { // elements in the matrix. The remaining elements // occupy the next eight positions in row-major order. //////////////////////////////////////////////////////////////////// - -INLINE const FLOATTYPE1 *FLOATNAME(LMatrix3):: +template +INLINE const NumType *LMatrix3:: get_data() const { return _data; } @@ -436,8 +301,8 @@ get_data() const { // Access: Public // Description: Returns the number of elements in the matrix, nine. //////////////////////////////////////////////////////////////////// - -INLINE int FLOATNAME(LMatrix3):: +template +INLINE int LMatrix3:: get_num_components() const { return 9; } @@ -448,8 +313,8 @@ get_num_components() const { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3)::iterator FLOATNAME(LMatrix3):: +template +INLINE LMatrix3::iterator LMatrix3:: begin() { return _data; } @@ -460,8 +325,8 @@ begin() { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3)::iterator FLOATNAME(LMatrix3):: +template +INLINE LMatrix3::iterator LMatrix3:: end() { return begin() + get_num_components(); } @@ -472,8 +337,8 @@ end() { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3)::const_iterator FLOATNAME(LMatrix3):: +template +INLINE LMatrix3::const_iterator LMatrix3:: begin() const { return _data; } @@ -484,20 +349,39 @@ begin() const { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3)::const_iterator FLOATNAME(LMatrix3):: +template +INLINE LMatrix3::const_iterator LMatrix3:: end() const { return begin() + get_num_components(); } +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::Equality Operator +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +bool LMatrix3:: +operator == (const LMatrix3 &other) const { + return ((*this)(0, 0) == other(0, 0) && + (*this)(0, 1) == other(0, 1) && + (*this)(0, 2) == other(0, 2) && + (*this)(1, 0) == other(1, 0) && + (*this)(1, 1) == other(1, 1) && + (*this)(1, 2) == other(1, 2) && + (*this)(2, 0) == other(2, 0) && + (*this)(2, 1) == other(2, 1) && + (*this)(2, 2) == other(2, 2)); +} + //////////////////////////////////////////////////////////////////// // Function: LMatrix3::Inequality Operator // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LMatrix3):: -operator != (const FLOATNAME(LMatrix3) &other) const { +template +INLINE bool LMatrix3:: +operator != (const LMatrix3 &other) const { return !operator == (other); } @@ -507,10 +391,30 @@ operator != (const FLOATNAME(LMatrix3) &other) const { // Description: This flavor of compare_to uses a default threshold // value based on the numeric type. //////////////////////////////////////////////////////////////////// +template +INLINE int LMatrix3:: +compare_to(const LMatrix3 &other) const { + return compare_to(other, NEARLY_ZERO(NumType)); +} -INLINE int FLOATNAME(LMatrix3):: -compare_to(const FLOATNAME(LMatrix3) &other) const { - return compare_to(other, NEARLY_ZERO(FLOATTYPE1)); +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::compare_to +// Access: Public +// Description: Sorts matrices lexicographically, componentwise. +// Returns a number less than 0 if this matrix sorts +// before the other one, greater than zero if it sorts +// after, 0 if they are equivalent (within the indicated +// tolerance). +//////////////////////////////////////////////////////////////////// +template +int LMatrix3:: +compare_to(const LMatrix3 &other, NumType threshold) const { + for (int i = 0; i < 9; i++) { + if (!IS_THRESHOLD_EQUAL(_data[i], other._data[i], threshold)) { + return (_data[i] < other._data[i]) ? -1 : 1; + } + } + return 0; } //////////////////////////////////////////////////////////////////// @@ -519,10 +423,10 @@ compare_to(const FLOATNAME(LMatrix3) &other) const { // Description: 3-component vector or point times matrix. This is a // fully general operation. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LMatrix3):: -xform(const FLOATNAME(LVecBase3) &v) const { - return FLOATNAME(LVecBase3)(v.dot(get_col(0)), +template +INLINE LVecBase3 LMatrix3:: +xform(const LVecBase3 &v) const { + return LVecBase3(v.dot(get_col(0)), v.dot(get_col(1)), v.dot(get_col(2))); } @@ -534,10 +438,10 @@ xform(const FLOATNAME(LVecBase3) &v) const { // translation component) and returns the result. This // assumes the matrix is an affine transform. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LMatrix3):: -xform_point(const FLOATNAME(LVecBase2) &v) const { - return FLOATNAME(LVecBase2)(v.dot(get_col2(0)) + (*this)(2, 0), +template +INLINE LVecBase2 LMatrix3:: +xform_point(const LVecBase2 &v) const { + return LVecBase2(v.dot(get_col2(0)) + (*this)(2, 0), v.dot(get_col2(1)) + (*this)(2, 1)); } @@ -548,10 +452,10 @@ xform_point(const FLOATNAME(LVecBase2) &v) const { // translation component) and returns the result. This // assumes the matrix is an affine transform. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LMatrix3):: -xform_vec(const FLOATNAME(LVecBase2) &v) const { - return FLOATNAME(LVecBase2)(v.dot(get_col2(0)), +template +INLINE LVecBase2 LMatrix3:: +xform_vec(const LVecBase2 &v) const { + return LVecBase2(v.dot(get_col2(0)), v.dot(get_col2(1))); } @@ -561,20 +465,141 @@ xform_vec(const FLOATNAME(LVecBase2) &v) const { // Description: Returns one cell of the result of a matrix-matrix // multiplication operation. //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LMatrix3):: -mult_cel(const FLOATNAME(LMatrix3) &other, int row, int col) const { +template +INLINE NumType LMatrix3:: +mult_cel(const LMatrix3 &other, int row, int col) const { return get_row(row).dot(other.get_col(col)); } +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::matrix * matrix +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +LMatrix3 LMatrix3:: +operator * (const LMatrix3 &other) const { + LMatrix3 t; + + t(0, 0) = mult_cel(other, 0, 0); + t(0, 1) = mult_cel(other, 0, 1); + t(0, 2) = mult_cel(other, 0, 2); + + t(1, 0) = mult_cel(other, 1, 0); + t(1, 1) = mult_cel(other, 1, 1); + t(1, 2) = mult_cel(other, 1, 2); + + t(2, 0) = mult_cel(other, 2, 0); + t(2, 1) = mult_cel(other, 2, 1); + t(2, 2) = mult_cel(other, 2, 2); + + return t; +} + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::matrix * scalar +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +LMatrix3 LMatrix3:: +operator * (NumType scalar) const { + LMatrix3 t; + + t(0, 0) = (*this)(0, 0) * scalar; + t(0, 1) = (*this)(0, 1) * scalar; + t(0, 2) = (*this)(0, 2) * scalar; + + t(1, 0) = (*this)(1, 0) * scalar; + t(1, 1) = (*this)(1, 1) * scalar; + t(1, 2) = (*this)(1, 2) * scalar; + + t(2, 0) = (*this)(2, 0) * scalar; + t(2, 1) = (*this)(2, 1) * scalar; + t(2, 2) = (*this)(2, 2) * scalar; + + return t; +} + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::matrix / scalar +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +LMatrix3 LMatrix3:: +operator / (NumType scalar) const { + LMatrix3 t; + + t(0, 0) = (*this)(0, 0) / scalar; + t(0, 1) = (*this)(0, 1) / scalar; + t(0, 2) = (*this)(0, 2) / scalar; + + t(1, 0) = (*this)(1, 0) / scalar; + t(1, 1) = (*this)(1, 1) / scalar; + t(1, 2) = (*this)(1, 2) / scalar; + + t(2, 0) = (*this)(2, 0) / scalar; + t(2, 1) = (*this)(2, 1) / scalar; + t(2, 2) = (*this)(2, 2) / scalar; + + return t; +} + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::matrix += matrix +// Access: Public +// Description: Performs a memberwise addition between two matrices. +//////////////////////////////////////////////////////////////////// +template +LMatrix3 &LMatrix3:: +operator += (const LMatrix3 &other) { + (*this)(0, 0) += other(0, 0); + (*this)(0, 1) += other(0, 1); + (*this)(0, 2) += other(0, 2); + + (*this)(1, 0) += other(1, 0); + (*this)(1, 1) += other(1, 1); + (*this)(1, 2) += other(1, 2); + + (*this)(2, 0) += other(2, 0); + (*this)(2, 1) += other(2, 1); + (*this)(2, 2) += other(2, 2); + + return *this; +} + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::matrix -= matrix +// Access: Public +// Description: Performs a memberwise subtraction between two matrices. +//////////////////////////////////////////////////////////////////// +template +LMatrix3 &LMatrix3:: +operator -= (const LMatrix3 &other) { + (*this)(0, 0) -= other(0, 0); + (*this)(0, 1) -= other(0, 1); + (*this)(0, 2) -= other(0, 2); + + (*this)(1, 0) -= other(1, 0); + (*this)(1, 1) -= other(1, 1); + (*this)(1, 2) -= other(1, 2); + + (*this)(2, 0) -= other(2, 0); + (*this)(2, 1) -= other(2, 1); + (*this)(2, 2) -= other(2, 2); + + return *this; +} + //////////////////////////////////////////////////////////////////// // Function: LMatrix3::matrix *= matrix // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) &FLOATNAME(LMatrix3):: -operator *= (const FLOATNAME(LMatrix3) &other) { +template +INLINE LMatrix3 &LMatrix3:: +operator *= (const LMatrix3 &other) { (*this) = (*this) * other; return *this; } @@ -584,9 +609,9 @@ operator *= (const FLOATNAME(LMatrix3) &other) { // Access: Public // Description: Performs a memberwise scale. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) &FLOATNAME(LMatrix3):: -operator *= (FLOATTYPE1 scalar) { +template +LMatrix3 &LMatrix3:: +operator *= (NumType scalar) { (*this)(0, 0) *= scalar; (*this)(0, 1) *= scalar; (*this)(0, 2) *= scalar; @@ -607,9 +632,9 @@ operator *= (FLOATTYPE1 scalar) { // Access: Public // Description: Performs a memberwise scale. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) &FLOATNAME(LMatrix3):: -operator /= (FLOATTYPE1 scalar) { +template +LMatrix3 &LMatrix3:: +operator /= (NumType scalar) { (*this)(0, 0) /= scalar; (*this)(0, 1) /= scalar; (*this)(0, 2) /= scalar; @@ -630,9 +655,9 @@ operator /= (FLOATTYPE1 scalar) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix3):: -transpose_from(const FLOATNAME(LMatrix3) &other) { +template +void LMatrix3:: +transpose_from(const LMatrix3 &other) { (*this)(0, 0) = other(0, 0); (*this)(0, 1) = other(1, 0); (*this)(0, 2) = other(2, 0); @@ -652,10 +677,10 @@ transpose_from(const FLOATNAME(LMatrix3) &other) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix3):: +template +INLINE void LMatrix3:: transpose_in_place() { - FLOATNAME(LMatrix3) temp = (*this); + LMatrix3 temp = (*this); transpose_from(temp); } @@ -666,9 +691,9 @@ transpose_in_place() { // Access: Private, Static // Description: Returns the determinant of a 2x2 matrix. //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LMatrix3):: -det2(FLOATTYPE1 e00, FLOATTYPE1 e01, FLOATTYPE1 e10, FLOATTYPE1 e11) const { +template +INLINE NumType LMatrix3:: +det2(NumType e00, NumType e01, NumType e10, NumType e11) const { return (e00 * e11 - e10 * e01); } @@ -677,8 +702,8 @@ det2(FLOATTYPE1 e00, FLOATTYPE1 e01, FLOATTYPE1 e10, FLOATTYPE1 e11) const { // Access: Public // Description: Returns the determinant of the matrix. //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LMatrix3):: +template +INLINE NumType LMatrix3:: determinant() const { return (*this)(0,0) * det2((*this)(1,1),(*this)(1,2),(*this)(2,1),(*this)(2,2)) @@ -702,10 +727,10 @@ determinant() const { // successfully inverted, false if the was a // singularity. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LMatrix3):: -invert_from(const FLOATNAME(LMatrix3) &other) { - FLOATTYPE1 d = other.determinant(); +template +bool LMatrix3:: +invert_from(const LMatrix3 &other) { + NumType d = other.determinant(); if (IS_NEARLY_ZERO(d)) { linmath_cat.warning() @@ -737,23 +762,38 @@ invert_from(const FLOATNAME(LMatrix3) &other) { // inverse is successful, false if the matrix was // singular. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LMatrix3):: +template +INLINE bool LMatrix3:: invert_in_place() { - FLOATNAME(LMatrix3) temp = (*this); + LMatrix3 temp = (*this); return invert_from(temp); } +//////////////////////////////////////////////////////////////////// +// Function: LMatrix::ident_mat +// Access: Public, Static +// Description: Returns an identity matrix. +//////////////////////////////////////////////////////////////////// +template +const LMatrix3 &LMatrix3:: +ident_mat() { + static LMatrix3 mat(1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0); + return mat; +} + + //////////////////////////////////////////////////////////////////// // Function: LMatrix::translate_mat // Access: Public, Static // Description: Returns a matrix that applies the indicated // translation. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) FLOATNAME(LMatrix3):: -translate_mat(const FLOATNAME(LVecBase2) &trans) { - return FLOATNAME(LMatrix3)(1.0, 0.0, 0.0, +template +LMatrix3 LMatrix3:: +translate_mat(const LVecBase2 &trans) { + return LMatrix3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, trans[0], trans[1], 1.0); } @@ -764,41 +804,43 @@ translate_mat(const FLOATNAME(LVecBase2) &trans) { // Description: Returns a matrix that applies the indicated // translation. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) FLOATNAME(LMatrix3):: -translate_mat(FLOATTYPE1 tx, FLOATTYPE1 ty) { - return FLOATNAME(LMatrix3)(1.0, 0.0, 0.0, +template +LMatrix3 LMatrix3:: +translate_mat(NumType tx, NumType ty) { + return LMatrix3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, tx, ty, 1.0); } + //////////////////////////////////////////////////////////////////// // Function: LMatrix::rotate_mat // Access: Public, Static // Description: Returns a matrix that rotates by the given angle in // degrees counterclockwise. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) FLOATNAME(LMatrix3):: -rotate_mat(FLOATTYPE1 angle) { +template +LMatrix3 LMatrix3:: +rotate_mat(NumType angle) { double angle_rad=deg_2_rad(angle); double s,c; csincos(angle_rad,&s,&c); - return FLOATNAME(LMatrix3)( c, s, 0.0, + return LMatrix3( c, s, 0.0, -s, c, 0.0, 0.0, 0.0, 1.0); } + //////////////////////////////////////////////////////////////////// // Function: LMatrix::scale_mat // Access: Public, Static // Description: Returns a matrix that applies the indicated // scale in each of the two axes. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) FLOATNAME(LMatrix3):: -scale_mat(const FLOATNAME(LVecBase2) &scale) { - return FLOATNAME(LMatrix3)(scale[0], 0.0, 0.0, +template +LMatrix3 LMatrix3:: +scale_mat(const LVecBase2 &scale) { + return LMatrix3(scale[0], 0.0, 0.0, 0.0, scale[1], 0.0, 0.0, 0.0, 1.0); } @@ -809,28 +851,29 @@ scale_mat(const FLOATNAME(LVecBase2) &scale) { // Description: Returns a matrix that applies the indicated // scale in each of the two axes. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) FLOATNAME(LMatrix3):: -scale_mat(FLOATTYPE1 sx, FLOATTYPE1 sy) { - return FLOATNAME(LMatrix3)(sx, 0.0, 0.0, +template +LMatrix3 LMatrix3:: +scale_mat(NumType sx, NumType sy) { + return LMatrix3(sx, 0.0, 0.0, 0.0, sy, 0.0, 0.0, 0.0, 1.0); } + //////////////////////////////////////////////////////////////////// // Function: LMatrix::rotate_mat // Access: Public, Static // Description: Returns a matrix that rotates by the given angle in // degrees counterclockwise about the indicated vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) FLOATNAME(LMatrix3):: -rotate_mat(FLOATTYPE1 angle, FLOATNAME(LVecBase3) axis, +template +LMatrix3 LMatrix3:: +rotate_mat(NumType angle, LVecBase3 axis, CoordinateSystem cs) { if (cs == CS_default) { cs = default_coordinate_system; } - FLOATNAME(LMatrix3) mat; + LMatrix3 mat; if (!is_right_handed(cs)) { // In a left-handed coordinate system, counterclockwise is the @@ -839,9 +882,9 @@ rotate_mat(FLOATTYPE1 angle, FLOATNAME(LVecBase3) axis, } // Normalize the axis. - FLOATTYPE1 length = axis.dot(axis); + NumType length = axis.dot(axis); nassertr(length != 0.0, ident_mat()); - FLOATTYPE1 recip_length=1.0f/length; + NumType recip_length=1.0f/length; axis *= recip_length; double angle_rad=deg_2_rad(angle); @@ -864,16 +907,17 @@ rotate_mat(FLOATTYPE1 angle, FLOATNAME(LVecBase3) axis, return mat; } + //////////////////////////////////////////////////////////////////// // Function: LMatrix::scale_mat // Access: Public, Static // Description: Returns a matrix that applies the indicated // scale in each of the three axes. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) FLOATNAME(LMatrix3):: -scale_mat(const FLOATNAME(LVecBase3) &scale) { - return FLOATNAME(LMatrix3)(scale[0], 0.0, 0.0, +template +LMatrix3 LMatrix3:: +scale_mat(const LVecBase3 &scale) { + return LMatrix3(scale[0], 0.0, 0.0, 0.0, scale[1], 0.0, 0.0, 0.0, scale[2]); } @@ -884,24 +928,44 @@ scale_mat(const FLOATNAME(LVecBase3) &scale) { // Description: Returns a matrix that applies the indicated // scale in each of the three axes. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) FLOATNAME(LMatrix3):: -scale_mat(FLOATTYPE1 sx, FLOATTYPE1 sy, FLOATTYPE1 sz) { - return FLOATNAME(LMatrix3)(sx, 0.0, 0.0, +template +LMatrix3 LMatrix3:: +scale_mat(NumType sx, NumType sy, NumType sz) { + return LMatrix3(sx, 0.0, 0.0, 0.0, sy, 0.0, 0.0, 0.0, sz); } +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::almost_equal +// Access: Public +// Description: Returns true if two matrices are memberwise equal +// within a specified tolerance. +//////////////////////////////////////////////////////////////////// +template +bool LMatrix3:: +almost_equal(const LMatrix3 &other, NumType threshold) const { + return (IS_THRESHOLD_EQUAL((*this)(0, 0), other(0, 0), threshold) && + IS_THRESHOLD_EQUAL((*this)(0, 1), other(0, 1), threshold) && + IS_THRESHOLD_EQUAL((*this)(0, 2), other(0, 2), threshold) && + IS_THRESHOLD_EQUAL((*this)(1, 0), other(1, 0), threshold) && + IS_THRESHOLD_EQUAL((*this)(1, 1), other(1, 1), threshold) && + IS_THRESHOLD_EQUAL((*this)(1, 2), other(1, 2), threshold) && + IS_THRESHOLD_EQUAL((*this)(2, 0), other(2, 0), threshold) && + IS_THRESHOLD_EQUAL((*this)(2, 1), other(2, 1), threshold) && + IS_THRESHOLD_EQUAL((*this)(2, 2), other(2, 2), threshold)); +} + //////////////////////////////////////////////////////////////////// // Function: LMatrix3::almost_equal // Access: Public // Description: Returns true if two matrices are memberwise equal // within a default tolerance based on the numeric type. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LMatrix3):: -almost_equal(const FLOATNAME(LMatrix3) &other) const { - return almost_equal(other, NEARLY_ZERO(FLOATTYPE1)); +template +INLINE bool LMatrix3:: +almost_equal(const LMatrix3 &other) const { + return almost_equal(other, NEARLY_ZERO(NumType)); } //////////////////////////////////////////////////////////////////// @@ -909,8 +973,8 @@ almost_equal(const FLOATNAME(LMatrix3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix3):: +template +INLINE void LMatrix3:: output(ostream &out) const { out << "[ " << MAYBE_ZERO((*this)(0, 0)) << " " @@ -927,38 +991,13 @@ output(ostream &out) const { << " ]"; } -//////////////////////////////////////////////////////////////////// -// Function: LMatrix3::transpose -// Description: Transposes the given matrix and returns it. -//////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) -transpose(const FLOATNAME(LMatrix3) &a) { - FLOATNAME(LMatrix3) result; - result.transpose_from(a); - return result; -} - -//////////////////////////////////////////////////////////////////// -// Function: LMatrix3::invert -// Description: Inverts the given matrix and returns it. -//////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) -invert(const FLOATNAME(LMatrix3) &a) { - FLOATNAME(LMatrix3) result; - bool nonsingular = result.invert_from(a); - nassertr(nonsingular, FLOATNAME(LMatrix3)::ident_mat()); - return result; -} - //////////////////////////////////////////////////////////////////// // Function: LMatrix3::write // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix3):: +template +INLINE void LMatrix3:: write(ostream &out, int indent_level) const { indent(out, indent_level) << MAYBE_ZERO((*this)(0, 0)) << " " @@ -977,140 +1016,95 @@ write(ostream &out, int indent_level) const { << "\n"; } - //////////////////////////////////////////////////////////////////// -// Function: LMatrix3::matrix * matrix -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) FLOATNAME(LMatrix3):: -operator * (const FLOATNAME(LMatrix3) &other) const { - FLOATNAME(LMatrix3) t; - - t(0, 0) = mult_cel(other, 0, 0); - t(0, 1) = mult_cel(other, 0, 1); - t(0, 2) = mult_cel(other, 0, 2); - - t(1, 0) = mult_cel(other, 1, 0); - t(1, 1) = mult_cel(other, 1, 1); - t(1, 2) = mult_cel(other, 1, 2); - - t(2, 0) = mult_cel(other, 2, 0); - t(2, 1) = mult_cel(other, 2, 1); - t(2, 2) = mult_cel(other, 2, 2); - - return t; -} - -//////////////////////////////////////////////////////////////////// -// Function: LMatrix3::matrix * scalar -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) FLOATNAME(LMatrix3):: -operator * (FLOATTYPE1 scalar) const { - FLOATNAME(LMatrix3) t; - - t(0, 0) = (*this)(0, 0) * scalar; - t(0, 1) = (*this)(0, 1) * scalar; - t(0, 2) = (*this)(0, 2) * scalar; - - t(1, 0) = (*this)(1, 0) * scalar; - t(1, 1) = (*this)(1, 1) * scalar; - t(1, 2) = (*this)(1, 2) * scalar; - - t(2, 0) = (*this)(2, 0) * scalar; - t(2, 1) = (*this)(2, 1) * scalar; - t(2, 2) = (*this)(2, 2) * scalar; - - return t; -} - -//////////////////////////////////////////////////////////////////// -// Function: LMatrix3::matrix / scalar -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) FLOATNAME(LMatrix3):: -operator / (FLOATTYPE1 scalar) const { - FLOATNAME(LMatrix3) t; - - t(0, 0) = (*this)(0, 0) / scalar; - t(0, 1) = (*this)(0, 1) / scalar; - t(0, 2) = (*this)(0, 2) / scalar; - - t(1, 0) = (*this)(1, 0) / scalar; - t(1, 1) = (*this)(1, 1) / scalar; - t(1, 2) = (*this)(1, 2) / scalar; - - t(2, 0) = (*this)(2, 0) / scalar; - t(2, 1) = (*this)(2, 1) / scalar; - t(2, 2) = (*this)(2, 2) / scalar; - - return t; -} - -//////////////////////////////////////////////////////////////////// -// Function: LMatrix3::matrix += matrix -// Access: Public -// Description: Performs a memberwise addition between two matrices. -//////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) &FLOATNAME(LMatrix3):: -operator += (const FLOATNAME(LMatrix3) &other) { - (*this)(0, 0) += other(0, 0); - (*this)(0, 1) += other(0, 1); - (*this)(0, 2) += other(0, 2); - - (*this)(1, 0) += other(1, 0); - (*this)(1, 1) += other(1, 1); - (*this)(1, 2) += other(1, 2); - - (*this)(2, 0) += other(2, 0); - (*this)(2, 1) += other(2, 1); - (*this)(2, 2) += other(2, 2); - - return *this; -} - -//////////////////////////////////////////////////////////////////// -// Function: LMatrix3::matrix -= matrix -// Access: Public -// Description: Performs a memberwise subtraction between two matrices. -//////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) &FLOATNAME(LMatrix3):: -operator -= (const FLOATNAME(LMatrix3) &other) { - (*this)(0, 0) -= other(0, 0); - (*this)(0, 1) -= other(0, 1); - (*this)(0, 2) -= other(0, 2); - - (*this)(1, 0) -= other(1, 0); - (*this)(1, 1) -= other(1, 1); - (*this)(1, 2) -= other(1, 2); - - (*this)(2, 0) -= other(2, 0); - (*this)(2, 1) -= other(2, 1); - (*this)(2, 2) -= other(2, 2); - - return *this; -} - -//////////////////////////////////////////////////////////////////// -// Function: LMatrix::ident_mat +// Function: LMatrix3::init_type // Access: Public, Static -// Description: Returns an identity matrix. +// Description: //////////////////////////////////////////////////////////////////// - -INLINE const FLOATNAME(LMatrix3) &FLOATNAME(LMatrix3):: -ident_mat() { - static FLOATNAME(LMatrix3) mat(1.0, 0.0, 0.0, - 0.0, 1.0, 0.0, - 0.0, 0.0, 1.0); - return mat; +template +void LMatrix3:: +init_type() { + if (_type_handle == TypeHandle::none()) { + // Format a string to describe the type. + do_init_type(NumType); + string name = + "LMatrix3<" + get_type_handle(NumType).get_name() + ">"; + register_type(_type_handle, name); + } } +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::write_datagram +// Description: Writes the matrix to the datagram +//////////////////////////////////////////////////////////////////// +template +void LMatrix3:: +write_datagram(Datagram &destination) const +{ + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + destination.add_float32(get_cell(i,j)); + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::read_datagram +// Description: Reads itself out of the datagram +//////////////////////////////////////////////////////////////////// +template +void LMatrix3:: +read_datagram(DatagramIterator &scan) +{ + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + set_cell(i, j, scan.get_float32()); + } + } +} + + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::transpose +// Description: Transposes the given matrix and returns it. +//////////////////////////////////////////////////////////////////// +template +INLINE LMatrix3 +transpose(const LMatrix3 &a) { + LMatrix3 result; + result.transpose_from(a); + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix3::invert +// Description: Inverts the given matrix and returns it. +//////////////////////////////////////////////////////////////////// +template +INLINE LMatrix3 +invert(const LMatrix3 &a) { + LMatrix3 result; + bool nonsingular = result.invert_from(a); + nassertr(nonsingular, LMatrix3::ident_mat()); + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: lcast_to +// Description: Converts a matrix from one numeric representation to +// another one. This is usually invoked using the macro +// LCAST. +//////////////////////////////////////////////////////////////////// +template +INLINE LMatrix3 +lcast_to(NumType2 *, const LMatrix3 &source) { + return LMatrix3 + (source(0, 0), source(0, 1), source(0, 2), + source(1, 0), source(1, 1), source(1, 2), + source(2, 0), source(2, 1), source(2, 2)); +} diff --git a/panda/src/linmath/lmatrix3.h b/panda/src/linmath/lmatrix3.h index 075693d96a..75cb1324a5 100644 --- a/panda/src/linmath/lmatrix3.h +++ b/panda/src/linmath/lmatrix3.h @@ -7,50 +7,188 @@ #define LMATRIX3_H #include -#include -#include -#include -#include -#include -#include -#include "deg_2_rad.h" -#include "nearly_zero.h" + #include "coordinateSystem.h" #include "lvecBase3.h" #include "lvecBase2.h" -#include "fltnames.I" -#include "lmatrix3.I" - -#include "dblnames.I" -#include "lmatrix3.I" +#include +#include +#include //////////////////////////////////////////////////////////////////// -// Function: lcast_to -// Description: Converts a matrix from one numeric representation to -// another one. This is usually invoked using the macro -// LCAST. +// Class : LMatrix3 +// Description : This is a 3-by-3 transform matrix. It typically will +// represent either a rotation-and-scale (no +// translation) matrix in 3-d, or a full affine matrix +// (rotation, scale, translation) in 2-d, e.g. for a +// texture matrix. //////////////////////////////////////////////////////////////////// -INLINE FLOATNAME2(LMatrix3) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LMatrix3) &source) { - return FLOATNAME2(LMatrix3) - (source(0, 0), source(0, 1), source(0, 2), - source(1, 0), source(1, 1), source(1, 2), - source(2, 0), source(2, 1), source(2, 2)); -} - -#include "fltnames.I" -INLINE FLOATNAME2(LMatrix3) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LMatrix3) &source) { - return FLOATNAME2(LMatrix3) - (source(0, 0), source(0, 1), source(0, 2), - source(1, 0), source(1, 1), source(1, 2), - source(2, 0), source(2, 1), source(2, 2)); +template +class LMatrix3 { +PUBLISHED: + typedef const NumType *iterator; + typedef const NumType *const_iterator; + + INLINE LMatrix3(); + INLINE LMatrix3(const LMatrix3 &other); + LMatrix3 &operator = (const LMatrix3 &other); + INLINE LMatrix3 &operator = (NumType fill_value); + INLINE LMatrix3(NumType e00, NumType e01, NumType e02, + NumType e10, NumType e11, NumType e12, + NumType e20, NumType e21, NumType e22); + + void fill(NumType fill_value); + INLINE void set(NumType e00, NumType e01, NumType e02, + NumType e10, NumType e11, NumType e12, + NumType e20, NumType e21, NumType e22); + + INLINE void set_row(int row, const LVecBase3 &v); + INLINE void set_col(int col, const LVecBase3 &v); + + INLINE void set_row(int row, const LVecBase2 &v); + INLINE void set_col(int col, const LVecBase2 &v); + + INLINE LVecBase3 get_row(int row) const; + INLINE LVecBase3 get_col(int col) const; + + INLINE LVecBase2 get_row2(int row) const; + INLINE LVecBase2 get_col2(int col) const; + + INLINE NumType &operator () (int row, int col); + INLINE NumType operator () (int row, int col) const; + + INLINE bool is_nan() const; + + INLINE NumType get_cell(int row, int col) const; + INLINE void set_cell(int row, int col, NumType value); + + INLINE const NumType *get_data() const; + INLINE int get_num_components() const; + +public: + INLINE iterator begin(); + INLINE iterator end(); + + INLINE const_iterator begin() const; + INLINE const_iterator end() const; + +PUBLISHED: + bool operator == (const LMatrix3 &other) const; + INLINE bool operator != (const LMatrix3 &other) const; + + INLINE int compare_to(const LMatrix3 &other) const; + int compare_to(const LMatrix3 &other, NumType threshold) const; + + INLINE LVecBase3 + xform(const LVecBase3 &v) const; + + INLINE LVecBase2 + xform_point(const LVecBase2 &v) const; + + INLINE LVecBase2 + xform_vec(const LVecBase2 &v) const; + + LMatrix3 operator * (const LMatrix3 &other) const; + LMatrix3 operator * (NumType scalar) const; + LMatrix3 operator / (NumType scalar) const; + + LMatrix3 &operator += (const LMatrix3 &other); + LMatrix3 &operator -= (const LMatrix3 &other); + + INLINE LMatrix3 &operator *= (const LMatrix3 &other); + + LMatrix3 &operator *= (NumType scalar); + LMatrix3 &operator /= (NumType scalar); + + INLINE NumType determinant() const; + + void transpose_from(const LMatrix3 &other); + INLINE void transpose_in_place(); + + bool invert_from(const LMatrix3 &other); + INLINE bool invert_in_place(); + + static const LMatrix3 &ident_mat(); + + // A 3x3 matrix is likely to be used for one of two purposes. In + // 2-d coordinate space (e.g. texture or surface coordinates), it + // can contain a full affine transform, with scale, rotate, + // translate. In 3-d coordinate space, it can contain only scale + // and/or rotate; e.g., the upper 3x3 rectangle of a full 4x4 + // matrix. + + // The following named constructors return 3x3 matrices suitable for + // affine transforms in 2-d coordinate space. + + static LMatrix3 translate_mat(const LVecBase2 &trans); + static LMatrix3 translate_mat(NumType tx, NumType ty); + static LMatrix3 rotate_mat(NumType angle); + static LMatrix3 scale_mat(const LVecBase2 &scale); + static LMatrix3 scale_mat(NumType sx, NumType sy); + + // The following named constructors return 3x3 matrices suitable for + // scale/rotate transforms in 3-d coordinate space. + static LMatrix3 rotate_mat(NumType angle, + LVecBase3 axis, + CoordinateSystem cs = CS_default); + static LMatrix3 scale_mat(const LVecBase3 &scale); + static LMatrix3 scale_mat(NumType sx, NumType sy, NumType sz); + + // We don't have a scale_mat() that takes a single uniform scale + // parameter, because it would be ambiguous whether we mean a 2-d or + // a 3-d scale. + + + bool almost_equal(const LMatrix3 &other, + NumType threshold) const; + + INLINE bool almost_equal(const LMatrix3 &other) const; + + INLINE void output(ostream &out) const; + INLINE void write(ostream &out, int indent_level = 0) const; + +private: + INLINE NumType mult_cel(const LMatrix3 &other, int x, int y) const; + INLINE NumType det2(NumType e00, NumType e01, NumType e10, NumType e11) const; + + NumType _data[3 * 3]; + + //Functionality for reading and writing from/to a binary source +public: + void write_datagram(Datagram& destination) const; + void read_datagram(DatagramIterator& scan); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type(); + +private: + static TypeHandle _type_handle; +}; + +template +INLINE ostream &operator << (ostream &out, const LMatrix3 &mat) { + mat.output(out); + return out; } +template +INLINE LMatrix3 transpose(const LMatrix3 &a); +template +INLINE LMatrix3 invert(const LMatrix3 &a); +// Cast to a different numeric type +template +INLINE LMatrix3 +lcast_to(NumType2 *type, const LMatrix3 &source); +#include "lmatrix3.I" +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LMatrix3) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LMatrix3) #endif diff --git a/panda/src/linmath/lmatrix4.I b/panda/src/linmath/lmatrix4.I index 61d9393ddf..282c5bd80b 100644 --- a/panda/src/linmath/lmatrix4.I +++ b/panda/src/linmath/lmatrix4.I @@ -1,171 +1,29 @@ -// Filename: lmatrix4.I +// Filename: lmatrix.I // Created by: drose (15Jan99) // //////////////////////////////////////////////////////////////////// +#include +#include "deg_2_rad.h" +#include "nearly_zero.h" +#include "config_linmath.h" +#include -//////////////////////////////////////////////////////////////////// -// Class : LMatrix4 -// Description : This is a 4-by-4 transform matrix. -//////////////////////////////////////////////////////////////////// +#include -class EXPCL_PANDA FLOATNAME(LMatrix4) { -PUBLISHED: - typedef const FLOATTYPE1 *iterator; - typedef const FLOATTYPE1 *const_iterator; - - INLINE FLOATNAME(LMatrix4)(); - INLINE FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix4) &other); - INLINE FLOATNAME(LMatrix4) &operator = (const FLOATNAME(LMatrix4) &other); - INLINE FLOATNAME(LMatrix4) &operator = (FLOATTYPE1 fill_value); - - INLINE FLOATNAME(LMatrix4)(FLOATTYPE1 e00, FLOATTYPE1 e01, FLOATTYPE1 e02, FLOATTYPE1 e03, - FLOATTYPE1 e10, FLOATTYPE1 e11, FLOATTYPE1 e12, FLOATTYPE1 e13, - FLOATTYPE1 e20, FLOATTYPE1 e21, FLOATTYPE1 e22, FLOATTYPE1 e23, - FLOATTYPE1 e30, FLOATTYPE1 e31, FLOATTYPE1 e32, FLOATTYPE1 e33); - - // Construct a 4x4 matrix given a 3x3 rotation matrix and an optional - // translation component. - INLINE FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix3) &upper3); - INLINE FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix3) &upper3,const FLOATNAME(LVecBase3) &trans); - - INLINE void fill(FLOATTYPE1 fill_value); - INLINE void set(FLOATTYPE1 e00, FLOATTYPE1 e01, FLOATTYPE1 e02, FLOATTYPE1 e03, - FLOATTYPE1 e10, FLOATTYPE1 e11, FLOATTYPE1 e12, FLOATTYPE1 e13, - FLOATTYPE1 e20, FLOATTYPE1 e21, FLOATTYPE1 e22, FLOATTYPE1 e23, - FLOATTYPE1 e30, FLOATTYPE1 e31, FLOATTYPE1 e32, FLOATTYPE1 e33); - - // Get and set the upper 3x3 rotation matrix. - INLINE void set_upper_3(const FLOATNAME(LMatrix3) &upper3); - INLINE FLOATNAME(LMatrix3) get_upper_3() const; - - INLINE void set_row(int row, const FLOATNAME(LVecBase4) &v); - INLINE void set_col(int col, const FLOATNAME(LVecBase4) &v); - - INLINE void set_row(int row, const FLOATNAME(LVecBase3) &v); - INLINE void set_col(int col, const FLOATNAME(LVecBase3) &v); - - INLINE FLOATNAME(LVecBase4) get_row(int row) const; - INLINE FLOATNAME(LVecBase4) get_col(int col) const; - - INLINE FLOATNAME(LVecBase3) get_row3(int row) const; - INLINE FLOATNAME(LVecBase3) get_col3(int col) const; - - INLINE FLOATTYPE1 &operator () (int row, int col); - INLINE FLOATTYPE1 operator () (int row, int col) const; - - INLINE bool is_nan() const; - - INLINE FLOATTYPE1 get_cell(int row, int col) const; - INLINE void set_cell(int row, int col, FLOATTYPE1 value); - - INLINE const FLOATTYPE1 *get_data() const; - INLINE int get_num_components() const; - - INLINE iterator begin(); - INLINE iterator end(); - - INLINE const_iterator begin() const; - INLINE const_iterator end() const; - - bool operator == (const FLOATNAME(LMatrix4) &other) const; - INLINE bool operator != (const FLOATNAME(LMatrix4) &other) const; - - INLINE int compare_to(const FLOATNAME(LMatrix4) &other) const; - int compare_to(const FLOATNAME(LMatrix4) &other, FLOATTYPE1 threshold) const; - - INLINE FLOATNAME(LVecBase4) - xform(const FLOATNAME(LVecBase4) &v) const; - - INLINE FLOATNAME(LVecBase3) - xform_point(const FLOATNAME(LVecBase3) &v) const; - - INLINE FLOATNAME(LVecBase3) - xform_vec(const FLOATNAME(LVecBase3) &v) const; - - INLINE FLOATNAME(LMatrix4) operator * (const FLOATNAME(LMatrix4) &other) const; - INLINE FLOATNAME(LMatrix4) operator * (FLOATTYPE1 scalar) const; - INLINE FLOATNAME(LMatrix4) operator / (FLOATTYPE1 scalar) const; - - INLINE FLOATNAME(LMatrix4) &operator += (const FLOATNAME(LMatrix4) &other); - INLINE FLOATNAME(LMatrix4) &operator -= (const FLOATNAME(LMatrix4) &other); - - INLINE FLOATNAME(LMatrix4) &operator *= (const FLOATNAME(LMatrix4) &other); - - INLINE FLOATNAME(LMatrix4) &operator *= (FLOATTYPE1 scalar); - INLINE FLOATNAME(LMatrix4) &operator /= (FLOATTYPE1 scalar); - - INLINE void transpose_from(const FLOATNAME(LMatrix4) &other); - INLINE void transpose_in_place(); - - INLINE bool invert_from(const FLOATNAME(LMatrix4) &other); - INLINE bool invert_affine_from(const FLOATNAME(LMatrix4) &other); - INLINE bool invert_in_place(); - - INLINE static const FLOATNAME(LMatrix4) &ident_mat(); - INLINE static FLOATNAME(LMatrix4) translate_mat(const FLOATNAME(LVecBase3) &trans); - INLINE static FLOATNAME(LMatrix4) translate_mat(FLOATTYPE1 tx, FLOATTYPE1 ty, FLOATTYPE1 tz); - INLINE static FLOATNAME(LMatrix4) rotate_mat(FLOATTYPE1 angle, - FLOATNAME(LVecBase3) axis, - CoordinateSystem cs = CS_default); - INLINE static FLOATNAME(LMatrix4) scale_mat(const FLOATNAME(LVecBase3) &scale); - INLINE static FLOATNAME(LMatrix4) scale_mat(FLOATTYPE1 sx, FLOATTYPE1 sy, FLOATTYPE1 sz); - INLINE static FLOATNAME(LMatrix4) scale_mat(FLOATTYPE1 scale); - - INLINE static const FLOATNAME(LMatrix4) &y_to_z_up_mat(); - INLINE static const FLOATNAME(LMatrix4) &z_to_y_up_mat(); - - static FLOATNAME(LMatrix4) convert_mat(CoordinateSystem from, - CoordinateSystem to); - - bool almost_equal(const FLOATNAME(LMatrix4) &other, - FLOATTYPE1 threshold) const; - INLINE bool almost_equal(const FLOATNAME(LMatrix4) &other) const; - - INLINE void output(ostream &out) const; - INLINE void write(ostream &out, int indent_level = 0) const; - -private: - INLINE FLOATTYPE1 mult_cel(const FLOATNAME(LMatrix4) &other, int x, int y) const; - bool decompose_mat(int index[4]); - bool back_sub_mat(int index[4], FLOATNAME(LMatrix4) &inv, int row) const; - - FLOATTYPE1 _data[4 * 4]; - - //Functionality for reading and writing from/to a binary source -public: - void write_datagram(Datagram& destination) const; - void read_datagram(DatagramIterator& scan); - -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type(); - -private: - static TypeHandle _type_handle; -}; - -INLINE ostream &operator << (ostream &out, const FLOATNAME(LMatrix4) &mat) { - mat.output(out); - return out; -} - -INLINE FLOATNAME(LMatrix4) transpose(const FLOATNAME(LMatrix4) &a); - -INLINE FLOATNAME(LMatrix4) invert(const FLOATNAME(LMatrix4) &a); +template +TypeHandle LMatrix4::_type_handle; //////////////////////////////////////////////////////////////////// // Function: LMatrix4::Default Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4):: -FLOATNAME(LMatrix4)() { +template +INLINE LMatrix4:: +LMatrix4() { } //////////////////////////////////////////////////////////////////// @@ -173,9 +31,9 @@ FLOATNAME(LMatrix4)() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4):: -FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix4) ©) { +template +INLINE LMatrix4:: +LMatrix4(const LMatrix4 ©) { (*this) = copy; } @@ -184,9 +42,9 @@ FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix4) ©) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4):: -operator = (const FLOATNAME(LMatrix4) ©) { +template +LMatrix4 &LMatrix4:: +operator = (const LMatrix4 ©) { set(copy(0, 0), copy(0, 1), copy(0, 2), copy(0, 3), copy(1, 0), copy(1, 1), copy(1, 2), copy(1, 3), copy(2, 0), copy(2, 1), copy(2, 2), copy(2, 3), @@ -199,9 +57,9 @@ operator = (const FLOATNAME(LMatrix4) ©) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4):: -operator = (FLOATTYPE1 fill_value) { +template +INLINE LMatrix4 &LMatrix4:: +operator = (NumType fill_value) { fill(fill_value); return *this; } @@ -211,12 +69,12 @@ operator = (FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4):: -FLOATNAME(LMatrix4)(FLOATTYPE1 e00, FLOATTYPE1 e01, FLOATTYPE1 e02, FLOATTYPE1 e03, - FLOATTYPE1 e10, FLOATTYPE1 e11, FLOATTYPE1 e12, FLOATTYPE1 e13, - FLOATTYPE1 e20, FLOATTYPE1 e21, FLOATTYPE1 e22, FLOATTYPE1 e23, - FLOATTYPE1 e30, FLOATTYPE1 e31, FLOATTYPE1 e32, FLOATTYPE1 e33) { +template +INLINE LMatrix4:: +LMatrix4(NumType e00, NumType e01, NumType e02, NumType e03, + NumType e10, NumType e11, NumType e12, NumType e13, + NumType e20, NumType e21, NumType e22, NumType e23, + NumType e30, NumType e31, NumType e32, NumType e33) { set(e00, e01, e02, e03, e10, e11, e12, e13, e20, e21, e22, e23, @@ -228,9 +86,9 @@ FLOATNAME(LMatrix4)(FLOATTYPE1 e00, FLOATTYPE1 e01, FLOATTYPE1 e02, FLOATTYPE1 e // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4):: -FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix3) &upper3) { +template +LMatrix4:: +LMatrix4(const LMatrix3 &upper3) { set(upper3(0, 0), upper3(0, 1), upper3(0, 2), 0.0, upper3(1, 0), upper3(1, 1), upper3(1, 2), 0.0, upper3(2, 0), upper3(2, 1), upper3(2, 2), 0.0, @@ -242,10 +100,10 @@ FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix3) &upper3) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4):: -FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix3) &upper3, - const FLOATNAME(LVecBase3) &trans) { +template +LMatrix4:: +LMatrix4(const LMatrix3 &upper3, + const LVecBase3 &trans) { set(upper3(0, 0), upper3(0, 1), upper3(0, 2), 0.0, upper3(1, 0), upper3(1, 1), upper3(1, 2), 0.0, upper3(2, 0), upper3(2, 1), upper3(2, 2), 0.0, @@ -259,9 +117,9 @@ FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix3) &upper3, // fill_value. This is of questionable value, but is // sometimes useful when initializing to zero. //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix4):: -fill(FLOATTYPE1 fill_value) { +template +void LMatrix4:: +fill(NumType fill_value) { set(fill_value, fill_value, fill_value, fill_value, fill_value, fill_value, fill_value, fill_value, fill_value, fill_value, fill_value, fill_value, @@ -273,12 +131,12 @@ fill(FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix4):: -set(FLOATTYPE1 e00, FLOATTYPE1 e01, FLOATTYPE1 e02, FLOATTYPE1 e03, - FLOATTYPE1 e10, FLOATTYPE1 e11, FLOATTYPE1 e12, FLOATTYPE1 e13, - FLOATTYPE1 e20, FLOATTYPE1 e21, FLOATTYPE1 e22, FLOATTYPE1 e23, - FLOATTYPE1 e30, FLOATTYPE1 e31, FLOATTYPE1 e32, FLOATTYPE1 e33) { +template +INLINE void LMatrix4:: +set(NumType e00, NumType e01, NumType e02, NumType e03, + NumType e10, NumType e11, NumType e12, NumType e13, + NumType e20, NumType e21, NumType e22, NumType e23, + NumType e30, NumType e31, NumType e32, NumType e33) { (*this)(0, 0) = e00; (*this)(0, 1) = e01; (*this)(0, 2) = e02; @@ -305,9 +163,9 @@ set(FLOATTYPE1 e00, FLOATTYPE1 e01, FLOATTYPE1 e02, FLOATTYPE1 e03, // Access: Public // Description: Sets the upper 3x3 submatrix. //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix4):: -set_upper_3(const FLOATNAME(LMatrix3) &upper3) { +template +INLINE void LMatrix4:: +set_upper_3(const LMatrix3 &upper3) { (*this)(0, 0) = upper3(0, 0); (*this)(0, 1) = upper3(0, 1); (*this)(0, 2) = upper3(0, 2); @@ -326,10 +184,10 @@ set_upper_3(const FLOATNAME(LMatrix3) &upper3) { // Access: Public // Description: Retrieves the upper 3x3 submatrix. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) FLOATNAME(LMatrix4):: +template +INLINE LMatrix3 LMatrix4:: get_upper_3() const { - return FLOATNAME(LMatrix3) + return LMatrix3 ((*this)(0, 0), (*this)(0, 1), (*this)(0, 2), (*this)(1, 0), (*this)(1, 1), (*this)(1, 2), (*this)(2, 0), (*this)(2, 1), (*this)(2, 2)); @@ -340,9 +198,9 @@ get_upper_3() const { // Access: Public // Description: Replaces the indicated row of the matrix. //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix4):: -set_row(int row, const FLOATNAME(LVecBase4) &v) { +template +INLINE void LMatrix4:: +set_row(int row, const LVecBase4 &v) { (*this)(row, 0) = v[0]; (*this)(row, 1) = v[1]; (*this)(row, 2) = v[2]; @@ -354,9 +212,9 @@ set_row(int row, const FLOATNAME(LVecBase4) &v) { // Access: Public // Description: Replaces the indicated column of the matrix. //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix4):: -set_col(int col, const FLOATNAME(LVecBase4) &v) { +template +INLINE void LMatrix4:: +set_col(int col, const LVecBase4 &v) { (*this)(0, col) = v[0]; (*this)(1, col) = v[1]; (*this)(2, col) = v[2]; @@ -370,9 +228,9 @@ set_col(int col, const FLOATNAME(LVecBase4) &v) { // indicated 3-component vector, ignoring the last // column. //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix4):: -set_row(int row, const FLOATNAME(LVecBase3) &v) { +template +INLINE void LMatrix4:: +set_row(int row, const LVecBase3 &v) { (*this)(row, 0) = v[0]; (*this)(row, 1) = v[1]; (*this)(row, 2) = v[2]; @@ -385,9 +243,9 @@ set_row(int row, const FLOATNAME(LVecBase3) &v) { // indicated 3-component vector, ignoring the last // row. //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix4):: -set_col(int col, const FLOATNAME(LVecBase3) &v) { +template +INLINE void LMatrix4:: +set_col(int col, const LVecBase3 &v) { (*this)(0, col) = v[0]; (*this)(1, col) = v[1]; (*this)(2, col) = v[2]; @@ -399,10 +257,10 @@ set_col(int col, const FLOATNAME(LVecBase3) &v) { // Description: Retrieves the indicated row of the matrix as a // 4-component vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LMatrix4):: +template +INLINE LVecBase4 LMatrix4:: get_row(int row) const { - return FLOATNAME(LVecBase4)((*this)(row, 0), + return LVecBase4((*this)(row, 0), (*this)(row, 1), (*this)(row, 2), (*this)(row, 3)); @@ -414,10 +272,10 @@ get_row(int row) const { // Description: Retrieves the indicated column of the matrix as a // 4-component vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LMatrix4):: +template +INLINE LVecBase4 LMatrix4:: get_col(int col) const { - return FLOATNAME(LVecBase4)((*this)(0, col), + return LVecBase4((*this)(0, col), (*this)(1, col), (*this)(2, col), (*this)(3, col)); @@ -429,10 +287,10 @@ get_col(int col) const { // Description: Retrieves the row column of the matrix as a // 3-component vector, ignoring the last column. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LMatrix4):: +template +INLINE LVecBase3 LMatrix4:: get_row3(int row) const { - return FLOATNAME(LVecBase3)((*this)(row, 0), + return LVecBase3((*this)(row, 0), (*this)(row, 1), (*this)(row, 2)); } @@ -443,10 +301,10 @@ get_row3(int row) const { // Description: Retrieves the indicated column of the matrix as a // 3-component vector, ignoring the last row. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LMatrix4):: +template +INLINE LVecBase3 LMatrix4:: get_col3(int col) const { - return FLOATNAME(LVecBase3)((*this)(0, col), + return LVecBase3((*this)(0, col), (*this)(1, col), (*this)(2, col)); } @@ -456,8 +314,8 @@ get_col3(int col) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 &FLOATNAME(LMatrix4):: +template +INLINE NumType &LMatrix4:: operator () (int row, int col) { nassertr(row >= 0 && row < 4, _data[0]); nassertr(col >= 0 && col < 4, _data[0]); @@ -469,8 +327,8 @@ operator () (int row, int col) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LMatrix4):: +template +INLINE NumType LMatrix4:: operator () (int row, int col) const { nassertr(row >= 0 && row < 4, 0.0); nassertr(col >= 0 && col < 4, 0.0); @@ -483,8 +341,8 @@ operator () (int row, int col) const { // Description: Returns true if any component of the matrix is // not-a-number, false otherwise. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LMatrix4):: +template +INLINE bool LMatrix4:: is_nan() const { return cnan(_data[0]) || cnan(_data[1]) || cnan(_data[2]) || cnan(_data[3]) || @@ -498,8 +356,8 @@ is_nan() const { // Access: Public // Description: Returns a particular element of the matrix. //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LMatrix4):: +template +INLINE NumType LMatrix4:: get_cell(int row, int col) const { nassertr(row >= 0 && row < 4, 0.0); nassertr(col >= 0 && col < 4, 0.0); @@ -511,9 +369,9 @@ get_cell(int row, int col) const { // Access: Public // Description: Changes a particular element of the matrix. //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix4):: -set_cell(int row, int col, FLOATTYPE1 value) { +template +INLINE void LMatrix4:: +set_cell(int row, int col, NumType value) { nassertv(row >= 0 && row < 4); nassertv(col >= 0 && col < 4); _data[row * 4 + col] = value; @@ -526,8 +384,8 @@ set_cell(int row, int col, FLOATTYPE1 value) { // elements in the matrix. The remaining elements // occupy the next eight positions in row-major order. //////////////////////////////////////////////////////////////////// - -INLINE const FLOATTYPE1 *FLOATNAME(LMatrix4):: +template +INLINE const NumType *LMatrix4:: get_data() const { return _data; } @@ -537,8 +395,8 @@ get_data() const { // Access: Public // Description: Returns the number of elements in the matrix, 16. //////////////////////////////////////////////////////////////////// - -INLINE int FLOATNAME(LMatrix4):: +template +INLINE int LMatrix4:: get_num_components() const { return 16; } @@ -549,8 +407,8 @@ get_num_components() const { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4)::iterator FLOATNAME(LMatrix4):: +template +INLINE LMatrix4::iterator LMatrix4:: begin() { return _data; } @@ -561,8 +419,8 @@ begin() { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4)::iterator FLOATNAME(LMatrix4):: +template +INLINE LMatrix4::iterator LMatrix4:: end() { return begin() + 16; } @@ -573,8 +431,8 @@ end() { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4)::const_iterator FLOATNAME(LMatrix4):: +template +INLINE LMatrix4::const_iterator LMatrix4:: begin() const { return _data; } @@ -585,20 +443,46 @@ begin() const { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4)::const_iterator FLOATNAME(LMatrix4):: +template +INLINE LMatrix4::const_iterator LMatrix4:: end() const { return begin() + 16; } +//////////////////////////////////////////////////////////////////// +// Function: LMatrix4::Equality Operator +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +bool LMatrix4:: +operator == (const LMatrix4 &other) const { + return ((*this)(0, 0) == other(0, 0) && + (*this)(0, 1) == other(0, 1) && + (*this)(0, 2) == other(0, 2) && + (*this)(0, 3) == other(0, 3) && + (*this)(1, 0) == other(1, 0) && + (*this)(1, 1) == other(1, 1) && + (*this)(1, 2) == other(1, 2) && + (*this)(1, 3) == other(1, 3) && + (*this)(2, 0) == other(2, 0) && + (*this)(2, 1) == other(2, 1) && + (*this)(2, 2) == other(2, 2) && + (*this)(2, 3) == other(2, 3) && + (*this)(3, 0) == other(3, 0) && + (*this)(3, 1) == other(3, 1) && + (*this)(3, 2) == other(3, 2) && + (*this)(3, 3) == other(3, 3)); +} + //////////////////////////////////////////////////////////////////// // Function: LMatrix4::Inequality Operator // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LMatrix4):: -operator != (const FLOATNAME(LMatrix4) &other) const { +template +INLINE bool LMatrix4:: +operator != (const LMatrix4 &other) const { return !operator == (other); } @@ -608,12 +492,31 @@ operator != (const FLOATNAME(LMatrix4) &other) const { // Description: This flavor of compare_to uses a default threshold // value based on the numeric type. //////////////////////////////////////////////////////////////////// - -INLINE int FLOATNAME(LMatrix4):: -compare_to(const FLOATNAME(LMatrix4) &other) const { - return compare_to(other, NEARLY_ZERO(FLOATTYPE1)); +template +INLINE int LMatrix4:: +compare_to(const LMatrix4 &other) const { + return compare_to(other, NEARLY_ZERO(NumType)); } +//////////////////////////////////////////////////////////////////// +// Function: LMatrix4::compare_to +// Access: Public +// Description: Sorts matrices lexicographically, componentwise. +// Returns a number less than 0 if this matrix sorts +// before the other one, greater than zero if it sorts +// after, 0 if they are equivalent (within the indicated +// tolerance). +//////////////////////////////////////////////////////////////////// +template +int LMatrix4:: +compare_to(const LMatrix4 &other, NumType threshold) const { + for (int i = 0; i < 16; i++) { + if (!IS_THRESHOLD_EQUAL(_data[i], other._data[i], threshold)) { + return (_data[i] < other._data[i]) ? -1 : 1; + } + } + return 0; +} //////////////////////////////////////////////////////////////////// // Function: LMatrix4::xform @@ -621,10 +524,10 @@ compare_to(const FLOATNAME(LMatrix4) &other) const { // Description: 4-component vector or point times matrix. This is a // fully general operation. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LMatrix4):: -xform(const FLOATNAME(LVecBase4) &v) const { - return FLOATNAME(LVecBase4)(v.dot(get_col(0)), +template +INLINE LVecBase4 LMatrix4:: +xform(const LVecBase4 &v) const { + return LVecBase4(v.dot(get_col(0)), v.dot(get_col(1)), v.dot(get_col(2)), v.dot(get_col(3))); @@ -637,10 +540,10 @@ xform(const FLOATNAME(LVecBase4) &v) const { // translation component) and returns the result. This // assumes the matrix is an affine transform. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LMatrix4):: -xform_point(const FLOATNAME(LVecBase3) &v) const { - return FLOATNAME(LVecBase3)(v.dot(get_col3(0)) + (*this)(3, 0), +template +INLINE LVecBase3 LMatrix4:: +xform_point(const LVecBase3 &v) const { + return LVecBase3(v.dot(get_col3(0)) + (*this)(3, 0), v.dot(get_col3(1)) + (*this)(3, 1), v.dot(get_col3(2)) + (*this)(3, 2)); } @@ -652,10 +555,10 @@ xform_point(const FLOATNAME(LVecBase3) &v) const { // translation component) and returns the result. This // assumes the matrix is an affine transform. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LMatrix4):: -xform_vec(const FLOATNAME(LVecBase3) &v) const { - return FLOATNAME(LVecBase3)(v.dot(get_col3(0)), +template +INLINE LVecBase3 LMatrix4:: +xform_vec(const LVecBase3 &v) const { + return LVecBase3(v.dot(get_col3(0)), v.dot(get_col3(1)), v.dot(get_col3(2))); } @@ -666,9 +569,9 @@ xform_vec(const FLOATNAME(LVecBase3) &v) const { // Description: Returns one cell of the result of a matrix-matrix // multiplication operation. //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LMatrix4):: -mult_cel(const FLOATNAME(LMatrix4) &other, int row, int col) const { +template +INLINE NumType LMatrix4:: +mult_cel(const LMatrix4 &other, int row, int col) const { return get_row(row).dot(other.get_col(col)); } @@ -678,10 +581,10 @@ mult_cel(const FLOATNAME(LMatrix4) &other, int row, int col) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) FLOATNAME(LMatrix4):: -operator * (const FLOATNAME(LMatrix4) &other) const { - FLOATNAME(LMatrix4) t; +template +LMatrix4 LMatrix4:: +operator * (const LMatrix4 &other) const { + LMatrix4 t; t(0, 0) = mult_cel(other, 0, 0); t(0, 1) = mult_cel(other, 0, 1); @@ -711,10 +614,10 @@ operator * (const FLOATNAME(LMatrix4) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) FLOATNAME(LMatrix4):: -operator * (FLOATTYPE1 scalar) const { - FLOATNAME(LMatrix4) t; +template +LMatrix4 LMatrix4:: +operator * (NumType scalar) const { + LMatrix4 t; t(0, 0) = (*this)(0, 0) * scalar; t(0, 1) = (*this)(0, 1) * scalar; @@ -744,10 +647,10 @@ operator * (FLOATTYPE1 scalar) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) FLOATNAME(LMatrix4):: -operator / (FLOATTYPE1 scalar) const { - FLOATNAME(LMatrix4) t; +template +LMatrix4 LMatrix4:: +operator / (NumType scalar) const { + LMatrix4 t; t(0, 0) = (*this)(0, 0) / scalar; t(0, 1) = (*this)(0, 1) / scalar; @@ -777,9 +680,9 @@ operator / (FLOATTYPE1 scalar) const { // Access: Public // Description: Performs a memberwise addition between two matrices. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4):: -operator += (const FLOATNAME(LMatrix4) &other) { +template +LMatrix4 &LMatrix4:: +operator += (const LMatrix4 &other) { (*this)(0, 0) += other(0, 0); (*this)(0, 1) += other(0, 1); (*this)(0, 2) += other(0, 2); @@ -808,9 +711,9 @@ operator += (const FLOATNAME(LMatrix4) &other) { // Access: Public // Description: Performs a memberwise addition between two matrices. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4):: -operator -= (const FLOATNAME(LMatrix4) &other) { +template +LMatrix4 &LMatrix4:: +operator -= (const LMatrix4 &other) { (*this)(0, 0) -= other(0, 0); (*this)(0, 1) -= other(0, 1); (*this)(0, 2) -= other(0, 2); @@ -839,9 +742,9 @@ operator -= (const FLOATNAME(LMatrix4) &other) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4):: -operator *= (const FLOATNAME(LMatrix4) &other) { +template +INLINE LMatrix4 &LMatrix4:: +operator *= (const LMatrix4 &other) { (*this) = (*this) * other; return *this; } @@ -851,9 +754,9 @@ operator *= (const FLOATNAME(LMatrix4) &other) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4):: -operator *= (FLOATTYPE1 scalar) { +template +LMatrix4 &LMatrix4:: +operator *= (NumType scalar) { (*this)(0, 0) *= scalar; (*this)(0, 1) *= scalar; (*this)(0, 2) *= scalar; @@ -882,9 +785,9 @@ operator *= (FLOATTYPE1 scalar) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4):: -operator /= (FLOATTYPE1 scalar) { +template +LMatrix4 &LMatrix4:: +operator /= (NumType scalar) { (*this)(0, 0) /= scalar; (*this)(0, 1) /= scalar; (*this)(0, 2) /= scalar; @@ -914,9 +817,9 @@ operator /= (FLOATTYPE1 scalar) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix4):: -transpose_from(const FLOATNAME(LMatrix4) &other) { +template +void LMatrix4:: +transpose_from(const LMatrix4 &other) { (*this)(0, 0) = other(0, 0); (*this)(0, 1) = other(1, 0); (*this)(0, 2) = other(2, 0); @@ -944,10 +847,10 @@ transpose_from(const FLOATNAME(LMatrix4) &other) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix4):: +template +INLINE void LMatrix4:: transpose_in_place() { - FLOATNAME(LMatrix4) temp = (*this); + LMatrix4 temp = (*this); transpose_from(temp); } @@ -969,9 +872,9 @@ transpose_in_place() { // successfully inverted, false if the was a // singularity. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LMatrix4):: -invert_from(const FLOATNAME(LMatrix4) &other) { +template +bool LMatrix4:: +invert_from(const LMatrix4 &other) { if (IS_NEARLY_EQUAL(other(3, 0), 0.0) && IS_NEARLY_EQUAL(other(3, 1), 0.0) && IS_NEARLY_EQUAL(other(3, 2), 0.0) && @@ -989,7 +892,7 @@ invert_from(const FLOATNAME(LMatrix4) &other) { return false; } - FLOATNAME(LMatrix4) inv = FLOATNAME(LMatrix4)::ident_mat(); + LMatrix4 inv = LMatrix4::ident_mat(); int row; for (row = 0; row < 4; row++) { @@ -1016,14 +919,14 @@ invert_from(const FLOATNAME(LMatrix4) &other) { // successfully inverted, false if the was a // singularity. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LMatrix4):: -invert_affine_from(const FLOATNAME(LMatrix4) &other) { - FLOATNAME(LMatrix3) rot; +template +bool LMatrix4:: +invert_affine_from(const LMatrix4 &other) { + LMatrix3 rot; rot.invert_from(other.get_upper_3()); set_upper_3(rot); - set_col(3, FLOATNAME(LVecBase4)(0.0, 0.0, 0.0, 1.0)); + set_col(3, LVecBase4(0.0, 0.0, 0.0, 1.0)); // compute -C*inv(A) for (int i = 0; i < 3; i++) { @@ -1043,22 +946,27 @@ invert_affine_from(const FLOATNAME(LMatrix4) &other) { // inverse is successful, false if the matrix was // singular. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LMatrix4):: +template +INLINE bool LMatrix4:: invert_in_place() { - FLOATNAME(LMatrix4) temp = (*this); + LMatrix4 temp = (*this); return invert_from(temp); } + + + + + //////////////////////////////////////////////////////////////////// // Function: LMatrix::ident_mat // Access: Public, Static // Description: Returns an identity matrix. //////////////////////////////////////////////////////////////////// - -INLINE const FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4):: +template +const LMatrix4 &LMatrix4:: ident_mat() { - static FLOATNAME(LMatrix4) mat(1.0, 0.0, 0.0, 0.0, + static LMatrix4 mat(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); @@ -1072,10 +980,10 @@ ident_mat() { // Description: Returns a matrix that applies the indicated // translation. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) FLOATNAME(LMatrix4):: -translate_mat(const FLOATNAME(LVecBase3) &trans) { - return FLOATNAME(LMatrix4)(1.0, 0.0, 0.0, 0.0, +template +LMatrix4 LMatrix4:: +translate_mat(const LVecBase3 &trans) { + return LMatrix4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, trans[0], trans[1], trans[2], 1.0); @@ -1087,29 +995,30 @@ translate_mat(const FLOATNAME(LVecBase3) &trans) { // Description: Returns a matrix that applies the indicated // translation. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) FLOATNAME(LMatrix4):: -translate_mat(FLOATTYPE1 tx, FLOATTYPE1 ty, FLOATTYPE1 tz) { - return FLOATNAME(LMatrix4)(1.0, 0.0, 0.0, 0.0, +template +LMatrix4 LMatrix4:: +translate_mat(NumType tx, NumType ty, NumType tz) { + return LMatrix4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, tx, ty, tz, 1.0); } + //////////////////////////////////////////////////////////////////// // Function: LMatrix::rotate_mat // Access: Public, Static // Description: Returns a matrix that rotates by the given angle in // degrees counterclockwise about the indicated vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) FLOATNAME(LMatrix4):: -rotate_mat(FLOATTYPE1 angle, FLOATNAME(LVecBase3) axis, +template +LMatrix4 LMatrix4:: +rotate_mat(NumType angle, LVecBase3 axis, CoordinateSystem cs) { if (cs == CS_default) { cs = default_coordinate_system; } - FLOATNAME(LMatrix4) mat; + LMatrix4 mat; if (!is_right_handed(cs)) { // In a left-handed coordinate system, counterclockwise is the @@ -1118,10 +1027,10 @@ rotate_mat(FLOATTYPE1 angle, FLOATNAME(LVecBase3) axis, } // Normalize the axis. - FLOATTYPE1 length2 = axis.dot(axis); + NumType length2 = axis.dot(axis); // Cannot rotate about a zero-length axis. nassertr(length2 != 0.0, ident_mat()); - FLOATTYPE1 recip_sqrt_length2=1.0f/csqrt(length2); + NumType recip_sqrt_length2=1.0f/csqrt(length2); axis *= recip_sqrt_length2; double angle_rad=deg_2_rad(angle); @@ -1152,16 +1061,17 @@ rotate_mat(FLOATTYPE1 angle, FLOATNAME(LVecBase3) axis, return mat; } + //////////////////////////////////////////////////////////////////// // Function: LMatrix::scale_mat // Access: Public, Static // Description: Returns a matrix that applies the indicated // scale in each of the three axes. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) FLOATNAME(LMatrix4):: -scale_mat(const FLOATNAME(LVecBase3) &scale) { - return FLOATNAME(LMatrix4)(scale[0], 0.0, 0.0, 0.0, +template +LMatrix4 LMatrix4:: +scale_mat(const LVecBase3 &scale) { + return LMatrix4(scale[0], 0.0, 0.0, 0.0, 0.0, scale[1], 0.0, 0.0, 0.0, 0.0, scale[2], 0.0, 0.0, 0.0, 0.0, 1.0); @@ -1174,10 +1084,10 @@ scale_mat(const FLOATNAME(LVecBase3) &scale) { // Description: Returns a matrix that applies the indicated // scale in each of the three axes. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) FLOATNAME(LMatrix4):: -scale_mat(FLOATTYPE1 sx, FLOATTYPE1 sy, FLOATTYPE1 sz) { - return FLOATNAME(LMatrix4)(sx, 0.0, 0.0, 0.0, +template +LMatrix4 LMatrix4:: +scale_mat(NumType sx, NumType sy, NumType sz) { + return LMatrix4(sx, 0.0, 0.0, 0.0, 0.0, sy, 0.0, 0.0, 0.0, 0.0, sz, 0.0, 0.0, 0.0, 0.0, 1.0); @@ -1190,10 +1100,10 @@ scale_mat(FLOATTYPE1 sx, FLOATTYPE1 sy, FLOATTYPE1 sz) { // Description: Returns a matrix that applies the indicated // uniform scale. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) FLOATNAME(LMatrix4):: -scale_mat(FLOATTYPE1 scale) { - return FLOATNAME(LMatrix4)(scale, 0.0, 0.0, 0.0, +template +LMatrix4 LMatrix4:: +scale_mat(NumType scale) { + return LMatrix4(scale, 0.0, 0.0, 0.0, 0.0, scale, 0.0, 0.0, 0.0, 0.0, scale, 0.0, 0.0, 0.0, 0.0, 1.0); @@ -1206,10 +1116,10 @@ scale_mat(FLOATTYPE1 scale) { // Description: Returns a matrix that transforms from the Y-up // coordinate system to the Z-up coordinate system. //////////////////////////////////////////////////////////////////// - -INLINE const FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4):: +template +const LMatrix4 &LMatrix4:: y_to_z_up_mat() { - static FLOATNAME(LMatrix4) mat(1.0, 0.0, 0.0, 0.0, + static LMatrix4 mat(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,-1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); @@ -1222,26 +1132,119 @@ y_to_z_up_mat() { // Description: Returns a matrix that transforms from the Y-up // coordinate system to the Z-up coordinate system. //////////////////////////////////////////////////////////////////// - -INLINE const FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4):: +template +const LMatrix4 &LMatrix4:: z_to_y_up_mat() { - static FLOATNAME(LMatrix4) mat(1.0, 0.0, 0.0, 0.0, + static LMatrix4 mat(1.0, 0.0, 0.0, 0.0, 0.0, 0.0,-1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); return mat; } + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix::convert_mat +// Access: Public, Static +// Description: Returns a matrix that transforms from the indicated +// coordinate system to the indicated coordinate system. +//////////////////////////////////////////////////////////////////// +template +LMatrix4 LMatrix4:: +convert_mat(CoordinateSystem from, CoordinateSystem to) { + if (from == CS_default) { + from = default_coordinate_system; + } + if (to == CS_default) { + to = default_coordinate_system; + } + switch (from) { + case CS_zup_left: + switch (to) { + case CS_zup_left: return ident_mat(); + case CS_yup_left: return z_to_y_up_mat(); + case CS_zup_right: return scale_mat(1.0, -1.0, 1.0); + case CS_yup_right: return scale_mat(1.0, -1.0, 1.0) * z_to_y_up_mat(); + default: break; + } + break; + + case CS_yup_left: + switch (to) { + case CS_zup_left: return y_to_z_up_mat(); + case CS_yup_left: return ident_mat(); + case CS_zup_right: return scale_mat(1.0, 1.0, -1.0) * y_to_z_up_mat(); + case CS_yup_right: return scale_mat(1.0, 1.0, -1.0); + default: break; + } + break; + + case CS_zup_right: + switch (to) { + case CS_zup_left: return scale_mat(1.0, -1.0, 1.0); + case CS_yup_left: return scale_mat(1.0, -1.0, 1.0) * z_to_y_up_mat(); + case CS_zup_right: return ident_mat(); + case CS_yup_right: return z_to_y_up_mat(); + default: break; + } + break; + + case CS_yup_right: + switch (to) { + case CS_zup_left: return scale_mat(1.0, 1.0, -1.0) * y_to_z_up_mat(); + case CS_yup_left: return scale_mat(1.0, 1.0, -1.0); + case CS_zup_right: return y_to_z_up_mat(); + case CS_yup_right: return ident_mat(); + default: break; + } + break; + + default: + break; + } + + linmath_cat.error() + << "Invalid coordinate system value!\n"; + return ident_mat(); +} + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix4::almost_equal +// Access: Public +// Description: Returns true if two matrices are memberwise equal +// within a specified tolerance. +//////////////////////////////////////////////////////////////////// +template +bool LMatrix4:: +almost_equal(const LMatrix4 &other, NumType threshold) const { + return (IS_THRESHOLD_EQUAL((*this)(0, 0), other(0, 0), threshold) && + IS_THRESHOLD_EQUAL((*this)(0, 1), other(0, 1), threshold) && + IS_THRESHOLD_EQUAL((*this)(0, 2), other(0, 2), threshold) && + IS_THRESHOLD_EQUAL((*this)(0, 3), other(0, 3), threshold) && + IS_THRESHOLD_EQUAL((*this)(1, 0), other(1, 0), threshold) && + IS_THRESHOLD_EQUAL((*this)(1, 1), other(1, 1), threshold) && + IS_THRESHOLD_EQUAL((*this)(1, 2), other(1, 2), threshold) && + IS_THRESHOLD_EQUAL((*this)(1, 3), other(1, 3), threshold) && + IS_THRESHOLD_EQUAL((*this)(2, 0), other(2, 0), threshold) && + IS_THRESHOLD_EQUAL((*this)(2, 1), other(2, 1), threshold) && + IS_THRESHOLD_EQUAL((*this)(2, 2), other(2, 2), threshold) && + IS_THRESHOLD_EQUAL((*this)(2, 3), other(2, 3), threshold) && + IS_THRESHOLD_EQUAL((*this)(3, 0), other(3, 0), threshold) && + IS_THRESHOLD_EQUAL((*this)(3, 1), other(3, 1), threshold) && + IS_THRESHOLD_EQUAL((*this)(3, 2), other(3, 2), threshold) && + IS_THRESHOLD_EQUAL((*this)(3, 3), other(3, 3), threshold)); +} + //////////////////////////////////////////////////////////////////// // Function: LMatrix4::almost_equal // Access: Public // Description: Returns true if two matrices are memberwise equal // within a default tolerance based on the numeric type. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LMatrix4):: -almost_equal(const FLOATNAME(LMatrix4) &other) const { - return almost_equal(other, NEARLY_ZERO(FLOATTYPE1)); +template +INLINE bool LMatrix4:: +almost_equal(const LMatrix4 &other) const { + return almost_equal(other, NEARLY_ZERO(NumType)); } //////////////////////////////////////////////////////////////////// @@ -1249,8 +1252,8 @@ almost_equal(const FLOATNAME(LMatrix4) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix4):: +template +INLINE void LMatrix4:: output(ostream &out) const { out << "[ " << MAYBE_ZERO((*this)(0, 0)) << " " @@ -1280,8 +1283,8 @@ output(ostream &out) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LMatrix4):: +template +INLINE void LMatrix4:: write(ostream &out, int indent_level) const { indent(out, indent_level) << MAYBE_ZERO((*this)(0, 0)) << " " @@ -1309,14 +1312,177 @@ write(ostream &out, int indent_level) const { << "\n"; } +//////////////////////////////////////////////////////////////////// +// Function: LMatrix4::decompose_mat +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +template +bool LMatrix4:: +decompose_mat(int index[4]) { + int i, j, k; + NumType vv[4]; + for (i = 0; i < 4; i++) { + NumType big = 0.0; + for (j = 0; j < 4; j++) { + NumType temp = fabs((*this)(i,j)); + if (temp > big) { + big = temp; + } + } + + if (IS_NEARLY_ZERO(big)) { + return false; + } + vv[i] = 1.0 / big; + } + + for (j = 0; j < 4; j++) { + for (i = 0; i < j; i++) { + NumType sum = (*this)(i,j); + for (k = 0; k < i; k++) { + sum -= (*this)(i,k) * (*this)(k,j); + } + (*this)(i,j) = sum; + } + + NumType big = 0.0; + int imax = -1; + for (i = j; i < 4; i++) { + NumType sum = (*this)(i,j); + for (k = 0; k < j; k++) { + sum -= (*this)(i,k) * (*this)(k,j); + } + (*this)(i,j) = sum; + + NumType dum = vv[i] * fabs(sum); + if (dum >= big) { + big = dum; + imax = i; + } + } + nassertr(imax >= 0, false); + if (j != imax) { + for (k = 0; k < 4; k++) { + NumType dum = (*this)(imax,k); + (*this)(imax,k) = (*this)(j,k); + (*this)(j,k) = dum; + } + vv[imax] = vv[j]; + } + index[j] = imax; + + if ((*this)(j,j) == 0.0) { + (*this)(j,j) = NEARLY_ZERO(NumType); + } + + if (j != 4 - 1) { + NumType dum = 1.0 / (*this)(j,j); + for (i = j + 1; i < 4; i++) { + (*this)(i,j) *= dum; + } + } + } + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix4::back_sub_mat +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +template +bool LMatrix4:: +back_sub_mat(int index[4], LMatrix4 &inv, int row) const { + int ii = -1; + int i, j; + for (i = 0; i < 4; i++) { + int ip = index[i]; + NumType sum = inv(row, ip); + inv(row, ip) = inv(row, i); + if (ii >= 0) { + for (j = ii; j <= i - 1; j++) { + sum -= (*this)(i,j) * inv(row, j); + } + } else if (sum) { + ii = i; + } + + inv(row, i) = sum; + } + + for (i = 4 - 1; i >= 0; i--) { + NumType sum = inv(row, i); + for (j = i + 1; j < 4; j++) { + sum -= (*this)(i,j) * inv(row, j); + } + inv(row, i) = sum / (*this)(i,i); + } + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix4::init_type +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +template +void LMatrix4:: +init_type() { + if (_type_handle == TypeHandle::none()) { + // Format a string to describe the type. + do_init_type(NumType); + string name = + "LMatrix4<" + get_type_handle(NumType).get_name() + ">"; + register_type(_type_handle, name); + } +} + + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix4::write_datagram +// Description: Writes the matrix to the datagram +//////////////////////////////////////////////////////////////////// +template +void LMatrix4:: +write_datagram(Datagram &destination) const +{ + for(int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + destination.add_float32(get_cell(i,j)); + } + } +} + + +//////////////////////////////////////////////////////////////////// +// Function: LMatrix4::read_datagram +// Description: Reads itself out of the datagram +//////////////////////////////////////////////////////////////////// +template +void LMatrix4:: +read_datagram(DatagramIterator &scan) +{ + for(int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + set_cell(i, j, scan.get_float32()); + } + } +} + //////////////////////////////////////////////////////////////////// // Function: LMatrix4::transpose // Description: Transposes the given matrix and returns it. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) -transpose(const FLOATNAME(LMatrix4) &a) { - FLOATNAME(LMatrix4) result; +template +INLINE LMatrix4 +transpose(const LMatrix4 &a) { + LMatrix4 result; result.transpose_from(a); return result; } @@ -1325,12 +1491,27 @@ transpose(const FLOATNAME(LMatrix4) &a) { // Function: LMatrix4::invert // Description: Inverts the given matrix and returns it. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) -invert(const FLOATNAME(LMatrix4) &a) { - FLOATNAME(LMatrix4) result; +template +INLINE LMatrix4 +invert(const LMatrix4 &a) { + LMatrix4 result; bool nonsingular = result.invert_from(a); - nassertr(nonsingular, FLOATNAME(LMatrix4)::ident_mat()); + nassertr(nonsingular, LMatrix4::ident_mat()); return result; } +//////////////////////////////////////////////////////////////////// +// Function: lcast_to +// Description: Converts a matrix from one numeric representation to +// another one. This is usually invoked using the macro +// LCAST. +//////////////////////////////////////////////////////////////////// +template +INLINE LMatrix4 +lcast_to(NumType2 *, const LMatrix4 &source) { + return LMatrix4 + (source(0, 0), source(0, 1), source(0, 2), source(0, 3), + source(1, 0), source(1, 1), source(1, 2), source(1, 3), + source(2, 0), source(2, 1), source(2, 2), source(2, 3), + source(3, 0), source(3, 1), source(3, 2), source(3, 3)); +} diff --git a/panda/src/linmath/lmatrix4.h b/panda/src/linmath/lmatrix4.h index 88545e2fa2..1d813d07c3 100644 --- a/panda/src/linmath/lmatrix4.h +++ b/panda/src/linmath/lmatrix4.h @@ -7,51 +7,182 @@ #define LMATRIX4_H #include -#include -#include -#include -#include -#include - -#include "deg_2_rad.h" -#include "nearly_zero.h" #include "coordinateSystem.h" #include "lvecBase4.h" #include "lvecBase3.h" #include "lmatrix3.h" -#include "fltnames.I" -#include "lmatrix4.I" - -#include "dblnames.I" -#include "lmatrix4.I" - +#include +#include +#include //////////////////////////////////////////////////////////////////// -// Function: lcast_to -// Description: Converts a matrix from one numeric representation to -// another one. This is usually invoked using the macro -// LCAST. +// Class : LMatrix4 +// Description : This is a 4-by-4 transform matrix. //////////////////////////////////////////////////////////////////// -INLINE FLOATNAME2(LMatrix4) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LMatrix4) &source) { - return FLOATNAME2(LMatrix4) - (source(0, 0), source(0, 1), source(0, 2), source(0, 3), - source(1, 0), source(1, 1), source(1, 2), source(1, 3), - source(2, 0), source(2, 1), source(2, 2), source(2, 3), - source(3, 0), source(3, 1), source(3, 2), source(3, 3)); +template +class LMatrix4 { +PUBLISHED: + typedef const NumType *iterator; + typedef const NumType *const_iterator; + + INLINE LMatrix4(); + INLINE LMatrix4(const LMatrix4 &other); + LMatrix4 &operator = (const LMatrix4 &other); + INLINE LMatrix4 &operator = (NumType fill_value); + INLINE LMatrix4(NumType e00, NumType e01, NumType e02, NumType e03, + NumType e10, NumType e11, NumType e12, NumType e13, + NumType e20, NumType e21, NumType e22, NumType e23, + NumType e30, NumType e31, NumType e32, NumType e33); + + // Construct a 4x4 matrix given a 3x3 rotation matrix and an optional + // translation component. + LMatrix4(const LMatrix3 &upper3); + LMatrix4(const LMatrix3 &upper3, + const LVecBase3 &trans); + + void fill(NumType fill_value); + INLINE void set(NumType e00, NumType e01, NumType e02, NumType e03, + NumType e10, NumType e11, NumType e12, NumType e13, + NumType e20, NumType e21, NumType e22, NumType e23, + NumType e30, NumType e31, NumType e32, NumType e33); + + // Get and set the upper 3x3 rotation matrix. + INLINE void set_upper_3(const LMatrix3 &upper3); + INLINE LMatrix3 get_upper_3() const; + + INLINE void set_row(int row, const LVecBase4 &v); + INLINE void set_col(int col, const LVecBase4 &v); + + INLINE void set_row(int row, const LVecBase3 &v); + INLINE void set_col(int col, const LVecBase3 &v); + + INLINE LVecBase4 get_row(int row) const; + INLINE LVecBase4 get_col(int col) const; + + INLINE LVecBase3 get_row3(int row) const; + INLINE LVecBase3 get_col3(int col) const; + + INLINE NumType &operator () (int row, int col); + INLINE NumType operator () (int row, int col) const; + + INLINE bool is_nan() const; + + INLINE NumType get_cell(int row, int col) const; + INLINE void set_cell(int row, int col, NumType value); + + INLINE const NumType *get_data() const; + INLINE int get_num_components() const; + + INLINE iterator begin(); + INLINE iterator end(); + + INLINE const_iterator begin() const; + INLINE const_iterator end() const; + + + bool operator == (const LMatrix4 &other) const; + INLINE bool operator != (const LMatrix4 &other) const; + + INLINE int compare_to(const LMatrix4 &other) const; + int compare_to(const LMatrix4 &other, NumType threshold) const; + + INLINE LVecBase4 + xform(const LVecBase4 &v) const; + + INLINE LVecBase3 + xform_point(const LVecBase3 &v) const; + + INLINE LVecBase3 + xform_vec(const LVecBase3 &v) const; + + LMatrix4 operator * (const LMatrix4 &other) const; + LMatrix4 operator * (NumType scalar) const; + LMatrix4 operator / (NumType scalar) const; + + LMatrix4 &operator += (const LMatrix4 &other); + LMatrix4 &operator -= (const LMatrix4 &other); + + INLINE LMatrix4 &operator *= (const LMatrix4 &other); + + LMatrix4 &operator *= (NumType scalar); + LMatrix4 &operator /= (NumType scalar); + + void transpose_from(const LMatrix4 &other); + INLINE void transpose_in_place(); + + bool invert_from(const LMatrix4 &other); + bool invert_affine_from(const LMatrix4 &other); + INLINE bool invert_in_place(); + + static const LMatrix4 &ident_mat(); + static LMatrix4 translate_mat(const LVecBase3 &trans); + static LMatrix4 translate_mat(NumType tx, NumType ty, NumType tz); + static LMatrix4 rotate_mat(NumType angle, + LVecBase3 axis, + CoordinateSystem cs = CS_default); + static LMatrix4 scale_mat(const LVecBase3 &scale); + static LMatrix4 scale_mat(NumType sx, NumType sy, NumType sz); + static LMatrix4 scale_mat(NumType scale); + + static const LMatrix4 &y_to_z_up_mat(); + static const LMatrix4 &z_to_y_up_mat(); + + static LMatrix4 convert_mat(CoordinateSystem from, + CoordinateSystem to); + + + bool almost_equal(const LMatrix4 &other, + NumType threshold) const; + INLINE bool almost_equal(const LMatrix4 &other) const; + + INLINE void output(ostream &out) const; + INLINE void write(ostream &out, int indent_level = 0) const; + +private: + INLINE NumType mult_cel(const LMatrix4 &other, int x, int y) const; + bool decompose_mat(int index[4]); + bool back_sub_mat(int index[4], LMatrix4 &inv, int row) const; + + NumType _data[4 * 4]; + + //Functionality for reading and writing from/to a binary source +public: + void write_datagram(Datagram& destination) const; + void read_datagram(DatagramIterator& scan); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type(); + +private: + static TypeHandle _type_handle; +}; + +template +INLINE ostream &operator << (ostream &out, const LMatrix4 &mat) { + mat.output(out); + return out; } -#include "fltnames.I" +template +INLINE LMatrix4 transpose(const LMatrix4 &a); -INLINE FLOATNAME2(LMatrix4) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LMatrix4) &source) { - return FLOATNAME2(LMatrix4) - (source(0, 0), source(0, 1), source(0, 2), source(0, 3), - source(1, 0), source(1, 1), source(1, 2), source(1, 3), - source(2, 0), source(2, 1), source(2, 2), source(2, 3), - source(3, 0), source(3, 1), source(3, 2), source(3, 3)); -} +template +INLINE LMatrix4 invert(const LMatrix4 &a); + +// Cast to a different numeric type +template +INLINE LMatrix4 +lcast_to(NumType2 *type, const LMatrix4 &source); + + +#include "lmatrix4.I" + +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LMatrix4) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LMatrix4) #endif diff --git a/panda/src/linmath/lorientation.I b/panda/src/linmath/lorientation.I index 2f7e63dedc..d4454a6228 100644 --- a/panda/src/linmath/lorientation.I +++ b/panda/src/linmath/lorientation.I @@ -3,43 +3,20 @@ // //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -// Class : LOrientation -// Description : This is a unit quaternion representing an orientation. -//////////////////////////////////////////////////////////////////////// -class EXPCL_PANDA FLOATNAME(LOrientation) : public FLOATNAME(LQuaternionBase) { -public: - INLINE FLOATNAME(LOrientation)(); - INLINE FLOATNAME(LOrientation)(const FLOATNAME(LQuaternionBase)&); - INLINE FLOATNAME(LOrientation)(FLOATTYPE1, FLOATTYPE1, FLOATTYPE1, FLOATTYPE1); - INLINE FLOATNAME(LOrientation)(const FLOATNAME(LVector3) &, float); - INLINE FLOATNAME(LOrientation)(const FLOATNAME(LMatrix3) &); - INLINE FLOATNAME(LOrientation)(const FLOATNAME(LMatrix4) &); - virtual ~FLOATNAME(LOrientation)(); +#include "lorientation.h" +#include - INLINE FLOATNAME(LOrientation) - operator *(const FLOATNAME(LQuaternionBase)& other) const; - - INLINE FLOATNAME(LOrientation) - operator *(const FLOATNAME(LOrientation)& other) const; - -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type(); -private: - static TypeHandle _type_handle; -}; +template +TypeHandle LOrientation::_type_handle; //////////////////////////////////////////////////////////////////// // Function: LOrientation::Default Constructor // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LOrientation):: -FLOATNAME(LOrientation)() { +template +INLINE LOrientation:: +LOrientation() { } //////////////////////////////////////////////////////////////////// @@ -47,10 +24,10 @@ FLOATNAME(LOrientation)() { // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LOrientation):: -FLOATNAME(LOrientation)(const FLOATNAME(LQuaternionBase)& c) : - FLOATNAME(LQuaternionBase)(c) { +template +INLINE LOrientation:: +LOrientation(const LQuaternionBase& c) : + LQuaternionBase(c) { } //////////////////////////////////////////////////////////////////// @@ -58,10 +35,10 @@ FLOATNAME(LOrientation)(const FLOATNAME(LQuaternionBase)& c) : // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LOrientation):: -FLOATNAME(LOrientation)(FLOATTYPE1 r, FLOATTYPE1 i, FLOATTYPE1 j, FLOATTYPE1 k) : - FLOATNAME(LQuaternionBase)(r, i, j, k) { +template +INLINE LOrientation:: +LOrientation(NumType r, NumType i, NumType j, NumType k) : + LQuaternionBase(r, i, j, k) { } //////////////////////////////////////////////////////////////////// @@ -69,9 +46,9 @@ FLOATNAME(LOrientation)(FLOATTYPE1 r, FLOATTYPE1 i, FLOATTYPE1 j, FLOATTYPE1 k) // Access: public // Description: vector + twist //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LOrientation):: -FLOATNAME(LOrientation)(const FLOATNAME(LVector3) &point_at, float twist) { +template +INLINE LOrientation:: +LOrientation(const LVector3 &point_at, float twist) { float radians = twist * ((float) MathNumbers::pi / 180.0f); float theta_over_2 = radians / 2.0f; float sin_to2 = sinf(theta_over_2); @@ -87,9 +64,9 @@ FLOATNAME(LOrientation)(const FLOATNAME(LVector3) &point_at, float twist) { // Access: public // Description: matrix3 //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LOrientation):: -FLOATNAME(LOrientation)(const FLOATNAME(LMatrix3) &m) { +template +INLINE LOrientation:: +LOrientation(const LMatrix3 &m) { set(m); } @@ -98,21 +75,31 @@ FLOATNAME(LOrientation)(const FLOATNAME(LMatrix3) &m) { // Access: public // Description: matrix4 //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LOrientation):: -FLOATNAME(LOrientation)(const FLOATNAME(LMatrix4) &m) { +template +INLINE LOrientation:: +LOrientation(const LMatrix4 &m) { set(m); } +//////////////////////////////////////////////////////////////////// +// Function: LOrientation::Destructor +// Access: public +// Description: +//////////////////////////////////////////////////////////////////// +template +LOrientation:: +~LOrientation() { +} + //////////////////////////////////////////////////////////////////// // Function: LOrientation::operator * // Access: public // Description: Orientation * rotation = Orientation // Applies an rotation to an orientation. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LOrientation) FLOATNAME(LOrientation):: -operator *(const FLOATNAME(LQuaternionBase)& other) const { +template +INLINE LOrientation LOrientation:: +operator *(const LQuaternionBase& other) const { return multiply(other); } @@ -123,8 +110,25 @@ operator *(const FLOATNAME(LQuaternionBase)& other) const { // This is a meaningless operation, and will always // simply return the rhs. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LOrientation) FLOATNAME(LOrientation):: -operator *(const FLOATNAME(LOrientation)& other) const { +template +INLINE LOrientation LOrientation:: +operator *(const LOrientation& other) const { return other; } + +//////////////////////////////////////////////////////////////////// +// Function: LOrientation::init_type +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +template +void LOrientation:: +init_type() { + if (_type_handle == TypeHandle::none()) { + // Format a string to describe the type. + do_init_type(NumType); + string name = + "LOrientation<" + get_type_handle(NumType).get_name() + ">"; + register_type(_type_handle, name); + } +} diff --git a/panda/src/linmath/lorientation.h b/panda/src/linmath/lorientation.h index 80155f5429..20a77490b0 100644 --- a/panda/src/linmath/lorientation.h +++ b/panda/src/linmath/lorientation.h @@ -7,16 +7,41 @@ #define __LORIENTATION_H__ #include -#include #include "lquaternion.h" -#include "fltnames.I" +//////////////////////////////////////////////////////////////////////// +// Class : LOrientation +// Description : This is a unit quaternion representing an orientation. +//////////////////////////////////////////////////////////////////////// +template +class LOrientation : public LQuaternionBase { +public: + INLINE LOrientation(); + INLINE LOrientation(const LQuaternionBase&); + INLINE LOrientation(NumType, NumType, NumType, NumType); + INLINE LOrientation(const LVector3 &, float); + INLINE LOrientation(const LMatrix3 &); + INLINE LOrientation(const LMatrix4 &); + virtual ~LOrientation(); + + INLINE LOrientation + operator *(const LQuaternionBase& other) const; + + INLINE LOrientation + operator *(const LOrientation& other) const; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type(); +private: + static TypeHandle _type_handle; +}; + #include "lorientation.I" -#include "dblnames.I" -#include "lorientation.I" - - - +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LOrientation) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LOrientation) #endif /* __LORIENTATION_H__ */ diff --git a/panda/src/linmath/lpoint2.I b/panda/src/linmath/lpoint2.I index fc54020aec..695472aea5 100644 --- a/panda/src/linmath/lpoint2.I +++ b/panda/src/linmath/lpoint2.I @@ -3,60 +3,17 @@ // //////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////// -// Class : LPoint2 -// Description : This is a two-component point in space. -//////////////////////////////////////////////////////////////////// - -class EXPCL_PANDA FLOATNAME(LPoint2) : public FLOATNAME(LVecBase2) { -PUBLISHED: - INLINE FLOATNAME(LPoint2)(); - INLINE FLOATNAME(LPoint2)(const FLOATNAME(LVecBase2) ©); - INLINE FLOATNAME(LPoint2) &operator = (const FLOATNAME(LVecBase2) ©); - INLINE FLOATNAME(LPoint2) &operator = (FLOATTYPE1 fill_value); - INLINE FLOATNAME(LPoint2)(FLOATTYPE1 fill_value); - INLINE FLOATNAME(LPoint2)(FLOATTYPE1 x, FLOATTYPE1 y); - - INLINE static FLOATNAME(LPoint2) zero(); - INLINE static FLOATNAME(LPoint2) unit_x(); - INLINE static FLOATNAME(LPoint2) unit_y(); - - INLINE FLOATNAME(LPoint2) operator - () const; - - INLINE FLOATNAME(LVecBase2) - operator + (const FLOATNAME(LVecBase2) &other) const; - INLINE FLOATNAME(LPoint2) - operator + (const FLOATNAME(LVector2) &other) const; - - INLINE FLOATNAME(LVecBase2) - operator - (const FLOATNAME(LVecBase2) &other) const; - INLINE FLOATNAME(LVector2) - operator - (const FLOATNAME(LPoint2) &other) const; - INLINE FLOATNAME(LPoint2) - operator - (const FLOATNAME(LVector2) &other) const; - - INLINE FLOATNAME(LPoint2) operator * (FLOATTYPE1 scalar) const; - INLINE FLOATNAME(LPoint2) operator / (FLOATTYPE1 scalar) const; - -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type(); - -private: - static TypeHandle _type_handle; -}; +template +TypeHandle LPoint2::_type_handle; //////////////////////////////////////////////////////////////////// // Function: LPoint2::Default Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint2):: -FLOATNAME(LPoint2)() { +template +INLINE LPoint2:: +LPoint2() { } //////////////////////////////////////////////////////////////////// @@ -64,9 +21,9 @@ FLOATNAME(LPoint2)() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint2):: -FLOATNAME(LPoint2)(const FLOATNAME(LVecBase2) ©) : FLOATNAME(LVecBase2)(copy) { +template +INLINE LPoint2:: +LPoint2(const LVecBase2 ©) : LVecBase2(copy) { } //////////////////////////////////////////////////////////////////// @@ -74,10 +31,10 @@ FLOATNAME(LPoint2)(const FLOATNAME(LVecBase2) ©) : FLOATNAME(LVecBase2)(copy // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint2) &FLOATNAME(LPoint2):: -operator = (const FLOATNAME(LVecBase2) ©) { - FLOATNAME(LVecBase2)::operator = (copy); +template +INLINE LPoint2 &LPoint2:: +operator = (const LVecBase2 ©) { + LVecBase2::operator = (copy); return *this; } @@ -86,10 +43,10 @@ operator = (const FLOATNAME(LVecBase2) ©) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint2) &FLOATNAME(LPoint2):: -operator = (FLOATTYPE1 fill_value) { - FLOATNAME(LVecBase2)::operator = (fill_value); +template +INLINE LPoint2 &LPoint2:: +operator = (NumType fill_value) { + LVecBase2::operator = (fill_value); return *this; } @@ -98,10 +55,10 @@ operator = (FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint2):: -FLOATNAME(LPoint2)(FLOATTYPE1 fill_value) : - FLOATNAME(LVecBase2)(fill_value) +template +INLINE LPoint2:: +LPoint2(NumType fill_value) : + LVecBase2(fill_value) { } @@ -110,10 +67,10 @@ FLOATNAME(LPoint2)(FLOATTYPE1 fill_value) : // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint2):: -FLOATNAME(LPoint2)(FLOATTYPE1 x, FLOATTYPE1 y) : - FLOATNAME(LVecBase2)(x, y) +template +INLINE LPoint2:: +LPoint2(NumType x, NumType y) : + LVecBase2(x, y) { } @@ -122,10 +79,10 @@ FLOATNAME(LPoint2)(FLOATTYPE1 x, FLOATTYPE1 y) : // Access: Public // Description: Returns a zero point. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2):: +template +INLINE LPoint2 LPoint2:: zero() { - return FLOATNAME(LPoint2)(0.0, 0.0); + return LPoint2(0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -133,10 +90,10 @@ zero() { // Access: Public // Description: Returns a unit X point. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2):: +template +INLINE LPoint2 LPoint2:: unit_x() { - return FLOATNAME(LPoint2)(1.0, 0.0); + return LPoint2(1.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -144,10 +101,10 @@ unit_x() { // Access: Public // Description: Returns a unit Y point. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2):: +template +INLINE LPoint2 LPoint2:: unit_y() { - return FLOATNAME(LPoint2)(0.0, 1.0); + return LPoint2(0.0, 1.0); } //////////////////////////////////////////////////////////////////// @@ -155,10 +112,10 @@ unit_y() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2):: +template +INLINE LPoint2 LPoint2:: operator - () const { - return FLOATNAME(LVecBase2)::operator - (); + return LVecBase2::operator - (); } //////////////////////////////////////////////////////////////////// @@ -166,10 +123,10 @@ operator - () const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LPoint2):: -operator + (const FLOATNAME(LVecBase2) &other) const { - return FLOATNAME(LVecBase2)::operator + (other); +template +INLINE LVecBase2 LPoint2:: +operator + (const LVecBase2 &other) const { + return LVecBase2::operator + (other); } //////////////////////////////////////////////////////////////////// @@ -177,10 +134,10 @@ operator + (const FLOATNAME(LVecBase2) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2):: -operator + (const FLOATNAME(LVector2) &other) const { - return FLOATNAME(LVecBase2)::operator + (other); +template +INLINE LPoint2 LPoint2:: +operator + (const LVector2 &other) const { + return LVecBase2::operator + (other); } //////////////////////////////////////////////////////////////////// @@ -188,10 +145,10 @@ operator + (const FLOATNAME(LVector2) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LPoint2):: -operator - (const FLOATNAME(LVecBase2) &other) const { - return FLOATNAME(LVecBase2)::operator - (other); +template +INLINE LVecBase2 LPoint2:: +operator - (const LVecBase2 &other) const { + return LVecBase2::operator - (other); } //////////////////////////////////////////////////////////////////// @@ -199,10 +156,10 @@ operator - (const FLOATNAME(LVecBase2) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2) FLOATNAME(LPoint2):: -operator - (const FLOATNAME(LPoint2) &other) const { - return FLOATNAME(LVecBase2)::operator - (other); +template +INLINE LVector2 LPoint2:: +operator - (const LPoint2 &other) const { + return LVecBase2::operator - (other); } //////////////////////////////////////////////////////////////////// @@ -210,10 +167,10 @@ operator - (const FLOATNAME(LPoint2) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2):: -operator - (const FLOATNAME(LVector2) &other) const { - return FLOATNAME(LVecBase2)::operator - (other); +template +INLINE LPoint2 LPoint2:: +operator - (const LVector2 &other) const { + return LVecBase2::operator - (other); } //////////////////////////////////////////////////////////////////// @@ -221,10 +178,10 @@ operator - (const FLOATNAME(LVector2) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2):: -operator * (FLOATTYPE1 scalar) const { - return FLOATNAME(LPoint2)(FLOATNAME(LVecBase2)::operator * (scalar)); +template +INLINE LPoint2 LPoint2:: +operator * (NumType scalar) const { + return LPoint2(LVecBase2::operator * (scalar)); } //////////////////////////////////////////////////////////////////// @@ -232,10 +189,37 @@ operator * (FLOATTYPE1 scalar) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2):: -operator / (FLOATTYPE1 scalar) const { - return FLOATNAME(LPoint2)(FLOATNAME(LVecBase2)::operator / (scalar)); +template +INLINE LPoint2 LPoint2:: +operator / (NumType scalar) const { + return LPoint2(LVecBase2::operator / (scalar)); } +//////////////////////////////////////////////////////////////////// +// Function: LPoint2::init_type +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +template +void LPoint2:: +init_type() { + if (_type_handle == TypeHandle::none()) { + LVecBase2::init_type(); + string name = + "LPoint2<" + get_type_handle(NumType).get_name() + ">"; + register_type(_type_handle, name, + LVecBase2::get_class_type()); + } +} +//////////////////////////////////////////////////////////////////// +// Function: lcast_to +// Description: Converts a vector from one numeric representation to +// another one. This is usually invoked using the macro +// LCAST. +//////////////////////////////////////////////////////////////////// +template +INLINE LPoint2 +lcast_to(NumType2 *, const LPoint2 &source) { + return LPoint2(source[0], source[1]); +} diff --git a/panda/src/linmath/lpoint2.h b/panda/src/linmath/lpoint2.h index 94b8146d6d..c444f5f68a 100644 --- a/panda/src/linmath/lpoint2.h +++ b/panda/src/linmath/lpoint2.h @@ -11,30 +11,59 @@ #include "lvecBase2.h" #include "lvector2.h" -#include "fltnames.I" +//////////////////////////////////////////////////////////////////// +// Class : LPoint2 +// Description : This is a two-component point in space. +//////////////////////////////////////////////////////////////////// +template +class LPoint2 : public LVecBase2 { +PUBLISHED: + INLINE LPoint2(); + INLINE LPoint2(const LVecBase2 ©); + INLINE LPoint2 &operator = (const LVecBase2 ©); + INLINE LPoint2 &operator = (NumType fill_value); + INLINE LPoint2(NumType fill_value); + INLINE LPoint2(NumType x, NumType y); + + INLINE static LPoint2 zero(); + INLINE static LPoint2 unit_x(); + INLINE static LPoint2 unit_y(); + + INLINE LPoint2 operator - () const; + + INLINE LVecBase2 + operator + (const LVecBase2 &other) const; + INLINE LPoint2 + operator + (const LVector2 &other) const; + + INLINE LVecBase2 + operator - (const LVecBase2 &other) const; + INLINE LVector2 + operator - (const LPoint2 &other) const; + INLINE LPoint2 + operator - (const LVector2 &other) const; + + INLINE LPoint2 operator * (NumType scalar) const; + INLINE LPoint2 operator / (NumType scalar) const; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type(); + +private: + static TypeHandle _type_handle; +}; + +// Cast to a different numeric type +template +INLINE LPoint2 +lcast_to(NumType2 *type, const LPoint2 &source); + #include "lpoint2.I" -#include "dblnames.I" -#include "lpoint2.I" - -//////////////////////////////////////////////////////////////////// -// Function: lcast_to -// Description: Converts a vector from one numeric representation to -// another one. This is usually invoked using the macro -// LCAST. -//////////////////////////////////////////////////////////////////// -INLINE FLOATNAME2(LPoint2) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LPoint2) &source) { - return FLOATNAME2(LPoint2)(source[0], source[1]); -} - -#include "fltnames.I" -INLINE FLOATNAME2(LPoint2) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LPoint2) &source) { - return FLOATNAME2(LPoint2)(source[0], source[1]); -} - - - +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LPoint2) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LPoint2) #endif diff --git a/panda/src/linmath/lpoint3.I b/panda/src/linmath/lpoint3.I index 8d442f1d75..14bd5d1326 100644 --- a/panda/src/linmath/lpoint3.I +++ b/panda/src/linmath/lpoint3.I @@ -3,74 +3,19 @@ // //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Class : LPoint3 -// Description : This is a three-component point in space (as opposed -// to a three-component vector, which represents a -// direction and a distance). Some of the methods are -// slightly different between LPoint3 and LVector3; in -// particular, subtraction of two points yields a -// vector, while addition of a vector and a point yields -// a point. -//////////////////////////////////////////////////////////////////// +#include "lvector3.h" -class EXPCL_PANDA FLOATNAME(LPoint3) : public FLOATNAME(LVecBase3) { -PUBLISHED: - INLINE FLOATNAME(LPoint3)(); - INLINE FLOATNAME(LPoint3)(const FLOATNAME(LVecBase3) ©); - INLINE FLOATNAME(LPoint3) &operator = (const FLOATNAME(LVecBase3) ©); - INLINE FLOATNAME(LPoint3) &operator = (FLOATTYPE1 fill_value); - INLINE FLOATNAME(LPoint3)(FLOATTYPE1 fill_value); - INLINE FLOATNAME(LPoint3)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z); - - INLINE static FLOATNAME(LPoint3) zero(); - INLINE static FLOATNAME(LPoint3) unit_x(); - INLINE static FLOATNAME(LPoint3) unit_y(); - INLINE static FLOATNAME(LPoint3) unit_z(); - - INLINE FLOATNAME(LPoint3) operator - () const; - - INLINE FLOATNAME(LVecBase3) - operator + (const FLOATNAME(LVecBase3) &other) const; - INLINE FLOATNAME(LPoint3) - operator + (const FLOATNAME(LVector3) &other) const; - - INLINE FLOATNAME(LVecBase3) - operator - (const FLOATNAME(LVecBase3) &other) const; - INLINE FLOATNAME(LVector3) - operator - (const FLOATNAME(LPoint3) &other) const; - INLINE FLOATNAME(LPoint3) - operator - (const FLOATNAME(LVector3) &other) const; - - INLINE FLOATNAME(LPoint3) cross(const FLOATNAME(LVecBase3) &other) const; - INLINE FLOATNAME(LPoint3) operator * (FLOATTYPE1 scalar) const; - INLINE FLOATNAME(LPoint3) operator / (FLOATTYPE1 scalar) const; - - // Some special named constructors for LPoint3. - - INLINE static FLOATNAME(LPoint3) origin(CoordinateSystem cs = CS_default); - INLINE static FLOATNAME(LPoint3) rfu(FLOATTYPE1 right, - FLOATTYPE1 fwd, - FLOATTYPE1 up, - CoordinateSystem cs = CS_default); -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type(); - -private: - static TypeHandle _type_handle; -}; +template +TypeHandle LPoint3::_type_handle; //////////////////////////////////////////////////////////////////// // Function: LPoint3::Default Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3):: -FLOATNAME(LPoint3)() { +template +INLINE LPoint3:: +LPoint3() { } //////////////////////////////////////////////////////////////////// @@ -78,9 +23,9 @@ FLOATNAME(LPoint3)() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3):: -FLOATNAME(LPoint3)(const FLOATNAME(LVecBase3) ©) : FLOATNAME(LVecBase3)(copy) { +template +INLINE LPoint3:: +LPoint3(const LVecBase3 ©) : LVecBase3(copy) { } //////////////////////////////////////////////////////////////////// @@ -88,10 +33,10 @@ FLOATNAME(LPoint3)(const FLOATNAME(LVecBase3) ©) : FLOATNAME(LVecBase3)(copy // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) &FLOATNAME(LPoint3):: -operator = (const FLOATNAME(LVecBase3) ©) { - FLOATNAME(LVecBase3)::operator = (copy); +template +INLINE LPoint3 &LPoint3:: +operator = (const LVecBase3 ©) { + LVecBase3::operator = (copy); return *this; } @@ -100,10 +45,10 @@ operator = (const FLOATNAME(LVecBase3) ©) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) &FLOATNAME(LPoint3):: -operator = (FLOATTYPE1 fill_value) { - FLOATNAME(LVecBase3)::operator = (fill_value); +template +INLINE LPoint3 &LPoint3:: +operator = (NumType fill_value) { + LVecBase3::operator = (fill_value); return *this; } @@ -112,10 +57,10 @@ operator = (FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3):: -FLOATNAME(LPoint3)(FLOATTYPE1 fill_value) : - FLOATNAME(LVecBase3)(fill_value) +template +INLINE LPoint3:: +LPoint3(NumType fill_value) : + LVecBase3(fill_value) { } @@ -124,10 +69,10 @@ FLOATNAME(LPoint3)(FLOATTYPE1 fill_value) : // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3):: -FLOATNAME(LPoint3)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z) : - FLOATNAME(LVecBase3)(x, y, z) +template +INLINE LPoint3:: +LPoint3(NumType x, NumType y, NumType z) : + LVecBase3(x, y, z) { } @@ -136,10 +81,10 @@ FLOATNAME(LPoint3)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z) : // Access: Public // Description: Returns a zero point. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3):: +template +INLINE LPoint3 LPoint3:: zero() { - return FLOATNAME(LPoint3)(0.0, 0.0, 0.0); + return LPoint3(0.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -147,10 +92,10 @@ zero() { // Access: Public // Description: Returns a unit X point. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3):: +template +INLINE LPoint3 LPoint3:: unit_x() { - return FLOATNAME(LPoint3)(1.0, 0.0, 0.0); + return LPoint3(1.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -158,10 +103,10 @@ unit_x() { // Access: Public // Description: Returns a unit Y point. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3):: +template +INLINE LPoint3 LPoint3:: unit_y() { - return FLOATNAME(LPoint3)(0.0, 1.0, 0.0); + return LPoint3(0.0, 1.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -169,10 +114,10 @@ unit_y() { // Access: Public // Description: Returns a unit Z point. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3):: +template +INLINE LPoint3 LPoint3:: unit_z() { - return FLOATNAME(LPoint3)(0.0, 0.0, 1.0); + return LPoint3(0.0, 0.0, 1.0); } //////////////////////////////////////////////////////////////////// @@ -180,10 +125,10 @@ unit_z() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3):: +template +INLINE LPoint3 LPoint3:: operator - () const { - return FLOATNAME(LVecBase3)::operator - (); + return LVecBase3::operator - (); } //////////////////////////////////////////////////////////////////// @@ -191,10 +136,10 @@ operator - () const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LPoint3):: -operator + (const FLOATNAME(LVecBase3) &other) const { - return FLOATNAME(LVecBase3)::operator + (other); +template +INLINE LVecBase3 LPoint3:: +operator + (const LVecBase3 &other) const { + return LVecBase3::operator + (other); } //////////////////////////////////////////////////////////////////// @@ -202,10 +147,10 @@ operator + (const FLOATNAME(LVecBase3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3):: -operator + (const FLOATNAME(LVector3) &other) const { - return FLOATNAME(LVecBase3)::operator + (other); +template +INLINE LPoint3 LPoint3:: +operator + (const LVector3 &other) const { + return LVecBase3::operator + (other); } //////////////////////////////////////////////////////////////////// @@ -213,10 +158,10 @@ operator + (const FLOATNAME(LVector3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LPoint3):: -operator - (const FLOATNAME(LVecBase3) &other) const { - return FLOATNAME(LVecBase3)::operator - (other); +template +INLINE LVecBase3 LPoint3:: +operator - (const LVecBase3 &other) const { + return LVecBase3::operator - (other); } //////////////////////////////////////////////////////////////////// @@ -224,10 +169,10 @@ operator - (const FLOATNAME(LVecBase3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LPoint3):: -operator - (const FLOATNAME(LPoint3) &other) const { - return FLOATNAME(LVecBase3)::operator - (other); +template +INLINE LVector3 LPoint3:: +operator - (const LPoint3 &other) const { + return LVecBase3::operator - (other); } //////////////////////////////////////////////////////////////////// @@ -235,10 +180,10 @@ operator - (const FLOATNAME(LPoint3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3):: -operator - (const FLOATNAME(LVector3) &other) const { - return FLOATNAME(LVecBase3)::operator - (other); +template +INLINE LPoint3 LPoint3:: +operator - (const LVector3 &other) const { + return LVecBase3::operator - (other); } //////////////////////////////////////////////////////////////////// @@ -246,10 +191,10 @@ operator - (const FLOATNAME(LVector3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3):: -cross(const FLOATNAME(LVecBase3) &other) const { - return FLOATNAME(LVecBase3)::cross(other); +template +INLINE LPoint3 LPoint3:: +cross(const LVecBase3 &other) const { + return LVecBase3::cross(other); } //////////////////////////////////////////////////////////////////// @@ -257,10 +202,10 @@ cross(const FLOATNAME(LVecBase3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3):: -operator * (FLOATTYPE1 scalar) const { - return FLOATNAME(LPoint3)(FLOATNAME(LVecBase3)::operator * (scalar)); +template +INLINE LPoint3 LPoint3:: +operator * (NumType scalar) const { + return LPoint3(LVecBase3::operator * (scalar)); } //////////////////////////////////////////////////////////////////// @@ -268,10 +213,10 @@ operator * (FLOATTYPE1 scalar) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3):: -operator / (FLOATTYPE1 scalar) const { - return FLOATNAME(LPoint3)(FLOATNAME(LVecBase3)::operator / (scalar)); +template +INLINE LPoint3 LPoint3:: +operator / (NumType scalar) const { + return LPoint3(LVecBase3::operator / (scalar)); } //////////////////////////////////////////////////////////////////// @@ -282,10 +227,10 @@ operator / (FLOATTYPE1 scalar) const { // existing coordinate systems; it's hard to imagine it // ever being different. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3):: +template +INLINE LPoint3 LPoint3:: origin(CoordinateSystem) { - return FLOATNAME(LPoint3)(0.0, 0.0, 0.0); + return LPoint3(0.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -295,11 +240,39 @@ origin(CoordinateSystem) { // displacements from the origin, wherever that maps to // in the given coordinate system. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3):: -rfu(FLOATTYPE1 right_v, FLOATTYPE1 fwd_v, FLOATTYPE1 up_v, +template +INLINE LPoint3 LPoint3:: +rfu(NumType right_v, NumType fwd_v, NumType up_v, CoordinateSystem cs) { return origin(cs) + - FLOATNAME(LVector3)::rfu(right_v, fwd_v, up_v, cs); + LVector3::rfu(right_v, fwd_v, up_v, cs); } +//////////////////////////////////////////////////////////////////// +// Function: LPoint3::init_type +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +template +void LPoint3:: +init_type() { + if (_type_handle == TypeHandle::none()) { + LVecBase3::init_type(); + string name = + "LPoint3<" + get_type_handle(NumType).get_name() + ">"; + register_type(_type_handle, name, + LVecBase3::get_class_type()); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: lcast_to +// Description: Converts a vector from one numeric representation to +// another one. This is usually invoked using the macro +// LCAST. +//////////////////////////////////////////////////////////////////// +template +INLINE LPoint3 +lcast_to(NumType2 *, const LPoint3 &source) { + return LPoint3(source[0], source[1], source[2]); +} diff --git a/panda/src/linmath/lpoint3.h b/panda/src/linmath/lpoint3.h index 4719bb7983..07de1ab8c6 100644 --- a/panda/src/linmath/lpoint3.h +++ b/panda/src/linmath/lpoint3.h @@ -12,31 +12,74 @@ #include "lvecBase3.h" #include "lvector3.h" -#include "fltnames.I" +//////////////////////////////////////////////////////////////////// +// Class : LPoint3 +// Description : This is a three-component point in space (as opposed +// to a three-component vector, which represents a +// direction and a distance). Some of the methods are +// slightly different between LPoint3 and LVector3; in +// particular, subtraction of two points yields a +// vector, while addition of a vector and a point yields +// a point. +//////////////////////////////////////////////////////////////////// +template +class LPoint3 : public LVecBase3 { +PUBLISHED: + INLINE LPoint3(); + INLINE LPoint3(const LVecBase3 ©); + INLINE LPoint3 &operator = (const LVecBase3 ©); + INLINE LPoint3 &operator = (NumType fill_value); + INLINE LPoint3(NumType fill_value); + INLINE LPoint3(NumType x, NumType y, NumType z); + + INLINE static LPoint3 zero(); + INLINE static LPoint3 unit_x(); + INLINE static LPoint3 unit_y(); + INLINE static LPoint3 unit_z(); + + INLINE LPoint3 operator - () const; + + INLINE LVecBase3 + operator + (const LVecBase3 &other) const; + INLINE LPoint3 + operator + (const LVector3 &other) const; + + INLINE LVecBase3 + operator - (const LVecBase3 &other) const; + INLINE LVector3 + operator - (const LPoint3 &other) const; + INLINE LPoint3 + operator - (const LVector3 &other) const; + + INLINE LPoint3 cross(const LVecBase3 &other) const; + INLINE LPoint3 operator * (NumType scalar) const; + INLINE LPoint3 operator / (NumType scalar) const; + + // Some special named constructors for LPoint3. + + INLINE static LPoint3 origin(CoordinateSystem cs = CS_default); + INLINE static LPoint3 rfu(NumType right, + NumType fwd, + NumType up, + CoordinateSystem cs = CS_default); +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type(); + +private: + static TypeHandle _type_handle; +}; + +// Cast to a different numeric type +template +INLINE LPoint3 +lcast_to(NumType2 *type, const LPoint3 &source); + #include "lpoint3.I" -#include "dblnames.I" -#include "lpoint3.I" - - -//////////////////////////////////////////////////////////////////// -// Function: lcast_to -// Description: Converts a vector from one numeric representation to -// another one. This is usually invoked using the macro -// LCAST. -//////////////////////////////////////////////////////////////////// -INLINE FLOATNAME2(LPoint3) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LPoint3) &source) { - return FLOATNAME2(LPoint3)(source[0], source[1], source[2]); -} - -#include "fltnames.I" -INLINE FLOATNAME2(LPoint3) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LPoint3) &source) { - return FLOATNAME2(LPoint3)(source[0], source[1], source[2]); -} - - - +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LPoint3) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LPoint3) #endif diff --git a/panda/src/linmath/lpoint4.I b/panda/src/linmath/lpoint4.I index a73221f6d7..c1dd818c71 100644 --- a/panda/src/linmath/lpoint4.I +++ b/panda/src/linmath/lpoint4.I @@ -3,61 +3,17 @@ // //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Class : LPoint4 -// Description : This is a four-component point in space. -//////////////////////////////////////////////////////////////////// - -class EXPCL_PANDA FLOATNAME(LPoint4) : public FLOATNAME(LVecBase4) { -PUBLISHED: - INLINE FLOATNAME(LPoint4)(); - INLINE FLOATNAME(LPoint4)(const FLOATNAME(LVecBase4) ©); - INLINE FLOATNAME(LPoint4) &operator = (const FLOATNAME(LVecBase4) ©); - INLINE FLOATNAME(LPoint4) &operator = (FLOATTYPE1 fill_value); - INLINE FLOATNAME(LPoint4)(FLOATTYPE1 fill_value); - INLINE FLOATNAME(LPoint4)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w); - - INLINE static FLOATNAME(LPoint4) zero(); - INLINE static FLOATNAME(LPoint4) unit_x(); - INLINE static FLOATNAME(LPoint4) unit_y(); - INLINE static FLOATNAME(LPoint4) unit_z(); - INLINE static FLOATNAME(LPoint4) unit_w(); - - INLINE FLOATNAME(LPoint4) operator - () const; - - INLINE FLOATNAME(LVecBase4) - operator + (const FLOATNAME(LVecBase4) &other) const; - INLINE FLOATNAME(LPoint4) - operator + (const FLOATNAME(LVector4) &other) const; - - INLINE FLOATNAME(LVecBase4) - operator - (const FLOATNAME(LVecBase4) &other) const; - INLINE FLOATNAME(LVector4) - operator - (const FLOATNAME(LPoint4) &other) const; - INLINE FLOATNAME(LPoint4) - operator - (const FLOATNAME(LVector4) &other) const; - - INLINE FLOATNAME(LPoint4) operator * (FLOATTYPE1 scalar) const; - INLINE FLOATNAME(LPoint4) operator / (FLOATTYPE1 scalar) const; - -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type(); - -private: - static TypeHandle _type_handle; -}; +template +TypeHandle LPoint4::_type_handle; //////////////////////////////////////////////////////////////////// // Function: LPoint4::Default Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4):: -FLOATNAME(LPoint4)() { +template +INLINE LPoint4:: +LPoint4() { } //////////////////////////////////////////////////////////////////// @@ -65,9 +21,9 @@ FLOATNAME(LPoint4)() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4):: -FLOATNAME(LPoint4)(const FLOATNAME(LVecBase4) ©) : FLOATNAME(LVecBase4)(copy) { +template +INLINE LPoint4:: +LPoint4(const LVecBase4 ©) : LVecBase4(copy) { } //////////////////////////////////////////////////////////////////// @@ -75,10 +31,10 @@ FLOATNAME(LPoint4)(const FLOATNAME(LVecBase4) ©) : FLOATNAME(LVecBase4)(copy // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4) &FLOATNAME(LPoint4):: -operator = (const FLOATNAME(LVecBase4) ©) { - FLOATNAME(LVecBase4)::operator = (copy); +template +INLINE LPoint4 &LPoint4:: +operator = (const LVecBase4 ©) { + LVecBase4::operator = (copy); return *this; } @@ -87,10 +43,10 @@ operator = (const FLOATNAME(LVecBase4) ©) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4) &FLOATNAME(LPoint4):: -operator = (FLOATTYPE1 fill_value) { - FLOATNAME(LVecBase4)::operator = (fill_value); +template +INLINE LPoint4 &LPoint4:: +operator = (NumType fill_value) { + LVecBase4::operator = (fill_value); return *this; } @@ -99,10 +55,10 @@ operator = (FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4):: -FLOATNAME(LPoint4)(FLOATTYPE1 fill_value) : - FLOATNAME(LVecBase4)(fill_value) +template +INLINE LPoint4:: +LPoint4(NumType fill_value) : + LVecBase4(fill_value) { } @@ -111,10 +67,10 @@ FLOATNAME(LPoint4)(FLOATTYPE1 fill_value) : // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4):: -FLOATNAME(LPoint4)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w) : - FLOATNAME(LVecBase4)(x, y, z, w) +template +INLINE LPoint4:: +LPoint4(NumType x, NumType y, NumType z, NumType w) : + LVecBase4(x, y, z, w) { } @@ -123,10 +79,10 @@ FLOATNAME(LPoint4)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w) : // Access: Public // Description: Returns a zero point. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4):: +template +INLINE LPoint4 LPoint4:: zero() { - return FLOATNAME(LPoint4)(0.0, 0.0, 0.0, 0.0); + return LPoint4(0.0, 0.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -134,10 +90,10 @@ zero() { // Access: Public // Description: Returns a unit X point. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4):: +template +INLINE LPoint4 LPoint4:: unit_x() { - return FLOATNAME(LPoint4)(1.0, 0.0, 0.0, 0.0); + return LPoint4(1.0, 0.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -145,10 +101,10 @@ unit_x() { // Access: Public // Description: Returns a unit Y point. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4):: +template +INLINE LPoint4 LPoint4:: unit_y() { - return FLOATNAME(LPoint4)(0.0, 1.0, 0.0, 0.0); + return LPoint4(0.0, 1.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -156,10 +112,10 @@ unit_y() { // Access: Public // Description: Returns a unit Z point. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4):: +template +INLINE LPoint4 LPoint4:: unit_z() { - return FLOATNAME(LPoint4)(0.0, 0.0, 1.0, 0.0); + return LPoint4(0.0, 0.0, 1.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -167,10 +123,10 @@ unit_z() { // Access: Public // Description: Returns a unit W point. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4):: +template +INLINE LPoint4 LPoint4:: unit_w() { - return FLOATNAME(LPoint4)(0.0, 0.0, 0.0, 1.0); + return LPoint4(0.0, 0.0, 0.0, 1.0); } //////////////////////////////////////////////////////////////////// @@ -178,10 +134,10 @@ unit_w() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4):: +template +INLINE LPoint4 LPoint4:: operator - () const { - return FLOATNAME(LVecBase4)::operator - (); + return LVecBase4::operator - (); } //////////////////////////////////////////////////////////////////// @@ -189,10 +145,10 @@ operator - () const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LPoint4):: -operator + (const FLOATNAME(LVecBase4) &other) const { - return FLOATNAME(LVecBase4)::operator + (other); +template +INLINE LVecBase4 LPoint4:: +operator + (const LVecBase4 &other) const { + return LVecBase4::operator + (other); } //////////////////////////////////////////////////////////////////// @@ -200,10 +156,10 @@ operator + (const FLOATNAME(LVecBase4) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4):: -operator + (const FLOATNAME(LVector4) &other) const { - return FLOATNAME(LVecBase4)::operator + (other); +template +INLINE LPoint4 LPoint4:: +operator + (const LVector4 &other) const { + return LVecBase4::operator + (other); } //////////////////////////////////////////////////////////////////// @@ -211,10 +167,10 @@ operator + (const FLOATNAME(LVector4) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LPoint4):: -operator - (const FLOATNAME(LVecBase4) &other) const { - return FLOATNAME(LVecBase4)::operator - (other); +template +INLINE LVecBase4 LPoint4:: +operator - (const LVecBase4 &other) const { + return LVecBase4::operator - (other); } //////////////////////////////////////////////////////////////////// @@ -222,10 +178,10 @@ operator - (const FLOATNAME(LVecBase4) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4) FLOATNAME(LPoint4):: -operator - (const FLOATNAME(LPoint4) &other) const { - return FLOATNAME(LVecBase4)::operator - (other); +template +INLINE LVector4 LPoint4:: +operator - (const LPoint4 &other) const { + return LVecBase4::operator - (other); } //////////////////////////////////////////////////////////////////// @@ -233,10 +189,10 @@ operator - (const FLOATNAME(LPoint4) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4):: -operator - (const FLOATNAME(LVector4) &other) const { - return FLOATNAME(LVecBase4)::operator - (other); +template +INLINE LPoint4 LPoint4:: +operator - (const LVector4 &other) const { + return LVecBase4::operator - (other); } //////////////////////////////////////////////////////////////////// @@ -244,10 +200,10 @@ operator - (const FLOATNAME(LVector4) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4):: -operator * (FLOATTYPE1 scalar) const { - return FLOATNAME(LPoint4)(FLOATNAME(LVecBase4)::operator * (scalar)); +template +INLINE LPoint4 LPoint4:: +operator * (NumType scalar) const { + return LPoint4(LVecBase4::operator * (scalar)); } //////////////////////////////////////////////////////////////////// @@ -255,9 +211,37 @@ operator * (FLOATTYPE1 scalar) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4):: -operator / (FLOATTYPE1 scalar) const { - return FLOATNAME(LPoint4)(FLOATNAME(LVecBase4)::operator / (scalar)); +template +INLINE LPoint4 LPoint4:: +operator / (NumType scalar) const { + return LPoint4(LVecBase4::operator / (scalar)); } +//////////////////////////////////////////////////////////////////// +// Function: LPoint4::init_type +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +template +void LPoint4:: +init_type() { + if (_type_handle == TypeHandle::none()) { + LVecBase4::init_type(); + string name = + "LPoint4<" + get_type_handle(NumType).get_name() + ">"; + register_type(_type_handle, name, + LVecBase4::get_class_type()); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: lcast_to +// Description: Converts a vector from one numeric representation to +// another one. This is usually invoked using the macro +// LCAST. +//////////////////////////////////////////////////////////////////// +template +INLINE LPoint4 +lcast_to(NumType2 *, const LPoint4 &source) { + return LPoint4(source[0], source[1], source[2], source[3]); +} diff --git a/panda/src/linmath/lpoint4.h b/panda/src/linmath/lpoint4.h index 27e1a420c4..f0ddf00156 100644 --- a/panda/src/linmath/lpoint4.h +++ b/panda/src/linmath/lpoint4.h @@ -11,33 +11,61 @@ #include "lvecBase4.h" #include "lvector4.h" -#include "fltnames.I" +//////////////////////////////////////////////////////////////////// +// Class : LPoint4 +// Description : This is a four-component point in space. +//////////////////////////////////////////////////////////////////// +template +class LPoint4 : public LVecBase4 { +PUBLISHED: + INLINE LPoint4(); + INLINE LPoint4(const LVecBase4 ©); + INLINE LPoint4 &operator = (const LVecBase4 ©); + INLINE LPoint4 &operator = (NumType fill_value); + INLINE LPoint4(NumType fill_value); + INLINE LPoint4(NumType x, NumType y, NumType z, NumType w); + + INLINE static LPoint4 zero(); + INLINE static LPoint4 unit_x(); + INLINE static LPoint4 unit_y(); + INLINE static LPoint4 unit_z(); + INLINE static LPoint4 unit_w(); + + INLINE LPoint4 operator - () const; + + INLINE LVecBase4 + operator + (const LVecBase4 &other) const; + INLINE LPoint4 + operator + (const LVector4 &other) const; + + INLINE LVecBase4 + operator - (const LVecBase4 &other) const; + INLINE LVector4 + operator - (const LPoint4 &other) const; + INLINE LPoint4 + operator - (const LVector4 &other) const; + + INLINE LPoint4 operator * (NumType scalar) const; + INLINE LPoint4 operator / (NumType scalar) const; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type(); + +private: + static TypeHandle _type_handle; +}; + +// Cast to a different numeric type +template +INLINE LPoint4 +lcast_to(NumType2 *type, const LPoint4 &source); + #include "lpoint4.I" -#include "dblnames.I" -#include "lpoint4.I" - -//////////////////////////////////////////////////////////////////// -// Function: lcast_to -// Description: Converts a vector from one numeric representation to -// another one. This is usually invoked using the macro -// LCAST. -//////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME2(LPoint4) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LPoint4) &source) { - return FLOATNAME2(LPoint4)(source[0], source[1], source[2], source[3]); -} - -#include "fltnames.I" - -INLINE FLOATNAME2(LPoint4) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LPoint4) &source) { - return FLOATNAME2(LPoint4)(source[0], source[1], source[2], source[3]); -} - - -////EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LPoint4) -////EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LPoint4) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LPoint4) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LPoint4) #endif diff --git a/panda/src/linmath/lquaternion.I b/panda/src/linmath/lquaternion.I index 82f7ff22ab..e5e22d1f33 100644 --- a/panda/src/linmath/lquaternion.I +++ b/panda/src/linmath/lquaternion.I @@ -3,127 +3,82 @@ // //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Class : FLOATNAME(LQuaternionBase) -// Description : This is the base quaternion class -//////////////////////////////////////////////////////////////////// -class EXPCL_PANDA FLOATNAME(LQuaternionBase) { -protected: - INLINE FLOATNAME(LQuaternionBase) - multiply(const FLOATNAME(LQuaternionBase)&) const; - -PUBLISHED: - INLINE FLOATNAME(LQuaternionBase)(void); - INLINE FLOATNAME(LQuaternionBase)(const FLOATNAME(LQuaternionBase) &); - INLINE FLOATNAME(LQuaternionBase)(FLOATTYPE1, FLOATTYPE1, FLOATTYPE1, FLOATTYPE1); - virtual ~FLOATNAME(LQuaternionBase)(void); - - static FLOATNAME(LQuaternionBase) pure_imaginary(const FLOATNAME(LVector3) &); - - INLINE FLOATNAME(LQuaternionBase)& operator =(const FLOATNAME(LQuaternionBase) &); - INLINE bool operator ==(const FLOATNAME(LQuaternionBase) &) const; - INLINE bool operator !=(const FLOATNAME(LQuaternionBase) &) const; - - INLINE FLOATNAME(LQuaternionBase) operator *(const FLOATNAME(LQuaternionBase) &); - INLINE FLOATNAME(LQuaternionBase)& operator *=(const FLOATNAME(LQuaternionBase) &); - - INLINE FLOATNAME(LMatrix3) operator *(const FLOATNAME(LMatrix3) &); - INLINE FLOATNAME(LMatrix4) operator *(const FLOATNAME(LMatrix4) &); - - INLINE bool almost_equal(const FLOATNAME(LQuaternionBase) &, FLOATTYPE1) const; - INLINE bool almost_equal(const FLOATNAME(LQuaternionBase) &) const; - - INLINE void output(ostream&) const; - - INLINE void set(FLOATTYPE1, FLOATTYPE1, FLOATTYPE1, FLOATTYPE1); - - void set(const FLOATNAME(LMatrix3) &m); - INLINE void set(const FLOATNAME(LMatrix4) &m); - - void extract_to_matrix(FLOATNAME(LMatrix3) &m) const; - void extract_to_matrix(FLOATNAME(LMatrix4) &m) const; - - void set_hpr(const FLOATNAME(LVecBase3) &hpr); - FLOATNAME(LVecBase3) get_hpr() const; - - INLINE FLOATTYPE1 get_r(void) const; - INLINE FLOATTYPE1 get_i(void) const; - INLINE FLOATTYPE1 get_j(void) const; - INLINE FLOATTYPE1 get_k(void) const; - - INLINE void set_r(FLOATTYPE1 r); - INLINE void set_i(FLOATTYPE1 i); - INLINE void set_j(FLOATTYPE1 j); - INLINE void set_k(FLOATTYPE1 k); - - INLINE void normalize(void); - - static const FLOATNAME(LQuaternionBase) &ident_quat(void); - -private: - FLOATTYPE1 _r, _i, _j, _k; -public: - static TypeHandle get_class_type(void) { - return _type_handle; - } - static void init_type(void); -private: - static TypeHandle _type_handle; -}; - - -INLINE ostream& operator<<(ostream& os, const FLOATNAME(LQuaternionBase)& q) { - q.output(os); - return os; -} - -BEGIN_PUBLISH -INLINE FLOATNAME(LMatrix3) -operator * (const FLOATNAME(LMatrix3) &m, const FLOATNAME(LQuaternionBase) &q); -INLINE FLOATNAME(LMatrix4) -operator * (const FLOATNAME(LMatrix4) &m, const FLOATNAME(LQuaternionBase) &q); -END_PUBLISH +template +TypeHandle LQuaternionBase::_type_handle; //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::Default Constructor +// Function: LQuaternionBase::Default Constructor // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LQuaternionBase):: -FLOATNAME(LQuaternionBase)(void) { +template +INLINE LQuaternionBase:: +LQuaternionBase(void) { } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::Copy Constructor +// Function: LQuaternionBase::Copy Constructor // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LQuaternionBase):: -FLOATNAME(LQuaternionBase)(const FLOATNAME(LQuaternionBase)& c) : +template +INLINE LQuaternionBase:: +LQuaternionBase(const LQuaternionBase& c) : _r(c._r), _i(c._i), _j(c._j), _k(c._k) { } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::Constructor +// Function: LQuaternionBase::Constructor // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LQuaternionBase):: -FLOATNAME(LQuaternionBase)(FLOATTYPE1 r, FLOATTYPE1 i, FLOATTYPE1 j, FLOATTYPE1 k) { +template +INLINE LQuaternionBase:: +LQuaternionBase(NumType r, NumType i, NumType j, NumType k) { set(r, i, j, k); } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::set +// Function: LQuaternionBase::Destructor +// Access: public +// Description: +//////////////////////////////////////////////////////////////////// +template +LQuaternionBase:: +~LQuaternionBase() { +} + +//////////////////////////////////////////////////////////////////// +// Function: LQuaternionBase::pure_imaginary_quat +// Access: public +// Description: +//////////////////////////////////////////////////////////////////// +template +LQuaternionBase LQuaternionBase:: +pure_imaginary(const LVector3 &v) { + return LQuaternionBase(0, v[0], v[1], v[2]); +} + +//////////////////////////////////////////////////////////////////// +// Function: LQuaternionBase::ident_quat +// Access: public +// Description: +//////////////////////////////////////////////////////////////////// +template +const LQuaternionBase &LQuaternionBase:: +ident_quat(void) { + static LQuaternionBase q(1, 0, 0, 0); + return q; +} + +//////////////////////////////////////////////////////////////////// +// Function: LQuaternionBase::set // Access: public // Description: assignment //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LQuaternionBase):: -set(FLOATTYPE1 r, FLOATTYPE1 i, FLOATTYPE1 j, FLOATTYPE1 k) { +template +INLINE void LQuaternionBase:: +set(NumType r, NumType i, NumType j, NumType k) { _r = r; _i = i; _j = j; @@ -131,13 +86,13 @@ set(FLOATTYPE1 r, FLOATTYPE1 i, FLOATTYPE1 j, FLOATTYPE1 k) { } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::Assignment Operator +// Function: LQuaternionBase::Assignment Operator // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LQuaternionBase)& FLOATNAME(LQuaternionBase):: -operator =(const FLOATNAME(LQuaternionBase)& c) { +template +INLINE LQuaternionBase& LQuaternionBase:: +operator =(const LQuaternionBase& c) { _r = c._r; _i = c._i; _j = c._j; @@ -147,13 +102,13 @@ operator =(const FLOATNAME(LQuaternionBase)& c) { } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::Equality Operator +// Function: LQuaternionBase::Equality Operator // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LQuaternionBase):: -operator ==(const FLOATNAME(LQuaternionBase)& c) const { +template +INLINE bool LQuaternionBase:: +operator ==(const LQuaternionBase& c) const { return (_r == c._r && _i == c._i && _j == c._j && @@ -161,81 +116,81 @@ operator ==(const FLOATNAME(LQuaternionBase)& c) const { } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::Inequality Operator +// Function: LQuaternionBase::Inequality Operator // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LQuaternionBase):: -operator !=(const FLOATNAME(LQuaternionBase)& c) const { +template +INLINE bool LQuaternionBase:: +operator !=(const LQuaternionBase& c) const { return !operator==(c); } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::multiply +// Function: LQuaternionBase::multiply // Access: protected // Description: actual multiply call (non virtual) //////////////////////////////////////////////////////////////////// +template +INLINE LQuaternionBase LQuaternionBase:: +multiply(const LQuaternionBase& rhs) const { + NumType r = (_r * rhs._r) - (_i * rhs._i) - (_j * rhs._j) - (_k * rhs._k); + NumType i = (_i * rhs._r) + (_r * rhs._i) - (_k * rhs._j) + (_j * rhs._k); + NumType j = (_j * rhs._r) + (_k * rhs._i) + (_r * rhs._j) - (_i * rhs._k); + NumType k = (_k * rhs._r) - (_j * rhs._i) + (_i * rhs._j) + (_r * rhs._k); -INLINE FLOATNAME(LQuaternionBase) FLOATNAME(LQuaternionBase):: -multiply(const FLOATNAME(LQuaternionBase)& rhs) const { - FLOATTYPE1 r = (_r * rhs._r) - (_i * rhs._i) - (_j * rhs._j) - (_k * rhs._k); - FLOATTYPE1 i = (_i * rhs._r) + (_r * rhs._i) - (_k * rhs._j) + (_j * rhs._k); - FLOATTYPE1 j = (_j * rhs._r) + (_k * rhs._i) + (_r * rhs._j) - (_i * rhs._k); - FLOATTYPE1 k = (_k * rhs._r) - (_j * rhs._i) + (_i * rhs._j) + (_r * rhs._k); - - return FLOATNAME(LQuaternionBase)(r, i , j, k); + return LQuaternionBase(r, i , j, k); } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::Multiply Operator +// Function: LQuaternionBase::Multiply Operator // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LQuaternionBase) FLOATNAME(LQuaternionBase):: -operator *(const FLOATNAME(LQuaternionBase)& c) { +template +INLINE LQuaternionBase LQuaternionBase:: +operator *(const LQuaternionBase& c) { return multiply(c); } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::Multiply Assignment Operator +// Function: LQuaternionBase::Multiply Assignment Operator // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LQuaternionBase)& FLOATNAME(LQuaternionBase):: -operator *=(const FLOATNAME(LQuaternionBase)& c) { +template +INLINE LQuaternionBase& LQuaternionBase:: +operator *=(const LQuaternionBase& c) { (*this) = operator*(c); return *this; } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::Multiply Operator +// Function: LQuaternionBase::Multiply Operator // Access: public // Description: Quat * Matrix = matrix //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) FLOATNAME(LQuaternionBase):: -operator *(const FLOATNAME(LMatrix3) &m) { - FLOATNAME(LMatrix3) result; +template +INLINE LMatrix3 LQuaternionBase:: +operator *(const LMatrix3 &m) { + LMatrix3 result; extract_to_matrix(result); return result * m; } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::Multiply Operator +// Function: LQuaternionBase::Multiply Operator // Access: public // Description: Quat * Matrix = matrix //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) FLOATNAME(LQuaternionBase):: -operator *(const FLOATNAME(LMatrix4) &m) { - FLOATNAME(LMatrix3) m_upper_3 = m.get_upper_3(); - FLOATNAME(LMatrix3) this_quat; +template +INLINE LMatrix4 LQuaternionBase:: +operator *(const LMatrix4 &m) { + LMatrix3 m_upper_3 = m.get_upper_3(); + LMatrix3 this_quat; extract_to_matrix(this_quat); - FLOATNAME(LMatrix4) result; + LMatrix4 result; result.set_upper_3(this_quat * m_upper_3); result.set_row(3, m.get_row(3)); result.set_col(3, m.get_col(3)); @@ -244,14 +199,14 @@ operator *(const FLOATNAME(LMatrix4) &m) { } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::almost_equal +// Function: LQuaternionBase::almost_equal // Access: public // Description: Returns true if two quaternions are memberwise equal // within a specified tolerance. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LQuaternionBase):: -almost_equal(const FLOATNAME(LQuaternionBase)& c, FLOATTYPE1 threshold) const { +template +INLINE bool LQuaternionBase:: +almost_equal(const LQuaternionBase& c, NumType threshold) const { return (IS_THRESHOLD_EQUAL(_r, c._r, threshold) && IS_THRESHOLD_EQUAL(_i, c._i, threshold) && IS_THRESHOLD_EQUAL(_j, c._j, threshold) && @@ -259,24 +214,24 @@ almost_equal(const FLOATNAME(LQuaternionBase)& c, FLOATTYPE1 threshold) const { } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::almost_equal +// Function: LQuaternionBase::almost_equal // Access: public // Description: Returns true if two quaternions are memberwise equal // within a default tolerance based on the numeric type. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LQuaternionBase):: -almost_equal(const FLOATNAME(LQuaternionBase)& c) const { - return almost_equal(c, NEARLY_ZERO(FLOATTYPE1)); +template +INLINE bool LQuaternionBase:: +almost_equal(const LQuaternionBase& c) const { + return almost_equal(c, NEARLY_ZERO(NumType)); } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::output +// Function: LQuaternionBase::output // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LQuaternionBase):: +template +INLINE void LQuaternionBase:: output(ostream& os) const { os << MAYBE_ZERO(_r) << " + " << MAYBE_ZERO(_i) << "i + " @@ -285,102 +240,102 @@ output(ostream& os) const { } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::get_r +// Function: LQuaternionBase::get_r // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LQuaternionBase):: +template +INLINE NumType LQuaternionBase:: get_r(void) const { return _r; } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::get_i +// Function: LQuaternionBase::get_i // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LQuaternionBase):: +template +INLINE NumType LQuaternionBase:: get_i(void) const { return _i; } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::get_j +// Function: LQuaternionBase::get_j // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LQuaternionBase):: +template +INLINE NumType LQuaternionBase:: get_j(void) const { return _j; } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::get_k +// Function: LQuaternionBase::get_k // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LQuaternionBase):: +template +INLINE NumType LQuaternionBase:: get_k(void) const { return _k; } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::set_r +// Function: LQuaternionBase::set_r // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LQuaternionBase):: -set_r(FLOATTYPE1 r) { +template +INLINE void LQuaternionBase:: +set_r(NumType r) { _r = r; } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::set_i +// Function: LQuaternionBase::set_i // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LQuaternionBase):: -set_i(FLOATTYPE1 i) { +template +INLINE void LQuaternionBase:: +set_i(NumType i) { _i = i; } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::set_j +// Function: LQuaternionBase::set_j // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LQuaternionBase):: -set_j(FLOATTYPE1 j) { +template +INLINE void LQuaternionBase:: +set_j(NumType j) { _j = j; } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::set_k +// Function: LQuaternionBase::set_k // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LQuaternionBase):: -set_k(FLOATTYPE1 k) { +template +INLINE void LQuaternionBase:: +set_k(NumType k) { _k = k; } //////////////////////////////////////////////////////////////////// -// Function: FLOATNAME(LQuaternionBase)::normalize +// Function: LQuaternionBase::normalize // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LQuaternionBase):: +template +INLINE void LQuaternionBase:: normalize(void) { - FLOATTYPE1 l = csqrt((_r*_r)+(_i*_i)+(_j*_j)+(_k*_k)); + NumType l = csqrt((_r*_r)+(_i*_i)+(_j*_j)+(_k*_k)); if (l == 0.0) { _r = 0.; @@ -396,26 +351,222 @@ normalize(void) { } } +//////////////////////////////////////////////////////////////////// +// Function: set +// Access: public +// Description: Do-While Jones. +//////////////////////////////////////////////////////////////////// +template +void LQuaternionBase:: +set(const LMatrix3 &m) { + NumType m00 = m.get_cell(0, 0); + NumType m01 = m.get_cell(0, 1); + NumType m02 = m.get_cell(0, 2); + NumType m10 = m.get_cell(1, 0); + NumType m11 = m.get_cell(1, 1); + NumType m12 = m.get_cell(1, 2); + NumType m20 = m.get_cell(2, 0); + NumType m21 = m.get_cell(2, 1); + NumType m22 = m.get_cell(2, 2); + + NumType T = m00 + m11 + m22 + 1.; + + if (T > 0.) { + // the easy case + NumType S = 0.5 / csqrt(T); + _r = 0.25 / S; + _i = (m21 - m12) * S; + _j = (m02 - m20) * S; + _k = (m10 - m01) * S; + } else { + // figure out which column to take as root + int c = 0; + if (cabs(m00) > cabs(m11)) { + if (cabs(m00) > cabs(m22)) + c = 0; + else + c = 2; + } else if (cabs(m11) > cabs(m22)) + c = 1; + else + c = 2; + + NumType S; + + switch (c) { + case 0: + S = csqrt(1. + m00 - m11 - m22) * 2.; + _r = (m12 + m21) / S; + _i = 0.5 / S; + _j = (m01 + m10) / S; + _k = (m02 + m20) / S; + break; + case 1: + S = csqrt(1. + m11 - m00 - m22) * 2.; + _r = (m02 + m20) / S; + _i = (m01 + m10) / S; + _j = 0.5 / S; + _k = (m12 + m21) / S; + break; + case 2: + S = csqrt(1. + m22 - m00 - m11) * 2.; + _r = (m01 + m10) / S; + _i = (m02 + m20) / S; + _j = (m12 + m21) / S; + _k = 0.5 / S; + break; + } + } +} + //////////////////////////////////////////////////////////////////// // Function: set // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LQuaternionBase):: -set(const FLOATNAME(LMatrix4) &m) { +template +INLINE void LQuaternionBase:: +set(const LMatrix4 &m) { set(m.get_upper_3()); } +//////////////////////////////////////////////////////////////////// +// Function: extract (LMatrix3) +// Access: public +// Description: Do-While Jones paper from cary. +//////////////////////////////////////////////////////////////////// +template +void LQuaternionBase:: +extract_to_matrix(LMatrix3 &m) const { + NumType N = (_r * _r) + (_i * _i) + (_j * _j) + (_k * _k); + NumType s = (N == 0.) ? 0. : (2. / N); + NumType xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz; + + xs = _i * s; ys = _j * s; zs = _k * s; + wx = _r * xs; wy = _r * ys; wz = _r * zs; + xx = _i * xs; xy = _i * ys; xz = _i * zs; + yy = _j * ys; yz = _j * zs; zz = _k * zs; + + m = LMatrix3((1. - (yy + zz)), (xy - wz), (xz + wy), + (xy + wz), (1. - (xx + zz)), (yz - wx), + (xz - wy), (yz + wx), (1. - (xx + yy))); +} + +//////////////////////////////////////////////////////////////////// +// Function: extract (LMatrix4) +// Access: public +// Description: +//////////////////////////////////////////////////////////////////// +template +void LQuaternionBase:: +extract_to_matrix(LMatrix4 &m) const { + NumType N = (_r * _r) + (_i * _i) + (_j * _j) + (_k * _k); + NumType s = (N == 0.) ? 0. : (2. / N); + NumType xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz; + + xs = _i * s; ys = _j * s; zs = _k * s; + wx = _r * xs; wy = _r * ys; wz = _r * zs; + xx = _i * xs; xy = _i * ys; xz = _i * zs; + yy = _j * ys; yz = _j * zs; zz = _k * zs; + + m = LMatrix4((1. - (yy + zz)), (xy - wz), (xz + wy), 0., + (xy + wz), (1. - (xx + zz)), (yz - wx), 0., + (xz - wy), (yz + wx), (1. - (xx + yy)), 0., + 0., 0., 0., 1.); +} + +//////////////////////////////////////////////////////////////////// +// Function: set_hpr +// Access: public +// Description: Sets the quaternion as the unit quaternion that +// is equivalent to these Euler angles. +// (from Real-time Rendering, p.49) +//////////////////////////////////////////////////////////////////// +template +INLINE void LQuaternionBase:: +set_hpr(const LVecBase3 &hpr) { + LQuaternionBase quat_h, quat_p, quat_r; + + LVector3 v = LVector3::up(); + NumType a = deg_2_rad(hpr[0] * 0.5); + NumType s,c; + + csincos(a,&s,&c); + quat_h.set(c, v[0] * s, v[1] * s, v[2] * s); + v = LVector3::right(); + a = deg_2_rad(hpr[1] * 0.5); + csincos(a,&s,&c); + s = csin(a); + quat_p.set(c, v[0] * s, v[1] * s, v[2] * s); + v = LVector3::forward(); + a = deg_2_rad(hpr[2] * 0.5); + csincos(a,&s,&c); + quat_r.set(c, v[0] * s, v[1] * s, v[2] * s); + + (*this) = quat_h * quat_p * quat_r; +} + +//////////////////////////////////////////////////////////////////// +// Function: get_hpr +// Access: public +// Description: Extracts the equivalent Euler angles from the unit +// quaternion. +//////////////////////////////////////////////////////////////////// +template +INLINE LVecBase3 LQuaternionBase:: +get_hpr() const { + NumType heading, pitch, roll; + NumType N = (_r * _r) + (_i * _i) + (_j * _j) + (_k * _k); + NumType s = (N == 0.) ? 0. : (2. / N); + NumType xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz, c1, c2, c3, c4; + NumType cr, sr, cp, sp, ch, sh; + + xs = _i * s; ys = _j * s; zs = _k * s; + wx = _r * xs; wy = _r * ys; wz = _r * zs; + xx = _i * xs; xy = _i * ys; xz = _i * zs; + yy = _j * ys; yz = _j * zs; zz = _k * zs; + c1 = xz - wy; + c2 = 1. - (xx + yy); + c3 = 1. - (yy + zz); + c4 = xy + wz; + + if (c1 == 0.) { // (roll = 0 or 180) or (pitch = +/- 90 + if (c2 >= 0.) { + roll = 0.; + ch = c3; + sh = c4; + cp = c2; + } else { + roll = 180.; + ch = -c3; + sh = -c4; + cp = -c2; + } + } else { + // this should work all the time, but the above saves some trig operations + roll = catan2(-c1, c2); + csincos(roll,&sr,&cr); + roll = rad_2_deg(roll); + ch = (cr * c3) + (sr * (xz + wy)); + sh = (cr * c4) + (sr * (yz - wx)); + cp = (cr * c2) - (sr * c1); + } + sp = yz + wx; + heading = rad_2_deg(catan2(sh, ch)); + pitch = rad_2_deg(catan2(sp, cp)); + + return LVecBase3(heading, pitch, roll); +} + //////////////////////////////////////////////////////////////////// // Function: operator *(Matrix3, Quat) // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix3) operator *(const FLOATNAME(LMatrix3) &m, - const FLOATNAME(LQuaternionBase) &q) { - FLOATNAME(LMatrix3) q_matrix; +template +LMatrix3 operator *(const LMatrix3 &m, + const LQuaternionBase &q) { + LMatrix3 q_matrix; q.extract_to_matrix(q_matrix); return m * q_matrix; @@ -426,15 +577,15 @@ INLINE FLOATNAME(LMatrix3) operator *(const FLOATNAME(LMatrix3) &m, // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) operator *(const FLOATNAME(LMatrix4) &m, - const FLOATNAME(LQuaternionBase) &q) { - FLOATNAME(LMatrix4) q_matrix; +template +LMatrix4 operator *(const LMatrix4 &m, + const LQuaternionBase &q) { + LMatrix4 q_matrix; q.extract_to_matrix(q_matrix); // preserve the homogeneous coords and the translate - FLOATNAME(LVector4) m_row3 = m.get_row(3); - FLOATNAME(LVector4) m_col3 = m.get_col(3); + LVector4 m_row3 = m.get_row(3); + LVector4 m_col3 = m.get_col(3); q_matrix = m * q_matrix; q_matrix.set_row(3, m_row3); @@ -443,3 +594,30 @@ INLINE FLOATNAME(LMatrix4) operator *(const FLOATNAME(LMatrix4) &m, return q_matrix; } +//////////////////////////////////////////////////////////////////// +// Function: LQuaternionBase::init_type +// Access: public +// Description: +//////////////////////////////////////////////////////////////////// +template +void LQuaternionBase:: +init_type(void) { + if (_type_handle == TypeHandle::none()) { + do_init_type(NumType); + string name = "LQuaternionBase<" + get_type_handle(NumType).get_name() + + ">"; + register_type(_type_handle, name); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: lcast_to +// Description: Converts a quaternion from one numeric representation +// to another one. This is usually invoked using the +// macro LCAST. +//////////////////////////////////////////////////////////////////// +template +INLINE LQuaternionBase +lcast_to(NumType2 *, const LQuaternionBase& c) { + return LQuaternionBase(c.get_r(), c.get_i(), c.get_j(), c.get_k()); +} diff --git a/panda/src/linmath/lquaternion.h b/panda/src/linmath/lquaternion.h index de8154a0c3..86ecfc17b9 100644 --- a/panda/src/linmath/lquaternion.h +++ b/panda/src/linmath/lquaternion.h @@ -7,39 +7,117 @@ #define __LQUATERNION_H__ #include "lmatrix.h" -#include "lvector3.h" -#include "lvector4.h" #include "nearly_zero.h" #include "cmath.h" #include "deg_2_rad.h" #include -#include "fltnames.I" -#include "lquaternion.I" - -#include "dblnames.I" -#include "lquaternion.I" - //////////////////////////////////////////////////////////////////// -// Function: lcast_to -// Description: Converts a quaternion from one numeric representation -// to another one. This is usually invoked using the -// macro LCAST. +// Class : LQuaternionBase +// Description : This is the base quaternion class //////////////////////////////////////////////////////////////////// -INLINE FLOATNAME2(LQuaternionBase) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LQuaternionBase)& c) { - return FLOATNAME2(LQuaternionBase)(c.get_r(), c.get_i(), c.get_j(), c.get_k()); +template +class LQuaternionBase { +protected: + INLINE LQuaternionBase + multiply(const LQuaternionBase&) const; + +PUBLISHED: + INLINE LQuaternionBase(void); + INLINE LQuaternionBase(const LQuaternionBase &); + INLINE LQuaternionBase(NumType, NumType, NumType, NumType); + virtual ~LQuaternionBase(void); + + static LQuaternionBase pure_imaginary(const LVector3 &); + + INLINE LQuaternionBase& operator =(const LQuaternionBase &); + INLINE bool operator ==(const LQuaternionBase &) const; + INLINE bool operator !=(const LQuaternionBase &) const; + + INLINE LQuaternionBase operator *(const LQuaternionBase &); + INLINE LQuaternionBase& operator *=(const LQuaternionBase &); + + INLINE LMatrix3 operator *(const LMatrix3 &); + INLINE LMatrix4 operator *(const LMatrix4 &); + + INLINE bool almost_equal(const LQuaternionBase &, NumType) const; + INLINE bool almost_equal(const LQuaternionBase &) const; + + INLINE void output(ostream&) const; + + INLINE void set(NumType, NumType, NumType, NumType); + + void set(const LMatrix3 &m); + INLINE void set(const LMatrix4 &m); + + void extract_to_matrix(LMatrix3 &m) const; + void extract_to_matrix(LMatrix4 &m) const; + + INLINE void set_hpr(const LVecBase3 &hpr); + LVecBase3 get_hpr() const; + + INLINE NumType get_r(void) const; + INLINE NumType get_i(void) const; + INLINE NumType get_j(void) const; + INLINE NumType get_k(void) const; + + INLINE void set_r(NumType r); + INLINE void set_i(NumType i); + INLINE void set_j(NumType j); + INLINE void set_k(NumType k); + + INLINE void normalize(void); + + static const LQuaternionBase &ident_quat(void); + +private: + NumType _r, _i, _j, _k; +public: + static TypeHandle get_class_type(void) { + return _type_handle; + } + static void init_type(void); +private: + static TypeHandle _type_handle; +}; + +template +INLINE ostream& operator<<(ostream& os, const LQuaternionBase& q) { + q.output(os); + return os; } -#include "fltnames.I" -INLINE FLOATNAME2(LQuaternionBase) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LQuaternionBase)& c) { - return FLOATNAME2(LQuaternionBase)(c.get_r(), c.get_i(), c.get_j(), c.get_k()); -} +// matrix times quat +template +INLINE LMatrix3 +operator * (const LMatrix3 &m, const LQuaternionBase &q); +template +INLINE LMatrix4 +operator * (const LMatrix4 &m, const LQuaternionBase &q); +// pacify interrogate. +#ifdef CPPPARSER +BEGIN_PUBLISH +INLINE LMatrix3 +operator * (const LMatrix3 &m, const LQuaternionBase &q); +INLINE LMatrix4 +operator * (const LMatrix4 &m, const LQuaternionBase &q); +INLINE LMatrix3 +operator * (const LMatrix3 &m, const LQuaternionBase &q); +INLINE LMatrix4 +operator * (const LMatrix4 &m, const LQuaternionBase &q); +END_PUBLISH +#endif +// Cast to a different numeric type +template +INLINE LQuaternionBase lcast_to(NumType2*, const LQuaternionBase&); +#include "lquaternion.I" + +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LQuaternionBase) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LQuaternionBase) #endif /* __LQUATERNION_H__ */ diff --git a/panda/src/linmath/lrotation.I b/panda/src/linmath/lrotation.I index 1d2b9b3797..b324feae17 100644 --- a/panda/src/linmath/lrotation.I +++ b/panda/src/linmath/lrotation.I @@ -3,44 +3,17 @@ // //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -// Class : LRotation -// Description : This is a unit quaternion representing a rotation. -//////////////////////////////////////////////////////////////////////// -class EXPCL_PANDA FLOATNAME(LRotation) : public FLOATNAME(LQuaternionBase) { -PUBLISHED: - INLINE FLOATNAME(LRotation)(); - INLINE FLOATNAME(LRotation)(const FLOATNAME(LQuaternionBase)&); - INLINE FLOATNAME(LRotation)(FLOATTYPE1, FLOATTYPE1, FLOATTYPE1, FLOATTYPE1); - INLINE FLOATNAME(LRotation)(const FLOATNAME(LVector3) &, FLOATTYPE1); - INLINE FLOATNAME(LRotation)(const FLOATNAME(LMatrix3) &); - INLINE FLOATNAME(LRotation)(const FLOATNAME(LMatrix4) &); - INLINE FLOATNAME(LRotation)(FLOATTYPE1, FLOATTYPE1, FLOATTYPE1); - virtual ~FLOATNAME(LRotation)(); - - INLINE FLOATNAME(LRotation) - operator*(const FLOATNAME(LRotation)& other) const; - - INLINE FLOATNAME(LQuaternionBase) - operator*(const FLOATNAME(LQuaternionBase)& other) const; - -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type(); -private: - static TypeHandle _type_handle; -}; +template +TypeHandle LRotation::_type_handle; //////////////////////////////////////////////////////////////////// // Function: LRotation::Default Constructor // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LRotation):: -FLOATNAME(LRotation)() { +template +INLINE LRotation:: +LRotation() { } //////////////////////////////////////////////////////////////////// @@ -48,10 +21,10 @@ FLOATNAME(LRotation)() { // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LRotation):: -FLOATNAME(LRotation)(const FLOATNAME(LQuaternionBase)& c) : - FLOATNAME(LQuaternionBase)(c) { +template +INLINE LRotation:: +LRotation(const LQuaternionBase& c) : + LQuaternionBase(c) { } //////////////////////////////////////////////////////////////////// @@ -59,10 +32,10 @@ FLOATNAME(LRotation)(const FLOATNAME(LQuaternionBase)& c) : // Access: public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LRotation):: -FLOATNAME(LRotation)(FLOATTYPE1 r, FLOATTYPE1 i, FLOATTYPE1 j, FLOATTYPE1 k) : - FLOATNAME(LQuaternionBase)(r, i, j, k) { +template +INLINE LRotation:: +LRotation(NumType r, NumType i, NumType j, NumType k) : + LQuaternionBase(r, i, j, k) { } //////////////////////////////////////////////////////////////////// @@ -70,9 +43,9 @@ FLOATNAME(LRotation)(FLOATTYPE1 r, FLOATTYPE1 i, FLOATTYPE1 j, FLOATTYPE1 k) : // Access: public // Description: lmatrix3 //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LRotation):: -FLOATNAME(LRotation)(const FLOATNAME(LMatrix3) &m) { +template +INLINE LRotation:: +LRotation(const LMatrix3 &m) { set(m); } @@ -81,9 +54,9 @@ FLOATNAME(LRotation)(const FLOATNAME(LMatrix3) &m) { // Access: public // Description: lmatrix4 //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LRotation):: -FLOATNAME(LRotation)(const FLOATNAME(LMatrix4) &m) { +template +INLINE LRotation:: +LRotation(const LMatrix4 &m) { set(m); } @@ -92,12 +65,12 @@ FLOATNAME(LRotation)(const FLOATNAME(LMatrix4) &m) { // Access: public // Description: axis + angle (in degrees) //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LRotation):: -FLOATNAME(LRotation)(const FLOATNAME(LVector3) &axis, FLOATTYPE1 angle) { - FLOATTYPE1 radians = angle * ((FLOATTYPE1) MathNumbers::pi / (FLOATTYPE1)180.0); - FLOATTYPE1 theta_over_2 = radians / (FLOATTYPE1)2.0; - FLOATTYPE1 sin_to2 = csin(theta_over_2); +template +INLINE LRotation:: +LRotation(const LVector3 &axis, NumType angle) { + NumType radians = angle * ((NumType) MathNumbers::pi / (NumType)180.0); + NumType theta_over_2 = radians / (NumType)2.0; + NumType sin_to2 = csin(theta_over_2); set_r(ccos(theta_over_2)); set_i(axis[0] * sin_to2); @@ -110,10 +83,20 @@ FLOATNAME(LRotation)(const FLOATNAME(LVector3) &axis, FLOATTYPE1 angle) { // Access: public // Description: Sets the rotation from the given Euler angles. //////////////////////////////////////////////////////////////////// +template +INLINE LRotation:: +LRotation(NumType h, NumType p, NumType r) { + set_hpr(LVecBase3(h, p, r)); +} -INLINE FLOATNAME(LRotation):: -FLOATNAME(LRotation)(FLOATTYPE1 h, FLOATTYPE1 p, FLOATTYPE1 r) { - set_hpr(FLOATNAME(LVecBase3)(h, p, r)); +//////////////////////////////////////////////////////////////////// +// Function: LRotation::Destructor +// Access: public +// Description: +//////////////////////////////////////////////////////////////////// +template +LRotation:: +~LRotation() { } //////////////////////////////////////////////////////////////////// @@ -121,9 +104,9 @@ FLOATNAME(LRotation)(FLOATTYPE1 h, FLOATTYPE1 p, FLOATTYPE1 r) { // Access: public // Description: Rotation * Rotation = Rotation //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LRotation) FLOATNAME(LRotation):: -operator*(const FLOATNAME(LRotation)& other) const { +template +INLINE LRotation LRotation:: +operator*(const LRotation& other) const { return multiply(other); } @@ -135,10 +118,25 @@ operator*(const FLOATNAME(LRotation)& other) const { // to apply an orientation to a rotation. It simply // returns the rhs. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LQuaternionBase) FLOATNAME(LRotation):: -operator*(const FLOATNAME(LQuaternionBase)& other) const { +template +INLINE LQuaternionBase LRotation:: +operator*(const LQuaternionBase& other) const { return other; } - +//////////////////////////////////////////////////////////////////// +// Function: LRotation::init_type +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +template +void LRotation:: +init_type() { + if (_type_handle == TypeHandle::none()) { + // Format a string to describe the type. + do_init_type(NumType); + string name = + "LRotation<" + get_type_handle(NumType).get_name() + ">"; + register_type(_type_handle, name); + } +} diff --git a/panda/src/linmath/lrotation.h b/panda/src/linmath/lrotation.h index 335e0df7a1..766ac0f8a8 100644 --- a/panda/src/linmath/lrotation.h +++ b/panda/src/linmath/lrotation.h @@ -12,13 +12,40 @@ #include -#include "fltnames.I" +//////////////////////////////////////////////////////////////////////// +// Class : LRotation +// Description : This is a unit quaternion representing a rotation. +//////////////////////////////////////////////////////////////////////// +template +class LRotation : public LQuaternionBase { +PUBLISHED: + INLINE LRotation(); + INLINE LRotation(const LQuaternionBase&); + INLINE LRotation(NumType, NumType, NumType, NumType); + INLINE LRotation(const LVector3 &, NumType); + INLINE LRotation(const LMatrix3 &); + INLINE LRotation(const LMatrix4 &); + INLINE LRotation(NumType, NumType, NumType); + virtual ~LRotation(); + + INLINE LRotation + operator*(const LRotation& other) const; + + INLINE LQuaternionBase + operator*(const LQuaternionBase& other) const; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type(); +private: + static TypeHandle _type_handle; +}; + #include "lrotation.I" -#include "dblnames.I" -#include "lrotation.I" - - - +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LRotation) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LRotation) #endif /* __LROTATION_H__ */ diff --git a/panda/src/linmath/luse.N b/panda/src/linmath/luse.N index 64a96301dd..182014e3f1 100644 --- a/panda/src/linmath/luse.N +++ b/panda/src/linmath/luse.N @@ -1,44 +1,85 @@ +forcetype LVecBase2 +forcetype LVecBase3 +forcetype LVecBase4 -renametype LPoint2f LPoint2f -renametype LPoint3f LPoint3f -renametype LPoint4f LPoint4f -renametype LPoint2d LPoint2d -renametype LPoint3d LPoint3d -renametype LPoint4d LPoint4d +forcetype LPoint2 +forcetype LPoint3 +forcetype LPoint4 +forcetype LVector2 +forcetype LVector3 +forcetype LVector4 -renametype LVecBase2f LVecBase2f -renametype LVecBase3f LVecBase3f -renametype LVecBase4f LVecBase4f -renametype LVecBase2d LVecBase2d -renametype LVecBase3d LVecBase3d -renametype LVecBase4d LVecBase4d +forcetype LMatrix3 +forcetype LMatrix4 -renametype LVector2f LVector2f -renametype LVector3f LVector3f -renametype LVector4f LVector4f -renametype LVector2d LVector2d -renametype LVector3d LVector3d -renametype LVector4d LVector4d +forcetype LPoint2f +forcetype LPoint3f +forcetype LPoint4f -renametype LMatrix3f LMatrix3f -renametype LMatrix4f LMatrix4f -renametype LMatrix3d LMatrix3d -renametype LMatrix4d LMatrix4d +forcetype LVector2f +forcetype LVector3f +forcetype LVector4f -renametype LQuaternionf LQuaternionf -renametype LRotationf LRotationf -renametype LOrientationf LOrientationf +forcetype Vertexf +forcetype Normalf +forcetype TexCoordf +forcetype Colorf +forcetype RGBColorf -renametype LQuaterniond LQuaterniond -renametype LRotationd LRotationd -renametype LOrientationd LOrientationd +forcetype LMatrix3f +forcetype LMatrix4f + +forcetype LVecBase2 +forcetype LVecBase3 +forcetype LVecBase4 + +forcetype LPoint2 +forcetype LPoint3 +forcetype LPoint4 +forcetype LVector2 +forcetype LVector3 +forcetype LVector4 + +forcetype LMatrix3 +forcetype LMatrix4 + +forcetype LPoint2d +forcetype LPoint3d +forcetype LPoint4d + +forcetype LVector2d +forcetype LVector3d +forcetype LVector4d + +forcetype Vertexd +forcetype Normald +forcetype TexCoordd +forcetype Colord +forcetype RGBColord + +forcetype LMatrix3d +forcetype LMatrix4d + +forcetype LQuaternionBase +forcetype LQuaternionBase +forcetype LRotation +forcetype LRotation +forcetype LOrientation +forcetype LOrientation + +forcetype LQuaternionf +forcetype LRotationf +forcetype LOrientationf +forcetype LQuaterniond +forcetype LRotationd +forcetype LOrientationd forcetype PTA_Vertexf -renametype PTA_Vertexf PTA_Vertexf forcetype PTA_Normalf -renametype PTA_Normalf PTA_Normalf forcetype PTA_TexCoordf -renametype PTA_TexCoordf PTA_TexCoordf forcetype PTA_Colorf -renametype PTA_Colorf PTA_Colorf +renametype PTA_Vertexf PTA_Vertexf +renametype PTA_Normalf PTA_Normalf +renametype PTA_TexCoordf PTA_TexCoordf +renametype PTA_Colorf PTA_Colorf diff --git a/panda/src/linmath/luse.h b/panda/src/linmath/luse.h index 2c352580c6..e626faa63a 100644 --- a/panda/src/linmath/luse.h +++ b/panda/src/linmath/luse.h @@ -12,12 +12,12 @@ // designed for specific uses. These all inherit from LVecBase, which // is the base class of all linear algebra vectors. // -// LPoint +// LPoint // // This should be used to represent a specific point in space. It // inherits most properties from LVecBase. // -// LVector +// LVector // // This should be used to represent a vector, or a distance between // two points in space. @@ -37,11 +37,11 @@ // // This file also defines the following: // -// Vertex, Vertexd, Vertexf -// Normal, Normald, Normalf -// TexCoord, TexCoordd, TexCoordf -// Color, Colord, Colorf -// RGBColor, RGBColord, RGBColorf +// Vertex, Vertexd, Vertexf +// Normal, Normald, Normalf +// TexCoord, TexCoordd, TexCoordf +// Color, Colord, Colorf +// RGBColor, RGBColord, RGBColorf // // These classes are derivations of LPoint or LVector, as appropriate, // and are intended to store a specific kind of rendering attribute. @@ -74,7 +74,7 @@ // Now we define some handy typedefs for these classes. -/* + typedef LVecBase2 LVecBase2f; typedef LVecBase3 LVecBase3f; typedef LVecBase4 LVecBase4f; @@ -85,13 +85,13 @@ typedef LVector4 LVector4f; typedef LPoint2 LPoint2f; typedef LPoint3 LPoint3f; typedef LPoint4 LPoint4f; -*/ + typedef LPoint3f Vertexf; typedef LVector3f Normalf; typedef LPoint2f TexCoordf; typedef LVecBase4f Colorf; typedef LVecBase3f RGBColorf; -/* + typedef LVecBase2 LVecBase2d; typedef LVecBase3 LVecBase3d; typedef LVecBase4 LVecBase4d; @@ -102,16 +102,13 @@ typedef LVector4 LVector4d; typedef LPoint2 LPoint2d; typedef LPoint3 LPoint3d; typedef LPoint4 LPoint4d; -*/ + typedef LPoint3d Vertexd; typedef LVector3d Normald; typedef LPoint2d TexCoordd; typedef LVecBase4d Colord; typedef LVecBase3d RGBColord; -typedef LQuaternionBasef LQuaternionf; -typedef LQuaternionBased LQuaterniond; -/* typedef LQuaternionBase LQuaternionf; typedef LRotation LRotationf; typedef LOrientation LOrientationf; @@ -119,7 +116,7 @@ typedef LOrientation LOrientationf; typedef LQuaternionBase LQuaterniond; typedef LRotation LRotationd; typedef LOrientation LOrientationd; -*/ + /* // Now define explicit instantiations of the output operator functions // for interrogate's benefit. These functions don't actually exist diff --git a/panda/src/linmath/lvec2_ops.I b/panda/src/linmath/lvec2_ops.I index 65d09f89f0..d63fd182c0 100644 --- a/panda/src/linmath/lvec2_ops.I +++ b/panda/src/linmath/lvec2_ops.I @@ -3,49 +3,17 @@ // //////////////////////////////////////////////////////////////////// -// When possible, operators have been defined within the classes. -// This file defines operator functions outside of classes where -// necessary. It also defines some convenient out-of-class wrappers -// around in-class functions (like dot, length, normalize). +#include - -// scalar * vec (vec * scalar is defined in class) - -INLINE FLOATNAME(LVecBase2) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LVecBase2) &a); - - -INLINE FLOATNAME(LPoint2) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LPoint2) &a); - - -INLINE FLOATNAME(LVector2) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LVector2) &a); - - -// dot product - -INLINE FLOATTYPE1 -dot(const FLOATNAME(LVecBase2) &a, const FLOATNAME(LVecBase2) &b); - - -// Length of a vector. - -INLINE FLOATTYPE1 -length(const FLOATNAME(LVector2) &a); - - -// A normalized vector. - -INLINE FLOATNAME(LVector2) -normalize(const FLOATNAME(LVector2) &v); +#include "nearly_zero.h" //////////////////////////////////////////////////////////////////// // Function: scalar * LVecBase2 // Description: //////////////////////////////////////////////////////////////////// -INLINE FLOATNAME(LVecBase2) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LVecBase2) &a) { +template +INLINE LVecBase2 +operator * (NumType2 scalar, const LVecBase2 &a) { return a * scalar; } @@ -53,8 +21,9 @@ operator * (FLOATTYPE2 scalar, const FLOATNAME(LVecBase2) &a) { // Function: scalar * LPoint2 // Description: //////////////////////////////////////////////////////////////////// -INLINE FLOATNAME(LPoint2) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LPoint2) &a) { +template +INLINE LPoint2 +operator * (NumType2 scalar, const LPoint2 &a) { return a * scalar; } @@ -62,8 +31,9 @@ operator * (FLOATTYPE2 scalar, const FLOATNAME(LPoint2) &a) { // Function: scalar * LVector2 // Description: //////////////////////////////////////////////////////////////////// -INLINE FLOATNAME(LVector2) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LVector2) &a) { +template +INLINE LVector2 +operator * (NumType2 scalar, const LVector2 &a) { return a * scalar; } @@ -71,19 +41,39 @@ operator * (FLOATTYPE2 scalar, const FLOATNAME(LVector2) &a) { // Function: dot product of LVecBase2 // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 -dot(const FLOATNAME(LVecBase2) &a, const FLOATNAME(LVecBase2) &b) { +template +INLINE NumType +dot(const LVecBase2 &a, const LVecBase2 &b) { return a.dot(b); } +//////////////////////////////////////////////////////////////////// +// Function: cross product of LVecBase2 +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE LVecBase2 +cross(const LVecBase2 &a, const LVecBase2 &b) { + return a.cross(b); +} + +//////////////////////////////////////////////////////////////////// +// Function: cross product of LVector2 +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE LVector2 +cross(const LVector2 &a, const LVector2 &b) { + return LVector2(a.cross(b)); +} + //////////////////////////////////////////////////////////////////// // Function: length of a vector // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 -length(const FLOATNAME(LVector2) &a) { +template +INLINE NumType +length(const LVector2 &a) { return a.length(); } @@ -92,10 +82,10 @@ length(const FLOATNAME(LVector2) &a) { // Function: normalize // Description: Returns a normalized vector from the given vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2) -normalize(const FLOATNAME(LVector2) &v) { - FLOATNAME(LVector2) v1 = v; +template +INLINE LVector2 +normalize(const LVector2 &v) { + LVector2 v1 = v; v1.normalize(); return v1; } diff --git a/panda/src/linmath/lvec2_ops.h b/panda/src/linmath/lvec2_ops.h index 3f51126072..07ada43cd4 100644 --- a/panda/src/linmath/lvec2_ops.h +++ b/panda/src/linmath/lvec2_ops.h @@ -6,16 +6,49 @@ #ifndef LVEC2_OPS_H #define LVEC2_OPS_H -#include -#include "nearly_zero.h" #include "lvecBase2.h" #include "lpoint2.h" #include "lvector2.h" -#include "fltnames.I" -#include "lvec2_ops.I" +// When possible, operators have been defined within the classes. +// This file defines operator functions outside of classes where +// necessary. It also defines some convenient out-of-class wrappers +// around in-class functions (like dot, length, normalize). + + +// scalar * vec (vec * scalar is defined in class) +template +INLINE LVecBase2 +operator * (NumType2 scalar, const LVecBase2 &a); + +template +INLINE LPoint2 +operator * (NumType2 scalar, const LPoint2 &a); + +template +INLINE LVector2 +operator * (NumType2 scalar, const LVector2 &a); + + +// dot product +template +INLINE NumType +dot(const LVecBase2 &a, const LVecBase2 &b); + + +// Length of a vector. +template +INLINE NumType +length(const LVector2 &a); + + +// A normalized vector. +template +INLINE LVector2 +normalize(const LVector2 &v); + + -#include "dblnames.I" #include "lvec2_ops.I" #endif diff --git a/panda/src/linmath/lvec3_ops.I b/panda/src/linmath/lvec3_ops.I index e33686c132..1e0d1ef116 100644 --- a/panda/src/linmath/lvec3_ops.I +++ b/panda/src/linmath/lvec3_ops.I @@ -3,60 +3,17 @@ // //////////////////////////////////////////////////////////////////// -// When possible, operators have been defined within the classes. -// This file defines operator functions outside of classes where -// necessary. It also defines some convenient out-of-class wrappers -// around in-class functions (like dot, length, normalize). - - -// scalar * vec (vec * scalar is defined in class) - -INLINE FLOATNAME(LVecBase3) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LVecBase3) &a); - - -INLINE FLOATNAME(LPoint3) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LPoint3) &a); - - -INLINE FLOATNAME(LVector3) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LVector3) &a); - - -// dot product - -INLINE FLOATTYPE1 -dot(const FLOATNAME(LVecBase3) &a, const FLOATNAME(LVecBase3) &b); - - -// cross product - -INLINE FLOATNAME(LVecBase3) -cross(const FLOATNAME(LVecBase3) &a, const FLOATNAME(LVecBase3) &b); - - -INLINE FLOATNAME(LVector3) -cross(const FLOATNAME(LVector3) &a, const FLOATNAME(LVector3) &b); - - -// Length of a vector. - -INLINE FLOATTYPE1 -length(const FLOATNAME(LVector3) &a); - - -// A normalized vector. - -INLINE FLOATNAME(LVector3) -normalize(const FLOATNAME(LVector3) &v); +#include +#include "nearly_zero.h" //////////////////////////////////////////////////////////////////// // Function: scalar * LVecBase3 // Description: //////////////////////////////////////////////////////////////////// -INLINE FLOATNAME(LVecBase3) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LVecBase3) &a) { +template +INLINE LVecBase3 +operator * (NumType2 scalar, const LVecBase3 &a) { return a * scalar; } @@ -64,8 +21,9 @@ operator * (FLOATTYPE2 scalar, const FLOATNAME(LVecBase3) &a) { // Function: scalar * LPoint3 // Description: //////////////////////////////////////////////////////////////////// -INLINE FLOATNAME(LPoint3) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LPoint3) &a) { +template +INLINE LPoint3 +operator * (NumType2 scalar, const LPoint3 &a) { return a * scalar; } @@ -73,8 +31,9 @@ operator * (FLOATTYPE2 scalar, const FLOATNAME(LPoint3) &a) { // Function: scalar * LVector3 // Description: //////////////////////////////////////////////////////////////////// -INLINE FLOATNAME(LVector3) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LVector3) &a) { +template +INLINE LVector3 +operator * (NumType2 scalar, const LVector3 &a) { return a * scalar; } @@ -82,9 +41,9 @@ operator * (FLOATTYPE2 scalar, const FLOATNAME(LVector3) &a) { // Function: dot product of LVecBase3 // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 -dot(const FLOATNAME(LVecBase3) &a, const FLOATNAME(LVecBase3) &b) { +template +INLINE NumType +dot(const LVecBase3 &a, const LVecBase3 &b) { return a.dot(b); } @@ -92,9 +51,9 @@ dot(const FLOATNAME(LVecBase3) &a, const FLOATNAME(LVecBase3) &b) { // Function: cross product of LVecBase3 // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) -cross(const FLOATNAME(LVecBase3) &a, const FLOATNAME(LVecBase3) &b) { +template +INLINE LVecBase3 +cross(const LVecBase3 &a, const LVecBase3 &b) { return a.cross(b); } @@ -102,10 +61,10 @@ cross(const FLOATNAME(LVecBase3) &a, const FLOATNAME(LVecBase3) &b) { // Function: cross product of LVector3 // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) -cross(const FLOATNAME(LVector3) &a, const FLOATNAME(LVector3) &b) { - return FLOATNAME(LVector3)(a.cross(b)); +template +INLINE LVector3 +cross(const LVector3 &a, const LVector3 &b) { + return LVector3(a.cross(b)); } @@ -113,9 +72,9 @@ cross(const FLOATNAME(LVector3) &a, const FLOATNAME(LVector3) &b) { // Function: length of a vector // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 -length(const FLOATNAME(LVector3) &a) { +template +INLINE NumType +length(const LVector3 &a) { return a.length(); } @@ -124,10 +83,10 @@ length(const FLOATNAME(LVector3) &a) { // Function: normalize // Description: Returns a normalized vector from the given vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) -normalize(const FLOATNAME(LVector3) &v) { - FLOATNAME(LVector3) v1 = v; +template +INLINE LVector3 +normalize(const LVector3 &v) { + LVector3 v1 = v; v1.normalize(); return v1; } diff --git a/panda/src/linmath/lvec3_ops.h b/panda/src/linmath/lvec3_ops.h index a094cec8c3..3330e380d7 100644 --- a/panda/src/linmath/lvec3_ops.h +++ b/panda/src/linmath/lvec3_ops.h @@ -6,17 +6,59 @@ #ifndef LVEC3_OPS_H #define LVEC3_OPS_H -#include -#include "nearly_zero.h" #include "lvecBase3.h" #include "lpoint3.h" #include "lvector3.h" -#include "fltnames.I" -#include "lvec3_ops.I" +// When possible, operators have been defined within the classes. +// This file defines operator functions outside of classes where +// necessary. It also defines some convenient out-of-class wrappers +// around in-class functions (like dot, length, normalize). -#include "dblnames.I" -#include "lvec3_ops.I" +// scalar * vec (vec * scalar is defined in class) +template +INLINE LVecBase3 +operator * (NumType2 scalar, const LVecBase3 &a); + +template +INLINE LPoint3 +operator * (NumType2 scalar, const LPoint3 &a); + +template +INLINE LVector3 +operator * (NumType2 scalar, const LVector3 &a); + + +// dot product +template +INLINE NumType +dot(const LVecBase3 &a, const LVecBase3 &b); + + +// cross product +template +INLINE LVecBase3 +cross(const LVecBase3 &a, const LVecBase3 &b); + +template +INLINE LVector3 +cross(const LVector3 &a, const LVector3 &b); + + +// Length of a vector. +template +INLINE NumType +length(const LVector3 &a); + + +// A normalized vector. +template +INLINE LVector3 +normalize(const LVector3 &v); + + + +#include "lvec3_ops.I" #endif diff --git a/panda/src/linmath/lvec4_ops.I b/panda/src/linmath/lvec4_ops.I index 37b1385dfb..9ffc7ee191 100644 --- a/panda/src/linmath/lvec4_ops.I +++ b/panda/src/linmath/lvec4_ops.I @@ -3,50 +3,17 @@ // //////////////////////////////////////////////////////////////////// -// When possible, operators have been defined within the classes. -// This file defines operator functions outside of classes where -// necessary. It also defines some convenient out-of-class wrappers -// around in-class functions (like dot, length, normalize). - - -// scalar * vec (vec * scalar is defined in class) - -INLINE FLOATNAME(LVecBase4) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LVecBase4) &a); - - -INLINE FLOATNAME(LPoint4) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LPoint4) &a); - - -INLINE FLOATNAME(LVector4) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LVector4) &a); - - -// dot product - -INLINE FLOATTYPE1 -dot(const FLOATNAME(LVecBase4) &a, const FLOATNAME(LVecBase4) &b); - - -// Length of a vector. - -INLINE FLOATTYPE1 -length(const FLOATNAME(LVector4) &a); - - -// A normalized vector. - -INLINE FLOATNAME(LVector4) -normalize(const FLOATNAME(LVector4) &v); +#include +#include "nearly_zero.h" //////////////////////////////////////////////////////////////////// // Function: scalar * LVecBase4 // Description: //////////////////////////////////////////////////////////////////// -INLINE FLOATNAME(LVecBase4) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LVecBase4) &a) { +template +INLINE LVecBase4 +operator * (NumType2 scalar, const LVecBase4 &a) { return a * scalar; } @@ -54,8 +21,9 @@ operator * (FLOATTYPE2 scalar, const FLOATNAME(LVecBase4) &a) { // Function: scalar * LPoint4 // Description: //////////////////////////////////////////////////////////////////// -INLINE FLOATNAME(LPoint4) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LPoint4) &a) { +template +INLINE LPoint4 +operator * (NumType2 scalar, const LPoint4 &a) { return a * scalar; } @@ -63,8 +31,9 @@ operator * (FLOATTYPE2 scalar, const FLOATNAME(LPoint4) &a) { // Function: scalar * LVector4 // Description: //////////////////////////////////////////////////////////////////// -INLINE FLOATNAME(LVector4) -operator * (FLOATTYPE2 scalar, const FLOATNAME(LVector4) &a) { +template +INLINE LVector4 +operator * (NumType2 scalar, const LVector4 &a) { return a * scalar; } @@ -72,9 +41,9 @@ operator * (FLOATTYPE2 scalar, const FLOATNAME(LVector4) &a) { // Function: dot product of LVecBase4 // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 -dot(const FLOATNAME(LVecBase4) &a, const FLOATNAME(LVecBase4) &b) { +template +INLINE NumType +dot(const LVecBase4 &a, const LVecBase4 &b) { return a.dot(b); } @@ -82,9 +51,9 @@ dot(const FLOATNAME(LVecBase4) &a, const FLOATNAME(LVecBase4) &b) { // Function: length of a vector // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 -length(const FLOATNAME(LVector4) &a) { +template +INLINE NumType +length(const LVector4 &a) { return a.length(); } @@ -93,10 +62,10 @@ length(const FLOATNAME(LVector4) &a) { // Function: normalize // Description: Returns a normalized vector from the given vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4) -normalize(const FLOATNAME(LVector4) &v) { - FLOATNAME(LVector4) v1 = v; +template +INLINE LVector4 +normalize(const LVector4 &v) { + LVector4 v1 = v; v1.normalize(); return v1; } diff --git a/panda/src/linmath/lvec4_ops.h b/panda/src/linmath/lvec4_ops.h index 0ace83c970..cd46d676c8 100644 --- a/panda/src/linmath/lvec4_ops.h +++ b/panda/src/linmath/lvec4_ops.h @@ -6,17 +6,49 @@ #ifndef LVEC4_OPS_H #define LVEC4_OPS_H -#include -#include "nearly_zero.h" #include "lvecBase4.h" #include "lpoint4.h" #include "lvector4.h" -#include "fltnames.I" -#include "lvec4_ops.I" +// When possible, operators have been defined within the classes. +// This file defines operator functions outside of classes where +// necessary. It also defines some convenient out-of-class wrappers +// around in-class functions (like dot, length, normalize). -#include "dblnames.I" -#include "lvec4_ops.I" +// scalar * vec (vec * scalar is defined in class) +template +INLINE LVecBase4 +operator * (NumType2 scalar, const LVecBase4 &a); + +template +INLINE LPoint4 +operator * (NumType2 scalar, const LPoint4 &a); + +template +INLINE LVector4 +operator * (NumType2 scalar, const LVector4 &a); + + +// dot product +template +INLINE NumType +dot(const LVecBase4 &a, const LVecBase4 &b); + + +// Length of a vector. +template +INLINE NumType +length(const LVector4 &a); + + +// A normalized vector. +template +INLINE LVector4 +normalize(const LVector4 &v); + + + +#include "lvec4_ops.I" #endif diff --git a/panda/src/linmath/lvecBase2.I b/panda/src/linmath/lvecBase2.I index 487be1be89..52717507fd 100644 --- a/panda/src/linmath/lvecBase2.I +++ b/panda/src/linmath/lvecBase2.I @@ -3,119 +3,23 @@ // //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Class : LVecBase2 -// Description : This is the base class for all two-component -// vectors and points. -//////////////////////////////////////////////////////////////////// +#include "nearly_zero.h" -class EXPCL_PANDA FLOATNAME(LVecBase2) { -PUBLISHED: - typedef const FLOATTYPE1 *iterator; - typedef const FLOATTYPE1 *const_iterator; +#include +#include +#include - INLINE FLOATNAME(LVecBase2)(); - INLINE FLOATNAME(LVecBase2)(const FLOATNAME(LVecBase2) ©); - INLINE FLOATNAME(LVecBase2) &operator = (const FLOATNAME(LVecBase2) ©); - INLINE FLOATNAME(LVecBase2) &operator = (FLOATTYPE1 fill_value); - INLINE FLOATNAME(LVecBase2)(FLOATTYPE1 fill_value); - INLINE FLOATNAME(LVecBase2)(FLOATTYPE1 x, FLOATTYPE1 y); - - INLINE static FLOATNAME(LVecBase2) zero(); - INLINE static FLOATNAME(LVecBase2) unit_x(); - INLINE static FLOATNAME(LVecBase2) unit_y(); - - INLINE ~FLOATNAME(LVecBase2)(); - - INLINE FLOATTYPE1 operator [](int i) const; - INLINE FLOATTYPE1 &operator [](int i); - - INLINE bool is_nan() const; - - INLINE FLOATTYPE1 get_cell(int i) const; - INLINE FLOATTYPE1 get_x() const; - INLINE FLOATTYPE1 get_y() const; - INLINE void set_cell(int i, FLOATTYPE1 value); - INLINE void set_x(FLOATTYPE1 value); - INLINE void set_y(FLOATTYPE1 value); - - INLINE const FLOATTYPE1 *get_data() const; - INLINE int get_num_components() const; - -public: - INLINE iterator begin(); - INLINE iterator end(); - - INLINE const_iterator begin() const; - INLINE const_iterator end() const; - -PUBLISHED: - INLINE void fill(FLOATTYPE1 fill_value); - INLINE void set(FLOATTYPE1 x, FLOATTYPE1 y); - - INLINE FLOATTYPE1 dot(const FLOATNAME(LVecBase2) &other) const; - - INLINE bool operator < (const FLOATNAME(LVecBase2) &other) const; - INLINE bool operator == (const FLOATNAME(LVecBase2) &other) const; - INLINE bool operator != (const FLOATNAME(LVecBase2) &other) const; - - INLINE int compare_to(const FLOATNAME(LVecBase2) &other) const; - INLINE int compare_to(const FLOATNAME(LVecBase2) &other, - FLOATTYPE1 threshold) const; - - INLINE FLOATNAME(LVecBase2) operator - () const; - - INLINE FLOATNAME(LVecBase2) - operator + (const FLOATNAME(LVecBase2) &other) const; - INLINE FLOATNAME(LVecBase2) - operator - (const FLOATNAME(LVecBase2) &other) const; - - INLINE FLOATNAME(LVecBase2) operator * (FLOATTYPE1 scalar) const; - INLINE FLOATNAME(LVecBase2) operator / (FLOATTYPE1 scalar) const; - - INLINE void operator += (const FLOATNAME(LVecBase2) &other); - INLINE void operator -= (const FLOATNAME(LVecBase2) &other); - - INLINE void operator *= (FLOATTYPE1 scalar); - INLINE void operator /= (FLOATTYPE1 scalar); - - INLINE bool almost_equal(const FLOATNAME(LVecBase2) &other, - FLOATTYPE1 threshold) const; - INLINE bool almost_equal(const FLOATNAME(LVecBase2) &other) const; - - INLINE void output(ostream &out) const; - -private: - FLOATTYPE1 _data[2]; - -public: - INLINE void write_datagram(Datagram &destination) const; - INLINE void read_datagram(DatagramIterator &source); - -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type(); - -private: - static TypeHandle _type_handle; -}; - - -INLINE ostream &operator << (ostream &out, const FLOATNAME(LVecBase2) &vec) { - vec.output(out); - return out; -} +template +TypeHandle LVecBase2::_type_handle; //////////////////////////////////////////////////////////////////// // Function: LVecBase2::Default Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2):: -FLOATNAME(LVecBase2)() { +template +INLINE LVecBase2:: +LVecBase2() { } //////////////////////////////////////////////////////////////////// @@ -123,9 +27,9 @@ FLOATNAME(LVecBase2)() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2):: -FLOATNAME(LVecBase2)(const FLOATNAME(LVecBase2) ©) { +template +INLINE LVecBase2:: +LVecBase2(const LVecBase2 ©) { (*this) = copy; } @@ -134,9 +38,9 @@ FLOATNAME(LVecBase2)(const FLOATNAME(LVecBase2) ©) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) &FLOATNAME(LVecBase2):: -operator = (const FLOATNAME(LVecBase2) ©) { +template +INLINE LVecBase2 &LVecBase2:: +operator = (const LVecBase2 ©) { set(copy[0], copy[1]); return *this; } @@ -146,9 +50,9 @@ operator = (const FLOATNAME(LVecBase2) ©) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) &FLOATNAME(LVecBase2):: -operator = (FLOATTYPE1 fill_value) { +template +INLINE LVecBase2 &LVecBase2:: +operator = (NumType fill_value) { fill(fill_value); return *this; } @@ -158,9 +62,9 @@ operator = (FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2):: -FLOATNAME(LVecBase2)(FLOATTYPE1 fill_value) { +template +INLINE LVecBase2:: +LVecBase2(NumType fill_value) { fill(fill_value); } @@ -169,9 +73,9 @@ FLOATNAME(LVecBase2)(FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2):: -FLOATNAME(LVecBase2)(FLOATTYPE1 x, FLOATTYPE1 y) { +template +INLINE LVecBase2:: +LVecBase2(NumType x, NumType y) { set(x, y); } @@ -180,10 +84,10 @@ FLOATNAME(LVecBase2)(FLOATTYPE1 x, FLOATTYPE1 y) { // Access: Public // Description: Returns a zero-length vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2):: +template +INLINE LVecBase2 LVecBase2:: zero() { - return FLOATNAME(LVecBase2)(0.0, 0.0); + return LVecBase2(0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -191,10 +95,10 @@ zero() { // Access: Public // Description: Returns a unit X vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2):: +template +INLINE LVecBase2 LVecBase2:: unit_x() { - return FLOATNAME(LVecBase2)(1.0, 0.0); + return LVecBase2(1.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -202,10 +106,10 @@ unit_x() { // Access: Public // Description: Returns a unit Y vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2):: +template +INLINE LVecBase2 LVecBase2:: unit_y() { - return FLOATNAME(LVecBase2)(0.0, 1.0); + return LVecBase2(0.0, 1.0); } //////////////////////////////////////////////////////////////////// @@ -213,9 +117,9 @@ unit_y() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2):: -~FLOATNAME(LVecBase2)() { +template +INLINE LVecBase2:: +~LVecBase2() { } //////////////////////////////////////////////////////////////////// @@ -223,8 +127,8 @@ INLINE FLOATNAME(LVecBase2):: // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase2):: +template +INLINE NumType LVecBase2:: operator [](int i) const { nassertr(i >= 0 && i < 2, 0); return _data[i]; @@ -235,8 +139,8 @@ operator [](int i) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 &FLOATNAME(LVecBase2):: +template +INLINE NumType &LVecBase2:: operator [](int i) { nassertr(i >= 0 && i < 2, _data[0]); return _data[i]; @@ -248,8 +152,8 @@ operator [](int i) { // Description: Returns true if any component of the vector is // not-a-number, false otherwise. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase2):: +template +INLINE bool LVecBase2:: is_nan() const { return cnan(_data[0]) || cnan(_data[1]); } @@ -259,8 +163,8 @@ is_nan() const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase2):: +template +INLINE NumType LVecBase2:: get_cell(int i) const { nassertr(i >= 0 && i < 2, 0); return _data[i]; @@ -271,8 +175,8 @@ get_cell(int i) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase2):: +template +INLINE NumType LVecBase2:: get_x() const { return _data[0]; } @@ -282,8 +186,8 @@ get_x() const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase2):: +template +INLINE NumType LVecBase2:: get_y() const { return _data[1]; } @@ -293,9 +197,9 @@ get_y() const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase2):: -set_cell(int i, FLOATTYPE1 value) { +template +INLINE void LVecBase2:: +set_cell(int i, NumType value) { nassertv(i >= 0 && i < 2); _data[i] = value; } @@ -305,9 +209,9 @@ set_cell(int i, FLOATTYPE1 value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase2):: -set_x(FLOATTYPE1 value) { +template +INLINE void LVecBase2:: +set_x(NumType value) { _data[0] = value; } @@ -316,9 +220,9 @@ set_x(FLOATTYPE1 value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase2):: -set_y(FLOATTYPE1 value) { +template +INLINE void LVecBase2:: +set_y(NumType value) { _data[1] = value; } @@ -329,8 +233,8 @@ set_y(FLOATTYPE1 value) { // elements in the vector. The next element // occupies the next position consecutively in memory. //////////////////////////////////////////////////////////////////// - -INLINE const FLOATTYPE1 *FLOATNAME(LVecBase2):: +template +INLINE const NumType *LVecBase2:: get_data() const { return _data; } @@ -340,8 +244,8 @@ get_data() const { // Access: Public // Description: Returns the number of elements in the vector, two. //////////////////////////////////////////////////////////////////// - -INLINE int FLOATNAME(LVecBase2):: +template +INLINE int LVecBase2:: get_num_components() const { return 2; } @@ -352,8 +256,8 @@ get_num_components() const { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2)::iterator FLOATNAME(LVecBase2):: +template +INLINE LVecBase2::iterator LVecBase2:: begin() { return _data; } @@ -364,8 +268,8 @@ begin() { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2)::iterator FLOATNAME(LVecBase2):: +template +INLINE LVecBase2::iterator LVecBase2:: end() { return begin() + get_num_components(); } @@ -376,8 +280,8 @@ end() { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2)::const_iterator FLOATNAME(LVecBase2):: +template +INLINE LVecBase2::const_iterator LVecBase2:: begin() const { return _data; } @@ -388,8 +292,8 @@ begin() const { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2)::const_iterator FLOATNAME(LVecBase2):: +template +INLINE LVecBase2::const_iterator LVecBase2:: end() const { return begin() + get_num_components(); } @@ -401,9 +305,9 @@ end() const { // fill_value. This is particularly useful for // initializing to zero. //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase2):: -fill(FLOATTYPE1 fill_value) { +template +INLINE void LVecBase2:: +fill(NumType fill_value) { _data[0] = fill_value; _data[1] = fill_value; } @@ -413,9 +317,9 @@ fill(FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase2):: -set(FLOATTYPE1 x, FLOATTYPE1 y) { +template +INLINE void LVecBase2:: +set(NumType x, NumType y) { _data[0] = x; _data[1] = y; } @@ -425,9 +329,9 @@ set(FLOATTYPE1 x, FLOATTYPE1 y) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase2):: -dot(const FLOATNAME(LVecBase2) &other) const { +template +INLINE NumType LVecBase2:: +dot(const LVecBase2 &other) const { return _data[0] * other[0] + _data[1] * other[1]; } @@ -440,9 +344,9 @@ dot(const FLOATNAME(LVecBase2) &other) const { // especially in an STL container. Also see // compare_to(). //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase2):: -operator < (const FLOATNAME(LVecBase2) &other) const { +template +INLINE bool LVecBase2:: +operator < (const LVecBase2 &other) const { return (compare_to(other) < 0); } @@ -451,9 +355,9 @@ operator < (const FLOATNAME(LVecBase2) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase2):: -operator == (const FLOATNAME(LVecBase2) &other) const { +template +INLINE bool LVecBase2:: +operator == (const LVecBase2 &other) const { return (_data[0] == other[0] && _data[1] == other[1]); } @@ -463,9 +367,9 @@ operator == (const FLOATNAME(LVecBase2) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase2):: -operator != (const FLOATNAME(LVecBase2) &other) const { +template +INLINE bool LVecBase2:: +operator != (const LVecBase2 &other) const { return !operator == (other); } @@ -475,10 +379,10 @@ operator != (const FLOATNAME(LVecBase2) &other) const { // Description: This flavor of compare_to uses a default threshold // value based on the numeric type. //////////////////////////////////////////////////////////////////// - -INLINE int FLOATNAME(LVecBase2):: -compare_to(const FLOATNAME(LVecBase2) &other) const { - return compare_to(other, NEARLY_ZERO(FLOATTYPE1)); +template +INLINE int LVecBase2:: +compare_to(const LVecBase2 &other) const { + return compare_to(other, NEARLY_ZERO(NumType)); } //////////////////////////////////////////////////////////////////// @@ -490,9 +394,9 @@ compare_to(const FLOATNAME(LVecBase2) &other) const { // after, 0 if they are equivalent (within the indicated // tolerance). //////////////////////////////////////////////////////////////////// - -INLINE int FLOATNAME(LVecBase2):: -compare_to(const FLOATNAME(LVecBase2) &other, FLOATTYPE1 threshold) const { +template +INLINE int LVecBase2:: +compare_to(const LVecBase2 &other, NumType threshold) const { if (!IS_THRESHOLD_EQUAL(_data[0], other[0], threshold)) { return (_data[0] < other[0]) ? -1 : 1; } @@ -507,10 +411,10 @@ compare_to(const FLOATNAME(LVecBase2) &other, FLOATTYPE1 threshold) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2):: +template +INLINE LVecBase2 LVecBase2:: operator - () const { - return FLOATNAME(LVecBase2)(-_data[0], -_data[1]); + return LVecBase2(-_data[0], -_data[1]); } //////////////////////////////////////////////////////////////////// @@ -518,10 +422,10 @@ operator - () const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2):: -operator + (const FLOATNAME(LVecBase2) &other) const { - return FLOATNAME(LVecBase2)(_data[0] + other[0], +template +INLINE LVecBase2 LVecBase2:: +operator + (const LVecBase2 &other) const { + return LVecBase2(_data[0] + other[0], _data[1] + other[1]); } @@ -530,10 +434,10 @@ operator + (const FLOATNAME(LVecBase2) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2):: -operator - (const FLOATNAME(LVecBase2) &other) const { - return FLOATNAME(LVecBase2)(_data[0] - other[0], +template +INLINE LVecBase2 LVecBase2:: +operator - (const LVecBase2 &other) const { + return LVecBase2(_data[0] - other[0], _data[1] - other[1]); } @@ -542,10 +446,10 @@ operator - (const FLOATNAME(LVecBase2) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2):: -operator * (FLOATTYPE1 scalar) const { - return FLOATNAME(LVecBase2)(_data[0] * scalar, +template +INLINE LVecBase2 LVecBase2:: +operator * (NumType scalar) const { + return LVecBase2(_data[0] * scalar, _data[1] * scalar); } @@ -554,10 +458,10 @@ operator * (FLOATTYPE1 scalar) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2):: -operator / (FLOATTYPE1 scalar) const { - return FLOATNAME(LVecBase2)(_data[0] / scalar, +template +INLINE LVecBase2 LVecBase2:: +operator / (NumType scalar) const { + return LVecBase2(_data[0] / scalar, _data[1] / scalar); } @@ -566,9 +470,9 @@ operator / (FLOATTYPE1 scalar) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase2):: -operator += (const FLOATNAME(LVecBase2) &other) { +template +INLINE void LVecBase2:: +operator += (const LVecBase2 &other) { _data[0] += other[0]; _data[1] += other[1]; } @@ -578,9 +482,9 @@ operator += (const FLOATNAME(LVecBase2) &other) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase2):: -operator -= (const FLOATNAME(LVecBase2) &other) { +template +INLINE void LVecBase2:: +operator -= (const LVecBase2 &other) { _data[0] -= other[0]; _data[1] -= other[1]; } @@ -590,9 +494,9 @@ operator -= (const FLOATNAME(LVecBase2) &other) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase2):: -operator *= (FLOATTYPE1 scalar) { +template +INLINE void LVecBase2:: +operator *= (NumType scalar) { _data[0] *= scalar; _data[1] *= scalar; } @@ -602,9 +506,9 @@ operator *= (FLOATTYPE1 scalar) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase2):: -operator /= (FLOATTYPE1 scalar) { +template +INLINE void LVecBase2:: +operator /= (NumType scalar) { _data[0] /= scalar; _data[1] /= scalar; } @@ -615,9 +519,9 @@ operator /= (FLOATTYPE1 scalar) { // Description: Returns true if two vectors are memberwise equal // within a specified tolerance. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase2):: -almost_equal(const FLOATNAME(LVecBase2) &other, FLOATTYPE1 threshold) const { +template +INLINE bool LVecBase2:: +almost_equal(const LVecBase2 &other, NumType threshold) const { return (IS_THRESHOLD_EQUAL(_data[0], other[0], threshold) && IS_THRESHOLD_EQUAL(_data[1], other[1], threshold)); } @@ -628,10 +532,10 @@ almost_equal(const FLOATNAME(LVecBase2) &other, FLOATTYPE1 threshold) const { // Description: Returns true if two vectors are memberwise equal // within a default tolerance based on the numeric type. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase2):: -almost_equal(const FLOATNAME(LVecBase2) &other) const { - return almost_equal(other, NEARLY_ZERO(FLOATTYPE1)); +template +INLINE bool LVecBase2:: +almost_equal(const LVecBase2 &other) const { + return almost_equal(other, NEARLY_ZERO(NumType)); } //////////////////////////////////////////////////////////////////// @@ -639,20 +543,37 @@ almost_equal(const FLOATNAME(LVecBase2) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase2):: +template +INLINE void LVecBase2:: output(ostream &out) const { out << MAYBE_ZERO(_data[0]) << " " << MAYBE_ZERO(_data[1]); } +//////////////////////////////////////////////////////////////////// +// Function: LVecBase2::init_type +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +template +void LVecBase2:: +init_type() { + if (_type_handle == TypeHandle::none()) { + // Format a string to describe the type. + do_init_type(NumType); + string name = + "LVecBase2<" + get_type_handle(NumType).get_name() + ">"; + register_type(_type_handle, name); + } +} + //////////////////////////////////////////////////////////////////// // Function: LVecBase2::write_datagram // Access: Public // Description: Function to write itself into a datagram //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase2):: +template +void LVecBase2:: write_datagram(Datagram &destination) const { destination.add_float32(_data[0]); destination.add_float32(_data[1]); @@ -663,12 +584,21 @@ write_datagram(Datagram &destination) const { // Access: Public // Description: Function to read itself from a datagramIterator //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase2):: +template +void LVecBase2:: read_datagram(DatagramIterator &source) { _data[0] = source.get_float32(); _data[1] = source.get_float32(); } - - +//////////////////////////////////////////////////////////////////// +// Function: lcast_to +// Description: Converts a vector from one numeric representation to +// another one. This is usually invoked using the macro +// LCAST. +//////////////////////////////////////////////////////////////////// +template +INLINE LVecBase2 +lcast_to(NumType2 *, const LVecBase2 &source) { + return LVecBase2(source[0], source[1]); +} diff --git a/panda/src/linmath/lvecBase2.h b/panda/src/linmath/lvecBase2.h index bd834c35af..77c9c8e376 100644 --- a/panda/src/linmath/lvecBase2.h +++ b/panda/src/linmath/lvecBase2.h @@ -7,40 +7,129 @@ #define LVECBASE2_H #include -#include -#include -#include -#include + #include "cmath.h" -#include "nearly_zero.h" + +#include class Datagram; class DatagramIterator; -#include "fltnames.I" -#include "lvecBase2.I" - -#include "dblnames.I" -#include "lvecBase2.I" - //////////////////////////////////////////////////////////////////// -// Function: lcast_to -// Description: Converts a vector from one numeric representation to -// another one. This is usually invoked using the macro -// LCAST. +// Class : LVecBase2 +// Description : This is the base class for all two-component +// vectors and points. //////////////////////////////////////////////////////////////////// -INLINE FLOATNAME2(LVecBase2) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LVecBase2) &source) { - return FLOATNAME2(LVecBase2)(source[0], source[1]); -} +template +class LVecBase2 { +PUBLISHED: + typedef const NumType *iterator; + typedef const NumType *const_iterator; -#include "fltnames.I" -INLINE FLOATNAME2(LVecBase2) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LVecBase2) &source) { - return FLOATNAME2(LVecBase2)(source[0], source[1]); + INLINE LVecBase2(); + INLINE LVecBase2(const LVecBase2 ©); + INLINE LVecBase2 &operator = (const LVecBase2 ©); + INLINE LVecBase2 &operator = (NumType fill_value); + INLINE LVecBase2(NumType fill_value); + INLINE LVecBase2(NumType x, NumType y); + + INLINE static LVecBase2 zero(); + INLINE static LVecBase2 unit_x(); + INLINE static LVecBase2 unit_y(); + + INLINE ~LVecBase2(); + + INLINE NumType operator [](int i) const; + INLINE NumType &operator [](int i); + + INLINE bool is_nan() const; + + INLINE NumType get_cell(int i) const; + INLINE NumType get_x() const; + INLINE NumType get_y() const; + INLINE void set_cell(int i, NumType value); + INLINE void set_x(NumType value); + INLINE void set_y(NumType value); + + INLINE const NumType *get_data() const; + INLINE int get_num_components() const; + +public: + INLINE iterator begin(); + INLINE iterator end(); + + INLINE const_iterator begin() const; + INLINE const_iterator end() const; + +PUBLISHED: + INLINE void fill(NumType fill_value); + INLINE void set(NumType x, NumType y); + + INLINE NumType dot(const LVecBase2 &other) const; + + INLINE bool operator < (const LVecBase2 &other) const; + INLINE bool operator == (const LVecBase2 &other) const; + INLINE bool operator != (const LVecBase2 &other) const; + + INLINE int compare_to(const LVecBase2 &other) const; + INLINE int compare_to(const LVecBase2 &other, + NumType threshold) const; + + INLINE LVecBase2 + operator - () const; + + INLINE LVecBase2 + operator + (const LVecBase2 &other) const; + INLINE LVecBase2 + operator - (const LVecBase2 &other) const; + + INLINE LVecBase2 operator * (NumType scalar) const; + INLINE LVecBase2 operator / (NumType scalar) const; + + INLINE void operator += (const LVecBase2 &other); + INLINE void operator -= (const LVecBase2 &other); + + INLINE void operator *= (NumType scalar); + INLINE void operator /= (NumType scalar); + + INLINE bool almost_equal(const LVecBase2 &other, + NumType threshold) const; + INLINE bool almost_equal(const LVecBase2 &other) const; + + INLINE void output(ostream &out) const; + +private: + NumType _data[2]; + +public: + INLINE void write_datagram(Datagram &destination) const; + INLINE void read_datagram(DatagramIterator &source); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type(); + +private: + static TypeHandle _type_handle; +}; + +template +INLINE ostream &operator << (ostream &out, const LVecBase2 &vec) { + vec.output(out); + return out; } +// Cast to a different numeric type +template +INLINE LVecBase2 +lcast_to(NumType2 *type, const LVecBase2 &source); +#include "lvecBase2.I" + +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVecBase2) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVecBase2) #endif diff --git a/panda/src/linmath/lvecBase3.I b/panda/src/linmath/lvecBase3.I index aa69e4cc36..c69fd85da8 100644 --- a/panda/src/linmath/lvecBase3.I +++ b/panda/src/linmath/lvecBase3.I @@ -3,125 +3,23 @@ // //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Class : LVecBase3 -// Description : This is the base class for all three-component -// vectors and points. -//////////////////////////////////////////////////////////////////// +#include "nearly_zero.h" -class EXPCL_PANDA FLOATNAME(LVecBase3) { -PUBLISHED: - typedef const FLOATTYPE1 *iterator; - typedef const FLOATTYPE1 *const_iterator; +#include +#include +#include - INLINE FLOATNAME(LVecBase3)(); - INLINE FLOATNAME(LVecBase3)(const FLOATNAME(LVecBase3) ©); - INLINE FLOATNAME(LVecBase3) &operator = (const FLOATNAME(LVecBase3) ©); - INLINE FLOATNAME(LVecBase3) &operator = (FLOATTYPE1 fill_value); - INLINE FLOATNAME(LVecBase3)(FLOATTYPE1 fill_value); - INLINE FLOATNAME(LVecBase3)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z); - - INLINE static FLOATNAME(LVecBase3) zero(); - INLINE static FLOATNAME(LVecBase3) unit_x(); - INLINE static FLOATNAME(LVecBase3) unit_y(); - INLINE static FLOATNAME(LVecBase3) unit_z(); - - INLINE ~FLOATNAME(LVecBase3)(); - - INLINE FLOATTYPE1 operator [](int i) const; - INLINE FLOATTYPE1 &operator [](int i); - - INLINE bool is_nan() const; - - INLINE FLOATTYPE1 get_cell(int i) const; - INLINE FLOATTYPE1 get_x() const; - INLINE FLOATTYPE1 get_y() const; - INLINE FLOATTYPE1 get_z() const; - INLINE void set_cell(int i, FLOATTYPE1 value); - INLINE void set_x(FLOATTYPE1 value); - INLINE void set_y(FLOATTYPE1 value); - INLINE void set_z(FLOATTYPE1 value); - - INLINE const FLOATTYPE1 *get_data() const; - INLINE int get_num_components() const; - -public: - INLINE iterator begin(); - INLINE iterator end(); - - INLINE const_iterator begin() const; - INLINE const_iterator end() const; - -PUBLISHED: - INLINE void fill(FLOATTYPE1 fill_value); - INLINE void set(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z); - - INLINE FLOATTYPE1 dot(const FLOATNAME(LVecBase3) &other) const; - INLINE FLOATNAME(LVecBase3) cross(const FLOATNAME(LVecBase3) &other) const; - - INLINE bool operator < (const FLOATNAME(LVecBase3) &other) const; - INLINE bool operator == (const FLOATNAME(LVecBase3) &other) const; - INLINE bool operator != (const FLOATNAME(LVecBase3) &other) const; - - INLINE int compare_to(const FLOATNAME(LVecBase3) &other) const; - INLINE int compare_to(const FLOATNAME(LVecBase3) &other, - FLOATTYPE1 threshold) const; - - INLINE FLOATNAME(LVecBase3) operator - () const; - - INLINE FLOATNAME(LVecBase3) - operator + (const FLOATNAME(LVecBase3) &other) const; - INLINE FLOATNAME(LVecBase3) - operator - (const FLOATNAME(LVecBase3) &other) const; - - INLINE FLOATNAME(LVecBase3) operator * (FLOATTYPE1 scalar) const; - INLINE FLOATNAME(LVecBase3) operator / (FLOATTYPE1 scalar) const; - - INLINE void operator += (const FLOATNAME(LVecBase3) &other); - INLINE void operator -= (const FLOATNAME(LVecBase3) &other); - - INLINE void operator *= (FLOATTYPE1 scalar); - INLINE void operator /= (FLOATTYPE1 scalar); - - INLINE void cross_into(const FLOATNAME(LVecBase3) &other); - - INLINE bool almost_equal(const FLOATNAME(LVecBase3) &other, - FLOATTYPE1 threshold) const; - INLINE bool almost_equal(const FLOATNAME(LVecBase3) &other) const; - - INLINE void output(ostream &out) const; - -private: - FLOATTYPE1 _data[3]; - -public: - INLINE void write_datagram(Datagram &destination) const; - INLINE void read_datagram(DatagramIterator &source); - -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type(); - -private: - static TypeHandle _type_handle; -}; - - -INLINE ostream &operator << (ostream &out, const FLOATNAME(LVecBase3) &vec) { - vec.output(out); - return out; -}; +template +TypeHandle LVecBase3::_type_handle; //////////////////////////////////////////////////////////////////// // Function: LVecBase3::Default Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3):: -FLOATNAME(LVecBase3)() { +template +INLINE LVecBase3:: +LVecBase3() { } //////////////////////////////////////////////////////////////////// @@ -129,9 +27,9 @@ FLOATNAME(LVecBase3)() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3):: -FLOATNAME(LVecBase3)(const FLOATNAME(LVecBase3) ©) { +template +INLINE LVecBase3:: +LVecBase3(const LVecBase3 ©) { (*this) = copy; } @@ -140,9 +38,9 @@ FLOATNAME(LVecBase3)(const FLOATNAME(LVecBase3) ©) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) &FLOATNAME(LVecBase3):: -operator = (const FLOATNAME(LVecBase3) ©) { +template +INLINE LVecBase3 &LVecBase3:: +operator = (const LVecBase3 ©) { set(copy[0], copy[1], copy[2]); return *this; } @@ -152,9 +50,9 @@ operator = (const FLOATNAME(LVecBase3) ©) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) &FLOATNAME(LVecBase3):: -operator = (FLOATTYPE1 fill_value) { +template +INLINE LVecBase3 &LVecBase3:: +operator = (NumType fill_value) { fill(fill_value); return *this; } @@ -164,9 +62,9 @@ operator = (FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3):: -FLOATNAME(LVecBase3)(FLOATTYPE1 fill_value) { +template +INLINE LVecBase3:: +LVecBase3(NumType fill_value) { fill(fill_value); } @@ -175,9 +73,9 @@ FLOATNAME(LVecBase3)(FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3):: -FLOATNAME(LVecBase3)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z) { +template +INLINE LVecBase3:: +LVecBase3(NumType x, NumType y, NumType z) { set(x, y, z); } @@ -186,10 +84,10 @@ FLOATNAME(LVecBase3)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z) { // Access: Public // Description: Returns a zero-length vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3):: +template +INLINE LVecBase3 LVecBase3:: zero() { - return FLOATNAME(LVecBase3)(0.0, 0.0, 0.0); + return LVecBase3(0.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -197,10 +95,10 @@ zero() { // Access: Public // Description: Returns a unit X vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3):: +template +INLINE LVecBase3 LVecBase3:: unit_x() { - return FLOATNAME(LVecBase3)(1.0, 0.0, 0.0); + return LVecBase3(1.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -208,10 +106,10 @@ unit_x() { // Access: Public // Description: Returns a unit Y vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3):: +template +INLINE LVecBase3 LVecBase3:: unit_y() { - return FLOATNAME(LVecBase3)(0.0, 1.0, 0.0); + return LVecBase3(0.0, 1.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -219,10 +117,10 @@ unit_y() { // Access: Public // Description: Returns a unit Z vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3):: +template +INLINE LVecBase3 LVecBase3:: unit_z() { - return FLOATNAME(LVecBase3)(0.0, 0.0, 1.0); + return LVecBase3(0.0, 0.0, 1.0); } //////////////////////////////////////////////////////////////////// @@ -230,9 +128,9 @@ unit_z() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3):: -~FLOATNAME(LVecBase3)() { +template +INLINE LVecBase3:: +~LVecBase3() { } //////////////////////////////////////////////////////////////////// @@ -240,8 +138,8 @@ INLINE FLOATNAME(LVecBase3):: // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase3):: +template +INLINE NumType LVecBase3:: operator [](int i) const { nassertr(i >= 0 && i < 3, 0); return _data[i]; @@ -252,8 +150,8 @@ operator [](int i) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 &FLOATNAME(LVecBase3):: +template +INLINE NumType &LVecBase3:: operator [](int i) { nassertr(i >= 0 && i < 3, _data[0]); return _data[i]; @@ -265,8 +163,8 @@ operator [](int i) { // Description: Returns true if any component of the vector is // not-a-number, false otherwise. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase3):: +template +INLINE bool LVecBase3:: is_nan() const { return cnan(_data[0]) || cnan(_data[1]) || cnan(_data[2]); } @@ -276,8 +174,8 @@ is_nan() const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase3):: +template +INLINE NumType LVecBase3:: get_cell(int i) const { nassertr(i >= 0 && i < 3, 0); return _data[i]; @@ -288,8 +186,8 @@ get_cell(int i) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase3):: +template +INLINE NumType LVecBase3:: get_x() const { return _data[0]; } @@ -299,8 +197,8 @@ get_x() const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase3):: +template +INLINE NumType LVecBase3:: get_y() const { return _data[1]; } @@ -310,8 +208,8 @@ get_y() const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase3):: +template +INLINE NumType LVecBase3:: get_z() const { return _data[2]; } @@ -321,9 +219,9 @@ get_z() const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase3):: -set_cell(int i, FLOATTYPE1 value) { +template +INLINE void LVecBase3:: +set_cell(int i, NumType value) { nassertv(i >= 0 && i < 3); _data[i] = value; } @@ -333,9 +231,9 @@ set_cell(int i, FLOATTYPE1 value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase3):: -set_x(FLOATTYPE1 value) { +template +INLINE void LVecBase3:: +set_x(NumType value) { _data[0] = value; } @@ -344,9 +242,9 @@ set_x(FLOATTYPE1 value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase3):: -set_y(FLOATTYPE1 value) { +template +INLINE void LVecBase3:: +set_y(NumType value) { _data[1] = value; } @@ -355,9 +253,9 @@ set_y(FLOATTYPE1 value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase3):: -set_z(FLOATTYPE1 value) { +template +INLINE void LVecBase3:: +set_z(NumType value) { _data[2] = value; } @@ -368,8 +266,8 @@ set_z(FLOATTYPE1 value) { // elements in the vector. The remaining elements // occupy the next positions consecutively in memory. //////////////////////////////////////////////////////////////////// - -INLINE const FLOATTYPE1 *FLOATNAME(LVecBase3):: +template +INLINE const NumType *LVecBase3:: get_data() const { return _data; } @@ -379,8 +277,8 @@ get_data() const { // Access: Public // Description: Returns the number of elements in the vector, three. //////////////////////////////////////////////////////////////////// - -INLINE int FLOATNAME(LVecBase3):: +template +INLINE int LVecBase3:: get_num_components() const { return 3; } @@ -391,8 +289,8 @@ get_num_components() const { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3)::iterator FLOATNAME(LVecBase3):: +template +INLINE LVecBase3::iterator LVecBase3:: begin() { return _data; } @@ -403,8 +301,8 @@ begin() { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3)::iterator FLOATNAME(LVecBase3):: +template +INLINE LVecBase3::iterator LVecBase3:: end() { return begin() + get_num_components(); } @@ -415,8 +313,8 @@ end() { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3)::const_iterator FLOATNAME(LVecBase3):: +template +INLINE LVecBase3::const_iterator LVecBase3:: begin() const { return _data; } @@ -427,8 +325,8 @@ begin() const { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3)::const_iterator FLOATNAME(LVecBase3):: +template +INLINE LVecBase3::const_iterator LVecBase3:: end() const { return begin() + get_num_components(); } @@ -440,9 +338,9 @@ end() const { // fill_value. This is particularly useful for // initializing to zero. //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase3):: -fill(FLOATTYPE1 fill_value) { +template +INLINE void LVecBase3:: +fill(NumType fill_value) { _data[0] = fill_value; _data[1] = fill_value; _data[2] = fill_value; @@ -453,9 +351,9 @@ fill(FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase3):: -set(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z) { +template +INLINE void LVecBase3:: +set(NumType x, NumType y, NumType z) { _data[0] = x; _data[1] = y; _data[2] = z; @@ -466,9 +364,9 @@ set(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase3):: -dot(const FLOATNAME(LVecBase3) &other) const { +template +INLINE NumType LVecBase3:: +dot(const LVecBase3 &other) const { return _data[0] * other[0] + _data[1] * other[1] + _data[2] * other[2]; } @@ -477,10 +375,10 @@ dot(const FLOATNAME(LVecBase3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3):: -cross(const FLOATNAME(LVecBase3) &other) const { - return FLOATNAME(LVecBase3)(_data[1] * other[2] - other[1] * _data[2], +template +INLINE LVecBase3 LVecBase3:: +cross(const LVecBase3 &other) const { + return LVecBase3(_data[1] * other[2] - other[1] * _data[2], other[0] * _data[2] - _data[0] * other[2], _data[0] * other[1] - other[0] * _data[1]); } @@ -494,9 +392,9 @@ cross(const FLOATNAME(LVecBase3) &other) const { // especially in an STL container. Also see // compare_to(). //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase3):: -operator < (const FLOATNAME(LVecBase3) &other) const { +template +INLINE bool LVecBase3:: +operator < (const LVecBase3 &other) const { return (compare_to(other) < 0); } @@ -505,9 +403,9 @@ operator < (const FLOATNAME(LVecBase3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase3):: -operator == (const FLOATNAME(LVecBase3) &other) const { +template +INLINE bool LVecBase3:: +operator == (const LVecBase3 &other) const { return (_data[0] == other[0] && _data[1] == other[1] && _data[2] == other[2]); @@ -518,9 +416,9 @@ operator == (const FLOATNAME(LVecBase3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase3):: -operator != (const FLOATNAME(LVecBase3) &other) const { +template +INLINE bool LVecBase3:: +operator != (const LVecBase3 &other) const { return !operator == (other); } @@ -530,10 +428,10 @@ operator != (const FLOATNAME(LVecBase3) &other) const { // Description: This flavor of compare_to uses a default threshold // value based on the numeric type. //////////////////////////////////////////////////////////////////// - -INLINE int FLOATNAME(LVecBase3):: -compare_to(const FLOATNAME(LVecBase3) &other) const { - return compare_to(other, NEARLY_ZERO(FLOATTYPE1)); +template +INLINE int LVecBase3:: +compare_to(const LVecBase3 &other) const { + return compare_to(other, NEARLY_ZERO(NumType)); } //////////////////////////////////////////////////////////////////// @@ -545,9 +443,9 @@ compare_to(const FLOATNAME(LVecBase3) &other) const { // after, 0 if they are equivalent (within the indicated // tolerance). //////////////////////////////////////////////////////////////////// - -INLINE int FLOATNAME(LVecBase3):: -compare_to(const FLOATNAME(LVecBase3) &other, FLOATTYPE1 threshold) const { +template +INLINE int LVecBase3:: +compare_to(const LVecBase3 &other, NumType threshold) const { if (!IS_THRESHOLD_EQUAL(_data[0], other[0], threshold)) { return (_data[0] < other[0]) ? -1 : 1; } @@ -565,10 +463,10 @@ compare_to(const FLOATNAME(LVecBase3) &other, FLOATTYPE1 threshold) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3):: +template +INLINE LVecBase3 LVecBase3:: operator - () const { - return FLOATNAME(LVecBase3)(-_data[0], -_data[1], -_data[2]); + return LVecBase3(-_data[0], -_data[1], -_data[2]); } //////////////////////////////////////////////////////////////////// @@ -576,10 +474,10 @@ operator - () const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3):: -operator + (const FLOATNAME(LVecBase3) &other) const { - return FLOATNAME(LVecBase3)(_data[0] + other[0], +template +INLINE LVecBase3 LVecBase3:: +operator + (const LVecBase3 &other) const { + return LVecBase3(_data[0] + other[0], _data[1] + other[1], _data[2] + other[2]); } @@ -589,10 +487,10 @@ operator + (const FLOATNAME(LVecBase3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3):: -operator - (const FLOATNAME(LVecBase3) &other) const { - return FLOATNAME(LVecBase3)(_data[0] - other[0], +template +INLINE LVecBase3 LVecBase3:: +operator - (const LVecBase3 &other) const { + return LVecBase3(_data[0] - other[0], _data[1] - other[1], _data[2] - other[2]); } @@ -602,10 +500,10 @@ operator - (const FLOATNAME(LVecBase3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3):: -operator * (FLOATTYPE1 scalar) const { - return FLOATNAME(LVecBase3)(_data[0] * scalar, +template +INLINE LVecBase3 LVecBase3:: +operator * (NumType scalar) const { + return LVecBase3(_data[0] * scalar, _data[1] * scalar, _data[2] * scalar); } @@ -615,10 +513,10 @@ operator * (FLOATTYPE1 scalar) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3):: -operator / (FLOATTYPE1 scalar) const { - return FLOATNAME(LVecBase3)(_data[0] / scalar, +template +INLINE LVecBase3 LVecBase3:: +operator / (NumType scalar) const { + return LVecBase3(_data[0] / scalar, _data[1] / scalar, _data[2] / scalar); } @@ -628,9 +526,9 @@ operator / (FLOATTYPE1 scalar) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase3):: -operator += (const FLOATNAME(LVecBase3) &other) { +template +INLINE void LVecBase3:: +operator += (const LVecBase3 &other) { _data[0] += other[0]; _data[1] += other[1]; _data[2] += other[2]; @@ -641,9 +539,9 @@ operator += (const FLOATNAME(LVecBase3) &other) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase3):: -operator -= (const FLOATNAME(LVecBase3) &other) { +template +INLINE void LVecBase3:: +operator -= (const LVecBase3 &other) { _data[0] -= other[0]; _data[1] -= other[1]; _data[2] -= other[2]; @@ -654,9 +552,9 @@ operator -= (const FLOATNAME(LVecBase3) &other) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase3):: -operator *= (FLOATTYPE1 scalar) { +template +INLINE void LVecBase3:: +operator *= (NumType scalar) { _data[0] *= scalar; _data[1] *= scalar; _data[2] *= scalar; @@ -667,9 +565,9 @@ operator *= (FLOATTYPE1 scalar) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase3):: -operator /= (FLOATTYPE1 scalar) { +template +INLINE void LVecBase3:: +operator /= (NumType scalar) { _data[0] /= scalar; _data[1] /= scalar; _data[2] /= scalar; @@ -680,9 +578,9 @@ operator /= (FLOATTYPE1 scalar) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase3):: -cross_into(const FLOATNAME(LVecBase3) &other) { +template +INLINE void LVecBase3:: +cross_into(const LVecBase3 &other) { (*this) = cross(other); } @@ -692,9 +590,9 @@ cross_into(const FLOATNAME(LVecBase3) &other) { // Description: Returns true if two vectors are memberwise equal // within a specified tolerance. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase3):: -almost_equal(const FLOATNAME(LVecBase3) &other, FLOATTYPE1 threshold) const { +template +INLINE bool LVecBase3:: +almost_equal(const LVecBase3 &other, NumType threshold) const { return (IS_THRESHOLD_EQUAL(_data[0], other[0], threshold) && IS_THRESHOLD_EQUAL(_data[1], other[1], threshold) && IS_THRESHOLD_EQUAL(_data[2], other[2], threshold)); @@ -706,10 +604,10 @@ almost_equal(const FLOATNAME(LVecBase3) &other, FLOATTYPE1 threshold) const { // Description: Returns true if two vectors are memberwise equal // within a default tolerance based on the numeric type. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase3):: -almost_equal(const FLOATNAME(LVecBase3) &other) const { - return almost_equal(other, NEARLY_ZERO(FLOATTYPE1)); +template +INLINE bool LVecBase3:: +almost_equal(const LVecBase3 &other) const { + return almost_equal(other, NEARLY_ZERO(NumType)); } //////////////////////////////////////////////////////////////////// @@ -717,22 +615,38 @@ almost_equal(const FLOATNAME(LVecBase3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase3):: +template +INLINE void LVecBase3:: output(ostream &out) const { out << MAYBE_ZERO(_data[0]) << " " << MAYBE_ZERO(_data[1]) << " " << MAYBE_ZERO(_data[2]); } +//////////////////////////////////////////////////////////////////// +// Function: LVecBase3::init_type +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +template +void LVecBase3:: +init_type() { + if (_type_handle == TypeHandle::none()) { + // Format a string to describe the type. + do_init_type(NumType); + string name = + "LVecBase3<" + get_type_handle(NumType).get_name() + ">"; + register_type(_type_handle, name); + } +} //////////////////////////////////////////////////////////////////// // Function: LVecBase3::write_datagram // Access: Public // Description: Function to write itself into a datagram //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase3):: +template +void LVecBase3:: write_datagram(Datagram &destination) const { destination.add_float32(_data[0]); destination.add_float32(_data[1]); @@ -744,11 +658,23 @@ write_datagram(Datagram &destination) const { // Access: Public // Description: Function to read itself from a datagramIterator //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase3):: +template +void LVecBase3:: read_datagram(DatagramIterator &source) { _data[0] = source.get_float32(); _data[1] = source.get_float32(); _data[2] = source.get_float32(); } + +//////////////////////////////////////////////////////////////////// +// Function: lcast_to +// Description: Converts a vector from one numeric representation to +// another one. This is usually invoked using the macro +// LCAST. +//////////////////////////////////////////////////////////////////// +template +INLINE LVecBase3 +lcast_to(NumType2 *, const LVecBase3 &source) { + return LVecBase3(source[0], source[1], source[2]); +} diff --git a/panda/src/linmath/lvecBase3.h b/panda/src/linmath/lvecBase3.h index ce55de079a..15b75c083f 100644 --- a/panda/src/linmath/lvecBase3.h +++ b/panda/src/linmath/lvecBase3.h @@ -7,37 +7,135 @@ #define LVECBASE3_H #include -#include -#include -#include -#include + #include "cmath.h" -#include "nearly_zero.h" + +#include class Datagram; class DatagramIterator; -#include "fltnames.I" -#include "lvecBase3.I" - -#include "dblnames.I" -#include "lvecBase3.I" - //////////////////////////////////////////////////////////////////// -// Function: lcast_to -// Description: Converts a vector from one numeric representation to -// another one. This is usually invoked using the macro -// LCAST. +// Class : LVecBase3 +// Description : This is the base class for all three-component +// vectors and points. //////////////////////////////////////////////////////////////////// -INLINE FLOATNAME2(LVecBase3) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LVecBase3) &source) { - return FLOATNAME2(LVecBase3)(source[0], source[1], source[2]); +template +class LVecBase3 { +PUBLISHED: + typedef const NumType *iterator; + typedef const NumType *const_iterator; + + INLINE LVecBase3(); + INLINE LVecBase3(const LVecBase3 ©); + INLINE LVecBase3 &operator = (const LVecBase3 ©); + INLINE LVecBase3 &operator = (NumType fill_value); + INLINE LVecBase3(NumType fill_value); + INLINE LVecBase3(NumType x, NumType y, NumType z); + + INLINE static LVecBase3 zero(); + INLINE static LVecBase3 unit_x(); + INLINE static LVecBase3 unit_y(); + INLINE static LVecBase3 unit_z(); + + INLINE ~LVecBase3(); + + INLINE NumType operator [](int i) const; + INLINE NumType &operator [](int i); + + INLINE bool is_nan() const; + + INLINE NumType get_cell(int i) const; + INLINE NumType get_x() const; + INLINE NumType get_y() const; + INLINE NumType get_z() const; + INLINE void set_cell(int i, NumType value); + INLINE void set_x(NumType value); + INLINE void set_y(NumType value); + INLINE void set_z(NumType value); + + INLINE const NumType *get_data() const; + INLINE int get_num_components() const; + +public: + INLINE iterator begin(); + INLINE iterator end(); + + INLINE const_iterator begin() const; + INLINE const_iterator end() const; + +PUBLISHED: + INLINE void fill(NumType fill_value); + INLINE void set(NumType x, NumType y, NumType z); + + INLINE NumType dot(const LVecBase3 &other) const; + INLINE LVecBase3 cross(const LVecBase3 &other) const; + + INLINE bool operator < (const LVecBase3 &other) const; + INLINE bool operator == (const LVecBase3 &other) const; + INLINE bool operator != (const LVecBase3 &other) const; + + INLINE int compare_to(const LVecBase3 &other) const; + INLINE int compare_to(const LVecBase3 &other, + NumType threshold) const; + + INLINE LVecBase3 + operator - () const; + + INLINE LVecBase3 + operator + (const LVecBase3 &other) const; + INLINE LVecBase3 + operator - (const LVecBase3 &other) const; + + INLINE LVecBase3 operator * (NumType scalar) const; + INLINE LVecBase3 operator / (NumType scalar) const; + + INLINE void operator += (const LVecBase3 &other); + INLINE void operator -= (const LVecBase3 &other); + + INLINE void operator *= (NumType scalar); + INLINE void operator /= (NumType scalar); + + INLINE void cross_into(const LVecBase3 &other); + + INLINE bool almost_equal(const LVecBase3 &other, + NumType threshold) const; + INLINE bool almost_equal(const LVecBase3 &other) const; + + INLINE void output(ostream &out) const; + +private: + NumType _data[3]; + +public: + INLINE void write_datagram(Datagram &destination) const; + INLINE void read_datagram(DatagramIterator &source); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type(); + +private: + static TypeHandle _type_handle; +}; + +template +INLINE ostream &operator << (ostream &out, const LVecBase3 &vec) { + vec.output(out); + return out; } -#include "fltnames.I" -INLINE FLOATNAME2(LVecBase3) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LVecBase3) &source) { - return FLOATNAME2(LVecBase3)(source[0], source[1], source[2]); -} + +// Cast to a different numeric type +template +INLINE LVecBase3 +lcast_to(NumType2 *type, const LVecBase3 &source); + +#include "lvecBase3.I" + +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVecBase3) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVecBase3) #endif diff --git a/panda/src/linmath/lvecBase4.I b/panda/src/linmath/lvecBase4.I index 5e29186b07..e2e96e2475 100644 --- a/panda/src/linmath/lvecBase4.I +++ b/panda/src/linmath/lvecBase4.I @@ -3,125 +3,23 @@ // //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Class : LVecBase4 -// Description : This is the base class for all three-component -// vectors and points. -//////////////////////////////////////////////////////////////////// +#include "nearly_zero.h" -class EXPCL_PANDA FLOATNAME(LVecBase4) { -PUBLISHED: - typedef const FLOATTYPE1 *iterator; - typedef const FLOATTYPE1 *const_iterator; +#include +#include +#include - INLINE FLOATNAME(LVecBase4)(); - INLINE FLOATNAME(LVecBase4)(const FLOATNAME(LVecBase4) ©); - INLINE FLOATNAME(LVecBase4) &operator = (const FLOATNAME(LVecBase4) ©); - INLINE FLOATNAME(LVecBase4) &operator = (FLOATTYPE1 fill_value); - INLINE FLOATNAME(LVecBase4)(FLOATTYPE1 fill_value); - INLINE FLOATNAME(LVecBase4)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w); - - INLINE static FLOATNAME(LVecBase4) zero(); - INLINE static FLOATNAME(LVecBase4) unit_x(); - INLINE static FLOATNAME(LVecBase4) unit_y(); - INLINE static FLOATNAME(LVecBase4) unit_z(); - INLINE static FLOATNAME(LVecBase4) unit_w(); - - INLINE ~FLOATNAME(LVecBase4)(); - - INLINE FLOATTYPE1 operator [](int i) const; - INLINE FLOATTYPE1 &operator [](int i); - - INLINE bool is_nan() const; - - INLINE FLOATTYPE1 get_cell(int i) const; - INLINE FLOATTYPE1 get_x() const; - INLINE FLOATTYPE1 get_y() const; - INLINE FLOATTYPE1 get_z() const; - INLINE FLOATTYPE1 get_w() const; - INLINE void set_cell(int i, FLOATTYPE1 value); - INLINE void set_x(FLOATTYPE1 value); - INLINE void set_y(FLOATTYPE1 value); - INLINE void set_z(FLOATTYPE1 value); - INLINE void set_w(FLOATTYPE1 value); - - INLINE const FLOATTYPE1 *get_data() const; - INLINE int get_num_components() const; - -public: - INLINE iterator begin(); - INLINE iterator end(); - - INLINE const_iterator begin() const; - INLINE const_iterator end() const; - -PUBLISHED: - INLINE void fill(FLOATTYPE1 fill_value); - INLINE void set(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w); - - INLINE FLOATTYPE1 dot(const FLOATNAME(LVecBase4) &other) const; - - INLINE bool operator < (const FLOATNAME(LVecBase4) &other) const; - INLINE bool operator == (const FLOATNAME(LVecBase4) &other) const; - INLINE bool operator != (const FLOATNAME(LVecBase4) &other) const; - - INLINE int compare_to(const FLOATNAME(LVecBase4) &other) const; - INLINE int compare_to(const FLOATNAME(LVecBase4) &other, - FLOATTYPE1 threshold) const; - - INLINE FLOATNAME(LVecBase4) operator - () const; - - INLINE FLOATNAME(LVecBase4) - operator + (const FLOATNAME(LVecBase4) &other) const; - INLINE FLOATNAME(LVecBase4) - operator - (const FLOATNAME(LVecBase4) &other) const; - - INLINE FLOATNAME(LVecBase4) operator * (FLOATTYPE1 scalar) const; - INLINE FLOATNAME(LVecBase4) operator / (FLOATTYPE1 scalar) const; - - INLINE void operator += (const FLOATNAME(LVecBase4) &other); - INLINE void operator -= (const FLOATNAME(LVecBase4) &other); - - INLINE void operator *= (FLOATTYPE1 scalar); - INLINE void operator /= (FLOATTYPE1 scalar); - - INLINE bool almost_equal(const FLOATNAME(LVecBase4) &other, - FLOATTYPE1 threshold) const; - INLINE bool almost_equal(const FLOATNAME(LVecBase4) &other) const; - - INLINE void output(ostream &out) const; - -private: - FLOATTYPE1 _data[4]; - -public: - INLINE void write_datagram(Datagram &destination) const; - INLINE void read_datagram(DatagramIterator &source); - -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type(); - -private: - static TypeHandle _type_handle; -}; - - -INLINE ostream &operator << (ostream &out, const FLOATNAME(LVecBase4) &vec) { - vec.output(out); - return out; -} +template +TypeHandle LVecBase4::_type_handle; //////////////////////////////////////////////////////////////////// // Function: LVecBase4::Default Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4):: -FLOATNAME(LVecBase4)() { +template +INLINE LVecBase4:: +LVecBase4() { } //////////////////////////////////////////////////////////////////// @@ -129,9 +27,9 @@ FLOATNAME(LVecBase4)() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4):: -FLOATNAME(LVecBase4)(const FLOATNAME(LVecBase4) ©) { +template +INLINE LVecBase4:: +LVecBase4(const LVecBase4 ©) { (*this) = copy; } @@ -140,9 +38,9 @@ FLOATNAME(LVecBase4)(const FLOATNAME(LVecBase4) ©) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) &FLOATNAME(LVecBase4):: -operator = (const FLOATNAME(LVecBase4) ©) { +template +INLINE LVecBase4 &LVecBase4:: +operator = (const LVecBase4 ©) { set(copy[0], copy[1], copy[2], copy[3]); return *this; } @@ -152,9 +50,9 @@ operator = (const FLOATNAME(LVecBase4) ©) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) &FLOATNAME(LVecBase4):: -operator = (FLOATTYPE1 fill_value) { +template +INLINE LVecBase4 &LVecBase4:: +operator = (NumType fill_value) { fill(fill_value); return *this; } @@ -164,9 +62,9 @@ operator = (FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4):: -FLOATNAME(LVecBase4)(FLOATTYPE1 fill_value) { +template +INLINE LVecBase4:: +LVecBase4(NumType fill_value) { fill(fill_value); } @@ -175,9 +73,9 @@ FLOATNAME(LVecBase4)(FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4):: -FLOATNAME(LVecBase4)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w) { +template +INLINE LVecBase4:: +LVecBase4(NumType x, NumType y, NumType z, NumType w) { set(x, y, z, w); } @@ -186,9 +84,9 @@ FLOATNAME(LVecBase4)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4):: -~FLOATNAME(LVecBase4)() { +template +INLINE LVecBase4:: +~LVecBase4() { } //////////////////////////////////////////////////////////////////// @@ -196,10 +94,10 @@ INLINE FLOATNAME(LVecBase4):: // Access: Public // Description: Returns a zero-length vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4):: +template +INLINE LVecBase4 LVecBase4:: zero() { - return FLOATNAME(LVecBase4)(0.0, 0.0, 0.0, 0.0); + return LVecBase4(0.0, 0.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -207,10 +105,10 @@ zero() { // Access: Public // Description: Returns a unit X vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4):: +template +INLINE LVecBase4 LVecBase4:: unit_x() { - return FLOATNAME(LVecBase4)(1.0, 0.0, 0.0, 0.0); + return LVecBase4(1.0, 0.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -218,10 +116,10 @@ unit_x() { // Access: Public // Description: Returns a unit Y vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4):: +template +INLINE LVecBase4 LVecBase4:: unit_y() { - return FLOATNAME(LVecBase4)(0.0, 1.0, 0.0, 0.0); + return LVecBase4(0.0, 1.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -229,10 +127,10 @@ unit_y() { // Access: Public // Description: Returns a unit Z vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4):: +template +INLINE LVecBase4 LVecBase4:: unit_z() { - return FLOATNAME(LVecBase4)(0.0, 0.0, 1.0, 0.0); + return LVecBase4(0.0, 0.0, 1.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -240,10 +138,10 @@ unit_z() { // Access: Public // Description: Returns a unit W vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4):: +template +INLINE LVecBase4 LVecBase4:: unit_w() { - return FLOATNAME(LVecBase4)(0.0, 0.0, 0.0, 1.0); + return LVecBase4(0.0, 0.0, 0.0, 1.0); } //////////////////////////////////////////////////////////////////// @@ -251,8 +149,8 @@ unit_w() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase4):: +template +INLINE NumType LVecBase4:: operator [](int i) const { nassertr(i >= 0 && i < 4, 0); return _data[i]; @@ -263,8 +161,8 @@ operator [](int i) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 &FLOATNAME(LVecBase4):: +template +INLINE NumType &LVecBase4:: operator [](int i) { nassertr(i >= 0 && i < 4, _data[0]); return _data[i]; @@ -276,8 +174,8 @@ operator [](int i) { // Description: Returns true if any component of the vector is // not-a-number, false otherwise. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase4):: +template +INLINE bool LVecBase4:: is_nan() const { return cnan(_data[0]) || cnan(_data[1]) || cnan(_data[2]) || cnan(_data[3]); } @@ -287,8 +185,8 @@ is_nan() const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase4):: +template +INLINE NumType LVecBase4:: get_cell(int i) const { nassertr(i >= 0 && i < 4, 0); return _data[i]; @@ -299,8 +197,8 @@ get_cell(int i) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase4):: +template +INLINE NumType LVecBase4:: get_x() const { return _data[0]; } @@ -310,8 +208,8 @@ get_x() const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase4):: +template +INLINE NumType LVecBase4:: get_y() const { return _data[1]; } @@ -321,8 +219,8 @@ get_y() const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase4):: +template +INLINE NumType LVecBase4:: get_z() const { return _data[2]; } @@ -332,8 +230,8 @@ get_z() const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase4):: +template +INLINE NumType LVecBase4:: get_w() const { return _data[3]; } @@ -343,9 +241,9 @@ get_w() const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase4):: -set_cell(int i, FLOATTYPE1 value) { +template +INLINE void LVecBase4:: +set_cell(int i, NumType value) { nassertv(i >= 0 && i < 4); _data[i] = value; } @@ -355,9 +253,9 @@ set_cell(int i, FLOATTYPE1 value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase4):: -set_x(FLOATTYPE1 value) { +template +INLINE void LVecBase4:: +set_x(NumType value) { _data[0] = value; } @@ -366,9 +264,9 @@ set_x(FLOATTYPE1 value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase4):: -set_y(FLOATTYPE1 value) { +template +INLINE void LVecBase4:: +set_y(NumType value) { _data[1] = value; } @@ -377,9 +275,9 @@ set_y(FLOATTYPE1 value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase4):: -set_z(FLOATTYPE1 value) { +template +INLINE void LVecBase4:: +set_z(NumType value) { _data[2] = value; } @@ -388,9 +286,9 @@ set_z(FLOATTYPE1 value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase4):: -set_w(FLOATTYPE1 value) { +template +INLINE void LVecBase4:: +set_w(NumType value) { _data[3] = value; } @@ -401,8 +299,8 @@ set_w(FLOATTYPE1 value) { // elements in the vector. The remaining elements // occupy the next positions consecutively in memory. //////////////////////////////////////////////////////////////////// - -INLINE const FLOATTYPE1 *FLOATNAME(LVecBase4):: +template +INLINE const NumType *LVecBase4:: get_data() const { return _data; } @@ -412,8 +310,8 @@ get_data() const { // Access: Public // Description: Returns the number of elements in the vector, four. //////////////////////////////////////////////////////////////////// - -INLINE int FLOATNAME(LVecBase4):: +template +INLINE int LVecBase4:: get_num_components() const { return 4; } @@ -424,8 +322,8 @@ get_num_components() const { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4)::iterator FLOATNAME(LVecBase4):: +template +INLINE LVecBase4::iterator LVecBase4:: begin() { return _data; } @@ -436,8 +334,8 @@ begin() { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4)::iterator FLOATNAME(LVecBase4):: +template +INLINE LVecBase4::iterator LVecBase4:: end() { return begin() + get_num_components(); } @@ -448,8 +346,8 @@ end() { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4)::const_iterator FLOATNAME(LVecBase4):: +template +INLINE LVecBase4::const_iterator LVecBase4:: begin() const { return _data; } @@ -460,8 +358,8 @@ begin() const { // Description: Returns an iterator that may be used to traverse the // elements of the matrix, STL-style. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4)::const_iterator FLOATNAME(LVecBase4):: +template +INLINE LVecBase4::const_iterator LVecBase4:: end() const { return begin() + get_num_components(); } @@ -473,9 +371,9 @@ end() const { // fill_value. This is particularly useful for // initializing to zero. //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase4):: -fill(FLOATTYPE1 fill_value) { +template +INLINE void LVecBase4:: +fill(NumType fill_value) { _data[0] = fill_value; _data[1] = fill_value; _data[2] = fill_value; @@ -487,9 +385,9 @@ fill(FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase4):: -set(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w) { +template +INLINE void LVecBase4:: +set(NumType x, NumType y, NumType z, NumType w) { _data[0] = x; _data[1] = y; _data[2] = z; @@ -501,9 +399,9 @@ set(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVecBase4):: -dot(const FLOATNAME(LVecBase4) &other) const { +template +INLINE NumType LVecBase4:: +dot(const LVecBase4 &other) const { return _data[0] * other[0] + _data[1] * other[1] + _data[2] * other[2] + _data[3] * other[3]; @@ -518,9 +416,9 @@ dot(const FLOATNAME(LVecBase4) &other) const { // especially in an STL container. Also see // compare_to(). //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase4):: -operator < (const FLOATNAME(LVecBase4) &other) const { +template +INLINE bool LVecBase4:: +operator < (const LVecBase4 &other) const { return (compare_to(other) < 0); } @@ -529,9 +427,9 @@ operator < (const FLOATNAME(LVecBase4) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase4):: -operator == (const FLOATNAME(LVecBase4) &other) const { +template +INLINE bool LVecBase4:: +operator == (const LVecBase4 &other) const { return (_data[0] == other[0] && _data[1] == other[1] && _data[2] == other[2] && @@ -543,9 +441,9 @@ operator == (const FLOATNAME(LVecBase4) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase4):: -operator != (const FLOATNAME(LVecBase4) &other) const { +template +INLINE bool LVecBase4:: +operator != (const LVecBase4 &other) const { return !operator == (other); } @@ -555,10 +453,10 @@ operator != (const FLOATNAME(LVecBase4) &other) const { // Description: This flavor of compare_to uses a default threshold // value based on the numeric type. //////////////////////////////////////////////////////////////////// - -INLINE int FLOATNAME(LVecBase4):: -compare_to(const FLOATNAME(LVecBase4) &other) const { - return compare_to(other, NEARLY_ZERO(FLOATTYPE1)); +template +INLINE int LVecBase4:: +compare_to(const LVecBase4 &other) const { + return compare_to(other, NEARLY_ZERO(NumType)); } //////////////////////////////////////////////////////////////////// @@ -570,9 +468,9 @@ compare_to(const FLOATNAME(LVecBase4) &other) const { // after, 0 if they are equivalent (within the indicated // tolerance). //////////////////////////////////////////////////////////////////// - -INLINE int FLOATNAME(LVecBase4):: -compare_to(const FLOATNAME(LVecBase4) &other, FLOATTYPE1 threshold) const { +template +INLINE int LVecBase4:: +compare_to(const LVecBase4 &other, NumType threshold) const { if (!IS_THRESHOLD_EQUAL(_data[0], other[0], threshold)) { return (_data[0] < other[0]) ? -1 : 1; } @@ -593,10 +491,10 @@ compare_to(const FLOATNAME(LVecBase4) &other, FLOATTYPE1 threshold) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4):: +template +INLINE LVecBase4 LVecBase4:: operator - () const { - return FLOATNAME(LVecBase4)(-_data[0], -_data[1], -_data[2], -_data[3]); + return LVecBase4(-_data[0], -_data[1], -_data[2], -_data[3]); } //////////////////////////////////////////////////////////////////// @@ -604,10 +502,10 @@ operator - () const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4):: -operator + (const FLOATNAME(LVecBase4) &other) const { - return FLOATNAME(LVecBase4)(_data[0] + other[0], +template +INLINE LVecBase4 LVecBase4:: +operator + (const LVecBase4 &other) const { + return LVecBase4(_data[0] + other[0], _data[1] + other[1], _data[2] + other[2], _data[3] + other[3]); @@ -618,10 +516,10 @@ operator + (const FLOATNAME(LVecBase4) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4):: -operator - (const FLOATNAME(LVecBase4) &other) const { - return FLOATNAME(LVecBase4)(_data[0] - other[0], +template +INLINE LVecBase4 LVecBase4:: +operator - (const LVecBase4 &other) const { + return LVecBase4(_data[0] - other[0], _data[1] - other[1], _data[2] - other[2], _data[3] - other[3]); @@ -632,10 +530,10 @@ operator - (const FLOATNAME(LVecBase4) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4):: -operator * (FLOATTYPE1 scalar) const { - return FLOATNAME(LVecBase4)(_data[0] * scalar, +template +INLINE LVecBase4 LVecBase4:: +operator * (NumType scalar) const { + return LVecBase4(_data[0] * scalar, _data[1] * scalar, _data[2] * scalar, _data[3] * scalar); @@ -646,10 +544,10 @@ operator * (FLOATTYPE1 scalar) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4):: -operator / (FLOATTYPE1 scalar) const { - return FLOATNAME(LVecBase4)(_data[0] / scalar, +template +INLINE LVecBase4 LVecBase4:: +operator / (NumType scalar) const { + return LVecBase4(_data[0] / scalar, _data[1] / scalar, _data[2] / scalar, _data[3] / scalar); @@ -660,9 +558,9 @@ operator / (FLOATTYPE1 scalar) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase4):: -operator += (const FLOATNAME(LVecBase4) &other) { +template +INLINE void LVecBase4:: +operator += (const LVecBase4 &other) { _data[0] += other[0]; _data[1] += other[1]; _data[2] += other[2]; @@ -674,9 +572,9 @@ operator += (const FLOATNAME(LVecBase4) &other) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase4):: -operator -= (const FLOATNAME(LVecBase4) &other) { +template +INLINE void LVecBase4:: +operator -= (const LVecBase4 &other) { _data[0] -= other[0]; _data[1] -= other[1]; _data[2] -= other[2]; @@ -688,9 +586,9 @@ operator -= (const FLOATNAME(LVecBase4) &other) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase4):: -operator *= (FLOATTYPE1 scalar) { +template +INLINE void LVecBase4:: +operator *= (NumType scalar) { _data[0] *= scalar; _data[1] *= scalar; _data[2] *= scalar; @@ -702,9 +600,9 @@ operator *= (FLOATTYPE1 scalar) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase4):: -operator /= (FLOATTYPE1 scalar) { +template +INLINE void LVecBase4:: +operator /= (NumType scalar) { _data[0] /= scalar; _data[1] /= scalar; _data[2] /= scalar; @@ -717,9 +615,9 @@ operator /= (FLOATTYPE1 scalar) { // Description: Returns true if two vectors are memberwise equal // within a specified tolerance. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase4):: -almost_equal(const FLOATNAME(LVecBase4) &other, FLOATTYPE1 threshold) const { +template +INLINE bool LVecBase4:: +almost_equal(const LVecBase4 &other, NumType threshold) const { return (IS_THRESHOLD_EQUAL(_data[0], other[0], threshold) && IS_THRESHOLD_EQUAL(_data[1], other[1], threshold) && IS_THRESHOLD_EQUAL(_data[2], other[2], threshold) && @@ -732,10 +630,10 @@ almost_equal(const FLOATNAME(LVecBase4) &other, FLOATTYPE1 threshold) const { // Description: Returns true if two vectors are memberwise equal // within a default tolerance based on the numeric type. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVecBase4):: -almost_equal(const FLOATNAME(LVecBase4) &other) const { - return almost_equal(other, NEARLY_ZERO(FLOATTYPE1)); +template +INLINE bool LVecBase4:: +almost_equal(const LVecBase4 &other) const { + return almost_equal(other, NEARLY_ZERO(NumType)); } //////////////////////////////////////////////////////////////////// @@ -743,8 +641,8 @@ almost_equal(const FLOATNAME(LVecBase4) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase4):: +template +INLINE void LVecBase4:: output(ostream &out) const { out << MAYBE_ZERO(_data[0]) << " " << MAYBE_ZERO(_data[1]) << " " @@ -752,13 +650,31 @@ output(ostream &out) const { << MAYBE_ZERO(_data[3]); } +//////////////////////////////////////////////////////////////////// +// Function: LVecBase4::init_type +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +template +void LVecBase4:: +init_type() { + if (_type_handle == TypeHandle::none()) { + // Format a string to describe the type. + do_init_type(NumType); + string name = + "LVecBase4<" + get_type_handle(NumType).get_name() + ">"; + register_type(_type_handle, name); + } +} + + //////////////////////////////////////////////////////////////////// // Function: LVecBase4::write_datagram // Access: Public // Description: Function to write itself into a datagram //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase4):: +template +void LVecBase4:: write_datagram(Datagram &destination) const { destination.add_float32(_data[0]); destination.add_float32(_data[1]); @@ -771,8 +687,8 @@ write_datagram(Datagram &destination) const { // Access: Public // Description: Function to read itself from a datagramIterator //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(LVecBase4):: +template +void LVecBase4:: read_datagram(DatagramIterator &source) { _data[0] = source.get_float32(); _data[1] = source.get_float32(); @@ -781,5 +697,14 @@ read_datagram(DatagramIterator &source) { } - - +//////////////////////////////////////////////////////////////////// +// Function: lcast_to +// Description: Converts a vector from one numeric representation to +// another one. This is usually invoked using the macro +// LCAST. +//////////////////////////////////////////////////////////////////// +template +INLINE LVecBase4 +lcast_to(NumType2 *, const LVecBase4 &source) { + return LVecBase4(source[0], source[1], source[2], source[3]); +} diff --git a/panda/src/linmath/lvecBase4.h b/panda/src/linmath/lvecBase4.h index 1492d071bc..8332171620 100644 --- a/panda/src/linmath/lvecBase4.h +++ b/panda/src/linmath/lvecBase4.h @@ -7,42 +7,135 @@ #define LVECBASE4_H #include -#include -#include -#include -#include + #include "cmath.h" -#include "nearly_zero.h" + +#include class Datagram; class DatagramIterator; -#include "fltnames.I" -#include "lvecBase4.I" - -#include "dblnames.I" -#include "lvecBase4.I" - //////////////////////////////////////////////////////////////////// -// Function: lcast_to -// Description: Converts a vector from one numeric representation to -// another one. This is usually invoked using the macro -// LCAST. +// Class : LVecBase4 +// Description : This is the base class for all three-component +// vectors and points. //////////////////////////////////////////////////////////////////// +template +class LVecBase4 { +PUBLISHED: + typedef const NumType *iterator; + typedef const NumType *const_iterator; -INLINE FLOATNAME2(LVecBase4) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LVecBase4) &source) { - return FLOATNAME2(LVecBase4)(source[0], source[1], source[2], source[3]); -} + INLINE LVecBase4(); + INLINE LVecBase4(const LVecBase4 ©); + INLINE LVecBase4 &operator = (const LVecBase4 ©); + INLINE LVecBase4 &operator = (NumType fill_value); + INLINE LVecBase4(NumType fill_value); + INLINE LVecBase4(NumType x, NumType y, NumType z, NumType w); -#include "fltnames.I" -INLINE FLOATNAME2(LVecBase4) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LVecBase4) &source) { - return FLOATNAME2(LVecBase4)(source[0], source[1], source[2], source[3]); + INLINE static LVecBase4 zero(); + INLINE static LVecBase4 unit_x(); + INLINE static LVecBase4 unit_y(); + INLINE static LVecBase4 unit_z(); + INLINE static LVecBase4 unit_w(); + + INLINE ~LVecBase4(); + + INLINE NumType operator [](int i) const; + INLINE NumType &operator [](int i); + + INLINE bool is_nan() const; + + INLINE NumType get_cell(int i) const; + INLINE NumType get_x() const; + INLINE NumType get_y() const; + INLINE NumType get_z() const; + INLINE NumType get_w() const; + INLINE void set_cell(int i, NumType value); + INLINE void set_x(NumType value); + INLINE void set_y(NumType value); + INLINE void set_z(NumType value); + INLINE void set_w(NumType value); + + INLINE const NumType *get_data() const; + INLINE int get_num_components() const; + +public: + INLINE iterator begin(); + INLINE iterator end(); + + INLINE const_iterator begin() const; + INLINE const_iterator end() const; + +PUBLISHED: + INLINE void fill(NumType fill_value); + INLINE void set(NumType x, NumType y, NumType z, NumType w); + + INLINE NumType dot(const LVecBase4 &other) const; + + INLINE bool operator < (const LVecBase4 &other) const; + INLINE bool operator == (const LVecBase4 &other) const; + INLINE bool operator != (const LVecBase4 &other) const; + + INLINE int compare_to(const LVecBase4 &other) const; + INLINE int compare_to(const LVecBase4 &other, + NumType threshold) const; + + INLINE LVecBase4 + operator - () const; + + INLINE LVecBase4 + operator + (const LVecBase4 &other) const; + INLINE LVecBase4 + operator - (const LVecBase4 &other) const; + + INLINE LVecBase4 operator * (NumType scalar) const; + INLINE LVecBase4 operator / (NumType scalar) const; + + INLINE void operator += (const LVecBase4 &other); + INLINE void operator -= (const LVecBase4 &other); + + INLINE void operator *= (NumType scalar); + INLINE void operator /= (NumType scalar); + + INLINE bool almost_equal(const LVecBase4 &other, + NumType threshold) const; + INLINE bool almost_equal(const LVecBase4 &other) const; + + INLINE void output(ostream &out) const; + +private: + NumType _data[4]; + +public: + INLINE void write_datagram(Datagram &destination) const; + INLINE void read_datagram(DatagramIterator &source); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type(); + +private: + static TypeHandle _type_handle; +}; + +template +INLINE ostream &operator << (ostream &out, const LVecBase4 &vec) { + vec.output(out); + return out; } +// Cast to a different numeric type +template +INLINE LVecBase4 +lcast_to(NumType2 *type, const LVecBase4 &source); +#include "lvecBase4.I" +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVecBase4) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVecBase4) #endif diff --git a/panda/src/linmath/lvector2.I b/panda/src/linmath/lvector2.I index af8a44bd47..78be371947 100644 --- a/panda/src/linmath/lvector2.I +++ b/panda/src/linmath/lvector2.I @@ -3,56 +3,19 @@ // //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Class : LVector2 -// Description : This is a two-component vector offset. -//////////////////////////////////////////////////////////////////// +#include "cmath.h" -class EXPCL_PANDA FLOATNAME(LVector2) : public FLOATNAME(LVecBase2) { -PUBLISHED: - INLINE FLOATNAME(LVector2)(); - INLINE FLOATNAME(LVector2)(const FLOATNAME(LVecBase2) ©); - INLINE FLOATNAME(LVector2) &operator = (const FLOATNAME(LVecBase2) ©); - INLINE FLOATNAME(LVector2) &operator = (FLOATTYPE1 fill_value); - INLINE FLOATNAME(LVector2)(FLOATTYPE1 fill_value); - INLINE FLOATNAME(LVector2)(FLOATTYPE1 x, FLOATTYPE1 y); - - INLINE static FLOATNAME(LVector2) zero(); - INLINE static FLOATNAME(LVector2) unit_x(); - INLINE static FLOATNAME(LVector2) unit_y(); - - INLINE FLOATNAME(LVector2) operator - () const; - - INLINE FLOATNAME(LVecBase2)operator + (const FLOATNAME(LVecBase2) &other) const; - INLINE FLOATNAME(LVector2) operator + (const FLOATNAME(LVector2) &other) const; - - INLINE FLOATNAME(LVecBase2) operator - (const FLOATNAME(LVecBase2) &other) const; - INLINE FLOATNAME(LVector2) operator - (const FLOATNAME(LVector2) &other) const; - - INLINE FLOATTYPE1 length() const; - INLINE FLOATTYPE1 length_squared() const; - INLINE bool normalize(); - INLINE FLOATNAME(LVector2) operator * (FLOATTYPE1 scalar) const; - INLINE FLOATNAME(LVector2) operator / (FLOATTYPE1 scalar) const; - -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type(); - -private: - static TypeHandle _type_handle; -}; +template +TypeHandle LVector2::_type_handle; //////////////////////////////////////////////////////////////////// // Function: LVector2::Default Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2):: -FLOATNAME(LVector2)() { +template +INLINE LVector2:: +LVector2() { } //////////////////////////////////////////////////////////////////// @@ -60,9 +23,9 @@ FLOATNAME(LVector2)() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2):: -FLOATNAME(LVector2)(const FLOATNAME(LVecBase2) ©) : FLOATNAME(LVecBase2)(copy) { +template +INLINE LVector2:: +LVector2(const LVecBase2 ©) : LVecBase2(copy) { } //////////////////////////////////////////////////////////////////// @@ -70,10 +33,10 @@ FLOATNAME(LVector2)(const FLOATNAME(LVecBase2) ©) : FLOATNAME(LVecBase2)(cop // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2) &FLOATNAME(LVector2):: -operator = (const FLOATNAME(LVecBase2) ©) { - FLOATNAME(LVecBase2)::operator = (copy); +template +INLINE LVector2 &LVector2:: +operator = (const LVecBase2 ©) { + LVecBase2::operator = (copy); return *this; } @@ -82,10 +45,10 @@ operator = (const FLOATNAME(LVecBase2) ©) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2) &FLOATNAME(LVector2):: -operator = (FLOATTYPE1 fill_value) { - FLOATNAME(LVecBase2)::operator = (fill_value); +template +INLINE LVector2 &LVector2:: +operator = (NumType fill_value) { + LVecBase2::operator = (fill_value); return *this; } @@ -94,10 +57,10 @@ operator = (FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2):: -FLOATNAME(LVector2)(FLOATTYPE1 fill_value) : - FLOATNAME(LVecBase2)(fill_value) +template +INLINE LVector2:: +LVector2(NumType fill_value) : + LVecBase2(fill_value) { } @@ -106,10 +69,10 @@ FLOATNAME(LVector2)(FLOATTYPE1 fill_value) : // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2):: -FLOATNAME(LVector2)(FLOATTYPE1 x, FLOATTYPE1 y) : - FLOATNAME(LVecBase2)(x, y) +template +INLINE LVector2:: +LVector2(NumType x, NumType y) : + LVecBase2(x, y) { } @@ -118,10 +81,10 @@ FLOATNAME(LVector2)(FLOATTYPE1 x, FLOATTYPE1 y) : // Access: Public // Description: Returns a zero-length vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2) FLOATNAME(LVector2):: +template +INLINE LVector2 LVector2:: zero() { - return FLOATNAME(LVector2)(0.0, 0.0); + return LVector2(0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -129,10 +92,10 @@ zero() { // Access: Public // Description: Returns a unit X vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2) FLOATNAME(LVector2):: +template +INLINE LVector2 LVector2:: unit_x() { - return FLOATNAME(LVector2)(1.0, 0.0); + return LVector2(1.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -140,10 +103,10 @@ unit_x() { // Access: Public // Description: Returns a unit Y vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2) FLOATNAME(LVector2):: +template +INLINE LVector2 LVector2:: unit_y() { - return FLOATNAME(LVector2)(0.0, 1.0); + return LVector2(0.0, 1.0); } //////////////////////////////////////////////////////////////////// @@ -151,10 +114,10 @@ unit_y() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2) FLOATNAME(LVector2):: +template +INLINE LVector2 LVector2:: operator - () const { - return FLOATNAME(LVecBase2)::operator - (); + return LVecBase2::operator - (); } //////////////////////////////////////////////////////////////////// @@ -162,10 +125,10 @@ operator - () const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LVector2):: -operator + (const FLOATNAME(LVecBase2) &other) const { - return FLOATNAME(LVecBase2)::operator + (other); +template +INLINE LVecBase2 LVector2:: +operator + (const LVecBase2 &other) const { + return LVecBase2::operator + (other); } //////////////////////////////////////////////////////////////////// @@ -173,10 +136,10 @@ operator + (const FLOATNAME(LVecBase2) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2) FLOATNAME(LVector2):: -operator + (const FLOATNAME(LVector2) &other) const { - return FLOATNAME(LVecBase2)::operator + (other); +template +INLINE LVector2 LVector2:: +operator + (const LVector2 &other) const { + return LVecBase2::operator + (other); } //////////////////////////////////////////////////////////////////// @@ -184,10 +147,10 @@ operator + (const FLOATNAME(LVector2) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase2) FLOATNAME(LVector2):: -operator - (const FLOATNAME(LVecBase2) &other) const { - return FLOATNAME(LVecBase2)::operator - (other); +template +INLINE LVecBase2 LVector2:: +operator - (const LVecBase2 &other) const { + return LVecBase2::operator - (other); } //////////////////////////////////////////////////////////////////// @@ -195,10 +158,10 @@ operator - (const FLOATNAME(LVecBase2) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2) FLOATNAME(LVector2):: -operator - (const FLOATNAME(LVector2) &other) const { - return FLOATNAME(LVecBase2)::operator - (other); +template +INLINE LVector2 LVector2:: +operator - (const LVector2 &other) const { + return LVecBase2::operator - (other); } //////////////////////////////////////////////////////////////////// @@ -207,8 +170,8 @@ operator - (const FLOATNAME(LVector2) &other) const { // Description: Returns the length of the vector, by the Pythagorean // theorem. //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVector2):: +template +INLINE NumType LVector2:: length() const { return csqrt((*this).dot(*this)); } @@ -219,8 +182,8 @@ length() const { // Description: Returns the square of the vector's length, cheap and // easy. //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVector2):: +template +INLINE NumType LVector2:: length_squared() const { return (*this).dot(*this); } @@ -232,15 +195,15 @@ length_squared() const { // vector was normalized, false if it was a zero-length // vector. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVector2):: +template +INLINE bool LVector2:: normalize() { - FLOATTYPE1 l2 = length_squared(); - if (l2 == (FLOATTYPE1)0.0) { + NumType l2 = length_squared(); + if (l2 == (NumType)0.0) { set(0.0, 0.0); return false; - } else if (!IS_THRESHOLD_EQUAL(l2, 1.0, NEARLY_ZERO(FLOATTYPE1) * NEARLY_ZERO(FLOATTYPE1))) { + } else if (!IS_THRESHOLD_EQUAL(l2, 1.0, NEARLY_ZERO(NumType) * NEARLY_ZERO(NumType))) { (*this) /= csqrt(l2); } @@ -252,10 +215,10 @@ normalize() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2) FLOATNAME(LVector2):: -operator * (FLOATTYPE1 scalar) const { - return FLOATNAME(LVector2)(FLOATNAME(LVecBase2)::operator * (scalar)); +template +INLINE LVector2 LVector2:: +operator * (NumType scalar) const { + return LVector2(LVecBase2::operator * (scalar)); } //////////////////////////////////////////////////////////////////// @@ -263,9 +226,37 @@ operator * (FLOATTYPE1 scalar) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector2) FLOATNAME(LVector2):: -operator / (FLOATTYPE1 scalar) const { - return FLOATNAME(LVector2)(FLOATNAME(LVecBase2)::operator / (scalar)); +template +INLINE LVector2 LVector2:: +operator / (NumType scalar) const { + return LVector2(LVecBase2::operator / (scalar)); } +//////////////////////////////////////////////////////////////////// +// Function: LVector2::init_type +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +template +void LVector2:: +init_type() { + if (_type_handle == TypeHandle::none()) { + LVecBase2::init_type(); + string name = + "LVector2<" + get_type_handle(NumType).get_name() + ">"; + register_type(_type_handle, name, + LVecBase2::get_class_type()); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: lcast_to +// Description: Converts a vector from one numeric representation to +// another one. This is usually invoked using the macro +// LCAST. +//////////////////////////////////////////////////////////////////// +template +INLINE LVector2 +lcast_to(NumType2 *, const LVector2 &source) { + return LVector2(source[0], source[1]); +} diff --git a/panda/src/linmath/lvector2.h b/panda/src/linmath/lvector2.h index 367c2ee2b8..42f3406722 100644 --- a/panda/src/linmath/lvector2.h +++ b/panda/src/linmath/lvector2.h @@ -7,35 +7,63 @@ #define LVECTOR2_H #include -#include "cmath.h" -#include "config_linmath.h" + #include "lvecBase2.h" -#include "fltnames.I" +//////////////////////////////////////////////////////////////////// +// Class : LVector2 +// Description : This is a two-component vector offset. +//////////////////////////////////////////////////////////////////// +template +class LVector2 : public LVecBase2 { +PUBLISHED: + INLINE LVector2(); + INLINE LVector2(const LVecBase2 ©); + INLINE LVector2 &operator = (const LVecBase2 ©); + INLINE LVector2 &operator = (NumType fill_value); + INLINE LVector2(NumType fill_value); + INLINE LVector2(NumType x, NumType y); + + INLINE static LVector2 zero(); + INLINE static LVector2 unit_x(); + INLINE static LVector2 unit_y(); + + INLINE LVector2 operator - () const; + + INLINE LVecBase2 + operator + (const LVecBase2 &other) const; + INLINE LVector2 + operator + (const LVector2 &other) const; + + INLINE LVecBase2 + operator - (const LVecBase2 &other) const; + INLINE LVector2 + operator - (const LVector2 &other) const; + + INLINE NumType length() const; + INLINE NumType length_squared() const; + INLINE bool normalize(); + INLINE LVector2 operator * (NumType scalar) const; + INLINE LVector2 operator / (NumType scalar) const; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type(); + +private: + static TypeHandle _type_handle; +}; + +// Cast to a different numeric type +template +INLINE LVector2 +lcast_to(NumType2 *type, const LVector2 &source); + #include "lvector2.I" -#include "dblnames.I" -#include "lvector2.I" - -//////////////////////////////////////////////////////////////////// -// Function: lcast_to -// Description: Converts a vector from one numeric representation to -// another one. This is usually invoked using the macro -// LCAST. -//////////////////////////////////////////////////////////////////// -INLINE FLOATNAME2(LVector2) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LVector2) &source) { - return FLOATNAME2(LVector2)(source[0], source[1]); -} - -#include "fltnames.I" - -INLINE FLOATNAME2(LVector2) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LVector2) &source) { - return FLOATNAME2(LVector2)(source[0], source[1]); -} - - - +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVector2) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVector2) #endif diff --git a/panda/src/linmath/lvector3.I b/panda/src/linmath/lvector3.I index e0bb1becf5..81aa9a66a2 100644 --- a/panda/src/linmath/lvector3.I +++ b/panda/src/linmath/lvector3.I @@ -3,79 +3,20 @@ // //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Class : LVector3 -// Description : This is a three-component vector distance (as opposed -// to a three-component point, which represents a -// particular point in space). Some of the methods are -// slightly different between LPoint3 and LVector3; in -// particular, subtraction of two points yields a -// vector, while addition of a vector and a point yields -// a point. -//////////////////////////////////////////////////////////////////// +#include "config_linmath.h" +#include "cmath.h" -class EXPCL_PANDA FLOATNAME(LVector3) : public FLOATNAME(LVecBase3) { -PUBLISHED: - INLINE FLOATNAME(LVector3)(); - INLINE FLOATNAME(LVector3)(const FLOATNAME(LVecBase3) ©); - INLINE FLOATNAME(LVector3) &operator = (const FLOATNAME(LVecBase3) ©); - INLINE FLOATNAME(LVector3) &operator = (FLOATTYPE1 fill_value); - INLINE FLOATNAME(LVector3)(FLOATTYPE1 fill_value); - INLINE FLOATNAME(LVector3)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z); - - INLINE static FLOATNAME(LVector3) zero(); - INLINE static FLOATNAME(LVector3) unit_x(); - INLINE static FLOATNAME(LVector3) unit_y(); - INLINE static FLOATNAME(LVector3) unit_z(); - - INLINE FLOATNAME(LVector3) operator - () const; - - INLINE FLOATNAME(LVecBase3) operator + (const FLOATNAME(LVecBase3) &other) const; - INLINE FLOATNAME(LVector3) operator + (const FLOATNAME(LVector3) &other) const; - - INLINE FLOATNAME(LVecBase3) operator - (const FLOATNAME(LVecBase3) &other) const; - INLINE FLOATNAME(LVector3) operator - (const FLOATNAME(LVector3) &other) const; - - INLINE FLOATTYPE1 length() const; - INLINE FLOATTYPE1 length_squared() const; - INLINE bool normalize(); - INLINE FLOATNAME(LVector3) cross(const FLOATNAME(LVecBase3) &other) const; - INLINE FLOATNAME(LVector3) operator * (FLOATTYPE1 scalar) const; - INLINE FLOATNAME(LVector3) operator / (FLOATTYPE1 scalar) const; - - // Some special named constructors for LVector3. - - INLINE static FLOATNAME(LVector3) up(CoordinateSystem cs = CS_default); - INLINE static FLOATNAME(LVector3) right(CoordinateSystem cs = CS_default); - INLINE static FLOATNAME(LVector3) forward(CoordinateSystem cs = CS_default); - - INLINE static FLOATNAME(LVector3) down(CoordinateSystem cs = CS_default); - INLINE static FLOATNAME(LVector3) left(CoordinateSystem cs = CS_default); - INLINE static FLOATNAME(LVector3) back(CoordinateSystem cs = CS_default); - - INLINE static FLOATNAME(LVector3) rfu(FLOATTYPE1 right, - FLOATTYPE1 fwd, - FLOATTYPE1 up, - CoordinateSystem cs = CS_default); - -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type(); - -private: - static TypeHandle _type_handle; -}; +template +TypeHandle LVector3::_type_handle; //////////////////////////////////////////////////////////////////// // Function: LVector3::Default Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3):: -FLOATNAME(LVector3)() { +template +INLINE LVector3:: +LVector3() { } //////////////////////////////////////////////////////////////////// @@ -83,9 +24,9 @@ FLOATNAME(LVector3)() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3):: -FLOATNAME(LVector3)(const FLOATNAME(LVecBase3) ©) : FLOATNAME(LVecBase3)(copy) { +template +INLINE LVector3:: +LVector3(const LVecBase3 ©) : LVecBase3(copy) { } //////////////////////////////////////////////////////////////////// @@ -93,10 +34,10 @@ FLOATNAME(LVector3)(const FLOATNAME(LVecBase3) ©) : FLOATNAME(LVecBase3)(cop // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) &FLOATNAME(LVector3):: -operator = (const FLOATNAME(LVecBase3) ©) { - FLOATNAME(LVecBase3)::operator = (copy); +template +INLINE LVector3 &LVector3:: +operator = (const LVecBase3 ©) { + LVecBase3::operator = (copy); return *this; } @@ -105,10 +46,10 @@ operator = (const FLOATNAME(LVecBase3) ©) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) &FLOATNAME(LVector3):: -operator = (FLOATTYPE1 fill_value) { - FLOATNAME(LVecBase3)::operator = (fill_value); +template +INLINE LVector3 &LVector3:: +operator = (NumType fill_value) { + LVecBase3::operator = (fill_value); return *this; } @@ -117,10 +58,10 @@ operator = (FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3):: -FLOATNAME(LVector3)(FLOATTYPE1 fill_value) : - FLOATNAME(LVecBase3)(fill_value) +template +INLINE LVector3:: +LVector3(NumType fill_value) : + LVecBase3(fill_value) { } @@ -129,10 +70,10 @@ FLOATNAME(LVector3)(FLOATTYPE1 fill_value) : // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3):: -FLOATNAME(LVector3)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z) : - FLOATNAME(LVecBase3)(x, y, z) +template +INLINE LVector3:: +LVector3(NumType x, NumType y, NumType z) : + LVecBase3(x, y, z) { } @@ -141,10 +82,10 @@ FLOATNAME(LVector3)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z) : // Access: Public // Description: Returns a zero-length vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: +template +INLINE LVector3 LVector3:: zero() { - return FLOATNAME(LVector3)(0.0, 0.0, 0.0); + return LVector3(0.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -152,10 +93,10 @@ zero() { // Access: Public // Description: Returns a unit X vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: +template +INLINE LVector3 LVector3:: unit_x() { - return FLOATNAME(LVector3)(1.0, 0.0, 0.0); + return LVector3(1.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -163,10 +104,10 @@ unit_x() { // Access: Public // Description: Returns a unit Y vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: +template +INLINE LVector3 LVector3:: unit_y() { - return FLOATNAME(LVector3)(0.0, 1.0, 0.0); + return LVector3(0.0, 1.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -174,10 +115,10 @@ unit_y() { // Access: Public // Description: Returns a unit Z vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: +template +INLINE LVector3 LVector3:: unit_z() { - return FLOATNAME(LVector3)(0.0, 0.0, 1.0); + return LVector3(0.0, 0.0, 1.0); } //////////////////////////////////////////////////////////////////// @@ -185,10 +126,10 @@ unit_z() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: +template +INLINE LVector3 LVector3:: operator - () const { - return FLOATNAME(LVecBase3)::operator - (); + return LVecBase3::operator - (); } //////////////////////////////////////////////////////////////////// @@ -196,10 +137,10 @@ operator - () const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LVector3):: -operator + (const FLOATNAME(LVecBase3) &other) const { - return FLOATNAME(LVecBase3)::operator + (other); +template +INLINE LVecBase3 LVector3:: +operator + (const LVecBase3 &other) const { + return LVecBase3::operator + (other); } //////////////////////////////////////////////////////////////////// @@ -207,10 +148,10 @@ operator + (const FLOATNAME(LVecBase3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: -operator + (const FLOATNAME(LVector3) &other) const { - return FLOATNAME(LVecBase3)::operator + (other); +template +INLINE LVector3 LVector3:: +operator + (const LVector3 &other) const { + return LVecBase3::operator + (other); } //////////////////////////////////////////////////////////////////// @@ -218,10 +159,10 @@ operator + (const FLOATNAME(LVector3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase3) FLOATNAME(LVector3):: -operator - (const FLOATNAME(LVecBase3) &other) const { - return FLOATNAME(LVecBase3)::operator - (other); +template +INLINE LVecBase3 LVector3:: +operator - (const LVecBase3 &other) const { + return LVecBase3::operator - (other); } //////////////////////////////////////////////////////////////////// @@ -229,10 +170,10 @@ operator - (const FLOATNAME(LVecBase3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: -operator - (const FLOATNAME(LVector3) &other) const { - return FLOATNAME(LVecBase3)::operator - (other); +template +INLINE LVector3 LVector3:: +operator - (const LVector3 &other) const { + return LVecBase3::operator - (other); } //////////////////////////////////////////////////////////////////// @@ -241,8 +182,8 @@ operator - (const FLOATNAME(LVector3) &other) const { // Description: Returns the length of the vector, by the Pythagorean // theorem. //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVector3):: +template +INLINE NumType LVector3:: length() const { return csqrt((*this).dot(*this)); } @@ -253,8 +194,8 @@ length() const { // Description: Returns the square of the vector's length, cheap and // easy. //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVector3):: +template +INLINE NumType LVector3:: length_squared() const { return (*this).dot(*this); } @@ -266,15 +207,15 @@ length_squared() const { // vector was normalized, false if it was a zero-length // vector. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVector3):: +template +INLINE bool LVector3:: normalize() { - FLOATTYPE1 l2 = length_squared(); - if (l2 == (FLOATTYPE1)0.0) { + NumType l2 = length_squared(); + if (l2 == (NumType)0.0) { set(0.0, 0.0, 0.0); return false; - } else if (!IS_THRESHOLD_EQUAL(l2, 1.0, NEARLY_ZERO(FLOATTYPE1) * NEARLY_ZERO(FLOATTYPE1))) { + } else if (!IS_THRESHOLD_EQUAL(l2, 1.0, NEARLY_ZERO(NumType) * NEARLY_ZERO(NumType))) { (*this) /= csqrt(l2); } @@ -286,10 +227,10 @@ normalize() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: -cross(const FLOATNAME(LVecBase3) &other) const { - return FLOATNAME(LVecBase3)::cross(other); +template +INLINE LVector3 LVector3:: +cross(const LVecBase3 &other) const { + return LVecBase3::cross(other); } //////////////////////////////////////////////////////////////////// @@ -297,10 +238,10 @@ cross(const FLOATNAME(LVecBase3) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: -operator * (FLOATTYPE1 scalar) const { - return FLOATNAME(LVector3)(FLOATNAME(LVecBase3)::operator * (scalar)); +template +INLINE LVector3 LVector3:: +operator * (NumType scalar) const { + return LVector3(LVecBase3::operator * (scalar)); } //////////////////////////////////////////////////////////////////// @@ -308,10 +249,10 @@ operator * (FLOATTYPE1 scalar) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: -operator / (FLOATTYPE1 scalar) const { - return FLOATNAME(LVector3)(FLOATNAME(LVecBase3)::operator / (scalar)); +template +INLINE LVector3 LVector3:: +operator / (NumType scalar) const { + return LVector3(LVecBase3::operator / (scalar)); } //////////////////////////////////////////////////////////////////// @@ -320,8 +261,8 @@ operator / (FLOATTYPE1 scalar) const { // Description: Returns the up vector for the given coordinate // system. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: +template +LVector3 LVector3:: up(CoordinateSystem cs) { if (cs == CS_default) { cs = default_coordinate_system; @@ -329,16 +270,16 @@ up(CoordinateSystem cs) { switch (cs) { case CS_zup_right: case CS_zup_left: - return FLOATNAME(LVector3)(0.0, 0.0, 1.0); + return LVector3(0.0, 0.0, 1.0); case CS_yup_right: case CS_yup_left: - return FLOATNAME(LVector3)(0.0, 1.0, 0.0); + return LVector3(0.0, 1.0, 0.0); default: linmath_cat.error() << "Invalid coordinate system!\n"; - return FLOATNAME(LVector3)(0.0, 0.0, 0.0); + return LVector3(0.0, 0.0, 0.0); } } @@ -348,10 +289,10 @@ up(CoordinateSystem cs) { // Description: Returns the right vector for the given coordinate // system. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: +template +INLINE LVector3 LVector3:: right(CoordinateSystem) { - return FLOATNAME(LVector3)(1.0, 0.0, 0.0); + return LVector3(1.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -360,29 +301,29 @@ right(CoordinateSystem) { // Description: Returns the forward vector for the given coordinate // system. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: +template +LVector3 LVector3:: forward(CoordinateSystem cs) { if (cs == CS_default) { cs = default_coordinate_system; } switch (cs) { case CS_zup_right: - return FLOATNAME(LVector3)(0.0, 1.0, 0.0); + return LVector3(0.0, 1.0, 0.0); case CS_zup_left: - return FLOATNAME(LVector3)(0.0, -1.0, 0.0); + return LVector3(0.0, -1.0, 0.0); case CS_yup_right: - return FLOATNAME(LVector3)(0.0, 0.0, -1.0); + return LVector3(0.0, 0.0, -1.0); case CS_yup_left: - return FLOATNAME(LVector3)(0.0, 0.0, 1.0); + return LVector3(0.0, 0.0, 1.0); default: linmath_cat.error() << "Invalid coordinate system!\n"; - return FLOATNAME(LVector3)(0.0, 0.0, 0.0); + return LVector3(0.0, 0.0, 0.0); } } @@ -392,8 +333,8 @@ forward(CoordinateSystem cs) { // Description: Returns the down vector for the given coordinate // system. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: +template +INLINE LVector3 LVector3:: down(CoordinateSystem cs) { return -up(cs); } @@ -404,8 +345,8 @@ down(CoordinateSystem cs) { // Description: Returns the left vector for the given coordinate // system. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: +template +INLINE LVector3 LVector3:: left(CoordinateSystem cs) { return -right(cs); } @@ -416,8 +357,8 @@ left(CoordinateSystem cs) { // Description: Returns the back vector for the given coordinate // system. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: +template +INLINE LVector3 LVector3:: back(CoordinateSystem cs) { return -forward(cs); } @@ -429,10 +370,38 @@ back(CoordinateSystem cs) { // forward, and up components, in whatever way the // coordinate system represents that vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(LVector3):: -rfu(FLOATTYPE1 right_v, FLOATTYPE1 fwd_v, FLOATTYPE1 up_v, +template +INLINE LVector3 LVector3:: +rfu(NumType right_v, NumType fwd_v, NumType up_v, CoordinateSystem cs) { - return forward(cs) * fwd_v + up(cs) * up_v + right(cs) * right_v; + return fwd_v * forward(cs) + up_v * up(cs) + right_v * right(cs); } +//////////////////////////////////////////////////////////////////// +// Function: LVector3::init_type +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +template +void LVector3:: +init_type() { + if (_type_handle == TypeHandle::none()) { + LVecBase3::init_type(); + string name = + "LVector3<" + get_type_handle(NumType).get_name() + ">"; + register_type(_type_handle, name, + LVecBase3::get_class_type()); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: lcast_to +// Description: Converts a vector from one numeric representation to +// another one. This is usually invoked using the macro +// LCAST. +//////////////////////////////////////////////////////////////////// +template +INLINE LVector3 +lcast_to(NumType2 *, const LVector3 &source) { + return LVector3(source[0], source[1], source[2]); +} diff --git a/panda/src/linmath/lvector3.h b/panda/src/linmath/lvector3.h index 5ceec1c655..f2c2e3c117 100644 --- a/panda/src/linmath/lvector3.h +++ b/panda/src/linmath/lvector3.h @@ -9,37 +9,85 @@ #include #include "coordinateSystem.h" -#include "cmath.h" -#include "config_linmath.h" #include "lvecBase3.h" -#include "fltnames.I" +//////////////////////////////////////////////////////////////////// +// Class : LVector3 +// Description : This is a three-component vector distance (as opposed +// to a three-component point, which represents a +// particular point in space). Some of the methods are +// slightly different between LPoint3 and LVector3; in +// particular, subtraction of two points yields a +// vector, while addition of a vector and a point yields +// a point. +//////////////////////////////////////////////////////////////////// +template +class LVector3 : public LVecBase3 { +PUBLISHED: + INLINE LVector3(); + INLINE LVector3(const LVecBase3 ©); + INLINE LVector3 &operator = (const LVecBase3 ©); + INLINE LVector3 &operator = (NumType fill_value); + INLINE LVector3(NumType fill_value); + INLINE LVector3(NumType x, NumType y, NumType z); + + INLINE static LVector3 zero(); + INLINE static LVector3 unit_x(); + INLINE static LVector3 unit_y(); + INLINE static LVector3 unit_z(); + + INLINE LVector3 operator - () const; + + INLINE LVecBase3 + operator + (const LVecBase3 &other) const; + INLINE LVector3 + operator + (const LVector3 &other) const; + + INLINE LVecBase3 + operator - (const LVecBase3 &other) const; + INLINE LVector3 + operator - (const LVector3 &other) const; + + INLINE NumType length() const; + INLINE NumType length_squared() const; + INLINE bool normalize(); + INLINE LVector3 cross(const LVecBase3 &other) const; + INLINE LVector3 operator * (NumType scalar) const; + INLINE LVector3 operator / (NumType scalar) const; + + // Some special named constructors for LVector3. + + static LVector3 up(CoordinateSystem cs = CS_default); + INLINE static LVector3 right(CoordinateSystem cs = CS_default); + static LVector3 forward(CoordinateSystem cs = CS_default); + + INLINE static LVector3 down(CoordinateSystem cs = CS_default); + INLINE static LVector3 left(CoordinateSystem cs = CS_default); + INLINE static LVector3 back(CoordinateSystem cs = CS_default); + + INLINE static LVector3 rfu(NumType right, + NumType fwd, + NumType up, + CoordinateSystem cs = CS_default); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type(); + +private: + static TypeHandle _type_handle; +}; + +// Cast to a different numeric type +template +INLINE LVector3 +lcast_to(NumType2 *type, const LVector3 &source); + #include "lvector3.I" -#include "dblnames.I" -#include "lvector3.I" - -//////////////////////////////////////////////////////////////////// -// Function: lcast_to -// Description: Converts a vector from one numeric representation to -// another one. This is usually invoked using the macro -// LCAST. -//////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME2(LVector3) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LVector3) &source) { - return FLOATNAME2(LVector3)(source[0], source[1], source[2]); -} - - -#include "fltnames.I" - -INLINE FLOATNAME2(LVector3) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LVector3) &source) { - return FLOATNAME2(LVector3)(source[0], source[1], source[2]); -} - - - +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVector3) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVector3) #endif diff --git a/panda/src/linmath/lvector4.I b/panda/src/linmath/lvector4.I index eba27af8ac..841f0ee850 100644 --- a/panda/src/linmath/lvector4.I +++ b/panda/src/linmath/lvector4.I @@ -3,58 +3,20 @@ // //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Class : LVector4 -// Description : This is a four-component vector distance. -//////////////////////////////////////////////////////////////////// +#include "cmath.h" -class EXPCL_PANDA FLOATNAME(LVector4) : public FLOATNAME(LVecBase4) { -PUBLISHED: - INLINE FLOATNAME(LVector4)(); - INLINE FLOATNAME(LVector4)(const FLOATNAME(LVecBase4) ©); - INLINE FLOATNAME(LVector4) &operator = (const FLOATNAME(LVecBase4) ©); - INLINE FLOATNAME(LVector4) &operator = (FLOATTYPE1 fill_value); - INLINE FLOATNAME(LVector4)(FLOATTYPE1 fill_value); - INLINE FLOATNAME(LVector4)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w); - INLINE static FLOATNAME(LVector4) zero(); - INLINE static FLOATNAME(LVector4) unit_x(); - INLINE static FLOATNAME(LVector4) unit_y(); - INLINE static FLOATNAME(LVector4) unit_z(); - INLINE static FLOATNAME(LVector4) unit_w(); - - INLINE FLOATNAME(LVector4) operator - () const; - - INLINE FLOATNAME(LVecBase4) operator + (const FLOATNAME(LVecBase4) &other) const; - INLINE FLOATNAME(LVector4) operator + (const FLOATNAME(LVector4) &other) const; - - INLINE FLOATNAME(LVecBase4) operator - (const FLOATNAME(LVecBase4) &other) const; - INLINE FLOATNAME(LVector4) operator - (const FLOATNAME(LVector4) &other) const; - - INLINE FLOATTYPE1 length() const; - INLINE FLOATTYPE1 length_squared() const; - INLINE bool normalize(); - INLINE FLOATNAME(LVector4) operator * (FLOATTYPE1 scalar) const; - INLINE FLOATNAME(LVector4) operator / (FLOATTYPE1 scalar) const; - -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type(); - -private: - static TypeHandle _type_handle; -}; +template +TypeHandle LVector4::_type_handle; //////////////////////////////////////////////////////////////////// // Function: LVector4::Default Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4):: -FLOATNAME(LVector4)() { +template +INLINE LVector4:: +LVector4() { } //////////////////////////////////////////////////////////////////// @@ -62,9 +24,9 @@ FLOATNAME(LVector4)() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4):: -FLOATNAME(LVector4)(const FLOATNAME(LVecBase4) ©) : FLOATNAME(LVecBase4)(copy) { +template +INLINE LVector4:: +LVector4(const LVecBase4 ©) : LVecBase4(copy) { } //////////////////////////////////////////////////////////////////// @@ -72,10 +34,10 @@ FLOATNAME(LVector4)(const FLOATNAME(LVecBase4) ©) : FLOATNAME(LVecBase4)(cop // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4) &FLOATNAME(LVector4):: -operator = (const FLOATNAME(LVecBase4) ©) { - FLOATNAME(LVecBase4)::operator = (copy); +template +INLINE LVector4 &LVector4:: +operator = (const LVecBase4 ©) { + LVecBase4::operator = (copy); return *this; } @@ -84,10 +46,10 @@ operator = (const FLOATNAME(LVecBase4) ©) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4) &FLOATNAME(LVector4):: -operator = (FLOATTYPE1 fill_value) { - FLOATNAME(LVecBase4)::operator = (fill_value); +template +INLINE LVector4 &LVector4:: +operator = (NumType fill_value) { + LVecBase4::operator = (fill_value); return *this; } @@ -96,10 +58,10 @@ operator = (FLOATTYPE1 fill_value) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4):: -FLOATNAME(LVector4)(FLOATTYPE1 fill_value) : - FLOATNAME(LVecBase4)(fill_value) +template +INLINE LVector4:: +LVector4(NumType fill_value) : + LVecBase4(fill_value) { } @@ -108,10 +70,10 @@ FLOATNAME(LVector4)(FLOATTYPE1 fill_value) : // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4):: -FLOATNAME(LVector4)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w) : - FLOATNAME(LVecBase4)(x, y, z, w) +template +INLINE LVector4:: +LVector4(NumType x, NumType y, NumType z, NumType w) : + LVecBase4(x, y, z, w) { } @@ -120,10 +82,10 @@ FLOATNAME(LVector4)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w) : // Access: Public // Description: Returns a zero-length vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4) FLOATNAME(LVector4):: +template +INLINE LVector4 LVector4:: zero() { - return FLOATNAME(LVector4)(0.0, 0.0, 0.0, 0.0); + return LVector4(0.0, 0.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -131,10 +93,10 @@ zero() { // Access: Public // Description: Returns a unit X vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4) FLOATNAME(LVector4):: +template +INLINE LVector4 LVector4:: unit_x() { - return FLOATNAME(LVector4)(1.0, 0.0, 0.0, 0.0); + return LVector4(1.0, 0.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -142,10 +104,10 @@ unit_x() { // Access: Public // Description: Returns a unit Y vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4) FLOATNAME(LVector4):: +template +INLINE LVector4 LVector4:: unit_y() { - return FLOATNAME(LVector4)(0.0, 1.0, 0.0, 0.0); + return LVector4(0.0, 1.0, 0.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -153,10 +115,10 @@ unit_y() { // Access: Public // Description: Returns a unit Z vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4) FLOATNAME(LVector4):: +template +INLINE LVector4 LVector4:: unit_z() { - return FLOATNAME(LVector4)(0.0, 0.0, 1.0, 0.0); + return LVector4(0.0, 0.0, 1.0, 0.0); } //////////////////////////////////////////////////////////////////// @@ -164,10 +126,10 @@ unit_z() { // Access: Public // Description: Returns a unit W vector. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4) FLOATNAME(LVector4):: +template +INLINE LVector4 LVector4:: unit_w() { - return FLOATNAME(LVector4)(0.0, 0.0, 0.0, 1.0); + return LVector4(0.0, 0.0, 0.0, 1.0); } //////////////////////////////////////////////////////////////////// @@ -175,10 +137,10 @@ unit_w() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4) FLOATNAME(LVector4):: +template +INLINE LVector4 LVector4:: operator - () const { - return FLOATNAME(LVecBase4)::operator - (); + return LVecBase4::operator - (); } //////////////////////////////////////////////////////////////////// @@ -186,10 +148,10 @@ operator - () const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LVector4):: -operator + (const FLOATNAME(LVecBase4) &other) const { - return FLOATNAME(LVecBase4)::operator + (other); +template +INLINE LVecBase4 LVector4:: +operator + (const LVecBase4 &other) const { + return LVecBase4::operator + (other); } //////////////////////////////////////////////////////////////////// @@ -197,10 +159,10 @@ operator + (const FLOATNAME(LVecBase4) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4) FLOATNAME(LVector4):: -operator + (const FLOATNAME(LVector4) &other) const { - return FLOATNAME(LVecBase4)::operator + (other); +template +INLINE LVector4 LVector4:: +operator + (const LVector4 &other) const { + return LVecBase4::operator + (other); } //////////////////////////////////////////////////////////////////// @@ -208,10 +170,10 @@ operator + (const FLOATNAME(LVector4) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVecBase4) FLOATNAME(LVector4):: -operator - (const FLOATNAME(LVecBase4) &other) const { - return FLOATNAME(LVecBase4)::operator - (other); +template +INLINE LVecBase4 LVector4:: +operator - (const LVecBase4 &other) const { + return LVecBase4::operator - (other); } //////////////////////////////////////////////////////////////////// @@ -219,10 +181,10 @@ operator - (const FLOATNAME(LVecBase4) &other) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4) FLOATNAME(LVector4):: -operator - (const FLOATNAME(LVector4) &other) const { - return FLOATNAME(LVecBase4)::operator - (other); +template +INLINE LVector4 LVector4:: +operator - (const LVector4 &other) const { + return LVecBase4::operator - (other); } //////////////////////////////////////////////////////////////////// @@ -231,8 +193,8 @@ operator - (const FLOATNAME(LVector4) &other) const { // Description: Returns the length of the vector, by the Pythagorean // theorem. //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVector4):: +template +INLINE NumType LVector4:: length() const { return csqrt((*this).dot(*this)); } @@ -243,8 +205,8 @@ length() const { // Description: Returns the square of the vector's length, cheap and // easy. //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(LVector4):: +template +INLINE NumType LVector4:: length_squared() const { return (*this).dot(*this); } @@ -256,15 +218,15 @@ length_squared() const { // vector was normalized, false if it was a zero-length // vector. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(LVector4):: +template +INLINE bool LVector4:: normalize() { - FLOATTYPE1 l2 = length_squared(); - if (l2 == (FLOATTYPE1)0.0) { + NumType l2 = length_squared(); + if (l2 == (NumType)0.0) { set(0.0, 0.0, 0.0, 0.0); return false; - } else if (!IS_THRESHOLD_EQUAL(l2, 1.0, NEARLY_ZERO(FLOATTYPE1) * NEARLY_ZERO(FLOATTYPE1))) { + } else if (!IS_THRESHOLD_EQUAL(l2, 1.0, NEARLY_ZERO(NumType) * NEARLY_ZERO(NumType))) { (*this) /= csqrt(l2); } @@ -276,10 +238,10 @@ normalize() { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4) FLOATNAME(LVector4):: -operator * (FLOATTYPE1 scalar) const { - return FLOATNAME(LVector4)(FLOATNAME(LVecBase4)::operator * (scalar)); +template +INLINE LVector4 LVector4:: +operator * (NumType scalar) const { + return LVector4(LVecBase4::operator * (scalar)); } //////////////////////////////////////////////////////////////////// @@ -287,9 +249,37 @@ operator * (FLOATTYPE1 scalar) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector4) FLOATNAME(LVector4):: -operator / (FLOATTYPE1 scalar) const { - return FLOATNAME(LVector4)(FLOATNAME(LVecBase4)::operator / (scalar)); +template +INLINE LVector4 LVector4:: +operator / (NumType scalar) const { + return LVector4(LVecBase4::operator / (scalar)); } +//////////////////////////////////////////////////////////////////// +// Function: LVector4::init_type +// Access: Public, Static +// Description: +//////////////////////////////////////////////////////////////////// +template +void LVector4:: +init_type() { + if (_type_handle == TypeHandle::none()) { + LVecBase4::init_type(); + string name = + "LVector4<" + get_type_handle(NumType).get_name() + ">"; + register_type(_type_handle, name, + LVecBase4::get_class_type()); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: lcast_to +// Description: Converts a vector from one numeric representation to +// another one. This is usually invoked using the macro +// LCAST. +//////////////////////////////////////////////////////////////////// +template +INLINE LVector4 +lcast_to(NumType2 *, const LVector4 &source) { + return LVector4(source[0], source[1], source[2], source[3]); +} diff --git a/panda/src/linmath/lvector4.h b/panda/src/linmath/lvector4.h index 0536e61f50..37164261c2 100644 --- a/panda/src/linmath/lvector4.h +++ b/panda/src/linmath/lvector4.h @@ -7,34 +7,64 @@ #define LVECTOR4_H #include -#include "cmath.h" -#include "config_linmath.h" + #include "lvecBase4.h" -#include "fltnames.I" +//////////////////////////////////////////////////////////////////// +// Class : LVector4 +// Description : This is a four-component vector distance. +//////////////////////////////////////////////////////////////////// +template +class LVector4 : public LVecBase4 { +PUBLISHED: + INLINE LVector4(); + INLINE LVector4(const LVecBase4 ©); + INLINE LVector4 &operator = (const LVecBase4 ©); + INLINE LVector4 &operator = (NumType fill_value); + INLINE LVector4(NumType fill_value); + INLINE LVector4(NumType x, NumType y, NumType z, NumType w); + + INLINE static LVector4 zero(); + INLINE static LVector4 unit_x(); + INLINE static LVector4 unit_y(); + INLINE static LVector4 unit_z(); + INLINE static LVector4 unit_w(); + + INLINE LVector4 operator - () const; + + INLINE LVecBase4 + operator + (const LVecBase4 &other) const; + INLINE LVector4 + operator + (const LVector4 &other) const; + + INLINE LVecBase4 + operator - (const LVecBase4 &other) const; + INLINE LVector4 + operator - (const LVector4 &other) const; + + INLINE NumType length() const; + INLINE NumType length_squared() const; + INLINE bool normalize(); + INLINE LVector4 operator * (NumType scalar) const; + INLINE LVector4 operator / (NumType scalar) const; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type(); + +private: + static TypeHandle _type_handle; +}; + +template +INLINE LVector4 +lcast_to(NumType2 *type, const LVector4 &source); + #include "lvector4.I" -#include "dblnames.I" -#include "lvector4.I" - -//////////////////////////////////////////////////////////////////// -// Function: lcast_to -// Description: Converts a vector from one numeric representation to -// another one. This is usually invoked using the macro -// LCAST. -//////////////////////////////////////////////////////////////////// -INLINE FLOATNAME2(LVector4) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LVector4) &source) { - return FLOATNAME2(LVector4)(source[0], source[1], source[2], source[3]); -} - -#include "fltnames.I" -INLINE FLOATNAME2(LVector4) -lcast_to(FLOATTYPE2 *, const FLOATNAME(LVector4) &source) { - return FLOATNAME2(LVector4)(source[0], source[1], source[2], source[3]); -} - - - +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVector4) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVector4) #endif diff --git a/panda/src/linmath/nearly_zero.h b/panda/src/linmath/nearly_zero.h index b27ac2a00b..31de0a048a 100644 --- a/panda/src/linmath/nearly_zero.h +++ b/panda/src/linmath/nearly_zero.h @@ -35,7 +35,7 @@ get_nearly_zero_value(float) { // NEARLY_ZERO(float) returns a number that is considered to be so // close to zero as not to matter for a float. NEARLY_ZERO(double) // returns a similar, smaller number for a double. -#define NEARLY_ZERO(FLOATTYPE1) (get_nearly_zero_value((FLOATTYPE1)0)) +#define NEARLY_ZERO(NumType) (get_nearly_zero_value((NumType)0)) // IS_NEARLY_ZERO(value) returns true if the value is very close to // zero. diff --git a/panda/src/mathutil/Sources.pp b/panda/src/mathutil/Sources.pp index 27ec25c7a5..96a7be4047 100644 --- a/panda/src/mathutil/Sources.pp +++ b/panda/src/mathutil/Sources.pp @@ -16,11 +16,11 @@ config_mathutil.h \ fftCompressor.cxx fftCompressor.h \ finiteBoundingVolume.cxx finiteBoundingVolume.h \ - frustum.I frustum.h frustum.N plane.N\ + frustum.I frustum.h \ geometricBoundingVolume.I geometricBoundingVolume.cxx \ - geometricBoundingVolume.h look_at.I look_at.cxx look_at.h look_at_src.I\ + geometricBoundingVolume.h look_at.I look_at.cxx look_at.h \ omniBoundingVolume.I omniBoundingVolume.cxx omniBoundingVolume.h \ - plane.I plane.cxx plane.h rotate_to.cxx rotate_to_src.I rotate_to.h + plane.I plane.N plane.cxx plane.h rotate_to.cxx rotate_to.h #define INSTALL_HEADERS \ boundingHexahedron.I boundingHexahedron.h boundingLine.I \ diff --git a/panda/src/mathutil/frustum.I b/panda/src/mathutil/frustum.I index db906cec0a..396f7f08f1 100644 --- a/panda/src/mathutil/frustum.I +++ b/panda/src/mathutil/frustum.I @@ -6,50 +6,10 @@ //////////////////////////////////////////////////////////////////// // Includes //////////////////////////////////////////////////////////////////// +#include "mathutil.h" +#include "config_mathutil.h" -//////////////////////////////////////////////////////////////////// -// Defines -//////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////// -// Class : Frustum -// Description : -//////////////////////////////////////////////////////////////////// -class EXPCL_PANDA FLOATNAME(Frustum) { -PUBLISHED: - INLINE FLOATNAME(Frustum)(); - - INLINE void make_ortho_2D(void); - INLINE void make_ortho_2D(FLOATTYPE1 l, FLOATTYPE1 r, FLOATTYPE1 t, FLOATTYPE1 b); - - INLINE void make_ortho(FLOATTYPE1 fnear, FLOATTYPE1 ffar); - INLINE void make_ortho(FLOATTYPE1 fnear, FLOATTYPE1 ffar, - FLOATTYPE1 l, FLOATTYPE1 r, FLOATTYPE1 t, FLOATTYPE1 b); - - INLINE void make_perspective_hfov(FLOATTYPE1 xfov, FLOATTYPE1 aspect, - FLOATTYPE1 fnear, FLOATTYPE1 ffar); - INLINE void make_perspective_vfov(FLOATTYPE1 yfov, FLOATTYPE1 aspect, - FLOATTYPE1 fnear, FLOATTYPE1 ffar); - INLINE void make_perspective(FLOATTYPE1 xfov, FLOATTYPE1 yfov, FLOATTYPE1 fnear, - FLOATTYPE1 ffar); - INLINE void get_perspective_params(FLOATTYPE1 &yfov, FLOATTYPE1 &aspect, - FLOATTYPE1 &fnear, FLOATTYPE1 &ffar) const; - INLINE void get_perspective_params(FLOATTYPE1 &xfov, FLOATTYPE1 &yfov, - FLOATTYPE1 &aspect, FLOATTYPE1 &fnear, - FLOATTYPE1 &ffar) const; - -public: - INLINE FLOATNAME(LMatrix4) - get_perspective_projection_mat(CoordinateSystem cs = CS_default) const; - - INLINE FLOATNAME(LMatrix4) - get_ortho_projection_mat(CoordinateSystem cs = CS_default) const; - -public: - FLOATTYPE1 _l, _r, _b, _t; - FLOATTYPE1 _fnear, _ffar; -}; - +#include //////////////////////////////////////////////////////////////////// // Static variables @@ -60,9 +20,9 @@ public: // Access: // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(Frustum):: -FLOATNAME(Frustum)() { +template +Frustum:: +Frustum() { _fnear = 1.4142; _ffar = 10.0; _l = -1; @@ -76,8 +36,8 @@ FLOATNAME(Frustum)() { // Access: // Description: Sets up a two-dimensional orthographic frustum //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(Frustum)::make_ortho_2D(void) { +template +void Frustum::make_ortho_2D(void) { make_ortho(-1, 1); } @@ -86,9 +46,9 @@ INLINE void FLOATNAME(Frustum)::make_ortho_2D(void) { // Access: // Description: Sets up a two-dimensional orthographic frustum //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(Frustum):: -make_ortho_2D(FLOATTYPE1 l, FLOATTYPE1 r, FLOATTYPE1 t, FLOATTYPE1 b) { +template +void Frustum:: +make_ortho_2D(P_numtype l, P_numtype r, P_numtype t, P_numtype b) { make_ortho(-1, 1, l, r, t, b); } @@ -97,8 +57,8 @@ make_ortho_2D(FLOATTYPE1 l, FLOATTYPE1 r, FLOATTYPE1 t, FLOATTYPE1 b) { // Access: // Description: Behaves like gluOrtho //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(Frustum)::make_ortho(FLOATTYPE1 fnear, FLOATTYPE1 ffar) { +template +void Frustum::make_ortho(P_numtype fnear, P_numtype ffar) { _fnear = fnear; _ffar = ffar; _l = -1; @@ -112,10 +72,10 @@ INLINE void FLOATNAME(Frustum)::make_ortho(FLOATTYPE1 fnear, FLOATTYPE1 ffar) { // Access: // Description: Behaves like gluOrtho //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(Frustum):: -make_ortho(FLOATTYPE1 fnear, FLOATTYPE1 ffar, FLOATTYPE1 l, FLOATTYPE1 r, - FLOATTYPE1 t, FLOATTYPE1 b) { +template +void Frustum:: +make_ortho(P_numtype fnear, P_numtype ffar, P_numtype l, P_numtype r, + P_numtype t, P_numtype b) { _fnear = fnear; _ffar = ffar; _l = l; @@ -146,10 +106,10 @@ make_ortho(FLOATTYPE1 fnear, FLOATTYPE1 ffar, FLOATTYPE1 l, FLOATTYPE1 r, // W yfov // //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(Frustum):: -make_perspective_hfov(FLOATTYPE1 hfov, FLOATTYPE1 aspect, FLOATTYPE1 fnear, - FLOATTYPE1 ffar) { +template +void Frustum:: +make_perspective_hfov(P_numtype hfov, P_numtype aspect, P_numtype fnear, + P_numtype ffar) { _fnear = fnear; _ffar = ffar; _r = tan(deg_2_rad(hfov) * 0.5) * _fnear; @@ -158,10 +118,10 @@ make_perspective_hfov(FLOATTYPE1 hfov, FLOATTYPE1 aspect, FLOATTYPE1 fnear, _b = -_t; } - -INLINE void FLOATNAME(Frustum):: -make_perspective_vfov(FLOATTYPE1 yfov, FLOATTYPE1 aspect, FLOATTYPE1 fnear, - FLOATTYPE1 ffar) { +template +void Frustum:: +make_perspective_vfov(P_numtype yfov, P_numtype aspect, P_numtype fnear, + P_numtype ffar) { _fnear = fnear; _ffar = ffar; _t = tan(deg_2_rad(yfov) * 0.5) * _fnear; @@ -170,10 +130,10 @@ make_perspective_vfov(FLOATTYPE1 yfov, FLOATTYPE1 aspect, FLOATTYPE1 fnear, _l = -_r; } - -INLINE void FLOATNAME(Frustum):: -make_perspective(FLOATTYPE1 xfov, FLOATTYPE1 yfov, FLOATTYPE1 fnear, - FLOATTYPE1 ffar) { +template +void Frustum:: +make_perspective(P_numtype xfov, P_numtype yfov, P_numtype fnear, + P_numtype ffar) { _fnear = fnear; _ffar = ffar; _t = tan(deg_2_rad(yfov) * 0.5) * _fnear; @@ -187,10 +147,10 @@ make_perspective(FLOATTYPE1 xfov, FLOATTYPE1 yfov, FLOATTYPE1 fnear, // Access: // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(Frustum):: -get_perspective_params(FLOATTYPE1& yfov, FLOATTYPE1& aspect, - FLOATTYPE1& fnear, FLOATTYPE1& ffar) const { +template +void Frustum:: +get_perspective_params(P_numtype& yfov, P_numtype& aspect, + P_numtype& fnear, P_numtype& ffar) const { yfov = rad_2_deg(atan(_t / _fnear)) * 2.0; aspect = _r / _t; fnear = _fnear; @@ -202,10 +162,10 @@ get_perspective_params(FLOATTYPE1& yfov, FLOATTYPE1& aspect, // Access: // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(Frustum):: -get_perspective_params(FLOATTYPE1& xfov, FLOATTYPE1& yfov, FLOATTYPE1& aspect, - FLOATTYPE1& fnear, FLOATTYPE1& ffar) const { +template +void Frustum:: +get_perspective_params(P_numtype& xfov, P_numtype& yfov, P_numtype& aspect, + P_numtype& fnear, P_numtype& ffar) const { xfov = rad_2_deg(atan(_r / _fnear)) * 2.0; get_perspective_params(yfov, aspect, fnear, ffar); } @@ -217,45 +177,45 @@ get_perspective_params(FLOATTYPE1& xfov, FLOATTYPE1& yfov, FLOATTYPE1& aspect, // perspective transform defined by the frustum, // accordinate to the indicated coordinate system. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) FLOATNAME(Frustum):: +template +LMatrix4 Frustum:: get_perspective_projection_mat(CoordinateSystem cs) const { if (cs == CS_default) { cs = default_coordinate_system; } - FLOATTYPE1 a = (2.0 * _fnear) / (_r - _l); - FLOATTYPE1 b = (_t + _b) / (_t - _b); - FLOATTYPE1 c = (_ffar + _fnear) / (_ffar - _fnear); - FLOATTYPE1 d = (_r + _l) / (_r - _l); - FLOATTYPE1 e = (2.0 * _fnear) / (_t - _b); - FLOATTYPE1 f = (-2.0 * _ffar * _fnear) / (_ffar - _fnear); + P_numtype a = (2.0 * _fnear) / (_r - _l); + P_numtype b = (_t + _b) / (_t - _b); + P_numtype c = (_ffar + _fnear) / (_ffar - _fnear); + P_numtype d = (_r + _l) / (_r - _l); + P_numtype e = (2.0 * _fnear) / (_t - _b); + P_numtype f = (-2.0 * _ffar * _fnear) / (_ffar - _fnear); switch (cs) { case CS_zup_right: - return FLOATNAME(LMatrix4)( a, 0.0, 0.0, 0.0, + return LMatrix4( a, 0.0, 0.0, 0.0, 0.0, -b, c, 1.0, d, e, 0.0, 0.0, 0.0, 0.0, f, 0.0); case CS_yup_right: - return FLOATNAME(LMatrix4)( a, 0.0, 0.0, 0.0, + return LMatrix4( a, 0.0, 0.0, 0.0, 0.0, e, 0.0, 0.0, d, b, -c,-1.0, 0.0, 0.0, f, 0.0); case CS_zup_left: - return FLOATNAME(LMatrix4)::convert_mat(CS_zup_right, CS_zup_left) * + return LMatrix4::convert_mat(CS_zup_right, CS_zup_left) * get_perspective_projection_mat(CS_zup_right); case CS_yup_left: - return FLOATNAME(LMatrix4)::convert_mat(CS_yup_right, CS_yup_left) * + return LMatrix4::convert_mat(CS_yup_right, CS_yup_left) * get_perspective_projection_mat(CS_yup_right); default: mathutil_cat.error() << "Invalid coordinate system!\n"; - return FLOATNAME(LMatrix4)::ident_mat(); + return LMatrix4::ident_mat(); } } @@ -266,42 +226,42 @@ get_perspective_projection_mat(CoordinateSystem cs) const { // orthographic transform defined by the frustum, // accordinate to the indicated coordinate system. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) FLOATNAME(Frustum):: +template +LMatrix4 Frustum:: get_ortho_projection_mat(CoordinateSystem cs) const { if (cs == CS_default) { cs = default_coordinate_system; } - FLOATTYPE1 a = 2.0 / (_r - _l); - FLOATTYPE1 b = 2.0 / (_t - _b); - FLOATTYPE1 c = 2.0 / (_ffar - _fnear); - FLOATTYPE1 d = (_r + _l) / (_r - _l); - FLOATTYPE1 e = (_t + _b) / (_t - _b); - FLOATTYPE1 f = (_ffar + _fnear) / (_ffar - _fnear); + P_numtype a = 2.0 / (_r - _l); + P_numtype b = 2.0 / (_t - _b); + P_numtype c = 2.0 / (_ffar - _fnear); + P_numtype d = (_r + _l) / (_r - _l); + P_numtype e = (_t + _b) / (_t - _b); + P_numtype f = (_ffar + _fnear) / (_ffar - _fnear); switch (cs) { case CS_zup_right: - return FLOATNAME(LMatrix4)::convert_mat(CS_yup_right, CS_zup_right) * + return LMatrix4::convert_mat(CS_yup_right, CS_zup_right) * get_ortho_projection_mat(CS_yup_right); case CS_yup_right: - return FLOATNAME(LMatrix4)( a, 0.0, 0.0, 0.0, + return LMatrix4( a, 0.0, 0.0, 0.0, 0.0, b, 0.0, 0.0, 0.0, 0.0, -c, 0.0, -d, -e, -f, 1.0); case CS_zup_left: - return FLOATNAME(LMatrix4)::convert_mat(CS_zup_right, CS_zup_left) * + return LMatrix4::convert_mat(CS_zup_right, CS_zup_left) * get_ortho_projection_mat(CS_zup_right); case CS_yup_left: - return FLOATNAME(LMatrix4)::convert_mat(CS_yup_right, CS_yup_left) * + return LMatrix4::convert_mat(CS_yup_right, CS_yup_left) * get_ortho_projection_mat(CS_yup_right); default: mathutil_cat.error() << "Invalid coordinate system!\n"; - return FLOATNAME(LMatrix4)::ident_mat(); + return LMatrix4::ident_mat(); } } diff --git a/panda/src/mathutil/frustum.N b/panda/src/mathutil/frustum.N index 921040faca..40aeca57bf 100644 --- a/panda/src/mathutil/frustum.N +++ b/panda/src/mathutil/frustum.N @@ -1,4 +1,2 @@ -forcetype Frustumf -renametype Frustumf Frustumf -forcetype Frustumd -renametype Frustumd Frustumd +forcetype Frustum +forcetype Frustum diff --git a/panda/src/mathutil/frustum.h b/panda/src/mathutil/frustum.h index ce8f635254..122540c3db 100644 --- a/panda/src/mathutil/frustum.h +++ b/panda/src/mathutil/frustum.h @@ -10,15 +10,56 @@ // Includes //////////////////////////////////////////////////////////////////// #include -#include + #include -#include "mathutil.h" -#include "config_mathutil.h" -#include "fltnames.I" +//////////////////////////////////////////////////////////////////// +// Defines +//////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////// +// Class : Frustum +// Description : +//////////////////////////////////////////////////////////////////// +template +class EXPCL_PANDA Frustum { +PUBLISHED: + Frustum(); + + void make_ortho_2D(void); + void make_ortho_2D(P_numtype l, P_numtype r, P_numtype t, P_numtype b); + + void make_ortho(P_numtype fnear, P_numtype ffar); + void make_ortho(P_numtype fnear, P_numtype ffar, + P_numtype l, P_numtype r, P_numtype t, P_numtype b); + + void make_perspective_hfov(P_numtype xfov, P_numtype aspect, + P_numtype fnear, P_numtype ffar); + void make_perspective_vfov(P_numtype yfov, P_numtype aspect, + P_numtype fnear, P_numtype ffar); + void make_perspective(P_numtype xfov, P_numtype yfov, P_numtype fnear, + P_numtype ffar); + void get_perspective_params(P_numtype &yfov, P_numtype &aspect, + P_numtype &fnear, P_numtype &ffar) const; + void get_perspective_params(P_numtype &xfov, P_numtype &yfov, + P_numtype &aspect, P_numtype &fnear, + P_numtype &ffar) const; + +public: + LMatrix4 + get_perspective_projection_mat(CoordinateSystem cs = CS_default) const; + + LMatrix4 + get_ortho_projection_mat(CoordinateSystem cs = CS_default) const; + +public: + P_numtype _l, _r, _b, _t; + P_numtype _fnear, _ffar; +}; + #include "frustum.I" -#include "dblnames.I" -#include "frustum.I" +typedef Frustum Frustumf; +typedef Frustum Frustumd; #endif diff --git a/panda/src/mathutil/look_at.I b/panda/src/mathutil/look_at.I index 51289fb2a9..43ed0b67be 100644 --- a/panda/src/mathutil/look_at.I +++ b/panda/src/mathutil/look_at.I @@ -3,86 +3,77 @@ // //////////////////////////////////////////////////////////////////// -// These functions return a matrix that rotates between a coordinate -// system defined with the given forward and up vectors, and the -// standard coordinate system with y-forward and z-up. They differ -// only in their behavior when the supplied forward and up vectors are -// not perpendicular; in this case, look_at will match the forward -// vector precisely, while heads_up will match the up vector -// precisely. - -// Since these functions only return a rotation matrix, the -// translation component is always zero. There are flavors of these -// functions that simply return the upper 3x3 part of the matrix, and -// flavors that return the whole 4x4 matrix with a zero bottom row. - -BEGIN_PUBLISH - -// Flavors for float-type arithmetic. - -EXPCL_PANDA void -heads_up(FLOATNAME(LMatrix3) &mat, const FLOATNAME(LVector3) &fwd, - const FLOATNAME(LVector3) &up = FLOATNAME(LVector3)::up(), - CoordinateSystem cs = CS_default); -EXPCL_PANDA void -look_at(FLOATNAME(LMatrix3) &mat, const FLOATNAME(LVector3) &fwd, - const FLOATNAME(LVector3) &up = FLOATNAME(LVector3)::up(), - CoordinateSystem cs = CS_default); - -INLINE void heads_up(FLOATNAME(LMatrix3) &mat, const FLOATNAME(LVector3) &fwd, - CoordinateSystem cs); -INLINE void look_at(FLOATNAME(LMatrix3) &mat, const FLOATNAME(LVector3) &fwd, - CoordinateSystem cs); - - -INLINE void heads_up(FLOATNAME(LMatrix4) &mat, const FLOATNAME(LVector3) &fwd, - const FLOATNAME(LVector3) &up = FLOATNAME(LVector3)::up(), - CoordinateSystem cs = CS_default); -INLINE void look_at(FLOATNAME(LMatrix4) &mat, const FLOATNAME(LVector3) &fwd, - const FLOATNAME(LVector3) &up = FLOATNAME(LVector3)::up(), - CoordinateSystem cs = CS_default); - -INLINE void heads_up(FLOATNAME(LMatrix4) &mat, const FLOATNAME(LVector3) &fwd, - CoordinateSystem cs); -INLINE void look_at(FLOATNAME(LMatrix4) &mat, const FLOATNAME(LVector3) &fwd, - CoordinateSystem cs); - -END_PUBLISH - - INLINE void -heads_up(FLOATNAME(LMatrix3) &mat, const FLOATNAME(LVector3) &fwd, CoordinateSystem cs) { - heads_up(mat, fwd, FLOATNAME(LVector3)::up(cs), cs); +heads_up(LMatrix3f &mat, const LVector3f &fwd, CoordinateSystem cs) { + heads_up(mat, fwd, LVector3f::up(cs), cs); } INLINE void -look_at(FLOATNAME(LMatrix3) &mat, const FLOATNAME(LVector3) &fwd, CoordinateSystem cs) { - look_at(mat, fwd, FLOATNAME(LVector3)::up(cs), cs); +look_at(LMatrix3f &mat, const LVector3f &fwd, CoordinateSystem cs) { + look_at(mat, fwd, LVector3f::up(cs), cs); } INLINE void -heads_up(FLOATNAME(LMatrix4) &mat, const FLOATNAME(LVector3) &fwd, - const FLOATNAME(LVector3) &up, CoordinateSystem cs) { - FLOATNAME(LMatrix3) mat3; +heads_up(LMatrix4f &mat, const LVector3f &fwd, + const LVector3f &up, CoordinateSystem cs) { + LMatrix3f mat3; heads_up(mat3, fwd, up, cs); - mat = FLOATNAME(LMatrix4)(mat3); + mat = LMatrix4f(mat3); } INLINE void -look_at(FLOATNAME(LMatrix4) &mat, const FLOATNAME(LVector3) &fwd, - const FLOATNAME(LVector3) &up, CoordinateSystem cs) { - FLOATNAME(LMatrix3) mat3; +look_at(LMatrix4f &mat, const LVector3f &fwd, + const LVector3f &up, CoordinateSystem cs) { + LMatrix3f mat3; look_at(mat3, fwd, up, cs); - mat = FLOATNAME(LMatrix4)(mat3); + mat = LMatrix4f(mat3); } INLINE void -heads_up(FLOATNAME(LMatrix4) &mat, const FLOATNAME(LVector3) &fwd, CoordinateSystem cs) { - heads_up(mat, fwd, FLOATNAME(LVector3)::up(cs), cs); +heads_up(LMatrix4f &mat, const LVector3f &fwd, CoordinateSystem cs) { + heads_up(mat, fwd, LVector3f::up(cs), cs); } INLINE void -look_at(FLOATNAME(LMatrix4) &mat, const FLOATNAME(LVector3) &fwd, CoordinateSystem cs) { - look_at(mat, fwd, FLOATNAME(LVector3)::up(cs), cs); +look_at(LMatrix4f &mat, const LVector3f &fwd, CoordinateSystem cs) { + look_at(mat, fwd, LVector3f::up(cs), cs); +} + + + +INLINE void +heads_up(LMatrix3d &mat, const LVector3d &fwd, CoordinateSystem cs) { + heads_up(mat, fwd, LVector3d::up(cs), cs); +} + +INLINE void +look_at(LMatrix3d &mat, const LVector3d &fwd, CoordinateSystem cs) { + look_at(mat, fwd, LVector3d::up(cs), cs); +} + +INLINE void +heads_up(LMatrix4d &mat, const LVector3d &fwd, + const LVector3d &up, CoordinateSystem cs) { + LMatrix3d mat3; + heads_up(mat3, fwd, up, cs); + mat = LMatrix4d(mat3); +} + +INLINE void +look_at(LMatrix4d &mat, const LVector3d &fwd, + const LVector3d &up, CoordinateSystem cs) { + LMatrix3d mat3; + look_at(mat3, fwd, up, cs); + mat = LMatrix4d(mat3); +} + +INLINE void +heads_up(LMatrix4d &mat, const LVector3d &fwd, CoordinateSystem cs) { + heads_up(mat, fwd, LVector3d::up(cs), cs); +} + +INLINE void +look_at(LMatrix4d &mat, const LVector3d &fwd, CoordinateSystem cs) { + look_at(mat, fwd, LVector3d::up(cs), cs); } diff --git a/panda/src/mathutil/look_at.cxx b/panda/src/mathutil/look_at.cxx index 0cf72e8ffd..ff7df16b80 100644 --- a/panda/src/mathutil/look_at.cxx +++ b/panda/src/mathutil/look_at.cxx @@ -2,11 +2,337 @@ // Created by: drose (25Apr97) // //////////////////////////////////////////////////////////////////// - +// +//////////////////////////////////////////////////////////////////// +// Includes +//////////////////////////////////////////////////////////////////// #include "look_at.h" +#include -#include "fltnames.I" -#include "look_at_src.I" +template +INLINE LMatrix3 +make_xi_mat(const LVector2 &x) { + return LMatrix3(1, 0, 0, + 0, x[0], x[1], + 0, -x[1], x[0]); +} -#include "dblnames.I" -#include "look_at_src.I" +template +INLINE LMatrix3 +make_x_mat(const LVector2 &x) { + return LMatrix3(1, 0, 0, + 0, x[1], x[0], + 0, -x[0], x[1]); +} + +template +INLINE LMatrix3 +make_y_mat(const LVector2 &y) { + return LMatrix3(y[1], 0, -y[0], + 0, 1, 0, + y[0], 0, y[1]); +} + +template +INLINE LMatrix3 +make_z_mat(const LVector2 &z) { + return LMatrix3(z[1], -z[0], 0, + z[0], z[1], 0, + 0, 0, 1); +} + +//////////////////////////////////////////////////////////////////// +// Function: heads_up +// Description: Given two vectors defining a forward direction and an +// up vector, constructs the matrix that rotates things +// from the defined coordinate system to y-forward and +// z-up. The up vector will be rotated to z-up first, +// then the forward vector will be rotated as nearly to +// y-forward as possible. This will only have a +// different effect from look_at() if the forward and up +// vectors are not perpendicular. +//////////////////////////////////////////////////////////////////// +template +static void +_heads_up(LMatrix3 &mat, const LVector3 &fwd, + const LVector3 &up, CoordinateSystem cs) { + if (cs == CS_zup_right || cs == CS_zup_left) { + // Z-up. + + // y is the projection of the up vector into the XZ plane. Its + // angle to the Z axis is the amount to rotate about the Y axis to + // bring the up vector into the YZ plane. + + LVector2 y(up[0], up[2]); + NumType d = dot(y, y); + if (d==0.0) { + y = LVector2(0.0, 1.0); + } else { + y /= csqrt(d); + } + + // x is the up vector rotated into the YZ plane. Its angle to the Z + // axis is the amount to rotate about the X axis to bring the up + // vector to the Z axis. + + LVector2 x(up[1], up[0]*y[0]+up[2]*y[1]); + d = dot(x, x); + if (d==0.0) { + x = LVector2(0.0, 1.0); + } else { + x /= csqrt(d); + } + + // Now apply both rotations to the forward vector. This will rotate + // the forward vector by the same amount we would have had to rotate + // the up vector to bring it to the Z axis. If the vectors were + // perpendicular, this will put the forward vector somewhere in the + // XY plane. + + // z is the projection of the newly rotated fwd vector into the XY + // plane. Its angle to the Y axis is the amount to rotate about the + // Z axis in order to bring the fwd vector to the Y axis. + LVector2 z(fwd[0]*y[1] - fwd[2]*y[0], + -fwd[0]*y[0]*x[0] + fwd[1]*x[1] - fwd[2]*y[1]*x[0]); + d = dot(z, z); + if (d==0.0) { + z = LVector2(0.0, 1.0); + } else { + z /= csqrt(d); + } + + // Now build the net rotation matrix. + if (cs == CS_zup_right) { + mat = + make_z_mat(z) * + make_x_mat(x) * + make_y_mat(y); + } else { // cs == CS_zup_left + mat = + make_z_mat(z) * + make_x_mat(-x) * + make_y_mat(-y); + } + } else { + // Y-up. + + // z is the projection of the forward vector into the XY plane. Its + // angle to the Y axis is the amount to rotate about the Z axis to + // bring the forward vector into the YZ plane. + + LVector2 z(up[0], up[1]); + NumType d = dot(z, z); + if (d==0.0) { + z = LVector2(0.0, 1.0); + } else { + z /= csqrt(d); + } + + // x is the forward vector rotated into the YZ plane. Its angle to + // the Y axis is the amount to rotate about the X axis to bring the + // forward vector to the Y axis. + + LVector2 x(up[0]*z[0] + up[1]*z[1], up[2]); + d = dot(x, x); + if (d==0.0) { + x = LVector2(1.0, 0.0); + } else { + x /= csqrt(d); + } + + // Now apply both rotations to the up vector. This will rotate + // the up vector by the same amount we would have had to rotate + // the forward vector to bring it to the Y axis. If the vectors were + // perpendicular, this will put the up vector somewhere in the + // XZ plane. + + // y is the projection of the newly rotated up vector into the XZ + // plane. Its angle to the Z axis is the amount to rotate about the + // Y axis in order to bring the up vector to the Z axis. + LVector2 y(fwd[0]*z[1] - fwd[1]*z[0], + -fwd[0]*x[1]*z[0] - fwd[1]*x[1]*z[1] + fwd[2]*x[0]); + d = dot(y, y); + if (d==0.0) { + y = LVector2(0.0, 1.0); + } else { + y /= csqrt(d); + } + + // Now build the net rotation matrix. + if (cs == CS_yup_right) { + mat = + make_y_mat(y) * + make_xi_mat(-x) * + make_z_mat(-z); + } else { // cs == CS_yup_left + mat = + make_y_mat(y) * + make_xi_mat(x) * + make_z_mat(z); + } + } +} + + +//////////////////////////////////////////////////////////////////// +// Function: look_at +// Description: Given two vectors defining a forward direction and an +// up vector, constructs the matrix that rotates things +// from the defined coordinate system to y-forward and +// z-up. The forward vector will be rotated to +// y-forward first, then the up vector will be rotated +// as nearly to z-up as possible. This will only have a +// different effect from heads_up() if the forward and +// up vectors are not perpendicular. +//////////////////////////////////////////////////////////////////// +template +static void +_look_at(LMatrix3 &mat, const LVector3 &fwd, + const LVector3 &up, CoordinateSystem cs) { + if (cs == CS_default) { + cs = default_coordinate_system; + } + + if (cs == CS_zup_right || cs == CS_zup_left) { + // Z-up. + + // z is the projection of the forward vector into the XY plane. Its + // angle to the Y axis is the amount to rotate about the Z axis to + // bring the forward vector into the YZ plane. + + LVector2 z(fwd[0], fwd[1]); + NumType d = dot(z, z); + if (d==0.0) { + z = LVector2(0.0, 1.0); + } else { + z /= csqrt(d); + } + + // x is the forward vector rotated into the YZ plane. Its angle to + // the Y axis is the amount to rotate about the X axis to bring the + // forward vector to the Y axis. + + LVector2 x(fwd[0]*z[0] + fwd[1]*z[1], fwd[2]); + d = dot(x, x); + if (d==0.0) { + x = LVector2(1.0, 0.0); + } else { + x /= csqrt(d); + } + + // Now apply both rotations to the up vector. This will rotate + // the up vector by the same amount we would have had to rotate + // the forward vector to bring it to the Y axis. If the vectors were + // perpendicular, this will put the up vector somewhere in the + // XZ plane. + + // y is the projection of the newly rotated up vector into the XZ + // plane. Its angle to the Z axis is the amount to rotate about the + // Y axis in order to bring the up vector to the Z axis. + LVector2 y(up[0]*z[1] - up[1]*z[0], + -up[0]*x[1]*z[0] - up[1]*x[1]*z[1] + up[2]*x[0]); + d = dot(y, y); + if (d==0.0) { + y = LVector2(0.0, 1.0); + } else { + y /= csqrt(d); + } + + // Now build the net rotation matrix. + if (cs == CS_zup_right) { + mat = + make_y_mat(y) * + make_xi_mat(x) * + make_z_mat(z); + } else { // cs == CS_zup_left + mat = + make_y_mat(-y) * + make_xi_mat(-x) * + make_z_mat(z); + } + } else { + // Y-up. + + // y is the projection of the up vector into the XZ plane. Its + // angle to the Z axis is the amount to rotate about the Y axis to + // bring the up vector into the YZ plane. + + LVector2 y(fwd[0], fwd[2]); + NumType d = dot(y, y); + if (d==0.0) { + y = LVector2(0.0, 1.0); + } else { + y /= csqrt(d); + } + + // x is the up vector rotated into the YZ plane. Its angle to the Z + // axis is the amount to rotate about the X axis to bring the up + // vector to the Z axis. + + LVector2 x(fwd[1], fwd[0]*y[0]+fwd[2]*y[1]); + d = dot(x, x); + if (d==0.0) { + x = LVector2(0.0, 1.0); + } else { + x /= csqrt(d); + } + + // Now apply both rotations to the forward vector. This will rotate + // the forward vector by the same amount we would have had to rotate + // the up vector to bring it to the Z axis. If the vectors were + // perpendicular, this will put the forward vector somewhere in the + // XY plane. + + // z is the projection of the newly rotated fwd vector into the XY + // plane. Its angle to the Y axis is the amount to rotate about the + // Z axis in order to bring the fwd vector to the Y axis. + LVector2 z(up[0]*y[1] - up[2]*y[0], + -up[0]*y[0]*x[0] + up[1]*x[1] - up[2]*y[1]*x[0]); + d = dot(z, z); + if (d==0.0) { + z = LVector2(0.0, 1.0); + } else { + z /= csqrt(d); + } + + // Now build the net rotation matrix. + if (cs == CS_yup_right) { + mat = + make_z_mat(z) * + make_x_mat(x) * + make_y_mat(-y); + } else { // cs == CS_yup_left + mat = + make_z_mat(-z) * + make_x_mat(-x) * + make_y_mat(-y); + } + } +} + +// The following functions are the non-template functions that are +// actually exported. + +void +heads_up(LMatrix3f &mat, const LVector3f &fwd, + const LVector3f &up, CoordinateSystem cs) { + _heads_up(mat, fwd, up, cs); +} + +void +look_at(LMatrix3f &mat, const LVector3f &fwd, + const LVector3f &up, CoordinateSystem cs) { + _look_at(mat, fwd, up, cs); +} + +void +heads_up(LMatrix3d &mat, const LVector3d &fwd, + const LVector3d &up, CoordinateSystem cs) { + _heads_up(mat, fwd, up, cs); +} + +void +look_at(LMatrix3d &mat, const LVector3d &fwd, + const LVector3d &up, CoordinateSystem cs) { + _look_at(mat, fwd, up, cs); +} diff --git a/panda/src/mathutil/look_at.h b/panda/src/mathutil/look_at.h index bb43c94efc..819809731a 100644 --- a/panda/src/mathutil/look_at.h +++ b/panda/src/mathutil/look_at.h @@ -10,14 +10,86 @@ // Includes /////////////////////////////////////////////////////////////////// #include -#include "cmath.h" -#include "coordinateSystem.h" -#include "luse.h" -#include "fltnames.I" -#include "look_at.I" +#include +#include + +// These functions return a matrix that rotates between a coordinate +// system defined with the given forward and up vectors, and the +// standard coordinate system with y-forward and z-up. They differ +// only in their behavior when the supplied forward and up vectors are +// not perpendicular; in this case, look_at will match the forward +// vector precisely, while heads_up will match the up vector +// precisely. + +// Since these functions only return a rotation matrix, the +// translation component is always zero. There are flavors of these +// functions that simply return the upper 3x3 part of the matrix, and +// flavors that return the whole 4x4 matrix with a zero bottom row. + +BEGIN_PUBLISH + +// Flavors for float-type arithmetic. + +EXPCL_PANDA void +heads_up(LMatrix3f &mat, const LVector3f &fwd, + const LVector3f &up = LVector3f::up(), + CoordinateSystem cs = CS_default); +EXPCL_PANDA void +look_at(LMatrix3f &mat, const LVector3f &fwd, + const LVector3f &up = LVector3f::up(), + CoordinateSystem cs = CS_default); + +INLINE void heads_up(LMatrix3f &mat, const LVector3f &fwd, + CoordinateSystem cs); +INLINE void look_at(LMatrix3f &mat, const LVector3f &fwd, + CoordinateSystem cs); + + +INLINE void heads_up(LMatrix4f &mat, const LVector3f &fwd, + const LVector3f &up = LVector3f::up(), + CoordinateSystem cs = CS_default); +INLINE void look_at(LMatrix4f &mat, const LVector3f &fwd, + const LVector3f &up = LVector3f::up(), + CoordinateSystem cs = CS_default); + +INLINE void heads_up(LMatrix4f &mat, const LVector3f &fwd, + CoordinateSystem cs); +INLINE void look_at(LMatrix4f &mat, const LVector3f &fwd, + CoordinateSystem cs); + + +// Flavors for double-type arithmetic. + +EXPCL_PANDA void +heads_up(LMatrix3d &mat, const LVector3d &fwd, + const LVector3d &up = LVector3d::up(), + CoordinateSystem cs = CS_default); +EXPCL_PANDA void +look_at(LMatrix3d &mat, const LVector3d &fwd, + const LVector3d &up = LVector3d::up(), + CoordinateSystem cs = CS_default); + +INLINE void heads_up(LMatrix3d &mat, const LVector3d &fwd, + CoordinateSystem cs); +INLINE void look_at(LMatrix3d &mat, const LVector3d &fwd, + CoordinateSystem cs); + + +INLINE void heads_up(LMatrix4d &mat, const LVector3d &fwd, + const LVector3d &up = LVector3d::up(), + CoordinateSystem cs = CS_default); +INLINE void look_at(LMatrix4d &mat, const LVector3d &fwd, + const LVector3d &up = LVector3d::up(), + CoordinateSystem cs = CS_default); + +INLINE void heads_up(LMatrix4d &mat, const LVector3d &fwd, + CoordinateSystem cs); +INLINE void look_at(LMatrix4d &mat, const LVector3d &fwd, + CoordinateSystem cs); + +END_PUBLISH -#include "dblnames.I" #include "look_at.I" #endif diff --git a/panda/src/mathutil/plane.I b/panda/src/mathutil/plane.I index ddd4a68694..d51ef97ffc 100644 --- a/panda/src/mathutil/plane.I +++ b/panda/src/mathutil/plane.I @@ -2,53 +2,14 @@ // Created by: mike (09Jan97) // //////////////////////////////////////////////////////////////////// - +// //////////////////////////////////////////////////////////////////// -// Class : FLOATNAME(Plane) -// Description : +// Includes //////////////////////////////////////////////////////////////////// +#include "mathutil.h" -class EXPCL_PANDA FLOATNAME(Plane) { -PUBLISHED: - INLINE FLOATNAME(Plane)(void); - INLINE FLOATNAME(Plane)(const FLOATNAME(Plane) ©); - INLINE FLOATNAME(Plane)(const FLOATNAME(LPoint3) &a, const FLOATNAME(LPoint3) &b, - const FLOATNAME(LPoint3) &c); - INLINE FLOATNAME(Plane)(const FLOATNAME(LVector3) &normal, - const FLOATNAME(LPoint3) &point); - - INLINE FLOATNAME(Plane)& operator = (const FLOATNAME(Plane)& copy); - - INLINE FLOATNAME(Plane) operator * (const FLOATNAME(LMatrix3) &mat) const; - INLINE FLOATNAME(Plane) operator * (const FLOATNAME(LMatrix4) &mat) const; - - INLINE FLOATNAME(LMatrix4) get_reflection_mat(void) const; - - INLINE FLOATNAME(LVector3) get_normal() const; - INLINE FLOATNAME(LPoint3) get_point() const; - INLINE FLOATTYPE1 dist_to_plane(const FLOATNAME(LPoint3) &point) const; - INLINE bool intersects_line(FLOATNAME(LPoint3) &intersection_point, - const FLOATNAME(LPoint3) &p1, - const FLOATNAME(LPoint3) &p2) const; - INLINE bool intersects_line(FLOATTYPE1 &t, - const FLOATNAME(LPoint3) &from, - const FLOATNAME(LVector3) &delta) const; - - INLINE void output(ostream &out) const; - INLINE void write(ostream &out, int indent_level = 0) const; - -public: - INLINE void write_datagram(Datagram &dest); - INLINE void read_datagram(DatagramIterator &source); - -public: - FLOATTYPE1 _a, _b, _c, _d; -}; - -INLINE ostream &operator << (ostream &out, const FLOATNAME(Plane) &p) { - p.output(out); - return out; -} +#include +#include //////////////////////////////////////////////////////////////////// // Static variables @@ -61,9 +22,9 @@ INLINE ostream &operator << (ostream &out, const FLOATNAME(Plane) &p) { // intersect the origin, perpendicular to the Z axis. // It's not clear how useful a default plane is. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(Plane):: -FLOATNAME(Plane)(void) { +template +INLINE Plane:: +Plane(void) { _a = 0.0; _b = 0.0; _c = 1.0; @@ -75,9 +36,9 @@ FLOATNAME(Plane)(void) { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(Plane):: -FLOATNAME(Plane)(const FLOATNAME(Plane) ©) : +template +INLINE Plane:: +Plane(const Plane ©) : _a(copy._a), _b(copy._b), _c(copy._c), @@ -93,13 +54,13 @@ FLOATNAME(Plane)(const FLOATNAME(Plane) ©) : // viewed from the end of the normal vector, looking // down). //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(Plane):: -FLOATNAME(Plane)(const FLOATNAME(LPoint3) &a, const FLOATNAME(LPoint3) &b, - const FLOATNAME(LPoint3) &c) { - FLOATNAME(LVector3) u = b - a; - FLOATNAME(LVector3) v = c - a; - FLOATNAME(LVector3) p = normalize(cross(u, v)); +template +INLINE Plane:: +Plane(const LPoint3 &a, const LPoint3 &b, + const LPoint3 &c) { + LVector3 u = b - a; + LVector3 v = c - a; + LVector3 p = normalize(cross(u, v)); _a = p[0]; _b = p[1]; @@ -113,10 +74,10 @@ FLOATNAME(Plane)(const FLOATNAME(LPoint3) &a, const FLOATNAME(LPoint3) &b, // Description: Constructs a plane given a surface normal vector and // a point within the plane. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(Plane):: -FLOATNAME(Plane)(const FLOATNAME(LVector3) &normal, const FLOATNAME(LPoint3) &point) { - FLOATNAME(LVector3) p = normalize(normal); +template +INLINE Plane:: +Plane(const LVector3 &normal, const LPoint3 &point) { + LVector3 p = normalize(normal); _a = p[0]; _b = p[1]; @@ -129,9 +90,9 @@ FLOATNAME(Plane)(const FLOATNAME(LVector3) &normal, const FLOATNAME(LPoint3) &po // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(Plane)& FLOATNAME(Plane):: -operator = (const FLOATNAME(Plane)& p) { +template +INLINE Plane& Plane:: +operator = (const Plane& p) { _a = p._a; _b = p._b; _c = p._c; @@ -144,12 +105,12 @@ operator = (const FLOATNAME(Plane)& p) { // Access: Public // Description: Transforms the plane by the indicated matrix. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(Plane) FLOATNAME(Plane):: -operator * (const FLOATNAME(LMatrix3) &mat) const { - FLOATNAME(LVector3) new_normal = get_normal() * mat; - FLOATNAME(LPoint3) new_point = get_point() * mat; - return FLOATNAME(Plane)(new_normal, new_point); +template +INLINE Plane Plane:: +operator * (const LMatrix3 &mat) const { + LVector3 new_normal = get_normal() * mat; + LPoint3 new_point = get_point() * mat; + return Plane(new_normal, new_point); } //////////////////////////////////////////////////////////////////// @@ -157,12 +118,12 @@ operator * (const FLOATNAME(LMatrix3) &mat) const { // Access: Public // Description: Transforms the plane by the indicated matrix. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(Plane) FLOATNAME(Plane):: -operator * (const FLOATNAME(LMatrix4) &mat) const { - FLOATNAME(LVector3) new_normal = get_normal() * mat; - FLOATNAME(LPoint3) new_point = get_point() * mat; - return FLOATNAME(Plane)(new_normal, new_point); +template +INLINE Plane Plane:: +operator * (const LMatrix4 &mat) const { + LVector3 new_normal = get_normal() * mat; + LPoint3 new_point = get_point() * mat; + return Plane(new_normal, new_point); } //////////////////////////////////////////////////////////////////// @@ -172,16 +133,16 @@ operator * (const FLOATNAME(LMatrix4) &mat) const { // perspective transform defined by the frustum, // accordinate to the indicated coordinate system. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LMatrix4) FLOATNAME(Plane):: +template +LMatrix4 Plane:: get_reflection_mat(void) const { - FLOATTYPE1 aa = _a * _a; FLOATTYPE1 ab = _a * _b; FLOATTYPE1 ac = _a * _c; - FLOATTYPE1 ad = _a * _d; - FLOATTYPE1 bb = _b * _b; FLOATTYPE1 bc = _b * _c; FLOATTYPE1 bd = _b * _d; - FLOATTYPE1 cc = _c * _c; FLOATTYPE1 cd = _c * _d; + NumType aa = _a * _a; NumType ab = _a * _b; NumType ac = _a * _c; + NumType ad = _a * _d; + NumType bb = _b * _b; NumType bc = _b * _c; NumType bd = _b * _d; + NumType cc = _c * _c; NumType cd = _c * _d; - return FLOATNAME(LMatrix4)( 1-2*aa, -2*ab, -2*ac, 0, + return LMatrix4( 1-2*aa, -2*ab, -2*ac, 0, -2*ab, 1-2*bb, -2*bc, 0, -2*ac, -2*bc, 1-2*cc, 0, -2*ad, -2*bd, -2*cd, 1 ); @@ -192,10 +153,10 @@ get_reflection_mat(void) const { // Access: Public // Description: Returns the surface normal of the plane. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LVector3) FLOATNAME(Plane):: +template +INLINE LVector3 Plane:: get_normal() const { - return FLOATNAME(LVector3)(_a, _b, _c); + return LVector3(_a, _b, _c); } //////////////////////////////////////////////////////////////////// @@ -205,19 +166,19 @@ get_normal() const { // used along with the normal returned by get_normal() // to reconstruct the plane. //////////////////////////////////////////////////////////////////// - -INLINE FLOATNAME(LPoint3) FLOATNAME(Plane):: +template +LPoint3 Plane:: get_point() const { // Choose the denominator based on the largest axis in the normal. if (cabs(_a) >= cabs(_b) && cabs(_a) >= cabs(_c)) { - nassertr(_a != 0.0, FLOATNAME(LPoint3)(0.0, 0.0, 0.0)); - return FLOATNAME(LPoint3)(-_d / _a, 0.0, 0.0); + nassertr(_a != 0.0, LPoint3(0.0, 0.0, 0.0)); + return LPoint3(-_d / _a, 0.0, 0.0); } else if (cabs(_b) >= cabs(_c)) { - nassertr(_b != 0.0, FLOATNAME(LPoint3)(0.0, 0.0, 0.0)); - return FLOATNAME(LPoint3)(0.0, -_d / _b, 0.0); + nassertr(_b != 0.0, LPoint3(0.0, 0.0, 0.0)); + return LPoint3(0.0, -_d / _b, 0.0); } else { - nassertr(_c != 0.0, FLOATNAME(LPoint3)(0.0, 0.0, 0.0)); - return FLOATNAME(LPoint3)(0.0, 0.0, -_d / _c); + nassertr(_c != 0.0, LPoint3(0.0, 0.0, 0.0)); + return LPoint3(0.0, 0.0, -_d / _c); } } @@ -231,9 +192,9 @@ get_point() const { // the plane (on the opposite side from the normal). // It's zero if the point is exactly in the plane. //////////////////////////////////////////////////////////////////// - -INLINE FLOATTYPE1 FLOATNAME(Plane):: -dist_to_plane(const FLOATNAME(LPoint3) &point) const { +template +INLINE NumType Plane:: +dist_to_plane(const LPoint3 &point) const { return (_a * point[0] + _b * point[1] + _c * point[2] + _d); } @@ -247,12 +208,12 @@ dist_to_plane(const FLOATNAME(LPoint3) &point) const { // bearing on the intersection test. If true, sets // intersection_point to the point of intersection. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(Plane):: -intersects_line(FLOATNAME(LPoint3) &intersection_point, - const FLOATNAME(LPoint3) &p1, - const FLOATNAME(LPoint3) &p2) const { - FLOATTYPE1 t; +template +INLINE bool Plane:: +intersects_line(LPoint3 &intersection_point, + const LPoint3 &p1, + const LPoint3 &p2) const { + NumType t; if (!intersects_line(t, p1, p2 - p1)) { return false; } @@ -277,12 +238,12 @@ intersects_line(FLOATNAME(LPoint3) &intersection_point, // point from, and t == 1.0 implies at point from + // delta, with other values of t accordingly. //////////////////////////////////////////////////////////////////// - -INLINE bool FLOATNAME(Plane):: -intersects_line(FLOATTYPE1 &t, - const FLOATNAME(LPoint3) &from, - const FLOATNAME(LVector3) &delta) const { - FLOATTYPE1 denom = dot(get_normal(), delta); +template +INLINE bool Plane:: +intersects_line(NumType &t, + const LPoint3 &from, + const LVector3 &delta) const { + NumType denom = dot(get_normal(), delta); if (IS_NEARLY_ZERO(denom)) { return false; } @@ -296,8 +257,8 @@ intersects_line(FLOATTYPE1 &t, // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(Plane):: +template +void Plane:: output(ostream &out) const { out << "Plane(" << _a << " " << _b << " " << _c << " " << _d << ")"; } @@ -307,8 +268,8 @@ output(ostream &out) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(Plane):: +template +void Plane:: write(ostream &out, int indent_level) const { indent(out, indent_level) << *this << "\n"; } @@ -318,8 +279,8 @@ write(ostream &out, int indent_level) const { // Access: Public // Description: //////////////////////////////////////////////////////////////////// - -INLINE void FLOATNAME(Plane):: +template +void Plane:: write_datagram(Datagram &dest) { dest.add_float32(_a); @@ -333,9 +294,8 @@ write_datagram(Datagram &dest) // Access: Public // Description: //////////////////////////////////////////////////////////////////// - - -INLINE void FLOATNAME(Plane):: +template +void Plane:: read_datagram(DatagramIterator &source) { _a = source.get_float32(); diff --git a/panda/src/mathutil/plane.N b/panda/src/mathutil/plane.N index 7fc43d6e1d..9b8394214f 100644 --- a/panda/src/mathutil/plane.N +++ b/panda/src/mathutil/plane.N @@ -1,4 +1,2 @@ -forcetype Planef -renametype Planef Planef -forcetype Planed -renametype Planed Planed +forcetype Plane +forcetype Plane diff --git a/panda/src/mathutil/plane.h b/panda/src/mathutil/plane.h index e1b6fa418b..6c24966b16 100644 --- a/panda/src/mathutil/plane.h +++ b/panda/src/mathutil/plane.h @@ -1,10 +1,10 @@ -// Filename: FLOATNAME(Plane).h +// Filename: plane.h // Created by: mike (09Jan97) // //////////////////////////////////////////////////////////////////// // -#ifndef Plane_H -#define Plane_H +#ifndef PLANE_H +#define PLANE_H // //////////////////////////////////////////////////////////////////// // Includes @@ -13,17 +13,76 @@ #include #include -#include -#include -#include "mathutil.h" class Datagram; class DatagramIterator; -#include "fltnames.I" +//////////////////////////////////////////////////////////////////// +// Defines +//////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////// +// Class : Plane +// Description : +//////////////////////////////////////////////////////////////////// +template +class Plane { +PUBLISHED: + INLINE Plane(void); + INLINE Plane(const Plane ©); + INLINE Plane(const LPoint3 &a, const LPoint3 &b, + const LPoint3 &c); + INLINE Plane(const LVector3 &normal, + const LPoint3 &point); + + INLINE Plane& operator = (const Plane& copy); + + INLINE Plane operator * (const LMatrix3 &mat) const; + INLINE Plane operator * (const LMatrix4 &mat) const; + + + LMatrix4 + get_reflection_mat(void) const; + + INLINE LVector3 get_normal() const; + LPoint3 get_point() const; + INLINE NumType dist_to_plane(const LPoint3 &point) const; + INLINE bool intersects_line(LPoint3 &intersection_point, + const LPoint3 &p1, + const LPoint3 &p2) const; + INLINE bool intersects_line(NumType &t, + const LPoint3 &from, + const LVector3 &delta) const; + + void output(ostream &out) const; + void write(ostream &out, int indent_level = 0) const; + +public: + INLINE void write_datagram(Datagram &dest); + INLINE void read_datagram(DatagramIterator &source); + +public: + NumType _a, _b, _c, _d; +}; + +template +INLINE ostream &operator << (ostream &out, const Plane &p) { + p.output(out); + return out; +} + +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, Plane) +EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, Plane) + +typedef Plane Planef; +typedef Plane Planed; + #include "plane.I" -#include "dblnames.I" -#include "plane.I" + +// Tell GCC that we'll take care of the instantiation explicitly here. +#ifdef __GNUC__ +#pragma interface +#endif #endif diff --git a/panda/src/mathutil/rotate_to.cxx b/panda/src/mathutil/rotate_to.cxx index ea9e32e948..917b2c3ee7 100644 --- a/panda/src/mathutil/rotate_to.cxx +++ b/panda/src/mathutil/rotate_to.cxx @@ -4,11 +4,89 @@ //////////////////////////////////////////////////////////////////// #include -#include #include "rotate_to.h" +#include "luse.h" -#include "fltnames.I" -#include "rotate_to_src.I" +#include -#include "dblnames.I" -#include "rotate_to_src.I" \ No newline at end of file +//////////////////////////////////////////////////////////////////// +// Function: _rotate_to +// Description: Computes the matrix necessary to rotate vector a onto +// vector b. It is assumed that both vectors are +// normalized. +//////////////////////////////////////////////////////////////////// +template +static void +_rotate_to(LMatrix3 &mat, + const LVector3 &a, const LVector3 &b) { + NumType cos_theta = a.dot(b); + + LVector3 axis = a.cross(b); + NumType sin_theta = length(axis); + + // Check for collinear vectors + if (sin_theta < 0.0001) { + // The vectors are collinear. + + if (cos_theta < 0.0) { + // The vectors are opposite; choose an arbitrary axis + // perpendicular to a. + LVector3 absa(fabs(a[0]), fabs(a[1]), fabs(a[2])); + LVector3 lca(0., 0., 0.); + lca[absa[0]<=absa[1] ? absa[0]<=absa[2] ? 0 : 2 + : absa[1]<=absa[2] ? 1 : 2] = 1.0; + + axis = normalize(a.cross(lca)); + } else { + mat = LMatrix3::ident_mat(); + return; + } + + } else { + // The vectors are not collinear; determine the best axis. + axis /= sin_theta; + } + + NumType x = axis[0]; + NumType y = axis[1]; + NumType z = axis[2]; + + NumType t = 1.0 - cos_theta; + + mat(0, 0) = t * x * x + cos_theta; + mat(0, 1) = t * x * y + sin_theta * z; + mat(0, 2) = t * x * z - sin_theta * y; + + mat(1, 0) = t * y * x - sin_theta * z; + mat(1, 1) = t * y * y + cos_theta; + mat(1, 2) = t * y * z + sin_theta * x; + + mat(2, 0) = t * z * x + sin_theta * y; + mat(2, 1) = t * z * y - sin_theta * x; + mat(2, 2) = t * z * z + cos_theta; +} + + +void +rotate_to(LMatrix3f &mat, const LVector3f &a, const LVector3f &b) { + _rotate_to(mat, a, b); +} + +void +rotate_to(LMatrix3d &mat, const LVector3d &a, const LVector3d &b) { + _rotate_to(mat, a, b); +} + +void +rotate_to(LMatrix4f &mat, const LVector3f &a, const LVector3f &b) { + LMatrix3f m3; + _rotate_to(m3, a, b); + mat = LMatrix4f(m3); +} + +void +rotate_to(LMatrix4d &mat, const LVector3d &a, const LVector3d &b) { + LMatrix3d m3; + _rotate_to(m3, a, b); + mat = LMatrix4d(m3); +} diff --git a/panda/src/mathutil/rotate_to.h b/panda/src/mathutil/rotate_to.h index 24142443b2..f60d665a2c 100644 --- a/panda/src/mathutil/rotate_to.h +++ b/panda/src/mathutil/rotate_to.h @@ -17,8 +17,9 @@ // //////////////////////////////////////////////////////////////////// -#include #include + +#include "lmatrix.h" #include "luse.h" BEGIN_PUBLISH