physics engine: impulse

You could probably use some sort of software that can use the diff file posted above, but I did manually. You can see there where the lines that need replacement or adding are and there are (+) and (-) signs where you need to add or cut stuff from the original file.

Anyway, since you probably need the final code, here it is, in case you want to skip patching:

from direct.directbase.DirectStart import * 
from pandac.PandaModules import * 
from direct.showbase.DirectObject import DirectObject 
from direct.task.Task import Task 
from direct.gui.OnscreenText import OnscreenText 
import sys, math, random 

# Function to put title on the screen. 
def addTitle(text): 
    return OnscreenText(text=text, style=1, fg=(1,1,1,1), 
            pos=(1.0,0.8), align=TextNode.ARight, scale = .08) 

# Function to put instructions on the screen. 
def addInstructions(pos, msg): 
    return OnscreenText(text=msg, style=1, fg=(1,1,1,1), 
            pos=(-1.23, pos), align=TextNode.ALeft, scale = .07) 
            
# Function to put output on the screen. 
def addOutput(pos, msg): 
    return OnscreenText(text=msg, style=1, fg=(1,1,1,1), 
            pos=(-1.1, pos), align=TextNode.ALeft, scale = .06) 
            
# Function to put information to the screen. 
def addInfo (msg): 
    return OnscreenText(text=msg, style=1, fg=(1,1,1,1), 
            pos=(0, -0.8), align=TextNode.ACenter, scale = .06) 

class World (DirectObject): 
    def __init__(self): 
        base.win.setClearColor(Vec4(0,0,0,1)) 
        base.setBackgroundColor(0,0,0,1) 

        # Post the instructions 

        self.title = addTitle("Impulse") 
        self.inst1 = addInstructions(0.85, "[ESC]: Quit") 
        self.inst2 = addInstructions(0.75, "[W]:   Applies +Y force") 
        self.inst3 = addInstructions(0.65, "[E]:   Applies -Y force") 
        self.inst4 = addInfo ("The force is applied as long as the key is held down, i.e., the rockets are on and the impulse is increasing") 
        self.output1 = addOutput(0.30, "") 
        self.output2 = addOutput(0.20, "") 
        self.output3 = addOutput(0.10, "") 
        self.output4 = addOutput(0, "") 
        
        
        
        #ambient light 
        self.alight = AmbientLight('alight') 
        self.alight.setColor(VBase4(0.5,0.5, 0.5, 1)) 
        self.alnp = render.attachNewNode(self.alight) 
        render.setLight(self.alnp) 
        
        #light used as a reference point for 0,0,0 
        self.plight = PointLight('plight') 
        self.plight.setColor(VBase4(1, 1, 1, 1)) 
        self.plight.setAttenuation(Point3(0,0.2, 0)) 
        self.plnp = render.attachNewNode(self.plight) 
        render.setLight(self.plnp) 

        #object to apply a force to 
        self.cubeBoy = loader.loadModel('box') 

        #'camera' 
        base.oobe() 
        base.disableMouse() 
        self.camDist =20 
        self.camHeight = 10 
        base.camera.setPos(0,-self.camDist,self.camHeight) 
        base.camera.lookAt(self.cubeBoy) 
        base.camera.reparentTo(self.cubeBoy) 
            
        #initialize variables 
        self.Yforce = 40 
        self.thisPImpulse = 0 
        self.totalPImpulse = 0 
        self.thisNImpulse = 0 
        self.totalNImpulse = 0 
        self.totalImpulse = 0 
        self.currentImpulse = 0 
        self.timeForceApplied = 0 
        
        #setup a force along Y axis 
        self.setupForce() 
        
        #keys to add positive and negative impulse 
        # 
        #as long as the key is held down, the force is applied 
        #i.e., the rockets are on 
        #impulse = force X time 
        #if you increase the amount of time the force is applied 
        #you increase the impulse, which is an increase in acceleration 
        
        self.accept("w", self.PYimpulse, [1]) 
        self.accept("w-up", self.PYimpulse, [-1]) 
        self.accept("e", self.NYimpulse, [1]) 
        self.accept("e-up", self.NYimpulse, [-1]) 
        self.accept("escape", sys.exit) 

        #task to update output 
        taskMgr.add(self.updateT, "updateT") 
        
        
    def updateT(self,task): 
        self.output1 ['text'] = "Cube Position:           %0.2f" % self.cubeBoy.getY(self.plnp) 
        self.output2 ['text'] = "Last applied impulse:    %0.2f" % self.currentImpulse
        self.output3 ['text'] = "Force of 40 applied for: %0.4f seconds " % self.timeForceApplied 
        self.output4 ['text'] = "Total impulse:           %0.2f" % self.totalImpulse 
        return Task.cont 
    
    def PYimpulse(self, arg): 
        if arg ==1: 
            self.pull = LinearVectorForce(0, self.Yforce, 0) 
            self.fn.addForce(self.pull) 
            self.an.getPhysical(0).addLinearForce(self.pull) 
            
            self.startTime = globalClock.getFrameTime() 
        else: 
            self.fn.removeForce(self.pull) 
            self.an.getPhysical(0).removeLinearForce(self.pull) 
            
            self.endTime = globalClock.getFrameTime() 
            self.timeForceApplied = self.endTime - self.startTime 
  
            self.thisPImpulse = self.timeForceApplied * self.Yforce 
            self.currentImpulse = self.thisPImpulse 
            self.totalPImpulse+=self.thisPImpulse #ever applied 
            self.totalImpulse = self.totalPImpulse + self.totalNImpulse #current net impulse 

            
            

        
    def NYimpulse(self, arg): 
        if arg ==1: 
            self.pull = LinearVectorForce(0, -self.Yforce, 0) 
            self.fn.addForce(self.pull) 
            self.an.getPhysical(0).addLinearForce(self.pull) 
            
            self.startTime = globalClock.getFrameTime() 
        else: 
            self.fn.removeForce(self.pull) 
            self.an.getPhysical(0).removeLinearForce(self.pull) 
            
            self.endTime = globalClock.getFrameTime() 
            self.timeForceApplied = self.endTime - self.startTime 
            self.startTime =0 
            
            self.thisNImpulse = self.timeForceApplied * -self.Yforce 
            self.currentImpulse = self.thisNImpulse 
            self.totalNImpulse+=self.thisNImpulse 
            self.totalImpulse = self.totalPImpulse + self.totalNImpulse 
        


    def setupForce(self): 
        # This method must be called to enable the task that computes the 
        # PhysicsManager every frame. 
        base.enableParticles() 

        # The physical object, that is, the object which is acted upon by 
        # the physics system, needs an ActorNode to define the coordinate 
        # system in which it is moving, and to manifest the object's 
        # actions.  
        self.an = ActorNode('actor node') 
        self.anp = render.attachNewNode(self.an) 

        # A model is parented to the ActorNode just so we can see what 
        # it's doing. 
        
        self.cubeBoy.reparentTo(self.anp) 
    
        #light to highlight object 
        self.plight1 = PointLight('plight1') 
        self.plight1.setColor(VBase4(1, 1, 1, 1)) 
        self.plight1.setAttenuation(Point3(0,0.2, 0)) 
        self.plnp1 = self.cubeBoy.attachNewNode(self.plight1) 
        self.plnp1.setPos(0,0,1) 
        render.setLight(self.plnp1) 

        # We need to attach it to a PhysicsManager to do the actual work 
        # of moving it around.  
        base.physicsMgr.attachPhysicalNode(self.an) 

        # Now apply a force to the ActorNode.  The Force needs a 
        # ForceNode, to define the coordinate system in which it is 
        # applied. 
        self.fn = ForceNode('pull') 
        self.fnp = render.attachNewNode(self.fn) 
        self.pull = LinearVectorForce(0, 0, 0) 
        self.fn.addForce(self.pull) 

        # Here we make it a local force that affects only this one 
        # ActorNode.  We could make it a global force instead by adding it 
        # to base.physicsMgr. 
        self.an.getPhysical(0).addLinearForce(self.pull) 
    
w=World() 
run()