mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
425 lines
17 KiB
Python
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)
|
|
|