37PStatCollector CollisionPlane::_volume_pcollector(
"Collision Volumes:CollisionPlane");
38PStatCollector CollisionPlane::_test_pcollector(
"Collision Tests:CollisionPlane");
46 return new CollisionPlane(*
this);
53xform(
const LMatrix4 &mat) {
54 _plane = _plane * mat;
67 return LPoint3::origin();
76 return _volume_pcollector;
85 return _test_pcollector;
92output(std::ostream &out)
const {
93 out <<
"cplane, (" << _plane <<
")";
100compute_internal_bounds()
const {
101 return new BoundingPlane(_plane);
109 const CollisionSphere *sphere;
110 DCAST_INTO_R(sphere, entry.
get_from(),
nullptr);
113 const LMatrix4 &wrt_mat = wrt_space->get_mat();
115 LPoint3 from_center = sphere->get_center() * wrt_mat;
116 LVector3 from_radius_v =
117 LVector3(sphere->get_radius(), 0.0f, 0.0f) * wrt_mat;
118 PN_stdfloat from_radius = length(from_radius_v);
120 PN_stdfloat dist = dist_to_plane(from_center);
121 if (dist > from_radius) {
126 if (collide_cat.is_debug()) {
131 PT(CollisionEntry) new_entry =
new CollisionEntry(entry);
137 new_entry->set_surface_normal(normal);
138 new_entry->set_surface_point(from_center - get_normal() * dist);
139 new_entry->set_interior_point(from_center - get_normal() * from_radius);
149 const CollisionLine *line;
150 DCAST_INTO_R(line, entry.
get_from(),
nullptr);
153 const LMatrix4 &wrt_mat = wrt_space->get_mat();
155 LPoint3 from_origin = line->get_origin() * wrt_mat;
156 LVector3 from_direction = line->get_direction() * wrt_mat;
159 if (!_plane.intersects_line(t, from_origin, from_direction)) {
162 if (_plane.dist_to_plane(from_origin) > 0.0f) {
171 if (collide_cat.is_debug()) {
176 PT(CollisionEntry) new_entry =
new CollisionEntry(entry);
178 LPoint3 into_intersection_point = from_origin + t * from_direction;
184 new_entry->set_surface_normal(normal);
185 new_entry->set_surface_point(into_intersection_point);
195 const CollisionRay *ray;
196 DCAST_INTO_R(ray, entry.
get_from(),
nullptr);
199 const LMatrix4 &wrt_mat = wrt_space->get_mat();
201 LPoint3 from_origin = ray->get_origin() * wrt_mat;
202 LVector3 from_direction = ray->get_direction() * wrt_mat;
206 if (_plane.dist_to_plane(from_origin) < 0.0f) {
212 if (!_plane.intersects_line(t, from_origin, from_direction)) {
224 if (collide_cat.is_debug()) {
229 PT(CollisionEntry) new_entry =
new CollisionEntry(entry);
231 LPoint3 into_intersection_point = from_origin + t * from_direction;
237 new_entry->set_surface_normal(normal);
238 new_entry->set_surface_point(into_intersection_point);
247test_intersection_from_segment(
const CollisionEntry &entry)
const {
248 const CollisionSegment *segment;
249 DCAST_INTO_R(segment, entry.
get_from(),
nullptr);
252 const LMatrix4 &wrt_mat = wrt_space->get_mat();
254 LPoint3 from_a = segment->get_point_a() * wrt_mat;
255 LPoint3 from_b = segment->get_point_b() * wrt_mat;
257 PN_stdfloat dist_a = _plane.dist_to_plane(from_a);
258 PN_stdfloat dist_b = _plane.dist_to_plane(from_b);
260 if (dist_a >= 0.0f && dist_b >= 0.0f) {
265 if (collide_cat.is_debug()) {
270 PT(CollisionEntry) new_entry =
new CollisionEntry(entry);
273 new_entry->set_surface_normal(normal);
276 LVector3 from_direction = from_b - from_a;
277 if (_plane.intersects_line(t, from_a, from_direction)) {
279 if (t >= 0.0f && t <= 1.0f) {
281 new_entry->set_surface_point(from_a + t * from_direction);
285 if (dist_a < dist_b) {
287 new_entry->set_interior_point(from_a);
289 }
else if (dist_b < dist_a) {
291 new_entry->set_interior_point(from_b);
295 new_entry->set_interior_point((from_a + from_b) * 0.5);
305test_intersection_from_capsule(
const CollisionEntry &entry)
const {
306 const CollisionCapsule *capsule;
307 DCAST_INTO_R(capsule, entry.
get_from(),
nullptr);
310 const LMatrix4 &wrt_mat = wrt_space->get_mat();
312 LPoint3 from_a = capsule->get_point_a() * wrt_mat;
313 LPoint3 from_b = capsule->get_point_b() * wrt_mat;
314 LVector3 from_radius_v =
315 LVector3(capsule->get_radius(), 0.0f, 0.0f) * wrt_mat;
316 PN_stdfloat from_radius = length(from_radius_v);
318 PN_stdfloat dist_a = _plane.dist_to_plane(from_a);
319 PN_stdfloat dist_b = _plane.dist_to_plane(from_b);
321 if (dist_a >= from_radius && dist_b >= from_radius) {
326 if (collide_cat.is_debug()) {
331 PT(CollisionEntry) new_entry =
new CollisionEntry(entry);
334 new_entry->set_surface_normal(normal);
337 LVector3 from_direction = from_b - from_a;
338 if (_plane.intersects_line(t, from_a, from_direction)) {
341 new_entry->set_surface_point(from_b - get_normal() * dist_b);
343 }
else if (t <= 0.0f) {
344 new_entry->set_surface_point(from_a - get_normal() * dist_a);
348 new_entry->set_surface_point(from_a + t * from_direction);
353 new_entry->set_surface_point(from_a + 0.5f * from_direction - get_normal() * dist_a);
356 if (IS_NEARLY_EQUAL(dist_a, dist_b)) {
358 new_entry->set_interior_point(from_a + 0.5f * from_direction - get_normal() * from_radius);
360 }
else if (dist_a < dist_b) {
362 new_entry->set_interior_point(from_a - get_normal() * from_radius);
364 }
else if (dist_b < dist_a) {
366 new_entry->set_interior_point(from_b - get_normal() * from_radius);
377test_intersection_from_parabola(
const CollisionEntry &entry)
const {
378 const CollisionParabola *parabola;
379 DCAST_INTO_R(parabola, entry.
get_from(),
nullptr);
382 const LMatrix4 &wrt_mat = wrt_space->get_mat();
386 local_p.xform(wrt_mat);
389 if (_plane.dist_to_plane(local_p.calc_point(parabola->
get_t1())) < 0.0f) {
396 if (!get_plane().intersects_parabola(t1, t2, local_p)) {
402 if (t1 >= parabola->
get_t1() && t1 <= parabola->get_t2()) {
403 if (t2 >= parabola->
get_t1() && t2 <= parabola->get_t2()) {
406 t = std::min(t1, t2);
412 }
else if (t2 >= parabola->
get_t1() && t2 <= parabola->get_t2()) {
422 if (collide_cat.is_debug()) {
427 PT(CollisionEntry) new_entry =
new CollisionEntry(entry);
429 LPoint3 into_intersection_point = local_p.calc_point(t);
433 new_entry->set_surface_normal(normal);
434 new_entry->set_surface_point(into_intersection_point);
445 const CollisionBox *box;
446 DCAST_INTO_R(box, entry.
get_from(),
nullptr);
449 const LMatrix4 &wrt_mat = wrt_space->get_mat();
451 LPoint3 from_center = box->get_center() * wrt_mat;
452 LVector3 from_extents = box->get_dimensions() * 0.5f;
453 PN_stdfloat dist = _plane.dist_to_plane(from_center);
456 LVecBase3 box_x = wrt_mat.get_row3(0) * from_extents[0];
457 LVecBase3 box_y = wrt_mat.get_row3(1) * from_extents[1];
458 LVecBase3 box_z = wrt_mat.get_row3(2) * from_extents[2];
462 PN_stdfloat dx = box_x.dot(_plane.get_normal());
463 PN_stdfloat dy = box_y.dot(_plane.get_normal());
464 PN_stdfloat dz = box_z.dot(_plane.get_normal());
465 PN_stdfloat depth = dist - (cabs(dx) + cabs(dy) + cabs(dz));
472 if (collide_cat.is_debug()) {
477 PT(CollisionEntry) new_entry =
new CollisionEntry(entry);
480 new_entry->set_surface_normal(normal);
484 LPoint3 interior_point = from_center +
485 box_x * ((dx < 0) - (dx > 0)) +
486 box_y * ((dy < 0) - (dy > 0)) +
487 box_z * ((dz < 0) - (dz > 0));
490 new_entry->set_surface_point(interior_point - get_normal() * depth);
491 new_entry->set_interior_point(interior_point);
502 if (collide_cat.is_debug()) {
504 <<
"Recomputing viz for " << *
this <<
"\n";
519 LVector3 p1, p2, p3, p4;
521 LVector3 normal = get_normal();
522 PN_stdfloat D = _plane[3];
524 if (fabs(normal[0]) > fabs(normal[1]) &&
525 fabs(normal[0]) > fabs(normal[2])) {
527 cp.set(-D / normal[0], 0.0f, 0.0f);
528 p1 = LPoint3(-(normal[1] + normal[2] + D)/normal[0], 1.0f, 1.0f) - cp;
530 }
else if (fabs(normal[1]) > fabs(normal[2])) {
532 cp.set(0.0f, -D / normal[1], 0.0f);
533 p1 = LPoint3(1.0f, -(normal[0] + normal[2] + D)/normal[1], 1.0f) - cp;
537 cp.set(0.0f, 0.0f, -D / normal[2]);
538 p1 = LPoint3(1.0f, 1.0f, -(normal[0] + normal[1] + D)/normal[2]) - cp;
542 p2 = cross(normal, p1);
543 p3 = cross(normal, p2);
544 p4 = cross(normal, p3);
546 static const double plane_scale = 10.0;
548 PT(GeomVertexData) vdata =
new GeomVertexData
551 GeomVertexWriter vertex(vdata, InternalName::get_vertex());
553 vertex.add_data3(cp + p1 * plane_scale);
554 vertex.add_data3(cp + p2 * plane_scale);
555 vertex.add_data3(cp + p3 * plane_scale);
556 vertex.add_data3(cp + p4 * plane_scale);
558 PT(GeomTrifans) body =
new GeomTrifans(Geom::UH_static);
559 body->add_consecutive_vertices(0, 4);
560 body->close_primitive();
562 PT(GeomLinestrips) border =
new GeomLinestrips(Geom::UH_static);
563 border->add_consecutive_vertices(0, 4);
564 border->add_vertex(0);
565 border->close_primitive();
567 PT(Geom) geom1 =
new Geom(vdata);
568 geom1->add_primitive(body);
570 PT(Geom) geom2 =
new Geom(vdata);
571 geom2->add_primitive(border);
573 _viz_geom->add_geom(geom1, get_solid_viz_state());
574 _viz_geom->add_geom(geom2, get_wireframe_viz_state());
576 _bounds_viz_geom->add_geom(geom1, get_solid_bounds_viz_state());
577 _bounds_viz_geom->add_geom(geom2, get_wireframe_bounds_viz_state());
588 _plane.write_datagram(me);
599 CollisionSolid::fillin(scan, manager);
600 _plane.read_datagram(scan);
609 CollisionPlane *me =
new CollisionPlane;
614 me->fillin(scan, manager);
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void parse_params(const FactoryParams ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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...
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
Defines a single collision event.
get_from_node_path
Returns the NodePath that represents the CollisionNode that contains the CollisionSolid that triggere...
get_into_node_path
Returns the NodePath that represents the specific CollisionNode or GeomNode instance that was collide...
get_from
Returns the CollisionSolid pointer for the particular solid that triggered this collision.
get_t1
Returns the starting point on the parabola.
get_parabola
Returns the parabola specified by this solid.
virtual LPoint3 get_collision_origin() const
Returns the point in space deemed to be the "origin" of the solid for collision purposes.
virtual PStatCollector & get_volume_pcollector()
Returns a PStatCollector that is used to count the number of bounding volume tests made against a sol...
static void register_with_read_factory()
Factory method to generate a CollisionPlane object.
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
static TypedWritable * make_CollisionPlane(const FactoryParams ¶ms)
Factory method to generate a CollisionPlane object.
virtual PStatCollector & get_test_pcollector()
Returns a PStatCollector that is used to count the number of intersection tests made against a solid ...
virtual void xform(const LMatrix4 &mat)
Transforms the solid by the indicated matrix.
The abstract base class for all things that can collide with other things in the world,...
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
bool has_effective_normal() const
Returns true if a special normal was set by set_effective_normal(), false otherwise.
const LVector3 & get_effective_normal() const
Returns the normal that was set by set_effective_normal().
virtual void xform(const LMatrix4 &mat)
Transforms the solid by the indicated matrix.
get_respect_effective_normal
See set_respect_effective_normal().
A class to retrieve the individual data elements previously stored in a Datagram.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
An instance of this class is passed to the Factory when requesting it to do its business and construc...
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
A lightweight class that represents a single element that may be timed and/or counted via stats.
TypeHandle is the identifier used to differentiate C++ class types.
Base class for objects that can be written to and read from Bam files.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.