37 "Collision Volumes:CollisionSolid");
39 "Collision Tests:CollisionSolid");
46 CollisionSolid() : _lock(
"CollisionSolid") {
47 _flags = F_viz_geom_stale | F_tangible | F_internal_bounds_stale;
56 _effective_normal(copy._effective_normal),
57 _internal_bounds(copy._internal_bounds),
59 _lock(
"CollisionSolid")
61 _flags |= F_viz_geom_stale;
85 if (_flags & F_internal_bounds_stale) {
86 ((
CollisionSolid *)
this)->_internal_bounds = compute_internal_bounds();
89 return _internal_bounds;
98 ((
CollisionSolid *)
this)->_internal_bounds = bounding_volume.make_copy();
110 report_undefined_from_intersection(get_type());
117 void CollisionSolid::
118 xform(
const LMatrix4 &mat) {
120 if ((_flags & F_effective_normal) != 0) {
121 _effective_normal = _effective_normal * mat;
122 _effective_normal.normalize();
125 _flags |= F_viz_geom_stale | F_internal_bounds_stale;
136 if ((_flags & F_viz_geom_stale) != 0) {
137 if (_viz_geom ==
nullptr) {
141 _viz_geom->remove_all_geoms();
142 _bounds_viz_geom->remove_all_geoms();
149 return _bounds_viz_geom;
160 get_volume_pcollector() {
161 return _volume_pcollector;
170 return _test_pcollector;
176 void CollisionSolid::
177 output(std::ostream &out)
const {
184 void CollisionSolid::
185 write(std::ostream &out,
int indent_level)
const {
186 indent(out, indent_level) << (*this) <<
"\n";
193 compute_internal_bounds()
const {
203 report_undefined_intersection_test(CollisionSphere::get_class_type(),
214 report_undefined_intersection_test(CollisionLine::get_class_type(),
225 report_undefined_intersection_test(CollisionRay::get_class_type(),
236 report_undefined_intersection_test(CollisionSegment::get_class_type(),
247 report_undefined_intersection_test(CollisionCapsule::get_class_type(),
258 report_undefined_intersection_test(CollisionParabola::get_class_type(),
269 report_undefined_intersection_test(CollisionBox::get_class_type(),
276 class CollisionSolidUndefinedPair {
281 bool operator < (
const CollisionSolidUndefinedPair &other)
const {
282 if (_a != other._a) {
283 return _a < other._a;
285 return _b < other._b;
297 void CollisionSolid::
301 static Reported reported;
303 if (reported.insert(CollisionSolidUndefinedPair(from_type, into_type)).second) {
305 <<
"Invalid attempt to detect collision from " << from_type <<
" into "
306 << into_type <<
"!\n\n"
308 "This means that a " << from_type <<
" object attempted to test for an\n"
309 "intersection into a " << into_type <<
" object. This intersection\n"
310 "test has not yet been defined; it is possible the " << into_type <<
"\n"
311 "object is not intended to be collidable. Consider calling\n"
312 "set_into_collide_mask(0) on the " << into_type <<
" object, or\n"
313 "set_from_collide_mask(0) on the " << from_type <<
" object.\n\n";
322 void CollisionSolid::
323 report_undefined_from_intersection(
TypeHandle from_type) {
326 static Reported reported;
328 if (reported.insert(from_type).second) {
330 <<
"Invalid attempt to detect collision from " << from_type <<
"!\n\n"
332 "This means that a " << from_type <<
" object was added to a\n"
333 "CollisionTraverser as if it were a colliding object. However,\n"
334 "no implementation for this kind of object has yet been defined\n"
335 "to collide with other objects.\n\n";
350 if ((_flags & F_effective_normal) != 0) {
351 _effective_normal.write_datagram(me);
360 void CollisionSolid::
363 if ((_flags & F_effective_normal) != 0) {
364 _effective_normal.read_datagram(scan);
369 _flags |= F_viz_geom_stale | F_internal_bounds_stale;
377 void CollisionSolid::
389 get_solid_viz_state() {
393 if (base_state ==
nullptr) {
394 base_state = RenderState::make
395 (CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise),
396 RenderModeAttrib::make(RenderModeAttrib::M_filled),
397 TransparencyAttrib::make(TransparencyAttrib::M_alpha));
400 if (!do_is_tangible()) {
401 static CPT(
RenderState) intangible_state =
nullptr;
402 if (intangible_state ==
nullptr) {
403 intangible_state = base_state->add_attrib
404 (ColorAttrib::make_flat(LColor(1.0f, 0.3, 0.5f, 0.5f)));
406 return intangible_state;
408 }
else if (do_has_effective_normal()) {
409 static CPT(
RenderState) fakenormal_state =
nullptr;
410 if (fakenormal_state ==
nullptr) {
411 fakenormal_state = base_state->add_attrib
412 (ColorAttrib::make_flat(LColor(0.5f, 0.5f, 1.0f, 0.5f)));
414 return fakenormal_state;
418 if (tangible_state ==
nullptr) {
419 tangible_state = base_state->add_attrib
420 (ColorAttrib::make_flat(LColor(1.0f, 1.0f, 1.0f, 0.5f)));
422 return tangible_state;
435 get_wireframe_viz_state() {
439 if (base_state ==
nullptr) {
440 base_state = RenderState::make
441 (CullFaceAttrib::make(CullFaceAttrib::M_cull_none),
442 RenderModeAttrib::make(RenderModeAttrib::M_wireframe),
443 TransparencyAttrib::make(TransparencyAttrib::M_none));
446 if (!do_is_tangible()) {
447 static CPT(
RenderState) intangible_state =
nullptr;
448 if (intangible_state ==
nullptr) {
449 intangible_state = base_state->add_attrib
450 (ColorAttrib::make_flat(LColor(1.0f, 1.0f, 0.0f, 1.0f)));
452 return intangible_state;
454 }
else if (do_has_effective_normal()) {
455 static CPT(
RenderState) fakenormal_state =
nullptr;
456 if (fakenormal_state ==
nullptr) {
457 fakenormal_state = base_state->add_attrib
458 (ColorAttrib::make_flat(LColor(0.0f, 0.0f, 1.0f, 1.0f)));
460 return fakenormal_state;
464 if (tangible_state ==
nullptr) {
465 tangible_state = base_state->add_attrib
466 (ColorAttrib::make_flat(LColor(0.0f, 0.0f, 1.0f, 1.0f)));
468 return tangible_state;
480 get_other_viz_state() {
484 if (base_state ==
nullptr) {
485 base_state = RenderState::make
486 (CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise),
487 RenderModeAttrib::make(RenderModeAttrib::M_filled),
488 TransparencyAttrib::make(TransparencyAttrib::M_alpha));
504 get_solid_bounds_viz_state() {
508 if (base_state ==
nullptr) {
509 base_state = RenderState::make
510 (CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise),
511 RenderModeAttrib::make(RenderModeAttrib::M_filled),
512 TransparencyAttrib::make(TransparencyAttrib::M_alpha));
515 if (!do_is_tangible()) {
516 static CPT(
RenderState) intangible_state =
nullptr;
517 if (intangible_state ==
nullptr) {
518 intangible_state = base_state->add_attrib
519 (ColorAttrib::make_flat(LColor(1.0f, 1.0f, 0.5f, 0.3)));
521 return intangible_state;
523 }
else if (do_has_effective_normal()) {
524 static CPT(
RenderState) fakenormal_state =
nullptr;
525 if (fakenormal_state ==
nullptr) {
526 fakenormal_state = base_state->add_attrib
527 (ColorAttrib::make_flat(LColor(0.5f, 0.5f, 1.0f, 0.3)));
529 return fakenormal_state;
533 if (tangible_state ==
nullptr) {
534 tangible_state = base_state->add_attrib
535 (ColorAttrib::make_flat(LColor(1.0f, 1.0f, 0.5f, 0.3)));
537 return tangible_state;
550 get_wireframe_bounds_viz_state() {
554 if (base_state ==
nullptr) {
555 base_state = RenderState::make
556 (CullFaceAttrib::make(CullFaceAttrib::M_cull_none),
557 RenderModeAttrib::make(RenderModeAttrib::M_wireframe),
558 TransparencyAttrib::make(TransparencyAttrib::M_none),
559 ColorAttrib::make_flat(LColor(1.0f, 0.0f, 0.0f, 1.0f)));
573 get_other_bounds_viz_state() {
577 if (base_state ==
nullptr) {
578 base_state = RenderState::make
579 (CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise),
580 RenderModeAttrib::make(RenderModeAttrib::M_filled),
581 TransparencyAttrib::make(TransparencyAttrib::M_alpha));