panda3d/direct/src/interval/LerpInterval.py
2002-02-09 00:58:34 +00:00

425 lines
17 KiB
Python

"""LerpInterval module: contains the LerpInterval class"""
from Interval import *
from PandaModules import *
import LerpBlendHelpers
class LerpInterval(Interval):
# create LerpInterval DirectNotify category
notify = directNotify.newCategory('LerpInterval')
# Class methods
def __init__(self, name, duration, functorFunc, blendType='noBlend'):
"""__init__(name, duration, functorFunc, blendType)
"""
# Record instance variables
self.lerp = None
self.functorFunc = functorFunc
self.blendType = self.getBlend(blendType)
# Initialize superclass
Interval.__init__(self, name, duration)
def updateFunc(self, t, event = IVAL_NONE):
""" updateFunc(t, event)
"""
# Check to see if we need to create the lerp
if (event == IVAL_INIT):
self.lerp = Lerp(self.functorFunc(), self.duration,
self.blendType)
# Make sure lerp exists
if (not self.lerp):
self.lerp = Lerp(self.functorFunc(), self.duration,
self.blendType)
# Evaluate the lerp
self.lerp.setT(t)
# Print debug information
self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t))
def getBlend(self, blendType):
"""__getBlend(self, string)
Return the C++ blend class corresponding to blendType string
"""
if (blendType == "easeIn"):
return LerpBlendHelpers.easeIn
elif (blendType == "easeOut"):
return LerpBlendHelpers.easeOut
elif (blendType == "easeInOut"):
return LerpBlendHelpers.easeInOut
elif (blendType == "noBlend"):
return LerpBlendHelpers.noBlend
else:
raise Exception(
'Error: LerpInterval.__getBlend: Unknown blend type')
class LerpPosInterval(LerpInterval):
# Name counter
lerpPosNum = 1
# Class methods
def __init__(self, node, duration, pos, startPos=None,
other=None, blendType='noBlend', name=None):
""" __init__(node, duration, pos, startPos, other, blendType, name)
"""
def functorFunc(node=node, pos=pos, startPos=startPos,
other=other):
assert(not node.isEmpty())
if callable(pos):
# This may be a thunk that returns a point.
pos = pos()
if (other != None):
# lerp wrt other
if (startPos == None):
startPos = node.getPos(other)
functor = PosLerpFunctor(node, startPos, pos, other)
else:
if (startPos == None):
startPos = node.getPos()
functor = PosLerpFunctor(node, startPos, pos)
return functor
# Generate unique name if necessary
if (name == None):
name = 'LerpPosInterval-%d' % LerpPosInterval.lerpPosNum
LerpPosInterval.lerpPosNum += 1
# Initialize superclass
LerpInterval.__init__(self, name, duration, functorFunc, blendType)
class LerpHprInterval(LerpInterval):
# Name counter
lerpHprNum = 1
# Class methods
def __init__(self, node, duration, hpr, startHpr=None,
other=None, blendType='noBlend', name=None):
""" __init__(node, duration, hpr, startHpr, other, blendType, name)
"""
def functorFunc(node=node, hpr=hpr, startHpr=startHpr,
other=other):
assert(not node.isEmpty())
if callable(hpr):
# This may be a thunk that returns a point.
hpr = hpr()
if (other != None):
# lerp wrt other
if (startHpr == None):
startHpr = VBase3(node.getHpr(other))
functor = HprLerpFunctor(node, startHpr, hpr, other)
else:
if (startHpr == None):
startHpr = node.getHpr()
functor = HprLerpFunctor(node, startHpr, hpr)
return functor
# Generate unique name if necessary
if (name == None):
name = 'LerpHprInterval-%d' % LerpHprInterval.lerpHprNum
LerpHprInterval.lerpHprNum += 1
# Initialize superclass
LerpInterval.__init__(self, name, duration, functorFunc, blendType)
class LerpScaleInterval(LerpInterval):
# Interval counter
lerpScaleNum = 1
# Class methods
def __init__(self, node, duration, scale, startScale=None,
other=None, blendType='noBlend', name=None):
""" __init__(node, duration, scale, startScale, other, blendType, name)
"""
def functorFunc(node=node, scale=scale,
startScale=startScale, other=other):
assert(not node.isEmpty())
if callable(scale):
# This may be a thunk that returns a point.
scale = scale()
if (other != None):
# lerp wrt other
if (startScale == None):
startScale = node.getScale(other)
functor = ScaleLerpFunctor(node, startScale, scale, other)
else:
if (startScale == None):
startScale = node.getScale()
functor = ScaleLerpFunctor(node, startScale, scale)
return functor
# Generate unique name if necessary
if (name == None):
name = 'LerpScaleInterval-%d' % LerpScaleInterval.lerpScaleNum
LerpScaleInterval.lerpScaleNum += 1
# Initialize superclass
LerpInterval.__init__(self, name, duration, functorFunc, blendType)
class LerpPosHprInterval(LerpInterval):
# Interval counter
lerpPosHprNum = 1
def __init__(self, node, duration, pos, hpr, startPos=None,
startHpr=None, other=None, blendType='noBlend', name=None):
""" __init__(node, duration, pos, hpr, startPos, startHpr,
other, blendType, name)
"""
def functorFunc(node=node, pos=pos, hpr=hpr,
startPos=startPos, startHpr=startHpr, other=other):
assert(not node.isEmpty())
if callable(pos):
# This may be a thunk that returns a point.
pos = pos()
if callable(hpr):
# This may be a thunk that returns a point.
hpr = hpr()
if (other != None):
# lerp wrt other
if (startPos == None):
startPos = node.getPos(other)
if (startHpr == None):
startHpr = node.getHpr(other)
functor = PosHprLerpFunctor(
node, startPos, pos,
startHpr, hpr, other)
else:
if (startPos == None):
startPos = node.getPos()
if (startHpr == None):
startHpr = node.getHpr()
functor = PosHprLerpFunctor(
node, startPos, pos,
startHpr, hpr)
return functor
# Generate unique name if necessary
if (name == None):
name = 'LerpPosHpr-%d' % LerpPosHprInterval.lerpPosHprNum
LerpPosHprInterval.lerpPosHprNum += 1
# Initialize superclass
LerpInterval.__init__(self, name, duration, functorFunc, blendType)
class LerpHprScaleInterval(LerpInterval):
# Interval counter
lerpHprScaleNum = 1
# Class methods
def __init__(self, node, duration, hpr, scale,
startHpr=None, startScale=None,
other=None, blendType='noBlend', name=None):
""" __init__(node, duration, hpr, scale,
startHpr, startScale,
other, blendType, name)
"""
def functorFunc(node=node, hpr=hpr, scale=scale,
startHpr=startHpr,
startScale=startScale, other=other):
assert(not node.isEmpty())
if callable(hpr):
# This may be a thunk that returns a point.
hpr = hpr()
if callable(scale):
# This may be a thunk that returns a point.
scale = scale()
if (other != None):
# lerp wrt other
if (startHpr == None):
startHpr = node.getHpr(other)
if (startScale == None):
startScale = node.getScale(other)
functor = HprScaleLerpFunctor(
node, startHpr, hpr,
startScale, scale, other)
else:
if (startHpr == None):
startHpr = node.getHpr()
if (startScale == None):
startScale = node.getScale()
functor = HprScaleLerpFunctor(
node, startHpr, hpr, startScale, scale)
return functor
# Generate unique name if necessary
if (name == None):
name = ('LerpHprScale-%d' %
LerpHprScaleInterval.lerpHprScaleNum)
LerpHprScaleInterval.lerpHprScaleNum += 1
# Initialize superclass
LerpInterval.__init__(self, name, duration, functorFunc, blendType)
class LerpPosHprScaleInterval(LerpInterval):
# Interval counter
lerpPosHprScaleNum = 1
# Class methods
def __init__(self, node, duration, pos, hpr, scale,
startPos=None, startHpr=None, startScale=None,
other=None, blendType='noBlend', name=None):
""" __init__(node, duration, pos, hpr, scale,
startPos, startHpr, startScale,
other, blendType, name)
"""
def functorFunc(node=node, pos=pos, hpr=hpr, scale=scale,
startPos=startPos, startHpr=startHpr,
startScale=startScale, other=other):
assert(not node.isEmpty())
if callable(pos):
# This may be a thunk that returns a point.
pos = pos()
if callable(hpr):
# This may be a thunk that returns a point.
hpr = hpr()
if callable(scale):
# This may be a thunk that returns a point.
scale = scale()
if (other != None):
# lerp wrt other
if (startPos == None):
startPos = node.getPos(other)
if (startHpr == None):
startHpr = node.getHpr(other)
if (startScale == None):
startScale = node.getScale(other)
functor = PosHprScaleLerpFunctor(
node, startPos, pos, startHpr, hpr,
startScale, scale, other)
else:
if (startPos == None):
startPos = node.getPos()
if (startHpr == None):
startHpr = node.getHpr()
if (startScale == None):
startScale = node.getScale()
functor = PosHprScaleLerpFunctor(
node, startPos, pos, startHpr, hpr, startScale, scale)
return functor
# Generate unique name if necessary
if (name == None):
name = ('LerpPosHprScale-%d' %
LerpPosHprScaleInterval.lerpPosHprScaleNum)
LerpPosHprScaleInterval.lerpPosHprScaleNum += 1
# Initialize superclass
LerpInterval.__init__(self, name, duration, functorFunc, blendType)
# Class used to execute a function over time. Function can access fromData
# and toData to perform blend. If fromData and toData not specified, will
# execute the given function passing in values ranging from 0 to 1
class LerpFunctionInterval(Interval):
# Interval counter
lerpFunctionIntervalNum = 1
# create LerpFunctionInterval DirectNotify category
notify = directNotify.newCategory('LerpFunctionInterval')
# Class methods
def __init__(self, function, fromData = 0, toData = 1, duration = 0.0,
blendType = 'noBlend', extraArgs = [], name = None):
"""__init__(function, duration, fromData, toData, name)
"""
# Record instance variables
self.function = function
self.fromData = fromData
self.toData = toData
self.blendType = self.getBlend(blendType)
self.extraArgs = extraArgs
# Generate unique name if necessary
if (name == None):
name = ('LerpFunctionInterval-%d' %
LerpFunctionInterval.lerpFunctionIntervalNum)
LerpFunctionInterval.lerpFunctionIntervalNum += 1
# Initialize superclass
Interval.__init__(self, name, duration)
def updateFunc(self, t, event = IVAL_NONE):
""" updateFunc(t, event)
"""
# Evaluate the function
if (t >= self.duration):
# Set to end value
apply(self.function, [self.toData] + self.extraArgs)
elif self.duration == 0.0:
# Zero duration, just use endpoint
apply(self.function, [self.toData] + self.extraArgs)
else:
# In the middle of the lerp, compute appropriate blended value
bt = self.blendType(t/self.duration)
data = (self.fromData * (1 - bt)) + (self.toData * bt)
# Evaluate function
apply(self.function, [data] + self.extraArgs)
# Print debug information
self.notify.debug('updateFunc() - %s: t = %f' % (self.name, t))
def getBlend(self, blendType):
"""__getBlend(self, string)
Return the C++ blend class corresponding to blendType string
"""
# Note, this is temporary until blend functions get exposed
if (blendType == "easeIn"):
return LerpBlendHelpers.easeIn
elif (blendType == "easeOut"):
return LerpBlendHelpers.easeOut
elif (blendType == "easeInOut"):
return LerpBlendHelpers.easeInOut
elif (blendType == "noBlend"):
return LerpBlendHelpers.noBlend
else:
raise Exception(
'Error: LerpInterval.__getBlend: Unknown blend type')
# New interface
class LerpFunc(LerpFunctionInterval):
def __init__(self, *args, **kw):
LerpFunctionInterval.__init__(self, *args, **kw)
class LerpColorScaleInterval(LerpInterval):
# Name counter
lerpColorScaleNum = 1
# Class methods
def __init__(self, node, duration, startColor, endColor,
other=None, blendType='noBlend', name=None):
def functorFunc(node=node, startColor=startColor, endColor=endColor, other=other):
assert(not node.isEmpty())
if callable(endColor):
# This may be a thunk that returns a point.
endColor = endColor()
if callable(startColor):
# This may be a thunk that returns a point.
startColor = startColor()
if (other != None):
functor = ColorScaleLerpFunctor(node, startColor, endColor, other)
else:
functor = ColorScaleLerpFunctor(node, startColor, endColor)
return functor
# Generate unique name if necessary
if (name == None):
name = 'LerpColorScaleInterval-%d' % LerpColorScaleInterval.lerpColorScaleNum
LerpColorScaleInterval.lerpColorScaleNum += 1
# Initialize superclass
LerpInterval.__init__(self, name, duration, functorFunc, blendType)
class LerpColorInterval(LerpInterval):
# Name counter
lerpColorNum = 1
# Class methods
def __init__(self, node, duration, startColor, endColor,
other=None, blendType='noBlend', name=None):
def functorFunc(node=node, startColor=startColor,
endColor=endColor, other=other):
assert(not node.isEmpty())
if callable(endColor):
# This may be a thunk that returns a point.
endColor = endColor()
if callable(startColor):
# This may be a thunk that returns a point.
startColor = startColor()
if (other != None):
functor = ColorLerpFunctor(node, startColor, endColor, other)
else:
functor = ColorLerpFunctor(node, startColor, endColor)
return functor
# Generate unique name if necessary
if (name == None):
name = 'LerpColorInterval-%d' % LerpColorInterval.lerpColorNum
LerpColorInterval.lerpColorNum += 1
# Initialize superclass
LerpInterval.__init__(self, name, duration, functorFunc, blendType)