a brail for the lady - motion trail

#lightspeed brail 
#animation and changes by dhochegger 2008 
#based on the motion trail tutorial Josh Yelon 
# 
from pandac.PandaModules import Point3,Vec3,Vec4 
import direct.directbase.DirectStart 
from pandac.PandaModules import GraphicsOutput 
from pandac.PandaModules import Filename,Texture 
from pandac.PandaModules import CardMaker,Vec4 
from pandac.PandaModules import NodePath,TextNode 
from pandac.PandaModules import AmbientLight,DirectionalLight 
from direct.showbase.DirectObject import DirectObject 
from direct.gui.OnscreenText import OnscreenText 
from pandac.PandaModules import Texture 
from direct.task.Task import Task 
from direct.actor.Actor import Actor 
from random import uniform 
import sys,os 
import math 

base.disableMouse() 

base.setBackgroundColor(0,0,0) 

MYDIR=os.path.abspath(sys.path[0]) 
MYDIR=Filename.fromOsSpecific(MYDIR).getFullpath() 

def addInstructions(pos, msg): 
    return OnscreenText(text=msg, 
                         style=1, fg=(1,1,1,1), pos=(-1.3, pos), 
                        align=TextNode.ALeft, scale = .05) 

class MotionTrails(DirectObject): 
    def __init__(self): 
        
        # create a texture into which we can copy the main window. 

        self.tex = Texture() 
        self.tex.setMinfilter(Texture.FTLinear) 
        self.tex.setMagfilter(Texture.FTLinear) 
        self.tex.isMipmap(Texture.FTLinearMipmapLinear) 
        self.tex.setAnisotropicDegree(100) 
        base.win.addRenderTexture(self.tex, GraphicsOutput.RTMTriggeredCopyTexture) 
        
        # Create another 2D camera. Tell it to render before the main camera. 

        self.backcam = base.makeCamera2d(base.win, sort=-10) 
        self.background = NodePath("background") 
        self.backcam.reparentTo(self.background) 
        self.background.setDepthTest(0) 
        self.background.setDepthWrite(0) 
        self.backcam.node().getDisplayRegion(0).setClearDepthActive(0) 

        # Obtain two texture cards. One renders before the dragon, the other after. 
        self.bcard = base.win.getTextureCard() 
        self.bcard.reparentTo(self.background) 
        self.bcard.setTransparency(1) 
        self.fcard = base.win.getTextureCard() 
        self.fcard.reparentTo(render2d) 
        self.fcard.setTransparency(1) 
        
        self.bcard1 = base.win.getTextureCard() 
        self.bcard1.reparentTo(self.background) 
        self.bcard1.setTransparency(1) 
        self.fcard1 = base.win.getTextureCard() 
        self.fcard1.reparentTo(render2d) 
        self.fcard1.setTransparency(1) 

        # Initialize one of the nice effects. 
        self.chooseEffectWhirlpool() 
        
        # Add the task that initiates the screenshots. 
        taskMgr.add(self.takeSnapShot, "takeSnapShot") 



        if (base.win.getGsg().getCopyTextureInverted()): 
            self.bcard.setScale(1,1,-1) 
            self.fcard.setScale(1,1,-1) 
            
            self.bcard1.setScale(1,1,-1) 
            self.fcard1.setScale(1,1,-1) 


    
    def takeSnapShot(self, task): 
        if (task.time > self.nextclick): 
            self.nextclick += .001 / self.clickrate 
            if (self.nextclick < task.time): 
                self.nextclick = task.time 
            base.win.triggerCopy() 
        return Task.cont 



    def chooseEffectWhirlpool(self): 
        sat = loader.loadModel("smiley") 
        planet = loader.loadModel("smiley") 
        def rot(task): 
            t = task.time 
            speed = t / math.cos(5)*math.sin(5)/5 
            dis = sat.getPos() - planet.getPos() 
            distance=dis.length() 
            ampX = 20 -distance 
            ampZ = 2 -distance 
            self.bcard.setR(math.cos(speed)*math.sin(speed)+distance) 
            self.bcard.setScale(0.5*distance/math.cos(speed)*math.sin(speed)) 
            self.clickrate = 1000*distance 
            self.bcard.setColor(.2+math.cos(speed/10*distance),.2+math.cos(speed*5),.2*math.cos(t),1) 
            sat.setX(ampX*math.sin(speed)) 
            sat.setZ(ampZ*math.cos(speed)) 
            return task.cont 
 
        taskMgr.add(rot,"rotTask") 
        base.setBackgroundColor(0,0,0,0) 
        self.bcard.show() 
        self.fcard.hide() 
        self.bcard.setPos(0,0,0) 
        self.nextclick = 0 
        
        sat = loader.loadModel("smiley") 
        planet = loader.loadModel("smiley") 
        def rot(task): 
            t = task.time 
            speed = t /5 
            dis = sat.getPos() - planet.getPos() 
            distance=dis.length() 
            ampX = 20 -distance 
            ampZ = 2 -distance 
            self.bcard1.setR(math.cos(speed)*math.sin(speed)) 
            self.bcard1.setScale(0.1*distance) 
            self.clickrate = 100000*distance 
            self.bcard1.setColor(.2+math.cos(speed),.2+math.cos(distance*10),.5+math.cos(speed*10),1) 
            sat.setX(ampX*math.sin(speed)) 
            sat.setZ(ampZ*math.cos(speed)) 
            return task.cont 

        taskMgr.add(rot,"rotTask") 
        base.setBackgroundColor(0,0,0,0) 
        self.bcard1.show() 
        self.fcard1.hide() 
        self.bcard1.setPos(0,0,0) 
        self.nextclick = 0 

        
t=MotionTrails() 

sat = loader.loadModel("smiley") 
sat.reparentTo(render) 
sat.setPos(0,0,0) 

sat1 = loader.loadModel("smiley") 
sat1.reparentTo(render) 


sat2 = loader.loadModel("smiley") 
sat2.reparentTo(render) 


planet = loader.loadModel("smiley") 
#planet.reparentTo(render) 
        

def rot(task): 
            t = task.time 

            
            speed = t / math.cos(5)*math.sin(5)          
            global distance 
            dis = sat.getPos() - planet.getPos() 
            distance=dis.length() 

            planet.setH(-45*distance) 

            ampX = 20 -distance 
            ampZ = 10 -distance 
            
            ampX1 = 1 -distance 
            ampZ1 = 1 -distance 
            
            ampX2 = 5 -distance 
            ampZ2 = 15-distance 

                        
            px =planet.getX() 
            py =planet.getY() 
            pz =planet.getZ() 
            
            sx =sat.getX() 
            sy =sat.getY() 
            sz =sat.getZ() 
            

            damp = 200 
            power = distance/damp                

            
            sat.setX(ampX*math.sin(speed)) 
            sat.setZ(ampZ*math.cos(speed)) 
            
            sat1.setX(ampX1*math.sin(speed)) 
            sat1.setZ(ampZ1*math.cos(speed)) 
                      
            sat2.setX(ampX2*math.sin(speed)) 
            sat2.setZ(ampZ2*math.cos(speed)) 
            

            base.camera.setPos(0,-10*distance,0) 

            return task.cont 
taskMgr.add(rot,"rotTask") 


#put some lighting on the model 
dlight = DirectionalLight('dlight') 
alight = AmbientLight('alight') 
dlnp = render.attachNewNode(dlight.upcastToPandaNode()) 
alnp = render.attachNewNode(alight.upcastToPandaNode()) 
dlight.setColor(Vec4(1.0, 0.9, 0.8, 1)) 
alight.setColor(Vec4(0.2, 0.3, 0.4, 1)) 
dlnp.setHpr(0, -60, 0) 
render.setLight(dlnp) 
render.setLight(alnp) 

run()