Browse Source

use new parabola-based collision system

David Rose 18 years ago
parent
commit
2a3d4d0934
1 changed files with 41 additions and 9 deletions
  1. 41 9
      direct/src/interval/ProjectileInterval.py

+ 41 - 9
direct/src/interval/ProjectileInterval.py

@@ -28,7 +28,8 @@ class ProjectileInterval(Interval):
                  endPos = None, duration = None,
                  endPos = None, duration = None,
                  startVel = None, endZ = None,
                  startVel = None, endZ = None,
                  wayPoint = None, timeToWayPoint = None,
                  wayPoint = None, timeToWayPoint = None,
-                 gravityMult = None, name = None):
+                 gravityMult = None, name = None,
+                 collNode = None):
         """
         """
         You may specify several different sets of input parameters.
         You may specify several different sets of input parameters.
         (If startPos is not provided, it will be obtained from the node's
         (If startPos is not provided, it will be obtained from the node's
@@ -48,8 +49,22 @@ class ProjectileInterval(Interval):
         You may alter gravity by providing a multiplier in 'gravityMult'.
         You may alter gravity by providing a multiplier in 'gravityMult'.
         '2.' will make gravity twice as strong, '.5' half as strong.
         '2.' will make gravity twice as strong, '.5' half as strong.
         '-1.' will reverse gravity
         '-1.' will reverse gravity
+
+        If collNode is not None, it should be an empty CollisionNode
+        which will be filled with an appropriate CollisionParabola
+        when the interval starts.  This CollisionParabola will be set
+        to match the interval's parabola, and its t1, t2 values will
+        be updated automatically as the interval plays.  It will *not*
+        be automatically removed from the node when the interval
+        finishes.
+        
         """
         """
         self.node = node
         self.node = node
+        self.collNode = collNode
+        if self.collNode:
+            if isinstance(self.collNode, NodePath):
+                self.collNode = self.collNode.node()
+            assert self.collNode.getNumSolids() == 0
 
 
         if name == None:
         if name == None:
             name = '%s-%s' % (self.__class__.__name__,
             name = '%s-%s' % (self.__class__.__name__,
@@ -158,7 +173,7 @@ class ProjectileInterval(Interval):
             assert not timeToWayPoint
             assert not timeToWayPoint
             self.duration = duration
             self.duration = duration
             self.startVel = startVel
             self.startVel = startVel
-            self.endPos = self.__calcPos(self.duration)
+            self.endPos = None
         elif (None not in (startVel, endZ)):
         elif (None not in (startVel, endZ)):
             assert not endPos
             assert not endPos
             assert not duration
             assert not duration
@@ -171,7 +186,7 @@ class ProjectileInterval(Interval):
                 self.notify.error(
                 self.notify.error(
                     'projectile never reaches plane Z=%s' % endZ)
                     'projectile never reaches plane Z=%s' % endZ)
             self.duration = time
             self.duration = time
-            self.endPos = self.__calcPos(self.duration)
+            self.endPos = None
         elif (None not in (wayPoint, timeToWayPoint, endZ)):
         elif (None not in (wayPoint, timeToWayPoint, endZ)):
             assert not endPos
             assert not endPos
             assert not duration
             assert not duration
@@ -182,16 +197,24 @@ class ProjectileInterval(Interval):
                                          timeToWayPoint, self.zAcc)
                                          timeToWayPoint, self.zAcc)
             self.duration = calcTimeOfLastImpactOnPlane(
             self.duration = calcTimeOfLastImpactOnPlane(
                 self.startPos[2], endZ, self.startVel[2], self.zAcc)
                 self.startPos[2], endZ, self.startVel[2], self.zAcc)
-            self.endPos = self.__calcPos(self.duration)
+            self.endPos = None
         else:
         else:
             self.notify.error('invalid set of inputs to ProjectileInterval')
             self.notify.error('invalid set of inputs to ProjectileInterval')
 
 
+        self.parabola = Parabolaf(VBase3(0, 0, 0.5 * self.zAcc),
+                                  self.startVel,
+                                  self.startPos)
+
+        if not self.endPos:
+            self.endPos = self.__calcPos(self.duration)
+            
         # these are the parameters that we need to know:
         # these are the parameters that we need to know:
         self.notify.debug('startPos: %s' % `self.startPos`)
         self.notify.debug('startPos: %s' % `self.startPos`)
         self.notify.debug('endPos:   %s' % `self.endPos`)
         self.notify.debug('endPos:   %s' % `self.endPos`)
         self.notify.debug('duration: %s' % self.duration)
         self.notify.debug('duration: %s' % self.duration)
         self.notify.debug('startVel: %s' % `self.startVel`)
         self.notify.debug('startVel: %s' % `self.startVel`)
         self.notify.debug('z-accel:  %s' % self.zAcc)
         self.notify.debug('z-accel:  %s' % self.zAcc)
+            
 
 
     def __initialize(self):
     def __initialize(self):
         if self.implicitStartPos:
         if self.implicitStartPos:
@@ -199,22 +222,31 @@ class ProjectileInterval(Interval):
 
 
     def privInitialize(self, t):
     def privInitialize(self, t):
         self.__initialize()
         self.__initialize()
+        if self.collNode:
+            self.collNode.clearSolids()
+            csolid = CollisionParabola(self.parabola, 0, 0)
+            self.collNode.addSolid(csolid)
+
         Interval.privInitialize(self, t)
         Interval.privInitialize(self, t)
 
 
     def privInstant(self):
     def privInstant(self):
         self.__initialize()
         self.__initialize()
         Interval.privInstant(self)
         Interval.privInstant(self)
+        if self.collNode:
+            self.collNode.clearSolids()
+            csolid = CollisionParabola(self.parabola, 0, self.duration)
+            self.collNode.addSolid(csolid)
 
 
     def __calcPos(self, t):
     def __calcPos(self, t):
-        return Point3(
-            self.startPos[0] + (self.startVel[0] * t),
-            self.startPos[1] + (self.startVel[1] * t),
-            (self.startPos[2] + (self.startVel[2] * t) +
-             (.5 * self.zAcc * t * t)))
+        return self.parabola.calcPoint(t)
 
 
     def privStep(self, t):
     def privStep(self, t):
         self.node.setFluidPos(self.__calcPos(t))
         self.node.setFluidPos(self.__calcPos(t))
         Interval.privStep(self, t)
         Interval.privStep(self, t)
+        if self.collNode and self.collNode.getNumSolids() > 0:
+            csolid = self.collNode.modifySolid(0)
+            csolid.setT1(csolid.getT2())
+            csolid.setT2(t)
 
 
 """
 """
         ##################################################################
         ##################################################################