00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef CPPPARSER
00016
00017
00018
00019
00020
00021 template<class MaskType>
00022 INLINE CollisionLevelState<MaskType>::
00023 CollisionLevelState(const NodePath &node_path) :
00024 CollisionLevelStateBase(node_path),
00025 _current(CurrentMask::all_off())
00026 {
00027 }
00028 #endif // CPPPARSER
00029
00030 #ifndef CPPPARSER
00031
00032
00033
00034
00035
00036
00037 template<class MaskType>
00038 INLINE CollisionLevelState<MaskType>::
00039 CollisionLevelState(const CollisionLevelState<MaskType> &parent, PandaNode *child) :
00040 CollisionLevelStateBase(parent, child),
00041 _current(parent._current)
00042 {
00043 }
00044 #endif // CPPPARSER
00045
00046 #ifndef CPPPARSER
00047
00048
00049
00050
00051
00052 template<class MaskType>
00053 INLINE CollisionLevelState<MaskType>::
00054 CollisionLevelState(const CollisionLevelState<MaskType> ©) :
00055 CollisionLevelStateBase(copy),
00056 _current(copy._current)
00057 {
00058 }
00059 #endif // CPPPARSER
00060
00061 #ifndef CPPPARSER
00062
00063
00064
00065
00066
00067 template<class MaskType>
00068 INLINE void CollisionLevelState<MaskType>::
00069 operator = (const CollisionLevelState<MaskType> ©) {
00070 CollisionLevelStateBase::operator = (copy);
00071 _current = copy._current;
00072 }
00073 #endif // CPPPARSER
00074
00075 #ifndef CPPPARSER
00076
00077
00078
00079
00080
00081 template<class MaskType>
00082 INLINE void CollisionLevelState<MaskType>::
00083 clear() {
00084 CollisionLevelStateBase::clear();
00085 _current.clear();
00086 }
00087 #endif // CPPPARSER
00088
00089 #ifndef CPPPARSER
00090
00091
00092
00093
00094
00095
00096 template<class MaskType>
00097 INLINE void CollisionLevelState<MaskType>::
00098 prepare_collider(const ColliderDef &def, const NodePath &root) {
00099 int index = (int)_colliders.size();
00100 nassertv(!CurrentMask::has_max_num_bits() ||
00101 index <= CurrentMask::get_max_num_bits());
00102
00103 CollisionLevelStateBase::prepare_collider(def, root);
00104 _current.set_bit(index);
00105 }
00106 #endif // CPPPARSER
00107
00108 #ifndef CPPPARSER
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 template<class MaskType>
00120 bool CollisionLevelState<MaskType>::
00121 any_in_bounds() {
00122 #ifndef NDEBUG
00123 int indent_level = 0;
00124 if (collide_cat.is_spam()) {
00125 indent_level = _node_path.get_num_nodes() * 2;
00126 collide_cat.spam();
00127 indent(collide_cat.spam(false), indent_level)
00128 << "Considering " << _node_path.get_node_path() << "\n";
00129 }
00130 #endif // NDEBUG
00131
00132 CPT(BoundingVolume) node_bv = node()->get_bounds();
00133 if (node_bv->is_of_type(GeometricBoundingVolume::get_class_type())) {
00134 const GeometricBoundingVolume *node_gbv;
00135 DCAST_INTO_R(node_gbv, node_bv, false);
00136
00137 int num_colliders = get_num_colliders();
00138 for (int c = 0; c < num_colliders; c++) {
00139 if (has_collider(c)) {
00140 CollisionNode *cnode = get_collider_node(c);
00141 bool is_in = false;
00142
00143
00144
00145
00146 CollideMask from_mask = cnode->get_from_collide_mask() & _include_mask;
00147 if (!(from_mask & node()->get_net_collide_mask()).is_zero()) {
00148
00149
00150 if (node() == cnode) {
00151 #ifndef NDEBUG
00152 if (collide_cat.is_spam()) {
00153 indent(collide_cat.spam(false), indent_level)
00154 << "Not comparing " << c << " to " << _node_path
00155 << " (same node)\n";
00156 }
00157 #endif // NDEBUG
00158
00159 } else {
00160
00161
00162 const GeometricBoundingVolume *col_gbv =
00163 get_local_bound(c);
00164
00165 is_in = true;
00166
00167 if (col_gbv != (GeometricBoundingVolume *)NULL) {
00168 is_in = (node_gbv->contains(col_gbv) != 0);
00169 _node_volume_pcollector.add_level(1);
00170
00171 #ifndef NDEBUG
00172 if (collide_cat.is_spam()) {
00173 indent(collide_cat.spam(false), indent_level)
00174 << "Comparing " << c << ": " << *col_gbv
00175 << " to " << *node_gbv << ", is_in = " << is_in << "\n";
00176 }
00177 #endif // NDEBUG
00178 }
00179 }
00180 }
00181
00182 if (!is_in) {
00183
00184
00185 omit_collider(c);
00186 }
00187 }
00188 }
00189 }
00190
00191 #ifndef NDEBUG
00192 if (collide_cat.is_spam()) {
00193 int num_active_colliders = 0;
00194 int num_colliders = get_num_colliders();
00195 for (int c = 0; c < num_colliders; c++) {
00196 if (has_collider(c)) {
00197 num_active_colliders++;
00198 }
00199 }
00200
00201 collide_cat.spam();
00202 indent(collide_cat.spam(false), indent_level)
00203 << _node_path.get_node_path() << " has " << num_active_colliders
00204 << " interested colliders";
00205 if (num_colliders != 0) {
00206 collide_cat.spam(false)
00207 << " (";
00208 for (int c = 0; c < num_colliders; c++) {
00209 if (has_collider(c)) {
00210 CollisionNode *cnode = get_collider_node(c);
00211 collide_cat.spam(false)
00212 << " " << c << ". " << cnode->get_name();
00213 }
00214 }
00215 collide_cat.spam(false)
00216 << " )";
00217 }
00218 collide_cat.spam(false)
00219 << "\n";
00220 }
00221 #endif // NDEBUG
00222 return has_any_collider();
00223 }
00224 #endif // CPPPARSER
00225
00226 #ifndef CPPPARSER
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 template<class MaskType>
00239 bool CollisionLevelState<MaskType>::
00240 apply_transform() {
00241
00242
00243 _parent_bounds = _local_bounds;
00244
00245 if (node()->is_final()) {
00246
00247
00248
00249
00250 BoundingVolumes new_bounds;
00251
00252 int num_colliders = get_num_colliders();
00253 new_bounds.reserve(num_colliders);
00254 for (int c = 0; c < num_colliders; c++) {
00255 new_bounds.push_back((GeometricBoundingVolume *)NULL);
00256 }
00257
00258 _local_bounds = new_bounds;
00259
00260 } else {
00261
00262
00263
00264 const TransformState *node_transform = node()->get_transform();
00265 if (!node_transform->is_identity()) {
00266 CPT(TransformState) inv_transform =
00267 node_transform->invert_compose(TransformState::make_identity());
00268 if (!inv_transform->has_mat()) {
00269
00270 return false;
00271 }
00272
00273 const LMatrix4 &mat = inv_transform->get_mat();
00274
00275
00276 BoundingVolumes new_bounds;
00277
00278 int num_colliders = get_num_colliders();
00279 new_bounds.reserve(num_colliders);
00280 for (int c = 0; c < num_colliders; c++) {
00281 if (!has_collider(c) ||
00282 get_local_bound(c) == (GeometricBoundingVolume *)NULL) {
00283 new_bounds.push_back((GeometricBoundingVolume *)NULL);
00284 } else {
00285 const GeometricBoundingVolume *old_bound = get_local_bound(c);
00286 GeometricBoundingVolume *new_bound =
00287 DCAST(GeometricBoundingVolume, old_bound->make_copy());
00288 new_bound->xform(mat);
00289 new_bounds.push_back(new_bound);
00290 }
00291 }
00292
00293 _local_bounds = new_bounds;
00294 }
00295 }
00296
00297 return true;
00298 }
00299 #endif // CPPPARSER
00300
00301 #ifndef CPPPARSER
00302
00303
00304
00305
00306
00307
00308
00309 template<class MaskType>
00310 INLINE bool CollisionLevelState<MaskType>::
00311 has_max_colliders() {
00312 return CurrentMask::has_max_num_bits();
00313 }
00314 #endif // CPPPARSER
00315
00316 #ifndef CPPPARSER
00317
00318
00319
00320
00321
00322
00323 template<class MaskType>
00324 INLINE int CollisionLevelState<MaskType>::
00325 get_max_colliders() {
00326 return CurrentMask::get_max_num_bits();
00327 }
00328 #endif // CPPPARSER
00329
00330 #ifndef CPPPARSER
00331
00332
00333
00334
00335
00336
00337 template<class MaskType>
00338 INLINE bool CollisionLevelState<MaskType>::
00339 has_collider(int n) const {
00340 nassertr(n >= 0 && n < (int)_colliders.size(), false);
00341 return (_current.get_bit(n));
00342 }
00343 #endif // CPPPARSER
00344
00345 #ifndef CPPPARSER
00346
00347
00348
00349
00350
00351 template<class MaskType>
00352 INLINE bool CollisionLevelState<MaskType>::
00353 has_any_collider() const {
00354 return !_current.is_zero();
00355 }
00356 #endif // CPPPARSER
00357
00358 #ifndef CPPPARSER
00359
00360
00361
00362
00363
00364 template<class MaskType>
00365 INLINE void CollisionLevelState<MaskType>::
00366 omit_collider(int n) {
00367 nassertv(n >= 0 && n < (int)_colliders.size());
00368 nassertv(has_collider(n));
00369
00370 _current.clear_bit(n);
00371 }
00372 #endif // CPPPARSER