38 PStatCollector CollisionCapsule::_volume_pcollector(
"Collision Volumes:CollisionCapsule");
    39 PStatCollector CollisionCapsule::_test_pcollector(
"Collision Tests:CollisionCapsule");
    55   return entry.
get_into()->test_intersection_from_capsule(entry);
    61 void CollisionCapsule::
    62 xform(
const LMatrix4 &mat) {
    68   LVector3 radius_v = LVector3(_radius, 0.0f, 0.0f) * mat;
    69   _radius = length(radius_v);
    72   CollisionSolid::xform(mat);
    91   return _volume_pcollector;
   100   return _test_pcollector;
   106 void CollisionCapsule::
   107 output(std::ostream &out)
 const {
   108   out << 
"capsule, a (" << _a << 
"), b (" << _b << 
"), r " << _radius;
   115 compute_internal_bounds()
 const {
   116   PT(
BoundingVolume) bound = CollisionSolid::compute_internal_bounds();
   118   if (bound->is_of_type(GeometricBoundingVolume::get_class_type())) {
   120     DCAST_INTO_R(gbound, bound, bound);
   122     LVector3 vec = (_b - _a);
   123     if (vec.normalize()) {
   127       points[0] = _a - vec * _radius;
   128       points[1] = _b + vec * _radius;
   130       gbound->
around(points, points + 2);
   147 test_intersection_from_sphere(
const CollisionEntry &entry)
 const {
   149   DCAST_INTO_R(sphere, entry.
get_from(), 
nullptr);
   154   const LMatrix4 &wrt_mat = wrt_space->get_mat();
   156   LPoint3 from_a = sphere->get_center() * wrt_mat;
   157   LPoint3 from_b = from_a;
   159   LPoint3 contact_point;
   160   PN_stdfloat actual_t = 0.0f;
   162   if (wrt_prev_space != wrt_space) {
   164     from_a = sphere->get_center() * wrt_prev_space->get_mat();
   167   LVector3 from_direction = from_b - from_a;
   169   LVector3 from_radius_v =
   170     LVector3(sphere->get_radius(), 0.0f, 0.0f) * wrt_mat;
   171   PN_stdfloat from_radius = length(from_radius_v);
   174   if (!intersects_line(t1, t2, from_a, from_direction, from_radius)) {
   179   if (t2 < 0.0 || t1 > 1.0) {
   186   actual_t = std::min(1.0, std::max(0.0, t1));
   187   contact_point = from_a + actual_t * (from_b - from_a);
   189   if (collide_cat.is_debug()) {
   196   LPoint3 into_intersection_point;
   200     into_intersection_point = from_b;
   204     into_intersection_point = from_a + t2 * from_direction;
   206   set_intersection_point(new_entry, into_intersection_point, from_radius);
   208   LPoint3 fake_contact_point;
   209   LVector3 contact_normal;
   210   calculate_surface_point_and_normal(contact_point,
   214   new_entry->set_contact_pos(contact_point);
   215   new_entry->set_contact_normal(contact_normal);
   216   new_entry->set_t(actual_t);
   227   DCAST_INTO_R(line, entry.
get_from(), 
nullptr);
   229   const LMatrix4 &wrt_mat = entry.get_wrt_mat();
   231   LPoint3 from_origin = line->get_origin() * wrt_mat;
   232   LVector3 from_direction = line->get_direction() * wrt_mat;
   235   if (!intersects_line(t1, t2, from_origin, from_direction, 0.0f)) {
   240   if (collide_cat.is_debug()) {
   247   LPoint3 into_intersection_point = from_origin + t1 * from_direction;
   248   set_intersection_point(new_entry, into_intersection_point, 0.0);
   254     LVector3 normal = into_intersection_point * _inv_mat;
   255     if (normal[1] > _length) {
   257       normal[1] -= _length;
   258     } 
else if (normal[1] > 0.0f) {
   262     normal = normalize(normal * _mat);
   263     new_entry->set_surface_normal(normal);
   275   DCAST_INTO_R(ray, entry.
get_from(), 
nullptr);
   277   const LMatrix4 &wrt_mat = entry.get_wrt_mat();
   279   LPoint3 from_origin = ray->get_origin() * wrt_mat;
   280   LVector3 from_direction = ray->get_direction() * wrt_mat;
   283   if (!intersects_line(t1, t2, from_origin, from_direction, 0.0f)) {
   293   if (collide_cat.is_debug()) {
   300   LPoint3 into_intersection_point;
   304     into_intersection_point = from_origin;
   307     into_intersection_point = from_origin + t1 * from_direction;
   309   set_intersection_point(new_entry, into_intersection_point, 0.0);
   315     LVector3 normal = into_intersection_point * _inv_mat;
   316     if (normal[1] > _length) {
   318       normal[1] -= _length;
   319     } 
else if (normal[1] > 0.0f) {
   323     normal = normalize(normal * _mat);
   324     new_entry->set_surface_normal(normal);
   334 test_intersection_from_segment(
const CollisionEntry &entry)
 const {
   336   DCAST_INTO_R(segment, entry.
get_from(), 
nullptr);
   338   const LMatrix4 &wrt_mat = entry.get_wrt_mat();
   340   LPoint3 from_a = segment->get_point_a() * wrt_mat;
   341   LPoint3 from_b = segment->get_point_b() * wrt_mat;
   342   LVector3 from_direction = from_b - from_a;
   345   if (!intersects_line(t1, t2, from_a, from_direction, 0.0f)) {
   350   if (t2 < 0.0 || t1 > 1.0) {
   356   if (collide_cat.is_debug()) {
   363   LPoint3 into_intersection_point;
   367     into_intersection_point = from_a;
   371     into_intersection_point = from_a + t1 * from_direction;
   373   set_intersection_point(new_entry, into_intersection_point, 0.0);
   379     LVector3 normal = into_intersection_point * _inv_mat;
   380     if (normal[1] > _length) {
   382       normal[1] -= _length;
   383     } 
else if (normal[1] > 0.0f) {
   387     normal = normalize(normal * _mat);
   388     new_entry->set_surface_normal(normal);
   398 test_intersection_from_capsule(
const CollisionEntry &entry)
 const {
   400   DCAST_INTO_R(capsule, entry.
get_from(), 
nullptr);
   403   LVector3 into_direction = _b - into_a;
   405   const LMatrix4 &wrt_mat = entry.get_wrt_mat();
   407   LPoint3 from_a = capsule->get_point_a() * wrt_mat;
   408   LPoint3 from_b = capsule->get_point_b() * wrt_mat;
   409   LVector3 from_direction = from_b - from_a;
   411   LVector3 from_radius_v =
   412     LVector3(capsule->get_radius(), 0.0f, 0.0f) * wrt_mat;
   413   PN_stdfloat from_radius = length(from_radius_v);
   416   double into_t, from_t;
   417   calc_closest_segment_points(into_t, from_t,
   418                               into_a, into_direction,
   419                               from_a, from_direction);
   420   LPoint3 into_closest = into_a + into_direction * into_t;
   421   LPoint3 from_closest = from_a + from_direction * from_t;
   424   LVector3 closest_vec = from_closest - into_closest;
   425   PN_stdfloat distance = closest_vec.length();
   426   if (distance > _radius + from_radius) {
   430   if (collide_cat.is_debug()) {
   440     LVector3 surface_normal = closest_vec * (1.0 / distance);
   442     new_entry->set_surface_point(into_closest + surface_normal * _radius);
   443     new_entry->set_interior_point(from_closest - surface_normal * from_radius);
   447     } 
else if (distance != 0) {
   448       new_entry->set_surface_normal(surface_normal);
   452     set_intersection_point(new_entry, into_closest, 0);
   462 test_intersection_from_parabola(
const CollisionEntry &entry)
 const {
   464   DCAST_INTO_R(parabola, entry.
get_from(), 
nullptr);
   466   const LMatrix4 &wrt_mat = entry.get_wrt_mat();
   470   local_p.xform(wrt_mat);
   473   if (!intersects_parabola(t, local_p, parabola->
get_t1(), parabola->
get_t2(),
   474                            local_p.calc_point(parabola->
get_t1()),
   475                            local_p.calc_point(parabola->
get_t2()))) {
   480   if (collide_cat.is_debug()) {
   487   LPoint3 into_intersection_point = local_p.calc_point(t);
   488   set_intersection_point(new_entry, into_intersection_point, 0.0);
   494     LVector3 normal = into_intersection_point * _inv_mat;
   495     if (normal[1] > _length) {
   497       normal[1] -= _length;
   498     } 
else if (normal[1] > 0.0f) {
   502     normal = normalize(normal * _mat);
   503     new_entry->set_surface_normal(normal);
   513 void CollisionCapsule::
   515   if (collide_cat.is_debug()) {
   517       << 
"Recomputing viz for " << *
this << 
"\n";
   523   LVector3 direction = (_b - _a);
   524   PN_stdfloat length = direction.length();
   533   static const int num_slices = 8;
   534   static const int num_rings = 4;
   536   for (ri = 0; ri < num_rings; ri++) {
   537     for (si = 0; si <= num_slices; si++) {
   538       vertex.add_data3(calc_sphere1_vertex(ri, si, num_rings, num_slices));
   539       vertex.add_data3(calc_sphere1_vertex(ri + 1, si, num_rings, num_slices));
   541     strip->add_next_vertices((num_slices + 1) * 2);
   542     strip->close_primitive();
   546   for (si = 0; si <= num_slices; si++) {
   547     vertex.add_data3(calc_sphere1_vertex(num_rings, si, num_rings, num_slices));
   548     vertex.add_data3(calc_sphere2_vertex(num_rings, si, num_rings, num_slices,
   551   strip->add_next_vertices((num_slices + 1) * 2);
   552   strip->close_primitive();
   555   for (ri = num_rings - 1; ri >= 0; ri--) {
   556     for (si = 0; si <= num_slices; si++) {
   557       vertex.add_data3(calc_sphere2_vertex(ri + 1, si, num_rings, num_slices, length));
   558       vertex.add_data3(calc_sphere2_vertex(ri, si, num_rings, num_slices, length));
   560     strip->add_next_vertices((num_slices + 1) * 2);
   561     strip->close_primitive();
   565   geom->add_primitive(strip);
   569   look_at(mat, direction, LVector3(0.0f, 0.0f, 1.0f), CS_zup_right);
   571   geom->transform_vertices(mat);
   573   _viz_geom->add_geom(geom, get_solid_viz_state());
   574   _bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state());
   581 void CollisionCapsule::
   583   LVector3 direction = (_b - _a);
   584   _length = direction.length();
   586   look_at(_mat, direction, LVector3(0.0f, 0.0f, 1.0f), CS_zup_right);
   588   _inv_mat.invert_from(_mat);
   591   mark_internal_bounds_stale();
   598 LVertex CollisionCapsule::
   599 calc_sphere1_vertex(
int ri, 
int si, 
int num_rings, 
int num_slices) {
   600   PN_stdfloat r = (PN_stdfloat)ri / (PN_stdfloat)num_rings;
   601   PN_stdfloat s = (PN_stdfloat)si / (PN_stdfloat)num_slices;
   604   PN_stdfloat theta = s * 2.0f * MathNumbers::pi;
   605   PN_stdfloat x_rim = ccos(theta);
   606   PN_stdfloat z_rim = csin(theta);
   609   PN_stdfloat phi = r * 0.5f * MathNumbers::pi;
   610   PN_stdfloat to_pole = csin(phi);
   612   PN_stdfloat x = _radius * x_rim * to_pole;
   613   PN_stdfloat y = -_radius * ccos(phi);
   614   PN_stdfloat z = _radius * z_rim * to_pole;
   616   return LVertex(x, y, z);
   623 LVertex CollisionCapsule::
   624 calc_sphere2_vertex(
int ri, 
int si, 
int num_rings, 
int num_slices,
   625                     PN_stdfloat length) {
   626   PN_stdfloat r = (PN_stdfloat)ri / (PN_stdfloat)num_rings;
   627   PN_stdfloat s = (PN_stdfloat)si / (PN_stdfloat)num_slices;
   630   PN_stdfloat theta = s * 2.0f * MathNumbers::pi;
   631   PN_stdfloat x_rim = ccos(theta);
   632   PN_stdfloat z_rim = csin(theta);
   635   PN_stdfloat phi = r * 0.5f * MathNumbers::pi;
   636   PN_stdfloat to_pole = csin(phi);
   638   PN_stdfloat x = _radius * x_rim * to_pole;
   639   PN_stdfloat y = length + _radius * ccos(phi);
   640   PN_stdfloat z = _radius * z_rim * to_pole;
   642   return LVertex(x, y, z);
   649 void CollisionCapsule::
   650 calc_closest_segment_points(
double &t1, 
double &t2,
   651                             const LPoint3 &from1, 
const LVector3 &delta1,
   652                             const LPoint3 &from2, 
const LVector3 &delta2) {
   659   LVector3 w = from1 - from2;
   660   PN_stdfloat a = delta1.dot(delta1); 
   661   PN_stdfloat b = delta1.dot(delta2);
   662   PN_stdfloat c = delta2.dot(delta2); 
   663   PN_stdfloat d = delta1.dot(w);
   664   PN_stdfloat e = delta2.dot(w);
   665   PN_stdfloat D = a * c - b * b; 
   666   PN_stdfloat sN, sD = D;
   667   PN_stdfloat tN, tD = D;
   670   if (IS_NEARLY_ZERO(D)) { 
   683     } 
else if (sN > sD) { 
   701   } 
else if (tN > tD) { 
   704     if ((-d + b) < 0.0) {
   706     } 
else if ((-d + b) > a) {
   715   t1 = (IS_NEARLY_ZERO(sN) ? 0.0 : sN / sD);
   716   t2 = (IS_NEARLY_ZERO(tN) ? 0.0 : tN / tD);
   727 bool CollisionCapsule::
   728 intersects_line(
double &t1, 
double &t2,
   729                 const LPoint3 &from0, 
const LVector3 &delta0,
   730                 PN_stdfloat inflate_radius)
 const {
   733   LPoint3 from = from0 * _inv_mat;
   734   LVector3 delta = delta0 * _inv_mat;
   736   PN_stdfloat radius = _radius + inflate_radius;
   743   LVector2 from2(from[0], from[2]);
   744   LVector2 delta2(delta[0], delta[2]);
   746   double A = dot(delta2, delta2);
   748   if (IS_NEARLY_ZERO(A)) {
   752     if (from2.dot(from2) > radius * radius) {
   757     if (IS_NEARLY_ZERO(delta[1])) {
   762       if (from[1] < -radius || from[1] > _length + radius) {
   766       if (from[1] < 0.0f) {
   768         if (from.dot(from) > radius * radius) {
   771       } 
else if (from[1] > _length) {
   774         if (from.dot(from) > radius * radius) {
   786     t1 = (-radius - from[1]) / delta[1];
   787     t2 = (_length + radius - from[1]) / delta[1];
   794     double B = 2.0f * dot(delta2, from2);
   795     double fc_d2 = dot(from2, from2);
   796     double C = fc_d2 - radius * radius;
   798     double radical = B*B - 4.0*A*C;
   800     if (IS_NEARLY_ZERO(radical)) {
   802       t1 = t2 = -B / (2.0*A);
   804     } 
else if (radical < 0.0) {
   809       double reciprocal_2A = 1.0 / (2.0 * A);
   810       double sqrt_radical = sqrtf(radical);
   811       t1 = ( -B - sqrt_radical ) * reciprocal_2A;
   812       t2 = ( -B + sqrt_radical ) * reciprocal_2A;
   818   PN_stdfloat t1_y = from[1] + t1 * delta[1];
   819   PN_stdfloat t2_y = from[1] + t2 * delta[1];
   821   if (t1_y < -radius && t2_y < -radius) {
   824   } 
else if (t1_y > _length + radius && t2_y > _length + radius) {
   833     if (!sphere_intersects_line(t1a, t2a, 0.0f, from, delta, radius)) {
   840   } 
else if (t1_y > _length) {
   844     if (!sphere_intersects_line(t1b, t2b, _length, from, delta, radius)) {
   856     if (!sphere_intersects_line(t1a, t2a, 0.0f, from, delta, radius)) {
   863   } 
else if (t2_y > _length) {
   867     if (!sphere_intersects_line(t1b, t2b, _length, from, delta, radius)) {
   883 bool CollisionCapsule::
   884 sphere_intersects_line(
double &t1, 
double &t2, PN_stdfloat center_y,
   885                        const LPoint3 &from, 
const LVector3 &delta,
   886                        PN_stdfloat radius) {
   889   double A = dot(delta, delta);
   891   nassertr(A != 0.0, 
false);
   895   double B = 2.0f* dot(delta, fc);
   896   double fc_d2 = dot(fc, fc);
   897   double C = fc_d2 - radius * radius;
   899   double radical = B*B - 4.0*A*C;
   901   if (IS_NEARLY_ZERO(radical)) {
   903     t1 = t2 = -B / (2.0 * A);
   906   } 
else if (radical < 0.0) {
   911   double reciprocal_2A = 1.0 / (2.0 * A);
   912   double sqrt_radical = sqrtf(radical);
   913   t1 = ( -B - sqrt_radical ) * reciprocal_2A;
   914   t2 = ( -B + sqrt_radical ) * reciprocal_2A;
   927 bool CollisionCapsule::
   928 intersects_parabola(
double &t, 
const LParabola ¶bola,
   929                     double t1, 
double t2,
   930                     const LPoint3 &p1, 
const LPoint3 &p2)
 const {
   938   double tmid = (t1 + t2) * 0.5;
   940   if (tmid != t1 && tmid != t2) {
   941     LPoint3 pmid = parabola.calc_point(tmid);
   942     LPoint3 pmid2 = (p1 + p2) * 0.5f;
   944     if ((pmid - pmid2).length_squared() > 0.001f) {
   946       if (intersects_parabola(t, parabola, t1, tmid, p1, pmid)) {
   949       return intersects_parabola(t, parabola, tmid, t2, pmid, p2);
   955   if (!intersects_line(t1a, t2a, p1, p2 - p1, 0.0f)) {
   959   if (t2a < 0.0 || t1a > 1.0) {
   963   t = std::max(t1a, 0.0);
   972 void CollisionCapsule::
   973 calculate_surface_point_and_normal(
const LPoint3 &surface_point,
   975                                    LPoint3 &result_point,
   976                                    LVector3 &result_normal)
 const {
   978   LPoint3 point = surface_point * _inv_mat;
   981   if (point[1] <= 0.0) {
   984     if (!normal.normalize()) {
   985       normal.set(0.0, -1.0, 0.0);
   987     point = normal * _radius;
   989   } 
else if (point[1] >= _length) {
   991     normal.set(point[0], point[1] - _length, point[2]);
   992     if (!normal.normalize()) {
   993       normal.set(0.0, 1.0, 0.0);
   995     point = normal * _radius;
  1000     LVector2d normal2d(point[0], point[2]);
  1001     if (!normal2d.normalize()) {
  1002       normal2d.set(0.0, 1.0);
  1004     normal.set(normal2d[0], 0.0, normal2d[1]);
  1005     point.set(normal[0] * _radius, point[1], normal[2] * _radius);
  1009   result_point = point * _mat;
  1010   result_normal = normal * _mat;
  1018 void CollisionCapsule::
  1020                        const LPoint3 &into_intersection_point,
  1021                        double extra_radius)
 const {
  1025   calculate_surface_point_and_normal(into_intersection_point,
  1057   _a.write_datagram(dg);
  1058   _b.write_datagram(dg);
  1074   node->fillin(scan, manager);
  1083 void CollisionCapsule::
  1085   CollisionSolid::fillin(scan, manager);
  1086   _a.read_datagram(scan);
  1087   _b.read_datagram(scan);
 get_t2
Returns the ending point on the parabola.
 
virtual PStatCollector & get_volume_pcollector()
Returns a PStatCollector that is used to count the number of bounding volume tests made against a sol...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
const LVector3 & get_effective_normal() const
Returns the normal that was set by set_effective_normal().
 
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
 
get_from_node_path
Returns the NodePath that represents the CollisionNode that contains the CollisionSolid that triggere...
 
An infinite ray, with a specific origin and direction.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
virtual LPoint3 get_collision_origin() const
Returns the point in space deemed to be the "origin" of the solid for collision purposes.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
 
virtual PStatCollector & get_test_pcollector()
Returns a PStatCollector that is used to count the number of intersection tests made against a solid ...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
The abstract base class for all things that can collide with other things in the world,...
 
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
 
This defines a bounding sphere, consisting of a center and a radius.
 
Base class for objects that can be written to and read from Bam files.
 
get_parabola
Returns the parabola specified by this solid.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
Defines a series of triangle strips.
 
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
 
A spherical collision volume or object.
 
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
 
void set_interior_point(const LPoint3 &point)
Stores the point, within the interior of the "into" object, which represents the depth to which the "...
 
get_into_node_path
Returns the NodePath that represents the specific CollisionNode or GeomNode instance that was collide...
 
get_respect_effective_normal
See set_respect_effective_normal().
 
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
 
get_t1
Returns the starting point on the parabola.
 
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
 
A lightweight class that represents a single element that may be timed and/or counted via stats.
 
This is another abstract class, for a general class of bounding volumes that actually enclose points ...
 
void parse_params(const FactoryParams ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
 
A finite line segment, with two specific endpoints but no thickness.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
static void register_with_read_factory()
Tells the BamReader how to create objects of type CollisionCapsule.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
Defines a single collision event.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
 
This implements a solid consisting of a cylinder with hemispherical endcaps, also known as a capsule ...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
A container for geometry primitives.
 
An instance of this class is passed to the Factory when requesting it to do its business and construc...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
 
PT(CollisionEntry) CollisionCapsule
Transforms the solid by the indicated matrix.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
An infinite line, similar to a CollisionRay, except that it extends in both directions.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
 
get_into
Returns the CollisionSolid pointer for the particular solid was collided into.
 
get_from
Returns the CollisionSolid pointer for the particular solid that triggered this collision.
 
This defines a parabolic arc, or subset of an arc, similar to the path of a projectile or falling obj...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
bool has_effective_normal() const
Returns true if a special normal was set by set_effective_normal(), false otherwise.
 
A class to retrieve the individual data elements previously stored in a Datagram.
 
TypeHandle is the identifier used to differentiate C++ class types.
 
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
 
void set_surface_point(const LPoint3 &point)
Stores the point, on the surface of the "into" object, at which a collision is detected.
 
bool around(const GeometricBoundingVolume **first, const GeometricBoundingVolume **last)
Resets the volume to enclose only the volumes indicated.
 
void set_surface_normal(const LVector3 &normal)
Stores the surface normal of the "into" object at the point of the intersection.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
bool extend_by(const GeometricBoundingVolume *vol)
Increases the size of the volume to include the given volume.