00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "collisionSolid.h"
00021 #include "config_collide.h"
00022 #include "collisionSphere.h"
00023 #include "collisionRay.h"
00024 #include "collisionSegment.h"
00025
00026 #include "datagram.h"
00027 #include "datagramIterator.h"
00028 #include "bamReader.h"
00029 #include "bamWriter.h"
00030 #include "indent.h"
00031 #include "cullFaceAttrib.h"
00032 #include "colorAttrib.h"
00033 #include "renderModeAttrib.h"
00034 #include "transparencyAttrib.h"
00035 #include "geomNode.h"
00036
00037 TypeHandle CollisionSolid::_type_handle;
00038
00039
00040
00041
00042
00043
00044 CollisionSolid::
00045 CollisionSolid() {
00046 _viz_geom_stale = true;
00047 _tangible = true;
00048 }
00049
00050
00051
00052
00053
00054
00055 CollisionSolid::
00056 CollisionSolid(const CollisionSolid ©) :
00057 _tangible(copy._tangible)
00058 {
00059
00060 _viz_geom_stale = true;
00061 }
00062
00063
00064
00065
00066
00067
00068 CollisionSolid::
00069 ~CollisionSolid() {
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 PT(CollisionEntry) CollisionSolid::
00082 test_intersection(const CollisionEntry &) const {
00083 report_undefined_from_intersection(get_type());
00084 return NULL;
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 GeomNode *CollisionSolid::
00096 get_viz() const {
00097 if (_viz_geom_stale) {
00098 if (_viz_geom == (GeomNode *)NULL) {
00099 ((CollisionSolid *)this)->_viz_geom = new GeomNode("viz");
00100 } else {
00101 _viz_geom->remove_all_geoms();
00102 }
00103 ((CollisionSolid *)this)->fill_viz_geom();
00104 ((CollisionSolid *)this)->_viz_geom_stale = false;
00105 }
00106 return _viz_geom;
00107 }
00108
00109
00110
00111
00112
00113
00114 void CollisionSolid::
00115 output(ostream &out) const {
00116 out << get_type();
00117 }
00118
00119
00120
00121
00122
00123
00124 void CollisionSolid::
00125 write(ostream &out, int indent_level) const {
00126 indent(out, indent_level) << (*this) << "\n";
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136 PT(CollisionEntry) CollisionSolid::
00137 test_intersection_from_sphere(const CollisionEntry &) const {
00138 report_undefined_intersection_test(CollisionSphere::get_class_type(),
00139 get_type());
00140 return NULL;
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150 PT(CollisionEntry) CollisionSolid::
00151 test_intersection_from_ray(const CollisionEntry &) const {
00152 report_undefined_intersection_test(CollisionRay::get_class_type(),
00153 get_type());
00154 return NULL;
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164 PT(CollisionEntry) CollisionSolid::
00165 test_intersection_from_segment(const CollisionEntry &) const {
00166 report_undefined_intersection_test(CollisionSegment::get_class_type(),
00167 get_type());
00168 return NULL;
00169 }
00170
00171 #ifndef NDEBUG
00172 class CollisionSolidUndefinedPair {
00173 public:
00174 CollisionSolidUndefinedPair(TypeHandle a, TypeHandle b) :
00175 _a(a), _b(b)
00176 {}
00177 bool operator < (const CollisionSolidUndefinedPair &other) const {
00178 if (_a != other._a) {
00179 return _a < other._a;
00180 }
00181 return _b < other._b;
00182 }
00183
00184 TypeHandle _a;
00185 TypeHandle _b;
00186 };
00187 #endif // NDEBUG
00188
00189
00190
00191
00192
00193
00194
00195
00196 void CollisionSolid::
00197 report_undefined_intersection_test(TypeHandle from_type, TypeHandle into_type) {
00198 #ifndef NDEBUG
00199 typedef pset<CollisionSolidUndefinedPair> Reported;
00200 static Reported reported;
00201
00202 if (reported.insert(CollisionSolidUndefinedPair(from_type, into_type)).second) {
00203 collide_cat.error()
00204 << "Invalid attempt to detect collision from " << from_type << " into "
00205 << into_type << "!\n\n"
00206
00207 "This means that a " << from_type << " object attempted to test for an\n"
00208 "intersection into a " << into_type << " object. This intersection\n"
00209 "test has not yet been defined; it is possible the " << into_type << "\n"
00210 "object is not intended to be collidable. Consider calling\n"
00211 "set_into_collide_mask(0) on the " << into_type << " object, or\n"
00212 "set_from_collide_mask(0) on the " << from_type << " object.\n\n";
00213 }
00214 #endif // NDEBUG
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224 void CollisionSolid::
00225 report_undefined_from_intersection(TypeHandle from_type) {
00226 #ifndef NDEBUG
00227 typedef pset<TypeHandle> Reported;
00228 static Reported reported;
00229
00230 if (reported.insert(from_type).second) {
00231 collide_cat.error()
00232 << "Invalid attempt to detect collision from " << from_type << "!\n\n"
00233
00234 "This means that a " << from_type << " object was added to a\n"
00235 "CollisionTraverser as if it were a colliding object. However,\n"
00236 "no implementation for this kind of object has yet been defined\n"
00237 "to collide with other objects.\n\n";
00238 }
00239 #endif // NDEBUG
00240 }
00241
00242
00243
00244
00245
00246
00247
00248 void CollisionSolid::
00249 write_datagram(BamWriter *, Datagram &me)
00250 {
00251 me.add_uint8(_tangible);
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 void CollisionSolid::
00263 fillin(DatagramIterator& scan, BamReader*)
00264 {
00265 _tangible = (scan.get_uint8() != 0);
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275 void CollisionSolid::
00276 fill_viz_geom() {
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 CPT(RenderState) CollisionSolid::
00288 get_solid_viz_state() {
00289
00290
00291 static CPT(RenderState) base_state = (const RenderState *)NULL;
00292 if (base_state == (const RenderState *)NULL) {
00293 base_state = RenderState::make
00294 (CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise),
00295 RenderModeAttrib::make(RenderModeAttrib::M_filled),
00296 TransparencyAttrib::make(TransparencyAttrib::M_alpha));
00297 }
00298
00299 if (_tangible) {
00300 static CPT(RenderState) tangible_state = (const RenderState *)NULL;
00301 if (tangible_state == (const RenderState *)NULL) {
00302 tangible_state = base_state->add_attrib
00303 (ColorAttrib::make_flat(Colorf(1.0f, 1.0f, 1.0f, 0.5f)));
00304 }
00305 return tangible_state;
00306
00307 } else {
00308 static CPT(RenderState) intangible_state = (const RenderState *)NULL;
00309 if (intangible_state == (const RenderState *)NULL) {
00310 intangible_state = base_state->add_attrib
00311 (ColorAttrib::make_flat(Colorf(1.0f, 0.3f, 0.5f, 0.5f)));
00312 }
00313 return intangible_state;
00314 }
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 CPT(RenderState) CollisionSolid::
00327 get_wireframe_viz_state() {
00328
00329
00330 static CPT(RenderState) base_state = (const RenderState *)NULL;
00331 if (base_state == (const RenderState *)NULL) {
00332 base_state = RenderState::make
00333 (CullFaceAttrib::make(CullFaceAttrib::M_cull_none),
00334 RenderModeAttrib::make(RenderModeAttrib::M_wireframe),
00335 TransparencyAttrib::make(TransparencyAttrib::M_none));
00336 }
00337
00338 if (_tangible) {
00339 static CPT(RenderState) tangible_state = (const RenderState *)NULL;
00340 if (tangible_state == (const RenderState *)NULL) {
00341 tangible_state = base_state->add_attrib
00342 (ColorAttrib::make_flat(Colorf(0.0f, 0.0f, 1.0f, 1.0f)));
00343 }
00344 return tangible_state;
00345
00346 } else {
00347 static CPT(RenderState) intangible_state = (const RenderState *)NULL;
00348 if (intangible_state == (const RenderState *)NULL) {
00349 intangible_state = base_state->add_attrib
00350 (ColorAttrib::make_flat(Colorf(1.0f, 1.0f, 0.0f, 1.0f)));
00351 }
00352 return intangible_state;
00353 }
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 CPT(RenderState) CollisionSolid::
00365 get_other_viz_state() {
00366
00367
00368 static CPT(RenderState) base_state = (const RenderState *)NULL;
00369 if (base_state == (const RenderState *)NULL) {
00370 base_state = RenderState::make
00371 (CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise),
00372 RenderModeAttrib::make(RenderModeAttrib::M_filled),
00373 TransparencyAttrib::make(TransparencyAttrib::M_alpha));
00374 }
00375
00376
00377
00378 return base_state;
00379 }
00380