Panda3D
 All Classes Functions Variables Enumerations
collisionBox.I
00001 // Filename: collisionBox.I
00002 // Created by:  amith tudur (31Jul09)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 
00016 ////////////////////////////////////////////////////////////////////
00017 //     Function: CollisionBox::Constructor
00018 //       Access: Public
00019 //  Description: Create the Box by giving a Center and distances of
00020 //               of each of the sides of box from the Center.
00021 ////////////////////////////////////////////////////////////////////
00022 INLINE CollisionBox::
00023 CollisionBox(const LPoint3 &center, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) :
00024   _center(center), _x(x), _y(y), _z(z)
00025 {
00026   _min = LPoint3(_center.get_x() - _x, _center.get_y() - _y, _center.get_z() - _z);
00027   _max = LPoint3(_center.get_x() + _x, _center.get_y() + _y, _center.get_z() + _z); 
00028   _radius = sqrt(_x*_x + _y*_y + _z*_z);
00029   for(int v = 0; v < 8; v++)
00030     _vertex[v] = get_point_aabb(v);
00031   for(int p = 0; p < 6; p++)
00032     _planes[p] = set_plane(p);
00033   setup_box();
00034 }
00035 
00036 ////////////////////////////////////////////////////////////////////
00037 //     Function: CollisionBox::Constructor
00038 //       Access: Public
00039 //  Description: Create the Box by Specifying the Diagonal Points
00040 ////////////////////////////////////////////////////////////////////
00041 INLINE CollisionBox::
00042 CollisionBox(const LPoint3 &min, const LPoint3 &max) :
00043   _min(min), _max(max)
00044 {
00045   _center = (_min + _max) / 2;
00046   _x = _center.get_x() - _min.get_x();
00047   _y = _center.get_y() - _min.get_y();
00048   _z = _center.get_z() - _min.get_z();
00049   _radius = sqrt(_x*_x + _y*_y + _z*_z);
00050   for(int v = 0; v < 8; v++)
00051     _vertex[v] = get_point_aabb(v);
00052   for(int p = 0; p < 6; p++)
00053     _planes[p] = set_plane(p);
00054   setup_box();
00055 }
00056 
00057 ////////////////////////////////////////////////////////////////////
00058 //     Function: CollisionBox::Default constructor
00059 //       Access: Protected
00060 //  Description: Creates an invalid Box.  Only used when reading
00061 //               from a bam file.
00062 ////////////////////////////////////////////////////////////////////
00063 INLINE CollisionBox::
00064 CollisionBox() {
00065 }
00066 
00067 ////////////////////////////////////////////////////////////////////
00068 //     Function: CollisionBox::Copy Constructor
00069 //       Access: Public
00070 //  Description:
00071 ////////////////////////////////////////////////////////////////////
00072 INLINE CollisionBox::
00073 CollisionBox(const CollisionBox &copy) :
00074   CollisionSolid(copy),
00075   _center(copy._center),
00076   _min(copy._min),
00077   _max(copy._max),
00078   _x(copy._x ),
00079   _y(copy._y ),
00080   _z(copy._z ),
00081   _radius(copy._radius )
00082 {
00083   for(int v = 0; v < 8; v++)
00084     _vertex[v] = copy._vertex[v];
00085   for(int p = 0; p < 6; p++)
00086     _planes[p] = copy._planes[p];
00087   setup_box();
00088 }
00089 
00090 ////////////////////////////////////////////////////////////////////
00091 //     Function: CollisionBox::flush_level
00092 //       Access: Public, Static
00093 //  Description: Flushes the PStatCollectors used during traversal.
00094 ////////////////////////////////////////////////////////////////////
00095 INLINE void CollisionBox::
00096 flush_level() {
00097   _volume_pcollector.flush_level();
00098   _test_pcollector.flush_level();
00099 }
00100 
00101 ////////////////////////////////////////////////////////////////////
00102 //     Function: CollisionBox::set_center
00103 //       Access: Published
00104 //  Description:
00105 ////////////////////////////////////////////////////////////////////
00106 INLINE void CollisionBox::
00107 set_center(const LPoint3 &center) {
00108   _center = center;
00109   mark_internal_bounds_stale();
00110   mark_viz_stale();
00111 }
00112 
00113 ////////////////////////////////////////////////////////////////////
00114 //     Function: CollisionBox::set_center
00115 //       Access: Published
00116 //  Description:
00117 ////////////////////////////////////////////////////////////////////
00118 INLINE void CollisionBox::
00119 set_center(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
00120   set_center(LPoint3(x, y, z));
00121 }
00122 
00123 ////////////////////////////////////////////////////////////////////
00124 //     Function: CollisionBox::get_center
00125 //       Access: Published
00126 //  Description:
00127 ////////////////////////////////////////////////////////////////////
00128 INLINE const LPoint3 &CollisionBox::
00129 get_center() const {
00130   return _center;
00131 }
00132 
00133 ////////////////////////////////////////////////////////////////////
00134 //     Function: CollisionBox::get_radius
00135 //       Access: Published
00136 //  Description:
00137 ////////////////////////////////////////////////////////////////////
00138 INLINE PN_stdfloat CollisionBox::
00139 get_radius() const {
00140   return _radius;
00141 }
00142 
00143 ////////////////////////////////////////////////////////////////////
00144 //     Function: CollisionBox::get_num_points
00145 //       Access: Published
00146 //  Description: Returns 8: the number of vertices of a rectangular solid.
00147 ////////////////////////////////////////////////////////////////////
00148 INLINE_MATHUTIL int CollisionBox::
00149 get_num_points() const {
00150   return 8;
00151 }
00152 
00153 ////////////////////////////////////////////////////////////////////
00154 //     Function: CollisionBox::get_point
00155 //       Access: Published
00156 //  Description: Returns the nth vertex of the OBB.
00157 ////////////////////////////////////////////////////////////////////
00158 INLINE_MATHUTIL LPoint3 CollisionBox::
00159 get_point(int n) const {
00160   nassertr(n >= 0 && n < 8, LPoint3::zero());
00161   return _vertex[n];
00162 }
00163 
00164 
00165 ////////////////////////////////////////////////////////////////////
00166 //     Function: CollisionBox::get_point_aabb
00167 //       Access: Published
00168 //  Description: Returns the nth vertex of the Axis Aligned Bounding Box.
00169 ////////////////////////////////////////////////////////////////////
00170 INLINE_MATHUTIL LPoint3 CollisionBox::
00171 get_point_aabb(int n) const {
00172   nassertr(n >= 0 && n < 8, LPoint3::zero());
00173   
00174   // We do some trickery assuming that _min and _max are consecutive
00175   // in memory.
00176   const LPoint3 *a = &_min;
00177   return LPoint3(a[(n>>2)&1][0], a[(n>>1)&1][1], a[(n)&1][2]);
00178 }
00179 
00180 ////////////////////////////////////////////////////////////////////
00181 //     Function: CollisionBox::get_num_planes
00182 //       Access: Published
00183 //  Description: Returns 6: the number of faces of a rectangular solid.
00184 ////////////////////////////////////////////////////////////////////
00185 INLINE_MATHUTIL int CollisionBox::
00186 get_num_planes() const {
00187   return 6;
00188 }
00189 
00190 ////////////////////////////////////////////////////////////////////
00191 //     Function: CollisionBox::get_plane
00192 //       Access: Published
00193 //  Description: Returns the nth face of the rectangular solid.
00194 ////////////////////////////////////////////////////////////////////
00195 INLINE_MATHUTIL LPlane CollisionBox::
00196 get_plane(int n) const {
00197   nassertr(n >= 0 && n < 6, LPlane());
00198   return _planes[n];
00199 }
00200 
00201 ////////////////////////////////////////////////////////////////////
00202 //     Function: CollisionBox::set_plane
00203 //       Access: Published
00204 //  Description: Creates the nth face of the rectangular solid.
00205 ////////////////////////////////////////////////////////////////////
00206 INLINE_MATHUTIL LPlane CollisionBox::
00207 set_plane(int n) const {
00208   nassertr(n >= 0 && n < 6, LPlane());
00209   return LPlane(get_point(plane_def[n][0]),
00210                 get_point(plane_def[n][1]),
00211                 get_point(plane_def[n][2]));
00212 }
00213 
00214 
00215 ////////////////////////////////////////////////////////////////////
00216 //     Function: CollisionBox::is_right
00217 //       Access: Private, Static
00218 //  Description: Returns true if the 2-d v1 is to the right of v2.
00219 ////////////////////////////////////////////////////////////////////
00220 INLINE bool CollisionBox::
00221 is_right(const LVector2 &v1, const LVector2 &v2) {
00222   return (v1[0] * v2[1] - v1[1] * v2[0]) > 1.0e-6f;
00223 }
00224 
00225 ////////////////////////////////////////////////////////////////////
00226 //     Function: CollisionBox::dist_to_line
00227 //       Access: Private, Static
00228 //  Description: Returns the linear distance of p to the line defined
00229 //               by f and f+v, where v is a normalized vector.  The
00230 //               result is negative if p is left of the line, positive
00231 //               if it is right of the line.
00232 ////////////////////////////////////////////////////////////////////
00233 INLINE PN_stdfloat CollisionBox::
00234 dist_to_line(const LPoint2 &p,
00235              const LPoint2 &f, const LVector2 &v) {
00236   LVector2 v1 = (p - f);
00237   return (v1[0] * v[1] - v1[1] * v[0]);
00238 }
00239 
00240 ////////////////////////////////////////////////////////////////////
00241 //     Function: CollisionBox::to_2d
00242 //       Access: Private
00243 //  Description: Assuming the indicated point in 3-d space lies within
00244 //               the polygon's plane, returns the corresponding point
00245 //               in the polygon's 2-d definition space.
00246 ////////////////////////////////////////////////////////////////////
00247 INLINE LPoint2 CollisionBox::
00248 to_2d(const LVecBase3 &point3d, int plane) const {
00249   LPoint3 point = LPoint3(point3d) * _to_2d_mat[plane];
00250   return LPoint2(point[0], point[2]);
00251 }
00252 
00253 ////////////////////////////////////////////////////////////////////
00254 //     Function: CollisionBox::calc_to_3d_mat
00255 //       Access: Private
00256 //  Description: Fills the indicated matrix with the appropriate
00257 //               rotation transform to move points from the 2-d plane
00258 //               into the 3-d (X, 0, Z) plane.
00259 ////////////////////////////////////////////////////////////////////
00260 INLINE void CollisionBox::
00261 calc_to_3d_mat(LMatrix4 &to_3d_mat,int plane) const {
00262   // We have to be explicit about the coordinate system--we
00263   // specifically mean CS_zup_right, because that points the forward
00264   // vector down the Y axis and moves the coords in (X, 0, Z).  We
00265   // want this effect regardless of the user's coordinate system of
00266   // choice.
00267 
00268   // The up vector, on the other hand, is completely arbitrary.
00269 
00270   look_at(to_3d_mat, -get_plane(plane).get_normal(), 
00271           LVector3(0.0f, 0.0f, 1.0f), CS_zup_right);
00272   to_3d_mat.set_row(3, get_plane(plane).get_point());
00273 }
00274 
00275 ////////////////////////////////////////////////////////////////////
00276 //     Function: CollisionBox::rederive_to_3d_mat
00277 //       Access: Private
00278 //  Description: Fills the indicated matrix with the appropriate
00279 //               rotation transform to move points from the 2-d plane
00280 //               into the 3-d (X, 0, Z) plane.
00281 //
00282 //               This is essentially similar to calc_to_3d_mat, except
00283 //               that the matrix is rederived from whatever is stored
00284 //               in _to_2d_mat, guaranteeing that it will match
00285 //               whatever algorithm produced that one, even if it was
00286 //               produced on a different machine with different
00287 //               numerical precision.
00288 ////////////////////////////////////////////////////////////////////
00289 INLINE void CollisionBox::
00290 rederive_to_3d_mat(LMatrix4 &to_3d_mat, int plane) const {
00291   to_3d_mat.invert_from(_to_2d_mat[plane]);
00292 }
00293 
00294 ////////////////////////////////////////////////////////////////////
00295 //     Function: CollisionBox::to_3d
00296 //       Access: Private, Static
00297 //  Description: Extrude the indicated point in the polygon's 2-d
00298 //               definition space back into 3-d coordinates.
00299 ////////////////////////////////////////////////////////////////////
00300 INLINE LPoint3 CollisionBox::
00301 to_3d(const LVecBase2 &point2d, const LMatrix4 &to_3d_mat) {
00302   return LPoint3(point2d[0], 0.0f, point2d[1]) * to_3d_mat;
00303 }
00304 
00305 ////////////////////////////////////////////////////////////////////
00306 //     Function: CollisionBox::PointDef::Constructor
00307 //       Access: Public
00308 //  Description: 
00309 ////////////////////////////////////////////////////////////////////
00310 INLINE CollisionBox::PointDef::
00311 PointDef(const LPoint2 &p, const LVector2 &v) : _p(p), _v(v) {
00312 }
00313 
00314 ////////////////////////////////////////////////////////////////////
00315 //     Function: CollisionBox::PointDef::Constructor
00316 //       Access: Public
00317 //  Description: 
00318 ////////////////////////////////////////////////////////////////////
00319 INLINE CollisionBox::PointDef::
00320 PointDef(PN_stdfloat x, PN_stdfloat y) : _p(x, y), _v(0.0f, 0.0f) {
00321 }
00322 
00323 ////////////////////////////////////////////////////////////////////
00324 //     Function: CollisionBox::PointDef::Copy Constructor
00325 //       Access: Public
00326 //  Description: 
00327 ////////////////////////////////////////////////////////////////////
00328 INLINE CollisionBox::PointDef::
00329 PointDef(const CollisionBox::PointDef &copy) : _p(copy._p), _v(copy._v) {
00330 }
00331 
00332 ////////////////////////////////////////////////////////////////////
00333 //     Function: CollisionBox::PointDef::Copy Assignment Operator
00334 //       Access: Public
00335 //  Description: 
00336 ////////////////////////////////////////////////////////////////////
00337 INLINE void CollisionBox::PointDef::
00338 operator = (const CollisionBox::PointDef &copy) {
00339   _p = copy._p;
00340   _v = copy._v;
00341 }
00342 
00343 ////////////////////////////////////////////////////////////////////
00344 //     Function: CollisionBox::get_plane_points
00345 //       Access: Public
00346 //  Description: returns the points that form the nth plane
00347 ////////////////////////////////////////////////////////////////////
00348 INLINE CollisionBox::Points CollisionBox::
00349 get_plane_points(int n) {
00350   return _points[n];
00351 }
 All Classes Functions Variables Enumerations