15 #include "collisionSolid.h"
16 #include "config_collide.h"
17 #include "collisionSphere.h"
18 #include "collisionLine.h"
19 #include "collisionRay.h"
20 #include "collisionSegment.h"
21 #include "collisionParabola.h"
22 #include "collisionBox.h"
23 #include "collisionEntry.h"
24 #include "boundingSphere.h"
26 #include "datagramIterator.h"
27 #include "bamReader.h"
28 #include "bamWriter.h"
30 #include "cullFaceAttrib.h"
31 #include "colorAttrib.h"
32 #include "renderModeAttrib.h"
33 #include "transparencyAttrib.h"
37 "Collision Volumes:CollisionSolid");
39 "Collision Tests:CollisionSolid");
48 CollisionSolid() : _lock(
"CollisionSolid") {
49 _flags = F_viz_geom_stale | F_tangible | F_internal_bounds_stale;
60 _effective_normal(copy._effective_normal),
61 _internal_bounds(copy._internal_bounds),
63 _lock(
"CollisionSolid")
65 _flags |= F_viz_geom_stale;
95 if (_flags & F_internal_bounds_stale) {
96 ((
CollisionSolid *)
this)->_internal_bounds = compute_internal_bounds();
99 return _internal_bounds;
110 ((
CollisionSolid *)
this)->_internal_bounds = bounding_volume.make_copy();
125 report_undefined_from_intersection(get_type());
137 if ((_flags & F_effective_normal) != 0) {
138 _effective_normal = _effective_normal * mat;
142 _flags |= F_viz_geom_stale | F_internal_bounds_stale;
156 if ((_flags & F_viz_geom_stale) != 0) {
157 if (_viz_geom == (
GeomNode *)NULL) {
161 _viz_geom->remove_all_geoms();
162 _bounds_viz_geom->remove_all_geoms();
169 return _bounds_viz_geom.p();
171 return _viz_geom.p();
184 return _volume_pcollector;
196 return _test_pcollector;
204 void CollisionSolid::
205 output(ostream &out)
const {
214 void CollisionSolid::
215 write(ostream &out,
int indent_level)
const {
216 indent(out, indent_level) << (*this) <<
"\n";
225 compute_internal_bounds()
const {
237 test_intersection_from_sphere(const CollisionEntry &)
const {
238 report_undefined_intersection_test(CollisionSphere::get_class_type(),
251 test_intersection_from_line(const CollisionEntry &)
const {
252 report_undefined_intersection_test(CollisionLine::get_class_type(),
265 test_intersection_from_ray(const CollisionEntry &)
const {
266 report_undefined_intersection_test(CollisionRay::get_class_type(),
279 test_intersection_from_segment(const CollisionEntry &)
const {
280 report_undefined_intersection_test(CollisionSegment::get_class_type(),
293 test_intersection_from_parabola(const CollisionEntry &)
const {
294 report_undefined_intersection_test(CollisionParabola::get_class_type(),
307 test_intersection_from_box(const CollisionEntry &)
const {
308 report_undefined_intersection_test(CollisionBox::get_class_type(),
321 if (_a != other._a) {
322 return _a < other._a;
324 return _b < other._b;
339 void CollisionSolid::
343 static Reported reported;
347 <<
"Invalid attempt to detect collision from " << from_type <<
" into "
348 << into_type <<
"!\n\n"
350 "This means that a " << from_type <<
" object attempted to test for an\n"
351 "intersection into a " << into_type <<
" object. This intersection\n"
352 "test has not yet been defined; it is possible the " << into_type <<
"\n"
353 "object is not intended to be collidable. Consider calling\n"
354 "set_into_collide_mask(0) on the " << into_type <<
" object, or\n"
355 "set_from_collide_mask(0) on the " << from_type <<
" object.\n\n";
367 void CollisionSolid::
368 report_undefined_from_intersection(
TypeHandle from_type) {
371 static Reported reported;
373 if (reported.insert(from_type).second) {
375 <<
"Invalid attempt to detect collision from " << from_type <<
"!\n\n"
377 "This means that a " << from_type <<
" object was added to a\n"
378 "CollisionTraverser as if it were a colliding object. However,\n"
379 "no implementation for this kind of object has yet been defined\n"
380 "to collide with other objects.\n\n";
397 if ((_flags & F_effective_normal) != 0) {
410 void CollisionSolid::
413 if ((_flags & F_effective_normal) != 0) {
419 _flags |= F_viz_geom_stale | F_internal_bounds_stale;
429 void CollisionSolid::
444 get_solid_viz_state() {
449 base_state = RenderState::make
450 (CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise),
451 RenderModeAttrib::make(RenderModeAttrib::M_filled),
452 TransparencyAttrib::make(TransparencyAttrib::M_alpha));
455 if (!do_is_tangible()) {
457 if (intangible_state == (const
RenderState *)NULL) {
458 intangible_state = base_state->add_attrib
459 (ColorAttrib::make_flat(
LColor(1.0f, 0.3, 0.5f, 0.5f)));
461 return intangible_state;
463 }
else if (do_has_effective_normal()) {
465 if (fakenormal_state == (const
RenderState *)NULL) {
466 fakenormal_state = base_state->add_attrib
467 (ColorAttrib::make_flat(
LColor(0.5f, 0.5f, 1.0f, 0.5f)));
469 return fakenormal_state;
474 tangible_state = base_state->add_attrib
475 (ColorAttrib::make_flat(
LColor(1.0f, 1.0f, 1.0f, 0.5f)));
477 return tangible_state;
493 get_wireframe_viz_state() {
498 base_state = RenderState::make
499 (CullFaceAttrib::make(CullFaceAttrib::M_cull_none),
500 RenderModeAttrib::make(RenderModeAttrib::M_wireframe),
501 TransparencyAttrib::make(TransparencyAttrib::M_none));
504 if (!do_is_tangible()) {
506 if (intangible_state == (const
RenderState *)NULL) {
507 intangible_state = base_state->add_attrib
508 (ColorAttrib::make_flat(
LColor(1.0f, 1.0f, 0.0f, 1.0f)));
510 return intangible_state;
512 }
else if (do_has_effective_normal()) {
514 if (fakenormal_state == (const
RenderState *)NULL) {
515 fakenormal_state = base_state->add_attrib
516 (ColorAttrib::make_flat(
LColor(0.0f, 0.0f, 1.0f, 1.0f)));
518 return fakenormal_state;
523 tangible_state = base_state->add_attrib
524 (ColorAttrib::make_flat(
LColor(0.0f, 0.0f, 1.0f, 1.0f)));
526 return tangible_state;
541 get_other_viz_state() {
546 base_state = RenderState::make
547 (CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise),
548 RenderModeAttrib::make(RenderModeAttrib::M_filled),
549 TransparencyAttrib::make(TransparencyAttrib::M_alpha));
568 get_solid_bounds_viz_state() {
573 base_state = RenderState::make
574 (CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise),
575 RenderModeAttrib::make(RenderModeAttrib::M_filled),
576 TransparencyAttrib::make(TransparencyAttrib::M_alpha));
579 if (!do_is_tangible()) {
581 if (intangible_state == (const
RenderState *)NULL) {
582 intangible_state = base_state->add_attrib
583 (ColorAttrib::make_flat(
LColor(1.0f, 1.0f, 0.5f, 0.3)));
585 return intangible_state;
587 }
else if (do_has_effective_normal()) {
589 if (fakenormal_state == (const
RenderState *)NULL) {
590 fakenormal_state = base_state->add_attrib
591 (ColorAttrib::make_flat(
LColor(0.5f, 0.5f, 1.0f, 0.3)));
593 return fakenormal_state;
598 tangible_state = base_state->add_attrib
599 (ColorAttrib::make_flat(
LColor(1.0f, 1.0f, 0.5f, 0.3)));
601 return tangible_state;
617 get_wireframe_bounds_viz_state() {
622 base_state = RenderState::make
623 (CullFaceAttrib::make(CullFaceAttrib::M_cull_none),
624 RenderModeAttrib::make(RenderModeAttrib::M_wireframe),
625 TransparencyAttrib::make(TransparencyAttrib::M_none),
626 ColorAttrib::make_flat(
LColor(1.0f, 0.0f, 0.0f, 1.0f)));
643 get_other_bounds_viz_state() {
648 base_state = RenderState::make
649 (CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise),
650 RenderModeAttrib::make(RenderModeAttrib::M_filled),
651 TransparencyAttrib::make(TransparencyAttrib::M_alpha));
A basic node of the scene graph or data graph.
void add_uint8(PN_uint8 value)
Adds an unsigned 8-bit integer to the datagram.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
void read_datagram(DatagramIterator &source)
Reads the vector from the Datagram using get_stdfloat().
The abstract base class for all things that can collide with other things in the world, and all the things they can collide with (except geometry).
This defines a bounding sphere, consisting of a center and a radius.
This collects together the pieces of data that are accumulated for each node while walking the scene ...
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
PN_uint8 get_uint8()
Extracts an unsigned 8-bit integer.
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
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...
void set_bounds(const BoundingVolume &bounding_volume)
Returns the solid's bounding volume.
This is a 4-by-4 transform matrix.
virtual PStatCollector & get_volume_pcollector()
Returns a PStatCollector that is used to count the number of bounding volume tests made against a sol...
Similar to MutexHolder, but for a light mutex.
Defines a single collision event.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
This is the base class for all three-component vectors and points.
This base class provides basic reference counting, but also can be used with a CopyOnWritePointer to ...
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.
This is our own Panda specialization on the default STL set.
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
bool normalize()
Normalizes the vector in place.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling...
void write_datagram(Datagram &destination) const
Writes the vector to the Datagram using add_stdfloat().
A node that holds Geom objects, renderable pieces of geometry.