switch linmath from templates to classes

This commit is contained in:
cxgeorge 2001-03-10 02:14:23 +00:00
parent 698ce93e15
commit a0e51a9997
101 changed files with 5919 additions and 5884 deletions

View File

@ -957,7 +957,7 @@ convex_quad(Edge *common_edge, MesherStrip &front, MesherStrip &back,
}
}
LVecBase2<float> a2, b2, c2, d2;
LVecBase2f a2, b2, c2, d2;
a2.set(a3[xi], a3[yi]);
b2.set(b3[xi], b3[yi]);
c2.set(c3[xi], c3[yi]);

View File

@ -1499,7 +1499,7 @@ draw_sprite(const GeomSprite *geom) {
for (pSpr=SpriteArray,i = 0; i < nprims; i++,pSpr++) {
source_vert = geom->get_next_vertex(vi);
cameraspace_vert = modelview_mat * source_vert;
cameraspace_vert = source_vert * modelview_mat;
pSpr->_v.set(cameraspace_vert[0],cameraspace_vert[1],cameraspace_vert[2]);
@ -1596,10 +1596,10 @@ draw_sprite(const GeomSprite *geom) {
LMatrix3f xform_mat = LMatrix3f::rotate_mat(theta) *
LMatrix3f::scale_mat(scaled_width, scaled_height);
ur = (xform_mat * LVector3f(1, 1, 0)) + pSpr->_v;
ul = (xform_mat * LVector3f(-1, 1, 0)) + pSpr->_v;
lr = (xform_mat * LVector3f(1, -1, 0)) + pSpr->_v;
ll = (xform_mat * LVector3f(-1, -1, 0)) + pSpr->_v;
ur = (LVector3f( 1, 1, 0) * xform_mat) + pSpr->_v;
ul = (LVector3f(-1, 1, 0) * xform_mat) + pSpr->_v;
lr = (LVector3f( 1, -1, 0) * xform_mat) + pSpr->_v;
ll = (LVector3f(-1, -1, 0) * xform_mat) + pSpr->_v;
} else {
// create points for unrotated rect sprites
float x,y,negx,negy,z;

View File

@ -286,7 +286,7 @@ make_nonindexed_primitive(EggPrimitive *egg_prim, NamedNode *parent,
bprim.set_normal(LCAST(float, egg_prim->get_normal() * mat));
}
if (egg_prim->has_color() && !egg_false_color) {
bprim.set_color(LCAST(float, egg_prim->get_color()));
bprim.set_color(egg_prim->get_color());
}
bool has_vert_color = true;
@ -299,7 +299,7 @@ make_nonindexed_primitive(EggPrimitive *egg_prim, NamedNode *parent,
bvert.set_normal(LCAST(float, egg_vert->get_normal() * mat));
}
if (egg_vert->has_color() && !egg_false_color) {
bvert.set_color(LCAST(float, egg_vert->get_color()));
bvert.set_color(egg_vert->get_color());
} else {
// If any vertex doesn't have a color, we can't use any of the
// vertex colors.

View File

@ -1067,7 +1067,7 @@ draw_sprite(const GeomSprite *geom) {
source_vert = geom->get_next_vertex(vi);
// this mult converts to y-up cameraspace.
cameraspace_vert = modelview_mat * source_vert;
cameraspace_vert = source_vert * modelview_mat;
#ifdef DO_CHARLES_PROJECTION_MAT
float x,y,z;
@ -1137,13 +1137,12 @@ draw_sprite(const GeomSprite *geom) {
theta = cur_image._theta;
// create the rotated points
LMatrix3f xform_mat = LMatrix3f::rotate_mat(theta) *
LMatrix3f::scale_mat(scaled_width, scaled_height);
LMatrix3f xform_mat = LMatrix3f::rotate_mat(theta) * LMatrix3f::scale_mat(scaled_width, scaled_height);
ur = (xform_mat * LVector3f(1, 1, 0)) + cur_image._v;
ul = (xform_mat * LVector3f(-1, 1, 0)) + cur_image._v;
lr = (xform_mat * LVector3f(1, -1, 0)) + cur_image._v;
ll = (xform_mat * LVector3f(-1, -1, 0)) + cur_image._v;
ur = (LVector3f( 1, 1, 0) * xform_mat) + cur_image._v;
ul = (LVector3f(-1, 1, 0) * xform_mat) + cur_image._v;
lr = (LVector3f( 1, -1, 0) * xform_mat) + cur_image._v;
ll = (LVector3f(-1, -1, 0) * xform_mat) + cur_image._v;
}
else {
// create the normal points

View File

@ -21,8 +21,8 @@ void GuiItem::adjust_region(void) {
this->get_graph_mat(m);
LPoint3f ul = LVector3f::rfu(_left, 0., _top);
LPoint3f lr = LVector3f::rfu(_right, 0., _bottom);
ul = m * ul;
lr = m * lr;
ul = ul * m;
lr = lr * m ;
_left = ul.dot(LVector3f::rfu(1., 0., 0.));
_top = ul.dot(LVector3f::rfu(0., 0., 1.));
_right = lr.dot(LVector3f::rfu(1., 0., 0.));

View File

@ -369,8 +369,8 @@ void GuiLabel::get_extents(float& l, float& r, float& b, float& t) {
_scale_z)) *
LMatrix4f::scale_mat(_scale) *
LMatrix4f::translate_mat(_pos);
ul = mat * ul;
lr = mat * lr;
ul = ul * mat;
lr = lr * mat;
l = ul.dot(ul.right());
r = lr.dot(lr.right());
b = lr.dot(lr.up());

View File

@ -12,13 +12,22 @@
coordinateSystem.h deg_2_rad.h \
ioPtaDatagramLinMath.I ioPtaDatagramLinMath.cxx \
ioPtaDatagramLinMath.h lmatrix.cxx lmatrix.h \
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 \
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\
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 \
@ -34,7 +43,8 @@
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 \
@ -42,7 +52,8 @@
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
vector_Vertexf.h \
fltnames.I dblnames.I
#define IGATESCAN all

View File

@ -3,47 +3,47 @@
//
////////////////////////////////////////////////////////////////////
INLINE LVecBase2<double> cast_to_double(const LVecBase2<float> &source) {
INLINE LVecBase2d cast_to_double(const LVecBase2f &source) {
return LCAST(double, source);
}
INLINE LVecBase3<double> cast_to_double(const LVecBase3<float> &source) {
INLINE LVecBase3d cast_to_double(const LVecBase3f &source) {
return LCAST(double, source);
}
INLINE LVecBase4<double> cast_to_double(const LVecBase4<float> &source) {
INLINE LVecBase4d cast_to_double(const LVecBase4f &source) {
return LCAST(double, source);
}
INLINE LVector2<double> cast_to_double(const LVector2<float> &source) {
INLINE LVector2d cast_to_double(const LVector2f &source) {
return LCAST(double, source);
}
INLINE LVector3<double> cast_to_double(const LVector3<float> &source) {
INLINE LVector3d cast_to_double(const LVector3f &source) {
return LCAST(double, source);
}
INLINE LVector4<double> cast_to_double(const LVector4<float> &source) {
INLINE LVector4d cast_to_double(const LVector4f &source) {
return LCAST(double, source);
}
INLINE LPoint2<double> cast_to_double(const LPoint2<float> &source) {
INLINE LPoint2d cast_to_double(const LPoint2f &source) {
return LCAST(double, source);
}
INLINE LPoint3<double> cast_to_double(const LPoint3<float> &source) {
INLINE LPoint3d cast_to_double(const LPoint3f &source) {
return LCAST(double, source);
}
INLINE LPoint4<double> cast_to_double(const LPoint4<float> &source) {
INLINE LPoint4d cast_to_double(const LPoint4f &source) {
return LCAST(double, source);
}
INLINE LMatrix3<double> cast_to_double(const LMatrix3<float> &source) {
INLINE LMatrix3d cast_to_double(const LMatrix3f &source) {
return LCAST(double, source);
}
INLINE LMatrix4<double> cast_to_double(const LMatrix4<float> &source) {
INLINE LMatrix4d cast_to_double(const LMatrix4f &source) {
return LCAST(double, source);
}

View File

@ -13,17 +13,17 @@
// These are a number of functions that convert our various math
// objects between floats and doubles.
INLINE LVecBase2<double> cast_to_double(const LVecBase2<float> &source);
INLINE LVecBase3<double> cast_to_double(const LVecBase3<float> &source);
INLINE LVecBase4<double> cast_to_double(const LVecBase4<float> &source);
INLINE LVector2<double> cast_to_double(const LVector2<float> &source);
INLINE LVector3<double> cast_to_double(const LVector3<float> &source);
INLINE LVector4<double> cast_to_double(const LVector4<float> &source);
INLINE LPoint2<double> cast_to_double(const LPoint2<float> &source);
INLINE LPoint3<double> cast_to_double(const LPoint3<float> &source);
INLINE LPoint4<double> cast_to_double(const LPoint4<float> &source);
INLINE LMatrix3<double> cast_to_double(const LMatrix3<float> &source);
INLINE LMatrix4<double> cast_to_double(const LMatrix4<float> &source);
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);
#include "cast_to_double.I"

View File

@ -3,47 +3,47 @@
//
////////////////////////////////////////////////////////////////////
INLINE LVecBase2<float> cast_to_float(const LVecBase2<double> &source) {
INLINE LVecBase2f cast_to_float(const LVecBase2d &source) {
return LCAST(float, source);
}
INLINE LVecBase3<float> cast_to_float(const LVecBase3<double> &source) {
INLINE LVecBase3f cast_to_float(const LVecBase3d &source) {
return LCAST(float, source);
}
INLINE LVecBase4<float> cast_to_float(const LVecBase4<double> &source) {
INLINE LVecBase4f cast_to_float(const LVecBase4d &source) {
return LCAST(float, source);
}
INLINE LVector2<float> cast_to_float(const LVector2<double> &source) {
INLINE LVector2f cast_to_float(const LVector2d &source) {
return LCAST(float, source);
}
INLINE LVector3<float> cast_to_float(const LVector3<double> &source) {
INLINE LVector3f cast_to_float(const LVector3d &source) {
return LCAST(float, source);
}
INLINE LVector4<float> cast_to_float(const LVector4<double> &source) {
INLINE LVector4f cast_to_float(const LVector4d &source) {
return LCAST(float, source);
}
INLINE LPoint2<float> cast_to_float(const LPoint2<double> &source) {
INLINE LPoint2f cast_to_float(const LPoint2d &source) {
return LCAST(float, source);
}
INLINE LPoint3<float> cast_to_float(const LPoint3<double> &source) {
INLINE LPoint3f cast_to_float(const LPoint3d &source) {
return LCAST(float, source);
}
INLINE LPoint4<float> cast_to_float(const LPoint4<double> &source) {
INLINE LPoint4f cast_to_float(const LPoint4d &source) {
return LCAST(float, source);
}
INLINE LMatrix3<float> cast_to_float(const LMatrix3<double> &source) {
INLINE LMatrix3f cast_to_float(const LMatrix3d &source) {
return LCAST(float, source);
}
INLINE LMatrix4<float> cast_to_float(const LMatrix4<double> &source) {
INLINE LMatrix4f cast_to_float(const LMatrix4d &source) {
return LCAST(float, source);
}

View File

@ -13,17 +13,17 @@
// These are a number of functions that convert our various math
// objects between floats and doubles.
INLINE LVecBase2<float> cast_to_float(const LVecBase2<double> &source);
INLINE LVecBase3<float> cast_to_float(const LVecBase3<double> &source);
INLINE LVecBase4<float> cast_to_float(const LVecBase4<double> &source);
INLINE LVector2<float> cast_to_float(const LVector2<double> &source);
INLINE LVector3<float> cast_to_float(const LVector3<double> &source);
INLINE LVector4<float> cast_to_float(const LVector4<double> &source);
INLINE LPoint2<float> cast_to_float(const LPoint2<double> &source);
INLINE LPoint3<float> cast_to_float(const LPoint3<double> &source);
INLINE LPoint4<float> cast_to_float(const LPoint4<double> &source);
INLINE LMatrix3<float> cast_to_float(const LMatrix3<double> &source);
INLINE LMatrix4<float> cast_to_float(const LMatrix4<double> &source);
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);
#include "cast_to_float.I"

View File

@ -1,77 +1,127 @@
////////////////////////////////////////////////////////////////////
// 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(LMatrix4f &mat,
const float components[9],
CoordinateSystem cs) {
LVector3f scale(components[0],
components[1],
components[2]);
LVector3f hpr(components[3],
components[4],
components[5]);
LVector3f translate(components[6],
components[7],
components[8]);
compose_matrix(mat, scale, hpr, translate, cs);
_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);
}
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;
////////////////////////////////////////////////////////////////////
// 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(LMatrix4d &mat,
const double components[9],
compose_matrix(FLOATNAME(LMatrix4) &mat,
const FLOATTYPE1 components[9],
CoordinateSystem cs) {
LVector3d scale(components[0],
FLOATNAME(LVector3) scale(components[0],
components[1],
components[2]);
LVector3d hpr(components[3],
FLOATNAME(LVector3) hpr(components[3],
components[4],
components[5]);
LVector3d translate(components[6],
FLOATNAME(LVector3) translate(components[6],
components[7],
components[8]);
compose_matrix(mat, scale, hpr, translate, 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;
EXPCL_PANDA INLINE void
compose_matrix(FLOATNAME(LMatrix3) &mat,
const FLOATNAME(LVecBase3) &scale,
const FLOATNAME(LVecBase3) &hpr,
CoordinateSystem cs) {
_compose_matrix(mat, scale, hpr, 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);
}

View File

@ -3,706 +3,15 @@
//
////////////////////////////////////////////////////////////////////
#include "compose_matrix.h"
#include "deg_2_rad.h"
#include "config_linmath.h"
#include "compose_matrix.h"
#include <math.h>
#include "fltnames.I"
#include "compose_matrix_src.I"
////////////////////////////////////////////////////////////////////
// Function: compose_matrix
// Description: Computes the 3x3 matrix from scale and rotation.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void
_compose_matrix(LMatrix3<NumType> &mat,
const LVecBase3<NumType> &scale,
const LVecBase3<NumType> &hpr,
CoordinateSystem cs) {
mat =
LMatrix3<NumType>::scale_mat(scale) *
LMatrix3<NumType>::rotate_mat(hpr[1], LVector3<NumType>::right(cs), cs) *
LMatrix3<NumType>::rotate_mat(hpr[0], LVector3<NumType>::up(cs), cs) *
LMatrix3<NumType>::rotate_mat(hpr[2], LVector3<NumType>::back(cs), cs);
}
#include "dblnames.I"
#include "compose_matrix_src.I"
////////////////////////////////////////////////////////////////////
// Function: compose_matrix
// Description: Computes the 4x4 matrix according to scale, rotation,
// and translation.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void
_compose_matrix(LMatrix4<NumType> &mat,
const LVecBase3<NumType> &scale,
const LVecBase3<NumType> &hpr,
const LVecBase3<NumType> &translate,
CoordinateSystem cs) {
LMatrix3<NumType> upper3;
_compose_matrix(upper3, scale, hpr, cs);
mat = LMatrix4<NumType>(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<class NumType>
static void
unwind_yup_rotation(LMatrix3<NumType> &mat, LVecBase3<NumType> &hpr) {
typedef LMatrix3<NumType> Matrix;
// Extract the axes from the matrix.
LVector3<NumType> 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<NumType> 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<NumType>(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<NumType> 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<NumType>(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<NumType> 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<NumType>(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<class NumType>
static void
unwind_yup_rotation(LMatrix3<NumType> &mat, LVecBase3<NumType> &hpr,
NumType roll) {
typedef LMatrix3<NumType> Matrix;
// Extract the axes from the matrix.
LVector3<NumType> 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<NumType>(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<NumType> 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<NumType>(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<NumType> 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<NumType>(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<class NumType>
static void
unwind_zup_rotation(LMatrix3<NumType> &mat, LVecBase3<NumType> &hpr) {
typedef LMatrix3<NumType> Matrix;
// Extract the axes from the matrix.
LVector3<NumType> 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<NumType> 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<NumType>(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<NumType> 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<NumType>(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<NumType> 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<NumType>(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<class NumType>
static void
unwind_zup_rotation(LMatrix3<NumType> &mat, LVecBase3<NumType> &hpr,
NumType roll) {
typedef LMatrix3<NumType> Matrix;
// Extract the axes from the matrix.
LVector3<NumType> 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<NumType>(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<NumType> 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<NumType>(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<NumType> 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<NumType>(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<class NumType>
static bool
_decompose_matrix(const LMatrix3<NumType> &mat,
LVecBase3<NumType> &scale,
LVecBase3<NumType> &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<NumType> 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<NumType> 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<NumType> 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<NumType> 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<class NumType>
static bool
_decompose_matrix(const LMatrix3<NumType> &mat,
LVecBase3<NumType> &scale,
LVecBase3<NumType> &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<NumType> 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<NumType> 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<NumType> 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<NumType> 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<class NumType>
INLINE bool
_decompose_matrix(const LMatrix4<NumType> &mat,
LVecBase3<NumType> &scale,
LVecBase3<NumType> &hpr,
LVecBase3<NumType> &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<class NumType>
INLINE bool
_decompose_matrix(const LMatrix4<NumType> &mat,
LVecBase3<NumType> &scale,
LVecBase3<NumType> &hpr,
LVecBase3<NumType> &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);
}

View File

@ -26,98 +26,14 @@
////////////////////////////////////////////////////////////////////
#include <pandabase.h>
#include <math.h>
#include "lmatrix.h"
#include "luse.h"
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 "fltnames.I"
#include "compose_matrix.I"
#include "dblnames.I"
#include "compose_matrix.I"
#endif

View File

@ -0,0 +1,616 @@
// Filename: compose_matrix.cxx
// Created by: drose (27Jan99)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// 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.
////////////////////////////////////////////////////////////////////
static void
unwind_yup_rotation(FLOATNAME(LMatrix3) &mat, FLOATNAME(LVecBase3) &hpr) {
typedef FLOATNAME(LMatrix3) Matrix;
// Extract the axes from the matrix.
FLOATNAME(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.
FLOATNAME(LVector2) xy(x[0], x[1]);
xy = normalize(xy);
// Compute the rotation about the +Z (back) axis. This is roll.
FLOATTYPE1 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, FLOATNAME(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.
FLOATNAME(LVector2) xz(x[0], x[2]);
xz = normalize(xz);
// Compute the rotation about the +Y (up) axis. This is yaw, or
// "heading".
FLOATTYPE1 heading = rad_2_deg(-atan2(xz[1], xz[0]));
// Unwind the heading, and continue.
Matrix rot_y;
rot_y = Matrix::rotate_mat(-heading, FLOATNAME(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.
FLOATNAME(LVector2) yz(z[1], z[2]);
yz = normalize(yz);
// Compute the rotation about the +X (right) axis. This is pitch.
FLOATTYPE1 pitch = rad_2_deg(-atan2(yz[0], yz[1]));
// Unwind the pitch.
Matrix rot_x;
rot_x = Matrix::rotate_mat(-pitch, FLOATNAME(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.
////////////////////////////////////////////////////////////////////
static void
unwind_yup_rotation(FLOATNAME(LMatrix3) &mat, FLOATNAME(LVecBase3) &hpr,
FLOATTYPE1 roll) {
typedef FLOATNAME(LMatrix3) Matrix;
// Extract the axes from the matrix.
FLOATNAME(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, FLOATNAME(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.
FLOATNAME(LVector2) xz(x[0], x[2]);
xz = normalize(xz);
// Compute the rotation about the +Y (up) axis. This is yaw, or
// "heading".
FLOATTYPE1 heading = rad_2_deg(-atan2(xz[1], xz[0]));
// Unwind the heading, and continue.
Matrix rot_y;
rot_y = Matrix::rotate_mat(-heading, FLOATNAME(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.
FLOATNAME(LVector2) yz(z[1], z[2]);
yz = normalize(yz);
// Compute the rotation about the +X (right) axis. This is pitch.
FLOATTYPE1 pitch = rad_2_deg(-atan2(yz[0], yz[1]));
// Unwind the pitch.
Matrix rot_x;
rot_x = Matrix::rotate_mat(-pitch, FLOATNAME(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.
////////////////////////////////////////////////////////////////////
static void
unwind_zup_rotation(FLOATNAME(LMatrix3) &mat, FLOATNAME(LVecBase3) &hpr) {
typedef FLOATNAME(LMatrix3) Matrix;
// Extract the axes from the matrix.
FLOATNAME(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.
FLOATNAME(LVector2) xz(x[0], x[2]);
xz = normalize(xz);
// Compute the rotation about the -Y (back) axis. This is roll.
FLOATTYPE1 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, FLOATNAME(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.
FLOATNAME(LVector2) xy(x[0], x[1]);
xy = normalize(xy);
// Compute the rotation about the +Z (up) axis. This is yaw, or
// "heading".
FLOATTYPE1 heading = rad_2_deg(atan2(xy[1], xy[0]));
// Unwind the heading, and continue.
Matrix rot_z;
rot_z = Matrix::rotate_mat(-heading, FLOATNAME(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.
FLOATNAME(LVector2) yz(y[1], y[2]);
yz = normalize(yz);
// Compute the rotation about the +X (right) axis. This is pitch.
FLOATTYPE1 pitch = rad_2_deg(atan2(yz[1], yz[0]));
// Unwind the pitch.
Matrix rot_x;
rot_x = Matrix::rotate_mat(-pitch, FLOATNAME(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.
////////////////////////////////////////////////////////////////////
static void
unwind_zup_rotation(FLOATNAME(LMatrix3) &mat, FLOATNAME(LVecBase3) &hpr,
FLOATTYPE1 roll) {
typedef FLOATNAME(LMatrix3) Matrix;
// Extract the axes from the matrix.
FLOATNAME(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, FLOATNAME(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.
FLOATNAME(LVector2) xy(x[0], x[1]);
xy = normalize(xy);
// Compute the rotation about the +Z (up) axis. This is yaw, or
// "heading".
FLOATTYPE1 heading = rad_2_deg(atan2(xy[1], xy[0]));
// Unwind the heading, and continue.
Matrix rot_z;
rot_z = Matrix::rotate_mat(-heading, FLOATNAME(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.
FLOATNAME(LVector2) yz(y[1], y[2]);
yz = normalize(yz);
// Compute the rotation about the +X (right) axis. This is pitch.
FLOATTYPE1 pitch = rad_2_deg(atan2(yz[1], yz[0]));
// Unwind the pitch.
Matrix rot_x;
rot_x = Matrix::rotate_mat(-pitch, FLOATNAME(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.
////////////////////////////////////////////////////////////////////
static bool
_decompose_matrix(const FLOATNAME(LMatrix3) &mat,
FLOATNAME(LVecBase3) &scale,
FLOATNAME(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:
{
FLOATNAME(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:
{
FLOATNAME(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:
{
FLOATNAME(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:
{
FLOATNAME(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.
////////////////////////////////////////////////////////////////////
static bool
_decompose_matrix(const FLOATNAME(LMatrix3) &mat,
FLOATNAME(LVecBase3) &scale,
FLOATNAME(LVecBase3) &hpr,
FLOATTYPE1 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:
{
FLOATNAME(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:
{
FLOATNAME(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:
{
FLOATNAME(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:
{
FLOATNAME(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;
}
INLINE bool
decompose_matrix(const FLOATNAME(LMatrix4) &mat,
FLOATTYPE1 components[9],
CoordinateSystem cs) {
FLOATNAME(LVector3) 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;
}
////////////////////////////////////////////////////////////////////
// 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.
////////////////////////////////////////////////////////////////////
INLINE bool
_decompose_matrix(const FLOATNAME(LMatrix4) &mat,
FLOATNAME(LVecBase3) &scale,
FLOATNAME(LVecBase3) &hpr,
FLOATNAME(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.
////////////////////////////////////////////////////////////////////
INLINE bool
_decompose_matrix(const FLOATNAME(LMatrix4) &mat,
FLOATNAME(LVecBase3) &scale,
FLOATNAME(LVecBase3) &hpr,
FLOATNAME(LVecBase3) &translate,
FLOATTYPE1 roll,
CoordinateSystem cs) {
// Get the translation first.
translate = mat.get_row3(3);
return _decompose_matrix(mat.get_upper_3(), scale, hpr, roll, cs);
}
bool
decompose_matrix(const FLOATNAME(LMatrix3) &mat,
FLOATNAME(LVecBase3) &scale,
FLOATNAME(LVecBase3) &hpr,
CoordinateSystem cs) {
return _decompose_matrix(mat, scale, hpr, cs);
}
bool
decompose_matrix(const FLOATNAME(LMatrix3) &mat,
FLOATNAME(LVecBase3) &scale,
FLOATNAME(LVecBase3) &hpr,
float roll,
CoordinateSystem cs) {
return _decompose_matrix(mat, scale, hpr, roll, cs);
}
bool
decompose_matrix(const FLOATNAME(LMatrix4) &mat,
FLOATNAME(LVecBase3) &scale,
FLOATNAME(LVecBase3) &hpr,
FLOATNAME(LVecBase3) &translate,
CoordinateSystem cs) {
return _decompose_matrix(mat, scale, hpr, translate, cs);
}
bool
decompose_matrix(const FLOATNAME(LMatrix4) &mat,
FLOATNAME(LVecBase3) &scale,
FLOATNAME(LVecBase3) &hpr,
FLOATNAME(LVecBase3) &translate,
float roll,
CoordinateSystem cs) {
return _decompose_matrix(mat, scale, hpr, translate, roll, cs);
}

View File

@ -0,0 +1,9 @@
#undef FLOATTYPE1
#undef FLOATTYPE2
#undef FLOATNAME
#undef FLOATNAME2
#define FLOATTYPE1 double
#define FLOATTYPE2 float
#define FLOATNAME(ARG) ARG##d
#define FLOATNAME2(ARG) ARG##f

View File

@ -0,0 +1,9 @@
#undef FLOATTYPE1
#undef FLOATTYPE2
#undef FLOATNAME
#undef FLOATNAME2
#define FLOATTYPE1 float
#define FLOATTYPE2 double
#define FLOATNAME(ARG) ARG##f
#define FLOATNAME2(ARG) ARG##d

View File

@ -3,13 +3,90 @@
//
////////////////////////////////////////////////////////////////////
/*
// 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<double>
operator * (const LVecBase3<double> &v, const LMatrix3<double> &m);
INLINE LVector2<double>
operator * (const LVector2<double> &v, const LMatrix3<double> &m);
INLINE LPoint2<double>
operator * (const LPoint2<double> &v, const LMatrix3<double> &m);
INLINE LVecBase4<double>
operator * (const LVecBase4<double> &v, const LMatrix4<double> &m);
INLINE LVector3<double>
operator * (const LVector3<double> &v, const LMatrix4<double> &m);
INLINE LPoint3<double>
operator * (const LPoint3<double> &v, const LMatrix4<double> &m);
*/
END_PUBLISH
#endif // CPPPARSER
////////////////////////////////////////////////////////////////////
// Function: LVecBase3 times LMatrix3
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType>
operator * (const LVecBase3<NumType> &v, const LMatrix3<NumType> &m) {
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) {
return m.xform(v);
}
@ -17,9 +94,9 @@ operator * (const LVecBase3<NumType> &v, const LMatrix3<NumType> &m) {
// Function: LVector2 times LMatrix3
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType>
operator * (const LVector2<NumType> &v, const LMatrix3<NumType> &m) {
INLINE FLOATNAME(LVector2)
operator * (const FLOATNAME(LVector2) &v, const FLOATNAME(LMatrix3) &m) {
return m.xform_vec(v);
}
@ -27,9 +104,9 @@ operator * (const LVector2<NumType> &v, const LMatrix3<NumType> &m) {
// Function: LPoint2 times LMatrix3
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint2<NumType>
operator * (const LPoint2<NumType> &v, const LMatrix3<NumType> &m) {
INLINE FLOATNAME(LPoint2)
operator * (const FLOATNAME(LPoint2) &v, const FLOATNAME(LMatrix3) &m) {
return m.xform_point(v);
}
@ -38,19 +115,30 @@ operator * (const LPoint2<NumType> &v, const LMatrix3<NumType> &m) {
// Function: LVecBase4 times LMatrix4
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType>
operator * (const LVecBase4<NumType> &v, const LMatrix4<NumType> &m) {
INLINE FLOATNAME(LVecBase4)
operator * (const FLOATNAME(LVecBase4) &v, const FLOATNAME(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:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType>
operator * (const LVector3<NumType> &v, const LMatrix4<NumType> &m) {
INLINE FLOATNAME(LVector3)
operator * (const FLOATNAME(LVector3) &v, const FLOATNAME(LMatrix4) &m) {
return m.xform_vec(v);
}
@ -58,9 +146,9 @@ operator * (const LVector3<NumType> &v, const LMatrix4<NumType> &m) {
// Function: LPoint3 times LMatrix4
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType>
operator * (const LPoint3<NumType> &v, const LMatrix4<NumType> &m) {
INLINE FLOATNAME(LPoint3)
operator * (const FLOATNAME(LPoint3) &v, const FLOATNAME(LMatrix4) &m) {
return m.xform_point(v);
}

View File

@ -15,71 +15,11 @@
#include "lmatrix3.h"
#include "lmatrix4.h"
// vector times matrix3
template<class NumType>
INLINE LVecBase3<NumType>
operator * (const LVecBase3<NumType> &v, const LMatrix3<NumType> &m);
template<class NumType>
INLINE LVector2<NumType>
operator * (const LVector2<NumType> &v, const LMatrix3<NumType> &m);
template<class NumType>
INLINE LPoint2<NumType>
operator * (const LPoint2<NumType> &v, const LMatrix3<NumType> &m);
// vector times matrix4
template<class NumType>
INLINE LVecBase4<NumType>
operator * (const LVecBase4<NumType> &v, const LMatrix4<NumType> &m);
template<class NumType>
INLINE LVector3<NumType>
operator * (const LVector3<NumType> &v, const LMatrix4<NumType> &m);
template<class NumType>
INLINE LPoint3<NumType>
operator * (const LPoint3<NumType> &v, const LMatrix4<NumType> &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<float>
operator * (const LVecBase3<float> &v, const LMatrix3<float> &m);
INLINE LVector2<float>
operator * (const LVector2<float> &v, const LMatrix3<float> &m);
INLINE LPoint2<float>
operator * (const LPoint2<float> &v, const LMatrix3<float> &m);
INLINE LVecBase4<float>
operator * (const LVecBase4<float> &v, const LMatrix4<float> &m);
INLINE LVector3<float>
operator * (const LVector3<float> &v, const LMatrix4<float> &m);
INLINE LPoint3<float>
operator * (const LPoint3<float> &v, const LMatrix4<float> &m);
INLINE LVecBase3<double>
operator * (const LVecBase3<double> &v, const LMatrix3<double> &m);
INLINE LVector2<double>
operator * (const LVector2<double> &v, const LMatrix3<double> &m);
INLINE LPoint2<double>
operator * (const LPoint2<double> &v, const LMatrix3<double> &m);
INLINE LVecBase4<double>
operator * (const LVecBase4<double> &v, const LMatrix4<double> &m);
INLINE LVector3<double>
operator * (const LVector3<double> &v, const LMatrix4<double> &m);
INLINE LPoint3<double>
operator * (const LPoint3<double> &v, const LMatrix4<double> &m);
END_PUBLISH
#endif // CPPPARSER
#include "fltnames.I"
#include "lmat_ops.I"
#include "dblnames.I"
#include "lmat_ops.I"
#endif

View File

@ -7,15 +7,18 @@
#define LMATRIX_H
#include <pandabase.h>
#include "config_linmath.h"
#include "lmatrix3.h"
#include "lmatrix4.h"
/*
typedef LMatrix3<float> LMatrix3f;
typedef LMatrix4<float> LMatrix4f;
typedef LMatrix3<double> LMatrix3d;
typedef LMatrix4<double> LMatrix4d;
*/
// Tell GCC that we'll take care of the instantiation explicitly here.
#ifdef __GNUC__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
// Filename: lmatrix3.cxx
// Created by: drose (29Jan99)
//
////////////////////////////////////////////////////////////////////
#include "config_linmath.h"
#include "lmatrix3.h"
#include "fltnames.I"
#include "lmatrix3_src.I"
#include "dblnames.I"
#include "lmatrix3_src.I"

View File

@ -7,188 +7,50 @@
#define LMATRIX3_H
#include <pandabase.h>
#include <math.h>
#include <typeHandle.h>
#include <datagram.h>
#include <datagramIterator.h>
#include <notify.h>
#include <indent.h>
#include "deg_2_rad.h"
#include "nearly_zero.h"
#include "coordinateSystem.h"
#include "lvecBase3.h"
#include "lvecBase2.h"
#include <typeHandle.h>
#include <datagram.h>
#include <datagramIterator.h>
////////////////////////////////////////////////////////////////////
// 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.
////////////////////////////////////////////////////////////////////
template<class NumType>
class LMatrix3 {
PUBLISHED:
typedef const NumType *iterator;
typedef const NumType *const_iterator;
INLINE LMatrix3();
INLINE LMatrix3(const LMatrix3<NumType> &other);
LMatrix3<NumType> &operator = (const LMatrix3<NumType> &other);
INLINE LMatrix3<NumType> &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<NumType> &v);
INLINE void set_col(int col, const LVecBase3<NumType> &v);
INLINE void set_row(int row, const LVecBase2<NumType> &v);
INLINE void set_col(int col, const LVecBase2<NumType> &v);
INLINE LVecBase3<NumType> get_row(int row) const;
INLINE LVecBase3<NumType> get_col(int col) const;
INLINE LVecBase2<NumType> get_row2(int row) const;
INLINE LVecBase2<NumType> 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<NumType> &other) const;
INLINE bool operator != (const LMatrix3<NumType> &other) const;
INLINE int compare_to(const LMatrix3<NumType> &other) const;
int compare_to(const LMatrix3<NumType> &other, NumType threshold) const;
INLINE LVecBase3<NumType>
xform(const LVecBase3<NumType> &v) const;
INLINE LVecBase2<NumType>
xform_point(const LVecBase2<NumType> &v) const;
INLINE LVecBase2<NumType>
xform_vec(const LVecBase2<NumType> &v) const;
LMatrix3<NumType> operator * (const LMatrix3<NumType> &other) const;
LMatrix3<NumType> operator * (NumType scalar) const;
LMatrix3<NumType> operator / (NumType scalar) const;
LMatrix3<NumType> &operator += (const LMatrix3<NumType> &other);
LMatrix3<NumType> &operator -= (const LMatrix3<NumType> &other);
INLINE LMatrix3<NumType> &operator *= (const LMatrix3<NumType> &other);
LMatrix3<NumType> &operator *= (NumType scalar);
LMatrix3<NumType> &operator /= (NumType scalar);
INLINE NumType determinant() const;
void transpose_from(const LMatrix3<NumType> &other);
INLINE void transpose_in_place();
bool invert_from(const LMatrix3<NumType> &other);
INLINE bool invert_in_place();
static const LMatrix3<NumType> &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<NumType> translate_mat(const LVecBase2<NumType> &trans);
static LMatrix3<NumType> translate_mat(NumType tx, NumType ty);
static LMatrix3<NumType> rotate_mat(NumType angle);
static LMatrix3<NumType> scale_mat(const LVecBase2<NumType> &scale);
static LMatrix3<NumType> 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<NumType> rotate_mat(NumType angle,
LVecBase3<NumType> axis,
CoordinateSystem cs = CS_default);
static LMatrix3<NumType> scale_mat(const LVecBase3<NumType> &scale);
static LMatrix3<NumType> 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<NumType> &other,
NumType threshold) const;
INLINE bool almost_equal(const LMatrix3<NumType> &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<NumType> &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<class NumType>
INLINE ostream &operator << (ostream &out, const LMatrix3<NumType> &mat) {
mat.output(out);
return out;
}
template<class NumType>
INLINE LMatrix3<NumType> transpose(const LMatrix3<NumType> &a);
template<class NumType>
INLINE LMatrix3<NumType> invert(const LMatrix3<NumType> &a);
// Cast to a different numeric type
template<class NumType, class NumType2>
INLINE LMatrix3<NumType2>
lcast_to(NumType2 *type, const LMatrix3<NumType> &source);
#include "fltnames.I"
#include "lmatrix3.I"
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LMatrix3<float>)
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LMatrix3<double>)
#include "dblnames.I"
#include "lmatrix3.I"
////////////////////////////////////////////////////////////////////
// Function: lcast_to
// Description: Converts a matrix from one numeric representation to
// another one. This is usually invoked using the macro
// LCAST.
////////////////////////////////////////////////////////////////////
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));
}
#endif

View File

@ -0,0 +1,123 @@
// Filename: lmatrix3.I
// Created by: drose (29Jan99)
//
////////////////////////////////////////////////////////////////////
TypeHandle FLOATNAME(LMatrix3)::_type_handle;
////////////////////////////////////////////////////////////////////
// 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.
////////////////////////////////////////////////////////////////////
void FLOATNAME(LMatrix3)::
fill(FLOATTYPE1 fill_value) {
set(fill_value, fill_value, fill_value,
fill_value, fill_value, fill_value,
fill_value, fill_value, fill_value);
}
////////////////////////////////////////////////////////////////////
// Function: LMatrix3::Equality Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool FLOATNAME(LMatrix3)::
operator == (const FLOATNAME(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));
}
int FLOATNAME(LMatrix3)::
compare_to(const FLOATNAME(LMatrix3) &other, FLOATTYPE1 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;
}
////////////////////////////////////////////////////////////////////
// Function: LMatrix3::almost_equal
// Access: Public
// Description: Returns true if two matrices are memberwise equal
// within a specified tolerance.
////////////////////////////////////////////////////////////////////
bool FLOATNAME(LMatrix3)::
almost_equal(const FLOATNAME(LMatrix3) &other, FLOATTYPE1 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::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
void FLOATNAME(LMatrix3)::
init_type() {
if (_type_handle == TypeHandle::none()) {
// Format a string to describe the type.
do_init_type(FLOATTYPE1);
string name =
"LMatrix3<" + get_type_handle(FLOATTYPE1).get_name() + ">";
register_type(_type_handle, name);
}
}
////////////////////////////////////////////////////////////////////
// Function: LMatrix3::write_datagram
// Description: Writes the matrix to the datagram
////////////////////////////////////////////////////////////////////
void FLOATNAME(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
////////////////////////////////////////////////////////////////////
void FLOATNAME(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());
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
// Filename: lmatrix3.cxx
// Created by: drose (29Jan99)
//
////////////////////////////////////////////////////////////////////
#include "config_linmath.h"
#include "lmatrix4.h"
#include "fltnames.I"
#include "lmatrix4_src.I"
#include "dblnames.I"
#include "lmatrix4_src.I"

View File

@ -7,182 +7,51 @@
#define LMATRIX4_H
#include <pandabase.h>
#include <math.h>
#include <typeHandle.h>
#include <datagram.h>
#include <datagramIterator.h>
#include <indent.h>
#include "deg_2_rad.h"
#include "nearly_zero.h"
#include "coordinateSystem.h"
#include "lvecBase4.h"
#include "lvecBase3.h"
#include "lmatrix3.h"
#include <typeHandle.h>
#include <datagram.h>
#include <datagramIterator.h>
////////////////////////////////////////////////////////////////////
// Class : LMatrix4
// Description : This is a 4-by-4 transform matrix.
////////////////////////////////////////////////////////////////////
template<class NumType>
class LMatrix4 {
PUBLISHED:
typedef const NumType *iterator;
typedef const NumType *const_iterator;
INLINE LMatrix4();
INLINE LMatrix4(const LMatrix4<NumType> &other);
LMatrix4<NumType> &operator = (const LMatrix4<NumType> &other);
INLINE LMatrix4<NumType> &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<NumType> &upper3);
LMatrix4(const LMatrix3<NumType> &upper3,
const LVecBase3<NumType> &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<NumType> &upper3);
INLINE LMatrix3<NumType> get_upper_3() const;
INLINE void set_row(int row, const LVecBase4<NumType> &v);
INLINE void set_col(int col, const LVecBase4<NumType> &v);
INLINE void set_row(int row, const LVecBase3<NumType> &v);
INLINE void set_col(int col, const LVecBase3<NumType> &v);
INLINE LVecBase4<NumType> get_row(int row) const;
INLINE LVecBase4<NumType> get_col(int col) const;
INLINE LVecBase3<NumType> get_row3(int row) const;
INLINE LVecBase3<NumType> 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<NumType> &other) const;
INLINE bool operator != (const LMatrix4<NumType> &other) const;
INLINE int compare_to(const LMatrix4<NumType> &other) const;
int compare_to(const LMatrix4<NumType> &other, NumType threshold) const;
INLINE LVecBase4<NumType>
xform(const LVecBase4<NumType> &v) const;
INLINE LVecBase3<NumType>
xform_point(const LVecBase3<NumType> &v) const;
INLINE LVecBase3<NumType>
xform_vec(const LVecBase3<NumType> &v) const;
LMatrix4<NumType> operator * (const LMatrix4<NumType> &other) const;
LMatrix4<NumType> operator * (NumType scalar) const;
LMatrix4<NumType> operator / (NumType scalar) const;
LMatrix4<NumType> &operator += (const LMatrix4<NumType> &other);
LMatrix4<NumType> &operator -= (const LMatrix4<NumType> &other);
INLINE LMatrix4<NumType> &operator *= (const LMatrix4<NumType> &other);
LMatrix4<NumType> &operator *= (NumType scalar);
LMatrix4<NumType> &operator /= (NumType scalar);
void transpose_from(const LMatrix4<NumType> &other);
INLINE void transpose_in_place();
bool invert_from(const LMatrix4<NumType> &other);
bool invert_affine_from(const LMatrix4<NumType> &other);
INLINE bool invert_in_place();
static const LMatrix4<NumType> &ident_mat();
static LMatrix4<NumType> translate_mat(const LVecBase3<NumType> &trans);
static LMatrix4<NumType> translate_mat(NumType tx, NumType ty, NumType tz);
static LMatrix4<NumType> rotate_mat(NumType angle,
LVecBase3<NumType> axis,
CoordinateSystem cs = CS_default);
static LMatrix4<NumType> scale_mat(const LVecBase3<NumType> &scale);
static LMatrix4<NumType> scale_mat(NumType sx, NumType sy, NumType sz);
static LMatrix4<NumType> scale_mat(NumType scale);
static const LMatrix4<NumType> &y_to_z_up_mat();
static const LMatrix4<NumType> &z_to_y_up_mat();
static LMatrix4<NumType> convert_mat(CoordinateSystem from,
CoordinateSystem to);
bool almost_equal(const LMatrix4<NumType> &other,
NumType threshold) const;
INLINE bool almost_equal(const LMatrix4<NumType> &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<NumType> &other, int x, int y) const;
bool decompose_mat(int index[4]);
bool back_sub_mat(int index[4], LMatrix4<NumType> &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<class NumType>
INLINE ostream &operator << (ostream &out, const LMatrix4<NumType> &mat) {
mat.output(out);
return out;
}
template<class NumType>
INLINE LMatrix4<NumType> transpose(const LMatrix4<NumType> &a);
template<class NumType>
INLINE LMatrix4<NumType> invert(const LMatrix4<NumType> &a);
// Cast to a different numeric type
template<class NumType, class NumType2>
INLINE LMatrix4<NumType2>
lcast_to(NumType2 *type, const LMatrix4<NumType> &source);
#include "fltnames.I"
#include "lmatrix4.I"
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LMatrix4<float>)
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LMatrix4<double>)
#include "dblnames.I"
#include "lmatrix4.I"
////////////////////////////////////////////////////////////////////
// Function: lcast_to
// Description: Converts a matrix from one numeric representation to
// another one. This is usually invoked using the macro
// LCAST.
////////////////////////////////////////////////////////////////////
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));
}
#include "fltnames.I"
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));
}
#endif

View File

@ -0,0 +1,309 @@
// Filename: lmatrix4_src.I
// Created by: drose (15Jan99)
//
////////////////////////////////////////////////////////////////////
TypeHandle FLOATNAME(LMatrix4)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LMatrix4::Equality Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool FLOATNAME(LMatrix4)::
operator == (const FLOATNAME(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: LMatrix::convert_mat
// Access: Public, Static
// Description: Returns a matrix that transforms from the indicated
// coordinate system to the indicated coordinate system.
////////////////////////////////////////////////////////////////////
FLOATNAME(LMatrix4) FLOATNAME(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.
////////////////////////////////////////////////////////////////////
bool FLOATNAME(LMatrix4)::
almost_equal(const FLOATNAME(LMatrix4) &other, FLOATTYPE1 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::decompose_mat
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
bool FLOATNAME(LMatrix4)::
decompose_mat(int index[4]) {
int i, j, k;
FLOATTYPE1 vv[4];
for (i = 0; i < 4; i++) {
FLOATTYPE1 big = 0.0;
for (j = 0; j < 4; j++) {
FLOATTYPE1 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++) {
FLOATTYPE1 sum = (*this)(i,j);
for (k = 0; k < i; k++) {
sum -= (*this)(i,k) * (*this)(k,j);
}
(*this)(i,j) = sum;
}
FLOATTYPE1 big = 0.0;
int imax = -1;
for (i = j; i < 4; i++) {
FLOATTYPE1 sum = (*this)(i,j);
for (k = 0; k < j; k++) {
sum -= (*this)(i,k) * (*this)(k,j);
}
(*this)(i,j) = sum;
FLOATTYPE1 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++) {
FLOATTYPE1 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(FLOATTYPE1);
}
if (j != 4 - 1) {
FLOATTYPE1 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:
////////////////////////////////////////////////////////////////////
bool FLOATNAME(LMatrix4)::
back_sub_mat(int index[4], FLOATNAME(LMatrix4) &inv, int row) const {
int ii = -1;
int i, j;
for (i = 0; i < 4; i++) {
int ip = index[i];
FLOATTYPE1 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--) {
FLOATTYPE1 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:
////////////////////////////////////////////////////////////////////
void FLOATNAME(LMatrix4)::
init_type() {
if (_type_handle == TypeHandle::none()) {
// Format a string to describe the type.
do_init_type(FLOATTYPE1);
string name =
"LMatrix4<" + get_type_handle(FLOATTYPE1).get_name() + ">";
register_type(_type_handle, name);
}
}
////////////////////////////////////////////////////////////////////
// Function: LMatrix4::write_datagram
// Description: Writes the matrix to the datagram
////////////////////////////////////////////////////////////////////
void FLOATNAME(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
////////////////////////////////////////////////////////////////////
void FLOATNAME(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::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).
////////////////////////////////////////////////////////////////////
int FLOATNAME(LMatrix4)::
compare_to(const FLOATNAME(LMatrix4) &other, FLOATTYPE1 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;
}

View File

@ -3,20 +3,43 @@
//
////////////////////////////////////////////////////////////////////
#include "lorientation.h"
#include <notify.h>
////////////////////////////////////////////////////////////////////////
// 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)();
template<class NumType>
TypeHandle LOrientation<NumType>::_type_handle;
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;
};
////////////////////////////////////////////////////////////////////
// Function: LOrientation::Default Constructor
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LOrientation<NumType>::
LOrientation() {
INLINE FLOATNAME(LOrientation)::
FLOATNAME(LOrientation)() {
}
////////////////////////////////////////////////////////////////////
@ -24,10 +47,10 @@ LOrientation() {
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LOrientation<NumType>::
LOrientation(const LQuaternionBase<NumType>& c) :
LQuaternionBase<NumType>(c) {
INLINE FLOATNAME(LOrientation)::
FLOATNAME(LOrientation)(const FLOATNAME(LQuaternionBase)& c) :
FLOATNAME(LQuaternionBase)(c) {
}
////////////////////////////////////////////////////////////////////
@ -35,10 +58,10 @@ LOrientation(const LQuaternionBase<NumType>& c) :
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LOrientation<NumType>::
LOrientation(NumType r, NumType i, NumType j, NumType k) :
LQuaternionBase<NumType>(r, i, j, k) {
INLINE FLOATNAME(LOrientation)::
FLOATNAME(LOrientation)(FLOATTYPE1 r, FLOATTYPE1 i, FLOATTYPE1 j, FLOATTYPE1 k) :
FLOATNAME(LQuaternionBase)(r, i, j, k) {
}
////////////////////////////////////////////////////////////////////
@ -46,9 +69,9 @@ LOrientation(NumType r, NumType i, NumType j, NumType k) :
// Access: public
// Description: vector + twist
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LOrientation<NumType>::
LOrientation(const LVector3<NumType> &point_at, float twist) {
INLINE FLOATNAME(LOrientation)::
FLOATNAME(LOrientation)(const FLOATNAME(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);
@ -64,9 +87,9 @@ LOrientation(const LVector3<NumType> &point_at, float twist) {
// Access: public
// Description: matrix3
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LOrientation<NumType>::
LOrientation(const LMatrix3<NumType> &m) {
INLINE FLOATNAME(LOrientation)::
FLOATNAME(LOrientation)(const FLOATNAME(LMatrix3) &m) {
set(m);
}
@ -75,20 +98,10 @@ LOrientation(const LMatrix3<NumType> &m) {
// Access: public
// Description: matrix4
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LOrientation<NumType>::
LOrientation(const LMatrix4<NumType> &m) {
set(m);
}
////////////////////////////////////////////////////////////////////
// Function: LOrientation::Destructor
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
LOrientation<NumType>::
~LOrientation() {
INLINE FLOATNAME(LOrientation)::
FLOATNAME(LOrientation)(const FLOATNAME(LMatrix4) &m) {
set(m);
}
////////////////////////////////////////////////////////////////////
@ -97,9 +110,9 @@ LOrientation<NumType>::
// Description: Orientation * rotation = Orientation
// Applies an rotation to an orientation.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LOrientation<NumType> LOrientation<NumType>::
operator *(const LQuaternionBase<NumType>& other) const {
INLINE FLOATNAME(LOrientation) FLOATNAME(LOrientation)::
operator *(const FLOATNAME(LQuaternionBase)& other) const {
return multiply(other);
}
@ -110,25 +123,8 @@ operator *(const LQuaternionBase<NumType>& other) const {
// This is a meaningless operation, and will always
// simply return the rhs.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LOrientation<NumType> LOrientation<NumType>::
operator *(const LOrientation<NumType>& other) const {
INLINE FLOATNAME(LOrientation) FLOATNAME(LOrientation)::
operator *(const FLOATNAME(LOrientation)& other) const {
return other;
}
////////////////////////////////////////////////////////////////////
// Function: LOrientation::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void LOrientation<NumType>::
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);
}
}

View File

@ -0,0 +1,13 @@
// Filename: lorientation.h
// Created by: frang, charles (23Jun00)
//
////////////////////////////////////////////////////////////////////
#include "lorientation.h"
#include "fltnames.I"
#include "lorientation_src.I"
#include "dblnames.I"
#include "lorientation_src.I"

View File

@ -7,41 +7,16 @@
#define __LORIENTATION_H__
#include <pandabase.h>
#include <notify.h>
#include "lquaternion.h"
////////////////////////////////////////////////////////////////////////
// Class : LOrientation
// Description : This is a unit quaternion representing an orientation.
////////////////////////////////////////////////////////////////////////
template <class NumType>
class LOrientation : public LQuaternionBase<NumType> {
public:
INLINE LOrientation();
INLINE LOrientation(const LQuaternionBase<NumType>&);
INLINE LOrientation(NumType, NumType, NumType, NumType);
INLINE LOrientation(const LVector3<NumType> &, float);
INLINE LOrientation(const LMatrix3<NumType> &);
INLINE LOrientation(const LMatrix4<NumType> &);
virtual ~LOrientation();
INLINE LOrientation<NumType>
operator *(const LQuaternionBase<NumType>& other) const;
INLINE LOrientation<NumType>
operator *(const LOrientation<NumType>& other) const;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type();
private:
static TypeHandle _type_handle;
};
#include "fltnames.I"
#include "lorientation.I"
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LOrientation<float>)
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LOrientation<double>)
#include "dblnames.I"
#include "lorientation.I"
#endif /* __LORIENTATION_H__ */

View File

@ -0,0 +1,33 @@
// Filename: lorientation.I
// Created by: frang, charles (23Jun00)
//
////////////////////////////////////////////////////////////////////
TypeHandle FLOATNAME(LOrientation)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LOrientation::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
void FLOATNAME(LOrientation)::
init_type() {
if (_type_handle == TypeHandle::none()) {
// Format a string to describe the type.
do_init_type(FLOATTYPE1);
string name =
"LOrientation<" + get_type_handle(FLOATTYPE1).get_name() + ">";
register_type(_type_handle, name);
}
}
////////////////////////////////////////////////////////////////////
// Function: LOrientation::Destructor
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
FLOATNAME(LOrientation)::
~FLOATNAME(LOrientation)() {
}

View File

@ -3,17 +3,60 @@
//
////////////////////////////////////////////////////////////////////
template<class NumType>
TypeHandle LPoint2<NumType>::_type_handle;
////////////////////////////////////////////////////////////////////
// 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) &copy);
INLINE FLOATNAME(LPoint2) &operator = (const FLOATNAME(LVecBase2) &copy);
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;
};
////////////////////////////////////////////////////////////////////
// Function: LPoint2::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint2<NumType>::
LPoint2() {
INLINE FLOATNAME(LPoint2)::
FLOATNAME(LPoint2)() {
}
////////////////////////////////////////////////////////////////////
@ -21,9 +64,9 @@ LPoint2() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint2<NumType>::
LPoint2(const LVecBase2<NumType> &copy) : LVecBase2<NumType>(copy) {
INLINE FLOATNAME(LPoint2)::
FLOATNAME(LPoint2)(const FLOATNAME(LVecBase2) &copy) : FLOATNAME(LVecBase2)(copy) {
}
////////////////////////////////////////////////////////////////////
@ -31,10 +74,10 @@ LPoint2(const LVecBase2<NumType> &copy) : LVecBase2<NumType>(copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint2<NumType> &LPoint2<NumType>::
operator = (const LVecBase2<NumType> &copy) {
LVecBase2<NumType>::operator = (copy);
INLINE FLOATNAME(LPoint2) &FLOATNAME(LPoint2)::
operator = (const FLOATNAME(LVecBase2) &copy) {
FLOATNAME(LVecBase2)::operator = (copy);
return *this;
}
@ -43,10 +86,10 @@ operator = (const LVecBase2<NumType> &copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint2<NumType> &LPoint2<NumType>::
operator = (NumType fill_value) {
LVecBase2<NumType>::operator = (fill_value);
INLINE FLOATNAME(LPoint2) &FLOATNAME(LPoint2)::
operator = (FLOATTYPE1 fill_value) {
FLOATNAME(LVecBase2)::operator = (fill_value);
return *this;
}
@ -55,10 +98,10 @@ operator = (NumType fill_value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint2<NumType>::
LPoint2(NumType fill_value) :
LVecBase2<NumType>(fill_value)
INLINE FLOATNAME(LPoint2)::
FLOATNAME(LPoint2)(FLOATTYPE1 fill_value) :
FLOATNAME(LVecBase2)(fill_value)
{
}
@ -67,10 +110,10 @@ LPoint2(NumType fill_value) :
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint2<NumType>::
LPoint2(NumType x, NumType y) :
LVecBase2<NumType>(x, y)
INLINE FLOATNAME(LPoint2)::
FLOATNAME(LPoint2)(FLOATTYPE1 x, FLOATTYPE1 y) :
FLOATNAME(LVecBase2)(x, y)
{
}
@ -79,10 +122,10 @@ LPoint2(NumType x, NumType y) :
// Access: Public
// Description: Returns a zero point.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint2<NumType> LPoint2<NumType>::
INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2)::
zero() {
return LPoint2<NumType>(0.0, 0.0);
return FLOATNAME(LPoint2)(0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -90,10 +133,10 @@ zero() {
// Access: Public
// Description: Returns a unit X point.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint2<NumType> LPoint2<NumType>::
INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2)::
unit_x() {
return LPoint2<NumType>(1.0, 0.0);
return FLOATNAME(LPoint2)(1.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -101,10 +144,10 @@ unit_x() {
// Access: Public
// Description: Returns a unit Y point.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint2<NumType> LPoint2<NumType>::
INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2)::
unit_y() {
return LPoint2<NumType>(0.0, 1.0);
return FLOATNAME(LPoint2)(0.0, 1.0);
}
////////////////////////////////////////////////////////////////////
@ -112,10 +155,10 @@ unit_y() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint2<NumType> LPoint2<NumType>::
INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2)::
operator - () const {
return LVecBase2<NumType>::operator - ();
return FLOATNAME(LVecBase2)::operator - ();
}
////////////////////////////////////////////////////////////////////
@ -123,10 +166,10 @@ operator - () const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType> LPoint2<NumType>::
operator + (const LVecBase2<NumType> &other) const {
return LVecBase2<NumType>::operator + (other);
INLINE FLOATNAME(LVecBase2) FLOATNAME(LPoint2)::
operator + (const FLOATNAME(LVecBase2) &other) const {
return FLOATNAME(LVecBase2)::operator + (other);
}
////////////////////////////////////////////////////////////////////
@ -134,10 +177,10 @@ operator + (const LVecBase2<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint2<NumType> LPoint2<NumType>::
operator + (const LVector2<NumType> &other) const {
return LVecBase2<NumType>::operator + (other);
INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2)::
operator + (const FLOATNAME(LVector2) &other) const {
return FLOATNAME(LVecBase2)::operator + (other);
}
////////////////////////////////////////////////////////////////////
@ -145,10 +188,10 @@ operator + (const LVector2<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType> LPoint2<NumType>::
operator - (const LVecBase2<NumType> &other) const {
return LVecBase2<NumType>::operator - (other);
INLINE FLOATNAME(LVecBase2) FLOATNAME(LPoint2)::
operator - (const FLOATNAME(LVecBase2) &other) const {
return FLOATNAME(LVecBase2)::operator - (other);
}
////////////////////////////////////////////////////////////////////
@ -156,10 +199,10 @@ operator - (const LVecBase2<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType> LPoint2<NumType>::
operator - (const LPoint2<NumType> &other) const {
return LVecBase2<NumType>::operator - (other);
INLINE FLOATNAME(LVector2) FLOATNAME(LPoint2)::
operator - (const FLOATNAME(LPoint2) &other) const {
return FLOATNAME(LVecBase2)::operator - (other);
}
////////////////////////////////////////////////////////////////////
@ -167,10 +210,10 @@ operator - (const LPoint2<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint2<NumType> LPoint2<NumType>::
operator - (const LVector2<NumType> &other) const {
return LVecBase2<NumType>::operator - (other);
INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2)::
operator - (const FLOATNAME(LVector2) &other) const {
return FLOATNAME(LVecBase2)::operator - (other);
}
////////////////////////////////////////////////////////////////////
@ -178,10 +221,10 @@ operator - (const LVector2<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint2<NumType> LPoint2<NumType>::
operator * (NumType scalar) const {
return LPoint2<NumType>(LVecBase2<NumType>::operator * (scalar));
INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2)::
operator * (FLOATTYPE1 scalar) const {
return FLOATNAME(LPoint2)(FLOATNAME(LVecBase2)::operator * (scalar));
}
////////////////////////////////////////////////////////////////////
@ -189,37 +232,10 @@ operator * (NumType scalar) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint2<NumType> LPoint2<NumType>::
operator / (NumType scalar) const {
return LPoint2<NumType>(LVecBase2<NumType>::operator / (scalar));
INLINE FLOATNAME(LPoint2) FLOATNAME(LPoint2)::
operator / (FLOATTYPE1 scalar) const {
return FLOATNAME(LPoint2)(FLOATNAME(LVecBase2)::operator / (scalar));
}
////////////////////////////////////////////////////////////////////
// Function: LPoint2::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void LPoint2<NumType>::
init_type() {
if (_type_handle == TypeHandle::none()) {
LVecBase2<NumType>::init_type();
string name =
"LPoint2<" + get_type_handle(NumType).get_name() + ">";
register_type(_type_handle, name,
LVecBase2<NumType>::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<class NumType, class NumType2>
INLINE LPoint2<NumType2>
lcast_to(NumType2 *, const LPoint2<NumType> &source) {
return LPoint2<NumType2>(source[0], source[1]);
}

View File

@ -0,0 +1,13 @@
// Filename: lpoint2.cxx
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
#include "lpoint2.h"
#include "fltnames.I"
#include "lpoint2_src.I"
#include "dblnames.I"
#include "lpoint2_src.I"

View File

@ -11,59 +11,30 @@
#include "lvecBase2.h"
#include "lvector2.h"
////////////////////////////////////////////////////////////////////
// Class : LPoint2
// Description : This is a two-component point in space.
////////////////////////////////////////////////////////////////////
template<class NumType>
class LPoint2 : public LVecBase2<NumType> {
PUBLISHED:
INLINE LPoint2();
INLINE LPoint2(const LVecBase2<NumType> &copy);
INLINE LPoint2<NumType> &operator = (const LVecBase2<NumType> &copy);
INLINE LPoint2<NumType> &operator = (NumType fill_value);
INLINE LPoint2(NumType fill_value);
INLINE LPoint2(NumType x, NumType y);
INLINE static LPoint2<NumType> zero();
INLINE static LPoint2<NumType> unit_x();
INLINE static LPoint2<NumType> unit_y();
INLINE LPoint2<NumType> operator - () const;
INLINE LVecBase2<NumType>
operator + (const LVecBase2<NumType> &other) const;
INLINE LPoint2<NumType>
operator + (const LVector2<NumType> &other) const;
INLINE LVecBase2<NumType>
operator - (const LVecBase2<NumType> &other) const;
INLINE LVector2<NumType>
operator - (const LPoint2<NumType> &other) const;
INLINE LPoint2<NumType>
operator - (const LVector2<NumType> &other) const;
INLINE LPoint2<NumType> operator * (NumType scalar) const;
INLINE LPoint2<NumType> 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<class NumType, class NumType2>
INLINE LPoint2<NumType2>
lcast_to(NumType2 *type, const LPoint2<NumType> &source);
#include "fltnames.I"
#include "lpoint2.I"
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LPoint2<float>)
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LPoint2<double>)
#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]);
}
#endif

View File

@ -0,0 +1,25 @@
// Filename: lpoint2.I
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
TypeHandle FLOATNAME(LPoint2)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LPoint2::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
void FLOATNAME(LPoint2)::
init_type() {
if (_type_handle == TypeHandle::none()) {
FLOATNAME(LVecBase2)::init_type();
string name =
"LPoint2<" + get_type_handle(FLOATTYPE1).get_name() + ">";
register_type(_type_handle, name,
FLOATNAME(LVecBase2)::get_class_type());
}
}

View File

@ -3,19 +3,74 @@
//
////////////////////////////////////////////////////////////////////
#include "lvector3.h"
////////////////////////////////////////////////////////////////////
// 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 NumType>
TypeHandle LPoint3<NumType>::_type_handle;
class EXPCL_PANDA FLOATNAME(LPoint3) : public FLOATNAME(LVecBase3) {
PUBLISHED:
INLINE FLOATNAME(LPoint3)();
INLINE FLOATNAME(LPoint3)(const FLOATNAME(LVecBase3) &copy);
INLINE FLOATNAME(LPoint3) &operator = (const FLOATNAME(LVecBase3) &copy);
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;
};
////////////////////////////////////////////////////////////////////
// Function: LPoint3::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType>::
LPoint3() {
INLINE FLOATNAME(LPoint3)::
FLOATNAME(LPoint3)() {
}
////////////////////////////////////////////////////////////////////
@ -23,9 +78,9 @@ LPoint3() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType>::
LPoint3(const LVecBase3<NumType> &copy) : LVecBase3<NumType>(copy) {
INLINE FLOATNAME(LPoint3)::
FLOATNAME(LPoint3)(const FLOATNAME(LVecBase3) &copy) : FLOATNAME(LVecBase3)(copy) {
}
////////////////////////////////////////////////////////////////////
@ -33,10 +88,10 @@ LPoint3(const LVecBase3<NumType> &copy) : LVecBase3<NumType>(copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType> &LPoint3<NumType>::
operator = (const LVecBase3<NumType> &copy) {
LVecBase3<NumType>::operator = (copy);
INLINE FLOATNAME(LPoint3) &FLOATNAME(LPoint3)::
operator = (const FLOATNAME(LVecBase3) &copy) {
FLOATNAME(LVecBase3)::operator = (copy);
return *this;
}
@ -45,10 +100,10 @@ operator = (const LVecBase3<NumType> &copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType> &LPoint3<NumType>::
operator = (NumType fill_value) {
LVecBase3<NumType>::operator = (fill_value);
INLINE FLOATNAME(LPoint3) &FLOATNAME(LPoint3)::
operator = (FLOATTYPE1 fill_value) {
FLOATNAME(LVecBase3)::operator = (fill_value);
return *this;
}
@ -57,10 +112,10 @@ operator = (NumType fill_value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType>::
LPoint3(NumType fill_value) :
LVecBase3<NumType>(fill_value)
INLINE FLOATNAME(LPoint3)::
FLOATNAME(LPoint3)(FLOATTYPE1 fill_value) :
FLOATNAME(LVecBase3)(fill_value)
{
}
@ -69,10 +124,10 @@ LPoint3(NumType fill_value) :
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType>::
LPoint3(NumType x, NumType y, NumType z) :
LVecBase3<NumType>(x, y, z)
INLINE FLOATNAME(LPoint3)::
FLOATNAME(LPoint3)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z) :
FLOATNAME(LVecBase3)(x, y, z)
{
}
@ -81,10 +136,10 @@ LPoint3(NumType x, NumType y, NumType z) :
// Access: Public
// Description: Returns a zero point.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType> LPoint3<NumType>::
INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3)::
zero() {
return LPoint3<NumType>(0.0, 0.0, 0.0);
return FLOATNAME(LPoint3)(0.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -92,10 +147,10 @@ zero() {
// Access: Public
// Description: Returns a unit X point.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType> LPoint3<NumType>::
INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3)::
unit_x() {
return LPoint3<NumType>(1.0, 0.0, 0.0);
return FLOATNAME(LPoint3)(1.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -103,10 +158,10 @@ unit_x() {
// Access: Public
// Description: Returns a unit Y point.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType> LPoint3<NumType>::
INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3)::
unit_y() {
return LPoint3<NumType>(0.0, 1.0, 0.0);
return FLOATNAME(LPoint3)(0.0, 1.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -114,10 +169,10 @@ unit_y() {
// Access: Public
// Description: Returns a unit Z point.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType> LPoint3<NumType>::
INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3)::
unit_z() {
return LPoint3<NumType>(0.0, 0.0, 1.0);
return FLOATNAME(LPoint3)(0.0, 0.0, 1.0);
}
////////////////////////////////////////////////////////////////////
@ -125,10 +180,10 @@ unit_z() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType> LPoint3<NumType>::
INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3)::
operator - () const {
return LVecBase3<NumType>::operator - ();
return FLOATNAME(LVecBase3)::operator - ();
}
////////////////////////////////////////////////////////////////////
@ -136,10 +191,10 @@ operator - () const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> LPoint3<NumType>::
operator + (const LVecBase3<NumType> &other) const {
return LVecBase3<NumType>::operator + (other);
INLINE FLOATNAME(LVecBase3) FLOATNAME(LPoint3)::
operator + (const FLOATNAME(LVecBase3) &other) const {
return FLOATNAME(LVecBase3)::operator + (other);
}
////////////////////////////////////////////////////////////////////
@ -147,10 +202,10 @@ operator + (const LVecBase3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType> LPoint3<NumType>::
operator + (const LVector3<NumType> &other) const {
return LVecBase3<NumType>::operator + (other);
INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3)::
operator + (const FLOATNAME(LVector3) &other) const {
return FLOATNAME(LVecBase3)::operator + (other);
}
////////////////////////////////////////////////////////////////////
@ -158,10 +213,10 @@ operator + (const LVector3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> LPoint3<NumType>::
operator - (const LVecBase3<NumType> &other) const {
return LVecBase3<NumType>::operator - (other);
INLINE FLOATNAME(LVecBase3) FLOATNAME(LPoint3)::
operator - (const FLOATNAME(LVecBase3) &other) const {
return FLOATNAME(LVecBase3)::operator - (other);
}
////////////////////////////////////////////////////////////////////
@ -169,10 +224,10 @@ operator - (const LVecBase3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LPoint3<NumType>::
operator - (const LPoint3<NumType> &other) const {
return LVecBase3<NumType>::operator - (other);
INLINE FLOATNAME(LVector3) FLOATNAME(LPoint3)::
operator - (const FLOATNAME(LPoint3) &other) const {
return FLOATNAME(LVecBase3)::operator - (other);
}
////////////////////////////////////////////////////////////////////
@ -180,10 +235,10 @@ operator - (const LPoint3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType> LPoint3<NumType>::
operator - (const LVector3<NumType> &other) const {
return LVecBase3<NumType>::operator - (other);
INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3)::
operator - (const FLOATNAME(LVector3) &other) const {
return FLOATNAME(LVecBase3)::operator - (other);
}
////////////////////////////////////////////////////////////////////
@ -191,10 +246,10 @@ operator - (const LVector3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType> LPoint3<NumType>::
cross(const LVecBase3<NumType> &other) const {
return LVecBase3<NumType>::cross(other);
INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3)::
cross(const FLOATNAME(LVecBase3) &other) const {
return FLOATNAME(LVecBase3)::cross(other);
}
////////////////////////////////////////////////////////////////////
@ -202,10 +257,10 @@ cross(const LVecBase3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType> LPoint3<NumType>::
operator * (NumType scalar) const {
return LPoint3<NumType>(LVecBase3<NumType>::operator * (scalar));
INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3)::
operator * (FLOATTYPE1 scalar) const {
return FLOATNAME(LPoint3)(FLOATNAME(LVecBase3)::operator * (scalar));
}
////////////////////////////////////////////////////////////////////
@ -213,10 +268,10 @@ operator * (NumType scalar) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType> LPoint3<NumType>::
operator / (NumType scalar) const {
return LPoint3<NumType>(LVecBase3<NumType>::operator / (scalar));
INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3)::
operator / (FLOATTYPE1 scalar) const {
return FLOATNAME(LPoint3)(FLOATNAME(LVecBase3)::operator / (scalar));
}
////////////////////////////////////////////////////////////////////
@ -227,10 +282,10 @@ operator / (NumType scalar) const {
// existing coordinate systems; it's hard to imagine it
// ever being different.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType> LPoint3<NumType>::
INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3)::
origin(CoordinateSystem) {
return LPoint3<NumType>(0.0, 0.0, 0.0);
return FLOATNAME(LPoint3)(0.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -240,39 +295,11 @@ origin(CoordinateSystem) {
// displacements from the origin, wherever that maps to
// in the given coordinate system.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint3<NumType> LPoint3<NumType>::
rfu(NumType right_v, NumType fwd_v, NumType up_v,
INLINE FLOATNAME(LPoint3) FLOATNAME(LPoint3)::
rfu(FLOATTYPE1 right_v, FLOATTYPE1 fwd_v, FLOATTYPE1 up_v,
CoordinateSystem cs) {
return origin(cs) +
LVector3<NumType>::rfu(right_v, fwd_v, up_v, cs);
FLOATNAME(LVector3)::rfu(right_v, fwd_v, up_v, cs);
}
////////////////////////////////////////////////////////////////////
// Function: LPoint3::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void LPoint3<NumType>::
init_type() {
if (_type_handle == TypeHandle::none()) {
LVecBase3<NumType>::init_type();
string name =
"LPoint3<" + get_type_handle(NumType).get_name() + ">";
register_type(_type_handle, name,
LVecBase3<NumType>::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<class NumType, class NumType2>
INLINE LPoint3<NumType2>
lcast_to(NumType2 *, const LPoint3<NumType> &source) {
return LPoint3<NumType2>(source[0], source[1], source[2]);
}

View File

@ -0,0 +1,13 @@
// Filename: lpoint2.cxx
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
#include "lpoint3.h"
#include "fltnames.I"
#include "lpoint3_src.I"
#include "dblnames.I"
#include "lpoint3_src.I"

View File

@ -12,74 +12,31 @@
#include "lvecBase3.h"
#include "lvector3.h"
////////////////////////////////////////////////////////////////////
// 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 NumType>
class LPoint3 : public LVecBase3<NumType> {
PUBLISHED:
INLINE LPoint3();
INLINE LPoint3(const LVecBase3<NumType> &copy);
INLINE LPoint3<NumType> &operator = (const LVecBase3<NumType> &copy);
INLINE LPoint3<NumType> &operator = (NumType fill_value);
INLINE LPoint3(NumType fill_value);
INLINE LPoint3(NumType x, NumType y, NumType z);
INLINE static LPoint3<NumType> zero();
INLINE static LPoint3<NumType> unit_x();
INLINE static LPoint3<NumType> unit_y();
INLINE static LPoint3<NumType> unit_z();
INLINE LPoint3<NumType> operator - () const;
INLINE LVecBase3<NumType>
operator + (const LVecBase3<NumType> &other) const;
INLINE LPoint3<NumType>
operator + (const LVector3<NumType> &other) const;
INLINE LVecBase3<NumType>
operator - (const LVecBase3<NumType> &other) const;
INLINE LVector3<NumType>
operator - (const LPoint3<NumType> &other) const;
INLINE LPoint3<NumType>
operator - (const LVector3<NumType> &other) const;
INLINE LPoint3<NumType> cross(const LVecBase3<NumType> &other) const;
INLINE LPoint3<NumType> operator * (NumType scalar) const;
INLINE LPoint3<NumType> operator / (NumType scalar) const;
// Some special named constructors for LPoint3.
INLINE static LPoint3<NumType> origin(CoordinateSystem cs = CS_default);
INLINE static LPoint3<NumType> 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<class NumType, class NumType2>
INLINE LPoint3<NumType2>
lcast_to(NumType2 *type, const LPoint3<NumType> &source);
#include "fltnames.I"
#include "lpoint3.I"
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LPoint3<float>)
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LPoint3<double>)
#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]);
}
#endif

View File

@ -0,0 +1,24 @@
// Filename: lpoint3.I
// Created by: drose (25Sep99)
//
////////////////////////////////////////////////////////////////////
TypeHandle FLOATNAME(LPoint3)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LPoint3::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
void FLOATNAME(LPoint3)::
init_type() {
if (_type_handle == TypeHandle::none()) {
FLOATNAME(LVecBase3)::init_type();
string name =
"LPoint3<" + get_type_handle(FLOATTYPE1).get_name() + ">";
register_type(_type_handle, name,
FLOATNAME(LVecBase3)::get_class_type());
}
}

View File

@ -3,17 +3,61 @@
//
////////////////////////////////////////////////////////////////////
template<class NumType>
TypeHandle LPoint4<NumType>::_type_handle;
////////////////////////////////////////////////////////////////////
// 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) &copy);
INLINE FLOATNAME(LPoint4) &operator = (const FLOATNAME(LVecBase4) &copy);
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;
};
////////////////////////////////////////////////////////////////////
// Function: LPoint4::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType>::
LPoint4() {
INLINE FLOATNAME(LPoint4)::
FLOATNAME(LPoint4)() {
}
////////////////////////////////////////////////////////////////////
@ -21,9 +65,9 @@ LPoint4() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType>::
LPoint4(const LVecBase4<NumType> &copy) : LVecBase4<NumType>(copy) {
INLINE FLOATNAME(LPoint4)::
FLOATNAME(LPoint4)(const FLOATNAME(LVecBase4) &copy) : FLOATNAME(LVecBase4)(copy) {
}
////////////////////////////////////////////////////////////////////
@ -31,10 +75,10 @@ LPoint4(const LVecBase4<NumType> &copy) : LVecBase4<NumType>(copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType> &LPoint4<NumType>::
operator = (const LVecBase4<NumType> &copy) {
LVecBase4<NumType>::operator = (copy);
INLINE FLOATNAME(LPoint4) &FLOATNAME(LPoint4)::
operator = (const FLOATNAME(LVecBase4) &copy) {
FLOATNAME(LVecBase4)::operator = (copy);
return *this;
}
@ -43,10 +87,10 @@ operator = (const LVecBase4<NumType> &copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType> &LPoint4<NumType>::
operator = (NumType fill_value) {
LVecBase4<NumType>::operator = (fill_value);
INLINE FLOATNAME(LPoint4) &FLOATNAME(LPoint4)::
operator = (FLOATTYPE1 fill_value) {
FLOATNAME(LVecBase4)::operator = (fill_value);
return *this;
}
@ -55,10 +99,10 @@ operator = (NumType fill_value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType>::
LPoint4(NumType fill_value) :
LVecBase4<NumType>(fill_value)
INLINE FLOATNAME(LPoint4)::
FLOATNAME(LPoint4)(FLOATTYPE1 fill_value) :
FLOATNAME(LVecBase4)(fill_value)
{
}
@ -67,10 +111,10 @@ LPoint4(NumType fill_value) :
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType>::
LPoint4(NumType x, NumType y, NumType z, NumType w) :
LVecBase4<NumType>(x, y, z, w)
INLINE FLOATNAME(LPoint4)::
FLOATNAME(LPoint4)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w) :
FLOATNAME(LVecBase4)(x, y, z, w)
{
}
@ -79,10 +123,10 @@ LPoint4(NumType x, NumType y, NumType z, NumType w) :
// Access: Public
// Description: Returns a zero point.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType> LPoint4<NumType>::
INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4)::
zero() {
return LPoint4<NumType>(0.0, 0.0, 0.0, 0.0);
return FLOATNAME(LPoint4)(0.0, 0.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -90,10 +134,10 @@ zero() {
// Access: Public
// Description: Returns a unit X point.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType> LPoint4<NumType>::
INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4)::
unit_x() {
return LPoint4<NumType>(1.0, 0.0, 0.0, 0.0);
return FLOATNAME(LPoint4)(1.0, 0.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -101,10 +145,10 @@ unit_x() {
// Access: Public
// Description: Returns a unit Y point.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType> LPoint4<NumType>::
INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4)::
unit_y() {
return LPoint4<NumType>(0.0, 1.0, 0.0, 0.0);
return FLOATNAME(LPoint4)(0.0, 1.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -112,10 +156,10 @@ unit_y() {
// Access: Public
// Description: Returns a unit Z point.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType> LPoint4<NumType>::
INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4)::
unit_z() {
return LPoint4<NumType>(0.0, 0.0, 1.0, 0.0);
return FLOATNAME(LPoint4)(0.0, 0.0, 1.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -123,10 +167,10 @@ unit_z() {
// Access: Public
// Description: Returns a unit W point.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType> LPoint4<NumType>::
INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4)::
unit_w() {
return LPoint4<NumType>(0.0, 0.0, 0.0, 1.0);
return FLOATNAME(LPoint4)(0.0, 0.0, 0.0, 1.0);
}
////////////////////////////////////////////////////////////////////
@ -134,10 +178,10 @@ unit_w() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType> LPoint4<NumType>::
INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4)::
operator - () const {
return LVecBase4<NumType>::operator - ();
return FLOATNAME(LVecBase4)::operator - ();
}
////////////////////////////////////////////////////////////////////
@ -145,10 +189,10 @@ operator - () const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> LPoint4<NumType>::
operator + (const LVecBase4<NumType> &other) const {
return LVecBase4<NumType>::operator + (other);
INLINE FLOATNAME(LVecBase4) FLOATNAME(LPoint4)::
operator + (const FLOATNAME(LVecBase4) &other) const {
return FLOATNAME(LVecBase4)::operator + (other);
}
////////////////////////////////////////////////////////////////////
@ -156,10 +200,10 @@ operator + (const LVecBase4<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType> LPoint4<NumType>::
operator + (const LVector4<NumType> &other) const {
return LVecBase4<NumType>::operator + (other);
INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4)::
operator + (const FLOATNAME(LVector4) &other) const {
return FLOATNAME(LVecBase4)::operator + (other);
}
////////////////////////////////////////////////////////////////////
@ -167,10 +211,10 @@ operator + (const LVector4<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> LPoint4<NumType>::
operator - (const LVecBase4<NumType> &other) const {
return LVecBase4<NumType>::operator - (other);
INLINE FLOATNAME(LVecBase4) FLOATNAME(LPoint4)::
operator - (const FLOATNAME(LVecBase4) &other) const {
return FLOATNAME(LVecBase4)::operator - (other);
}
////////////////////////////////////////////////////////////////////
@ -178,10 +222,10 @@ operator - (const LVecBase4<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType> LPoint4<NumType>::
operator - (const LPoint4<NumType> &other) const {
return LVecBase4<NumType>::operator - (other);
INLINE FLOATNAME(LVector4) FLOATNAME(LPoint4)::
operator - (const FLOATNAME(LPoint4) &other) const {
return FLOATNAME(LVecBase4)::operator - (other);
}
////////////////////////////////////////////////////////////////////
@ -189,10 +233,10 @@ operator - (const LPoint4<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType> LPoint4<NumType>::
operator - (const LVector4<NumType> &other) const {
return LVecBase4<NumType>::operator - (other);
INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4)::
operator - (const FLOATNAME(LVector4) &other) const {
return FLOATNAME(LVecBase4)::operator - (other);
}
////////////////////////////////////////////////////////////////////
@ -200,10 +244,10 @@ operator - (const LVector4<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType> LPoint4<NumType>::
operator * (NumType scalar) const {
return LPoint4<NumType>(LVecBase4<NumType>::operator * (scalar));
INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4)::
operator * (FLOATTYPE1 scalar) const {
return FLOATNAME(LPoint4)(FLOATNAME(LVecBase4)::operator * (scalar));
}
////////////////////////////////////////////////////////////////////
@ -211,37 +255,9 @@ operator * (NumType scalar) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LPoint4<NumType> LPoint4<NumType>::
operator / (NumType scalar) const {
return LPoint4<NumType>(LVecBase4<NumType>::operator / (scalar));
INLINE FLOATNAME(LPoint4) FLOATNAME(LPoint4)::
operator / (FLOATTYPE1 scalar) const {
return FLOATNAME(LPoint4)(FLOATNAME(LVecBase4)::operator / (scalar));
}
////////////////////////////////////////////////////////////////////
// Function: LPoint4::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void LPoint4<NumType>::
init_type() {
if (_type_handle == TypeHandle::none()) {
LVecBase4<NumType>::init_type();
string name =
"LPoint4<" + get_type_handle(NumType).get_name() + ">";
register_type(_type_handle, name,
LVecBase4<NumType>::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<class NumType, class NumType2>
INLINE LPoint4<NumType2>
lcast_to(NumType2 *, const LPoint4<NumType> &source) {
return LPoint4<NumType2>(source[0], source[1], source[2], source[3]);
}

View File

@ -0,0 +1,13 @@
// Filename: lpoint2.cxx
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
#include "lpoint4.h"
#include "fltnames.I"
#include "lpoint4_src.I"
#include "dblnames.I"
#include "lpoint4_src.I"

View File

@ -11,61 +11,33 @@
#include "lvecBase4.h"
#include "lvector4.h"
////////////////////////////////////////////////////////////////////
// Class : LPoint4
// Description : This is a four-component point in space.
////////////////////////////////////////////////////////////////////
template<class NumType>
class LPoint4 : public LVecBase4<NumType> {
PUBLISHED:
INLINE LPoint4();
INLINE LPoint4(const LVecBase4<NumType> &copy);
INLINE LPoint4<NumType> &operator = (const LVecBase4<NumType> &copy);
INLINE LPoint4<NumType> &operator = (NumType fill_value);
INLINE LPoint4(NumType fill_value);
INLINE LPoint4(NumType x, NumType y, NumType z, NumType w);
INLINE static LPoint4<NumType> zero();
INLINE static LPoint4<NumType> unit_x();
INLINE static LPoint4<NumType> unit_y();
INLINE static LPoint4<NumType> unit_z();
INLINE static LPoint4<NumType> unit_w();
INLINE LPoint4<NumType> operator - () const;
INLINE LVecBase4<NumType>
operator + (const LVecBase4<NumType> &other) const;
INLINE LPoint4<NumType>
operator + (const LVector4<NumType> &other) const;
INLINE LVecBase4<NumType>
operator - (const LVecBase4<NumType> &other) const;
INLINE LVector4<NumType>
operator - (const LPoint4<NumType> &other) const;
INLINE LPoint4<NumType>
operator - (const LVector4<NumType> &other) const;
INLINE LPoint4<NumType> operator * (NumType scalar) const;
INLINE LPoint4<NumType> 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<class NumType, class NumType2>
INLINE LPoint4<NumType2>
lcast_to(NumType2 *type, const LPoint4<NumType> &source);
#include "fltnames.I"
#include "lpoint4.I"
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LPoint4<float>)
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LPoint4<double>)
#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<float>)
////EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LPoint4<double>)
#endif

View File

@ -0,0 +1,25 @@
// Filename: lpoint4.I
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
TypeHandle FLOATNAME(LPoint4)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LPoint4::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
void FLOATNAME(LPoint4)::
init_type() {
if (_type_handle == TypeHandle::none()) {
FLOATNAME(LVecBase4)::init_type();
string name =
"LPoint4<" + get_type_handle(FLOATTYPE1).get_name() + ">";
register_type(_type_handle, name,
FLOATNAME(LVecBase4)::get_class_type());
}
}

View File

@ -3,82 +3,127 @@
//
////////////////////////////////////////////////////////////////////
template<class NumType>
TypeHandle LQuaternionBase<NumType>::_type_handle;
////////////////////////////////////////////////////////////////////
// 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);
INLINE void extract_to_matrix(FLOATNAME(LMatrix3) &m) const;
INLINE void extract_to_matrix(FLOATNAME(LMatrix4) &m) const;
INLINE void set_hpr(const FLOATNAME(LVecBase3) &hpr);
INLINE 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
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::Default Constructor
// Function: FLOATNAME(LQuaternionBase)::Default Constructor
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LQuaternionBase<NumType>::
LQuaternionBase(void) {
INLINE FLOATNAME(LQuaternionBase)::
FLOATNAME(LQuaternionBase)(void) {
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::Copy Constructor
// Function: FLOATNAME(LQuaternionBase)::Copy Constructor
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LQuaternionBase<NumType>::
LQuaternionBase(const LQuaternionBase<NumType>& c) :
INLINE FLOATNAME(LQuaternionBase)::
FLOATNAME(LQuaternionBase)(const FLOATNAME(LQuaternionBase)& c) :
_r(c._r), _i(c._i), _j(c._j), _k(c._k) {
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::Constructor
// Function: FLOATNAME(LQuaternionBase)::Constructor
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LQuaternionBase<NumType>::
LQuaternionBase(NumType r, NumType i, NumType j, NumType k) {
INLINE FLOATNAME(LQuaternionBase)::
FLOATNAME(LQuaternionBase)(FLOATTYPE1 r, FLOATTYPE1 i, FLOATTYPE1 j, FLOATTYPE1 k) {
set(r, i, j, k);
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::Destructor
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
LQuaternionBase<NumType>::
~LQuaternionBase() {
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::pure_imaginary_quat
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
LQuaternionBase<NumType> LQuaternionBase<NumType>::
pure_imaginary(const LVector3<NumType> &v) {
return LQuaternionBase<NumType>(0, v[0], v[1], v[2]);
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::ident_quat
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
const LQuaternionBase<NumType> &LQuaternionBase<NumType>::
ident_quat(void) {
static LQuaternionBase<NumType> q(1, 0, 0, 0);
return q;
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::set
// Function: FLOATNAME(LQuaternionBase)::set
// Access: public
// Description: assignment
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LQuaternionBase<NumType>::
set(NumType r, NumType i, NumType j, NumType k) {
INLINE void FLOATNAME(LQuaternionBase)::
set(FLOATTYPE1 r, FLOATTYPE1 i, FLOATTYPE1 j, FLOATTYPE1 k) {
_r = r;
_i = i;
_j = j;
@ -86,13 +131,13 @@ set(NumType r, NumType i, NumType j, NumType k) {
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::Assignment Operator
// Function: FLOATNAME(LQuaternionBase)::Assignment Operator
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LQuaternionBase<NumType>& LQuaternionBase<NumType>::
operator =(const LQuaternionBase<NumType>& c) {
INLINE FLOATNAME(LQuaternionBase)& FLOATNAME(LQuaternionBase)::
operator =(const FLOATNAME(LQuaternionBase)& c) {
_r = c._r;
_i = c._i;
_j = c._j;
@ -102,13 +147,13 @@ operator =(const LQuaternionBase<NumType>& c) {
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::Equality Operator
// Function: FLOATNAME(LQuaternionBase)::Equality Operator
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LQuaternionBase<NumType>::
operator ==(const LQuaternionBase<NumType>& c) const {
INLINE bool FLOATNAME(LQuaternionBase)::
operator ==(const FLOATNAME(LQuaternionBase)& c) const {
return (_r == c._r &&
_i == c._i &&
_j == c._j &&
@ -116,81 +161,81 @@ operator ==(const LQuaternionBase<NumType>& c) const {
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::Inequality Operator
// Function: FLOATNAME(LQuaternionBase)::Inequality Operator
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LQuaternionBase<NumType>::
operator !=(const LQuaternionBase<NumType>& c) const {
INLINE bool FLOATNAME(LQuaternionBase)::
operator !=(const FLOATNAME(LQuaternionBase)& c) const {
return !operator==(c);
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::multiply
// Function: FLOATNAME(LQuaternionBase)::multiply
// Access: protected
// Description: actual multiply call (non virtual)
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LQuaternionBase<NumType> LQuaternionBase<NumType>::
multiply(const LQuaternionBase<NumType>& 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);
return LQuaternionBase<NumType>(r, i , j, 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);
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::Multiply Operator
// Function: FLOATNAME(LQuaternionBase)::Multiply Operator
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LQuaternionBase<NumType> LQuaternionBase<NumType>::
operator *(const LQuaternionBase<NumType>& c) {
INLINE FLOATNAME(LQuaternionBase) FLOATNAME(LQuaternionBase)::
operator *(const FLOATNAME(LQuaternionBase)& c) {
return multiply(c);
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::Multiply Assignment Operator
// Function: FLOATNAME(LQuaternionBase)::Multiply Assignment Operator
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LQuaternionBase<NumType>& LQuaternionBase<NumType>::
operator *=(const LQuaternionBase<NumType>& c) {
INLINE FLOATNAME(LQuaternionBase)& FLOATNAME(LQuaternionBase)::
operator *=(const FLOATNAME(LQuaternionBase)& c) {
(*this) = operator*(c);
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::Multiply Operator
// Function: FLOATNAME(LQuaternionBase)::Multiply Operator
// Access: public
// Description: Quat * Matrix = matrix
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LMatrix3<NumType> LQuaternionBase<NumType>::
operator *(const LMatrix3<NumType> &m) {
LMatrix3<NumType> result;
INLINE FLOATNAME(LMatrix3) FLOATNAME(LQuaternionBase)::
operator *(const FLOATNAME(LMatrix3) &m) {
FLOATNAME(LMatrix3) result;
extract_to_matrix(result);
return result * m;
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::Multiply Operator
// Function: FLOATNAME(LQuaternionBase)::Multiply Operator
// Access: public
// Description: Quat * Matrix = matrix
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LMatrix4<NumType> LQuaternionBase<NumType>::
operator *(const LMatrix4<NumType> &m) {
LMatrix3<NumType> m_upper_3 = m.get_upper_3();
LMatrix3<NumType> this_quat;
INLINE FLOATNAME(LMatrix4) FLOATNAME(LQuaternionBase)::
operator *(const FLOATNAME(LMatrix4) &m) {
FLOATNAME(LMatrix3) m_upper_3 = m.get_upper_3();
FLOATNAME(LMatrix3) this_quat;
extract_to_matrix(this_quat);
LMatrix4<NumType> result;
FLOATNAME(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));
@ -199,14 +244,14 @@ operator *(const LMatrix4<NumType> &m) {
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::almost_equal
// Function: FLOATNAME(LQuaternionBase)::almost_equal
// Access: public
// Description: Returns true if two quaternions are memberwise equal
// within a specified tolerance.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LQuaternionBase<NumType>::
almost_equal(const LQuaternionBase<NumType>& c, NumType threshold) const {
INLINE bool FLOATNAME(LQuaternionBase)::
almost_equal(const FLOATNAME(LQuaternionBase)& c, FLOATTYPE1 threshold) const {
return (IS_THRESHOLD_EQUAL(_r, c._r, threshold) &&
IS_THRESHOLD_EQUAL(_i, c._i, threshold) &&
IS_THRESHOLD_EQUAL(_j, c._j, threshold) &&
@ -214,24 +259,24 @@ almost_equal(const LQuaternionBase<NumType>& c, NumType threshold) const {
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::almost_equal
// Function: FLOATNAME(LQuaternionBase)::almost_equal
// Access: public
// Description: Returns true if two quaternions are memberwise equal
// within a default tolerance based on the numeric type.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LQuaternionBase<NumType>::
almost_equal(const LQuaternionBase<NumType>& c) const {
return almost_equal(c, NEARLY_ZERO(NumType));
INLINE bool FLOATNAME(LQuaternionBase)::
almost_equal(const FLOATNAME(LQuaternionBase)& c) const {
return almost_equal(c, NEARLY_ZERO(FLOATTYPE1));
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::output
// Function: FLOATNAME(LQuaternionBase)::output
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LQuaternionBase<NumType>::
INLINE void FLOATNAME(LQuaternionBase)::
output(ostream& os) const {
os << MAYBE_ZERO(_r) << " + "
<< MAYBE_ZERO(_i) << "i + "
@ -240,102 +285,102 @@ output(ostream& os) const {
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::get_r
// Function: FLOATNAME(LQuaternionBase)::get_r
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LQuaternionBase<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LQuaternionBase)::
get_r(void) const {
return _r;
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::get_i
// Function: FLOATNAME(LQuaternionBase)::get_i
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LQuaternionBase<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LQuaternionBase)::
get_i(void) const {
return _i;
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::get_j
// Function: FLOATNAME(LQuaternionBase)::get_j
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LQuaternionBase<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LQuaternionBase)::
get_j(void) const {
return _j;
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::get_k
// Function: FLOATNAME(LQuaternionBase)::get_k
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LQuaternionBase<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LQuaternionBase)::
get_k(void) const {
return _k;
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::set_r
// Function: FLOATNAME(LQuaternionBase)::set_r
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LQuaternionBase<NumType>::
set_r(NumType r) {
INLINE void FLOATNAME(LQuaternionBase)::
set_r(FLOATTYPE1 r) {
_r = r;
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::set_i
// Function: FLOATNAME(LQuaternionBase)::set_i
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LQuaternionBase<NumType>::
set_i(NumType i) {
INLINE void FLOATNAME(LQuaternionBase)::
set_i(FLOATTYPE1 i) {
_i = i;
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::set_j
// Function: FLOATNAME(LQuaternionBase)::set_j
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LQuaternionBase<NumType>::
set_j(NumType j) {
INLINE void FLOATNAME(LQuaternionBase)::
set_j(FLOATTYPE1 j) {
_j = j;
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::set_k
// Function: FLOATNAME(LQuaternionBase)::set_k
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LQuaternionBase<NumType>::
set_k(NumType k) {
INLINE void FLOATNAME(LQuaternionBase)::
set_k(FLOATTYPE1 k) {
_k = k;
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::normalize
// Function: FLOATNAME(LQuaternionBase)::normalize
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LQuaternionBase<NumType>::
INLINE void FLOATNAME(LQuaternionBase)::
normalize(void) {
NumType l = csqrt((_r*_r)+(_i*_i)+(_j*_j)+(_k*_k));
FLOATTYPE1 l = csqrt((_r*_r)+(_i*_i)+(_j*_j)+(_k*_k));
if (l == 0.0) {
_r = 0.;
@ -351,82 +396,14 @@ normalize(void) {
}
}
////////////////////////////////////////////////////////////////////
// Function: set
// Access: public
// Description: Do-While Jones.
////////////////////////////////////////////////////////////////////
template<class NumType>
void LQuaternionBase<NumType>::
set(const LMatrix3<NumType> &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:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LQuaternionBase<NumType>::
set(const LMatrix4<NumType> &m) {
INLINE void FLOATNAME(LQuaternionBase)::
set(const FLOATNAME(LMatrix4) &m) {
set(m.get_upper_3());
}
@ -435,19 +412,19 @@ set(const LMatrix4<NumType> &m) {
// Access: public
// Description: Do-While Jones paper from cary.
////////////////////////////////////////////////////////////////////
template<class NumType>
void LQuaternionBase<NumType>::
extract_to_matrix(LMatrix3<NumType> &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;
INLINE void FLOATNAME(LQuaternionBase)::
extract_to_matrix(FLOATNAME(LMatrix3) &m) const {
FLOATTYPE1 N = (_r * _r) + (_i * _i) + (_j * _j) + (_k * _k);
FLOATTYPE1 s = (N == 0.) ? 0. : (2. / N);
FLOATTYPE1 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<NumType>((1. - (yy + zz)), (xy - wz), (xz + wy),
m = FLOATNAME(LMatrix3)((1. - (yy + zz)), (xy - wz), (xz + wy),
(xy + wz), (1. - (xx + zz)), (yz - wx),
(xz - wy), (yz + wx), (1. - (xx + yy)));
}
@ -457,19 +434,19 @@ extract_to_matrix(LMatrix3<NumType> &m) const {
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void LQuaternionBase<NumType>::
extract_to_matrix(LMatrix4<NumType> &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;
INLINE void FLOATNAME(LQuaternionBase)::
extract_to_matrix(FLOATNAME(LMatrix4) &m) const {
FLOATTYPE1 N = (_r * _r) + (_i * _i) + (_j * _j) + (_k * _k);
FLOATTYPE1 s = (N == 0.) ? 0. : (2. / N);
FLOATTYPE1 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<NumType>((1. - (yy + zz)), (xy - wz), (xz + wy), 0.,
m = FLOATNAME(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.);
@ -482,23 +459,23 @@ extract_to_matrix(LMatrix4<NumType> &m) const {
// is equivalent to these Euler angles.
// (from Real-time Rendering, p.49)
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LQuaternionBase<NumType>::
set_hpr(const LVecBase3<NumType> &hpr) {
LQuaternionBase<NumType> quat_h, quat_p, quat_r;
LVector3<NumType> v = LVector3<NumType>::up();
NumType a = deg_2_rad(hpr[0] * 0.5);
NumType s,c;
INLINE void FLOATNAME(LQuaternionBase)::
set_hpr(const FLOATNAME(LVecBase3) &hpr) {
FLOATNAME(LQuaternionBase) quat_h, quat_p, quat_r;
FLOATNAME(LVector3) v = FLOATNAME(LVector3)::up();
FLOATTYPE1 a = deg_2_rad(hpr[0] * 0.5);
FLOATTYPE1 s,c;
csincos(a,&s,&c);
quat_h.set(c, v[0] * s, v[1] * s, v[2] * s);
v = LVector3<NumType>::right();
v = FLOATNAME(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<NumType>::forward();
v = FLOATNAME(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);
@ -512,14 +489,14 @@ set_hpr(const LVecBase3<NumType> &hpr) {
// Description: Extracts the equivalent Euler angles from the unit
// quaternion.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> LQuaternionBase<NumType>::
INLINE FLOATNAME(LVecBase3) FLOATNAME(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;
FLOATTYPE1 heading, pitch, roll;
FLOATTYPE1 N = (_r * _r) + (_i * _i) + (_j * _j) + (_k * _k);
FLOATTYPE1 s = (N == 0.) ? 0. : (2. / N);
FLOATTYPE1 xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz, c1, c2, c3, c4;
FLOATTYPE1 cr, sr, cp, sp, ch, sh;
xs = _i * s; ys = _j * s; zs = _k * s;
wx = _r * xs; wy = _r * ys; wz = _r * zs;
@ -555,7 +532,75 @@ get_hpr() const {
heading = rad_2_deg(catan2(sh, ch));
pitch = rad_2_deg(catan2(sp, cp));
return LVecBase3<NumType>(heading, pitch, roll);
return FLOATNAME(LVecBase3)(heading, pitch, roll);
}
////////////////////////////////////////////////////////////////////
// Function: set
// Access: public
// Description: Do-While Jones.
////////////////////////////////////////////////////////////////////
INLINE void FLOATNAME(LQuaternionBase)::
set(const FLOATNAME(LMatrix3) &m) {
FLOATTYPE1 m00 = m.get_cell(0, 0);
FLOATTYPE1 m01 = m.get_cell(0, 1);
FLOATTYPE1 m02 = m.get_cell(0, 2);
FLOATTYPE1 m10 = m.get_cell(1, 0);
FLOATTYPE1 m11 = m.get_cell(1, 1);
FLOATTYPE1 m12 = m.get_cell(1, 2);
FLOATTYPE1 m20 = m.get_cell(2, 0);
FLOATTYPE1 m21 = m.get_cell(2, 1);
FLOATTYPE1 m22 = m.get_cell(2, 2);
FLOATTYPE1 T = m00 + m11 + m22 + 1.;
if (T > 0.) {
// the easy case
FLOATTYPE1 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;
FLOATTYPE1 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;
}
}
}
////////////////////////////////////////////////////////////////////
@ -563,10 +608,10 @@ get_hpr() const {
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
LMatrix3<NumType> operator *(const LMatrix3<NumType> &m,
const LQuaternionBase<NumType> &q) {
LMatrix3<NumType> q_matrix;
FLOATNAME(LMatrix3) operator *(const FLOATNAME(LMatrix3) &m,
const FLOATNAME(LQuaternionBase) &q) {
FLOATNAME(LMatrix3) q_matrix;
q.extract_to_matrix(q_matrix);
return m * q_matrix;
@ -577,15 +622,15 @@ LMatrix3<NumType> operator *(const LMatrix3<NumType> &m,
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
LMatrix4<NumType> operator *(const LMatrix4<NumType> &m,
const LQuaternionBase<NumType> &q) {
LMatrix4<NumType> q_matrix;
FLOATNAME(LMatrix4) operator *(const FLOATNAME(LMatrix4) &m,
const FLOATNAME(LQuaternionBase) &q) {
FLOATNAME(LMatrix4) q_matrix;
q.extract_to_matrix(q_matrix);
// preserve the homogeneous coords and the translate
LVector4<NumType> m_row3 = m.get_row(3);
LVector4<NumType> m_col3 = m.get_col(3);
FLOATNAME(LVector4) m_row3 = m.get_row(3);
FLOATNAME(LVector4) m_col3 = m.get_col(3);
q_matrix = m * q_matrix;
q_matrix.set_row(3, m_row3);
@ -594,30 +639,3 @@ LMatrix4<NumType> operator *(const LMatrix4<NumType> &m,
return q_matrix;
}
////////////////////////////////////////////////////////////////////
// Function: LQuaternionBase::init_type
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void LQuaternionBase<NumType>::
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<class NumType, class NumType2>
INLINE LQuaternionBase<NumType2>
lcast_to(NumType2 *, const LQuaternionBase<NumType>& c) {
return LQuaternionBase<NumType2>(c.get_r(), c.get_i(), c.get_j(), c.get_k());
}

View File

@ -0,0 +1,13 @@
// Filename: lquaternion.cxx
// Created by: frang (06Jun00)
//
////////////////////////////////////////////////////////////////////
#include "lquaternion.h"
#include "fltnames.I"
#include "lquaternion_src.I"
#include "dblnames.I"
#include "lquaternion_src.I"

View File

@ -7,117 +7,39 @@
#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 <notify.h>
////////////////////////////////////////////////////////////////////
// Class : LQuaternionBase
// Description : This is the base quaternion class
////////////////////////////////////////////////////////////////////
template <class NumType>
class LQuaternionBase {
protected:
INLINE LQuaternionBase<NumType>
multiply(const LQuaternionBase<NumType>&) const;
PUBLISHED:
INLINE LQuaternionBase(void);
INLINE LQuaternionBase(const LQuaternionBase<NumType> &);
INLINE LQuaternionBase(NumType, NumType, NumType, NumType);
virtual ~LQuaternionBase(void);
static LQuaternionBase<NumType> pure_imaginary(const LVector3<NumType> &);
INLINE LQuaternionBase<NumType>& operator =(const LQuaternionBase<NumType> &);
INLINE bool operator ==(const LQuaternionBase<NumType> &) const;
INLINE bool operator !=(const LQuaternionBase<NumType> &) const;
INLINE LQuaternionBase<NumType> operator *(const LQuaternionBase<NumType> &);
INLINE LQuaternionBase<NumType>& operator *=(const LQuaternionBase<NumType> &);
INLINE LMatrix3<NumType> operator *(const LMatrix3<NumType> &);
INLINE LMatrix4<NumType> operator *(const LMatrix4<NumType> &);
INLINE bool almost_equal(const LQuaternionBase<NumType> &, NumType) const;
INLINE bool almost_equal(const LQuaternionBase<NumType> &) const;
INLINE void output(ostream&) const;
INLINE void set(NumType, NumType, NumType, NumType);
void set(const LMatrix3<NumType> &m);
INLINE void set(const LMatrix4<NumType> &m);
void extract_to_matrix(LMatrix3<NumType> &m) const;
void extract_to_matrix(LMatrix4<NumType> &m) const;
INLINE void set_hpr(const LVecBase3<NumType> &hpr);
LVecBase3<NumType> 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<NumType> &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<class NumType>
INLINE ostream& operator<<(ostream& os, const LQuaternionBase<NumType>& q) {
q.output(os);
return os;
}
// matrix times quat
template<class NumType>
INLINE LMatrix3<NumType>
operator * (const LMatrix3<NumType> &m, const LQuaternionBase<NumType> &q);
template<class NumType>
INLINE LMatrix4<NumType>
operator * (const LMatrix4<NumType> &m, const LQuaternionBase<NumType> &q);
// pacify interrogate.
#ifdef CPPPARSER
BEGIN_PUBLISH
INLINE LMatrix3<float>
operator * (const LMatrix3<float> &m, const LQuaternionBase<float> &q);
INLINE LMatrix4<float>
operator * (const LMatrix4<float> &m, const LQuaternionBase<float> &q);
INLINE LMatrix3<double>
operator * (const LMatrix3<double> &m, const LQuaternionBase<double> &q);
INLINE LMatrix4<double>
operator * (const LMatrix4<double> &m, const LQuaternionBase<double> &q);
END_PUBLISH
#endif
// Cast to a different numeric type
template<class NumType, class NumType2>
INLINE LQuaternionBase<NumType2> lcast_to(NumType2*, const LQuaternionBase<NumType>&);
#include "fltnames.I"
#include "lquaternion.I"
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LQuaternionBase<float>)
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LQuaternionBase<double>)
#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.
////////////////////////////////////////////////////////////////////
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());
}
#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());
}
#endif /* __LQUATERNION_H__ */

View File

@ -0,0 +1,51 @@
TypeHandle FLOATNAME(LQuaternionBase)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FLOATNAME(LQuaternionBase)::Destructor
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
FLOATNAME(LQuaternionBase)::
~FLOATNAME(LQuaternionBase)() {
}
////////////////////////////////////////////////////////////////////
// Function: FLOATNAME(LQuaternionBase)::pure_imaginary_quat
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
FLOATNAME(LQuaternionBase) FLOATNAME(LQuaternionBase)::
pure_imaginary(const FLOATNAME(LVector3) &v) {
return FLOATNAME(LQuaternionBase)(0, v[0], v[1], v[2]);
}
////////////////////////////////////////////////////////////////////
// Function: FLOATNAME(LQuaternionBase)::ident_quat
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
const FLOATNAME(LQuaternionBase) &FLOATNAME(LQuaternionBase)::
ident_quat(void) {
static FLOATNAME(LQuaternionBase) q(1, 0, 0, 0);
return q;
}
////////////////////////////////////////////////////////////////////
// Function: FLOATNAME(LQuaternionBase)::init_type
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
void FLOATNAME(LQuaternionBase)::
init_type(void) {
if (_type_handle == TypeHandle::none()) {
do_init_type(FLOATTYPE1);
string name = "FLOATNAME(LQuaternionBase)<" + get_type_handle(FLOATTYPE1).get_name()
+ ">";
register_type(_type_handle, name);
}
}

View File

@ -3,17 +3,44 @@
//
////////////////////////////////////////////////////////////////////
template<class NumType>
TypeHandle LRotation<NumType>::_type_handle;
////////////////////////////////////////////////////////////////////////
// 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;
};
////////////////////////////////////////////////////////////////////
// Function: LRotation::Default Constructor
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LRotation<NumType>::
LRotation() {
INLINE FLOATNAME(LRotation)::
FLOATNAME(LRotation)() {
}
////////////////////////////////////////////////////////////////////
@ -21,10 +48,10 @@ LRotation() {
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LRotation<NumType>::
LRotation(const LQuaternionBase<NumType>& c) :
LQuaternionBase<NumType>(c) {
INLINE FLOATNAME(LRotation)::
FLOATNAME(LRotation)(const FLOATNAME(LQuaternionBase)& c) :
FLOATNAME(LQuaternionBase)(c) {
}
////////////////////////////////////////////////////////////////////
@ -32,10 +59,10 @@ LRotation(const LQuaternionBase<NumType>& c) :
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LRotation<NumType>::
LRotation(NumType r, NumType i, NumType j, NumType k) :
LQuaternionBase<NumType>(r, i, j, k) {
INLINE FLOATNAME(LRotation)::
FLOATNAME(LRotation)(FLOATTYPE1 r, FLOATTYPE1 i, FLOATTYPE1 j, FLOATTYPE1 k) :
FLOATNAME(LQuaternionBase)(r, i, j, k) {
}
////////////////////////////////////////////////////////////////////
@ -43,9 +70,9 @@ LRotation(NumType r, NumType i, NumType j, NumType k) :
// Access: public
// Description: lmatrix3
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LRotation<NumType>::
LRotation(const LMatrix3<NumType> &m) {
INLINE FLOATNAME(LRotation)::
FLOATNAME(LRotation)(const FLOATNAME(LMatrix3) &m) {
set(m);
}
@ -54,9 +81,9 @@ LRotation(const LMatrix3<NumType> &m) {
// Access: public
// Description: lmatrix4
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LRotation<NumType>::
LRotation(const LMatrix4<NumType> &m) {
INLINE FLOATNAME(LRotation)::
FLOATNAME(LRotation)(const FLOATNAME(LMatrix4) &m) {
set(m);
}
@ -65,12 +92,12 @@ LRotation(const LMatrix4<NumType> &m) {
// Access: public
// Description: axis + angle (in degrees)
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LRotation<NumType>::
LRotation(const LVector3<NumType> &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);
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);
set_r(ccos(theta_over_2));
set_i(axis[0] * sin_to2);
@ -83,20 +110,10 @@ LRotation(const LVector3<NumType> &axis, NumType angle) {
// Access: public
// Description: Sets the rotation from the given Euler angles.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LRotation<NumType>::
LRotation(NumType h, NumType p, NumType r) {
set_hpr(LVecBase3<NumType>(h, p, r));
}
////////////////////////////////////////////////////////////////////
// Function: LRotation::Destructor
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
LRotation<NumType>::
~LRotation() {
INLINE FLOATNAME(LRotation)::
FLOATNAME(LRotation)(FLOATTYPE1 h, FLOATTYPE1 p, FLOATTYPE1 r) {
set_hpr(FLOATNAME(LVecBase3)(h, p, r));
}
////////////////////////////////////////////////////////////////////
@ -104,9 +121,9 @@ LRotation<NumType>::
// Access: public
// Description: Rotation * Rotation = Rotation
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LRotation<NumType> LRotation<NumType>::
operator*(const LRotation<NumType>& other) const {
INLINE FLOATNAME(LRotation) FLOATNAME(LRotation)::
operator*(const FLOATNAME(LRotation)& other) const {
return multiply(other);
}
@ -118,25 +135,10 @@ operator*(const LRotation<NumType>& other) const {
// to apply an orientation to a rotation. It simply
// returns the rhs.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LQuaternionBase<NumType> LRotation<NumType>::
operator*(const LQuaternionBase<NumType>& other) const {
INLINE FLOATNAME(LQuaternionBase) FLOATNAME(LRotation)::
operator*(const FLOATNAME(LQuaternionBase)& other) const {
return other;
}
////////////////////////////////////////////////////////////////////
// Function: LRotation::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void LRotation<NumType>::
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);
}
}

View File

@ -0,0 +1,13 @@
// Filename: lrotation.I
// Created by: frang, charles (23Jun00)
//
////////////////////////////////////////////////////////////////////
#include "lrotation.h"
#include "fltnames.I"
#include "lrotation_src.I"
#include "dblnames.I"
#include "lrotation_src.I"

View File

@ -12,40 +12,13 @@
#include <notify.h>
////////////////////////////////////////////////////////////////////////
// Class : LRotation
// Description : This is a unit quaternion representing a rotation.
////////////////////////////////////////////////////////////////////////
template <class NumType>
class LRotation : public LQuaternionBase<NumType> {
PUBLISHED:
INLINE LRotation();
INLINE LRotation(const LQuaternionBase<NumType>&);
INLINE LRotation(NumType, NumType, NumType, NumType);
INLINE LRotation(const LVector3<NumType> &, NumType);
INLINE LRotation(const LMatrix3<NumType> &);
INLINE LRotation(const LMatrix4<NumType> &);
INLINE LRotation(NumType, NumType, NumType);
virtual ~LRotation();
INLINE LRotation<NumType>
operator*(const LRotation<NumType>& other) const;
INLINE LQuaternionBase<NumType>
operator*(const LQuaternionBase<NumType>& other) const;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type();
private:
static TypeHandle _type_handle;
};
#include "fltnames.I"
#include "lrotation.I"
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LRotation<float>)
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LRotation<double>)
#include "dblnames.I"
#include "lrotation.I"
#endif /* __LROTATION_H__ */

View File

@ -0,0 +1,34 @@
// Filename: lrotation.I
// Created by: frang, charles (23Jun00)
//
////////////////////////////////////////////////////////////////////
TypeHandle FLOATNAME(LRotation)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LRotation::Destructor
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
FLOATNAME(LRotation)::
~FLOATNAME(LRotation)() {
}
////////////////////////////////////////////////////////////////////
// Function: LRotation::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
void FLOATNAME(LRotation)::
init_type() {
if (_type_handle == TypeHandle::none()) {
// Format a string to describe the type.
do_init_type(FLOATTYPE1);
string name =
"LRotation<" + get_type_handle(FLOATTYPE1).get_name() + ">";
register_type(_type_handle, name);
}
}

View File

@ -1,85 +1,44 @@
forcetype LVecBase2<float>
forcetype LVecBase3<float>
forcetype LVecBase4<float>
forcetype LPoint2<float>
forcetype LPoint3<float>
forcetype LPoint4<float>
forcetype LVector2<float>
forcetype LVector3<float>
forcetype LVector4<float>
renametype LPoint2f LPoint2f
renametype LPoint3f LPoint3f
renametype LPoint4f LPoint4f
renametype LPoint2d LPoint2d
renametype LPoint3d LPoint3d
renametype LPoint4d LPoint4d
forcetype LMatrix3<float>
forcetype LMatrix4<float>
renametype LVecBase2f LVecBase2f
renametype LVecBase3f LVecBase3f
renametype LVecBase4f LVecBase4f
renametype LVecBase2d LVecBase2d
renametype LVecBase3d LVecBase3d
renametype LVecBase4d LVecBase4d
forcetype LPoint2f
forcetype LPoint3f
forcetype LPoint4f
renametype LVector2f LVector2f
renametype LVector3f LVector3f
renametype LVector4f LVector4f
renametype LVector2d LVector2d
renametype LVector3d LVector3d
renametype LVector4d LVector4d
forcetype LVector2f
forcetype LVector3f
forcetype LVector4f
renametype LMatrix3f LMatrix3f
renametype LMatrix4f LMatrix4f
renametype LMatrix3d LMatrix3d
renametype LMatrix4d LMatrix4d
forcetype Vertexf
forcetype Normalf
forcetype TexCoordf
forcetype Colorf
forcetype RGBColorf
renametype LQuaternionf LQuaternionf
renametype LRotationf LRotationf
renametype LOrientationf LOrientationf
forcetype LMatrix3f
forcetype LMatrix4f
forcetype LVecBase2<double>
forcetype LVecBase3<double>
forcetype LVecBase4<double>
forcetype LPoint2<double>
forcetype LPoint3<double>
forcetype LPoint4<double>
forcetype LVector2<double>
forcetype LVector3<double>
forcetype LVector4<double>
forcetype LMatrix3<double>
forcetype LMatrix4<double>
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<float>
forcetype LQuaternionBase<double>
forcetype LRotation<float>
forcetype LRotation<double>
forcetype LOrientation<float>
forcetype LOrientation<double>
forcetype LQuaternionf
forcetype LRotationf
forcetype LOrientationf
forcetype LQuaterniond
forcetype LRotationd
forcetype LOrientationd
renametype LQuaterniond LQuaterniond
renametype LRotationd LRotationd
renametype LOrientationd LOrientationd
forcetype PTA_Vertexf
forcetype PTA_Normalf
forcetype PTA_TexCoordf
forcetype PTA_Colorf
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

View File

@ -12,12 +12,12 @@
// designed for specific uses. These all inherit from LVecBase, which
// is the base class of all linear algebra vectors.
//
// LPoint<P_numtype, N_length>
// LPoint<P_FLOATTYPE1, N_length>
//
// This should be used to represent a specific point in space. It
// inherits most properties from LVecBase.
//
// LVector<P_numtype, N_length>
// LVector<P_FLOATTYPE1, N_length>
//
// 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<P_numtype>, Vertexd, Vertexf
// Normal<P_numtype>, Normald, Normalf
// TexCoord<P_numtype>, TexCoordd, TexCoordf
// Color<P_numtype>, Colord, Colorf
// RGBColor<P_numtype>, RGBColord, RGBColorf
// Vertex<P_FLOATTYPE1>, Vertexd, Vertexf
// Normal<P_FLOATTYPE1>, Normald, Normalf
// TexCoord<P_FLOATTYPE1>, TexCoordd, TexCoordf
// Color<P_FLOATTYPE1>, Colord, Colorf
// RGBColor<P_FLOATTYPE1>, 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<float> LVecBase2f;
typedef LVecBase3<float> LVecBase3f;
typedef LVecBase4<float> LVecBase4f;
@ -85,13 +85,13 @@ typedef LVector4<float> LVector4f;
typedef LPoint2<float> LPoint2f;
typedef LPoint3<float> LPoint3f;
typedef LPoint4<float> LPoint4f;
*/
typedef LPoint3f Vertexf;
typedef LVector3f Normalf;
typedef LPoint2f TexCoordf;
typedef LVecBase4f Colorf;
typedef LVecBase3f RGBColorf;
/*
typedef LVecBase2<double> LVecBase2d;
typedef LVecBase3<double> LVecBase3d;
typedef LVecBase4<double> LVecBase4d;
@ -102,13 +102,16 @@ typedef LVector4<double> LVector4d;
typedef LPoint2<double> LPoint2d;
typedef LPoint3<double> LPoint3d;
typedef LPoint4<double> LPoint4d;
*/
typedef LPoint3d Vertexd;
typedef LVector3d Normald;
typedef LPoint2d TexCoordd;
typedef LVecBase4d Colord;
typedef LVecBase3d RGBColord;
typedef LQuaternionBasef LQuaternionf;
typedef LQuaternionBased LQuaterniond;
/*
typedef LQuaternionBase<float> LQuaternionf;
typedef LRotation<float> LRotationf;
typedef LOrientation<float> LOrientationf;
@ -116,7 +119,7 @@ typedef LOrientation<float> LOrientationf;
typedef LQuaternionBase<double> LQuaterniond;
typedef LRotation<double> LRotationd;
typedef LOrientation<double> LOrientationd;
*/
/*
// Now define explicit instantiations of the output operator functions
// for interrogate's benefit. These functions don't actually exist

View File

@ -3,17 +3,49 @@
//
////////////////////////////////////////////////////////////////////
#include <math.h>
// 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 "nearly_zero.h"
// 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);
////////////////////////////////////////////////////////////////////
// Function: scalar * LVecBase2
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType, class NumType2>
INLINE LVecBase2<NumType>
operator * (NumType2 scalar, const LVecBase2<NumType> &a) {
INLINE FLOATNAME(LVecBase2)
operator * (FLOATTYPE2 scalar, const FLOATNAME(LVecBase2) &a) {
return a * scalar;
}
@ -21,9 +53,8 @@ operator * (NumType2 scalar, const LVecBase2<NumType> &a) {
// Function: scalar * LPoint2
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType, class NumType2>
INLINE LPoint2<NumType>
operator * (NumType2 scalar, const LPoint2<NumType> &a) {
INLINE FLOATNAME(LPoint2)
operator * (FLOATTYPE2 scalar, const FLOATNAME(LPoint2) &a) {
return a * scalar;
}
@ -31,9 +62,8 @@ operator * (NumType2 scalar, const LPoint2<NumType> &a) {
// Function: scalar * LVector2
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType, class NumType2>
INLINE LVector2<NumType>
operator * (NumType2 scalar, const LVector2<NumType> &a) {
INLINE FLOATNAME(LVector2)
operator * (FLOATTYPE2 scalar, const FLOATNAME(LVector2) &a) {
return a * scalar;
}
@ -41,39 +71,19 @@ operator * (NumType2 scalar, const LVector2<NumType> &a) {
// Function: dot product of LVecBase2
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType
dot(const LVecBase2<NumType> &a, const LVecBase2<NumType> &b) {
INLINE FLOATTYPE1
dot(const FLOATNAME(LVecBase2) &a, const FLOATNAME(LVecBase2) &b) {
return a.dot(b);
}
////////////////////////////////////////////////////////////////////
// Function: cross product of LVecBase2
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType>
cross(const LVecBase2<NumType> &a, const LVecBase2<NumType> &b) {
return a.cross(b);
}
////////////////////////////////////////////////////////////////////
// Function: cross product of LVector2
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType>
cross(const LVector2<NumType> &a, const LVector2<NumType> &b) {
return LVector2<NumType>(a.cross(b));
}
////////////////////////////////////////////////////////////////////
// Function: length of a vector
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType
length(const LVector2<NumType> &a) {
INLINE FLOATTYPE1
length(const FLOATNAME(LVector2) &a) {
return a.length();
}
@ -82,10 +92,10 @@ length(const LVector2<NumType> &a) {
// Function: normalize
// Description: Returns a normalized vector from the given vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType>
normalize(const LVector2<NumType> &v) {
LVector2<NumType> v1 = v;
INLINE FLOATNAME(LVector2)
normalize(const FLOATNAME(LVector2) &v) {
FLOATNAME(LVector2) v1 = v;
v1.normalize();
return v1;
}

View File

@ -6,49 +6,16 @@
#ifndef LVEC2_OPS_H
#define LVEC2_OPS_H
#include <math.h>
#include "nearly_zero.h"
#include "lvecBase2.h"
#include "lpoint2.h"
#include "lvector2.h"
// 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<class NumType, class NumType2>
INLINE LVecBase2<NumType>
operator * (NumType2 scalar, const LVecBase2<NumType> &a);
template<class NumType, class NumType2>
INLINE LPoint2<NumType>
operator * (NumType2 scalar, const LPoint2<NumType> &a);
template<class NumType, class NumType2>
INLINE LVector2<NumType>
operator * (NumType2 scalar, const LVector2<NumType> &a);
// dot product
template<class NumType>
INLINE NumType
dot(const LVecBase2<NumType> &a, const LVecBase2<NumType> &b);
// Length of a vector.
template<class NumType>
INLINE NumType
length(const LVector2<NumType> &a);
// A normalized vector.
template<class NumType>
INLINE LVector2<NumType>
normalize(const LVector2<NumType> &v);
#include "fltnames.I"
#include "lvec2_ops.I"
#include "dblnames.I"
#include "lvec2_ops.I"
#endif

View File

@ -3,17 +3,60 @@
//
////////////////////////////////////////////////////////////////////
#include <math.h>
// 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 "nearly_zero.h"
////////////////////////////////////////////////////////////////////
// Function: scalar * LVecBase3
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType, class NumType2>
INLINE LVecBase3<NumType>
operator * (NumType2 scalar, const LVecBase3<NumType> &a) {
INLINE FLOATNAME(LVecBase3)
operator * (FLOATTYPE2 scalar, const FLOATNAME(LVecBase3) &a) {
return a * scalar;
}
@ -21,9 +64,8 @@ operator * (NumType2 scalar, const LVecBase3<NumType> &a) {
// Function: scalar * LPoint3
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType, class NumType2>
INLINE LPoint3<NumType>
operator * (NumType2 scalar, const LPoint3<NumType> &a) {
INLINE FLOATNAME(LPoint3)
operator * (FLOATTYPE2 scalar, const FLOATNAME(LPoint3) &a) {
return a * scalar;
}
@ -31,9 +73,8 @@ operator * (NumType2 scalar, const LPoint3<NumType> &a) {
// Function: scalar * LVector3
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType, class NumType2>
INLINE LVector3<NumType>
operator * (NumType2 scalar, const LVector3<NumType> &a) {
INLINE FLOATNAME(LVector3)
operator * (FLOATTYPE2 scalar, const FLOATNAME(LVector3) &a) {
return a * scalar;
}
@ -41,9 +82,9 @@ operator * (NumType2 scalar, const LVector3<NumType> &a) {
// Function: dot product of LVecBase3
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType
dot(const LVecBase3<NumType> &a, const LVecBase3<NumType> &b) {
INLINE FLOATTYPE1
dot(const FLOATNAME(LVecBase3) &a, const FLOATNAME(LVecBase3) &b) {
return a.dot(b);
}
@ -51,9 +92,9 @@ dot(const LVecBase3<NumType> &a, const LVecBase3<NumType> &b) {
// Function: cross product of LVecBase3
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType>
cross(const LVecBase3<NumType> &a, const LVecBase3<NumType> &b) {
INLINE FLOATNAME(LVecBase3)
cross(const FLOATNAME(LVecBase3) &a, const FLOATNAME(LVecBase3) &b) {
return a.cross(b);
}
@ -61,10 +102,10 @@ cross(const LVecBase3<NumType> &a, const LVecBase3<NumType> &b) {
// Function: cross product of LVector3
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType>
cross(const LVector3<NumType> &a, const LVector3<NumType> &b) {
return LVector3<NumType>(a.cross(b));
INLINE FLOATNAME(LVector3)
cross(const FLOATNAME(LVector3) &a, const FLOATNAME(LVector3) &b) {
return FLOATNAME(LVector3)(a.cross(b));
}
@ -72,9 +113,9 @@ cross(const LVector3<NumType> &a, const LVector3<NumType> &b) {
// Function: length of a vector
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType
length(const LVector3<NumType> &a) {
INLINE FLOATTYPE1
length(const FLOATNAME(LVector3) &a) {
return a.length();
}
@ -83,10 +124,10 @@ length(const LVector3<NumType> &a) {
// Function: normalize
// Description: Returns a normalized vector from the given vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType>
normalize(const LVector3<NumType> &v) {
LVector3<NumType> v1 = v;
INLINE FLOATNAME(LVector3)
normalize(const FLOATNAME(LVector3) &v) {
FLOATNAME(LVector3) v1 = v;
v1.normalize();
return v1;
}

View File

@ -6,59 +6,17 @@
#ifndef LVEC3_OPS_H
#define LVEC3_OPS_H
#include <math.h>
#include "nearly_zero.h"
#include "lvecBase3.h"
#include "lpoint3.h"
#include "lvector3.h"
// 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<class NumType, class NumType2>
INLINE LVecBase3<NumType>
operator * (NumType2 scalar, const LVecBase3<NumType> &a);
template<class NumType, class NumType2>
INLINE LPoint3<NumType>
operator * (NumType2 scalar, const LPoint3<NumType> &a);
template<class NumType, class NumType2>
INLINE LVector3<NumType>
operator * (NumType2 scalar, const LVector3<NumType> &a);
// dot product
template<class NumType>
INLINE NumType
dot(const LVecBase3<NumType> &a, const LVecBase3<NumType> &b);
// cross product
template<class NumType>
INLINE LVecBase3<NumType>
cross(const LVecBase3<NumType> &a, const LVecBase3<NumType> &b);
template<class NumType>
INLINE LVector3<NumType>
cross(const LVector3<NumType> &a, const LVector3<NumType> &b);
// Length of a vector.
template<class NumType>
INLINE NumType
length(const LVector3<NumType> &a);
// A normalized vector.
template<class NumType>
INLINE LVector3<NumType>
normalize(const LVector3<NumType> &v);
#include "fltnames.I"
#include "lvec3_ops.I"
#include "dblnames.I"
#include "lvec3_ops.I"
#endif

View File

@ -3,17 +3,50 @@
//
////////////////////////////////////////////////////////////////////
#include <math.h>
// 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 "nearly_zero.h"
////////////////////////////////////////////////////////////////////
// Function: scalar * LVecBase4
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType, class NumType2>
INLINE LVecBase4<NumType>
operator * (NumType2 scalar, const LVecBase4<NumType> &a) {
INLINE FLOATNAME(LVecBase4)
operator * (FLOATTYPE2 scalar, const FLOATNAME(LVecBase4) &a) {
return a * scalar;
}
@ -21,9 +54,8 @@ operator * (NumType2 scalar, const LVecBase4<NumType> &a) {
// Function: scalar * LPoint4
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType, class NumType2>
INLINE LPoint4<NumType>
operator * (NumType2 scalar, const LPoint4<NumType> &a) {
INLINE FLOATNAME(LPoint4)
operator * (FLOATTYPE2 scalar, const FLOATNAME(LPoint4) &a) {
return a * scalar;
}
@ -31,9 +63,8 @@ operator * (NumType2 scalar, const LPoint4<NumType> &a) {
// Function: scalar * LVector4
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType, class NumType2>
INLINE LVector4<NumType>
operator * (NumType2 scalar, const LVector4<NumType> &a) {
INLINE FLOATNAME(LVector4)
operator * (FLOATTYPE2 scalar, const FLOATNAME(LVector4) &a) {
return a * scalar;
}
@ -41,9 +72,9 @@ operator * (NumType2 scalar, const LVector4<NumType> &a) {
// Function: dot product of LVecBase4
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType
dot(const LVecBase4<NumType> &a, const LVecBase4<NumType> &b) {
INLINE FLOATTYPE1
dot(const FLOATNAME(LVecBase4) &a, const FLOATNAME(LVecBase4) &b) {
return a.dot(b);
}
@ -51,9 +82,9 @@ dot(const LVecBase4<NumType> &a, const LVecBase4<NumType> &b) {
// Function: length of a vector
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType
length(const LVector4<NumType> &a) {
INLINE FLOATTYPE1
length(const FLOATNAME(LVector4) &a) {
return a.length();
}
@ -62,10 +93,10 @@ length(const LVector4<NumType> &a) {
// Function: normalize
// Description: Returns a normalized vector from the given vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType>
normalize(const LVector4<NumType> &v) {
LVector4<NumType> v1 = v;
INLINE FLOATNAME(LVector4)
normalize(const FLOATNAME(LVector4) &v) {
FLOATNAME(LVector4) v1 = v;
v1.normalize();
return v1;
}

View File

@ -6,49 +6,17 @@
#ifndef LVEC4_OPS_H
#define LVEC4_OPS_H
#include <math.h>
#include "nearly_zero.h"
#include "lvecBase4.h"
#include "lpoint4.h"
#include "lvector4.h"
// 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<class NumType, class NumType2>
INLINE LVecBase4<NumType>
operator * (NumType2 scalar, const LVecBase4<NumType> &a);
template<class NumType, class NumType2>
INLINE LPoint4<NumType>
operator * (NumType2 scalar, const LPoint4<NumType> &a);
template<class NumType, class NumType2>
INLINE LVector4<NumType>
operator * (NumType2 scalar, const LVector4<NumType> &a);
// dot product
template<class NumType>
INLINE NumType
dot(const LVecBase4<NumType> &a, const LVecBase4<NumType> &b);
// Length of a vector.
template<class NumType>
INLINE NumType
length(const LVector4<NumType> &a);
// A normalized vector.
template<class NumType>
INLINE LVector4<NumType>
normalize(const LVector4<NumType> &v);
#include "fltnames.I"
#include "lvec4_ops.I"
#include "dblnames.I"
#include "lvec4_ops.I"
#endif

View File

@ -3,23 +3,119 @@
//
////////////////////////////////////////////////////////////////////
#include "nearly_zero.h"
////////////////////////////////////////////////////////////////////
// Class : LVecBase2
// Description : This is the base class for all two-component
// vectors and points.
////////////////////////////////////////////////////////////////////
#include <notify.h>
#include <datagram.h>
#include <datagramIterator.h>
class EXPCL_PANDA FLOATNAME(LVecBase2) {
PUBLISHED:
typedef const FLOATTYPE1 *iterator;
typedef const FLOATTYPE1 *const_iterator;
template<class NumType>
TypeHandle LVecBase2<NumType>::_type_handle;
INLINE FLOATNAME(LVecBase2)();
INLINE FLOATNAME(LVecBase2)(const FLOATNAME(LVecBase2) &copy);
INLINE FLOATNAME(LVecBase2) &operator = (const FLOATNAME(LVecBase2) &copy);
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;
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase2::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType>::
LVecBase2() {
INLINE FLOATNAME(LVecBase2)::
FLOATNAME(LVecBase2)() {
}
////////////////////////////////////////////////////////////////////
@ -27,9 +123,9 @@ LVecBase2() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType>::
LVecBase2(const LVecBase2<NumType> &copy) {
INLINE FLOATNAME(LVecBase2)::
FLOATNAME(LVecBase2)(const FLOATNAME(LVecBase2) &copy) {
(*this) = copy;
}
@ -38,9 +134,9 @@ LVecBase2(const LVecBase2<NumType> &copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType> &LVecBase2<NumType>::
operator = (const LVecBase2<NumType> &copy) {
INLINE FLOATNAME(LVecBase2) &FLOATNAME(LVecBase2)::
operator = (const FLOATNAME(LVecBase2) &copy) {
set(copy[0], copy[1]);
return *this;
}
@ -50,9 +146,9 @@ operator = (const LVecBase2<NumType> &copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType> &LVecBase2<NumType>::
operator = (NumType fill_value) {
INLINE FLOATNAME(LVecBase2) &FLOATNAME(LVecBase2)::
operator = (FLOATTYPE1 fill_value) {
fill(fill_value);
return *this;
}
@ -62,9 +158,9 @@ operator = (NumType fill_value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType>::
LVecBase2(NumType fill_value) {
INLINE FLOATNAME(LVecBase2)::
FLOATNAME(LVecBase2)(FLOATTYPE1 fill_value) {
fill(fill_value);
}
@ -73,9 +169,9 @@ LVecBase2(NumType fill_value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType>::
LVecBase2(NumType x, NumType y) {
INLINE FLOATNAME(LVecBase2)::
FLOATNAME(LVecBase2)(FLOATTYPE1 x, FLOATTYPE1 y) {
set(x, y);
}
@ -84,10 +180,10 @@ LVecBase2(NumType x, NumType y) {
// Access: Public
// Description: Returns a zero-length vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType> LVecBase2<NumType>::
INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2)::
zero() {
return LVecBase2<NumType>(0.0, 0.0);
return FLOATNAME(LVecBase2)(0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -95,10 +191,10 @@ zero() {
// Access: Public
// Description: Returns a unit X vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType> LVecBase2<NumType>::
INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2)::
unit_x() {
return LVecBase2<NumType>(1.0, 0.0);
return FLOATNAME(LVecBase2)(1.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -106,10 +202,10 @@ unit_x() {
// Access: Public
// Description: Returns a unit Y vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType> LVecBase2<NumType>::
INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2)::
unit_y() {
return LVecBase2<NumType>(0.0, 1.0);
return FLOATNAME(LVecBase2)(0.0, 1.0);
}
////////////////////////////////////////////////////////////////////
@ -117,9 +213,9 @@ unit_y() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType>::
~LVecBase2() {
INLINE FLOATNAME(LVecBase2)::
~FLOATNAME(LVecBase2)() {
}
////////////////////////////////////////////////////////////////////
@ -127,8 +223,8 @@ INLINE LVecBase2<NumType>::
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase2<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVecBase2)::
operator [](int i) const {
nassertr(i >= 0 && i < 2, 0);
return _data[i];
@ -139,8 +235,8 @@ operator [](int i) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType &LVecBase2<NumType>::
INLINE FLOATTYPE1 &FLOATNAME(LVecBase2)::
operator [](int i) {
nassertr(i >= 0 && i < 2, _data[0]);
return _data[i];
@ -152,8 +248,8 @@ operator [](int i) {
// Description: Returns true if any component of the vector is
// not-a-number, false otherwise.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase2<NumType>::
INLINE bool FLOATNAME(LVecBase2)::
is_nan() const {
return cnan(_data[0]) || cnan(_data[1]);
}
@ -163,8 +259,8 @@ is_nan() const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase2<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVecBase2)::
get_cell(int i) const {
nassertr(i >= 0 && i < 2, 0);
return _data[i];
@ -175,8 +271,8 @@ get_cell(int i) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase2<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVecBase2)::
get_x() const {
return _data[0];
}
@ -186,8 +282,8 @@ get_x() const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase2<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVecBase2)::
get_y() const {
return _data[1];
}
@ -197,9 +293,9 @@ get_y() const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase2<NumType>::
set_cell(int i, NumType value) {
INLINE void FLOATNAME(LVecBase2)::
set_cell(int i, FLOATTYPE1 value) {
nassertv(i >= 0 && i < 2);
_data[i] = value;
}
@ -209,9 +305,9 @@ set_cell(int i, NumType value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase2<NumType>::
set_x(NumType value) {
INLINE void FLOATNAME(LVecBase2)::
set_x(FLOATTYPE1 value) {
_data[0] = value;
}
@ -220,9 +316,9 @@ set_x(NumType value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase2<NumType>::
set_y(NumType value) {
INLINE void FLOATNAME(LVecBase2)::
set_y(FLOATTYPE1 value) {
_data[1] = value;
}
@ -233,8 +329,8 @@ set_y(NumType value) {
// elements in the vector. The next element
// occupies the next position consecutively in memory.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE const NumType *LVecBase2<NumType>::
INLINE const FLOATTYPE1 *FLOATNAME(LVecBase2)::
get_data() const {
return _data;
}
@ -244,8 +340,8 @@ get_data() const {
// Access: Public
// Description: Returns the number of elements in the vector, two.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE int LVecBase2<NumType>::
INLINE int FLOATNAME(LVecBase2)::
get_num_components() const {
return 2;
}
@ -256,8 +352,8 @@ get_num_components() const {
// Description: Returns an iterator that may be used to traverse the
// elements of the matrix, STL-style.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType>::iterator LVecBase2<NumType>::
INLINE FLOATNAME(LVecBase2)::iterator FLOATNAME(LVecBase2)::
begin() {
return _data;
}
@ -268,8 +364,8 @@ begin() {
// Description: Returns an iterator that may be used to traverse the
// elements of the matrix, STL-style.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType>::iterator LVecBase2<NumType>::
INLINE FLOATNAME(LVecBase2)::iterator FLOATNAME(LVecBase2)::
end() {
return begin() + get_num_components();
}
@ -280,8 +376,8 @@ end() {
// Description: Returns an iterator that may be used to traverse the
// elements of the matrix, STL-style.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType>::const_iterator LVecBase2<NumType>::
INLINE FLOATNAME(LVecBase2)::const_iterator FLOATNAME(LVecBase2)::
begin() const {
return _data;
}
@ -292,8 +388,8 @@ begin() const {
// Description: Returns an iterator that may be used to traverse the
// elements of the matrix, STL-style.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType>::const_iterator LVecBase2<NumType>::
INLINE FLOATNAME(LVecBase2)::const_iterator FLOATNAME(LVecBase2)::
end() const {
return begin() + get_num_components();
}
@ -305,9 +401,9 @@ end() const {
// fill_value. This is particularly useful for
// initializing to zero.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase2<NumType>::
fill(NumType fill_value) {
INLINE void FLOATNAME(LVecBase2)::
fill(FLOATTYPE1 fill_value) {
_data[0] = fill_value;
_data[1] = fill_value;
}
@ -317,9 +413,9 @@ fill(NumType fill_value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase2<NumType>::
set(NumType x, NumType y) {
INLINE void FLOATNAME(LVecBase2)::
set(FLOATTYPE1 x, FLOATTYPE1 y) {
_data[0] = x;
_data[1] = y;
}
@ -329,9 +425,9 @@ set(NumType x, NumType y) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase2<NumType>::
dot(const LVecBase2<NumType> &other) const {
INLINE FLOATTYPE1 FLOATNAME(LVecBase2)::
dot(const FLOATNAME(LVecBase2) &other) const {
return _data[0] * other[0] + _data[1] * other[1];
}
@ -344,9 +440,9 @@ dot(const LVecBase2<NumType> &other) const {
// especially in an STL container. Also see
// compare_to().
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase2<NumType>::
operator < (const LVecBase2<NumType> &other) const {
INLINE bool FLOATNAME(LVecBase2)::
operator < (const FLOATNAME(LVecBase2) &other) const {
return (compare_to(other) < 0);
}
@ -355,9 +451,9 @@ operator < (const LVecBase2<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase2<NumType>::
operator == (const LVecBase2<NumType> &other) const {
INLINE bool FLOATNAME(LVecBase2)::
operator == (const FLOATNAME(LVecBase2) &other) const {
return (_data[0] == other[0] &&
_data[1] == other[1]);
}
@ -367,9 +463,9 @@ operator == (const LVecBase2<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase2<NumType>::
operator != (const LVecBase2<NumType> &other) const {
INLINE bool FLOATNAME(LVecBase2)::
operator != (const FLOATNAME(LVecBase2) &other) const {
return !operator == (other);
}
@ -379,10 +475,10 @@ operator != (const LVecBase2<NumType> &other) const {
// Description: This flavor of compare_to uses a default threshold
// value based on the numeric type.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE int LVecBase2<NumType>::
compare_to(const LVecBase2<NumType> &other) const {
return compare_to(other, NEARLY_ZERO(NumType));
INLINE int FLOATNAME(LVecBase2)::
compare_to(const FLOATNAME(LVecBase2) &other) const {
return compare_to(other, NEARLY_ZERO(FLOATTYPE1));
}
////////////////////////////////////////////////////////////////////
@ -394,9 +490,9 @@ compare_to(const LVecBase2<NumType> &other) const {
// after, 0 if they are equivalent (within the indicated
// tolerance).
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE int LVecBase2<NumType>::
compare_to(const LVecBase2<NumType> &other, NumType threshold) const {
INLINE int FLOATNAME(LVecBase2)::
compare_to(const FLOATNAME(LVecBase2) &other, FLOATTYPE1 threshold) const {
if (!IS_THRESHOLD_EQUAL(_data[0], other[0], threshold)) {
return (_data[0] < other[0]) ? -1 : 1;
}
@ -411,10 +507,10 @@ compare_to(const LVecBase2<NumType> &other, NumType threshold) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType> LVecBase2<NumType>::
INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2)::
operator - () const {
return LVecBase2<NumType>(-_data[0], -_data[1]);
return FLOATNAME(LVecBase2)(-_data[0], -_data[1]);
}
////////////////////////////////////////////////////////////////////
@ -422,10 +518,10 @@ operator - () const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType> LVecBase2<NumType>::
operator + (const LVecBase2<NumType> &other) const {
return LVecBase2<NumType>(_data[0] + other[0],
INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2)::
operator + (const FLOATNAME(LVecBase2) &other) const {
return FLOATNAME(LVecBase2)(_data[0] + other[0],
_data[1] + other[1]);
}
@ -434,10 +530,10 @@ operator + (const LVecBase2<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType> LVecBase2<NumType>::
operator - (const LVecBase2<NumType> &other) const {
return LVecBase2<NumType>(_data[0] - other[0],
INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2)::
operator - (const FLOATNAME(LVecBase2) &other) const {
return FLOATNAME(LVecBase2)(_data[0] - other[0],
_data[1] - other[1]);
}
@ -446,10 +542,10 @@ operator - (const LVecBase2<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType> LVecBase2<NumType>::
operator * (NumType scalar) const {
return LVecBase2<NumType>(_data[0] * scalar,
INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2)::
operator * (FLOATTYPE1 scalar) const {
return FLOATNAME(LVecBase2)(_data[0] * scalar,
_data[1] * scalar);
}
@ -458,10 +554,10 @@ operator * (NumType scalar) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType> LVecBase2<NumType>::
operator / (NumType scalar) const {
return LVecBase2<NumType>(_data[0] / scalar,
INLINE FLOATNAME(LVecBase2) FLOATNAME(LVecBase2)::
operator / (FLOATTYPE1 scalar) const {
return FLOATNAME(LVecBase2)(_data[0] / scalar,
_data[1] / scalar);
}
@ -470,9 +566,9 @@ operator / (NumType scalar) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase2<NumType>::
operator += (const LVecBase2<NumType> &other) {
INLINE void FLOATNAME(LVecBase2)::
operator += (const FLOATNAME(LVecBase2) &other) {
_data[0] += other[0];
_data[1] += other[1];
}
@ -482,9 +578,9 @@ operator += (const LVecBase2<NumType> &other) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase2<NumType>::
operator -= (const LVecBase2<NumType> &other) {
INLINE void FLOATNAME(LVecBase2)::
operator -= (const FLOATNAME(LVecBase2) &other) {
_data[0] -= other[0];
_data[1] -= other[1];
}
@ -494,9 +590,9 @@ operator -= (const LVecBase2<NumType> &other) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase2<NumType>::
operator *= (NumType scalar) {
INLINE void FLOATNAME(LVecBase2)::
operator *= (FLOATTYPE1 scalar) {
_data[0] *= scalar;
_data[1] *= scalar;
}
@ -506,9 +602,9 @@ operator *= (NumType scalar) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase2<NumType>::
operator /= (NumType scalar) {
INLINE void FLOATNAME(LVecBase2)::
operator /= (FLOATTYPE1 scalar) {
_data[0] /= scalar;
_data[1] /= scalar;
}
@ -519,9 +615,9 @@ operator /= (NumType scalar) {
// Description: Returns true if two vectors are memberwise equal
// within a specified tolerance.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase2<NumType>::
almost_equal(const LVecBase2<NumType> &other, NumType threshold) const {
INLINE bool FLOATNAME(LVecBase2)::
almost_equal(const FLOATNAME(LVecBase2) &other, FLOATTYPE1 threshold) const {
return (IS_THRESHOLD_EQUAL(_data[0], other[0], threshold) &&
IS_THRESHOLD_EQUAL(_data[1], other[1], threshold));
}
@ -532,10 +628,10 @@ almost_equal(const LVecBase2<NumType> &other, NumType threshold) const {
// Description: Returns true if two vectors are memberwise equal
// within a default tolerance based on the numeric type.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase2<NumType>::
almost_equal(const LVecBase2<NumType> &other) const {
return almost_equal(other, NEARLY_ZERO(NumType));
INLINE bool FLOATNAME(LVecBase2)::
almost_equal(const FLOATNAME(LVecBase2) &other) const {
return almost_equal(other, NEARLY_ZERO(FLOATTYPE1));
}
////////////////////////////////////////////////////////////////////
@ -543,37 +639,20 @@ almost_equal(const LVecBase2<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase2<NumType>::
INLINE void FLOATNAME(LVecBase2)::
output(ostream &out) const {
out << MAYBE_ZERO(_data[0]) << " "
<< MAYBE_ZERO(_data[1]);
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase2::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void LVecBase2<NumType>::
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
////////////////////////////////////////////////////////////////////
template<class NumType>
void LVecBase2<NumType>::
INLINE void FLOATNAME(LVecBase2)::
write_datagram(Datagram &destination) const {
destination.add_float32(_data[0]);
destination.add_float32(_data[1]);
@ -584,21 +663,12 @@ write_datagram(Datagram &destination) const {
// Access: Public
// Description: Function to read itself from a datagramIterator
////////////////////////////////////////////////////////////////////
template<class NumType>
void LVecBase2<NumType>::
INLINE void FLOATNAME(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<class NumType, class NumType2>
INLINE LVecBase2<NumType2>
lcast_to(NumType2 *, const LVecBase2<NumType> &source) {
return LVecBase2<NumType2>(source[0], source[1]);
}

View File

@ -0,0 +1,13 @@
// Filename: lvecBase2.cxx
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
#include "lvecBase2.h"
#include "fltnames.I"
#include "lvecBase2_src.I"
#include "dblnames.I"
#include "lvecBase2_src.I"

View File

@ -7,129 +7,40 @@
#define LVECBASE2_H
#include <pandabase.h>
#include "cmath.h"
#include <typeHandle.h>
#include <notify.h>
#include <datagram.h>
#include <datagramIterator.h>
#include "cmath.h"
#include "nearly_zero.h"
class Datagram;
class DatagramIterator;
#include "fltnames.I"
#include "lvecBase2.I"
#include "dblnames.I"
#include "lvecBase2.I"
////////////////////////////////////////////////////////////////////
// Class : LVecBase2
// Description : This is the base class for all two-component
// vectors and points.
// Function: lcast_to
// Description: Converts a vector from one numeric representation to
// another one. This is usually invoked using the macro
// LCAST.
////////////////////////////////////////////////////////////////////
template<class NumType>
class LVecBase2 {
PUBLISHED:
typedef const NumType *iterator;
typedef const NumType *const_iterator;
INLINE FLOATNAME2(LVecBase2)
lcast_to(FLOATTYPE2 *, const FLOATNAME(LVecBase2) &source) {
return FLOATNAME2(LVecBase2)(source[0], source[1]);
}
INLINE LVecBase2();
INLINE LVecBase2(const LVecBase2<NumType> &copy);
INLINE LVecBase2<NumType> &operator = (const LVecBase2<NumType> &copy);
INLINE LVecBase2<NumType> &operator = (NumType fill_value);
INLINE LVecBase2(NumType fill_value);
INLINE LVecBase2(NumType x, NumType y);
INLINE static LVecBase2<NumType> zero();
INLINE static LVecBase2<NumType> unit_x();
INLINE static LVecBase2<NumType> 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<NumType> &other) const;
INLINE bool operator < (const LVecBase2<NumType> &other) const;
INLINE bool operator == (const LVecBase2<NumType> &other) const;
INLINE bool operator != (const LVecBase2<NumType> &other) const;
INLINE int compare_to(const LVecBase2<NumType> &other) const;
INLINE int compare_to(const LVecBase2<NumType> &other,
NumType threshold) const;
INLINE LVecBase2<NumType>
operator - () const;
INLINE LVecBase2<NumType>
operator + (const LVecBase2<NumType> &other) const;
INLINE LVecBase2<NumType>
operator - (const LVecBase2<NumType> &other) const;
INLINE LVecBase2<NumType> operator * (NumType scalar) const;
INLINE LVecBase2<NumType> operator / (NumType scalar) const;
INLINE void operator += (const LVecBase2<NumType> &other);
INLINE void operator -= (const LVecBase2<NumType> &other);
INLINE void operator *= (NumType scalar);
INLINE void operator /= (NumType scalar);
INLINE bool almost_equal(const LVecBase2<NumType> &other,
NumType threshold) const;
INLINE bool almost_equal(const LVecBase2<NumType> &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<class NumType>
INLINE ostream &operator << (ostream &out, const LVecBase2<NumType> &vec) {
vec.output(out);
return out;
#include "fltnames.I"
INLINE FLOATNAME2(LVecBase2)
lcast_to(FLOATTYPE2 *, const FLOATNAME(LVecBase2) &source) {
return FLOATNAME2(LVecBase2)(source[0], source[1]);
}
// Cast to a different numeric type
template<class NumType, class NumType2>
INLINE LVecBase2<NumType2>
lcast_to(NumType2 *type, const LVecBase2<NumType> &source);
#include "lvecBase2.I"
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVecBase2<float>)
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVecBase2<double>)
#endif

View File

@ -0,0 +1,23 @@
// Filename: lvecBase2.I
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
TypeHandle FLOATNAME(LVecBase2)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LVecBase2::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
void FLOATNAME(LVecBase2)::
init_type() {
if (_type_handle == TypeHandle::none()) {
// Format a string to describe the type.
do_init_type(FLOATTYPE1);
string name =
"LVecBase2<" + get_type_handle(FLOATTYPE1).get_name() + ">";
register_type(_type_handle, name);
}
}

View File

@ -3,23 +3,125 @@
//
////////////////////////////////////////////////////////////////////
#include "nearly_zero.h"
////////////////////////////////////////////////////////////////////
// Class : LVecBase3
// Description : This is the base class for all three-component
// vectors and points.
////////////////////////////////////////////////////////////////////
#include <notify.h>
#include <datagram.h>
#include <datagramIterator.h>
class EXPCL_PANDA FLOATNAME(LVecBase3) {
PUBLISHED:
typedef const FLOATTYPE1 *iterator;
typedef const FLOATTYPE1 *const_iterator;
template<class NumType>
TypeHandle LVecBase3<NumType>::_type_handle;
INLINE FLOATNAME(LVecBase3)();
INLINE FLOATNAME(LVecBase3)(const FLOATNAME(LVecBase3) &copy);
INLINE FLOATNAME(LVecBase3) &operator = (const FLOATNAME(LVecBase3) &copy);
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;
};
////////////////////////////////////////////////////////////////////
// Function: LVecBase3::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType>::
LVecBase3() {
INLINE FLOATNAME(LVecBase3)::
FLOATNAME(LVecBase3)() {
}
////////////////////////////////////////////////////////////////////
@ -27,9 +129,9 @@ LVecBase3() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType>::
LVecBase3(const LVecBase3<NumType> &copy) {
INLINE FLOATNAME(LVecBase3)::
FLOATNAME(LVecBase3)(const FLOATNAME(LVecBase3) &copy) {
(*this) = copy;
}
@ -38,9 +140,9 @@ LVecBase3(const LVecBase3<NumType> &copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> &LVecBase3<NumType>::
operator = (const LVecBase3<NumType> &copy) {
INLINE FLOATNAME(LVecBase3) &FLOATNAME(LVecBase3)::
operator = (const FLOATNAME(LVecBase3) &copy) {
set(copy[0], copy[1], copy[2]);
return *this;
}
@ -50,9 +152,9 @@ operator = (const LVecBase3<NumType> &copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> &LVecBase3<NumType>::
operator = (NumType fill_value) {
INLINE FLOATNAME(LVecBase3) &FLOATNAME(LVecBase3)::
operator = (FLOATTYPE1 fill_value) {
fill(fill_value);
return *this;
}
@ -62,9 +164,9 @@ operator = (NumType fill_value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType>::
LVecBase3(NumType fill_value) {
INLINE FLOATNAME(LVecBase3)::
FLOATNAME(LVecBase3)(FLOATTYPE1 fill_value) {
fill(fill_value);
}
@ -73,9 +175,9 @@ LVecBase3(NumType fill_value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType>::
LVecBase3(NumType x, NumType y, NumType z) {
INLINE FLOATNAME(LVecBase3)::
FLOATNAME(LVecBase3)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z) {
set(x, y, z);
}
@ -84,10 +186,10 @@ LVecBase3(NumType x, NumType y, NumType z) {
// Access: Public
// Description: Returns a zero-length vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> LVecBase3<NumType>::
INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3)::
zero() {
return LVecBase3<NumType>(0.0, 0.0, 0.0);
return FLOATNAME(LVecBase3)(0.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -95,10 +197,10 @@ zero() {
// Access: Public
// Description: Returns a unit X vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> LVecBase3<NumType>::
INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3)::
unit_x() {
return LVecBase3<NumType>(1.0, 0.0, 0.0);
return FLOATNAME(LVecBase3)(1.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -106,10 +208,10 @@ unit_x() {
// Access: Public
// Description: Returns a unit Y vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> LVecBase3<NumType>::
INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3)::
unit_y() {
return LVecBase3<NumType>(0.0, 1.0, 0.0);
return FLOATNAME(LVecBase3)(0.0, 1.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -117,10 +219,10 @@ unit_y() {
// Access: Public
// Description: Returns a unit Z vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> LVecBase3<NumType>::
INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3)::
unit_z() {
return LVecBase3<NumType>(0.0, 0.0, 1.0);
return FLOATNAME(LVecBase3)(0.0, 0.0, 1.0);
}
////////////////////////////////////////////////////////////////////
@ -128,9 +230,9 @@ unit_z() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType>::
~LVecBase3() {
INLINE FLOATNAME(LVecBase3)::
~FLOATNAME(LVecBase3)() {
}
////////////////////////////////////////////////////////////////////
@ -138,8 +240,8 @@ INLINE LVecBase3<NumType>::
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase3<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVecBase3)::
operator [](int i) const {
nassertr(i >= 0 && i < 3, 0);
return _data[i];
@ -150,8 +252,8 @@ operator [](int i) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType &LVecBase3<NumType>::
INLINE FLOATTYPE1 &FLOATNAME(LVecBase3)::
operator [](int i) {
nassertr(i >= 0 && i < 3, _data[0]);
return _data[i];
@ -163,8 +265,8 @@ operator [](int i) {
// Description: Returns true if any component of the vector is
// not-a-number, false otherwise.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase3<NumType>::
INLINE bool FLOATNAME(LVecBase3)::
is_nan() const {
return cnan(_data[0]) || cnan(_data[1]) || cnan(_data[2]);
}
@ -174,8 +276,8 @@ is_nan() const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase3<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVecBase3)::
get_cell(int i) const {
nassertr(i >= 0 && i < 3, 0);
return _data[i];
@ -186,8 +288,8 @@ get_cell(int i) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase3<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVecBase3)::
get_x() const {
return _data[0];
}
@ -197,8 +299,8 @@ get_x() const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase3<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVecBase3)::
get_y() const {
return _data[1];
}
@ -208,8 +310,8 @@ get_y() const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase3<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVecBase3)::
get_z() const {
return _data[2];
}
@ -219,9 +321,9 @@ get_z() const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase3<NumType>::
set_cell(int i, NumType value) {
INLINE void FLOATNAME(LVecBase3)::
set_cell(int i, FLOATTYPE1 value) {
nassertv(i >= 0 && i < 3);
_data[i] = value;
}
@ -231,9 +333,9 @@ set_cell(int i, NumType value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase3<NumType>::
set_x(NumType value) {
INLINE void FLOATNAME(LVecBase3)::
set_x(FLOATTYPE1 value) {
_data[0] = value;
}
@ -242,9 +344,9 @@ set_x(NumType value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase3<NumType>::
set_y(NumType value) {
INLINE void FLOATNAME(LVecBase3)::
set_y(FLOATTYPE1 value) {
_data[1] = value;
}
@ -253,9 +355,9 @@ set_y(NumType value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase3<NumType>::
set_z(NumType value) {
INLINE void FLOATNAME(LVecBase3)::
set_z(FLOATTYPE1 value) {
_data[2] = value;
}
@ -266,8 +368,8 @@ set_z(NumType value) {
// elements in the vector. The remaining elements
// occupy the next positions consecutively in memory.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE const NumType *LVecBase3<NumType>::
INLINE const FLOATTYPE1 *FLOATNAME(LVecBase3)::
get_data() const {
return _data;
}
@ -277,8 +379,8 @@ get_data() const {
// Access: Public
// Description: Returns the number of elements in the vector, three.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE int LVecBase3<NumType>::
INLINE int FLOATNAME(LVecBase3)::
get_num_components() const {
return 3;
}
@ -289,8 +391,8 @@ get_num_components() const {
// Description: Returns an iterator that may be used to traverse the
// elements of the matrix, STL-style.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType>::iterator LVecBase3<NumType>::
INLINE FLOATNAME(LVecBase3)::iterator FLOATNAME(LVecBase3)::
begin() {
return _data;
}
@ -301,8 +403,8 @@ begin() {
// Description: Returns an iterator that may be used to traverse the
// elements of the matrix, STL-style.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType>::iterator LVecBase3<NumType>::
INLINE FLOATNAME(LVecBase3)::iterator FLOATNAME(LVecBase3)::
end() {
return begin() + get_num_components();
}
@ -313,8 +415,8 @@ end() {
// Description: Returns an iterator that may be used to traverse the
// elements of the matrix, STL-style.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType>::const_iterator LVecBase3<NumType>::
INLINE FLOATNAME(LVecBase3)::const_iterator FLOATNAME(LVecBase3)::
begin() const {
return _data;
}
@ -325,8 +427,8 @@ begin() const {
// Description: Returns an iterator that may be used to traverse the
// elements of the matrix, STL-style.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType>::const_iterator LVecBase3<NumType>::
INLINE FLOATNAME(LVecBase3)::const_iterator FLOATNAME(LVecBase3)::
end() const {
return begin() + get_num_components();
}
@ -338,9 +440,9 @@ end() const {
// fill_value. This is particularly useful for
// initializing to zero.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase3<NumType>::
fill(NumType fill_value) {
INLINE void FLOATNAME(LVecBase3)::
fill(FLOATTYPE1 fill_value) {
_data[0] = fill_value;
_data[1] = fill_value;
_data[2] = fill_value;
@ -351,9 +453,9 @@ fill(NumType fill_value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase3<NumType>::
set(NumType x, NumType y, NumType z) {
INLINE void FLOATNAME(LVecBase3)::
set(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z) {
_data[0] = x;
_data[1] = y;
_data[2] = z;
@ -364,9 +466,9 @@ set(NumType x, NumType y, NumType z) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase3<NumType>::
dot(const LVecBase3<NumType> &other) const {
INLINE FLOATTYPE1 FLOATNAME(LVecBase3)::
dot(const FLOATNAME(LVecBase3) &other) const {
return _data[0] * other[0] + _data[1] * other[1] + _data[2] * other[2];
}
@ -375,10 +477,10 @@ dot(const LVecBase3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> LVecBase3<NumType>::
cross(const LVecBase3<NumType> &other) const {
return LVecBase3<NumType>(_data[1] * other[2] - other[1] * _data[2],
INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3)::
cross(const FLOATNAME(LVecBase3) &other) const {
return FLOATNAME(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]);
}
@ -392,9 +494,9 @@ cross(const LVecBase3<NumType> &other) const {
// especially in an STL container. Also see
// compare_to().
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase3<NumType>::
operator < (const LVecBase3<NumType> &other) const {
INLINE bool FLOATNAME(LVecBase3)::
operator < (const FLOATNAME(LVecBase3) &other) const {
return (compare_to(other) < 0);
}
@ -403,9 +505,9 @@ operator < (const LVecBase3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase3<NumType>::
operator == (const LVecBase3<NumType> &other) const {
INLINE bool FLOATNAME(LVecBase3)::
operator == (const FLOATNAME(LVecBase3) &other) const {
return (_data[0] == other[0] &&
_data[1] == other[1] &&
_data[2] == other[2]);
@ -416,9 +518,9 @@ operator == (const LVecBase3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase3<NumType>::
operator != (const LVecBase3<NumType> &other) const {
INLINE bool FLOATNAME(LVecBase3)::
operator != (const FLOATNAME(LVecBase3) &other) const {
return !operator == (other);
}
@ -428,10 +530,10 @@ operator != (const LVecBase3<NumType> &other) const {
// Description: This flavor of compare_to uses a default threshold
// value based on the numeric type.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE int LVecBase3<NumType>::
compare_to(const LVecBase3<NumType> &other) const {
return compare_to(other, NEARLY_ZERO(NumType));
INLINE int FLOATNAME(LVecBase3)::
compare_to(const FLOATNAME(LVecBase3) &other) const {
return compare_to(other, NEARLY_ZERO(FLOATTYPE1));
}
////////////////////////////////////////////////////////////////////
@ -443,9 +545,9 @@ compare_to(const LVecBase3<NumType> &other) const {
// after, 0 if they are equivalent (within the indicated
// tolerance).
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE int LVecBase3<NumType>::
compare_to(const LVecBase3<NumType> &other, NumType threshold) const {
INLINE int FLOATNAME(LVecBase3)::
compare_to(const FLOATNAME(LVecBase3) &other, FLOATTYPE1 threshold) const {
if (!IS_THRESHOLD_EQUAL(_data[0], other[0], threshold)) {
return (_data[0] < other[0]) ? -1 : 1;
}
@ -463,10 +565,10 @@ compare_to(const LVecBase3<NumType> &other, NumType threshold) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> LVecBase3<NumType>::
INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3)::
operator - () const {
return LVecBase3<NumType>(-_data[0], -_data[1], -_data[2]);
return FLOATNAME(LVecBase3)(-_data[0], -_data[1], -_data[2]);
}
////////////////////////////////////////////////////////////////////
@ -474,10 +576,10 @@ operator - () const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> LVecBase3<NumType>::
operator + (const LVecBase3<NumType> &other) const {
return LVecBase3<NumType>(_data[0] + other[0],
INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3)::
operator + (const FLOATNAME(LVecBase3) &other) const {
return FLOATNAME(LVecBase3)(_data[0] + other[0],
_data[1] + other[1],
_data[2] + other[2]);
}
@ -487,10 +589,10 @@ operator + (const LVecBase3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> LVecBase3<NumType>::
operator - (const LVecBase3<NumType> &other) const {
return LVecBase3<NumType>(_data[0] - other[0],
INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3)::
operator - (const FLOATNAME(LVecBase3) &other) const {
return FLOATNAME(LVecBase3)(_data[0] - other[0],
_data[1] - other[1],
_data[2] - other[2]);
}
@ -500,10 +602,10 @@ operator - (const LVecBase3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> LVecBase3<NumType>::
operator * (NumType scalar) const {
return LVecBase3<NumType>(_data[0] * scalar,
INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3)::
operator * (FLOATTYPE1 scalar) const {
return FLOATNAME(LVecBase3)(_data[0] * scalar,
_data[1] * scalar,
_data[2] * scalar);
}
@ -513,10 +615,10 @@ operator * (NumType scalar) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> LVecBase3<NumType>::
operator / (NumType scalar) const {
return LVecBase3<NumType>(_data[0] / scalar,
INLINE FLOATNAME(LVecBase3) FLOATNAME(LVecBase3)::
operator / (FLOATTYPE1 scalar) const {
return FLOATNAME(LVecBase3)(_data[0] / scalar,
_data[1] / scalar,
_data[2] / scalar);
}
@ -526,9 +628,9 @@ operator / (NumType scalar) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase3<NumType>::
operator += (const LVecBase3<NumType> &other) {
INLINE void FLOATNAME(LVecBase3)::
operator += (const FLOATNAME(LVecBase3) &other) {
_data[0] += other[0];
_data[1] += other[1];
_data[2] += other[2];
@ -539,9 +641,9 @@ operator += (const LVecBase3<NumType> &other) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase3<NumType>::
operator -= (const LVecBase3<NumType> &other) {
INLINE void FLOATNAME(LVecBase3)::
operator -= (const FLOATNAME(LVecBase3) &other) {
_data[0] -= other[0];
_data[1] -= other[1];
_data[2] -= other[2];
@ -552,9 +654,9 @@ operator -= (const LVecBase3<NumType> &other) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase3<NumType>::
operator *= (NumType scalar) {
INLINE void FLOATNAME(LVecBase3)::
operator *= (FLOATTYPE1 scalar) {
_data[0] *= scalar;
_data[1] *= scalar;
_data[2] *= scalar;
@ -565,9 +667,9 @@ operator *= (NumType scalar) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase3<NumType>::
operator /= (NumType scalar) {
INLINE void FLOATNAME(LVecBase3)::
operator /= (FLOATTYPE1 scalar) {
_data[0] /= scalar;
_data[1] /= scalar;
_data[2] /= scalar;
@ -578,9 +680,9 @@ operator /= (NumType scalar) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase3<NumType>::
cross_into(const LVecBase3<NumType> &other) {
INLINE void FLOATNAME(LVecBase3)::
cross_into(const FLOATNAME(LVecBase3) &other) {
(*this) = cross(other);
}
@ -590,9 +692,9 @@ cross_into(const LVecBase3<NumType> &other) {
// Description: Returns true if two vectors are memberwise equal
// within a specified tolerance.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase3<NumType>::
almost_equal(const LVecBase3<NumType> &other, NumType threshold) const {
INLINE bool FLOATNAME(LVecBase3)::
almost_equal(const FLOATNAME(LVecBase3) &other, FLOATTYPE1 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));
@ -604,10 +706,10 @@ almost_equal(const LVecBase3<NumType> &other, NumType threshold) const {
// Description: Returns true if two vectors are memberwise equal
// within a default tolerance based on the numeric type.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase3<NumType>::
almost_equal(const LVecBase3<NumType> &other) const {
return almost_equal(other, NEARLY_ZERO(NumType));
INLINE bool FLOATNAME(LVecBase3)::
almost_equal(const FLOATNAME(LVecBase3) &other) const {
return almost_equal(other, NEARLY_ZERO(FLOATTYPE1));
}
////////////////////////////////////////////////////////////////////
@ -615,38 +717,22 @@ almost_equal(const LVecBase3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase3<NumType>::
INLINE void FLOATNAME(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<class NumType>
void LVecBase3<NumType>::
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
////////////////////////////////////////////////////////////////////
template<class NumType>
void LVecBase3<NumType>::
INLINE void FLOATNAME(LVecBase3)::
write_datagram(Datagram &destination) const {
destination.add_float32(_data[0]);
destination.add_float32(_data[1]);
@ -658,23 +744,11 @@ write_datagram(Datagram &destination) const {
// Access: Public
// Description: Function to read itself from a datagramIterator
////////////////////////////////////////////////////////////////////
template<class NumType>
void LVecBase3<NumType>::
INLINE void FLOATNAME(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<class NumType, class NumType2>
INLINE LVecBase3<NumType2>
lcast_to(NumType2 *, const LVecBase3<NumType> &source) {
return LVecBase3<NumType2>(source[0], source[1], source[2]);
}

View File

@ -0,0 +1,13 @@
// Filename: lvecBase3.cxx
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
#include "lvecBase3.h"
#include "fltnames.I"
#include "lvecBase3_src.I"
#include "dblnames.I"
#include "lvecBase3_src.I"

View File

@ -7,135 +7,37 @@
#define LVECBASE3_H
#include <pandabase.h>
#include "cmath.h"
#include <typeHandle.h>
#include <notify.h>
#include <datagram.h>
#include <datagramIterator.h>
#include "cmath.h"
#include "nearly_zero.h"
class Datagram;
class DatagramIterator;
////////////////////////////////////////////////////////////////////
// Class : LVecBase3
// Description : This is the base class for all three-component
// vectors and points.
////////////////////////////////////////////////////////////////////
template<class NumType>
class LVecBase3 {
PUBLISHED:
typedef const NumType *iterator;
typedef const NumType *const_iterator;
INLINE LVecBase3();
INLINE LVecBase3(const LVecBase3<NumType> &copy);
INLINE LVecBase3<NumType> &operator = (const LVecBase3<NumType> &copy);
INLINE LVecBase3<NumType> &operator = (NumType fill_value);
INLINE LVecBase3(NumType fill_value);
INLINE LVecBase3(NumType x, NumType y, NumType z);
INLINE static LVecBase3<NumType> zero();
INLINE static LVecBase3<NumType> unit_x();
INLINE static LVecBase3<NumType> unit_y();
INLINE static LVecBase3<NumType> 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<NumType> &other) const;
INLINE LVecBase3<NumType> cross(const LVecBase3<NumType> &other) const;
INLINE bool operator < (const LVecBase3<NumType> &other) const;
INLINE bool operator == (const LVecBase3<NumType> &other) const;
INLINE bool operator != (const LVecBase3<NumType> &other) const;
INLINE int compare_to(const LVecBase3<NumType> &other) const;
INLINE int compare_to(const LVecBase3<NumType> &other,
NumType threshold) const;
INLINE LVecBase3<NumType>
operator - () const;
INLINE LVecBase3<NumType>
operator + (const LVecBase3<NumType> &other) const;
INLINE LVecBase3<NumType>
operator - (const LVecBase3<NumType> &other) const;
INLINE LVecBase3<NumType> operator * (NumType scalar) const;
INLINE LVecBase3<NumType> operator / (NumType scalar) const;
INLINE void operator += (const LVecBase3<NumType> &other);
INLINE void operator -= (const LVecBase3<NumType> &other);
INLINE void operator *= (NumType scalar);
INLINE void operator /= (NumType scalar);
INLINE void cross_into(const LVecBase3<NumType> &other);
INLINE bool almost_equal(const LVecBase3<NumType> &other,
NumType threshold) const;
INLINE bool almost_equal(const LVecBase3<NumType> &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<class NumType>
INLINE ostream &operator << (ostream &out, const LVecBase3<NumType> &vec) {
vec.output(out);
return out;
}
// Cast to a different numeric type
template<class NumType, class NumType2>
INLINE LVecBase3<NumType2>
lcast_to(NumType2 *type, const LVecBase3<NumType> &source);
#include "fltnames.I"
#include "lvecBase3.I"
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVecBase3<float>)
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVecBase3<double>)
#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.
////////////////////////////////////////////////////////////////////
INLINE FLOATNAME2(LVecBase3)
lcast_to(FLOATTYPE2 *, const FLOATNAME(LVecBase3) &source) {
return FLOATNAME2(LVecBase3)(source[0], source[1], source[2]);
}
#include "fltnames.I"
INLINE FLOATNAME2(LVecBase3)
lcast_to(FLOATTYPE2 *, const FLOATNAME(LVecBase3) &source) {
return FLOATNAME2(LVecBase3)(source[0], source[1], source[2]);
}
#endif

View File

@ -0,0 +1,23 @@
// Filename: lvecBase3.I
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
TypeHandle FLOATNAME(LVecBase3)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LVecBase3::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
void FLOATNAME(LVecBase3)::
init_type() {
if (_type_handle == TypeHandle::none()) {
// Format a string to describe the type.
do_init_type(FLOATTYPE1);
string name =
"LVecBase3<" + get_type_handle(FLOATTYPE1).get_name() + ">";
register_type(_type_handle, name);
}
}

View File

@ -3,23 +3,125 @@
//
////////////////////////////////////////////////////////////////////
#include "nearly_zero.h"
////////////////////////////////////////////////////////////////////
// Class : LVecBase4
// Description : This is the base class for all three-component
// vectors and points.
////////////////////////////////////////////////////////////////////
#include <notify.h>
#include <datagram.h>
#include <datagramIterator.h>
class EXPCL_PANDA FLOATNAME(LVecBase4) {
PUBLISHED:
typedef const FLOATTYPE1 *iterator;
typedef const FLOATTYPE1 *const_iterator;
template<class NumType>
TypeHandle LVecBase4<NumType>::_type_handle;
INLINE FLOATNAME(LVecBase4)();
INLINE FLOATNAME(LVecBase4)(const FLOATNAME(LVecBase4) &copy);
INLINE FLOATNAME(LVecBase4) &operator = (const FLOATNAME(LVecBase4) &copy);
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;
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType>::
LVecBase4() {
INLINE FLOATNAME(LVecBase4)::
FLOATNAME(LVecBase4)() {
}
////////////////////////////////////////////////////////////////////
@ -27,9 +129,9 @@ LVecBase4() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType>::
LVecBase4(const LVecBase4<NumType> &copy) {
INLINE FLOATNAME(LVecBase4)::
FLOATNAME(LVecBase4)(const FLOATNAME(LVecBase4) &copy) {
(*this) = copy;
}
@ -38,9 +140,9 @@ LVecBase4(const LVecBase4<NumType> &copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> &LVecBase4<NumType>::
operator = (const LVecBase4<NumType> &copy) {
INLINE FLOATNAME(LVecBase4) &FLOATNAME(LVecBase4)::
operator = (const FLOATNAME(LVecBase4) &copy) {
set(copy[0], copy[1], copy[2], copy[3]);
return *this;
}
@ -50,9 +152,9 @@ operator = (const LVecBase4<NumType> &copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> &LVecBase4<NumType>::
operator = (NumType fill_value) {
INLINE FLOATNAME(LVecBase4) &FLOATNAME(LVecBase4)::
operator = (FLOATTYPE1 fill_value) {
fill(fill_value);
return *this;
}
@ -62,9 +164,9 @@ operator = (NumType fill_value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType>::
LVecBase4(NumType fill_value) {
INLINE FLOATNAME(LVecBase4)::
FLOATNAME(LVecBase4)(FLOATTYPE1 fill_value) {
fill(fill_value);
}
@ -73,9 +175,9 @@ LVecBase4(NumType fill_value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType>::
LVecBase4(NumType x, NumType y, NumType z, NumType w) {
INLINE FLOATNAME(LVecBase4)::
FLOATNAME(LVecBase4)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w) {
set(x, y, z, w);
}
@ -84,9 +186,9 @@ LVecBase4(NumType x, NumType y, NumType z, NumType w) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType>::
~LVecBase4() {
INLINE FLOATNAME(LVecBase4)::
~FLOATNAME(LVecBase4)() {
}
////////////////////////////////////////////////////////////////////
@ -94,10 +196,10 @@ INLINE LVecBase4<NumType>::
// Access: Public
// Description: Returns a zero-length vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> LVecBase4<NumType>::
INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4)::
zero() {
return LVecBase4<NumType>(0.0, 0.0, 0.0, 0.0);
return FLOATNAME(LVecBase4)(0.0, 0.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -105,10 +207,10 @@ zero() {
// Access: Public
// Description: Returns a unit X vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> LVecBase4<NumType>::
INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4)::
unit_x() {
return LVecBase4<NumType>(1.0, 0.0, 0.0, 0.0);
return FLOATNAME(LVecBase4)(1.0, 0.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -116,10 +218,10 @@ unit_x() {
// Access: Public
// Description: Returns a unit Y vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> LVecBase4<NumType>::
INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4)::
unit_y() {
return LVecBase4<NumType>(0.0, 1.0, 0.0, 0.0);
return FLOATNAME(LVecBase4)(0.0, 1.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -127,10 +229,10 @@ unit_y() {
// Access: Public
// Description: Returns a unit Z vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> LVecBase4<NumType>::
INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4)::
unit_z() {
return LVecBase4<NumType>(0.0, 0.0, 1.0, 0.0);
return FLOATNAME(LVecBase4)(0.0, 0.0, 1.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -138,10 +240,10 @@ unit_z() {
// Access: Public
// Description: Returns a unit W vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> LVecBase4<NumType>::
INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4)::
unit_w() {
return LVecBase4<NumType>(0.0, 0.0, 0.0, 1.0);
return FLOATNAME(LVecBase4)(0.0, 0.0, 0.0, 1.0);
}
////////////////////////////////////////////////////////////////////
@ -149,8 +251,8 @@ unit_w() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase4<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVecBase4)::
operator [](int i) const {
nassertr(i >= 0 && i < 4, 0);
return _data[i];
@ -161,8 +263,8 @@ operator [](int i) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType &LVecBase4<NumType>::
INLINE FLOATTYPE1 &FLOATNAME(LVecBase4)::
operator [](int i) {
nassertr(i >= 0 && i < 4, _data[0]);
return _data[i];
@ -174,8 +276,8 @@ operator [](int i) {
// Description: Returns true if any component of the vector is
// not-a-number, false otherwise.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase4<NumType>::
INLINE bool FLOATNAME(LVecBase4)::
is_nan() const {
return cnan(_data[0]) || cnan(_data[1]) || cnan(_data[2]) || cnan(_data[3]);
}
@ -185,8 +287,8 @@ is_nan() const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase4<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVecBase4)::
get_cell(int i) const {
nassertr(i >= 0 && i < 4, 0);
return _data[i];
@ -197,8 +299,8 @@ get_cell(int i) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase4<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVecBase4)::
get_x() const {
return _data[0];
}
@ -208,8 +310,8 @@ get_x() const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase4<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVecBase4)::
get_y() const {
return _data[1];
}
@ -219,8 +321,8 @@ get_y() const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase4<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVecBase4)::
get_z() const {
return _data[2];
}
@ -230,8 +332,8 @@ get_z() const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase4<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVecBase4)::
get_w() const {
return _data[3];
}
@ -241,9 +343,9 @@ get_w() const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase4<NumType>::
set_cell(int i, NumType value) {
INLINE void FLOATNAME(LVecBase4)::
set_cell(int i, FLOATTYPE1 value) {
nassertv(i >= 0 && i < 4);
_data[i] = value;
}
@ -253,9 +355,9 @@ set_cell(int i, NumType value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase4<NumType>::
set_x(NumType value) {
INLINE void FLOATNAME(LVecBase4)::
set_x(FLOATTYPE1 value) {
_data[0] = value;
}
@ -264,9 +366,9 @@ set_x(NumType value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase4<NumType>::
set_y(NumType value) {
INLINE void FLOATNAME(LVecBase4)::
set_y(FLOATTYPE1 value) {
_data[1] = value;
}
@ -275,9 +377,9 @@ set_y(NumType value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase4<NumType>::
set_z(NumType value) {
INLINE void FLOATNAME(LVecBase4)::
set_z(FLOATTYPE1 value) {
_data[2] = value;
}
@ -286,9 +388,9 @@ set_z(NumType value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase4<NumType>::
set_w(NumType value) {
INLINE void FLOATNAME(LVecBase4)::
set_w(FLOATTYPE1 value) {
_data[3] = value;
}
@ -299,8 +401,8 @@ set_w(NumType value) {
// elements in the vector. The remaining elements
// occupy the next positions consecutively in memory.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE const NumType *LVecBase4<NumType>::
INLINE const FLOATTYPE1 *FLOATNAME(LVecBase4)::
get_data() const {
return _data;
}
@ -310,8 +412,8 @@ get_data() const {
// Access: Public
// Description: Returns the number of elements in the vector, four.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE int LVecBase4<NumType>::
INLINE int FLOATNAME(LVecBase4)::
get_num_components() const {
return 4;
}
@ -322,8 +424,8 @@ get_num_components() const {
// Description: Returns an iterator that may be used to traverse the
// elements of the matrix, STL-style.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType>::iterator LVecBase4<NumType>::
INLINE FLOATNAME(LVecBase4)::iterator FLOATNAME(LVecBase4)::
begin() {
return _data;
}
@ -334,8 +436,8 @@ begin() {
// Description: Returns an iterator that may be used to traverse the
// elements of the matrix, STL-style.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType>::iterator LVecBase4<NumType>::
INLINE FLOATNAME(LVecBase4)::iterator FLOATNAME(LVecBase4)::
end() {
return begin() + get_num_components();
}
@ -346,8 +448,8 @@ end() {
// Description: Returns an iterator that may be used to traverse the
// elements of the matrix, STL-style.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType>::const_iterator LVecBase4<NumType>::
INLINE FLOATNAME(LVecBase4)::const_iterator FLOATNAME(LVecBase4)::
begin() const {
return _data;
}
@ -358,8 +460,8 @@ begin() const {
// Description: Returns an iterator that may be used to traverse the
// elements of the matrix, STL-style.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType>::const_iterator LVecBase4<NumType>::
INLINE FLOATNAME(LVecBase4)::const_iterator FLOATNAME(LVecBase4)::
end() const {
return begin() + get_num_components();
}
@ -371,9 +473,9 @@ end() const {
// fill_value. This is particularly useful for
// initializing to zero.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase4<NumType>::
fill(NumType fill_value) {
INLINE void FLOATNAME(LVecBase4)::
fill(FLOATTYPE1 fill_value) {
_data[0] = fill_value;
_data[1] = fill_value;
_data[2] = fill_value;
@ -385,9 +487,9 @@ fill(NumType fill_value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase4<NumType>::
set(NumType x, NumType y, NumType z, NumType w) {
INLINE void FLOATNAME(LVecBase4)::
set(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w) {
_data[0] = x;
_data[1] = y;
_data[2] = z;
@ -399,9 +501,9 @@ set(NumType x, NumType y, NumType z, NumType w) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVecBase4<NumType>::
dot(const LVecBase4<NumType> &other) const {
INLINE FLOATTYPE1 FLOATNAME(LVecBase4)::
dot(const FLOATNAME(LVecBase4) &other) const {
return
_data[0] * other[0] + _data[1] * other[1] +
_data[2] * other[2] + _data[3] * other[3];
@ -416,9 +518,9 @@ dot(const LVecBase4<NumType> &other) const {
// especially in an STL container. Also see
// compare_to().
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase4<NumType>::
operator < (const LVecBase4<NumType> &other) const {
INLINE bool FLOATNAME(LVecBase4)::
operator < (const FLOATNAME(LVecBase4) &other) const {
return (compare_to(other) < 0);
}
@ -427,9 +529,9 @@ operator < (const LVecBase4<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase4<NumType>::
operator == (const LVecBase4<NumType> &other) const {
INLINE bool FLOATNAME(LVecBase4)::
operator == (const FLOATNAME(LVecBase4) &other) const {
return (_data[0] == other[0] &&
_data[1] == other[1] &&
_data[2] == other[2] &&
@ -441,9 +543,9 @@ operator == (const LVecBase4<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase4<NumType>::
operator != (const LVecBase4<NumType> &other) const {
INLINE bool FLOATNAME(LVecBase4)::
operator != (const FLOATNAME(LVecBase4) &other) const {
return !operator == (other);
}
@ -453,10 +555,10 @@ operator != (const LVecBase4<NumType> &other) const {
// Description: This flavor of compare_to uses a default threshold
// value based on the numeric type.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE int LVecBase4<NumType>::
compare_to(const LVecBase4<NumType> &other) const {
return compare_to(other, NEARLY_ZERO(NumType));
INLINE int FLOATNAME(LVecBase4)::
compare_to(const FLOATNAME(LVecBase4) &other) const {
return compare_to(other, NEARLY_ZERO(FLOATTYPE1));
}
////////////////////////////////////////////////////////////////////
@ -468,9 +570,9 @@ compare_to(const LVecBase4<NumType> &other) const {
// after, 0 if they are equivalent (within the indicated
// tolerance).
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE int LVecBase4<NumType>::
compare_to(const LVecBase4<NumType> &other, NumType threshold) const {
INLINE int FLOATNAME(LVecBase4)::
compare_to(const FLOATNAME(LVecBase4) &other, FLOATTYPE1 threshold) const {
if (!IS_THRESHOLD_EQUAL(_data[0], other[0], threshold)) {
return (_data[0] < other[0]) ? -1 : 1;
}
@ -491,10 +593,10 @@ compare_to(const LVecBase4<NumType> &other, NumType threshold) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> LVecBase4<NumType>::
INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4)::
operator - () const {
return LVecBase4<NumType>(-_data[0], -_data[1], -_data[2], -_data[3]);
return FLOATNAME(LVecBase4)(-_data[0], -_data[1], -_data[2], -_data[3]);
}
////////////////////////////////////////////////////////////////////
@ -502,10 +604,10 @@ operator - () const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> LVecBase4<NumType>::
operator + (const LVecBase4<NumType> &other) const {
return LVecBase4<NumType>(_data[0] + other[0],
INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4)::
operator + (const FLOATNAME(LVecBase4) &other) const {
return FLOATNAME(LVecBase4)(_data[0] + other[0],
_data[1] + other[1],
_data[2] + other[2],
_data[3] + other[3]);
@ -516,10 +618,10 @@ operator + (const LVecBase4<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> LVecBase4<NumType>::
operator - (const LVecBase4<NumType> &other) const {
return LVecBase4<NumType>(_data[0] - other[0],
INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4)::
operator - (const FLOATNAME(LVecBase4) &other) const {
return FLOATNAME(LVecBase4)(_data[0] - other[0],
_data[1] - other[1],
_data[2] - other[2],
_data[3] - other[3]);
@ -530,10 +632,10 @@ operator - (const LVecBase4<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> LVecBase4<NumType>::
operator * (NumType scalar) const {
return LVecBase4<NumType>(_data[0] * scalar,
INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4)::
operator * (FLOATTYPE1 scalar) const {
return FLOATNAME(LVecBase4)(_data[0] * scalar,
_data[1] * scalar,
_data[2] * scalar,
_data[3] * scalar);
@ -544,10 +646,10 @@ operator * (NumType scalar) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> LVecBase4<NumType>::
operator / (NumType scalar) const {
return LVecBase4<NumType>(_data[0] / scalar,
INLINE FLOATNAME(LVecBase4) FLOATNAME(LVecBase4)::
operator / (FLOATTYPE1 scalar) const {
return FLOATNAME(LVecBase4)(_data[0] / scalar,
_data[1] / scalar,
_data[2] / scalar,
_data[3] / scalar);
@ -558,9 +660,9 @@ operator / (NumType scalar) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase4<NumType>::
operator += (const LVecBase4<NumType> &other) {
INLINE void FLOATNAME(LVecBase4)::
operator += (const FLOATNAME(LVecBase4) &other) {
_data[0] += other[0];
_data[1] += other[1];
_data[2] += other[2];
@ -572,9 +674,9 @@ operator += (const LVecBase4<NumType> &other) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase4<NumType>::
operator -= (const LVecBase4<NumType> &other) {
INLINE void FLOATNAME(LVecBase4)::
operator -= (const FLOATNAME(LVecBase4) &other) {
_data[0] -= other[0];
_data[1] -= other[1];
_data[2] -= other[2];
@ -586,9 +688,9 @@ operator -= (const LVecBase4<NumType> &other) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase4<NumType>::
operator *= (NumType scalar) {
INLINE void FLOATNAME(LVecBase4)::
operator *= (FLOATTYPE1 scalar) {
_data[0] *= scalar;
_data[1] *= scalar;
_data[2] *= scalar;
@ -600,9 +702,9 @@ operator *= (NumType scalar) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase4<NumType>::
operator /= (NumType scalar) {
INLINE void FLOATNAME(LVecBase4)::
operator /= (FLOATTYPE1 scalar) {
_data[0] /= scalar;
_data[1] /= scalar;
_data[2] /= scalar;
@ -615,9 +717,9 @@ operator /= (NumType scalar) {
// Description: Returns true if two vectors are memberwise equal
// within a specified tolerance.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase4<NumType>::
almost_equal(const LVecBase4<NumType> &other, NumType threshold) const {
INLINE bool FLOATNAME(LVecBase4)::
almost_equal(const FLOATNAME(LVecBase4) &other, FLOATTYPE1 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) &&
@ -630,10 +732,10 @@ almost_equal(const LVecBase4<NumType> &other, NumType threshold) const {
// Description: Returns true if two vectors are memberwise equal
// within a default tolerance based on the numeric type.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVecBase4<NumType>::
almost_equal(const LVecBase4<NumType> &other) const {
return almost_equal(other, NEARLY_ZERO(NumType));
INLINE bool FLOATNAME(LVecBase4)::
almost_equal(const FLOATNAME(LVecBase4) &other) const {
return almost_equal(other, NEARLY_ZERO(FLOATTYPE1));
}
////////////////////////////////////////////////////////////////////
@ -641,8 +743,8 @@ almost_equal(const LVecBase4<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE void LVecBase4<NumType>::
INLINE void FLOATNAME(LVecBase4)::
output(ostream &out) const {
out << MAYBE_ZERO(_data[0]) << " "
<< MAYBE_ZERO(_data[1]) << " "
@ -650,31 +752,13 @@ output(ostream &out) const {
<< MAYBE_ZERO(_data[3]);
}
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void LVecBase4<NumType>::
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
////////////////////////////////////////////////////////////////////
template<class NumType>
void LVecBase4<NumType>::
INLINE void FLOATNAME(LVecBase4)::
write_datagram(Datagram &destination) const {
destination.add_float32(_data[0]);
destination.add_float32(_data[1]);
@ -687,8 +771,8 @@ write_datagram(Datagram &destination) const {
// Access: Public
// Description: Function to read itself from a datagramIterator
////////////////////////////////////////////////////////////////////
template<class NumType>
void LVecBase4<NumType>::
INLINE void FLOATNAME(LVecBase4)::
read_datagram(DatagramIterator &source) {
_data[0] = source.get_float32();
_data[1] = source.get_float32();
@ -697,14 +781,5 @@ 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<class NumType, class NumType2>
INLINE LVecBase4<NumType2>
lcast_to(NumType2 *, const LVecBase4<NumType> &source) {
return LVecBase4<NumType2>(source[0], source[1], source[2], source[3]);
}

View File

@ -0,0 +1,13 @@
// Filename: lvecBase4.cxx
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
#include "lvecBase4.h"
#include "fltnames.I"
#include "lvecBase4_src.I"
#include "dblnames.I"
#include "lvecBase4_src.I"

View File

@ -7,135 +7,42 @@
#define LVECBASE4_H
#include <pandabase.h>
#include "cmath.h"
#include <typeHandle.h>
#include <notify.h>
#include <datagram.h>
#include <datagramIterator.h>
#include "cmath.h"
#include "nearly_zero.h"
class Datagram;
class DatagramIterator;
#include "fltnames.I"
#include "lvecBase4.I"
#include "dblnames.I"
#include "lvecBase4.I"
////////////////////////////////////////////////////////////////////
// Class : LVecBase4
// Description : This is the base class for all three-component
// vectors and points.
// Function: lcast_to
// Description: Converts a vector from one numeric representation to
// another one. This is usually invoked using the macro
// LCAST.
////////////////////////////////////////////////////////////////////
template<class NumType>
class LVecBase4 {
PUBLISHED:
typedef const NumType *iterator;
typedef const NumType *const_iterator;
INLINE LVecBase4();
INLINE LVecBase4(const LVecBase4<NumType> &copy);
INLINE LVecBase4<NumType> &operator = (const LVecBase4<NumType> &copy);
INLINE LVecBase4<NumType> &operator = (NumType fill_value);
INLINE LVecBase4(NumType fill_value);
INLINE LVecBase4(NumType x, NumType y, NumType z, NumType w);
INLINE FLOATNAME2(LVecBase4)
lcast_to(FLOATTYPE2 *, const FLOATNAME(LVecBase4) &source) {
return FLOATNAME2(LVecBase4)(source[0], source[1], source[2], source[3]);
}
INLINE static LVecBase4<NumType> zero();
INLINE static LVecBase4<NumType> unit_x();
INLINE static LVecBase4<NumType> unit_y();
INLINE static LVecBase4<NumType> unit_z();
INLINE static LVecBase4<NumType> 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<NumType> &other) const;
INLINE bool operator < (const LVecBase4<NumType> &other) const;
INLINE bool operator == (const LVecBase4<NumType> &other) const;
INLINE bool operator != (const LVecBase4<NumType> &other) const;
INLINE int compare_to(const LVecBase4<NumType> &other) const;
INLINE int compare_to(const LVecBase4<NumType> &other,
NumType threshold) const;
INLINE LVecBase4<NumType>
operator - () const;
INLINE LVecBase4<NumType>
operator + (const LVecBase4<NumType> &other) const;
INLINE LVecBase4<NumType>
operator - (const LVecBase4<NumType> &other) const;
INLINE LVecBase4<NumType> operator * (NumType scalar) const;
INLINE LVecBase4<NumType> operator / (NumType scalar) const;
INLINE void operator += (const LVecBase4<NumType> &other);
INLINE void operator -= (const LVecBase4<NumType> &other);
INLINE void operator *= (NumType scalar);
INLINE void operator /= (NumType scalar);
INLINE bool almost_equal(const LVecBase4<NumType> &other,
NumType threshold) const;
INLINE bool almost_equal(const LVecBase4<NumType> &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<class NumType>
INLINE ostream &operator << (ostream &out, const LVecBase4<NumType> &vec) {
vec.output(out);
return out;
#include "fltnames.I"
INLINE FLOATNAME2(LVecBase4)
lcast_to(FLOATTYPE2 *, const FLOATNAME(LVecBase4) &source) {
return FLOATNAME2(LVecBase4)(source[0], source[1], source[2], source[3]);
}
// Cast to a different numeric type
template<class NumType, class NumType2>
INLINE LVecBase4<NumType2>
lcast_to(NumType2 *type, const LVecBase4<NumType> &source);
#include "lvecBase4.I"
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVecBase4<float>)
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVecBase4<double>)
#endif

View File

@ -0,0 +1,23 @@
// Filename: lvecBase4.I
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
TypeHandle FLOATNAME(LVecBase4)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LVecBase4::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
void FLOATNAME(LVecBase4)::
init_type() {
if (_type_handle == TypeHandle::none()) {
// Format a string to describe the type.
do_init_type(FLOATTYPE1);
string name =
"LVecBase4<" + get_type_handle(FLOATTYPE1).get_name() + ">";
register_type(_type_handle, name);
}
}

View File

@ -3,19 +3,56 @@
//
////////////////////////////////////////////////////////////////////
#include "cmath.h"
////////////////////////////////////////////////////////////////////
// Class : LVector2
// Description : This is a two-component vector offset.
////////////////////////////////////////////////////////////////////
template<class NumType>
TypeHandle LVector2<NumType>::_type_handle;
class EXPCL_PANDA FLOATNAME(LVector2) : public FLOATNAME(LVecBase2) {
PUBLISHED:
INLINE FLOATNAME(LVector2)();
INLINE FLOATNAME(LVector2)(const FLOATNAME(LVecBase2) &copy);
INLINE FLOATNAME(LVector2) &operator = (const FLOATNAME(LVecBase2) &copy);
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;
};
////////////////////////////////////////////////////////////////////
// Function: LVector2::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType>::
LVector2() {
INLINE FLOATNAME(LVector2)::
FLOATNAME(LVector2)() {
}
////////////////////////////////////////////////////////////////////
@ -23,9 +60,9 @@ LVector2() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType>::
LVector2(const LVecBase2<NumType> &copy) : LVecBase2<NumType>(copy) {
INLINE FLOATNAME(LVector2)::
FLOATNAME(LVector2)(const FLOATNAME(LVecBase2) &copy) : FLOATNAME(LVecBase2)(copy) {
}
////////////////////////////////////////////////////////////////////
@ -33,10 +70,10 @@ LVector2(const LVecBase2<NumType> &copy) : LVecBase2<NumType>(copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType> &LVector2<NumType>::
operator = (const LVecBase2<NumType> &copy) {
LVecBase2<NumType>::operator = (copy);
INLINE FLOATNAME(LVector2) &FLOATNAME(LVector2)::
operator = (const FLOATNAME(LVecBase2) &copy) {
FLOATNAME(LVecBase2)::operator = (copy);
return *this;
}
@ -45,10 +82,10 @@ operator = (const LVecBase2<NumType> &copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType> &LVector2<NumType>::
operator = (NumType fill_value) {
LVecBase2<NumType>::operator = (fill_value);
INLINE FLOATNAME(LVector2) &FLOATNAME(LVector2)::
operator = (FLOATTYPE1 fill_value) {
FLOATNAME(LVecBase2)::operator = (fill_value);
return *this;
}
@ -57,10 +94,10 @@ operator = (NumType fill_value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType>::
LVector2(NumType fill_value) :
LVecBase2<NumType>(fill_value)
INLINE FLOATNAME(LVector2)::
FLOATNAME(LVector2)(FLOATTYPE1 fill_value) :
FLOATNAME(LVecBase2)(fill_value)
{
}
@ -69,10 +106,10 @@ LVector2(NumType fill_value) :
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType>::
LVector2(NumType x, NumType y) :
LVecBase2<NumType>(x, y)
INLINE FLOATNAME(LVector2)::
FLOATNAME(LVector2)(FLOATTYPE1 x, FLOATTYPE1 y) :
FLOATNAME(LVecBase2)(x, y)
{
}
@ -81,10 +118,10 @@ LVector2(NumType x, NumType y) :
// Access: Public
// Description: Returns a zero-length vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType> LVector2<NumType>::
INLINE FLOATNAME(LVector2) FLOATNAME(LVector2)::
zero() {
return LVector2<NumType>(0.0, 0.0);
return FLOATNAME(LVector2)(0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -92,10 +129,10 @@ zero() {
// Access: Public
// Description: Returns a unit X vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType> LVector2<NumType>::
INLINE FLOATNAME(LVector2) FLOATNAME(LVector2)::
unit_x() {
return LVector2<NumType>(1.0, 0.0);
return FLOATNAME(LVector2)(1.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -103,10 +140,10 @@ unit_x() {
// Access: Public
// Description: Returns a unit Y vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType> LVector2<NumType>::
INLINE FLOATNAME(LVector2) FLOATNAME(LVector2)::
unit_y() {
return LVector2<NumType>(0.0, 1.0);
return FLOATNAME(LVector2)(0.0, 1.0);
}
////////////////////////////////////////////////////////////////////
@ -114,10 +151,10 @@ unit_y() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType> LVector2<NumType>::
INLINE FLOATNAME(LVector2) FLOATNAME(LVector2)::
operator - () const {
return LVecBase2<NumType>::operator - ();
return FLOATNAME(LVecBase2)::operator - ();
}
////////////////////////////////////////////////////////////////////
@ -125,10 +162,10 @@ operator - () const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType> LVector2<NumType>::
operator + (const LVecBase2<NumType> &other) const {
return LVecBase2<NumType>::operator + (other);
INLINE FLOATNAME(LVecBase2) FLOATNAME(LVector2)::
operator + (const FLOATNAME(LVecBase2) &other) const {
return FLOATNAME(LVecBase2)::operator + (other);
}
////////////////////////////////////////////////////////////////////
@ -136,10 +173,10 @@ operator + (const LVecBase2<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType> LVector2<NumType>::
operator + (const LVector2<NumType> &other) const {
return LVecBase2<NumType>::operator + (other);
INLINE FLOATNAME(LVector2) FLOATNAME(LVector2)::
operator + (const FLOATNAME(LVector2) &other) const {
return FLOATNAME(LVecBase2)::operator + (other);
}
////////////////////////////////////////////////////////////////////
@ -147,10 +184,10 @@ operator + (const LVector2<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase2<NumType> LVector2<NumType>::
operator - (const LVecBase2<NumType> &other) const {
return LVecBase2<NumType>::operator - (other);
INLINE FLOATNAME(LVecBase2) FLOATNAME(LVector2)::
operator - (const FLOATNAME(LVecBase2) &other) const {
return FLOATNAME(LVecBase2)::operator - (other);
}
////////////////////////////////////////////////////////////////////
@ -158,10 +195,10 @@ operator - (const LVecBase2<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType> LVector2<NumType>::
operator - (const LVector2<NumType> &other) const {
return LVecBase2<NumType>::operator - (other);
INLINE FLOATNAME(LVector2) FLOATNAME(LVector2)::
operator - (const FLOATNAME(LVector2) &other) const {
return FLOATNAME(LVecBase2)::operator - (other);
}
////////////////////////////////////////////////////////////////////
@ -170,8 +207,8 @@ operator - (const LVector2<NumType> &other) const {
// Description: Returns the length of the vector, by the Pythagorean
// theorem.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVector2<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVector2)::
length() const {
return csqrt((*this).dot(*this));
}
@ -182,8 +219,8 @@ length() const {
// Description: Returns the square of the vector's length, cheap and
// easy.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVector2<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVector2)::
length_squared() const {
return (*this).dot(*this);
}
@ -195,15 +232,15 @@ length_squared() const {
// vector was normalized, false if it was a zero-length
// vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVector2<NumType>::
INLINE bool FLOATNAME(LVector2)::
normalize() {
NumType l2 = length_squared();
if (l2 == (NumType)0.0) {
FLOATTYPE1 l2 = length_squared();
if (l2 == (FLOATTYPE1)0.0) {
set(0.0, 0.0);
return false;
} else if (!IS_THRESHOLD_EQUAL(l2, 1.0, NEARLY_ZERO(NumType) * NEARLY_ZERO(NumType))) {
} else if (!IS_THRESHOLD_EQUAL(l2, 1.0, NEARLY_ZERO(FLOATTYPE1) * NEARLY_ZERO(FLOATTYPE1))) {
(*this) /= csqrt(l2);
}
@ -215,10 +252,10 @@ normalize() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType> LVector2<NumType>::
operator * (NumType scalar) const {
return LVector2<NumType>(LVecBase2<NumType>::operator * (scalar));
INLINE FLOATNAME(LVector2) FLOATNAME(LVector2)::
operator * (FLOATTYPE1 scalar) const {
return FLOATNAME(LVector2)(FLOATNAME(LVecBase2)::operator * (scalar));
}
////////////////////////////////////////////////////////////////////
@ -226,37 +263,9 @@ operator * (NumType scalar) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector2<NumType> LVector2<NumType>::
operator / (NumType scalar) const {
return LVector2<NumType>(LVecBase2<NumType>::operator / (scalar));
INLINE FLOATNAME(LVector2) FLOATNAME(LVector2)::
operator / (FLOATTYPE1 scalar) const {
return FLOATNAME(LVector2)(FLOATNAME(LVecBase2)::operator / (scalar));
}
////////////////////////////////////////////////////////////////////
// Function: LVector2::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void LVector2<NumType>::
init_type() {
if (_type_handle == TypeHandle::none()) {
LVecBase2<NumType>::init_type();
string name =
"LVector2<" + get_type_handle(NumType).get_name() + ">";
register_type(_type_handle, name,
LVecBase2<NumType>::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<class NumType, class NumType2>
INLINE LVector2<NumType2>
lcast_to(NumType2 *, const LVector2<NumType> &source) {
return LVector2<NumType2>(source[0], source[1]);
}

View File

@ -0,0 +1,13 @@
// Filename: lvector2.cxx
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
#include "lvector2.h"
#include "fltnames.I"
#include "lvector2_src.I"
#include "dblnames.I"
#include "lvector2_src.I"

View File

@ -7,63 +7,35 @@
#define LVECTOR2_H
#include <pandabase.h>
#include "cmath.h"
#include "config_linmath.h"
#include "lvecBase2.h"
////////////////////////////////////////////////////////////////////
// Class : LVector2
// Description : This is a two-component vector offset.
////////////////////////////////////////////////////////////////////
template<class NumType>
class LVector2 : public LVecBase2<NumType> {
PUBLISHED:
INLINE LVector2();
INLINE LVector2(const LVecBase2<NumType> &copy);
INLINE LVector2<NumType> &operator = (const LVecBase2<NumType> &copy);
INLINE LVector2<NumType> &operator = (NumType fill_value);
INLINE LVector2(NumType fill_value);
INLINE LVector2(NumType x, NumType y);
INLINE static LVector2<NumType> zero();
INLINE static LVector2<NumType> unit_x();
INLINE static LVector2<NumType> unit_y();
INLINE LVector2<NumType> operator - () const;
INLINE LVecBase2<NumType>
operator + (const LVecBase2<NumType> &other) const;
INLINE LVector2<NumType>
operator + (const LVector2<NumType> &other) const;
INLINE LVecBase2<NumType>
operator - (const LVecBase2<NumType> &other) const;
INLINE LVector2<NumType>
operator - (const LVector2<NumType> &other) const;
INLINE NumType length() const;
INLINE NumType length_squared() const;
INLINE bool normalize();
INLINE LVector2<NumType> operator * (NumType scalar) const;
INLINE LVector2<NumType> 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<class NumType, class NumType2>
INLINE LVector2<NumType2>
lcast_to(NumType2 *type, const LVector2<NumType> &source);
#include "fltnames.I"
#include "lvector2.I"
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVector2<float>)
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVector2<double>)
#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]);
}
#endif

View File

@ -0,0 +1,25 @@
// Filename: lvector2.I
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
TypeHandle FLOATNAME(LVector2)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LVector2::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
void FLOATNAME(LVector2)::
init_type() {
if (_type_handle == TypeHandle::none()) {
FLOATNAME(LVecBase2)::init_type();
string name =
"LVector2<" + get_type_handle(FLOATTYPE1).get_name() + ">";
register_type(_type_handle, name,
FLOATNAME(LVecBase2)::get_class_type());
}
}

View File

@ -3,20 +3,79 @@
//
////////////////////////////////////////////////////////////////////
#include "config_linmath.h"
#include "cmath.h"
////////////////////////////////////////////////////////////////////
// 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 NumType>
TypeHandle LVector3<NumType>::_type_handle;
class EXPCL_PANDA FLOATNAME(LVector3) : public FLOATNAME(LVecBase3) {
PUBLISHED:
INLINE FLOATNAME(LVector3)();
INLINE FLOATNAME(LVector3)(const FLOATNAME(LVecBase3) &copy);
INLINE FLOATNAME(LVector3) &operator = (const FLOATNAME(LVecBase3) &copy);
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;
};
////////////////////////////////////////////////////////////////////
// Function: LVector3::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType>::
LVector3() {
INLINE FLOATNAME(LVector3)::
FLOATNAME(LVector3)() {
}
////////////////////////////////////////////////////////////////////
@ -24,9 +83,9 @@ LVector3() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType>::
LVector3(const LVecBase3<NumType> &copy) : LVecBase3<NumType>(copy) {
INLINE FLOATNAME(LVector3)::
FLOATNAME(LVector3)(const FLOATNAME(LVecBase3) &copy) : FLOATNAME(LVecBase3)(copy) {
}
////////////////////////////////////////////////////////////////////
@ -34,10 +93,10 @@ LVector3(const LVecBase3<NumType> &copy) : LVecBase3<NumType>(copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> &LVector3<NumType>::
operator = (const LVecBase3<NumType> &copy) {
LVecBase3<NumType>::operator = (copy);
INLINE FLOATNAME(LVector3) &FLOATNAME(LVector3)::
operator = (const FLOATNAME(LVecBase3) &copy) {
FLOATNAME(LVecBase3)::operator = (copy);
return *this;
}
@ -46,10 +105,10 @@ operator = (const LVecBase3<NumType> &copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> &LVector3<NumType>::
operator = (NumType fill_value) {
LVecBase3<NumType>::operator = (fill_value);
INLINE FLOATNAME(LVector3) &FLOATNAME(LVector3)::
operator = (FLOATTYPE1 fill_value) {
FLOATNAME(LVecBase3)::operator = (fill_value);
return *this;
}
@ -58,10 +117,10 @@ operator = (NumType fill_value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType>::
LVector3(NumType fill_value) :
LVecBase3<NumType>(fill_value)
INLINE FLOATNAME(LVector3)::
FLOATNAME(LVector3)(FLOATTYPE1 fill_value) :
FLOATNAME(LVecBase3)(fill_value)
{
}
@ -70,10 +129,10 @@ LVector3(NumType fill_value) :
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType>::
LVector3(NumType x, NumType y, NumType z) :
LVecBase3<NumType>(x, y, z)
INLINE FLOATNAME(LVector3)::
FLOATNAME(LVector3)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z) :
FLOATNAME(LVecBase3)(x, y, z)
{
}
@ -82,10 +141,10 @@ LVector3(NumType x, NumType y, NumType z) :
// Access: Public
// Description: Returns a zero-length vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LVector3<NumType>::
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
zero() {
return LVector3<NumType>(0.0, 0.0, 0.0);
return FLOATNAME(LVector3)(0.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -93,10 +152,10 @@ zero() {
// Access: Public
// Description: Returns a unit X vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LVector3<NumType>::
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
unit_x() {
return LVector3<NumType>(1.0, 0.0, 0.0);
return FLOATNAME(LVector3)(1.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -104,10 +163,10 @@ unit_x() {
// Access: Public
// Description: Returns a unit Y vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LVector3<NumType>::
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
unit_y() {
return LVector3<NumType>(0.0, 1.0, 0.0);
return FLOATNAME(LVector3)(0.0, 1.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -115,10 +174,10 @@ unit_y() {
// Access: Public
// Description: Returns a unit Z vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LVector3<NumType>::
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
unit_z() {
return LVector3<NumType>(0.0, 0.0, 1.0);
return FLOATNAME(LVector3)(0.0, 0.0, 1.0);
}
////////////////////////////////////////////////////////////////////
@ -126,10 +185,10 @@ unit_z() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LVector3<NumType>::
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
operator - () const {
return LVecBase3<NumType>::operator - ();
return FLOATNAME(LVecBase3)::operator - ();
}
////////////////////////////////////////////////////////////////////
@ -137,10 +196,10 @@ operator - () const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> LVector3<NumType>::
operator + (const LVecBase3<NumType> &other) const {
return LVecBase3<NumType>::operator + (other);
INLINE FLOATNAME(LVecBase3) FLOATNAME(LVector3)::
operator + (const FLOATNAME(LVecBase3) &other) const {
return FLOATNAME(LVecBase3)::operator + (other);
}
////////////////////////////////////////////////////////////////////
@ -148,10 +207,10 @@ operator + (const LVecBase3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LVector3<NumType>::
operator + (const LVector3<NumType> &other) const {
return LVecBase3<NumType>::operator + (other);
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
operator + (const FLOATNAME(LVector3) &other) const {
return FLOATNAME(LVecBase3)::operator + (other);
}
////////////////////////////////////////////////////////////////////
@ -159,10 +218,10 @@ operator + (const LVector3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase3<NumType> LVector3<NumType>::
operator - (const LVecBase3<NumType> &other) const {
return LVecBase3<NumType>::operator - (other);
INLINE FLOATNAME(LVecBase3) FLOATNAME(LVector3)::
operator - (const FLOATNAME(LVecBase3) &other) const {
return FLOATNAME(LVecBase3)::operator - (other);
}
////////////////////////////////////////////////////////////////////
@ -170,10 +229,10 @@ operator - (const LVecBase3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LVector3<NumType>::
operator - (const LVector3<NumType> &other) const {
return LVecBase3<NumType>::operator - (other);
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
operator - (const FLOATNAME(LVector3) &other) const {
return FLOATNAME(LVecBase3)::operator - (other);
}
////////////////////////////////////////////////////////////////////
@ -182,8 +241,8 @@ operator - (const LVector3<NumType> &other) const {
// Description: Returns the length of the vector, by the Pythagorean
// theorem.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVector3<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVector3)::
length() const {
return csqrt((*this).dot(*this));
}
@ -194,8 +253,8 @@ length() const {
// Description: Returns the square of the vector's length, cheap and
// easy.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVector3<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVector3)::
length_squared() const {
return (*this).dot(*this);
}
@ -207,15 +266,15 @@ length_squared() const {
// vector was normalized, false if it was a zero-length
// vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVector3<NumType>::
INLINE bool FLOATNAME(LVector3)::
normalize() {
NumType l2 = length_squared();
if (l2 == (NumType)0.0) {
FLOATTYPE1 l2 = length_squared();
if (l2 == (FLOATTYPE1)0.0) {
set(0.0, 0.0, 0.0);
return false;
} else if (!IS_THRESHOLD_EQUAL(l2, 1.0, NEARLY_ZERO(NumType) * NEARLY_ZERO(NumType))) {
} else if (!IS_THRESHOLD_EQUAL(l2, 1.0, NEARLY_ZERO(FLOATTYPE1) * NEARLY_ZERO(FLOATTYPE1))) {
(*this) /= csqrt(l2);
}
@ -227,10 +286,10 @@ normalize() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LVector3<NumType>::
cross(const LVecBase3<NumType> &other) const {
return LVecBase3<NumType>::cross(other);
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
cross(const FLOATNAME(LVecBase3) &other) const {
return FLOATNAME(LVecBase3)::cross(other);
}
////////////////////////////////////////////////////////////////////
@ -238,10 +297,10 @@ cross(const LVecBase3<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LVector3<NumType>::
operator * (NumType scalar) const {
return LVector3<NumType>(LVecBase3<NumType>::operator * (scalar));
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
operator * (FLOATTYPE1 scalar) const {
return FLOATNAME(LVector3)(FLOATNAME(LVecBase3)::operator * (scalar));
}
////////////////////////////////////////////////////////////////////
@ -249,10 +308,10 @@ operator * (NumType scalar) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LVector3<NumType>::
operator / (NumType scalar) const {
return LVector3<NumType>(LVecBase3<NumType>::operator / (scalar));
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
operator / (FLOATTYPE1 scalar) const {
return FLOATNAME(LVector3)(FLOATNAME(LVecBase3)::operator / (scalar));
}
////////////////////////////////////////////////////////////////////
@ -261,8 +320,8 @@ operator / (NumType scalar) const {
// Description: Returns the up vector for the given coordinate
// system.
////////////////////////////////////////////////////////////////////
template<class NumType>
LVector3<NumType> LVector3<NumType>::
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
up(CoordinateSystem cs) {
if (cs == CS_default) {
cs = default_coordinate_system;
@ -270,16 +329,16 @@ up(CoordinateSystem cs) {
switch (cs) {
case CS_zup_right:
case CS_zup_left:
return LVector3<NumType>(0.0, 0.0, 1.0);
return FLOATNAME(LVector3)(0.0, 0.0, 1.0);
case CS_yup_right:
case CS_yup_left:
return LVector3<NumType>(0.0, 1.0, 0.0);
return FLOATNAME(LVector3)(0.0, 1.0, 0.0);
default:
linmath_cat.error()
<< "Invalid coordinate system!\n";
return LVector3<NumType>(0.0, 0.0, 0.0);
return FLOATNAME(LVector3)(0.0, 0.0, 0.0);
}
}
@ -289,10 +348,10 @@ up(CoordinateSystem cs) {
// Description: Returns the right vector for the given coordinate
// system.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LVector3<NumType>::
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
right(CoordinateSystem) {
return LVector3<NumType>(1.0, 0.0, 0.0);
return FLOATNAME(LVector3)(1.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -301,29 +360,29 @@ right(CoordinateSystem) {
// Description: Returns the forward vector for the given coordinate
// system.
////////////////////////////////////////////////////////////////////
template<class NumType>
LVector3<NumType> LVector3<NumType>::
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
forward(CoordinateSystem cs) {
if (cs == CS_default) {
cs = default_coordinate_system;
}
switch (cs) {
case CS_zup_right:
return LVector3<NumType>(0.0, 1.0, 0.0);
return FLOATNAME(LVector3)(0.0, 1.0, 0.0);
case CS_zup_left:
return LVector3<NumType>(0.0, -1.0, 0.0);
return FLOATNAME(LVector3)(0.0, -1.0, 0.0);
case CS_yup_right:
return LVector3<NumType>(0.0, 0.0, -1.0);
return FLOATNAME(LVector3)(0.0, 0.0, -1.0);
case CS_yup_left:
return LVector3<NumType>(0.0, 0.0, 1.0);
return FLOATNAME(LVector3)(0.0, 0.0, 1.0);
default:
linmath_cat.error()
<< "Invalid coordinate system!\n";
return LVector3<NumType>(0.0, 0.0, 0.0);
return FLOATNAME(LVector3)(0.0, 0.0, 0.0);
}
}
@ -333,8 +392,8 @@ forward(CoordinateSystem cs) {
// Description: Returns the down vector for the given coordinate
// system.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LVector3<NumType>::
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
down(CoordinateSystem cs) {
return -up(cs);
}
@ -345,8 +404,8 @@ down(CoordinateSystem cs) {
// Description: Returns the left vector for the given coordinate
// system.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LVector3<NumType>::
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
left(CoordinateSystem cs) {
return -right(cs);
}
@ -357,8 +416,8 @@ left(CoordinateSystem cs) {
// Description: Returns the back vector for the given coordinate
// system.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LVector3<NumType>::
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
back(CoordinateSystem cs) {
return -forward(cs);
}
@ -370,38 +429,10 @@ back(CoordinateSystem cs) {
// forward, and up components, in whatever way the
// coordinate system represents that vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> LVector3<NumType>::
rfu(NumType right_v, NumType fwd_v, NumType up_v,
INLINE FLOATNAME(LVector3) FLOATNAME(LVector3)::
rfu(FLOATTYPE1 right_v, FLOATTYPE1 fwd_v, FLOATTYPE1 up_v,
CoordinateSystem cs) {
return fwd_v * forward(cs) + up_v * up(cs) + right_v * right(cs);
return forward(cs) * fwd_v + up(cs) * up_v + right(cs) * right_v;
}
////////////////////////////////////////////////////////////////////
// Function: LVector3::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void LVector3<NumType>::
init_type() {
if (_type_handle == TypeHandle::none()) {
LVecBase3<NumType>::init_type();
string name =
"LVector3<" + get_type_handle(NumType).get_name() + ">";
register_type(_type_handle, name,
LVecBase3<NumType>::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<class NumType, class NumType2>
INLINE LVector3<NumType2>
lcast_to(NumType2 *, const LVector3<NumType> &source) {
return LVector3<NumType2>(source[0], source[1], source[2]);
}

View File

@ -0,0 +1,13 @@
// Filename: lvector3.cxx
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
#include "lvector3.h"
#include "fltnames.I"
#include "lvector3_src.I"
#include "dblnames.I"
#include "lvector3_src.I"

View File

@ -9,85 +9,37 @@
#include <pandabase.h>
#include "coordinateSystem.h"
#include "cmath.h"
#include "config_linmath.h"
#include "lvecBase3.h"
////////////////////////////////////////////////////////////////////
// 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 NumType>
class LVector3 : public LVecBase3<NumType> {
PUBLISHED:
INLINE LVector3();
INLINE LVector3(const LVecBase3<NumType> &copy);
INLINE LVector3<NumType> &operator = (const LVecBase3<NumType> &copy);
INLINE LVector3<NumType> &operator = (NumType fill_value);
INLINE LVector3(NumType fill_value);
INLINE LVector3(NumType x, NumType y, NumType z);
INLINE static LVector3<NumType> zero();
INLINE static LVector3<NumType> unit_x();
INLINE static LVector3<NumType> unit_y();
INLINE static LVector3<NumType> unit_z();
INLINE LVector3<NumType> operator - () const;
INLINE LVecBase3<NumType>
operator + (const LVecBase3<NumType> &other) const;
INLINE LVector3<NumType>
operator + (const LVector3<NumType> &other) const;
INLINE LVecBase3<NumType>
operator - (const LVecBase3<NumType> &other) const;
INLINE LVector3<NumType>
operator - (const LVector3<NumType> &other) const;
INLINE NumType length() const;
INLINE NumType length_squared() const;
INLINE bool normalize();
INLINE LVector3<NumType> cross(const LVecBase3<NumType> &other) const;
INLINE LVector3<NumType> operator * (NumType scalar) const;
INLINE LVector3<NumType> operator / (NumType scalar) const;
// Some special named constructors for LVector3.
static LVector3<NumType> up(CoordinateSystem cs = CS_default);
INLINE static LVector3<NumType> right(CoordinateSystem cs = CS_default);
static LVector3<NumType> forward(CoordinateSystem cs = CS_default);
INLINE static LVector3<NumType> down(CoordinateSystem cs = CS_default);
INLINE static LVector3<NumType> left(CoordinateSystem cs = CS_default);
INLINE static LVector3<NumType> back(CoordinateSystem cs = CS_default);
INLINE static LVector3<NumType> 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<class NumType, class NumType2>
INLINE LVector3<NumType2>
lcast_to(NumType2 *type, const LVector3<NumType> &source);
#include "fltnames.I"
#include "lvector3.I"
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVector3<float>)
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVector3<double>)
#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]);
}
#endif

View File

@ -0,0 +1,25 @@
// Filename: lvector3.I
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
TypeHandle FLOATNAME(LVector3)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LVector3::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
void FLOATNAME(LVector3)::
init_type() {
if (_type_handle == TypeHandle::none()) {
FLOATNAME(LVecBase3)::init_type();
string name =
"LVector3<" + get_type_handle(FLOATTYPE1).get_name() + ">";
register_type(_type_handle, name,
FLOATNAME(LVecBase3)::get_class_type());
}
}

View File

@ -3,20 +3,58 @@
//
////////////////////////////////////////////////////////////////////
#include "cmath.h"
////////////////////////////////////////////////////////////////////
// Class : LVector4
// Description : This is a four-component vector distance.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA FLOATNAME(LVector4) : public FLOATNAME(LVecBase4) {
PUBLISHED:
INLINE FLOATNAME(LVector4)();
INLINE FLOATNAME(LVector4)(const FLOATNAME(LVecBase4) &copy);
INLINE FLOATNAME(LVector4) &operator = (const FLOATNAME(LVecBase4) &copy);
INLINE FLOATNAME(LVector4) &operator = (FLOATTYPE1 fill_value);
INLINE FLOATNAME(LVector4)(FLOATTYPE1 fill_value);
INLINE FLOATNAME(LVector4)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w);
template<class NumType>
TypeHandle LVector4<NumType>::_type_handle;
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;
};
////////////////////////////////////////////////////////////////////
// Function: LVector4::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType>::
LVector4() {
INLINE FLOATNAME(LVector4)::
FLOATNAME(LVector4)() {
}
////////////////////////////////////////////////////////////////////
@ -24,9 +62,9 @@ LVector4() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType>::
LVector4(const LVecBase4<NumType> &copy) : LVecBase4<NumType>(copy) {
INLINE FLOATNAME(LVector4)::
FLOATNAME(LVector4)(const FLOATNAME(LVecBase4) &copy) : FLOATNAME(LVecBase4)(copy) {
}
////////////////////////////////////////////////////////////////////
@ -34,10 +72,10 @@ LVector4(const LVecBase4<NumType> &copy) : LVecBase4<NumType>(copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType> &LVector4<NumType>::
operator = (const LVecBase4<NumType> &copy) {
LVecBase4<NumType>::operator = (copy);
INLINE FLOATNAME(LVector4) &FLOATNAME(LVector4)::
operator = (const FLOATNAME(LVecBase4) &copy) {
FLOATNAME(LVecBase4)::operator = (copy);
return *this;
}
@ -46,10 +84,10 @@ operator = (const LVecBase4<NumType> &copy) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType> &LVector4<NumType>::
operator = (NumType fill_value) {
LVecBase4<NumType>::operator = (fill_value);
INLINE FLOATNAME(LVector4) &FLOATNAME(LVector4)::
operator = (FLOATTYPE1 fill_value) {
FLOATNAME(LVecBase4)::operator = (fill_value);
return *this;
}
@ -58,10 +96,10 @@ operator = (NumType fill_value) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType>::
LVector4(NumType fill_value) :
LVecBase4<NumType>(fill_value)
INLINE FLOATNAME(LVector4)::
FLOATNAME(LVector4)(FLOATTYPE1 fill_value) :
FLOATNAME(LVecBase4)(fill_value)
{
}
@ -70,10 +108,10 @@ LVector4(NumType fill_value) :
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType>::
LVector4(NumType x, NumType y, NumType z, NumType w) :
LVecBase4<NumType>(x, y, z, w)
INLINE FLOATNAME(LVector4)::
FLOATNAME(LVector4)(FLOATTYPE1 x, FLOATTYPE1 y, FLOATTYPE1 z, FLOATTYPE1 w) :
FLOATNAME(LVecBase4)(x, y, z, w)
{
}
@ -82,10 +120,10 @@ LVector4(NumType x, NumType y, NumType z, NumType w) :
// Access: Public
// Description: Returns a zero-length vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType> LVector4<NumType>::
INLINE FLOATNAME(LVector4) FLOATNAME(LVector4)::
zero() {
return LVector4<NumType>(0.0, 0.0, 0.0, 0.0);
return FLOATNAME(LVector4)(0.0, 0.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -93,10 +131,10 @@ zero() {
// Access: Public
// Description: Returns a unit X vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType> LVector4<NumType>::
INLINE FLOATNAME(LVector4) FLOATNAME(LVector4)::
unit_x() {
return LVector4<NumType>(1.0, 0.0, 0.0, 0.0);
return FLOATNAME(LVector4)(1.0, 0.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -104,10 +142,10 @@ unit_x() {
// Access: Public
// Description: Returns a unit Y vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType> LVector4<NumType>::
INLINE FLOATNAME(LVector4) FLOATNAME(LVector4)::
unit_y() {
return LVector4<NumType>(0.0, 1.0, 0.0, 0.0);
return FLOATNAME(LVector4)(0.0, 1.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -115,10 +153,10 @@ unit_y() {
// Access: Public
// Description: Returns a unit Z vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType> LVector4<NumType>::
INLINE FLOATNAME(LVector4) FLOATNAME(LVector4)::
unit_z() {
return LVector4<NumType>(0.0, 0.0, 1.0, 0.0);
return FLOATNAME(LVector4)(0.0, 0.0, 1.0, 0.0);
}
////////////////////////////////////////////////////////////////////
@ -126,10 +164,10 @@ unit_z() {
// Access: Public
// Description: Returns a unit W vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType> LVector4<NumType>::
INLINE FLOATNAME(LVector4) FLOATNAME(LVector4)::
unit_w() {
return LVector4<NumType>(0.0, 0.0, 0.0, 1.0);
return FLOATNAME(LVector4)(0.0, 0.0, 0.0, 1.0);
}
////////////////////////////////////////////////////////////////////
@ -137,10 +175,10 @@ unit_w() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType> LVector4<NumType>::
INLINE FLOATNAME(LVector4) FLOATNAME(LVector4)::
operator - () const {
return LVecBase4<NumType>::operator - ();
return FLOATNAME(LVecBase4)::operator - ();
}
////////////////////////////////////////////////////////////////////
@ -148,10 +186,10 @@ operator - () const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> LVector4<NumType>::
operator + (const LVecBase4<NumType> &other) const {
return LVecBase4<NumType>::operator + (other);
INLINE FLOATNAME(LVecBase4) FLOATNAME(LVector4)::
operator + (const FLOATNAME(LVecBase4) &other) const {
return FLOATNAME(LVecBase4)::operator + (other);
}
////////////////////////////////////////////////////////////////////
@ -159,10 +197,10 @@ operator + (const LVecBase4<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType> LVector4<NumType>::
operator + (const LVector4<NumType> &other) const {
return LVecBase4<NumType>::operator + (other);
INLINE FLOATNAME(LVector4) FLOATNAME(LVector4)::
operator + (const FLOATNAME(LVector4) &other) const {
return FLOATNAME(LVecBase4)::operator + (other);
}
////////////////////////////////////////////////////////////////////
@ -170,10 +208,10 @@ operator + (const LVector4<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVecBase4<NumType> LVector4<NumType>::
operator - (const LVecBase4<NumType> &other) const {
return LVecBase4<NumType>::operator - (other);
INLINE FLOATNAME(LVecBase4) FLOATNAME(LVector4)::
operator - (const FLOATNAME(LVecBase4) &other) const {
return FLOATNAME(LVecBase4)::operator - (other);
}
////////////////////////////////////////////////////////////////////
@ -181,10 +219,10 @@ operator - (const LVecBase4<NumType> &other) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType> LVector4<NumType>::
operator - (const LVector4<NumType> &other) const {
return LVecBase4<NumType>::operator - (other);
INLINE FLOATNAME(LVector4) FLOATNAME(LVector4)::
operator - (const FLOATNAME(LVector4) &other) const {
return FLOATNAME(LVecBase4)::operator - (other);
}
////////////////////////////////////////////////////////////////////
@ -193,8 +231,8 @@ operator - (const LVector4<NumType> &other) const {
// Description: Returns the length of the vector, by the Pythagorean
// theorem.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVector4<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVector4)::
length() const {
return csqrt((*this).dot(*this));
}
@ -205,8 +243,8 @@ length() const {
// Description: Returns the square of the vector's length, cheap and
// easy.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType LVector4<NumType>::
INLINE FLOATTYPE1 FLOATNAME(LVector4)::
length_squared() const {
return (*this).dot(*this);
}
@ -218,15 +256,15 @@ length_squared() const {
// vector was normalized, false if it was a zero-length
// vector.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool LVector4<NumType>::
INLINE bool FLOATNAME(LVector4)::
normalize() {
NumType l2 = length_squared();
if (l2 == (NumType)0.0) {
FLOATTYPE1 l2 = length_squared();
if (l2 == (FLOATTYPE1)0.0) {
set(0.0, 0.0, 0.0, 0.0);
return false;
} else if (!IS_THRESHOLD_EQUAL(l2, 1.0, NEARLY_ZERO(NumType) * NEARLY_ZERO(NumType))) {
} else if (!IS_THRESHOLD_EQUAL(l2, 1.0, NEARLY_ZERO(FLOATTYPE1) * NEARLY_ZERO(FLOATTYPE1))) {
(*this) /= csqrt(l2);
}
@ -238,10 +276,10 @@ normalize() {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType> LVector4<NumType>::
operator * (NumType scalar) const {
return LVector4<NumType>(LVecBase4<NumType>::operator * (scalar));
INLINE FLOATNAME(LVector4) FLOATNAME(LVector4)::
operator * (FLOATTYPE1 scalar) const {
return FLOATNAME(LVector4)(FLOATNAME(LVecBase4)::operator * (scalar));
}
////////////////////////////////////////////////////////////////////
@ -249,37 +287,9 @@ operator * (NumType scalar) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector4<NumType> LVector4<NumType>::
operator / (NumType scalar) const {
return LVector4<NumType>(LVecBase4<NumType>::operator / (scalar));
INLINE FLOATNAME(LVector4) FLOATNAME(LVector4)::
operator / (FLOATTYPE1 scalar) const {
return FLOATNAME(LVector4)(FLOATNAME(LVecBase4)::operator / (scalar));
}
////////////////////////////////////////////////////////////////////
// Function: LVector4::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void LVector4<NumType>::
init_type() {
if (_type_handle == TypeHandle::none()) {
LVecBase4<NumType>::init_type();
string name =
"LVector4<" + get_type_handle(NumType).get_name() + ">";
register_type(_type_handle, name,
LVecBase4<NumType>::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<class NumType, class NumType2>
INLINE LVector4<NumType2>
lcast_to(NumType2 *, const LVector4<NumType> &source) {
return LVector4<NumType2>(source[0], source[1], source[2], source[3]);
}

View File

@ -0,0 +1,13 @@
// Filename: lvector4.cxx
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
#include "lvector4.h"
#include "fltnames.I"
#include "lvector4_src.I"
#include "dblnames.I"
#include "lvector4_src.I"

View File

@ -7,64 +7,34 @@
#define LVECTOR4_H
#include <pandabase.h>
#include "cmath.h"
#include "config_linmath.h"
#include "lvecBase4.h"
////////////////////////////////////////////////////////////////////
// Class : LVector4
// Description : This is a four-component vector distance.
////////////////////////////////////////////////////////////////////
template<class NumType>
class LVector4 : public LVecBase4<NumType> {
PUBLISHED:
INLINE LVector4();
INLINE LVector4(const LVecBase4<NumType> &copy);
INLINE LVector4<NumType> &operator = (const LVecBase4<NumType> &copy);
INLINE LVector4<NumType> &operator = (NumType fill_value);
INLINE LVector4(NumType fill_value);
INLINE LVector4(NumType x, NumType y, NumType z, NumType w);
INLINE static LVector4<NumType> zero();
INLINE static LVector4<NumType> unit_x();
INLINE static LVector4<NumType> unit_y();
INLINE static LVector4<NumType> unit_z();
INLINE static LVector4<NumType> unit_w();
INLINE LVector4<NumType> operator - () const;
INLINE LVecBase4<NumType>
operator + (const LVecBase4<NumType> &other) const;
INLINE LVector4<NumType>
operator + (const LVector4<NumType> &other) const;
INLINE LVecBase4<NumType>
operator - (const LVecBase4<NumType> &other) const;
INLINE LVector4<NumType>
operator - (const LVector4<NumType> &other) const;
INLINE NumType length() const;
INLINE NumType length_squared() const;
INLINE bool normalize();
INLINE LVector4<NumType> operator * (NumType scalar) const;
INLINE LVector4<NumType> operator / (NumType scalar) const;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type();
private:
static TypeHandle _type_handle;
};
template<class NumType, class NumType2>
INLINE LVector4<NumType2>
lcast_to(NumType2 *type, const LVector4<NumType> &source);
#include "fltnames.I"
#include "lvector4.I"
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVector4<float>)
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, LVector4<double>)
#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]);
}
#endif

View File

@ -0,0 +1,25 @@
// Filename: lvector4.I
// Created by: drose (08Mar00)
//
////////////////////////////////////////////////////////////////////
TypeHandle FLOATNAME(LVector4)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: LVector2::init_type
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
void FLOATNAME(LVector4)::
init_type() {
if (_type_handle == TypeHandle::none()) {
FLOATNAME(LVecBase4)::init_type();
string name =
"LVector4<" + get_type_handle(FLOATTYPE1).get_name() + ">";
register_type(_type_handle, name,
FLOATNAME(LVecBase4)::get_class_type());
}
}

View File

@ -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(NumType) (get_nearly_zero_value((NumType)0))
#define NEARLY_ZERO(FLOATTYPE1) (get_nearly_zero_value((FLOATTYPE1)0))
// IS_NEARLY_ZERO(value) returns true if the value is very close to
// zero.

View File

@ -16,11 +16,11 @@
config_mathutil.h \
fftCompressor.cxx fftCompressor.h \
finiteBoundingVolume.cxx finiteBoundingVolume.h \
frustum.I frustum.h \
frustum.I frustum.h frustum.N plane.N\
geometricBoundingVolume.I geometricBoundingVolume.cxx \
geometricBoundingVolume.h look_at.I look_at.cxx look_at.h \
geometricBoundingVolume.h look_at.I look_at.cxx look_at.h look_at_src.I\
omniBoundingVolume.I omniBoundingVolume.cxx omniBoundingVolume.h \
plane.I plane.N plane.cxx plane.h rotate_to.cxx rotate_to.h
plane.I plane.cxx plane.h rotate_to.cxx rotate_to_src.I rotate_to.h
#define INSTALL_HEADERS \
boundingHexahedron.I boundingHexahedron.h boundingLine.I \

View File

@ -6,10 +6,50 @@
////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////
#include "mathutil.h"
#include "config_mathutil.h"
#include <math.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;
};
////////////////////////////////////////////////////////////////////
// Static variables
@ -20,9 +60,9 @@
// Access:
// Description:
////////////////////////////////////////////////////////////////////
template<class P_numtype>
Frustum<P_numtype>::
Frustum() {
INLINE FLOATNAME(Frustum)::
FLOATNAME(Frustum)() {
_fnear = 1.4142;
_ffar = 10.0;
_l = -1;
@ -36,8 +76,8 @@ Frustum() {
// Access:
// Description: Sets up a two-dimensional orthographic frustum
////////////////////////////////////////////////////////////////////
template<class P_numtype>
void Frustum<P_numtype>::make_ortho_2D(void) {
INLINE void FLOATNAME(Frustum)::make_ortho_2D(void) {
make_ortho(-1, 1);
}
@ -46,9 +86,9 @@ void Frustum<P_numtype>::make_ortho_2D(void) {
// Access:
// Description: Sets up a two-dimensional orthographic frustum
////////////////////////////////////////////////////////////////////
template<class P_numtype>
void Frustum<P_numtype>::
make_ortho_2D(P_numtype l, P_numtype r, P_numtype t, P_numtype b) {
INLINE void FLOATNAME(Frustum)::
make_ortho_2D(FLOATTYPE1 l, FLOATTYPE1 r, FLOATTYPE1 t, FLOATTYPE1 b) {
make_ortho(-1, 1, l, r, t, b);
}
@ -57,8 +97,8 @@ make_ortho_2D(P_numtype l, P_numtype r, P_numtype t, P_numtype b) {
// Access:
// Description: Behaves like gluOrtho
////////////////////////////////////////////////////////////////////
template<class P_numtype>
void Frustum<P_numtype>::make_ortho(P_numtype fnear, P_numtype ffar) {
INLINE void FLOATNAME(Frustum)::make_ortho(FLOATTYPE1 fnear, FLOATTYPE1 ffar) {
_fnear = fnear;
_ffar = ffar;
_l = -1;
@ -72,10 +112,10 @@ void Frustum<P_numtype>::make_ortho(P_numtype fnear, P_numtype ffar) {
// Access:
// Description: Behaves like gluOrtho
////////////////////////////////////////////////////////////////////
template<class P_numtype>
void Frustum<P_numtype>::
make_ortho(P_numtype fnear, P_numtype ffar, P_numtype l, P_numtype r,
P_numtype t, P_numtype b) {
INLINE void FLOATNAME(Frustum)::
make_ortho(FLOATTYPE1 fnear, FLOATTYPE1 ffar, FLOATTYPE1 l, FLOATTYPE1 r,
FLOATTYPE1 t, FLOATTYPE1 b) {
_fnear = fnear;
_ffar = ffar;
_l = l;
@ -106,10 +146,10 @@ make_ortho(P_numtype fnear, P_numtype ffar, P_numtype l, P_numtype r,
// W yfov
//
////////////////////////////////////////////////////////////////////
template<class P_numtype>
void Frustum<P_numtype>::
make_perspective_hfov(P_numtype hfov, P_numtype aspect, P_numtype fnear,
P_numtype ffar) {
INLINE void FLOATNAME(Frustum)::
make_perspective_hfov(FLOATTYPE1 hfov, FLOATTYPE1 aspect, FLOATTYPE1 fnear,
FLOATTYPE1 ffar) {
_fnear = fnear;
_ffar = ffar;
_r = tan(deg_2_rad(hfov) * 0.5) * _fnear;
@ -118,10 +158,10 @@ make_perspective_hfov(P_numtype hfov, P_numtype aspect, P_numtype fnear,
_b = -_t;
}
template<class P_numtype>
void Frustum<P_numtype>::
make_perspective_vfov(P_numtype yfov, P_numtype aspect, P_numtype fnear,
P_numtype ffar) {
INLINE void FLOATNAME(Frustum)::
make_perspective_vfov(FLOATTYPE1 yfov, FLOATTYPE1 aspect, FLOATTYPE1 fnear,
FLOATTYPE1 ffar) {
_fnear = fnear;
_ffar = ffar;
_t = tan(deg_2_rad(yfov) * 0.5) * _fnear;
@ -130,10 +170,10 @@ make_perspective_vfov(P_numtype yfov, P_numtype aspect, P_numtype fnear,
_l = -_r;
}
template<class P_numtype>
void Frustum<P_numtype>::
make_perspective(P_numtype xfov, P_numtype yfov, P_numtype fnear,
P_numtype ffar) {
INLINE void FLOATNAME(Frustum)::
make_perspective(FLOATTYPE1 xfov, FLOATTYPE1 yfov, FLOATTYPE1 fnear,
FLOATTYPE1 ffar) {
_fnear = fnear;
_ffar = ffar;
_t = tan(deg_2_rad(yfov) * 0.5) * _fnear;
@ -147,10 +187,10 @@ make_perspective(P_numtype xfov, P_numtype yfov, P_numtype fnear,
// Access:
// Description:
////////////////////////////////////////////////////////////////////
template<class P_numtype>
void Frustum<P_numtype>::
get_perspective_params(P_numtype& yfov, P_numtype& aspect,
P_numtype& fnear, P_numtype& ffar) const {
INLINE void FLOATNAME(Frustum)::
get_perspective_params(FLOATTYPE1& yfov, FLOATTYPE1& aspect,
FLOATTYPE1& fnear, FLOATTYPE1& ffar) const {
yfov = rad_2_deg(atan(_t / _fnear)) * 2.0;
aspect = _r / _t;
fnear = _fnear;
@ -162,10 +202,10 @@ get_perspective_params(P_numtype& yfov, P_numtype& aspect,
// Access:
// Description:
////////////////////////////////////////////////////////////////////
template<class P_numtype>
void Frustum<P_numtype>::
get_perspective_params(P_numtype& xfov, P_numtype& yfov, P_numtype& aspect,
P_numtype& fnear, P_numtype& ffar) const {
INLINE void FLOATNAME(Frustum)::
get_perspective_params(FLOATTYPE1& xfov, FLOATTYPE1& yfov, FLOATTYPE1& aspect,
FLOATTYPE1& fnear, FLOATTYPE1& ffar) const {
xfov = rad_2_deg(atan(_r / _fnear)) * 2.0;
get_perspective_params(yfov, aspect, fnear, ffar);
}
@ -177,45 +217,45 @@ get_perspective_params(P_numtype& xfov, P_numtype& yfov, P_numtype& aspect,
// perspective transform defined by the frustum,
// accordinate to the indicated coordinate system.
////////////////////////////////////////////////////////////////////
template<class P_numtype>
LMatrix4<P_numtype> Frustum<P_numtype>::
INLINE FLOATNAME(LMatrix4) FLOATNAME(Frustum)::
get_perspective_projection_mat(CoordinateSystem cs) const {
if (cs == CS_default) {
cs = default_coordinate_system;
}
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);
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);
switch (cs) {
case CS_zup_right:
return LMatrix4<P_numtype>( a, 0.0, 0.0, 0.0,
return FLOATNAME(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 LMatrix4<P_numtype>( a, 0.0, 0.0, 0.0,
return FLOATNAME(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 LMatrix4<P_numtype>::convert_mat(CS_zup_right, CS_zup_left) *
return FLOATNAME(LMatrix4)::convert_mat(CS_zup_right, CS_zup_left) *
get_perspective_projection_mat(CS_zup_right);
case CS_yup_left:
return LMatrix4<P_numtype>::convert_mat(CS_yup_right, CS_yup_left) *
return FLOATNAME(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 LMatrix4<P_numtype>::ident_mat();
return FLOATNAME(LMatrix4)::ident_mat();
}
}
@ -226,42 +266,42 @@ get_perspective_projection_mat(CoordinateSystem cs) const {
// orthographic transform defined by the frustum,
// accordinate to the indicated coordinate system.
////////////////////////////////////////////////////////////////////
template<class P_numtype>
LMatrix4<P_numtype> Frustum<P_numtype>::
INLINE FLOATNAME(LMatrix4) FLOATNAME(Frustum)::
get_ortho_projection_mat(CoordinateSystem cs) const {
if (cs == CS_default) {
cs = default_coordinate_system;
}
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);
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);
switch (cs) {
case CS_zup_right:
return LMatrix4<P_numtype>::convert_mat(CS_yup_right, CS_zup_right) *
return FLOATNAME(LMatrix4)::convert_mat(CS_yup_right, CS_zup_right) *
get_ortho_projection_mat(CS_yup_right);
case CS_yup_right:
return LMatrix4<P_numtype>( a, 0.0, 0.0, 0.0,
return FLOATNAME(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 LMatrix4<P_numtype>::convert_mat(CS_zup_right, CS_zup_left) *
return FLOATNAME(LMatrix4)::convert_mat(CS_zup_right, CS_zup_left) *
get_ortho_projection_mat(CS_zup_right);
case CS_yup_left:
return LMatrix4<P_numtype>::convert_mat(CS_yup_right, CS_yup_left) *
return FLOATNAME(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 LMatrix4<P_numtype>::ident_mat();
return FLOATNAME(LMatrix4)::ident_mat();
}
}

View File

@ -1,2 +1,4 @@
forcetype Frustum<float>
forcetype Frustum<double>
forcetype Frustumf
renametype Frustumf Frustumf
forcetype Frustumd
renametype Frustumd Frustumd

View File

@ -10,56 +10,15 @@
// Includes
////////////////////////////////////////////////////////////////////
#include <pandabase.h>
#include <math.h>
#include <luse.h>
#include "mathutil.h"
#include "config_mathutil.h"
////////////////////////////////////////////////////////////////////
// Defines
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Class : Frustum
// Description :
////////////////////////////////////////////////////////////////////
template<class P_numtype>
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<P_numtype>
get_perspective_projection_mat(CoordinateSystem cs = CS_default) const;
LMatrix4<P_numtype>
get_ortho_projection_mat(CoordinateSystem cs = CS_default) const;
public:
P_numtype _l, _r, _b, _t;
P_numtype _fnear, _ffar;
};
#include "fltnames.I"
#include "frustum.I"
typedef Frustum<float> Frustumf;
typedef Frustum<double> Frustumd;
#include "dblnames.I"
#include "frustum.I"
#endif

View File

@ -3,77 +3,86 @@
//
////////////////////////////////////////////////////////////////////
// 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(LMatrix3f &mat, const LVector3f &fwd, CoordinateSystem cs) {
heads_up(mat, fwd, LVector3f::up(cs), cs);
heads_up(FLOATNAME(LMatrix3) &mat, const FLOATNAME(LVector3) &fwd, CoordinateSystem cs) {
heads_up(mat, fwd, FLOATNAME(LVector3)::up(cs), cs);
}
INLINE void
look_at(LMatrix3f &mat, const LVector3f &fwd, CoordinateSystem cs) {
look_at(mat, fwd, LVector3f::up(cs), cs);
look_at(FLOATNAME(LMatrix3) &mat, const FLOATNAME(LVector3) &fwd, CoordinateSystem cs) {
look_at(mat, fwd, FLOATNAME(LVector3)::up(cs), cs);
}
INLINE void
heads_up(LMatrix4f &mat, const LVector3f &fwd,
const LVector3f &up, CoordinateSystem cs) {
LMatrix3f mat3;
heads_up(FLOATNAME(LMatrix4) &mat, const FLOATNAME(LVector3) &fwd,
const FLOATNAME(LVector3) &up, CoordinateSystem cs) {
FLOATNAME(LMatrix3) mat3;
heads_up(mat3, fwd, up, cs);
mat = LMatrix4f(mat3);
mat = FLOATNAME(LMatrix4)(mat3);
}
INLINE void
look_at(LMatrix4f &mat, const LVector3f &fwd,
const LVector3f &up, CoordinateSystem cs) {
LMatrix3f mat3;
look_at(FLOATNAME(LMatrix4) &mat, const FLOATNAME(LVector3) &fwd,
const FLOATNAME(LVector3) &up, CoordinateSystem cs) {
FLOATNAME(LMatrix3) mat3;
look_at(mat3, fwd, up, cs);
mat = LMatrix4f(mat3);
mat = FLOATNAME(LMatrix4)(mat3);
}
INLINE void
heads_up(LMatrix4f &mat, const LVector3f &fwd, CoordinateSystem cs) {
heads_up(mat, fwd, LVector3f::up(cs), cs);
heads_up(FLOATNAME(LMatrix4) &mat, const FLOATNAME(LVector3) &fwd, CoordinateSystem cs) {
heads_up(mat, fwd, FLOATNAME(LVector3)::up(cs), cs);
}
INLINE void
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);
look_at(FLOATNAME(LMatrix4) &mat, const FLOATNAME(LVector3) &fwd, CoordinateSystem cs) {
look_at(mat, fwd, FLOATNAME(LVector3)::up(cs), cs);
}

View File

@ -2,337 +2,11 @@
// Created by: drose (25Apr97)
//
////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////
#include "look_at.h"
#include <cmath.h>
template<class NumType>
INLINE LMatrix3<NumType>
make_xi_mat(const LVector2<NumType> &x) {
return LMatrix3<NumType>(1, 0, 0,
0, x[0], x[1],
0, -x[1], x[0]);
}
#include "fltnames.I"
#include "look_at_src.I"
template<class NumType>
INLINE LMatrix3<NumType>
make_x_mat(const LVector2<NumType> &x) {
return LMatrix3<NumType>(1, 0, 0,
0, x[1], x[0],
0, -x[0], x[1]);
}
template<class NumType>
INLINE LMatrix3<NumType>
make_y_mat(const LVector2<NumType> &y) {
return LMatrix3<NumType>(y[1], 0, -y[0],
0, 1, 0,
y[0], 0, y[1]);
}
template<class NumType>
INLINE LMatrix3<NumType>
make_z_mat(const LVector2<NumType> &z) {
return LMatrix3<NumType>(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<class NumType>
static void
_heads_up(LMatrix3<NumType> &mat, const LVector3<NumType> &fwd,
const LVector3<NumType> &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<NumType> y(up[0], up[2]);
NumType d = dot(y, y);
if (d==0.0) {
y = LVector2<NumType>(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<NumType> x(up[1], up[0]*y[0]+up[2]*y[1]);
d = dot(x, x);
if (d==0.0) {
x = LVector2<NumType>(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<NumType> 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<NumType>(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<NumType> z(up[0], up[1]);
NumType d = dot(z, z);
if (d==0.0) {
z = LVector2<NumType>(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<NumType> x(up[0]*z[0] + up[1]*z[1], up[2]);
d = dot(x, x);
if (d==0.0) {
x = LVector2<NumType>(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<NumType> 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<NumType>(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<class NumType>
static void
_look_at(LMatrix3<NumType> &mat, const LVector3<NumType> &fwd,
const LVector3<NumType> &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<NumType> z(fwd[0], fwd[1]);
NumType d = dot(z, z);
if (d==0.0) {
z = LVector2<NumType>(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<NumType> x(fwd[0]*z[0] + fwd[1]*z[1], fwd[2]);
d = dot(x, x);
if (d==0.0) {
x = LVector2<NumType>(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<NumType> 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<NumType>(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<NumType> y(fwd[0], fwd[2]);
NumType d = dot(y, y);
if (d==0.0) {
y = LVector2<NumType>(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<NumType> x(fwd[1], fwd[0]*y[0]+fwd[2]*y[1]);
d = dot(x, x);
if (d==0.0) {
x = LVector2<NumType>(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<NumType> 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<NumType>(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);
}
#include "dblnames.I"
#include "look_at_src.I"

View File

@ -10,86 +10,14 @@
// Includes
///////////////////////////////////////////////////////////////////
#include <pandabase.h>
#include "cmath.h"
#include "coordinateSystem.h"
#include "luse.h"
#include <luse.h>
#include <coordinateSystem.h>
// 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 "fltnames.I"
#include "look_at.I"
#include "dblnames.I"
#include "look_at.I"
#endif

View File

@ -0,0 +1,319 @@
// Filename: lookAt.cxx
// Created by: drose (25Apr97)
//
////////////////////////////////////////////////////////////////////
INLINE FLOATNAME(LMatrix3)
make_xi_mat(const FLOATNAME(LVector2) &x) {
return FLOATNAME(LMatrix3)(1, 0, 0,
0, x[0], x[1],
0, -x[1], x[0]);
}
INLINE FLOATNAME(LMatrix3)
make_x_mat(const FLOATNAME(LVector2) &x) {
return FLOATNAME(LMatrix3)(1, 0, 0,
0, x[1], x[0],
0, -x[0], x[1]);
}
INLINE FLOATNAME(LMatrix3)
make_y_mat(const FLOATNAME(LVector2) &y) {
return FLOATNAME(LMatrix3)(y[1], 0, -y[0],
0, 1, 0,
y[0], 0, y[1]);
}
INLINE FLOATNAME(LMatrix3)
make_z_mat(const FLOATNAME(LVector2) &z) {
return FLOATNAME(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.
////////////////////////////////////////////////////////////////////
static void
_heads_up(FLOATNAME(LMatrix3) &mat, const FLOATNAME(LVector3) &fwd,
const FLOATNAME(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.
FLOATNAME(LVector2) y(up[0], up[2]);
FLOATTYPE1 d = dot(y, y);
if (d==0.0) {
y = FLOATNAME(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.
FLOATNAME(LVector2) x(up[1], up[0]*y[0]+up[2]*y[1]);
d = dot(x, x);
if (d==0.0) {
x = FLOATNAME(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.
FLOATNAME(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 = FLOATNAME(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.
FLOATNAME(LVector2) z(up[0], up[1]);
FLOATTYPE1 d = dot(z, z);
if (d==0.0) {
z = FLOATNAME(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.
FLOATNAME(LVector2) x(up[0]*z[0] + up[1]*z[1], up[2]);
d = dot(x, x);
if (d==0.0) {
x = FLOATNAME(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.
FLOATNAME(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 = FLOATNAME(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.
////////////////////////////////////////////////////////////////////
static void
_look_at(FLOATNAME(LMatrix3) &mat, const FLOATNAME(LVector3) &fwd,
const FLOATNAME(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.
FLOATNAME(LVector2) z(fwd[0], fwd[1]);
FLOATTYPE1 d = dot(z, z);
if (d==0.0) {
z = FLOATNAME(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.
FLOATNAME(LVector2) x(fwd[0]*z[0] + fwd[1]*z[1], fwd[2]);
d = dot(x, x);
if (d==0.0) {
x = FLOATNAME(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.
FLOATNAME(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 = FLOATNAME(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.
FLOATNAME(LVector2) y(fwd[0], fwd[2]);
FLOATTYPE1 d = dot(y, y);
if (d==0.0) {
y = FLOATNAME(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.
FLOATNAME(LVector2) x(fwd[1], fwd[0]*y[0]+fwd[2]*y[1]);
d = dot(x, x);
if (d==0.0) {
x = FLOATNAME(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.
FLOATNAME(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 = FLOATNAME(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-
// actually exported.
void
heads_up(FLOATNAME(LMatrix3) &mat, const FLOATNAME(LVector3) &fwd,
const FLOATNAME(LVector3) &up, CoordinateSystem cs) {
_heads_up(mat, fwd, up, cs);
}
void
look_at(FLOATNAME(LMatrix3) &mat, const FLOATNAME(LVector3) &fwd,
const FLOATNAME(LVector3) &up, CoordinateSystem cs) {
_look_at(mat, fwd, up, cs);
}

View File

@ -2,14 +2,53 @@
// Created by: mike (09Jan97)
//
////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////
#include "mathutil.h"
#include <nearly_zero.h>
#include <cmath.h>
////////////////////////////////////////////////////////////////////
// Class : FLOATNAME(Plane)
// Description :
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA FLOATNAME(Plane) {
PUBLISHED:
INLINE FLOATNAME(Plane)(void);
INLINE FLOATNAME(Plane)(const FLOATNAME(Plane) &copy);
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;
}
////////////////////////////////////////////////////////////////////
// Static variables
@ -22,9 +61,9 @@
// intersect the origin, perpendicular to the Z axis.
// It's not clear how useful a default plane is.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE Plane<NumType>::
Plane(void) {
INLINE FLOATNAME(Plane)::
FLOATNAME(Plane)(void) {
_a = 0.0;
_b = 0.0;
_c = 1.0;
@ -36,9 +75,9 @@ Plane(void) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE Plane<NumType>::
Plane(const Plane<NumType> &copy) :
INLINE FLOATNAME(Plane)::
FLOATNAME(Plane)(const FLOATNAME(Plane) &copy) :
_a(copy._a),
_b(copy._b),
_c(copy._c),
@ -54,13 +93,13 @@ Plane(const Plane<NumType> &copy) :
// viewed from the end of the normal vector, looking
// down).
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE Plane<NumType>::
Plane(const LPoint3<NumType> &a, const LPoint3<NumType> &b,
const LPoint3<NumType> &c) {
LVector3<NumType> u = b - a;
LVector3<NumType> v = c - a;
LVector3<NumType> p = normalize(cross(u, v));
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));
_a = p[0];
_b = p[1];
@ -74,10 +113,10 @@ Plane(const LPoint3<NumType> &a, const LPoint3<NumType> &b,
// Description: Constructs a plane given a surface normal vector and
// a point within the plane.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE Plane<NumType>::
Plane(const LVector3<NumType> &normal, const LPoint3<NumType> &point) {
LVector3<NumType> p = normalize(normal);
INLINE FLOATNAME(Plane)::
FLOATNAME(Plane)(const FLOATNAME(LVector3) &normal, const FLOATNAME(LPoint3) &point) {
FLOATNAME(LVector3) p = normalize(normal);
_a = p[0];
_b = p[1];
@ -90,9 +129,9 @@ Plane(const LVector3<NumType> &normal, const LPoint3<NumType> &point) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE Plane<NumType>& Plane<NumType>::
operator = (const Plane<NumType>& p) {
INLINE FLOATNAME(Plane)& FLOATNAME(Plane)::
operator = (const FLOATNAME(Plane)& p) {
_a = p._a;
_b = p._b;
_c = p._c;
@ -105,12 +144,12 @@ operator = (const Plane<NumType>& p) {
// Access: Public
// Description: Transforms the plane by the indicated matrix.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE Plane<NumType> Plane<NumType>::
operator * (const LMatrix3<NumType> &mat) const {
LVector3<NumType> new_normal = get_normal() * mat;
LPoint3<NumType> new_point = get_point() * mat;
return Plane<NumType>(new_normal, new_point);
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);
}
////////////////////////////////////////////////////////////////////
@ -118,12 +157,12 @@ operator * (const LMatrix3<NumType> &mat) const {
// Access: Public
// Description: Transforms the plane by the indicated matrix.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE Plane<NumType> Plane<NumType>::
operator * (const LMatrix4<NumType> &mat) const {
LVector3<NumType> new_normal = get_normal() * mat;
LPoint3<NumType> new_point = get_point() * mat;
return Plane<NumType>(new_normal, new_point);
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);
}
////////////////////////////////////////////////////////////////////
@ -133,16 +172,16 @@ operator * (const LMatrix4<NumType> &mat) const {
// perspective transform defined by the frustum,
// accordinate to the indicated coordinate system.
////////////////////////////////////////////////////////////////////
template<class NumType>
LMatrix4<NumType> Plane<NumType>::
INLINE FLOATNAME(LMatrix4) FLOATNAME(Plane)::
get_reflection_mat(void) const {
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;
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;
return LMatrix4<NumType>( 1-2*aa, -2*ab, -2*ac, 0,
return FLOATNAME(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 );
@ -153,10 +192,10 @@ get_reflection_mat(void) const {
// Access: Public
// Description: Returns the surface normal of the plane.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE LVector3<NumType> Plane<NumType>::
INLINE FLOATNAME(LVector3) FLOATNAME(Plane)::
get_normal() const {
return LVector3<NumType>(_a, _b, _c);
return FLOATNAME(LVector3)(_a, _b, _c);
}
////////////////////////////////////////////////////////////////////
@ -166,19 +205,19 @@ get_normal() const {
// used along with the normal returned by get_normal()
// to reconstruct the plane.
////////////////////////////////////////////////////////////////////
template<class NumType>
LPoint3<NumType> Plane<NumType>::
INLINE FLOATNAME(LPoint3) FLOATNAME(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, LPoint3<NumType>(0.0, 0.0, 0.0));
return LPoint3<NumType>(-_d / _a, 0.0, 0.0);
nassertr(_a != 0.0, FLOATNAME(LPoint3)(0.0, 0.0, 0.0));
return FLOATNAME(LPoint3)(-_d / _a, 0.0, 0.0);
} else if (cabs(_b) >= cabs(_c)) {
nassertr(_b != 0.0, LPoint3<NumType>(0.0, 0.0, 0.0));
return LPoint3<NumType>(0.0, -_d / _b, 0.0);
nassertr(_b != 0.0, FLOATNAME(LPoint3)(0.0, 0.0, 0.0));
return FLOATNAME(LPoint3)(0.0, -_d / _b, 0.0);
} else {
nassertr(_c != 0.0, LPoint3<NumType>(0.0, 0.0, 0.0));
return LPoint3<NumType>(0.0, 0.0, -_d / _c);
nassertr(_c != 0.0, FLOATNAME(LPoint3)(0.0, 0.0, 0.0));
return FLOATNAME(LPoint3)(0.0, 0.0, -_d / _c);
}
}
@ -192,9 +231,9 @@ get_point() const {
// the plane (on the opposite side from the normal).
// It's zero if the point is exactly in the plane.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE NumType Plane<NumType>::
dist_to_plane(const LPoint3<NumType> &point) const {
INLINE FLOATTYPE1 FLOATNAME(Plane)::
dist_to_plane(const FLOATNAME(LPoint3) &point) const {
return (_a * point[0] + _b * point[1] + _c * point[2] + _d);
}
@ -208,12 +247,12 @@ dist_to_plane(const LPoint3<NumType> &point) const {
// bearing on the intersection test. If true, sets
// intersection_point to the point of intersection.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool Plane<NumType>::
intersects_line(LPoint3<NumType> &intersection_point,
const LPoint3<NumType> &p1,
const LPoint3<NumType> &p2) const {
NumType t;
INLINE bool FLOATNAME(Plane)::
intersects_line(FLOATNAME(LPoint3) &intersection_point,
const FLOATNAME(LPoint3) &p1,
const FLOATNAME(LPoint3) &p2) const {
FLOATTYPE1 t;
if (!intersects_line(t, p1, p2 - p1)) {
return false;
}
@ -238,12 +277,12 @@ intersects_line(LPoint3<NumType> &intersection_point,
// point from, and t == 1.0 implies at point from +
// delta, with other values of t accordingly.
////////////////////////////////////////////////////////////////////
template<class NumType>
INLINE bool Plane<NumType>::
intersects_line(NumType &t,
const LPoint3<NumType> &from,
const LVector3<NumType> &delta) const {
NumType denom = dot(get_normal(), delta);
INLINE bool FLOATNAME(Plane)::
intersects_line(FLOATTYPE1 &t,
const FLOATNAME(LPoint3) &from,
const FLOATNAME(LVector3) &delta) const {
FLOATTYPE1 denom = dot(get_normal(), delta);
if (IS_NEARLY_ZERO(denom)) {
return false;
}
@ -257,8 +296,8 @@ intersects_line(NumType &t,
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void Plane<NumType>::
INLINE void FLOATNAME(Plane)::
output(ostream &out) const {
out << "Plane(" << _a << " " << _b << " " << _c << " " << _d << ")";
}
@ -268,8 +307,8 @@ output(ostream &out) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void Plane<NumType>::
INLINE void FLOATNAME(Plane)::
write(ostream &out, int indent_level) const {
indent(out, indent_level) << *this << "\n";
}
@ -279,8 +318,8 @@ write(ostream &out, int indent_level) const {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void Plane<NumType>::
INLINE void FLOATNAME(Plane)::
write_datagram(Datagram &dest)
{
dest.add_float32(_a);
@ -294,8 +333,9 @@ write_datagram(Datagram &dest)
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class NumType>
void Plane<NumType>::
INLINE void FLOATNAME(Plane)::
read_datagram(DatagramIterator &source)
{
_a = source.get_float32();

View File

@ -1,2 +1,4 @@
forcetype Plane<float>
forcetype Plane<double>
forcetype Planef
renametype Planef Planef
forcetype Planed
renametype Planed Planed

View File

@ -1,10 +1,10 @@
// Filename: plane.h
// Filename: FLOATNAME(Plane).h
// Created by: mike (09Jan97)
//
////////////////////////////////////////////////////////////////////
//
#ifndef PLANE_H
#define PLANE_H
#ifndef Plane_H
#define Plane_H
//
////////////////////////////////////////////////////////////////////
// Includes
@ -13,76 +13,17 @@
#include <luse.h>
#include <indent.h>
#include <nearly_zero.h>
#include <cmath.h>
#include "mathutil.h"
class Datagram;
class DatagramIterator;
////////////////////////////////////////////////////////////////////
// Defines
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Class : Plane
// Description :
////////////////////////////////////////////////////////////////////
template<class NumType>
class Plane {
PUBLISHED:
INLINE Plane(void);
INLINE Plane(const Plane &copy);
INLINE Plane(const LPoint3<NumType> &a, const LPoint3<NumType> &b,
const LPoint3<NumType> &c);
INLINE Plane(const LVector3<NumType> &normal,
const LPoint3<NumType> &point);
INLINE Plane& operator = (const Plane& copy);
INLINE Plane operator * (const LMatrix3<NumType> &mat) const;
INLINE Plane operator * (const LMatrix4<NumType> &mat) const;
LMatrix4<NumType>
get_reflection_mat(void) const;
INLINE LVector3<NumType> get_normal() const;
LPoint3<NumType> get_point() const;
INLINE NumType dist_to_plane(const LPoint3<NumType> &point) const;
INLINE bool intersects_line(LPoint3<NumType> &intersection_point,
const LPoint3<NumType> &p1,
const LPoint3<NumType> &p2) const;
INLINE bool intersects_line(NumType &t,
const LPoint3<NumType> &from,
const LVector3<NumType> &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<class NumType>
INLINE ostream &operator << (ostream &out, const Plane<NumType> &p) {
p.output(out);
return out;
}
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, Plane<float>)
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, Plane<double>)
typedef Plane<float> Planef;
typedef Plane<double> Planed;
#include "fltnames.I"
#include "plane.I"
// Tell GCC that we'll take care of the instantiation explicitly here.
#ifdef __GNUC__
#pragma interface
#endif
#include "dblnames.I"
#include "plane.I"
#endif

View File

@ -4,89 +4,11 @@
////////////////////////////////////////////////////////////////////
#include <pandabase.h>
#include "rotate_to.h"
#include "luse.h"
#include <math.h>
#include "rotate_to.h"
////////////////////////////////////////////////////////////////////
// Function: _rotate_to
// Description: Computes the matrix necessary to rotate vector a onto
// vector b. It is assumed that both vectors are
// normalized.
////////////////////////////////////////////////////////////////////
template<class NumType>
static void
_rotate_to(LMatrix3<NumType> &mat,
const LVector3<NumType> &a, const LVector3<NumType> &b) {
NumType cos_theta = a.dot(b);
#include "fltnames.I"
#include "rotate_to_src.I"
LVector3<NumType> 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<NumType> absa(fabs(a[0]), fabs(a[1]), fabs(a[2]));
LVector3<NumType> 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<NumType>::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);
}
#include "dblnames.I"
#include "rotate_to_src.I"

View File

@ -17,9 +17,8 @@
//
////////////////////////////////////////////////////////////////////
#include <math.h>
#include <pandabase.h>
#include "lmatrix.h"
#include "luse.h"
BEGIN_PUBLISH

View File

@ -0,0 +1,75 @@
// Filename: rotate_to.cxx
// Created by: drose (04Nov99)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: _rotate_to
// Description: Computes the matrix necessary to rotate vector a onto
// vector b. It is assumed that both vectors are
// normalized.
////////////////////////////////////////////////////////////////////
static void
_rotate_to(FLOATNAME(LMatrix3) &mat,
const FLOATNAME(LVector3) &a, const FLOATNAME(LVector3) &b) {
FLOATTYPE1 cos_theta = a.dot(b);
FLOATNAME(LVector3) axis = a.cross(b);
FLOATTYPE1 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.
FLOATNAME(LVector3) absa(fabs(a[0]), fabs(a[1]), fabs(a[2]));
FLOATNAME(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 = FLOATNAME(LMatrix3)::ident_mat();
return;
}
} else {
// The vectors are not collinear; determine the best axis.
axis /= sin_theta;
}
FLOATTYPE1 x = axis[0];
FLOATTYPE1 y = axis[1];
FLOATTYPE1 z = axis[2];
FLOATTYPE1 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(FLOATNAME(LMatrix3) &mat, const FLOATNAME(LVector3) &a, const FLOATNAME(LVector3) &b) {
_rotate_to(mat, a, b);
}
void
rotate_to(FLOATNAME(LMatrix4) &mat, const FLOATNAME(LVector3) &a, const FLOATNAME(LVector3) &b) {
FLOATNAME(LMatrix3) m3;
_rotate_to(m3, a, b);
mat = FLOATNAME(LMatrix4)(m3);
}

View File

@ -91,7 +91,7 @@ child_integrate(Physical *physical,
force_node = cur_force->get_force_node();
// now we go from force space to our object's space.
f = matrices[index++] * cur_force->get_vector(current_object);
f = cur_force->get_vector(current_object) * matrices[index++];
// tally it into the accum vector, applying the inertial tensor.
accum_vec += f;
@ -109,7 +109,7 @@ child_integrate(Physical *physical,
force_node = cur_force->get_force_node();
// go from force space to object space
f = matrices[index++] * cur_force->get_vector(current_object);
f = cur_force->get_vector(current_object) * matrices[index++];
// tally it into the accum vectors
accum_vec += f;
@ -118,7 +118,7 @@ child_integrate(Physical *physical,
// apply the accumulated torque vector to the object's inertial tensor.
// this matrix represents how much force the object 'wants' applied to it
// in any direction, among other things.
accum_vec = current_object->get_inertial_tensor() * accum_vec;
accum_vec = accum_vec * current_object->get_inertial_tensor();
// derive this into the angular velocity vector.
LVector3f rot_vec = current_object->get_rotation();

Some files were not shown because too many files have changed in this diff Show More