mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
Added CollisionBox courtesy CMU ETC student Amith Tudur
This commit is contained in:
parent
a4cd716f9f
commit
8278b963bd
@ -11,3 +11,4 @@
|
||||
#include "collisionTraverser.cxx"
|
||||
#include "collisionTube.cxx"
|
||||
#include "collisionVisualizer.cxx"
|
||||
#include "collisionBox.cxx"
|
||||
|
362
panda/src/collide/collisionBox.I
Normal file
362
panda/src/collide/collisionBox.I
Normal file
@ -0,0 +1,362 @@
|
||||
// Filename: collisionBox.I
|
||||
// Created by: amith tudur (31Jul09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::Constructor
|
||||
// Access: Public
|
||||
// Description: Create the Box by giving a Center and distances of
|
||||
// of each of the sides of box from the Center.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CollisionBox::
|
||||
CollisionBox(const LPoint3f ¢er, float x, float y, float z) :
|
||||
_center(center), _x(x), _y(y), _z(z)
|
||||
{
|
||||
_min = LPoint3f(_center.get_x() - _x, _center.get_y() - _y, _center.get_z() - _z);
|
||||
_max = LPoint3f(_center.get_x() + _x, _center.get_y() + _y, _center.get_z() + _z);
|
||||
_radius = sqrt(_x*_x + _y*_y + _z*_z);
|
||||
for(int v = 0; v < 8; v++)
|
||||
_vertex[v] = get_point_aabb(v);
|
||||
for(int p = 0; p < 6; p++)
|
||||
_planes[p] = set_plane(p);
|
||||
setup_box();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::Constructor
|
||||
// Access: Public
|
||||
// Description: Create the Box by Specifying the Diagonal Points
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CollisionBox::
|
||||
CollisionBox(const LPoint3f &min, const LPoint3f &max) :
|
||||
_min(min), _max(max)
|
||||
{
|
||||
_center = (_min + _max) / 2;
|
||||
_x = _center.get_x() - _min.get_x();
|
||||
_y = _center.get_y() - _min.get_y();
|
||||
_z = _center.get_z() - _min.get_z();
|
||||
_radius = sqrt(_x*_x + _y*_y + _z*_z);
|
||||
for(int v = 0; v < 8; v++)
|
||||
_vertex[v] = get_point_aabb(v);
|
||||
for(int p = 0; p < 6; p++)
|
||||
_planes[p] = set_plane(p);
|
||||
setup_box();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::Constructor
|
||||
// Access: Public
|
||||
// Description: Center as three separate co-ordinate points
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CollisionBox::
|
||||
CollisionBox(float cx, float cy, float cz, float x, float y, float z)
|
||||
{
|
||||
CollisionBox(LPoint3f(cx, cy, cz), x, y, z);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::Default constructor
|
||||
// Access: Protected
|
||||
// Description: Creates an invalid Box. Only used when reading
|
||||
// from a bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CollisionBox::
|
||||
CollisionBox() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CollisionBox::
|
||||
CollisionBox(const CollisionBox ©) :
|
||||
CollisionSolid(copy),
|
||||
_center(copy._center),
|
||||
_x( copy._x ),
|
||||
_y( copy._y ),
|
||||
_z( copy._z ),
|
||||
_min( copy._min),
|
||||
_max( copy._max),
|
||||
_radius( copy._radius )
|
||||
{
|
||||
for(int v = 0; v < 8; v++)
|
||||
_vertex[v] = copy._vertex[v];
|
||||
for(int p = 0; p < 6; p++)
|
||||
_planes[p] = copy._planes[p];
|
||||
setup_box();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::flush_level
|
||||
// Access: Public, Static
|
||||
// Description: Flushes the PStatCollectors used during traversal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionBox::
|
||||
flush_level() {
|
||||
_volume_pcollector.flush_level();
|
||||
_test_pcollector.flush_level();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::set_center
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionBox::
|
||||
set_center(const LPoint3f ¢er) {
|
||||
_center = center;
|
||||
mark_internal_bounds_stale();
|
||||
mark_viz_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::set_center
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionBox::
|
||||
set_center(float x, float y, float z) {
|
||||
set_center(LPoint3f(x, y, z));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::get_center
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LPoint3f &CollisionBox::
|
||||
get_center() const {
|
||||
return _center;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::get_radius
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float CollisionBox::
|
||||
get_radius() const {
|
||||
return _radius;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::get_num_points
|
||||
// Access: Published
|
||||
// Description: Returns 8: the number of vertices of a rectangular solid.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_MATHUTIL int CollisionBox::
|
||||
get_num_points() const {
|
||||
return 8;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::get_point
|
||||
// Access: Published
|
||||
// Description: Returns the nth vertex of the OBB.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_MATHUTIL LPoint3f CollisionBox::
|
||||
get_point(int n) const {
|
||||
nassertr(n >= 0 && n < 8, LPoint3f::zero());
|
||||
return _vertex[n];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::get_point_aabb
|
||||
// Access: Published
|
||||
// Description: Returns the nth vertex of the Axis Aligned Bounding Box.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_MATHUTIL LPoint3f CollisionBox::
|
||||
get_point_aabb(int n) const {
|
||||
nassertr(n >= 0 && n < 8, LPoint3f::zero());
|
||||
|
||||
// We do some trickery assuming that _min and _max are consecutive
|
||||
// in memory.
|
||||
const LPoint3f *a = &_min;
|
||||
return LPoint3f(a[(n>>2)&1][0], a[(n>>1)&1][1], a[(n)&1][2]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::get_num_planes
|
||||
// Access: Published
|
||||
// Description: Returns 6: the number of faces of a rectangular solid.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_MATHUTIL int CollisionBox::
|
||||
get_num_planes() const {
|
||||
return 6;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::get_plane
|
||||
// Access: Published
|
||||
// Description: Returns the nth face of the rectangular solid.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_MATHUTIL Planef CollisionBox::
|
||||
get_plane(int n) const {
|
||||
nassertr(n >= 0 && n < 6, Planef());
|
||||
return _planes[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::set_plane
|
||||
// Access: Published
|
||||
// Description: Creates the nth face of the rectangular solid.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_MATHUTIL Planef CollisionBox::
|
||||
set_plane(int n) const {
|
||||
nassertr(n >= 0 && n < 6, Planef());
|
||||
return Planef(get_point(plane_def[n][0]),
|
||||
get_point(plane_def[n][1]),
|
||||
get_point(plane_def[n][2]));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::is_right
|
||||
// Access: Private, Static
|
||||
// Description: Returns true if the 2-d v1 is to the right of v2.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CollisionBox::
|
||||
is_right(const LVector2f &v1, const LVector2f &v2) {
|
||||
return (v1[0] * v2[1] - v1[1] * v2[0]) > 1.0e-6f;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::dist_to_line
|
||||
// Access: Private, Static
|
||||
// Description: Returns the linear distance of p to the line defined
|
||||
// by f and f+v, where v is a normalized vector. The
|
||||
// result is negative if p is left of the line, positive
|
||||
// if it is right of the line.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float CollisionBox::
|
||||
dist_to_line(const LPoint2f &p,
|
||||
const LPoint2f &f, const LVector2f &v) {
|
||||
LVector2f v1 = (p - f);
|
||||
return (v1[0] * v[1] - v1[1] * v[0]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::to_2d
|
||||
// Access: Private
|
||||
// Description: Assuming the indicated point in 3-d space lies within
|
||||
// the polygon's plane, returns the corresponding point
|
||||
// in the polygon's 2-d definition space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LPoint2f CollisionBox::
|
||||
to_2d(const LVecBase3f &point3d, int plane) const {
|
||||
LPoint3f point = LPoint3f(point3d) * _to_2d_mat[plane];
|
||||
return LPoint2f(point[0], point[2]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::calc_to_3d_mat
|
||||
// Access: Private
|
||||
// Description: Fills the indicated matrix with the appropriate
|
||||
// rotation transform to move points from the 2-d plane
|
||||
// into the 3-d (X, 0, Z) plane.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionBox::
|
||||
calc_to_3d_mat(LMatrix4f &to_3d_mat,int plane) const {
|
||||
// We have to be explicit about the coordinate system--we
|
||||
// specifically mean CS_zup_right, because that points the forward
|
||||
// vector down the Y axis and moves the coords in (X, 0, Z). We
|
||||
// want this effect regardless of the user's coordinate system of
|
||||
// choice.
|
||||
|
||||
// The up vector, on the other hand, is completely arbitrary.
|
||||
|
||||
look_at(to_3d_mat, -get_plane(plane).get_normal(),
|
||||
LVector3f(0.0f, 0.0f, 1.0f), CS_zup_right);
|
||||
to_3d_mat.set_row(3, get_plane(plane).get_point());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::rederive_to_3d_mat
|
||||
// Access: Private
|
||||
// Description: Fills the indicated matrix with the appropriate
|
||||
// rotation transform to move points from the 2-d plane
|
||||
// into the 3-d (X, 0, Z) plane.
|
||||
//
|
||||
// This is essentially similar to calc_to_3d_mat, except
|
||||
// that the matrix is rederived from whatever is stored
|
||||
// in _to_2d_mat, guaranteeing that it will match
|
||||
// whatever algorithm produced that one, even if it was
|
||||
// produced on a different machine with different
|
||||
// numerical precision.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionBox::
|
||||
rederive_to_3d_mat(LMatrix4f &to_3d_mat, int plane) const {
|
||||
to_3d_mat.invert_from(_to_2d_mat[plane]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::to_3d
|
||||
// Access: Private, Static
|
||||
// Description: Extrude the indicated point in the polygon's 2-d
|
||||
// definition space back into 3-d coordinates.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LPoint3f CollisionBox::
|
||||
to_3d(const LVecBase2f &point2d, const LMatrix4f &to_3d_mat) {
|
||||
return LPoint3f(point2d[0], 0.0f, point2d[1]) * to_3d_mat;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::PointDef::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CollisionBox::PointDef::
|
||||
PointDef(const LPoint2f &p, const LVector2f &v) : _p(p), _v(v) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::PointDef::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CollisionBox::PointDef::
|
||||
PointDef(float x, float y) : _p(x, y), _v(0.0f, 0.0f) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::PointDef::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CollisionBox::PointDef::
|
||||
PointDef(const CollisionBox::PointDef ©) : _p(copy._p), _v(copy._v) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::PointDef::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CollisionBox::PointDef::
|
||||
operator = (const CollisionBox::PointDef ©) {
|
||||
_p = copy._p;
|
||||
_v = copy._v;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::get_plane_points
|
||||
// Access: Public
|
||||
// Description: returns the points that form the nth plane
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
INLINE CollisionBox::Points CollisionBox::
|
||||
get_plane_points( int n ){
|
||||
return _points[n];
|
||||
}
|
1044
panda/src/collide/collisionBox.cxx
Normal file
1044
panda/src/collide/collisionBox.cxx
Normal file
File diff suppressed because it is too large
Load Diff
175
panda/src/collide/collisionBox.h
Normal file
175
panda/src/collide/collisionBox.h
Normal file
@ -0,0 +1,175 @@
|
||||
// Filename: collisionBox.h
|
||||
// Created by: amith tudur( 31Jul09 )
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef COLLISIONBOX_H
|
||||
#define COLLISIONBOX_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "collisionSolid.h"
|
||||
#include "parabola.h"
|
||||
#include "plane.h"
|
||||
#include "look_at.h"
|
||||
#include "clipPlaneAttrib.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : CollisionBox
|
||||
// Description : A cuboid collision volume or object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_COLLIDE CollisionBox : public CollisionSolid {
|
||||
PUBLISHED:
|
||||
INLINE CollisionBox(const LPoint3f ¢er,
|
||||
float x, float y, float z);
|
||||
INLINE CollisionBox(float cx, float cy, float cz,
|
||||
float x, float y, float z);
|
||||
INLINE CollisionBox(const LPoint3f &min, const LPoint3f &max);
|
||||
|
||||
virtual LPoint3f get_collision_origin() const;
|
||||
|
||||
protected:
|
||||
INLINE CollisionBox();
|
||||
|
||||
public:
|
||||
INLINE CollisionBox(const CollisionBox ©);
|
||||
virtual CollisionSolid *make_copy();
|
||||
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection(const CollisionEntry &entry) const;
|
||||
virtual void xform(const LMatrix4f &mat);
|
||||
|
||||
virtual PStatCollector &get_volume_pcollector();
|
||||
virtual PStatCollector &get_test_pcollector();
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
virtual LPoint3f get_approx_center() const;
|
||||
virtual LPoint3f get_min() const;
|
||||
virtual LPoint3f get_max() const;
|
||||
|
||||
INLINE static void flush_level();
|
||||
void setup_box();
|
||||
|
||||
PUBLISHED:
|
||||
INLINE_MATHUTIL int get_num_points() const;
|
||||
INLINE_MATHUTIL LPoint3f get_point_aabb(int n) const;
|
||||
INLINE_MATHUTIL LPoint3f get_point(int n) const;
|
||||
INLINE_MATHUTIL int get_num_planes() const;
|
||||
INLINE_MATHUTIL Planef set_plane(int n) const;
|
||||
INLINE_MATHUTIL Planef get_plane(int n) const;
|
||||
INLINE void set_center(const LPoint3f ¢er);
|
||||
INLINE void set_center(float x, float y, float z);
|
||||
INLINE const LPoint3f &get_center() const;
|
||||
INLINE float get_radius() const;
|
||||
|
||||
protected:
|
||||
virtual PT(BoundingVolume) compute_internal_bounds() const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_sphere(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_ray(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_box(const CollisionEntry &entry) const;
|
||||
|
||||
virtual void fill_viz_geom();
|
||||
|
||||
protected:
|
||||
Vertexf compute_point(float latitude, float longitude) const;
|
||||
|
||||
private:
|
||||
LPoint3f _center;
|
||||
LPoint3f _min;
|
||||
LPoint3f _max;
|
||||
float _x, _y, _z, _radius;
|
||||
LPoint3f _vertex[8]; // Each of the Eight Vertices of the Box
|
||||
Planef _planes[6]; //Points to each of the six sides of the Box
|
||||
|
||||
static const int plane_def[6][4];
|
||||
|
||||
static PStatCollector _volume_pcollector;
|
||||
static PStatCollector _test_pcollector;
|
||||
|
||||
private:
|
||||
INLINE static bool is_right(const LVector2f &v1, const LVector2f &v2);
|
||||
INLINE static float dist_to_line(const LPoint2f &p,
|
||||
const LPoint2f &f, const LVector2f &v);
|
||||
static float dist_to_line_segment(const LPoint2f &p,
|
||||
const LPoint2f &f, const LPoint2f &t,
|
||||
const LVector2f &v);
|
||||
|
||||
public:
|
||||
class PointDef {
|
||||
public:
|
||||
INLINE PointDef(const LPoint2f &p, const LVector2f &v);
|
||||
INLINE PointDef(float x, float y);
|
||||
INLINE PointDef(const PointDef ©);
|
||||
INLINE void operator = (const PointDef ©);
|
||||
|
||||
LPoint2f _p; // the point in 2-d space
|
||||
LVector2f _v; // the normalized vector to the next point
|
||||
};
|
||||
typedef pvector<PointDef> Points;
|
||||
|
||||
static void compute_vectors(Points &points);
|
||||
void draw_polygon(GeomNode *viz_geom_node, GeomNode *bounds_viz_geom_node,
|
||||
const Points &points) const;
|
||||
|
||||
bool point_is_inside(const LPoint2f &p, const Points &points) const;
|
||||
float dist_to_polygon(const LPoint2f &p, const Points &points) const;
|
||||
|
||||
void setup_points(const LPoint3f *begin, const LPoint3f *end, int plane);
|
||||
INLINE LPoint2f to_2d(const LVecBase3f &point3d, int plane) const;
|
||||
INLINE void calc_to_3d_mat(LMatrix4f &to_3d_mat, int plane) const;
|
||||
INLINE void rederive_to_3d_mat(LMatrix4f &to_3d_mat, int plane) const;
|
||||
INLINE static LPoint3f to_3d(const LVecBase2f &point2d, const LMatrix4f &to_3d_mat);
|
||||
LPoint3f legacy_to_3d(const LVecBase2f &point2d, int axis) const;
|
||||
bool clip_polygon(Points &new_points, const Points &source_points,
|
||||
const Planef &plane,int plane_no) const;
|
||||
bool apply_clip_plane(Points &new_points, const ClipPlaneAttrib *cpa,
|
||||
const TransformState *net_transform, int plane_no) const;
|
||||
|
||||
private:
|
||||
Points _points[6]; // one set of points for each of the six planes that make up the box
|
||||
LMatrix4f _to_2d_mat[6];
|
||||
|
||||
public:
|
||||
INLINE Points get_plane_points( int n );
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &me);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_CollisionBox(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
CollisionSolid::init_type();
|
||||
register_type(_type_handle, "CollisionBox",
|
||||
CollisionSolid::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "collisionBox.I"
|
||||
|
||||
#endif /* COLLISIONBOX_H */
|
@ -19,6 +19,7 @@
|
||||
#include "collisionRay.h"
|
||||
#include "collisionSegment.h"
|
||||
#include "collisionParabola.h"
|
||||
#include "collisionBox.h"
|
||||
#include "collisionEntry.h"
|
||||
#include "boundingSphere.h"
|
||||
#include "datagram.h"
|
||||
@ -309,6 +310,21 @@ test_intersection_from_parabola(const CollisionEntry &) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionSolid::test_intersection_from_box
|
||||
// Access: Protected, Virtual
|
||||
// Description: This is part of the double-dispatch implementation of
|
||||
// test_intersection(). It is called when the "from"
|
||||
// object is a box.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(CollisionEntry) CollisionSolid::
|
||||
test_intersection_from_box(const CollisionEntry &) const {
|
||||
report_undefined_intersection_test(CollisionBox::get_class_type(),
|
||||
get_type());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
class CollisionSolidUndefinedPair {
|
||||
public:
|
||||
|
@ -110,6 +110,8 @@ protected:
|
||||
test_intersection_from_segment(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_parabola(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_box(const CollisionEntry &entry) const;
|
||||
|
||||
static void report_undefined_intersection_test(TypeHandle from_type,
|
||||
TypeHandle into_type);
|
||||
@ -178,6 +180,7 @@ private:
|
||||
friend class CollisionSegment;
|
||||
friend class CollisionParabola;
|
||||
friend class CollisionHandlerFluidPusher;
|
||||
friend class CollisionBox;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const CollisionSolid &cs) {
|
||||
|
@ -456,6 +456,132 @@ test_intersection_from_line(const CollisionEntry &entry) const {
|
||||
return new_entry;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionSphere::test_intersection_from_box
|
||||
// Access: Public, Virtual
|
||||
// Description: Double dispatch point for box as a FROM object
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(CollisionEntry) CollisionSphere::
|
||||
test_intersection_from_box(const CollisionEntry &entry) const {
|
||||
const CollisionBox *box;
|
||||
DCAST_INTO_R(box, entry.get_from(), 0);
|
||||
|
||||
CPT(TransformState) wrt_space = entry.get_wrt_space();
|
||||
CPT(TransformState) wrt_prev_space = entry.get_wrt_prev_space();
|
||||
|
||||
const LMatrix4f &wrt_mat = wrt_space->get_mat();
|
||||
|
||||
CollisionBox local_b( *box );
|
||||
local_b.xform( wrt_mat );
|
||||
|
||||
LPoint3f from_center = local_b.get_center();
|
||||
|
||||
LPoint3f orig_center = get_center();
|
||||
LPoint3f to_center = orig_center;
|
||||
bool moved_from_center = false;
|
||||
float t = 1.0f;
|
||||
LPoint3f contact_point(from_center);
|
||||
float actual_t = 1.0f;
|
||||
|
||||
float to_radius = get_radius();
|
||||
float to_radius_2 = to_radius * to_radius;
|
||||
|
||||
int ip;
|
||||
float max_dist,dist;
|
||||
bool intersect;
|
||||
Planef plane;
|
||||
LVector3f normal;
|
||||
|
||||
for( ip = 0, intersect=false; ip < 6 && !intersect; ip++ ){
|
||||
plane = local_b.get_plane( ip );
|
||||
if (local_b.get_plane_points(ip).size() < 3) {
|
||||
continue;
|
||||
}
|
||||
normal = (has_effective_normal() && box->get_respect_effective_normal()) ? get_effective_normal() : plane.get_normal();
|
||||
|
||||
#ifndef NDEBUG
|
||||
/*
|
||||
if (!IS_THRESHOLD_EQUAL(normal.length_squared(), 1.0f, 0.001), NULL) {
|
||||
collide_cat.info()
|
||||
<< "polygon being collided with " << entry.get_into_node_path()
|
||||
<< " has normal " << normal << " of length " << normal.length()
|
||||
<< "\n";
|
||||
normal.normalize();
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
// The nearest point within the plane to our center is the
|
||||
// intersection of the line (center, center - normal) with the plane.
|
||||
|
||||
if (!plane.intersects_line(dist, to_center, -(plane.get_normal()))) {
|
||||
// No intersection with plane? This means the plane's effective
|
||||
// normal was within the plane itself. A useless polygon.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dist > to_radius || dist < -to_radius) {
|
||||
// No intersection with the plane.
|
||||
continue;
|
||||
}
|
||||
|
||||
LPoint2f p = local_b.to_2d(to_center - dist * plane.get_normal(), ip);
|
||||
float edge_dist = 0.0f;
|
||||
|
||||
edge_dist = local_b.dist_to_polygon(p, local_b.get_plane_points(ip));
|
||||
|
||||
if(edge_dist < 0) {
|
||||
intersect = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if((edge_dist > 0) &&
|
||||
((edge_dist * edge_dist + dist * dist) > to_radius_2)) {
|
||||
// No intersection; the circle is outside the polygon.
|
||||
continue;
|
||||
}
|
||||
|
||||
// The sphere appears to intersect the polygon. If the edge is less
|
||||
// than to_radius away, the sphere may be resting on an edge of
|
||||
// the polygon. Determine how far the center of the sphere must
|
||||
// remain from the plane, based on its distance from the nearest
|
||||
// edge.
|
||||
|
||||
max_dist = to_radius;
|
||||
if (edge_dist >= 0.0f) {
|
||||
float max_dist_2 = max(to_radius_2 - edge_dist * edge_dist, 0.0f);
|
||||
max_dist = csqrt(max_dist_2);
|
||||
}
|
||||
|
||||
if (dist > max_dist) {
|
||||
// There's no intersection: the sphere is hanging off the edge.
|
||||
continue;
|
||||
}
|
||||
intersect = true;
|
||||
}
|
||||
if( !intersect )
|
||||
return NULL;
|
||||
|
||||
if (collide_cat.is_debug()) {
|
||||
collide_cat.debug()
|
||||
<< "intersection detected from " << entry.get_from_node_path()
|
||||
<< " into " << entry.get_into_node_path() << "\n";
|
||||
}
|
||||
|
||||
PT(CollisionEntry) new_entry = new CollisionEntry(entry);
|
||||
|
||||
float into_depth = max_dist - dist;
|
||||
|
||||
new_entry->set_surface_normal(normal);
|
||||
new_entry->set_surface_point(to_center - normal * dist);
|
||||
new_entry->set_interior_point(to_center - normal * (dist + into_depth));
|
||||
new_entry->set_contact_pos(contact_point);
|
||||
new_entry->set_contact_normal(plane.get_normal());
|
||||
new_entry->set_t(actual_t);
|
||||
|
||||
return new_entry;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionSphere::test_intersection_from_ray
|
||||
// Access: Public, Virtual
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "pandabase.h"
|
||||
#include "collisionSolid.h"
|
||||
#include "parabola.h"
|
||||
#include "collisionBox.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : CollisionSphere
|
||||
@ -72,6 +73,8 @@ protected:
|
||||
test_intersection_from_segment(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_parabola(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_box(const CollisionEntry &entry) const;
|
||||
|
||||
virtual void fill_viz_geom();
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "collisionRecorder.h"
|
||||
#include "collisionVisualizer.h"
|
||||
#include "collisionSphere.h"
|
||||
#include "collisionBox.h"
|
||||
#include "collisionTube.h"
|
||||
#include "collisionPolygon.h"
|
||||
#include "collisionPlane.h"
|
||||
@ -370,6 +371,7 @@ traverse(const NodePath &root) {
|
||||
CollisionTube::flush_level();
|
||||
CollisionPolygon::flush_level();
|
||||
CollisionPlane::flush_level();
|
||||
CollisionBox::flush_level();
|
||||
}
|
||||
|
||||
#ifdef DO_COLLISION_RECORDING
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "collisionSphere.h"
|
||||
#include "collisionTraverser.h"
|
||||
#include "collisionTube.h"
|
||||
#include "collisionBox.h"
|
||||
#include "collisionVisualizer.h"
|
||||
#include "dconfig.h"
|
||||
|
||||
@ -142,6 +143,7 @@ init_libcollide() {
|
||||
CollisionSphere::init_type();
|
||||
CollisionTraverser::init_type();
|
||||
CollisionTube::init_type();
|
||||
CollisionBox::init_type();
|
||||
|
||||
#ifdef DO_COLLISION_RECORDING
|
||||
CollisionRecorder::init_type();
|
||||
@ -160,4 +162,5 @@ init_libcollide() {
|
||||
CollisionSegment::register_with_read_factory();
|
||||
CollisionSphere::register_with_read_factory();
|
||||
CollisionTube::register_with_read_factory();
|
||||
CollisionBox::register_with_read_factory();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user