mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -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 "collisionTraverser.cxx"
|
||||||
#include "collisionTube.cxx"
|
#include "collisionTube.cxx"
|
||||||
#include "collisionVisualizer.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 "collisionRay.h"
|
||||||
#include "collisionSegment.h"
|
#include "collisionSegment.h"
|
||||||
#include "collisionParabola.h"
|
#include "collisionParabola.h"
|
||||||
|
#include "collisionBox.h"
|
||||||
#include "collisionEntry.h"
|
#include "collisionEntry.h"
|
||||||
#include "boundingSphere.h"
|
#include "boundingSphere.h"
|
||||||
#include "datagram.h"
|
#include "datagram.h"
|
||||||
@ -309,6 +310,21 @@ test_intersection_from_parabola(const CollisionEntry &) const {
|
|||||||
return NULL;
|
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
|
#ifndef NDEBUG
|
||||||
class CollisionSolidUndefinedPair {
|
class CollisionSolidUndefinedPair {
|
||||||
public:
|
public:
|
||||||
|
@ -110,6 +110,8 @@ protected:
|
|||||||
test_intersection_from_segment(const CollisionEntry &entry) const;
|
test_intersection_from_segment(const CollisionEntry &entry) const;
|
||||||
virtual PT(CollisionEntry)
|
virtual PT(CollisionEntry)
|
||||||
test_intersection_from_parabola(const CollisionEntry &entry) const;
|
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,
|
static void report_undefined_intersection_test(TypeHandle from_type,
|
||||||
TypeHandle into_type);
|
TypeHandle into_type);
|
||||||
@ -178,6 +180,7 @@ private:
|
|||||||
friend class CollisionSegment;
|
friend class CollisionSegment;
|
||||||
friend class CollisionParabola;
|
friend class CollisionParabola;
|
||||||
friend class CollisionHandlerFluidPusher;
|
friend class CollisionHandlerFluidPusher;
|
||||||
|
friend class CollisionBox;
|
||||||
};
|
};
|
||||||
|
|
||||||
INLINE ostream &operator << (ostream &out, const CollisionSolid &cs) {
|
INLINE ostream &operator << (ostream &out, const CollisionSolid &cs) {
|
||||||
|
@ -456,6 +456,132 @@ test_intersection_from_line(const CollisionEntry &entry) const {
|
|||||||
return new_entry;
|
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
|
// Function: CollisionSphere::test_intersection_from_ray
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "pandabase.h"
|
#include "pandabase.h"
|
||||||
#include "collisionSolid.h"
|
#include "collisionSolid.h"
|
||||||
#include "parabola.h"
|
#include "parabola.h"
|
||||||
|
#include "collisionBox.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : CollisionSphere
|
// Class : CollisionSphere
|
||||||
@ -72,6 +73,8 @@ protected:
|
|||||||
test_intersection_from_segment(const CollisionEntry &entry) const;
|
test_intersection_from_segment(const CollisionEntry &entry) const;
|
||||||
virtual PT(CollisionEntry)
|
virtual PT(CollisionEntry)
|
||||||
test_intersection_from_parabola(const CollisionEntry &entry) const;
|
test_intersection_from_parabola(const CollisionEntry &entry) const;
|
||||||
|
virtual PT(CollisionEntry)
|
||||||
|
test_intersection_from_box(const CollisionEntry &entry) const;
|
||||||
|
|
||||||
virtual void fill_viz_geom();
|
virtual void fill_viz_geom();
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "collisionRecorder.h"
|
#include "collisionRecorder.h"
|
||||||
#include "collisionVisualizer.h"
|
#include "collisionVisualizer.h"
|
||||||
#include "collisionSphere.h"
|
#include "collisionSphere.h"
|
||||||
|
#include "collisionBox.h"
|
||||||
#include "collisionTube.h"
|
#include "collisionTube.h"
|
||||||
#include "collisionPolygon.h"
|
#include "collisionPolygon.h"
|
||||||
#include "collisionPlane.h"
|
#include "collisionPlane.h"
|
||||||
@ -370,6 +371,7 @@ traverse(const NodePath &root) {
|
|||||||
CollisionTube::flush_level();
|
CollisionTube::flush_level();
|
||||||
CollisionPolygon::flush_level();
|
CollisionPolygon::flush_level();
|
||||||
CollisionPlane::flush_level();
|
CollisionPlane::flush_level();
|
||||||
|
CollisionBox::flush_level();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DO_COLLISION_RECORDING
|
#ifdef DO_COLLISION_RECORDING
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "collisionSphere.h"
|
#include "collisionSphere.h"
|
||||||
#include "collisionTraverser.h"
|
#include "collisionTraverser.h"
|
||||||
#include "collisionTube.h"
|
#include "collisionTube.h"
|
||||||
|
#include "collisionBox.h"
|
||||||
#include "collisionVisualizer.h"
|
#include "collisionVisualizer.h"
|
||||||
#include "dconfig.h"
|
#include "dconfig.h"
|
||||||
|
|
||||||
@ -142,6 +143,7 @@ init_libcollide() {
|
|||||||
CollisionSphere::init_type();
|
CollisionSphere::init_type();
|
||||||
CollisionTraverser::init_type();
|
CollisionTraverser::init_type();
|
||||||
CollisionTube::init_type();
|
CollisionTube::init_type();
|
||||||
|
CollisionBox::init_type();
|
||||||
|
|
||||||
#ifdef DO_COLLISION_RECORDING
|
#ifdef DO_COLLISION_RECORDING
|
||||||
CollisionRecorder::init_type();
|
CollisionRecorder::init_type();
|
||||||
@ -160,4 +162,5 @@ init_libcollide() {
|
|||||||
CollisionSegment::register_with_read_factory();
|
CollisionSegment::register_with_read_factory();
|
||||||
CollisionSphere::register_with_read_factory();
|
CollisionSphere::register_with_read_factory();
|
||||||
CollisionTube::register_with_read_factory();
|
CollisionTube::register_with_read_factory();
|
||||||
|
CollisionBox::register_with_read_factory();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user