Browse Source

add LerpQuatInterval and related

David Rose 21 years ago
parent
commit
a3ddf62e00

+ 20 - 0
direct/src/extensions/NodePath-extensions.py

@@ -955,6 +955,10 @@
     def hprInterval(self, *args, **kw):
     def hprInterval(self, *args, **kw):
         from direct.interval import LerpInterval
         from direct.interval import LerpInterval
         return LerpInterval.LerpHprInterval(self, *args, **kw)
         return LerpInterval.LerpHprInterval(self, *args, **kw)
+    
+    def quatInterval(self, *args, **kw):
+        from direct.interval import LerpInterval
+        return LerpInterval.LerpQuatInterval(self, *args, **kw)
 
 
     def scaleInterval(self, *args, **kw):
     def scaleInterval(self, *args, **kw):
         from direct.interval import LerpInterval
         from direct.interval import LerpInterval
@@ -968,18 +972,34 @@
         from direct.interval import LerpInterval
         from direct.interval import LerpInterval
         return LerpInterval.LerpPosHprInterval(self, *args, **kw)
         return LerpInterval.LerpPosHprInterval(self, *args, **kw)
 
 
+    def posQuatInterval(self, *args, **kw):
+        from direct.interval import LerpInterval
+        return LerpInterval.LerpPosQuatInterval(self, *args, **kw)
+
     def hprScaleInterval(self, *args, **kw):
     def hprScaleInterval(self, *args, **kw):
         from direct.interval import LerpInterval
         from direct.interval import LerpInterval
         return LerpInterval.LerpHprScaleInterval(self, *args, **kw)
         return LerpInterval.LerpHprScaleInterval(self, *args, **kw)
 
 
+    def quatScaleInterval(self, *args, **kw):
+        from direct.interval import LerpInterval
+        return LerpInterval.LerpQuatScaleInterval(self, *args, **kw)
+
     def posHprScaleInterval(self, *args, **kw):
     def posHprScaleInterval(self, *args, **kw):
         from direct.interval import LerpInterval
         from direct.interval import LerpInterval
         return LerpInterval.LerpPosHprScaleInterval(self, *args, **kw)
         return LerpInterval.LerpPosHprScaleInterval(self, *args, **kw)
 
 
+    def posQuatScaleInterval(self, *args, **kw):
+        from direct.interval import LerpInterval
+        return LerpInterval.LerpPosQuatScaleInterval(self, *args, **kw)
+
     def posHprScaleShearInterval(self, *args, **kw):
     def posHprScaleShearInterval(self, *args, **kw):
         from direct.interval import LerpInterval
         from direct.interval import LerpInterval
         return LerpInterval.LerpPosHprScaleShearInterval(self, *args, **kw)
         return LerpInterval.LerpPosHprScaleShearInterval(self, *args, **kw)
 
 
+    def posQuatScaleShearInterval(self, *args, **kw):
+        from direct.interval import LerpInterval
+        return LerpInterval.LerpPosQuatScaleShearInterval(self, *args, **kw)
+
     def colorInterval(self, *args, **kw):
     def colorInterval(self, *args, **kw):
         from direct.interval import LerpInterval
         from direct.interval import LerpInterval
         return LerpInterval.LerpColorInterval(self, *args, **kw)
         return LerpInterval.LerpColorInterval(self, *args, **kw)

+ 242 - 10
direct/src/interval/LerpInterval.py

@@ -108,22 +108,26 @@ class LerpPosInterval(LerpNodePathInterval):
                 
                 
 
 
 class LerpHprInterval(LerpNodePathInterval):
 class LerpHprInterval(LerpNodePathInterval):
-    def __init__(self, nodePath, duration, hpr, startHpr = None,
+    def __init__(self, nodePath, duration, hpr,
+                 startHpr = None, startQuat = None,
                  other = None, blendType = 'noBlend',
                  other = None, blendType = 'noBlend',
                  bakeInStart = 1, fluid = 0, name = None):
                  bakeInStart = 1, fluid = 0, name = None):
         LerpNodePathInterval.__init__(self, name, duration, blendType,
         LerpNodePathInterval.__init__(self, name, duration, blendType,
                                       bakeInStart, fluid, nodePath, other)
                                       bakeInStart, fluid, nodePath, other)
 
 
         # Check for functors in the input parameters.
         # Check for functors in the input parameters.
-        self.paramSetup = self.anyCallable(hpr, startHpr)
+        self.paramSetup = self.anyCallable(hpr, startHpr, startQuat)
         if self.paramSetup:
         if self.paramSetup:
             self.endHpr = hpr
             self.endHpr = hpr
             self.startHpr = startHpr
             self.startHpr = startHpr
+            self.startQuat = startQuat
             self.inPython = 1
             self.inPython = 1
         else:
         else:
             self.setEndHpr(hpr)
             self.setEndHpr(hpr)
             if startHpr != None:
             if startHpr != None:
                 self.setStartHpr(startHpr)
                 self.setStartHpr(startHpr)
+            if startQuat != None:
+                self.setStartQuat(startQuat)
 
 
     def privDoEvent(self, t, event):
     def privDoEvent(self, t, event):
         # This function is only used if Python functors were passed in
         # This function is only used if Python functors were passed in
@@ -131,6 +135,38 @@ class LerpHprInterval(LerpNodePathInterval):
         if self.paramSetup and event == CInterval.ETInitialize:
         if self.paramSetup and event == CInterval.ETInitialize:
             self.setupParam(self.setEndHpr, self.endHpr)
             self.setupParam(self.setEndHpr, self.endHpr)
             self.setupParam(self.setStartHpr, self.startHpr)
             self.setupParam(self.setStartHpr, self.startHpr)
+            self.setupParam(self.setStartQuat, self.startQuat)
+        LerpNodePathInterval.privDoEvent(self, t, event)
+
+class LerpQuatInterval(LerpNodePathInterval):
+    def __init__(self, nodePath, duration, quat,
+                 startHpr = None, startQuat = None,
+                 other = None, blendType = 'noBlend',
+                 bakeInStart = 1, fluid = 0, name = None):
+        LerpNodePathInterval.__init__(self, name, duration, blendType,
+                                      bakeInStart, fluid, nodePath, other)
+
+        # Check for functors in the input parameters.
+        self.paramSetup = self.anyCallable(quat, startHpr, startQuat)
+        if self.paramSetup:
+            self.endQuat = quat
+            self.startHpr = startHpr
+            self.startQuat = startQuat
+            self.inPython = 1
+        else:
+            self.setEndQuat(quat)
+            if startHpr != None:
+                self.setStartHpr(startHpr)
+            if startQuat != None:
+                self.setStartQuat(startQuat)
+
+    def privDoEvent(self, t, event):
+        # This function is only used if Python functors were passed in
+        # for some of the input parameters.
+        if self.paramSetup and event == CInterval.ETInitialize:
+            self.setupParam(self.setEndQuat, self.endQuat)
+            self.setupParam(self.setStartHpr, self.startHpr)
+            self.setupParam(self.setStartQuat, self.startQuat)
         LerpNodePathInterval.privDoEvent(self, t, event)
         LerpNodePathInterval.privDoEvent(self, t, event)
 
 
 class LerpScaleInterval(LerpNodePathInterval):
 class LerpScaleInterval(LerpNodePathInterval):
@@ -185,18 +221,19 @@ class LerpShearInterval(LerpNodePathInterval):
 
 
 class LerpPosHprInterval(LerpNodePathInterval):
 class LerpPosHprInterval(LerpNodePathInterval):
     def __init__(self, nodePath, duration, pos, hpr,
     def __init__(self, nodePath, duration, pos, hpr,
-                 startPos = None, startHpr = None,
+                 startPos = None, startHpr = None, startQuat = None,
                  other = None, blendType = 'noBlend',
                  other = None, blendType = 'noBlend',
                  bakeInStart = 1, fluid = 0, name = None):
                  bakeInStart = 1, fluid = 0, name = None):
         LerpNodePathInterval.__init__(self, name, duration, blendType,
         LerpNodePathInterval.__init__(self, name, duration, blendType,
                                       bakeInStart, fluid, nodePath, other)
                                       bakeInStart, fluid, nodePath, other)
         # Check for functors in the input parameters.
         # Check for functors in the input parameters.
-        self.paramSetup = self.anyCallable(pos, startPos, hpr, startHpr)
+        self.paramSetup = self.anyCallable(pos, startPos, hpr, startHpr, startQuat)
         if self.paramSetup:
         if self.paramSetup:
             self.endPos = pos
             self.endPos = pos
             self.startPos = startPos
             self.startPos = startPos
             self.endHpr = hpr
             self.endHpr = hpr
             self.startHpr = startHpr
             self.startHpr = startHpr
+            self.startQuat = startQuat
             self.inPython = 1
             self.inPython = 1
         else:
         else:
             self.setEndPos(pos)
             self.setEndPos(pos)
@@ -205,6 +242,8 @@ class LerpPosHprInterval(LerpNodePathInterval):
             self.setEndHpr(hpr)
             self.setEndHpr(hpr)
             if startHpr != None:
             if startHpr != None:
                 self.setStartHpr(startHpr)
                 self.setStartHpr(startHpr)
+            if startQuat != None:
+                self.setStartQuat(startQuat)
 
 
     def privDoEvent(self, t, event):
     def privDoEvent(self, t, event):
         # This function is only used if Python functors were passed in
         # This function is only used if Python functors were passed in
@@ -214,21 +253,60 @@ class LerpPosHprInterval(LerpNodePathInterval):
             self.setupParam(self.setStartPos, self.startPos)
             self.setupParam(self.setStartPos, self.startPos)
             self.setupParam(self.setEndHpr, self.endHpr)
             self.setupParam(self.setEndHpr, self.endHpr)
             self.setupParam(self.setStartHpr, self.startHpr)
             self.setupParam(self.setStartHpr, self.startHpr)
+            self.setupParam(self.setStartQuat, self.startQuat)
+        LerpNodePathInterval.privDoEvent(self, t, event)
+
+class LerpPosQuatInterval(LerpNodePathInterval):
+    def __init__(self, nodePath, duration, pos, quat,
+                 startPos = None, startHpr = None, startQuat = None,
+                 other = None, blendType = 'noBlend',
+                 bakeInStart = 1, fluid = 0, name = None):
+        LerpNodePathInterval.__init__(self, name, duration, blendType,
+                                      bakeInStart, fluid, nodePath, other)
+        # Check for functors in the input parameters.
+        self.paramSetup = self.anyCallable(pos, startPos, quat, startHpr, startQuat)
+        if self.paramSetup:
+            self.endPos = pos
+            self.startPos = startPos
+            self.endQuat = quat
+            self.startHpr = startHpr
+            self.startQuat = startQuat
+            self.inPython = 1
+        else:
+            self.setEndPos(pos)
+            if startPos != None:
+                self.setStartPos(startPos)
+            self.setEndQuat(quat)
+            if startHpr != None:
+                self.setStartHpr(startHpr)
+            if startQuat != None:
+                self.setStartQuat(startQuat)
+
+    def privDoEvent(self, t, event):
+        # This function is only used if Python functors were passed in
+        # for some of the input parameters.
+        if self.paramSetup and event == CInterval.ETInitialize:
+            self.setupParam(self.setEndPos, self.endPos)
+            self.setupParam(self.setStartPos, self.startPos)
+            self.setupParam(self.setEndQuat, self.endQuat)
+            self.setupParam(self.setStartHpr, self.startHpr)
+            self.setupParam(self.setStartQuat, self.startQuat)
         LerpNodePathInterval.privDoEvent(self, t, event)
         LerpNodePathInterval.privDoEvent(self, t, event)
 
 
 class LerpHprScaleInterval(LerpNodePathInterval):
 class LerpHprScaleInterval(LerpNodePathInterval):
     def __init__(self, nodePath, duration, hpr, scale,
     def __init__(self, nodePath, duration, hpr, scale,
-                 startHpr = None, startScale = None,
+                 startHpr = None, startQuat = None, startScale = None,
                  other = None, blendType = 'noBlend',
                  other = None, blendType = 'noBlend',
                  bakeInStart = 1, fluid = 0, name = None):
                  bakeInStart = 1, fluid = 0, name = None):
         LerpNodePathInterval.__init__(self, name, duration, blendType,
         LerpNodePathInterval.__init__(self, name, duration, blendType,
                                       bakeInStart, fluid, nodePath, other)
                                       bakeInStart, fluid, nodePath, other)
 
 
         # Check for functors in the input parameters.
         # Check for functors in the input parameters.
-        self.paramSetup = self.anyCallable(hpr, startHpr, scale, startScale)
+        self.paramSetup = self.anyCallable(hpr, startHpr, startQuat, scale, startScale)
         if self.paramSetup:
         if self.paramSetup:
             self.endHpr = hpr
             self.endHpr = hpr
             self.startHpr = startHpr
             self.startHpr = startHpr
+            self.startQuat = startQuat
             self.endScale = scale
             self.endScale = scale
             self.startScale = startScale
             self.startScale = startScale
             self.inPython = 1
             self.inPython = 1
@@ -236,6 +314,8 @@ class LerpHprScaleInterval(LerpNodePathInterval):
             self.setEndHpr(hpr)
             self.setEndHpr(hpr)
             if startHpr != None:
             if startHpr != None:
                 self.setStartHpr(startHpr)
                 self.setStartHpr(startHpr)
+            if startQuat != None:
+                self.setStartQuat(startQuat)
             self.setEndScale(scale)
             self.setEndScale(scale)
             if startScale != None:
             if startScale != None:
                 self.setStartScale(startScale)
                 self.setStartScale(startScale)
@@ -246,24 +326,66 @@ class LerpHprScaleInterval(LerpNodePathInterval):
         if self.paramSetup and event == CInterval.ETInitialize:
         if self.paramSetup and event == CInterval.ETInitialize:
             self.setupParam(self.setEndHpr, self.endHpr)
             self.setupParam(self.setEndHpr, self.endHpr)
             self.setupParam(self.setStartHpr, self.startHpr)
             self.setupParam(self.setStartHpr, self.startHpr)
+            self.setupParam(self.setStartQuat, self.startQuat)
+            self.setupParam(self.setEndScale, self.endScale)
+            self.setupParam(self.setStartScale, self.startScale)
+        LerpNodePathInterval.privDoEvent(self, t, event)
+
+class LerpQuatScaleInterval(LerpNodePathInterval):
+    def __init__(self, nodePath, duration, quat, scale,
+                 startHpr = None, startQuat = None, startScale = None,
+                 other = None, blendType = 'noBlend',
+                 bakeInStart = 1, fluid = 0, name = None):
+        LerpNodePathInterval.__init__(self, name, duration, blendType,
+                                      bakeInStart, fluid, nodePath, other)
+
+        # Check for functors in the input parameters.
+        self.paramSetup = self.anyCallable(quat, startHpr, startQuat, scale, startScale)
+        if self.paramSetup:
+            self.endQuat = quat
+            self.startHpr = startHpr
+            self.startQuat = startQuat
+            self.endScale = scale
+            self.startScale = startScale
+            self.inPython = 1
+        else:
+            self.setEndQuat(quat)
+            if startHpr != None:
+                self.setStartHpr(startHpr)
+            if startQuat != None:
+                self.setStartQuat(startQuat)
+            self.setEndScale(scale)
+            if startScale != None:
+                self.setStartScale(startScale)
+
+    def privDoEvent(self, t, event):
+        # This function is only used if Python functors were passed in
+        # for some of the input parameters.
+        if self.paramSetup and event == CInterval.ETInitialize:
+            self.setupParam(self.setEndQuat, self.endQuat)
+            self.setupParam(self.setStartHpr, self.startHpr)
+            self.setupParam(self.setStartQuat, self.startQuat)
             self.setupParam(self.setEndScale, self.endScale)
             self.setupParam(self.setEndScale, self.endScale)
             self.setupParam(self.setStartScale, self.startScale)
             self.setupParam(self.setStartScale, self.startScale)
         LerpNodePathInterval.privDoEvent(self, t, event)
         LerpNodePathInterval.privDoEvent(self, t, event)
 
 
 class LerpPosHprScaleInterval(LerpNodePathInterval):
 class LerpPosHprScaleInterval(LerpNodePathInterval):
     def __init__(self, nodePath, duration, pos, hpr, scale,
     def __init__(self, nodePath, duration, pos, hpr, scale,
-                 startPos = None, startHpr = None, startScale = None,
+                 startPos = None, startHpr = None, startQuat = None,
+                 startScale = None,
                  other = None, blendType = 'noBlend',
                  other = None, blendType = 'noBlend',
                  bakeInStart = 1, fluid = 0, name = None):
                  bakeInStart = 1, fluid = 0, name = None):
         LerpNodePathInterval.__init__(self, name, duration, blendType,
         LerpNodePathInterval.__init__(self, name, duration, blendType,
                                       bakeInStart, fluid, nodePath, other)
                                       bakeInStart, fluid, nodePath, other)
         # Check for functors in the input parameters.
         # Check for functors in the input parameters.
-        self.paramSetup = self.anyCallable(pos, startPos, hpr, startHpr, scale, startScale)
+        self.paramSetup = self.anyCallable(pos, startPos, hpr, startHpr,
+                                           startQuat, scale, startScale)
         if self.paramSetup:
         if self.paramSetup:
             self.endPos = pos
             self.endPos = pos
             self.startPos = startPos
             self.startPos = startPos
             self.endHpr = hpr
             self.endHpr = hpr
             self.startHpr = startHpr
             self.startHpr = startHpr
+            self.startQuat = startQuat
             self.endScale = scale
             self.endScale = scale
             self.startScale = startScale
             self.startScale = startScale
             self.inPython = 1
             self.inPython = 1
@@ -274,6 +396,8 @@ class LerpPosHprScaleInterval(LerpNodePathInterval):
             self.setEndHpr(hpr)
             self.setEndHpr(hpr)
             if startHpr != None:
             if startHpr != None:
                 self.setStartHpr(startHpr)
                 self.setStartHpr(startHpr)
+            if startQuat != None:
+                self.setStartQuat(startQuat)
             self.setEndScale(scale)
             self.setEndScale(scale)
             if startScale != None:
             if startScale != None:
                 self.setStartScale(startScale)
                 self.setStartScale(startScale)
@@ -286,24 +410,75 @@ class LerpPosHprScaleInterval(LerpNodePathInterval):
             self.setupParam(self.setStartPos, self.startPos)
             self.setupParam(self.setStartPos, self.startPos)
             self.setupParam(self.setEndHpr, self.endHpr)
             self.setupParam(self.setEndHpr, self.endHpr)
             self.setupParam(self.setStartHpr, self.startHpr)
             self.setupParam(self.setStartHpr, self.startHpr)
+            self.setupParam(self.setStartQuat, self.startQuat)
+            self.setupParam(self.setEndScale, self.endScale)
+            self.setupParam(self.setStartScale, self.startScale)
+        LerpNodePathInterval.privDoEvent(self, t, event)
+
+class LerpPosQuatScaleInterval(LerpNodePathInterval):
+    def __init__(self, nodePath, duration, pos, quat, scale,
+                 startPos = None, startHpr = None, startQuat = None,
+                 startScale = None,
+                 other = None, blendType = 'noBlend',
+                 bakeInStart = 1, fluid = 0, name = None):
+        LerpNodePathInterval.__init__(self, name, duration, blendType,
+                                      bakeInStart, fluid, nodePath, other)
+        # Check for functors in the input parameters.
+        self.paramSetup = self.anyCallable(pos, startPos, quat, startHpr,
+                                           startQuat, scale, startScale)
+        if self.paramSetup:
+            self.endPos = pos
+            self.startPos = startPos
+            self.endQuat = quat
+            self.startHpr = startHpr
+            self.startQuat = startQuat
+            self.endScale = scale
+            self.startScale = startScale
+            self.inPython = 1
+        else:
+            self.setEndPos(pos)
+            if startPos != None:
+                self.setStartPos(startPos)
+            self.setEndQuat(quat)
+            if startHpr != None:
+                self.setStartHpr(startHpr)
+            if startQuat != None:
+                self.setStartQuat(startQuat)
+            self.setEndScale(scale)
+            if startScale != None:
+                self.setStartScale(startScale)
+
+    def privDoEvent(self, t, event):
+        # This function is only used if Python functors were passed in
+        # for some of the input parameters.
+        if self.paramSetup and event == CInterval.ETInitialize:
+            self.setupParam(self.setEndPos, self.endPos)
+            self.setupParam(self.setStartPos, self.startPos)
+            self.setupParam(self.setEndQuat, self.endQuat)
+            self.setupParam(self.setStartHpr, self.startHpr)
+            self.setupParam(self.setStartQuat, self.startQuat)
             self.setupParam(self.setEndScale, self.endScale)
             self.setupParam(self.setEndScale, self.endScale)
             self.setupParam(self.setStartScale, self.startScale)
             self.setupParam(self.setStartScale, self.startScale)
         LerpNodePathInterval.privDoEvent(self, t, event)
         LerpNodePathInterval.privDoEvent(self, t, event)
 
 
 class LerpPosHprScaleShearInterval(LerpNodePathInterval):
 class LerpPosHprScaleShearInterval(LerpNodePathInterval):
     def __init__(self, nodePath, duration, pos, hpr, scale, shear,
     def __init__(self, nodePath, duration, pos, hpr, scale, shear,
-                 startPos = None, startHpr = None, startScale = None, startShear = None,
+                 startPos = None, startHpr = None, startQuat = None,
+                 startScale = None, startShear = None,
                  other = None, blendType = 'noBlend',
                  other = None, blendType = 'noBlend',
                  bakeInStart = 1, fluid = 0, name = None):
                  bakeInStart = 1, fluid = 0, name = None):
         LerpNodePathInterval.__init__(self, name, duration, blendType,
         LerpNodePathInterval.__init__(self, name, duration, blendType,
                                       bakeInStart, fluid, nodePath, other)
                                       bakeInStart, fluid, nodePath, other)
         # Check for functors in the input parameters.
         # Check for functors in the input parameters.
-        self.paramSetup = self.anyCallable(pos, startPos, hpr, startHpr, scale, startScale, shear, startShear)
+        self.paramSetup = self.anyCallable(pos, startPos, hpr, startHpr,
+                                           startQuat, scale, startScale,
+                                           shear, startShear)
         if self.paramSetup:
         if self.paramSetup:
             self.endPos = pos
             self.endPos = pos
             self.startPos = startPos
             self.startPos = startPos
             self.endHpr = hpr
             self.endHpr = hpr
             self.startHpr = startHpr
             self.startHpr = startHpr
+            self.startQuat = startQuat
             self.endScale = scale
             self.endScale = scale
             self.startScale = startScale
             self.startScale = startScale
             self.endShear = shear
             self.endShear = shear
@@ -316,6 +491,8 @@ class LerpPosHprScaleShearInterval(LerpNodePathInterval):
             self.setEndHpr(hpr)
             self.setEndHpr(hpr)
             if startHpr != None:
             if startHpr != None:
                 self.setStartHpr(startHpr)
                 self.setStartHpr(startHpr)
+            if startQuat != None:
+                self.setStartQuat(startQuat)
             self.setEndScale(scale)
             self.setEndScale(scale)
             if startScale != None:
             if startScale != None:
                 self.setStartScale(startScale)
                 self.setStartScale(startScale)
@@ -331,6 +508,61 @@ class LerpPosHprScaleShearInterval(LerpNodePathInterval):
             self.setupParam(self.setStartPos, self.startPos)
             self.setupParam(self.setStartPos, self.startPos)
             self.setupParam(self.setEndHpr, self.endHpr)
             self.setupParam(self.setEndHpr, self.endHpr)
             self.setupParam(self.setStartHpr, self.startHpr)
             self.setupParam(self.setStartHpr, self.startHpr)
+            self.setupParam(self.setStartQuat, self.startQuat)
+            self.setupParam(self.setEndScale, self.endScale)
+            self.setupParam(self.setStartScale, self.startScale)
+            self.setupParam(self.setEndShear, self.endShear)
+            self.setupParam(self.setStartShear, self.startShear)
+        LerpNodePathInterval.privDoEvent(self, t, event)
+
+class LerpPosQuatScaleShearInterval(LerpNodePathInterval):
+    def __init__(self, nodePath, duration, pos, quat, scale, shear,
+                 startPos = None, startHpr = None, startQuat = None,
+                 startScale = None, startShear = None,
+                 other = None, blendType = 'noBlend',
+                 bakeInStart = 1, fluid = 0, name = None):
+        LerpNodePathInterval.__init__(self, name, duration, blendType,
+                                      bakeInStart, fluid, nodePath, other)
+        # Check for functors in the input parameters.
+        self.paramSetup = self.anyCallable(pos, startPos, quat, startHpr,
+                                           startQuat, scale, startScale,
+                                           shear, startShear)
+        if self.paramSetup:
+            self.endPos = pos
+            self.startPos = startPos
+            self.endQuat = quat
+            self.startHpr = startHpr
+            self.startQuat = startQuat
+            self.endScale = scale
+            self.startScale = startScale
+            self.endShear = shear
+            self.startShear = startShear
+            self.inPython = 1
+        else:
+            self.setEndPos(pos)
+            if startPos != None:
+                self.setStartPos(startPos)
+            self.setEndQuat(quat)
+            if startHpr != None:
+                self.setStartHpr(startHpr)
+            if startQuat != None:
+                self.setStartQuat(startQuat)
+            self.setEndScale(scale)
+            if startScale != None:
+                self.setStartScale(startScale)
+            self.setEndShear(shear)
+            if startShear != None:
+                self.setStartShear(startShear)
+
+    def privDoEvent(self, t, event):
+        # This function is only used if Python functors were passed in
+        # for some of the input parameters.
+        if self.paramSetup and event == CInterval.ETInitialize:
+            self.setupParam(self.setEndPos, self.endPos)
+            self.setupParam(self.setStartPos, self.startPos)
+            self.setupParam(self.setEndQuat, self.endQuat)
+            self.setupParam(self.setStartHpr, self.startHpr)
+            self.setupParam(self.setStartQuat, self.startQuat)
             self.setupParam(self.setEndScale, self.endScale)
             self.setupParam(self.setEndScale, self.endScale)
             self.setupParam(self.setStartScale, self.startScale)
             self.setupParam(self.setStartScale, self.startScale)
             self.setupParam(self.setEndShear, self.endShear)
             self.setupParam(self.setEndShear, self.endShear)

+ 86 - 8
direct/src/interval/cLerpNodePathInterval.I

@@ -74,10 +74,11 @@ set_end_pos(const LVecBase3f &pos) {
 //     Function: CLerpNodePathInterval::set_start_hpr
 //     Function: CLerpNodePathInterval::set_start_hpr
 //       Access: Published
 //       Access: Published
 //  Description: Indicates the initial rotation of the lerped node.
 //  Description: Indicates the initial rotation of the lerped node.
-//               This is meaningful only if set_end_hpr() is also
-//               called.  This parameter is optional; if unspecified,
-//               the value will be taken from the node's actual
-//               rotation at the time the lerp is performed.
+//               This is meaningful only if either set_end_hpr() or
+//               set_end_quat() is also called.  This parameter is
+//               optional; if unspecified, the value will be taken
+//               from the node's actual rotation at the time the lerp
+//               is performed.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void CLerpNodePathInterval::
 INLINE void CLerpNodePathInterval::
 set_start_hpr(const LVecBase3f &hpr) {
 set_start_hpr(const LVecBase3f &hpr) {
@@ -90,14 +91,91 @@ set_start_hpr(const LVecBase3f &hpr) {
 //       Access: Published
 //       Access: Published
 //  Description: Indicates that the rotation of the node should be
 //  Description: Indicates that the rotation of the node should be
 //               lerped, and specifies the final rotation of the node.
 //               lerped, and specifies the final rotation of the node.
-//               This should be called before priv_initialize().  If this
-//               is not called, the node's rotation will not be
-//               affected by the lerp.
+//               This should be called before priv_initialize().
+//
+//               This replaces a previous call to set_end_quat().  If
+//               neither set_end_hpr() nor set_end_quat() is called,
+//               the node's rotation will not be affected by the lerp.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void CLerpNodePathInterval::
 INLINE void CLerpNodePathInterval::
 set_end_hpr(const LVecBase3f &hpr) {
 set_end_hpr(const LVecBase3f &hpr) {
   _end_hpr = hpr;
   _end_hpr = hpr;
-  _flags |= F_end_hpr;
+  _flags = (_flags & ~F_end_quat) | F_end_hpr;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLerpNodePathInterval::set_end_hpr
+//       Access: Published
+//  Description: Indicates that the rotation of the node should be
+//               lerped, and specifies the final rotation of the node.
+//               This should be called before priv_initialize().
+//
+//               This special function is overloaded to accept a
+//               quaternion, even though the function name is
+//               set_end_hpr().  The quaternion will be implicitly
+//               converted to a HPR trio, and the lerp will be
+//               performed in HPR space, componentwise.
+////////////////////////////////////////////////////////////////////
+INLINE void CLerpNodePathInterval::
+set_end_hpr(const LQuaternionf &quat) {
+  _end_hpr = quat.get_hpr();
+  _flags = (_flags & ~F_end_quat) | F_end_hpr;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLerpNodePathInterval::set_start_quat
+//       Access: Published
+//  Description: Indicates the initial rotation of the lerped node.
+//               This is meaningful only if either set_end_quat() or
+//               set_end_hpr() is also called.  This parameter is
+//               optional; if unspecified, the value will be taken
+//               from the node's actual rotation at the time the lerp
+//               is performed.
+////////////////////////////////////////////////////////////////////
+INLINE void CLerpNodePathInterval::
+set_start_quat(const LQuaternionf &quat) {
+  _start_quat = quat;
+  _flags |= F_start_quat;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLerpNodePathInterval::set_end_quat
+//       Access: Published
+//  Description: Indicates that the rotation of the node should be
+//               lerped, and specifies the final rotation of the node.
+//               This should be called before priv_initialize().
+//
+//               This replaces a previous call to set_end_hpr().  If
+//               neither set_end_quat() nor set_end_hpr() is called,
+//               the node's rotation will not be affected by the lerp.
+//
+//               This special function is overloaded to accept a HPR
+//               trio, even though the function name is
+//               set_end_quat().  The HPR will be implicitly converted
+//               to a quaternion, and the lerp will be performed in
+//               quaternion space, as a spherical lerp.
+////////////////////////////////////////////////////////////////////
+INLINE void CLerpNodePathInterval::
+set_end_quat(const LVecBase3f &hpr) {
+  _end_quat.set_hpr(hpr);
+  _flags = (_flags & ~F_end_hpr) | F_end_quat;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLerpNodePathInterval::set_end_quat
+//       Access: Published
+//  Description: Indicates that the rotation of the node should be
+//               lerped, and specifies the final rotation of the node.
+//               This should be called before priv_initialize().
+//
+//               This replaces a previous call to set_end_hpr().  If
+//               neither set_end_quat() nor set_end_hpr() is called,
+//               the node's rotation will not be affected by the lerp.
+////////////////////////////////////////////////////////////////////
+INLINE void CLerpNodePathInterval::
+set_end_quat(const LQuaternionf &quat) {
+  _end_quat = quat;
+  _flags = (_flags & ~F_end_hpr) | F_end_quat;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 81 - 8
direct/src/interval/cLerpNodePathInterval.cxx

@@ -128,7 +128,7 @@ priv_step(double t) {
   // Save this in case we want to restore it later.
   // Save this in case we want to restore it later.
   CPT(TransformState) prev_transform = _node.get_prev_transform();
   CPT(TransformState) prev_transform = _node.get_prev_transform();
 
 
-  if ((_flags & (F_end_pos | F_end_hpr | F_end_scale | F_end_shear)) != 0) {
+  if ((_flags & (F_end_pos | F_end_hpr | F_end_quat | F_end_scale | F_end_shear)) != 0) {
     // We have some transform lerp.
     // We have some transform lerp.
     CPT(TransformState) transform;
     CPT(TransformState) transform;
 
 
@@ -143,6 +143,7 @@ priv_step(double t) {
     
     
     LPoint3f pos;
     LPoint3f pos;
     LVecBase3f hpr;
     LVecBase3f hpr;
+    LQuaternionf quat;
     LVecBase3f scale;
     LVecBase3f scale;
     LVecBase3f shear;
     LVecBase3f shear;
 
 
@@ -165,6 +166,11 @@ priv_step(double t) {
       if ((_flags & F_start_hpr) != 0) {
       if ((_flags & F_start_hpr) != 0) {
         lerp_value(hpr, d, _start_hpr, _end_hpr);
         lerp_value(hpr, d, _start_hpr, _end_hpr);
 
 
+      } else if ((_flags & F_start_quat) != 0) {
+        _start_hpr = _start_quat.get_hpr();
+        _flags |= F_start_hpr;
+        lerp_value(hpr, d, _start_hpr, _end_hpr);
+
       } else if ((_flags & F_bake_in_start) != 0) {
       } else if ((_flags & F_bake_in_start) != 0) {
         set_start_hpr(transform->get_hpr());
         set_start_hpr(transform->get_hpr());
         lerp_value(hpr, d, _start_hpr, _end_hpr);
         lerp_value(hpr, d, _start_hpr, _end_hpr);
@@ -174,6 +180,25 @@ priv_step(double t) {
         lerp_value_from_prev(hpr, d, _prev_d, hpr, _end_hpr);
         lerp_value_from_prev(hpr, d, _prev_d, hpr, _end_hpr);
       }
       }
     }
     }
+    if ((_flags & F_end_quat) != 0) {
+      if ((_flags & F_start_quat) != 0) {
+        lerp_value(quat, d, _start_quat, _end_quat);
+
+      } else if ((_flags & F_start_hpr) != 0) {
+        _start_quat.set_hpr(_start_hpr);
+        _flags |= F_start_quat;
+        lerp_value(quat, d, _start_quat, _end_quat);
+
+      } else if ((_flags & F_bake_in_start) != 0) {
+        set_start_quat(transform->get_quat());
+        lerp_value(quat, d, _start_quat, _end_quat);
+
+      } else {
+        quat = transform->get_quat();
+        lerp_value_from_prev(quat, d, _prev_d, quat, _end_quat);
+      }
+      quat.normalize();
+    }
     if ((_flags & F_end_scale) != 0) {
     if ((_flags & F_end_scale) != 0) {
       if ((_flags & F_start_scale) != 0) {
       if ((_flags & F_start_scale) != 0) {
         lerp_value(scale, d, _start_scale, _end_scale);
         lerp_value(scale, d, _start_scale, _end_scale);
@@ -206,7 +231,8 @@ priv_step(double t) {
     // transform has hpr/scale components if they're not needed.  And
     // transform has hpr/scale components if they're not needed.  And
     // in any case, we only want to apply the components that we
     // in any case, we only want to apply the components that we
     // computed, above.
     // computed, above.
-    switch (_flags & (F_end_pos | F_end_hpr | F_end_scale)) {
+    unsigned int transform_flags = _flags & (F_end_pos | F_end_hpr | F_end_quat | F_end_scale);
+    switch (transform_flags) {
     case 0:
     case 0:
       break;
       break;
 
 
@@ -226,6 +252,14 @@ priv_step(double t) {
       }
       }
       break;
       break;
 
 
+    case F_end_quat:
+      if (_other.is_empty()) {
+        _node.set_quat(quat);
+      } else {
+        _node.set_quat(_other, quat);
+      }
+      break;
+
     case F_end_scale:
     case F_end_scale:
       if (_other.is_empty()) {
       if (_other.is_empty()) {
         _node.set_scale(scale);
         _node.set_scale(scale);
@@ -242,6 +276,14 @@ priv_step(double t) {
       }
       }
       break;
       break;
 
 
+    case F_end_quat | F_end_scale:
+      if (_other.is_empty()) {
+        _node.set_quat_scale(quat, scale);
+      } else {
+        _node.set_quat_scale(quat, scale);
+      }
+      break;
+
     case F_end_pos | F_end_hpr:
     case F_end_pos | F_end_hpr:
       if (_other.is_empty()) {
       if (_other.is_empty()) {
         _node.set_pos_hpr(pos, hpr);
         _node.set_pos_hpr(pos, hpr);
@@ -250,6 +292,14 @@ priv_step(double t) {
       }
       }
       break;
       break;
 
 
+    case F_end_pos | F_end_quat:
+      if (_other.is_empty()) {
+        _node.set_pos_quat(pos, quat);
+      } else {
+        _node.set_pos_quat(_other, pos, quat);
+      }
+      break;
+
     case F_end_pos | F_end_scale:
     case F_end_pos | F_end_scale:
       if (transform->quat_given()) {
       if (transform->quat_given()) {
         if (_other.is_empty()) {
         if (_other.is_empty()) {
@@ -284,16 +334,33 @@ priv_step(double t) {
       }
       }
       break;
       break;
 
 
+    case F_end_pos | F_end_quat | F_end_scale:
+      if ((_flags & F_end_shear) != 0) {
+        // Even better: we have all four components.
+        if (_other.is_empty()) {
+          _node.set_pos_quat_scale_shear(pos, quat, scale, shear);
+        } else {
+          _node.set_pos_quat_scale_shear(_other, pos, quat, scale, shear);
+        }
+      } else {
+        // We have only the primary three components.
+        if (_other.is_empty()) {
+          _node.set_pos_quat_scale(pos, quat, scale);
+        } else {
+          _node.set_pos_quat_scale(_other, pos, quat, scale);
+        }
+      }
+      break;
+
     default:
     default:
       // Some unhandled combination.  We should handle this.
       // Some unhandled combination.  We should handle this.
       interval_cat.error()
       interval_cat.error()
         << "Internal error in CLerpNodePathInterval::priv_step().\n";
         << "Internal error in CLerpNodePathInterval::priv_step().\n";
     }
     }
-
     if ((_flags & F_end_shear) != 0) {
     if ((_flags & F_end_shear) != 0) {
       // Also apply changes to shear.
       // Also apply changes to shear.
-      if ((_flags & (F_end_pos | F_end_hpr | F_end_scale)) == 
-          (F_end_pos | F_end_hpr | F_end_scale)) {
+      if (transform_flags == (F_end_pos | F_end_hpr | F_end_scale) ||
+          transform_flags == (F_end_pos | F_end_quat | F_end_scale)) {
         // Actually, we already handled this case above.
         // Actually, we already handled this case above.
 
 
       } else {
       } else {
@@ -384,9 +451,7 @@ priv_step(double t) {
     } else {
     } else {
       _node.set_state(_other, state);
       _node.set_state(_other, state);
     }
     }
-  }
-
-  _prev_d = d;
+  }  _prev_d = d;
   _curr_t = t;
   _curr_t = t;
 }
 }
 
 
@@ -451,6 +516,14 @@ output(ostream &out) const {
     out << " to " << _end_hpr;
     out << " to " << _end_hpr;
   }
   }
 
 
+  if ((_flags & F_end_quat) != 0) {
+    out << " quat";
+    if ((_flags & F_start_quat) != 0) {
+      out << " from " << _start_quat;
+    }
+    out << " to " << _end_quat;
+  }
+
   if ((_flags & F_end_scale) != 0) {
   if ((_flags & F_end_scale) != 0) {
     out << " scale";
     out << " scale";
     if ((_flags & F_start_scale) != 0) {
     if ((_flags & F_start_scale) != 0) {

+ 14 - 7
direct/src/interval/cLerpNodePathInterval.h

@@ -42,6 +42,10 @@ PUBLISHED:
   INLINE void set_end_pos(const LVecBase3f &pos);
   INLINE void set_end_pos(const LVecBase3f &pos);
   INLINE void set_start_hpr(const LVecBase3f &hpr);
   INLINE void set_start_hpr(const LVecBase3f &hpr);
   INLINE void set_end_hpr(const LVecBase3f &hpr);
   INLINE void set_end_hpr(const LVecBase3f &hpr);
+  INLINE void set_end_hpr(const LQuaternionf &quat);
+  INLINE void set_start_quat(const LQuaternionf &quat);
+  INLINE void set_end_quat(const LVecBase3f &hpr);
+  INLINE void set_end_quat(const LQuaternionf &quat);
   INLINE void set_start_scale(const LVecBase3f &scale);
   INLINE void set_start_scale(const LVecBase3f &scale);
   INLINE void set_start_scale(float scale);
   INLINE void set_start_scale(float scale);
   INLINE void set_end_scale(const LVecBase3f &scale);
   INLINE void set_end_scale(const LVecBase3f &scale);
@@ -68,13 +72,15 @@ private:
   enum Flags {
   enum Flags {
     F_end_pos            = 0x0001,
     F_end_pos            = 0x0001,
     F_end_hpr            = 0x0002,
     F_end_hpr            = 0x0002,
-    F_end_scale          = 0x0004,
-    F_end_color          = 0x0008,
-    F_end_color_scale    = 0x0010,
-    F_end_shear          = 0x0020,
-
-    F_start_pos          = 0x0100,
-    F_start_hpr          = 0x0200,
+    F_end_quat           = 0x0004,
+    F_end_scale          = 0x0008,
+    F_end_color          = 0x0010,
+    F_end_color_scale    = 0x0020,
+    F_end_shear          = 0x0040,
+
+    F_start_pos          = 0x0080,
+    F_start_hpr          = 0x0100,
+    F_start_quat         = 0x0200,
     F_start_scale        = 0x0400,
     F_start_scale        = 0x0400,
     F_start_color        = 0x0800,
     F_start_color        = 0x0800,
     F_start_color_scale  = 0x1000,
     F_start_color_scale  = 0x1000,
@@ -87,6 +93,7 @@ private:
   unsigned int _flags;
   unsigned int _flags;
   LPoint3f _start_pos, _end_pos;
   LPoint3f _start_pos, _end_pos;
   LVecBase3f _start_hpr, _end_hpr;
   LVecBase3f _start_hpr, _end_hpr;
+  LQuaternionf _start_quat, _end_quat;
   LVecBase3f _start_scale, _end_scale;
   LVecBase3f _start_scale, _end_scale;
   LVecBase3f _start_shear, _end_shear;
   LVecBase3f _start_shear, _end_shear;
   Colorf _start_color, _end_color;
   Colorf _start_color, _end_color;