Slight performance issue - Panda3D + arduino

Hi guys! Long time no see, hope everyone is doing well!

Here’s the thing, I’m preparing a demo for TEI with my girlfriend and I’m having a small issue…basically we have this structure: vimeo.com/33971358
and it’s working fine with the keyboard but when i use the sensors to trigger the animations on and off, it’s a little finicky! I think the issue might relate to the way I’m loading the videos:

from panda3d.core import * 
# Tell Panda3D to use OpenAL, not FMOD 
loadPrcFileData("", "textures-power-2 none") 
loadPrcFileData("", "audio-library-name p3openal_audio") 
from direct.showbase.DirectObject import DirectObject 
from direct.gui.OnscreenText import OnscreenText 
import direct.directbase.DirectStart 
from direct.gui.OnscreenImage import OnscreenImage
from button import *

from button import *

# The name of the media file. 
MEDIAFILE1="AA_500.mov" 
MEDIAFILE2="BB_500_second.mov" 
MEDIAFILE3="CC_500_second.mov"
MEDIAFILE4="DD_500.mov"

MEDIA={
            'p':"AA_500.mov" ,'o':"BB_500_second.mov" ,
            'i':"CC_500_second.mov",'u':"DD_500.mov",
}

ALPHA1="AA_500_opacity.mov"
ALPHA2="BB_500_opacity_second.mov"
ALPHA3="CC_500_opacity_second.mov"
ALPHA4="DD_500_opacity.mov"

ALPHA={
    'p':"AA_500_opacity.mov",
    'o':"BB_500_opacity_second.mov",
    'i':"CC_500_opacity_second.mov",
    'u':"DD_500_opacity.mov",
}

SOUNDS={
    'p':'opa1.wav','o':'opa2.wav','i':'opa3.wav','u':'opa4.wav',
}

BACKGROUND='default.egg'
USE_SENSOR=False

class World(DirectObject): 

    def __init__(self):
        base.setBackgroundColor(1,1,1,1) 
        if USE_SENSOR:
            self.sensor=Buttons(self.handler)
        base.disableMouse()
        self.keys={
                   'p':False, 'o':False,
                   'i':False, 'u':False,
        }
        self.sounds={
            'p':None, 'o':None,
            'i':None, 'u':None,
        }
        self.video={}
        self.enterDefault()
       
        self.accept('p', self.handler,extraArgs=['p',True])
        self.accept('p-up', self.handler,extraArgs=['p',False])
        self.accept('o', self.handler,extraArgs=['o',True])
        self.accept('o-up', self.handler,extraArgs=['o',False])
        self.accept('u', self.handler,extraArgs=['u',True])
        self.accept('u-up', self.handler,extraArgs=['u',False])
        self.accept('i', self.handler,extraArgs=['i',True])
        self.accept('i-up', self.handler,extraArgs=['i',False])

    def enterDefault(self):
       
        base.camera.setPos(0,0,0)
        self.default=self.loadegg(BACKGROUND,(0,20,0),(0,0,0),(8,1,8))
        
    def handler(self,b,s):
        if self.keys[b] is not s:
            if s is True:
               
                self.createVideo(b)
            else:
                self.removeVideo(b)
            self.keys[b]=s
        
    def setVisibility(self,obj,v):
        if v:
            obj.show()
        else:
            obj.hide()
            
    def createVideo(self,d):
        base.setBackgroundColor(1,1,1,1) 
        tex = MovieTexture("1") 
        assert tex.read(MEDIA[d],ALPHA[d],3,1), "Failed to load video!" 
        
        #tex = self.mediaTextureList[index];
        # Set up a fullscreen card to set the video texture on. 
        cm = CardMaker("My Fullscreen Card"); 
        cm.setFrameFullscreenQuad() 
        cm.setUvRange(tex) 
        self.video[d] = NodePath(cm.generate()) 
        self.video[d].reparentTo(render2d) 
        self.video[d].setTransparency(TransparencyAttrib.MAlpha) 
        self.video[d].setScale(self.video[d], 0.5)
        self.video[d].setTexture(tex) 
        self.video[d].setTexScale(TextureStage.getDefault(), tex.getTexScale()) 
        self.sounds[d]=loader.loadSfx(SOUNDS[d]) 
        # Synchronize the video to the sound. 
        tex.synchronizeTo(self.sounds[d]) 
        tex.stop()
        self.sounds[d].play()

    def removeVideo(self,d):
        self.video[d].remove()
        base.setBackgroundColor(1,1,1,1)
        self.tex4 = MovieTexture("4") 
        assert self.tex4.read(MEDIAFILE4,ALPHA4,3,1), "Failed to load video!" 

        # Set up a fullscreen card to set the video texture on. 
        cm = CardMaker("My Fullscreen Card"); 
        cm.setFrameFullscreenQuad() 
        cm.setUvRange(self.tex4) 
        card = NodePath(cm.generate()) 
        card.reparentTo(render2d) 
        card.setTransparency(TransparencyAttrib.MAlpha) 
        card.setScale(card, 1) 
        card.setTexture(self.tex4) 
        card.setTexScale(TextureStage.getDefault(), self.tex4.getTexScale())
        self.sounds['u']=loader.loadSfx('opa4.wav') 
        # Synchronize the video to the sound. 
        self.tex4.synchronizeTo(self.sounds['u']) 
        
        self.tex4.stop()
         
    def loadegg(self,path,pos,hpr,size):
        model=loader.loadModel(path)
        model.setPos(pos[0],pos[1],pos[2])
        model.setHpr(hpr[0],hpr[1],hpr[2])
        model.setScale(size[0],size[1],size[2])
        model.reparentTo(render)
        return model    
  
w = World() 
run() 

I talked to a friend who suggested this:

def __init__(self):
        ## make every MoviceTexture in advance
        ## self.mediaTextureList= {}
        ## for( ..... )   
                        
    def createVideo(self,d):
        ## intead of loading media every time
        tex = MovieTexture("1")   
        assert tex.read(MEDIA[d],ALPHA[d],3,1), "Failed to load video!" 
        ## uses MovieTexture loaded above

        tex = self.mediaTextureList[index];

But i really have no idea what he meant by that…any thoughts?

Thank you so much!

He means that instead of constantly creating and destroying your MovieTexture object, you should create a dictionary of MovieTexture objects in your class and swap them with each other.

thank you rdb (and thanks for getting me to my pm)

if anyone knows how to implement the proposed solution, i would be really appreciated since i honestly can’t figure that one out 8)

I already found out that P3D can’t handle creating and destroying instances on the fly. It’s way too expensive.

Instead, I always create a list or similar means for purpose of rotating geometry, textures, particles, etc.

Actually, I don’t know if you can pin that on P3D; it might just be python’s handling of unneeded instances causing the performance drop.

One could argue and say, destroying unneeded instances just takes time, but I have used some engines in the past that were able to create and destroy on the fly, but then again, those engines where developed and scripted to with either Delphi or C, entirely.

Any takers on this thought?