mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-26 13:12:30 -06:00
367 lines
No EOL
17 KiB
Python
367 lines
No EOL
17 KiB
Python
"""
|
|
Defines AnimMgrBase
|
|
"""
|
|
|
|
import os, wx, math
|
|
|
|
from direct.interval.IntervalGlobal import *
|
|
from panda3d.core import VBase3,VBase4
|
|
import ObjectGlobals as OG
|
|
import AnimGlobals as AG
|
|
|
|
class AnimMgrBase:
|
|
""" AnimMgr will create, manage, update animations in the scene """
|
|
|
|
def __init__(self, editor):
|
|
self.editor = editor
|
|
self.graphEditorCounter = 0
|
|
|
|
self.keyFramesInfo = {}
|
|
self.curveAnimation = {}
|
|
|
|
#normal properties
|
|
self.lerpFuncs={
|
|
'H' : self.lerpFuncH,
|
|
'P' : self.lerpFuncP,
|
|
'R' : self.lerpFuncR,
|
|
'SX' : self.lerpFuncSX,
|
|
'SY' : self.lerpFuncSY,
|
|
'SZ' : self.lerpFuncSZ,
|
|
'CR' : self.lerpFuncCR,
|
|
'CG' : self.lerpFuncCG,
|
|
'CB' : self.lerpFuncCB,
|
|
'CA' : self.lerpFuncCA
|
|
}
|
|
|
|
#Properties which has animation curves
|
|
self.curveLerpFuncs={
|
|
'X' : [ self.lerpFuncX, self.lerpCurveFuncX ],
|
|
'Y' : [ self.lerpFuncY, self.lerpCurveFuncY ],
|
|
'Z' : [ self.lerpFuncZ, self.lerpCurveFuncZ ]
|
|
}
|
|
|
|
def reset(self):
|
|
self.keyFramesInfo = {}
|
|
self.curveAnimation = {}
|
|
|
|
def generateKeyFrames(self):
|
|
#generate keyFrame list
|
|
self.keyFrames = []
|
|
for property in self.keyFramesInfo.keys():
|
|
for frameInfo in self.keyFramesInfo[property]:
|
|
frame = frameInfo[AG.FRAME]
|
|
exist = False
|
|
for keyFrame in self.keyFrames:
|
|
if frame == keyFrame:
|
|
exist = True
|
|
break
|
|
if exist == False:
|
|
self.keyFrames.append(frame)
|
|
|
|
def generateSlope(self, list):
|
|
#generate handler slope of every keyframe for animation curve
|
|
listLen = len(list)
|
|
if listLen == 2:
|
|
slope =[float(list[1][AG.FRAME]-list[0][AG.FRAME]),(float(list[1][AG.VALUE])-float(list[0][AG.VALUE]))]
|
|
list[0][AG.INSLOPE] = slope
|
|
list[1][AG.INSLOPE] = slope
|
|
list[0][AG.OUTSLOPE] = list[0][AG.INSLOPE]
|
|
list[1][AG.OUTSLOPE] = list[1][AG.INSLOPE]
|
|
return
|
|
|
|
if listLen >= 3:
|
|
list[0][AG.INSLOPE] = [float(list[1][AG.FRAME] - list[0][AG.FRAME]),(float(list[1][AG.VALUE]) - float(list[0][AG.VALUE]))]
|
|
list[0][AG.OUTSLOPE] = list[0][AG.INSLOPE]
|
|
for i in range(1, listLen-1):
|
|
list[i][AG.INSLOPE] = [float(list[i+1][AG.FRAME] - list[i-1][AG.FRAME]),(float(list[i+1][AG.VALUE]) - float(list[i-1][AG.VALUE]))]
|
|
list[i][AG.OUTSLOPE] = list[i][AG.INSLOPE]
|
|
list[listLen-1][AG.INSLOPE] = [float(list[listLen-1][AG.FRAME] - list[listLen-2][AG.FRAME]),(float(list[listLen-1][AG.VALUE]) - float(list[listLen-2][AG.VALUE]))]
|
|
list[listLen-1][AG.OUTSLOPE] = list[listLen-1][AG.INSLOPE]
|
|
return
|
|
|
|
def removeAnimInfo(self, uid):
|
|
for property in self.keyFramesInfo.keys():
|
|
if property[AG.UID] == uid:
|
|
del self.keyFramesInfo[property]
|
|
self.generateKeyFrames()
|
|
if self.editor.mode == self.editor.ANIM_MODE:
|
|
self.editor.ui.animUI.OnPropKey()
|
|
|
|
def singleCurveAnimation(self, nodePath, curve, time):
|
|
rope = curve[OG.OBJ_NP]
|
|
self.points = rope.getPoints(time)
|
|
self.hprs = []
|
|
temp = render.attachNewNode("temp")
|
|
temp.setHpr(0,0,0)
|
|
for i in range(len(self.points)-1):
|
|
temp.setPos(self.points[i])
|
|
temp.lookAt(self.points[i+1])
|
|
hpr = temp.getHpr()
|
|
## self.hprs.append(hpr)
|
|
self.hprs.append(VBase3(hpr[0]+180,hpr[1],hpr[2]))
|
|
self.hprs.append(self.hprs[len(self.points)-2])
|
|
|
|
curveSequenceName = str(nodePath[OG.OBJ_UID])+' '+str(curve[OG.OBJ_UID])+' '+str(time)
|
|
self.curveSequence = Sequence(name = curveSequenceName)
|
|
|
|
for i in range(len(self.points)-1):
|
|
myLerp = LerpPosHprInterval(nodePath[OG.OBJ_NP], float(1)/float(24), self.points[i+1], self.hprs[i+1], self.points[i], self.hprs[i])
|
|
self.curveSequence.append(myLerp)
|
|
|
|
return self.curveSequence
|
|
|
|
def createParallel(self, startFrame, endFrame):
|
|
self.parallel = []
|
|
self.parallel = Parallel(name="Current Parallel")
|
|
|
|
self.createCurveAnimation(self.parallel)
|
|
self.createActorAnimation(self.parallel, startFrame, endFrame)
|
|
self.createKeyFrameAnimation(self.parallel, startFrame, endFrame)
|
|
self.createCurveKeyFrameAnimation(self.parallel, startFrame, endFrame)
|
|
|
|
return self.parallel
|
|
|
|
def createCurveAnimation(self, parallel):
|
|
for key in self.curveAnimation:
|
|
curveInfo = self.curveAnimation[key]
|
|
nodePath = self.editor.objectMgr.findObjectById(curveInfo[AG.NODE])
|
|
curve = self.editor.objectMgr.findObjectById(curveInfo[AG.CURVE])
|
|
time = curveInfo[AG.TIME]
|
|
sequence = self.singleCurveAnimation(nodePath, curve, time)
|
|
parallel.append(sequence)
|
|
|
|
def createActorAnimation(self, parallel, startFrame, endFrame):
|
|
self.editor.objectMgr.findActors(render)
|
|
for actor in self.editor.objectMgr.Actor:
|
|
actorAnim = os.path.basename(actor[OG.OBJ_ANIM])
|
|
myInterval = ActorInterval(actor[OG.OBJ_NP], actorAnim, loop=1, duration = float(endFrame-startFrame+1)/float(24))
|
|
parallel.append(myInterval)
|
|
|
|
def createKeyFrameAnimation(self, parallel, startFrame, endFrame):
|
|
#generate key frame animation for normal property
|
|
self.editor.objectMgr.findNodes(render)
|
|
for node in self.editor.objectMgr.Nodes:
|
|
for property in self.keyFramesInfo.keys():
|
|
if property[AG.UID] == node[OG.OBJ_UID] and property[AG.PROP_NAME] != 'X' and property[AG.PROP_NAME] != 'Y' and property[AG.PROP_NAME] != 'Z':
|
|
mysequence = Sequence(name = node[OG.OBJ_UID])
|
|
keyFramesInfo = self.keyFramesInfo[property]
|
|
if len(keyFramesInfo) == 1:
|
|
myLerp = LerpFunc(self.lerpFuncs[property[AG.PROP_NAME]],fromData=float(keyFramesInfo[0][AG.VALUE]),toData=float(keyFramesInfo[0][AG.VALUE]),duration = float(endFrame-startFrame)/float(24),blendType = 'noBlend',extraArgs = [node[OG.OBJ_NP]])
|
|
mysequence.append(myLerp)
|
|
parallel.append(mysequence)
|
|
|
|
if len(keyFramesInfo) != 1:
|
|
myLerp = LerpFunc(self.lerpFuncs[property[AG.PROP_NAME]],fromData=float(keyFramesInfo[0][AG.VALUE]),toData=float(keyFramesInfo[0][AG.VALUE]),duration = float(keyFramesInfo[0][AG.FRAME]-startFrame)/float(24),blendType = 'noBlend',extraArgs = [node[OG.OBJ_NP]])
|
|
mysequence.append(myLerp)
|
|
|
|
for key in range(0,len(keyFramesInfo)-1):
|
|
myLerp = LerpFunc(self.lerpFuncs[property[AG.PROP_NAME]],fromData=float(keyFramesInfo[key][AG.VALUE]),toData=float(keyFramesInfo[key+1][AG.VALUE]),duration = float(keyFramesInfo[key+1][AG.FRAME]-keyFramesInfo[key][AG.FRAME])/float(24),blendType = 'noBlend',extraArgs = [node[OG.OBJ_NP]])
|
|
mysequence.append(myLerp)
|
|
|
|
myLerp = LerpFunc(self.lerpFuncs[property[AG.PROP_NAME]],fromData=float(keyFramesInfo[len(keyFramesInfo)-1][AG.VALUE]),toData=float(keyFramesInfo[len(keyFramesInfo)-1][AG.VALUE]),duration = float(endFrame-keyFramesInfo[len(keyFramesInfo)-1][AG.FRAME])/float(24),blendType = 'noBlend',extraArgs = [node[OG.OBJ_NP]])
|
|
mysequence.append(myLerp)
|
|
parallel.append(mysequence)
|
|
|
|
def createCurveKeyFrameAnimation(self, parallel, startFrame, endFrame):
|
|
#generate key frame animation for the property which is controled by animation curve
|
|
self.editor.objectMgr.findNodes(render)
|
|
for node in self.editor.objectMgr.Nodes:
|
|
for property in self.keyFramesInfo.keys():
|
|
if property[AG.UID] == node[OG.OBJ_UID]:
|
|
if property[AG.PROP_NAME] == 'X' or property[AG.PROP_NAME] == 'Y' or property[AG.PROP_NAME] == 'Z':
|
|
mysequence = Sequence(name = node[OG.OBJ_UID])
|
|
keyFramesInfo = self.keyFramesInfo[property]
|
|
if len(keyFramesInfo) == 1:
|
|
myLerp = LerpFunc(self.curveLerpFuncs[property[AG.PROP_NAME]][0],fromData=float(keyFramesInfo[0][AG.VALUE]),toData=float(keyFramesInfo[0][AG.VALUE]),duration = float(endFrame-startFrame)/float(24),blendType = 'noBlend',extraArgs = [node[OG.OBJ_NP]])
|
|
mysequence.append(myLerp)
|
|
parallel.append(mysequence)
|
|
|
|
if len(keyFramesInfo) == 2:
|
|
myLerp = LerpFunc(self.curveLerpFuncs[property[AG.PROP_NAME]][0],fromData=float(keyFramesInfo[0][AG.VALUE]),toData=float(keyFramesInfo[0][AG.VALUE]),duration = float(keyFramesInfo[0][AG.FRAME]-startFrame)/float(24),blendType = 'noBlend',extraArgs = [node[OG.OBJ_NP]])
|
|
mysequence.append(myLerp)
|
|
|
|
for key in range(0,len(keyFramesInfo)-1):
|
|
self.keyFrameInfoForSingleLerp = keyFramesInfo
|
|
self.keyInfoForSingleLerp = key
|
|
myLerp = LerpFunc(self.curveLerpFuncs[property[AG.PROP_NAME]][0],fromData=float(keyFramesInfo[key][AG.VALUE]),toData=float(keyFramesInfo[key+1][AG.VALUE]),duration = float(keyFramesInfo[key+1][AG.FRAME]-keyFramesInfo[key][AG.FRAME])/float(24),blendType = 'noBlend',extraArgs = [node[OG.OBJ_NP]])
|
|
mysequence.append(myLerp)
|
|
|
|
myLerp = LerpFunc(self.curveLerpFuncs[property[AG.PROP_NAME]][0],fromData=float(keyFramesInfo[len(keyFramesInfo)-1][AG.VALUE]),toData=float(keyFramesInfo[len(keyFramesInfo)-1][AG.VALUE]),duration = float(endFrame-keyFramesInfo[len(keyFramesInfo)-1][AG.FRAME])/float(24),blendType = 'noBlend',extraArgs = [node[OG.OBJ_NP]])
|
|
mysequence.append(myLerp)
|
|
parallel.append(mysequence)
|
|
|
|
if len(keyFramesInfo) > 2:
|
|
myLerp = LerpFunc(self.curveLerpFuncs[property[AG.PROP_NAME]][0],fromData=float(keyFramesInfo[0][AG.VALUE]),toData=float(keyFramesInfo[0][1]),duration = float(keyFramesInfo[0][AG.FRAME]-startFrame)/float(24),blendType = 'noBlend',extraArgs = [node[OG.OBJ_NP]])
|
|
mysequence.append(myLerp)
|
|
|
|
for key in range(0,len(keyFramesInfo)-1):
|
|
myLerp = LerpFunc(self.curveLerpFuncs[property[AG.PROP_NAME]][1],fromData=float(keyFramesInfo[key][AG.FRAME]),toData=float(keyFramesInfo[key+1][AG.FRAME]),duration = float(keyFramesInfo[key+1][AG.FRAME]-keyFramesInfo[key][AG.FRAME])/float(24),blendType = 'noBlend',extraArgs = [[node[OG.OBJ_NP], keyFramesInfo, key]])
|
|
mysequence.append(myLerp)
|
|
|
|
myLerp = LerpFunc(self.curveLerpFuncs[property[AG.PROP_NAME]][0],fromData=float(keyFramesInfo[len(keyFramesInfo)-1][AG.VALUE]),toData=float(keyFramesInfo[len(keyFramesInfo)-1][AG.VALUE]),duration = float(endFrame-keyFramesInfo[len(keyFramesInfo)-1][AG.FRAME])/float(24),blendType = 'noBlend',extraArgs = [node[OG.OBJ_NP]])
|
|
mysequence.append(myLerp)
|
|
parallel.append(mysequence)
|
|
|
|
def getPos(self, x, list, i):
|
|
#get the value from animation curve
|
|
x1 = float(list[i][AG.FRAME])
|
|
y1 = float(list[i][AG.VALUE])
|
|
|
|
x4 = float(list[i+1][AG.FRAME])
|
|
y4 = float(list[i+1][AG.VALUE])
|
|
|
|
t1x = list[i][AG.OUTSLOPE][0]
|
|
t1y = list[i][AG.OUTSLOPE][1]
|
|
|
|
t2x = list[i+1][AG.INSLOPE][0]
|
|
t2y = list[i+1][AG.INSLOPE][1]
|
|
|
|
x2 = x1 + (x4 - x1) / float(3)
|
|
scale1 = (x2 - x1) / t1x
|
|
y2 = y1 + t1y * scale1
|
|
|
|
x3 = x4 - (x4 - x1) / float(3)
|
|
scale2 = (x4 - x3) / t2x
|
|
y3 = y4 - t2y * scale2
|
|
|
|
ax = - float(1) * x1 + float(3) * x2 - float(3) * x3 + float(1) * x4
|
|
bx = float(3) * x1 - float(6) * x2 + float(3) * x3 + float(0) * x4
|
|
cx = - float(3) * x1 + float(3) * x2 + float(0) * x3 + float(0) * x4
|
|
dx = float(1) * x1 + float(0) * x2 - float(0) * x3 + float(0) * x4
|
|
|
|
ay = - float(1) * y1 + float(3) * y2 - float(3) * y3 + float(1) * y4
|
|
by = float(3) * y1 - float(6) * y2 + float(3) * y3 + float(0) * y4
|
|
cy = - float(3) * y1 + float(3) * y2 + float(0) * y3 + float(0) * y4
|
|
dy = float(1) * y1 + float(0) * y2 - float(0) * y3 + float(0) * y4
|
|
|
|
if ax == 0 and bx == 0 and cx == 0:
|
|
return 0
|
|
|
|
if ax == 0 and bx == 0 and cx != 0:
|
|
a = cx
|
|
b = dx-x
|
|
t = -b/a
|
|
y = ay * t*t*t + by * t*t + cy * t + dy
|
|
return y
|
|
|
|
if ax == 0 and bx!= 0:
|
|
a=bx
|
|
b=cx
|
|
c=dx-x
|
|
t=(-b+math.sqrt(b**2-4.0*a*c))/2*a
|
|
if t>=0 and t<=1:
|
|
y = ay * t*t*t + by * t*t + cy * t + dy
|
|
return y
|
|
else:
|
|
t=(-b-math.sqrt(b**2-4.0*a*c))/2*a
|
|
y = ay * t*t*t + by * t*t + cy * t + dy
|
|
return y
|
|
|
|
if ax != 0:
|
|
a = ax
|
|
b = bx
|
|
c = cx
|
|
d = dx - float(x)
|
|
t = self.calculateT(a, b, c, d, x)
|
|
y = ay * t*t*t + by * t*t + cy * t + dy
|
|
return y
|
|
|
|
def calculateT(self, a, b, c, d, x):
|
|
#Newton EQUATION
|
|
t = float(1)
|
|
t2 = t
|
|
t -= (a*t*t*t+b*t*t+c*t+d)/(float(3)*a*t*t+float(2)*b*t+c)
|
|
if abs(t-t2) <= 0.000001:
|
|
return t
|
|
else:
|
|
while abs(t - t2) > 0.000001:
|
|
t2 = t
|
|
t -= (a*t*t*t+b*t*t+c*t+d)/(float(3)*a*t*t+float(2)*b*t+c)
|
|
return t
|
|
|
|
def lerpFuncX(self,pos,np):
|
|
np.setX(pos)
|
|
|
|
def lerpFuncY(self,pos,np):
|
|
np.setY(pos)
|
|
|
|
def lerpFuncZ(self,pos,np):
|
|
np.setZ(pos)
|
|
|
|
def lerpCurveFuncX(self,t,extraArgs):
|
|
np = extraArgs[0]
|
|
pos = self.getPos(t, extraArgs[1], extraArgs[2])
|
|
np.setX(pos)
|
|
|
|
def lerpCurveFuncY(self,t,extraArgs):
|
|
np = extraArgs[0]
|
|
pos = self.getPos(t, extraArgs[1], extraArgs[2])
|
|
np.setY(pos)
|
|
|
|
def lerpCurveFuncZ(self,t,extraArgs):
|
|
np = extraArgs[0]
|
|
pos = self.getPos(t, extraArgs[1], extraArgs[2])
|
|
np.setZ(pos)
|
|
|
|
def lerpFuncH(self,angle,np):
|
|
np.setH(angle)
|
|
|
|
def lerpFuncP(self,angle,np):
|
|
np.setP(angle)
|
|
|
|
def lerpFuncR(self,angle,np):
|
|
np.setR(angle)
|
|
|
|
def lerpFuncSX(self,scale,np):
|
|
np.setSx(scale)
|
|
|
|
def lerpFuncSY(self,scale,np):
|
|
np.setSy(scale)
|
|
|
|
def lerpFuncSZ(self,scale,np):
|
|
np.setSz(scale)
|
|
|
|
def lerpFuncCR(self,R,np):
|
|
obj = self.editor.objectMgr.findObjectByNodePath(np)
|
|
r = obj[OG.OBJ_RGBA][0]
|
|
g = obj[OG.OBJ_RGBA][1]
|
|
b = obj[OG.OBJ_RGBA][2]
|
|
a = obj[OG.OBJ_RGBA][3]
|
|
self.colorUpdate(R,g,b,a,np)
|
|
|
|
def lerpFuncCG(self,G,np):
|
|
obj = self.editor.objectMgr.findObjectByNodePath(np)
|
|
r = obj[OG.OBJ_RGBA][0]
|
|
g = obj[OG.OBJ_RGBA][1]
|
|
b = obj[OG.OBJ_RGBA][2]
|
|
a = obj[OG.OBJ_RGBA][3]
|
|
self.colorUpdate(r,G,b,a,np)
|
|
|
|
def lerpFuncCB(self,B,np):
|
|
obj = self.editor.objectMgr.findObjectByNodePath(np)
|
|
r = obj[OG.OBJ_RGBA][0]
|
|
g = obj[OG.OBJ_RGBA][1]
|
|
b = obj[OG.OBJ_RGBA][2]
|
|
a = obj[OG.OBJ_RGBA][3]
|
|
self.colorUpdate(r,g,B,a,np)
|
|
|
|
def lerpFuncCA(self,A,np):
|
|
obj = self.editor.objectMgr.findObjectByNodePath(np)
|
|
r = obj[OG.OBJ_RGBA][0]
|
|
g = obj[OG.OBJ_RGBA][1]
|
|
b = obj[OG.OBJ_RGBA][2]
|
|
a = obj[OG.OBJ_RGBA][3]
|
|
self.colorUpdate(r,g,b,A,np)
|
|
|
|
def colorUpdate(self, r, g, b, a, np):
|
|
if base.direct.selected.last == None:
|
|
self.editor.objectMgr.updateObjectColor(r, g, b, a, np)
|
|
elif self.editor.objectMgr.findObjectByNodePath(np) == self.editor.objectMgr.findObjectByNodePath(base.direct.selected.last):
|
|
self.editor.ui.objectPropertyUI.propCR.setValue(r)
|
|
self.editor.ui.objectPropertyUI.propCG.setValue(g)
|
|
self.editor.ui.objectPropertyUI.propCB.setValue(b)
|
|
self.editor.ui.objectPropertyUI.propCA.setValue(a)
|
|
self.editor.objectMgr.updateObjectColor(r, g, b, a, np)
|
|
else:
|
|
self.editor.objectMgr.updateObjectColor(r, g, b, a, np)
|
|
|