Browse Source

work in progress

Dave Schuyler 19 years ago
parent
commit
247e79ccce
2 changed files with 156 additions and 47 deletions
  1. 63 6
      direct/src/controls/ShipPilot2.py
  2. 93 41
      panda/src/collide/collisionSphere.cxx

+ 63 - 6
direct/src/controls/ShipPilot2.py

@@ -29,6 +29,8 @@ class ShipPilot2(PhysicsWalker):
         'want-avatar-physics-indicator', 0)
 
     useBowSternSpheres = 1
+    useOneSphere = 0
+    useDSSolid = 0
     useLifter = 0
     useHeightRay = 0
 
@@ -73,7 +75,7 @@ class ShipPilot2(PhysicsWalker):
         self.avatarControlRotateSpeed=rotate
 
     def getSpeeds(self):
-        #assert(self.debugPrint("getSpeeds()"))
+        #assert self.debugPrint("getSpeeds()")
         return (self.__speed, self.__rotationSpeed)
 
     def setAvatar(self, ship):
@@ -91,7 +93,7 @@ class ShipPilot2(PhysicsWalker):
             if not hasattr(ship, "acceleration"):
                 self.ship.acceleration = 60
                 self.ship.maxSpeed = 14
-                self.ship.reverseAcceleration = 10
+                self.ship.reverseAcceleration = 30
                 self.ship.maxReverseSpeed = 2
                 self.ship.turnRate = 3
                 self.ship.maxTurn = 30
@@ -235,6 +237,55 @@ class ShipPilot2(PhysicsWalker):
             shipCollWall = self.avatarNodePath.hull.find("**/collision_hull")
             if not shipCollWall.isEmpty():
                 shipCollWall.stash()
+        elif self.useOneSphere:
+            # Front sphere:
+            self.cSphere = CollisionSphere(0.0, 0.0, -5.0, avatarRadius)
+            cSphereNode = CollisionNode('SP.cSphereNode')
+            cSphereNode.addSolid(self.cSphere)
+            self.cSphereNodePath = self.avatarNodePath.attachNewNode(
+                cSphereNode)
+            if 1:
+                self.cSphereNodePath.show()
+                self.cSphereNodePath.showBounds()
+
+            cSphereNode.setFromCollideMask(self.cSphereBitMask)
+            cSphereNode.setIntoCollideMask(BitMask32.allOff())
+
+            self.cSphereNode = cSphereNode
+
+            self.pusher.addCollider(
+                self.cSphereNodePath, self.avatarNodePath)
+
+            # hide other things on my ship that these spheres might collide
+            # with and which I dont need anyways...
+            shipCollWall = self.avatarNodePath.hull.find("**/collision_hull")
+            if not shipCollWall.isEmpty():
+                shipCollWall.stash()
+        elif self.useDSSolid:
+            # DSSolid:
+            self.cHull = CollisionDSSolid(
+                Point3(-160, 0, 0), 200, Point3(160, 0, 0), 200,
+                Plane(Vec3(0, 0, 1), Point3(0, 0, 50)),
+                Plane(Vec3(0, -1, 0), Point3(0, -90, 0)))
+            cHullNode = CollisionNode('SP.cHullNode')
+            cHullNode.addSolid(self.cHull)
+            self.cHullNodePath = self.avatarNodePath.attachNewNode(
+                cHullNode)
+            self.cHullNodePath.show()
+
+            cHullNode.setFromCollideMask(bitmask)
+            cHullNode.setIntoCollideMask(BitMask32.allOff())
+
+            self.cHullNode = cHullNode
+
+            self.pusher.addCollider(
+                self.cHullNodePath, self.avatarNodePath)            
+
+            # hide other things on my ship that these spheres might collide
+            # with and which I dont need anyways...
+            shipCollWall = self.avatarNodePath.hull.find("**/collision_hull")
+            if not shipCollWall.isEmpty():
+                shipCollWall.stash()
 
     def takedownPhysics(self):
         assert self.debugPrint("takedownPhysics()")
@@ -366,7 +417,7 @@ class ShipPilot2(PhysicsWalker):
             print "failed load of physics indicator"
 
     def avatarPhysicsIndicator(self, task):
-        #assert(self.debugPrint("avatarPhysicsIndicator()"))
+        #assert self.debugPrint("avatarPhysicsIndicator()")
         # Velocity:
         self.physVelocityIndicator.setPos(self.avatarNodePath, 0.0, 0.0, 6.0)
         physObject=self.actorNode.getPhysicsObject()
@@ -392,9 +443,12 @@ class ShipPilot2(PhysicsWalker):
             self.collisionsActive = active
             if active:
                 if self.useBowSternSpheres:
-                    #self.cTrav.addCollider(self.cSphereNodePath, self.pusher)
                     self.cTrav.addCollider(self.cBowSphereNodePath, self.pusher)
                     self.cTrav.addCollider(self.cSternSphereNodePath, self.pusher)
+                elif self.useOneSphere:
+                    self.cTrav.addCollider(self.cSphereNodePath, self.pusher)
+                elif self.useDSSolid:
+                    self.cTrav.addCollider(self.cHullNodePath, self.pusher)
                 if self.useHeightRay:
                     if self.useLifter:
                         self.cTrav.addCollider(self.cRayNodePath, self.lifter)
@@ -402,9 +456,12 @@ class ShipPilot2(PhysicsWalker):
                         self.cTrav.addCollider(self.cRayNodePath, self.cRayQueue)
             else:
                 if self.useBowSternSpheres:
-                    #self.cTrav.removeCollider(self.cSphereNodePath)
                     self.cTrav.removeCollider(self.cBowSphereNodePath)
                     self.cTrav.removeCollider(self.cSternSphereNodePath)
+                elif self.useOneSphere:
+                    self.cTrav.removeCollider(self.cSphereNodePath)
+                elif self.useDSSolid:
+                    self.cTrav.removeCollider(self.cHullNodePath)
                 if self.useHeightRay:
                     self.cTrav.removeCollider(self.cRayNodePath)
                 # Now that we have disabled collisions, make one more pass
@@ -520,7 +577,7 @@ class ShipPilot2(PhysicsWalker):
                     base.localAvatar.getPos().pPrintValues(),))
                 onScreenDebug.append("localAvatar hpr = %s\n"%(
                     base.localAvatar.getHpr().pPrintValues(),))
-        #assert(self.debugPrint("handleAvatarControls(task=%s)"%(task,)))
+        #assert self.debugPrint("handleAvatarControls(task=%s)"%(task,))
         physObject=self.actorNode.getPhysicsObject()
         contact=self.actorNode.getContactVector()
 

+ 93 - 41
panda/src/collide/collisionSphere.cxx

@@ -136,7 +136,7 @@ PT(BoundingVolume) CollisionSphere::
 compute_internal_bounds() const {
   return new BoundingSphere(_center, _radius);
 }
-#define USE_DS_SOLID_PLANES 0
+#define USE_DS_SOLID_PLANES 1
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionSphere::test_intersection_from_ds_solid
 //       Access: Public, Virtual
@@ -149,7 +149,6 @@ test_intersection_from_ds_solid(const CollisionEntry &entry) const {
   cerr<<"CollisionSphere::test_intersection_from_ds_solid\n";
 
   CPT(TransformState) wrt_space = entry.get_wrt_space();
-
   const LMatrix4f &wrt_mat = wrt_space->get_mat();
 
   LPoint3f into_center = get_center();
@@ -180,72 +179,125 @@ test_intersection_from_ds_solid(const CollisionEntry &entry) const {
   }
 
   #if USE_DS_SOLID_PLANES
-  float pa_distance = ds_solid->dist_to_plane_a(into_center);
-  if (pa_distance > into_radius) {
+  CPT(TransformState) inv_wrt_space = entry.get_inv_wrt_space();
+  const LMatrix4f &inv_wrt_mat = inv_wrt_space->get_mat();
+  
+  LPoint3f inv_into_center = get_center() * inv_wrt_mat;
+  float inv_into_radius = length(
+    LVector3f(get_radius(), 0.0f, 0.0f) * inv_wrt_mat);
+
+  float pa_distance =
+    ds_solid->dist_to_plane_a(inv_into_center) - inv_into_radius;
+  if (pa_distance > 0.0f) {
     // No intersection.
     return NULL;
   }
 
-  float pb_distance = ds_solid->dist_to_plane_b(into_center);
-  if (pb_distance > into_radius) {
+  float pb_distance =
+    ds_solid->dist_to_plane_b(inv_into_center) - inv_into_radius;
+  if (pb_distance > 0.0f) {
     // No intersection.
     return NULL;
   }
   #endif
 
-  if (collide_cat.is_debug()) {
-    collide_cat.debug()
-      << "intersection detected from " << entry.get_from_node_path()
-      << " into " << entry.get_into_node_path() << "\n";
-  }
+  LVector3f lens_center = ds_solid->get_collision_origin() * wrt_mat;
+  float lens_radius = length(
+    LVector3f(ds_solid->get_lens_radius(), 0.0f, 0.0f) * wrt_mat);
+  LVector3f lens_vec = lens_center - into_center;
+  float lens_distance_squared = dot(lens_vec, lens_vec);
 
   LVector3f surface_normal; // into
-  LPoint3f surface_point; // into
+  //LPoint3f surface_point; // into
   LPoint3f interior_point; // from
-  float spheres = sqrtf(sa_distance_squared) - sqrtf(sb_distance_squared);
+  float sa_distance = sqrtf(sa_distance_squared) - sa_radius;
+  float sb_distance = sqrtf(sb_distance_squared) - sb_radius;
+  pa_distance = ds_solid->dist_to_plane_a(inv_into_center);
+  pb_distance = ds_solid->dist_to_plane_b(inv_into_center);
   #if USE_DS_SOLID_PLANES
-  float planes = pa_distance - pb_distance;
-  if (spheres > planes) {
+  cerr
+    <<" sa_distance:"<<sa_distance
+    <<" sb_distance:"<<sb_distance
+    <<" pa_distance:"<<pa_distance
+    <<" pb_distance:"<<pb_distance<<"\n";
+  if ((sa_distance > pa_distance && sa_distance > pb_distance) ||
+      (sb_distance > pa_distance && sb_distance > pb_distance)) {
+  #else
+  cerr
+    <<" sa_distance:"<<sa_distance
+    <<" sb_distance:"<<sb_distance<<"\n";
   #endif
-    if (spheres > 0) {
+    LVector3f *primary_vec;
+    LPoint3f *primary_center;
+    float primary_radius;
+    LPoint3f *secondary_center;
+    float secondary_radius;
+    if (sa_distance > sb_distance) {
       // sphere_a is the furthest
-      cerr<<"sphere_a is the furthest"<<"\n";
-      float vec_length = sa_vec.length();
-      if (IS_NEARLY_ZERO(vec_length)) {
-        // The centers are coincident, use an arbitrary normal.
-        surface_normal.set(1.0, 0.0, 0.0);
-      } else {
-        surface_normal = sa_vec / vec_length;
-      }
-      interior_point = sa_center - surface_normal * sa_radius;
+      cerr<<"sphere_a is the furthest\n";
+      primary_vec = &sa_vec;
+      primary_center = &sa_center;
+      primary_radius = sa_radius;
+      secondary_center = &sb_center;
+      secondary_radius = sb_radius;
     } else {
       // sphere_b is the furthest
-      cerr<<"sphere_b is the furthest"<<"\n";
-      float vec_length = sb_vec.length();
-      if (IS_NEARLY_ZERO(vec_length)) {
-        // The centers are coincident, use an arbitrary normal.
-        surface_normal.set(1.0, 0.0, 0.0);
-      } else {
-        surface_normal = sb_vec / vec_length;
-      }
-      interior_point = sb_center - surface_normal * sb_radius;
+      cerr<<"sphere_b is the furthest\n";
+      primary_vec = &sb_vec;
+      primary_center = &sb_center;
+      primary_radius = sb_radius;
+      secondary_center = &sa_center;
+      secondary_radius = sa_radius;
+    }
+
+    float vec_length = primary_vec->length();
+    if (IS_NEARLY_ZERO(vec_length)) {
+      // The centers are coincident, use an arbitrary normal.
+      surface_normal.set(1.0, 0.0, 0.0);
+    } else {
+      // Lens face
+      surface_normal = *primary_vec / vec_length;
+    }
+    interior_point = *primary_center - surface_normal * primary_radius;
+
+    float temp_length_squared =
+      (interior_point - *secondary_center).length_squared();
+    if (temp_length_squared > (secondary_radius * secondary_radius)) {
+      cerr<<"foo\n";
+      LVector3f a = (*primary_center - lens_center).normalize();
+      LVector3f b =
+        cross(cross(a, (into_center - lens_center).normalize()), a).normalize();
+      interior_point = lens_center + b * lens_radius;
+      surface_normal = (interior_point - into_center).normalize();
     }
   #if USE_DS_SOLID_PLANES
   } else {
-    if (planes > 0) {
+    if (pa_distance > pb_distance) {
       // plane_a is the furthest
-      cerr<<"plane_a is the furthest"<<"\n";
-      surface_normal = ds_solid->get_plane_a().get_normal();
-      interior_point = into_center - surface_normal * pa_distance;
+      cerr<<"plane_a is the furthest\n";
+      surface_normal = -(ds_solid->get_plane_a().get_normal() * wrt_mat);
+      float d = length(
+        LVector3f(pa_distance, 0.0f, 0.0f) * wrt_mat);
+      interior_point = into_center + surface_normal * d;
     } else {
       // plane_b is the furthest
-      cerr<<"plane_b is the furthest"<<"\n";
-      surface_normal = ds_solid->get_plane_b().get_normal();
-      interior_point = into_center - surface_normal * pb_distance;
+      cerr<<"plane_b is the furthest\n";
+      //surface_normal = -(ds_solid->get_plane_b().get_normal() * wrt_mat);
+      surface_normal = -ds_solid->get_plane_b().get_normal();
+      surface_normal = surface_normal * wrt_mat;
+      float d = length(
+        LVector3f(pb_distance, 0.0f, 0.0f) * wrt_mat);
+      interior_point = into_center + surface_normal * d;
     }
   }
   #endif
 
+  if (collide_cat.is_debug()) {
+    collide_cat.debug()
+      << "intersection detected from " << entry.get_from_node_path()
+      << " into " << entry.get_into_node_path() << "\n";
+  }
+
   PT(CollisionEntry) new_entry = new CollisionEntry(entry);
   new_entry->set_surface_normal(surface_normal);
   new_entry->set_surface_point(into_center + surface_normal * into_radius);