Browse Source

Changed apply_tranform to return false when inverse transforim is invalid

Gyedo Jeon 16 years ago
parent
commit
5d00f81885

+ 13 - 1
panda/src/collide/collisionLevelState.I

@@ -229,9 +229,14 @@ any_in_bounds() {
 //       Access: Public
 //  Description: Applies the inverse transform from the current node,
 //               if any, onto all the colliders in the level state.
+//
+//               Returns true if the inverse transform is valid, or
+//               false if it is not valid (e.g. the transform has a
+//               scale to zero).  If the inverse transform is not
+//               valid, the caller should not visit this node.
 ////////////////////////////////////////////////////////////////////
 template<class MaskType>
-void CollisionLevelState<MaskType>::
+bool CollisionLevelState<MaskType>::
 apply_transform() {
   // The "parent" bounds list remembers the bounds list of the
   // previous node.
@@ -260,6 +265,11 @@ apply_transform() {
     if (!node_transform->is_identity()) {
       CPT(TransformState) inv_transform = 
         node_transform->invert_compose(TransformState::make_identity());
+      if (!inv_transform->has_mat()) {
+        // No inverse.
+        return false;
+      }
+
       const LMatrix4f &mat = inv_transform->get_mat();
       
       // Now build the new bounding volumes list.
@@ -283,6 +293,8 @@ apply_transform() {
       _local_bounds = new_bounds;
     }    
   }
+
+  return true;
 }
 #endif  // CPPPARSER
 

+ 1 - 1
panda/src/collide/collisionLevelState.h

@@ -49,7 +49,7 @@ public:
   INLINE void prepare_collider(const ColliderDef &def, const NodePath &root);
 
   bool any_in_bounds();
-  void apply_transform();
+  bool apply_transform();
 
   INLINE static bool has_max_colliders();
   INLINE static int get_max_colliders();

+ 9 - 3
panda/src/collide/collisionTraverser.cxx

@@ -600,7 +600,9 @@ r_traverse_single(CollisionLevelStateSingle &level_state, size_t pass) {
   if (!level_state.any_in_bounds()) {
     return;
   }
-  level_state.apply_transform();
+  if (!level_state.apply_transform()) {
+    return;
+  }
 
   PandaNode *node = level_state.node();
   if (node->is_exact_type(CollisionNode::get_class_type())) {
@@ -817,7 +819,9 @@ r_traverse_double(CollisionLevelStateDouble &level_state, size_t pass) {
   if (!level_state.any_in_bounds()) {
     return;
   }
-  level_state.apply_transform();
+  if (!level_state.apply_transform()) {
+    return;
+  }
 
   PandaNode *node = level_state.node();
   if (node->is_exact_type(CollisionNode::get_class_type())) {
@@ -1034,7 +1038,9 @@ r_traverse_quad(CollisionLevelStateQuad &level_state, size_t pass) {
   if (!level_state.any_in_bounds()) {
     return;
   }
-  level_state.apply_transform();
+  if (!level_state.apply_transform()) {
+    return;
+  }
 
   PandaNode *node = level_state.node();
   if (node->is_exact_type(CollisionNode::get_class_type())) {