Frame Tweening

Here is a framework I threw together for frame tweening…it appears to work. Note that base.setFrameRateMeter(True) shows the frames not of the program but of the game logic update…hence I made my own. Any feedback appreciated!

from pandac.PandaModules import loadPrcFileData
#loadPrcFileData("", "sync-video 0" )
#loadPrcFileData("", "sync-flip 0" )

import direct.directbase.DirectStart
from pandac.PandaModules import *
import time as GTime
from math import *
import sys

def time():
	#millisecs
	return GTime.time()*1000

class tweener:
	#time=pygame.time.get_ticks
	gameUPS = 60				#set this to your desired frame rate...*TO DO* make it set to monitor refresh rate
	period = int(1000 / gameUPS +.5)
	frameTime = int(time() - period +.5)

	frame_l = []

	def __init__(self):
		base.win.setActive(False)

	def captureWorld(self):
		l = render.findAllMatches('**/=tween=1')
		#l = render.findAllMatches('**/*')
		self.frame_l=[]
		for n in range(0,l.getNumPaths()):
			self.frame_l.append( [l[n],l[n].getPos(),l[n].getQuat(),l[n].getScale()] )

	def renderWorld(self,tween):
		#set all nodes to correct positions
		for f in self.frame_l:
			cur_pos,cur_rot,cur_scale = f[0].getPos(),f[0].getQuat(),f[0].getScale()
			p=f[1]+(cur_pos-f[1])*tween
			#p=f[1]*(1-tween)+cur_pos*tween
			r=f[2] + (cur_rot-f[2])*tween ; r.normalize()  #nlerp

			#r=f[2]*(1-tween)+cur_rot*tween ; r.normalize() #nlerp
			s=f[3]+(cur_scale-f[3])*tween
			#s=f[3]*(1-tween)+cur_scale*tween
			f[1],f[2],f[3]=cur_pos,cur_rot,cur_scale
			f[0].setPosQuatScale(p,r,s)
		#render
		base.win.setActive(True)
		base.graphicsEngine.renderFrame()
		base.win.setActive(False)

		#reset all nodes...
		for f in self.frame_l:
			f[0].setPosQuatScale(f[1],f[2],f[3])
	
	def run(self):
		self.frameTime = int(time() - self.period +.5)
		while (True):
			while(True):
				elapsed = int(time() - self.frameTime +.5)
				if elapsed>0: break

			ticks = int(elapsed / self.period + .5)
			tween = elapsed % self.period / float(self.period)

			for i in range(1,ticks+1):
				if i==ticks: self.captureWorld()
				self.frameTime+=self.period
				taskMgr.step()

			self.renderWorld(tween)

#note shows logic updates, not frames
#base.setFrameRateMeter(True)

smiley=loader.loadModel('models/smiley.egg.pz')
smiley.setPos(0,0,0)
smiley.setColor(1,0,0,1)
smiley.reparentTo(render)
smiley.setTag('tween','1')

smiley2=loader.loadModel('models/smiley.egg.pz')
smiley2.setColor(0,1,0,1)
smiley2.setPos(10,0,0)
smiley2.reparentTo(smiley)
smiley2.setTag('tween','1')

smiley3=loader.loadModel('models/smiley.egg.pz')
smiley3.setColor(0,0,1,1)
smiley3.setPos(-10,0,0)
smiley3.reparentTo(smiley)
smiley3.setTag('tween','1')

smiley4=loader.loadModel('models/smiley.egg.pz')
smiley4.setColor(1,1,0,1)
smiley4.setPos(0,10,0)
smiley4.reparentTo(smiley)
smiley4.setTag('tween','1')

smiley5=loader.loadModel('models/smiley.egg.pz')
smiley5.setColor(1,0,1,1)
smiley5.setPos(0,-10,0)
smiley5.reparentTo(smiley)
smiley5.setTag('tween','1')

smiley6=loader.loadModel('models/smiley.egg.pz')
smiley6.setColor(0,1,1,1)
smiley6.setPos(0,0,10)
smiley6.reparentTo(smiley)
smiley6.setTag('tween','1')

smiley7=loader.loadModel('models/smiley.egg.pz')
smiley7.setColor(0,0,0,1)
smiley7.setPos(0,0,-10)
smiley7.reparentTo(smiley)
smiley7.setTag('tween','1')

camNode=NodePath(PandaNode(''))
camNode.reparentTo(render)
camNode.setTag('tween','1')
base.camera.reparentTo(camNode)
base.camera.setPos(0,-100,0)
base.camera.setTag('tween','1')
base.disableMouse()

quat=Quat()
quat.setHpr(Vec3(1,.5,0))

quat2=Quat()
quat2.setHpr(Vec3(-1,0,.5))

def update(task):
	global smiley,camNode,quat,quat2,direction
	smiley.setQuat(smiley.getQuat()*quat)
	camNode.setQuat(camNode.getQuat()*quat2)
	base.camera.setPos(0,50*(sin(radians(camNode.getH()))-1)-100,0)
	return task.cont
taskMgr.add(update,'u')

t=tweener()
t.run()

Uhmm, what about this in Config.prc:

interpolate-frames 1

From the docs, that looks like it does the other half of what I am trying to do…the animations. I was looking for something that would basically do that for everything (pos,scale,rot). It does not do animation yet, but I am working on that now (although, do I need to with this true??)