Browse Source

pgraph lerps

David Rose 24 years ago
parent
commit
3c61d80b69

+ 24 - 8
direct/src/ffi/FFIRename.py

@@ -110,27 +110,35 @@ pgraphClassRenameDictionary = {
     'CollisionHandlerQueue'     : 'SpCollisionHandlerQueue',
     'CollisionHandlerQueue'     : 'SpCollisionHandlerQueue',
     'CollisionNode'             : 'SpCollisionNode',
     'CollisionNode'             : 'SpCollisionNode',
     'CollisionTraverser'        : 'SpCollisionTraverser',
     'CollisionTraverser'        : 'SpCollisionTraverser',
+    'ColorLerpFunctor'          : 'SpColorLerpFunctor',
+    'ColorScaleLerpFunctor'     : 'SpColorScaleLerpFunctor',
     'DataGraphTraverser'        : 'SpDataGraphTraverser',
     'DataGraphTraverser'        : 'SpDataGraphTraverser',
     'DataNode'                  : 'SpDataNode',
     'DataNode'                  : 'SpDataNode',
     'DialNode'                  : 'SpDialNode',
     'DialNode'                  : 'SpDialNode',
     'DriveInterface'            : 'SpDriveInterface',
     'DriveInterface'            : 'SpDriveInterface',
     'GeomNode'                  : 'SpGeomNode',
     'GeomNode'                  : 'SpGeomNode',
+    'HprLerpFunctor'            : 'SpHprLerpFunctor',
+    'HprScaleLerpFunctor'       : 'SpHprScaleLerpFunctor',
     'LODNode'                   : 'SpLODNode',
     'LODNode'                   : 'SpLODNode',
-    'LineSegs'                  : 'SpLineSegs',
     'LensNode'                  : 'SpLensNode',
     'LensNode'                  : 'SpLensNode',
+    'LineSegs'                  : 'SpLineSegs',
     'ModelNode'                 : 'SpModelNode',
     'ModelNode'                 : 'SpModelNode',
-    'ModelRoot'                 : 'SpModelRoot',
     'ModelPool'                 : 'SpModelPool',
     'ModelPool'                 : 'SpModelPool',
+    'ModelRoot'                 : 'SpModelRoot',
     'MouseAndKeyboard'          : 'SpMouseAndKeyboard',
     'MouseAndKeyboard'          : 'SpMouseAndKeyboard',
     'MouseWatcher'              : 'SpMouseWatcher',
     'MouseWatcher'              : 'SpMouseWatcher',
     'NodePath'                  : 'SpNodePath',
     'NodePath'                  : 'SpNodePath',
     'NodePathCollection'        : 'SpNodePathCollection',
     'NodePathCollection'        : 'SpNodePathCollection',
-    'PGTop'                     : 'SpPGTop',
-    'PGItem'                    : 'SpPGItem',
     'PGButton'                  : 'SpPGButton',
     'PGButton'                  : 'SpPGButton',
     'PGEntry'                   : 'SpPGEntry',
     'PGEntry'                   : 'SpPGEntry',
+    'PGItem'                    : 'SpPGItem',
+    'PGTop'                     : 'SpPGTop',
     'PGWaitBar'                 : 'SpPGWaitBar',
     'PGWaitBar'                 : 'SpPGWaitBar',
     'PartBundleNode'            : 'SpPartBundleNode',
     'PartBundleNode'            : 'SpPartBundleNode',
+    'PosHprLerpFunctor'         : 'SpPosHprLerpFunctor',
+    'PosHprScaleLerpFunctor'    : 'SpPosHprScaleLerpFunctor',
+    'PosLerpFunctor'            : 'SpPosLerpFunctor',
+    'ScaleLerpFunctor'          : 'SpScaleLerpFunctor',
     'SceneGraphReducer'         : 'SpSceneGraphReducer',
     'SceneGraphReducer'         : 'SpSceneGraphReducer',
     'SequenceNode'              : 'SpSequenceNode',
     'SequenceNode'              : 'SpSequenceNode',
     'TextNode'                  : 'SpTextNode',
     'TextNode'                  : 'SpTextNode',
@@ -156,27 +164,35 @@ pgraphClassRenameDictionary = {
     'QpCollisionHandlerQueue'   : 'CollisionHandlerQueue',
     'QpCollisionHandlerQueue'   : 'CollisionHandlerQueue',
     'QpCollisionNode'           : 'CollisionNode',
     'QpCollisionNode'           : 'CollisionNode',
     'QpCollisionTraverser'      : 'CollisionTraverser',
     'QpCollisionTraverser'      : 'CollisionTraverser',
+    'QpColorLerpFunctor'        : 'ColorLerpFunctor',
+    'QpColorScaleLerpFunctor'   : 'ColorScaleLerpFunctor',
     'QpDataGraphTraverser'      : 'DataGraphTraverser',
     'QpDataGraphTraverser'      : 'DataGraphTraverser',
     'QpDataNode'                : 'DataNode',
     'QpDataNode'                : 'DataNode',
     'QpDialNode'                : 'DialNode',
     'QpDialNode'                : 'DialNode',
     'QpDriveInterface'          : 'DriveInterface',
     'QpDriveInterface'          : 'DriveInterface',
     'QpGeomNode'                : 'GeomNode',
     'QpGeomNode'                : 'GeomNode',
+    'QpHprLerpFunctor'          : 'HprLerpFunctor',
+    'QpHprScaleLerpFunctor'     : 'HprScaleLerpFunctor',
     'QpLODNode'                 : 'LODNode',
     'QpLODNode'                 : 'LODNode',
-    'QpLineSegs'                : 'LineSegs',
     'QpLensNode'                : 'LensNode',
     'QpLensNode'                : 'LensNode',
+    'QpLineSegs'                : 'LineSegs',
     'QpModelNode'               : 'ModelNode',
     'QpModelNode'               : 'ModelNode',
-    'QpModelRoot'               : 'ModelRoot',
     'QpModelPool'               : 'ModelPool',
     'QpModelPool'               : 'ModelPool',
+    'QpModelRoot'               : 'ModelRoot',
     'QpMouseAndKeyboard'        : 'MouseAndKeyboard',
     'QpMouseAndKeyboard'        : 'MouseAndKeyboard',
     'QpMouseWatcher'            : 'MouseWatcher',
     'QpMouseWatcher'            : 'MouseWatcher',
     'QpNodePath'                : 'NodePath',
     'QpNodePath'                : 'NodePath',
     'QpNodePathCollection'      : 'NodePathCollection',
     'QpNodePathCollection'      : 'NodePathCollection',
-    'QpPGTop'                   : 'PGTop',
-    'QpPGItem'                  : 'PGItem',
     'QpPGButton'                : 'PGButton',
     'QpPGButton'                : 'PGButton',
     'QpPGEntry'                 : 'PGEntry',
     'QpPGEntry'                 : 'PGEntry',
+    'QpPGItem'                  : 'PGItem',
+    'QpPGTop'                   : 'PGTop',
     'QpPGWaitBar'               : 'PGWaitBar',
     'QpPGWaitBar'               : 'PGWaitBar',
     'QpPartBundleNode'          : 'PartBundleNode',
     'QpPartBundleNode'          : 'PartBundleNode',
+    'QpPosHprLerpFunctor'       : 'PosHprLerpFunctor',
+    'QpPosHprScaleLerpFunctor'  : 'PosHprScaleLerpFunctor',
+    'QpPosLerpFunctor'          : 'PosLerpFunctor',
+    'QpScaleLerpFunctor'        : 'ScaleLerpFunctor',
     'QpSceneGraphReducer'       : 'SceneGraphReducer',
     'QpSceneGraphReducer'       : 'SceneGraphReducer',
     'QpSequenceNode'            : 'SequenceNode',
     'QpSequenceNode'            : 'SequenceNode',
     'QpTextNode'                : 'TextNode',
     'QpTextNode'                : 'TextNode',

+ 4 - 1
panda/src/pgraph/Sources.pp

@@ -1,6 +1,6 @@
 #define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
 #define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
                    dtoolutil:c dtoolbase:c dtool:m
                    dtoolutil:c dtoolbase:c dtool:m
-#define LOCAL_LIBS event gsgbase gobj putil graph linmath express pandabase
+#define LOCAL_LIBS lerp event gsgbase gobj putil graph linmath express pandabase
 
 
 #begin lib_target
 #begin lib_target
   #define TARGET pgraph
   #define TARGET pgraph
@@ -44,6 +44,7 @@
     qpnodePath.I qpnodePath.h \
     qpnodePath.I qpnodePath.h \
     qpnodePathCollection.I qpnodePathCollection.h \
     qpnodePathCollection.I qpnodePathCollection.h \
     qpnodePathComponent.I qpnodePathComponent.h \
     qpnodePathComponent.I qpnodePathComponent.h \
+    qpnodePathLerps.h \
     pandaNode.I pandaNode.h \
     pandaNode.I pandaNode.h \
     renderAttrib.I renderAttrib.h \
     renderAttrib.I renderAttrib.h \
     renderEffect.I renderEffect.h \
     renderEffect.I renderEffect.h \
@@ -101,6 +102,7 @@
     qpnodePath.cxx \
     qpnodePath.cxx \
     qpnodePathCollection.cxx \
     qpnodePathCollection.cxx \
     qpnodePathComponent.cxx \
     qpnodePathComponent.cxx \
+    qpnodePathLerps.cxx \
     pandaNode.cxx \
     pandaNode.cxx \
     renderAttrib.cxx \
     renderAttrib.cxx \
     renderEffect.cxx \
     renderEffect.cxx \
@@ -160,6 +162,7 @@
     qpnodePath.I qpnodePath.h \
     qpnodePath.I qpnodePath.h \
     qpnodePathCollection.I qpnodePathCollection.h \
     qpnodePathCollection.I qpnodePathCollection.h \
     qpnodePathComponent.I qpnodePathComponent.h \
     qpnodePathComponent.I qpnodePathComponent.h \
+    qpnodePathLerps.h \
     pandaNode.I pandaNode.h \
     pandaNode.I pandaNode.h \
     renderAttrib.I renderAttrib.h \
     renderAttrib.I renderAttrib.h \
     renderEffect.I renderEffect.h \
     renderEffect.I renderEffect.h \

+ 9 - 0
panda/src/pgraph/config_pgraph.cxx

@@ -57,6 +57,7 @@
 #include "textureAttrib.h"
 #include "textureAttrib.h"
 #include "transformState.h"
 #include "transformState.h"
 #include "transparencyAttrib.h"
 #include "transparencyAttrib.h"
+#include "qpnodePathLerps.h"
 
 
 #include "dconfig.h"
 #include "dconfig.h"
 
 
@@ -132,6 +133,14 @@ init_libpgraph() {
   TextureAttrib::init_type();
   TextureAttrib::init_type();
   TransformState::init_type();
   TransformState::init_type();
   TransparencyAttrib::init_type();
   TransparencyAttrib::init_type();
+  qpPosLerpFunctor::init_type();
+  qpHprLerpFunctor::init_type();
+  qpScaleLerpFunctor::init_type();
+  qpPosHprLerpFunctor::init_type();
+  qpHprScaleLerpFunctor::init_type();
+  qpPosHprScaleLerpFunctor::init_type();
+  qpColorLerpFunctor::init_type();
+  qpColorScaleLerpFunctor::init_type();
 
 
   BillboardEffect::register_with_read_factory();
   BillboardEffect::register_with_read_factory();
   qpCamera::register_with_read_factory();
   qpCamera::register_with_read_factory();

+ 1 - 0
panda/src/pgraph/pgraph_composite2.cxx

@@ -13,6 +13,7 @@
 #include "qpnodePath.cxx"
 #include "qpnodePath.cxx"
 #include "qpnodePathCollection.cxx"
 #include "qpnodePathCollection.cxx"
 #include "qpnodePathComponent.cxx"
 #include "qpnodePathComponent.cxx"
+#include "qpnodePathLerps.cxx"
 #include "pandaNode.cxx"
 #include "pandaNode.cxx"
 #include "renderAttrib.cxx"
 #include "renderAttrib.cxx"
 #include "renderEffect.cxx"
 #include "renderEffect.cxx"

+ 296 - 0
panda/src/pgraph/qpnodePathLerps.cxx

@@ -0,0 +1,296 @@
+// Filename: qpnodePathLerps.cxx
+// Created by:  frang (01Jun00)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "qpnodePathLerps.h"
+
+TypeHandle qpPosLerpFunctor::_type_handle;
+TypeHandle qpHprLerpFunctor::_type_handle;
+TypeHandle qpScaleLerpFunctor::_type_handle;
+TypeHandle qpColorLerpFunctor::_type_handle;
+TypeHandle qpPosHprLerpFunctor::_type_handle;
+TypeHandle qpHprScaleLerpFunctor::_type_handle;
+TypeHandle qpPosHprScaleLerpFunctor::_type_handle;
+TypeHandle qpColorScaleLerpFunctor::_type_handle;
+
+
+qpPosLerpFunctor::qpPosLerpFunctor(const qpPosLerpFunctor& c)
+  : LPoint3fLerpFunctor(c), _node_path(c._node_path) {}
+
+qpPosLerpFunctor::~qpPosLerpFunctor(void)
+{
+}
+
+qpPosLerpFunctor& qpPosLerpFunctor::operator=(const qpPosLerpFunctor& c) {
+  _node_path = c._node_path;
+  LPoint3fLerpFunctor::operator=(c);
+  return *this;
+}
+
+void qpPosLerpFunctor::operator()(float t) {
+  if (_is_wrt)
+    _node_path.set_pos(_wrt_path, interpolate(t));
+  else
+    _node_path.set_pos(interpolate(t));
+}
+
+qpHprLerpFunctor::qpHprLerpFunctor(const qpHprLerpFunctor& c)
+  : LVecBase3fLerpFunctor(c), _node_path(c._node_path) {}
+
+void qpHprLerpFunctor::take_shortest(void) {
+  // so long as these are actually degrees
+  for (int i=0; i!=3; ++i)
+    if (this->_diff_cache[i] < -180.)
+      _start[i] -= 360.;
+    else if (this->_diff_cache[i] > 180.)
+      _start[i] += 360.;
+  this->_diff_cache = this->_end - this->_start;
+}
+
+void qpHprLerpFunctor::take_longest(void) {
+  // so long as these are actually degrees
+  for (int i=0; i!=3; ++i)
+    if ((this->_diff_cache[i] < 0.) && (this->_diff_cache[i] > -180.))
+      _start[i] -= 360.;
+    else if ((this->_diff_cache[i] >= 0.) && (this->_diff_cache[i] < 180))
+      _start[i] += 360.;
+  this->_diff_cache = this->_end - this->_start;
+}
+
+qpHprLerpFunctor::~qpHprLerpFunctor(void)
+{
+}
+
+qpHprLerpFunctor& qpHprLerpFunctor::operator=(const qpHprLerpFunctor& c) {
+  _node_path = c._node_path;
+  LVecBase3fLerpFunctor::operator=(c);
+  return *this;
+}
+
+void qpHprLerpFunctor::operator()(float t) {
+  if (_is_wrt)
+    _node_path.set_hpr(_wrt_path, interpolate(t));
+  else
+    _node_path.set_hpr(interpolate(t));
+}
+
+qpScaleLerpFunctor::qpScaleLerpFunctor(const qpScaleLerpFunctor& c)
+  : LVecBase3fLerpFunctor(c), _node_path(c._node_path) {}
+
+qpScaleLerpFunctor::~qpScaleLerpFunctor(void)
+{
+}
+
+qpScaleLerpFunctor& qpScaleLerpFunctor::operator=(const qpScaleLerpFunctor& c) {
+  _node_path = c._node_path;
+  LVecBase3fLerpFunctor::operator=(c);
+  return *this;
+}
+
+void qpScaleLerpFunctor::operator()(float t) {
+  if (_is_wrt)
+    _node_path.set_scale(_wrt_path, interpolate(t));
+  else
+    _node_path.set_scale(interpolate(t));
+}
+
+qpColorLerpFunctor::qpColorLerpFunctor(const qpColorLerpFunctor& c)
+  : LVecBase4fLerpFunctor(c), _node_path(c._node_path) {}
+
+qpColorLerpFunctor::~qpColorLerpFunctor(void)
+{
+}
+
+qpColorLerpFunctor& qpColorLerpFunctor::operator=(const qpColorLerpFunctor& c) {
+  _node_path = c._node_path;
+  LVecBase4fLerpFunctor::operator=(c);
+  return *this;
+}
+
+void qpColorLerpFunctor::operator()(float t) {
+        _node_path.set_color(interpolate(t));
+}
+
+
+qpPosHprLerpFunctor::qpPosHprLerpFunctor(const qpPosHprLerpFunctor& c)
+  : LerpFunctor(c), _node_path(c._node_path) {}
+
+void qpPosHprLerpFunctor::take_shortest(void) {
+  // so long as these are actually degrees
+  for (int i=0; i!=3; ++i)
+    if (this->_hdiff_cache[i] < -180.)
+      _hstart[i] -= 360.;
+    else if (this->_hdiff_cache[i] > 180.)
+      _hstart[i] += 360.;
+  this->_hdiff_cache = this->_hend - this->_hstart;
+}
+
+void qpPosHprLerpFunctor::take_longest(void) {
+  // so long as these are actually degrees
+  for (int i=0; i!=3; ++i)
+    if ((this->_hdiff_cache[i] < 0.) && (this->_hdiff_cache[i] > -180.))
+      _hstart[i] -= 360.;
+    else if ((this->_hdiff_cache[i] >= 0.) && (this->_hdiff_cache[i] < 180))
+      _hstart[i] += 360.;
+  this->_hdiff_cache = this->_hend - this->_hstart;
+}
+
+qpPosHprLerpFunctor::~qpPosHprLerpFunctor(void)
+{
+}
+
+qpPosHprLerpFunctor& qpPosHprLerpFunctor::operator=(const qpPosHprLerpFunctor& c) {
+  _node_path = c._node_path;
+  _pstart = c._pstart;
+  _pend = c._pend;
+  _pdiff_cache = c._pdiff_cache;
+  _hstart = c._hstart;
+  _hend = c._hend;
+  _hdiff_cache = c._hdiff_cache;
+  LerpFunctor::operator=(c);
+  return *this;
+}
+
+void qpPosHprLerpFunctor::operator()(float t) {
+  LPoint3f p = ((t * _pdiff_cache) + _pstart);
+  LVecBase3f h = ((t * _hdiff_cache) + _hstart);
+  if (_is_wrt)
+    _node_path.set_pos_hpr(_wrt_path, p, h);
+  else
+    _node_path.set_pos_hpr(p, h);
+}
+
+qpHprScaleLerpFunctor::qpHprScaleLerpFunctor(const qpHprScaleLerpFunctor& c)
+  : LerpFunctor(c), _node_path(c._node_path) {}
+
+void qpHprScaleLerpFunctor::take_shortest(void) {
+  // so long as these are actually degrees
+  for (int i=0; i!=3; ++i)
+    if (this->_hdiff_cache[i] < -180.)
+      _hstart[i] -= 360.;
+    else if (this->_hdiff_cache[i] > 180.)
+      _hstart[i] += 360.;
+  this->_hdiff_cache = this->_hend - this->_hstart;
+}
+
+void qpHprScaleLerpFunctor::take_longest(void) {
+  // so long as these are actually degrees
+  for (int i=0; i!=3; ++i)
+    if ((this->_hdiff_cache[i] < 0.) && (this->_hdiff_cache[i] > -180.))
+      _hstart[i] -= 360.;
+    else if ((this->_hdiff_cache[i] >= 0.) && (this->_hdiff_cache[i] < 180))
+      _hstart[i] += 360.;
+  this->_hdiff_cache = this->_hend - this->_hstart;
+}
+
+qpHprScaleLerpFunctor::~qpHprScaleLerpFunctor(void)
+{
+}
+
+qpHprScaleLerpFunctor&
+qpHprScaleLerpFunctor::operator=(const qpHprScaleLerpFunctor& c) {
+  _node_path = c._node_path;
+  _hstart = c._hstart;
+  _hend = c._hend;
+  _hdiff_cache = c._hdiff_cache;
+  _sstart = c._sstart;
+  _send = c._send;
+  _sdiff_cache = c._sdiff_cache;
+  LerpFunctor::operator=(c);
+  return *this;
+}
+
+void qpHprScaleLerpFunctor::operator()(float t) {
+  LVecBase3f h = ((t * _hdiff_cache) + _hstart);
+  LVecBase3f s = ((t * _sdiff_cache) + _sstart);
+  if (_is_wrt)
+    _node_path.set_hpr_scale(_wrt_path, h, s);
+  else
+    _node_path.set_hpr_scale(h, s);
+}
+
+qpPosHprScaleLerpFunctor::qpPosHprScaleLerpFunctor(const qpPosHprScaleLerpFunctor& c)
+  : LerpFunctor(c), _node_path(c._node_path) {}
+
+void qpPosHprScaleLerpFunctor::take_shortest(void) {
+  // so long as these are actually degrees
+  for (int i=0; i!=3; ++i)
+    if (this->_hdiff_cache[i] < -180.)
+      _hstart[i] -= 360.;
+    else if (this->_hdiff_cache[i] > 180.)
+      _hstart[i] += 360.;
+  this->_hdiff_cache = this->_hend - this->_hstart;
+}
+
+void qpPosHprScaleLerpFunctor::take_longest(void) {
+  // so long as these are actually degrees
+  for (int i=0; i!=3; ++i)
+    if ((this->_hdiff_cache[i] < 0.) && (this->_hdiff_cache[i] > -180.))
+      _hstart[i] -= 360.;
+    else if ((this->_hdiff_cache[i] >= 0.) && (this->_hdiff_cache[i] < 180))
+      _hstart[i] += 360.;
+  this->_hdiff_cache = this->_hend - this->_hstart;
+}
+
+qpPosHprScaleLerpFunctor::~qpPosHprScaleLerpFunctor(void)
+{
+}
+
+qpPosHprScaleLerpFunctor&
+qpPosHprScaleLerpFunctor::operator=(const qpPosHprScaleLerpFunctor& c) {
+  _node_path = c._node_path;
+  _pstart = c._pstart;
+  _pend = c._pend;
+  _pdiff_cache = c._pdiff_cache;
+  _hstart = c._hstart;
+  _hend = c._hend;
+  _hdiff_cache = c._hdiff_cache;
+  _sstart = c._sstart;
+  _send = c._send;
+  _sdiff_cache = c._sdiff_cache;
+  LerpFunctor::operator=(c);
+  return *this;
+}
+
+void qpPosHprScaleLerpFunctor::operator()(float t) {
+  LPoint3f p = ((t * _pdiff_cache) + _pstart);
+  LVecBase3f h = ((t * _hdiff_cache) + _hstart);
+  LVecBase3f s = ((t * _sdiff_cache) + _sstart);
+  if (_is_wrt)
+    _node_path.set_pos_hpr_scale(_wrt_path, p, h, s);
+  else
+    _node_path.set_pos_hpr_scale(p, h, s);
+}
+
+qpColorScaleLerpFunctor::qpColorScaleLerpFunctor(const qpColorScaleLerpFunctor& c)
+  : LVecBase4fLerpFunctor(c), _node_path(c._node_path) {}
+
+qpColorScaleLerpFunctor::~qpColorScaleLerpFunctor(void)
+{
+}
+
+qpColorScaleLerpFunctor& qpColorScaleLerpFunctor::operator=(const qpColorScaleLerpFunctor& c) {
+  _node_path = c._node_path;
+  LVecBase4fLerpFunctor::operator=(c);
+  return *this;
+}
+
+void qpColorScaleLerpFunctor::operator()(float t) {
+  _node_path.set_color_scale(interpolate(t));
+}
+
+

+ 528 - 0
panda/src/pgraph/qpnodePathLerps.h

@@ -0,0 +1,528 @@
+// Filename: qpnodePathLerps.h
+// Created by:  frang (01Jun00)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef qpNODEPATHLERPS_H
+#define qpNODEPATHLERPS_H
+
+#include "pandabase.h"
+
+#include "lerpfunctor.h"
+#include "qpnodePath.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : PosLerpFunctor
+// Description : Class for Lerping between positions in space
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA qpPosLerpFunctor : public LPoint3fLerpFunctor {
+private:
+  qpNodePath _node_path;
+  bool _is_wrt;
+  qpNodePath _wrt_path;
+
+PUBLISHED:
+  qpPosLerpFunctor(qpNodePath np, LPoint3f start, LPoint3f end)
+    : LPoint3fLerpFunctor(start, end), _node_path(np), _is_wrt(false) {}
+  qpPosLerpFunctor(qpNodePath np, float sx, float sy, float sz, float ex, float ey,
+                 float ez) : LPoint3fLerpFunctor(LPoint3f(sx, sy, sz),
+                                                 LPoint3f(ex, ey, ez)),
+                             _node_path(np), _is_wrt(false) {}
+  qpPosLerpFunctor(qpNodePath np, LPoint3f start, LPoint3f end, qpNodePath wrt)
+    : LPoint3fLerpFunctor(start, end), _node_path(np), _is_wrt(true),
+      _wrt_path(wrt) {}
+  qpPosLerpFunctor(qpNodePath np, float sx, float sy, float sz, float ex, float ey,
+                 float ez, qpNodePath wrt)
+    : LPoint3fLerpFunctor(LPoint3f(sx, sy, sz), LPoint3f(ex, ey, ez)),
+      _node_path(np), _is_wrt(true), _wrt_path(wrt) {}
+
+public:
+  qpPosLerpFunctor(const qpPosLerpFunctor&);
+  virtual ~qpPosLerpFunctor(void);
+  qpPosLerpFunctor& operator=(const qpPosLerpFunctor&);
+  virtual void operator()(float);
+
+public:
+  // now for typehandle stuff
+  static TypeHandle get_class_type(void) {
+    return _type_handle;
+  }
+  static void init_type(void) {
+    LPoint3fLerpFunctor::init_type();
+    register_type(_type_handle, "PosLerpFunctor",
+                  LPoint3fLerpFunctor::get_class_type());
+  }
+  virtual TypeHandle get_type(void) const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type(void) {
+    init_type();
+    return get_class_type();
+  }
+private:
+  static TypeHandle _type_handle;
+};
+
+
+// evil bad bad evil HPR
+////////////////////////////////////////////////////////////////////
+//       Class : HprLerpFunctor
+// Description : Class for Lerping between orientations in space
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA qpHprLerpFunctor : public LVecBase3fLerpFunctor {
+private:
+  qpNodePath _node_path;
+  bool _is_wrt;
+  qpNodePath _wrt_path;
+
+PUBLISHED:
+  qpHprLerpFunctor(qpNodePath np, LVecBase3f start, LVecBase3f end)
+    : LVecBase3fLerpFunctor(start, end), _node_path(np), _is_wrt(false) {}
+  qpHprLerpFunctor(qpNodePath np, float sx, float sy, float sz, float ex, float ey,
+                 float ez) : LVecBase3fLerpFunctor(LVecBase3f(sx, sy, sz),
+                                                  LVecBase3f(ex, ey, ez)),
+                             _node_path(np), _is_wrt(false) {}
+  qpHprLerpFunctor(qpNodePath np, LVecBase3f start, LVecBase3f end, qpNodePath wrt)
+    : LVecBase3fLerpFunctor(start, end), _node_path(np), _is_wrt(true),
+      _wrt_path(wrt) {}
+  qpHprLerpFunctor(qpNodePath np, float sx, float sy, float sz, float ex, float ey,
+                 float ez, qpNodePath wrt)
+    : LVecBase3fLerpFunctor(LVecBase3f(sx, sy, sz), LVecBase3f(ex, ey, ez)),
+      _node_path(np), _is_wrt(true), _wrt_path(wrt) {}
+  void take_shortest(void);
+  void take_longest(void);
+
+public:
+  qpHprLerpFunctor(const qpHprLerpFunctor&);
+  virtual ~qpHprLerpFunctor(void);
+  qpHprLerpFunctor& operator=(const qpHprLerpFunctor&);
+  virtual void operator()(float);
+
+public:
+  // now for typehandle stuff
+  static TypeHandle get_class_type(void) {
+    return _type_handle;
+  }
+  static void init_type(void) {
+    LVecBase3fLerpFunctor::init_type();
+    register_type(_type_handle, "qpHprLerpFunctor",
+                  LVecBase3fLerpFunctor::get_class_type());
+  }
+  virtual TypeHandle get_type(void) const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type(void) {
+    init_type();
+    return get_class_type();
+  }
+private:
+  static TypeHandle _type_handle;
+};
+
+////////////////////////////////////////////////////////////////////
+//       Class : qpScaleLerpFunctor
+// Description : Class for Lerping between scales
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA qpScaleLerpFunctor : public LVecBase3fLerpFunctor {
+private:
+  qpNodePath _node_path;
+  bool _is_wrt;
+  qpNodePath _wrt_path;
+
+PUBLISHED:
+  qpScaleLerpFunctor(qpNodePath np, LVecBase3f start, LVecBase3f end)
+    : LVecBase3fLerpFunctor(start, end), _node_path(np), _is_wrt(false) {}
+  qpScaleLerpFunctor(qpNodePath np, float sx, float sy, float sz, float ex,
+                   float ey, float ez)
+    : LVecBase3fLerpFunctor(LVecBase3f(sx, sy, sz), LVecBase3f(ex, ey, ez)),
+      _node_path(np), _is_wrt(false) {}
+  qpScaleLerpFunctor(qpNodePath np, LVecBase3f start, LVecBase3f end, qpNodePath wrt)
+    : LVecBase3fLerpFunctor(start, end), _node_path(np), _is_wrt(true),
+      _wrt_path(wrt) {}
+  qpScaleLerpFunctor(qpNodePath np, float sx, float sy, float sz, float ex,
+                   float ey, float ez, qpNodePath wrt)
+    : LVecBase3fLerpFunctor(LVecBase3f(sx, sy, sz), LVecBase3f(ex, ey, ez)),
+      _node_path(np), _is_wrt(true), _wrt_path(wrt) {}
+
+public:
+  qpScaleLerpFunctor(const qpScaleLerpFunctor&);
+  virtual ~qpScaleLerpFunctor(void);
+  qpScaleLerpFunctor& operator=(const qpScaleLerpFunctor&);
+  virtual void operator()(float);
+
+public:
+  // now for typehandle stuff
+  static TypeHandle get_class_type(void) {
+    return _type_handle;
+  }
+  static void init_type(void) {
+    LVecBase3fLerpFunctor::init_type();
+    register_type(_type_handle, "qpScaleLerpFunctor",
+                  LVecBase3fLerpFunctor::get_class_type());
+  }
+  virtual TypeHandle get_type(void) const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type(void) {
+    init_type();
+    return get_class_type();
+  }
+private:
+  static TypeHandle _type_handle;
+};
+
+////////////////////////////////////////////////////////////////////
+//       Class : qpColorLerpFunctor
+// Description : Class for Lerping between colors
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA qpColorLerpFunctor : public LVecBase4fLerpFunctor {
+private:
+  qpNodePath _node_path;
+  bool _is_wrt;
+  qpNodePath _wrt_path;
+
+PUBLISHED:
+  qpColorLerpFunctor(qpNodePath np, LVecBase4f start, LVecBase4f end)
+    : LVecBase4fLerpFunctor(start, end), _node_path(np), _is_wrt(false) {}
+  qpColorLerpFunctor(qpNodePath np, float sr, float sg, float sb, float sa,
+                float er, float eg, float eb, float ea) : LVecBase4fLerpFunctor(LVecBase4f(sr, sg, sb, sa),
+                                                 LVecBase4f(er, eg, eb, ea)), _node_path(np), _is_wrt(false) {}
+  qpColorLerpFunctor(qpNodePath np, LVecBase4f start, LVecBase4f end, qpNodePath wrt)
+    : LVecBase4fLerpFunctor(start, end), _node_path(np), _is_wrt(true),
+      _wrt_path(wrt) {}
+  qpColorLerpFunctor(qpNodePath np, float sr, float sg, float sb, float sa, float er, float eg,
+                 float eb, float ea, qpNodePath wrt)
+    : LVecBase4fLerpFunctor(LVecBase4f(sr, sg, sb, sa), LVecBase4f(er, eg, eb, ea)),
+      _node_path(np), _is_wrt(true), _wrt_path(wrt) {}
+
+public:
+  qpColorLerpFunctor(const qpColorLerpFunctor&);
+  virtual ~qpColorLerpFunctor(void);
+  qpColorLerpFunctor& operator=(const qpColorLerpFunctor&);
+  virtual void operator()(float);
+
+public:
+  // now for typehandle stuff
+  static TypeHandle get_class_type(void) {
+    return _type_handle;
+  }
+  static void init_type(void) {
+    LVecBase4fLerpFunctor::init_type();
+    register_type(_type_handle, "qpColorLerpFunctor",
+                  LVecBase4fLerpFunctor::get_class_type());
+  }
+  virtual TypeHandle get_type(void) const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type(void) {
+    init_type();
+    return get_class_type();
+  }
+private:
+  static TypeHandle _type_handle;
+};
+
+////////////////////////////////////////////////////////////////////
+//       Class : qpPosHprLerpFunctor
+// Description : Class for Lerping between positions and orientations
+//               in space
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA qpPosHprLerpFunctor : public LerpFunctor {
+private:
+  qpNodePath _node_path;
+  LPoint3f _pstart;
+  LPoint3f _pend;
+  LPoint3f _pdiff_cache;
+  LVecBase3f _hstart;
+  LVecBase3f _hend;
+  LVecBase3f _hdiff_cache;
+  bool _is_wrt;
+  qpNodePath _wrt_path;
+
+PUBLISHED:
+  qpPosHprLerpFunctor(qpNodePath np, LPoint3f pstart, LPoint3f pend,
+                    LVecBase3f hstart, LVecBase3f hend)
+    : LerpFunctor(), _node_path(np), _pstart(pstart), _pend(pend),
+      _pdiff_cache(pend-pstart), _hstart(hstart), _hend(hend),
+      _hdiff_cache(hend-hstart), _is_wrt(false) {}
+  qpPosHprLerpFunctor(qpNodePath np, float psx, float psy, float psz, float pex,
+                    float pey, float pez, float hsx, float hsy, float hsz,
+                    float hex, float hey, float hez)
+    : LerpFunctor(), _node_path(np), _pstart(psx, psy, psz),
+      _pend(pex, pey, pez), _pdiff_cache(_pend-_pstart),
+      _hstart(hsx, hsy, hsz), _hend(hex, hey, hez),
+      _hdiff_cache(_hend - _hstart), _is_wrt(false) {}
+  qpPosHprLerpFunctor(qpNodePath np, LPoint3f pstart, LPoint3f pend,
+                    LVecBase3f hstart, LVecBase3f hend, qpNodePath wrt)
+    : LerpFunctor(), _node_path(np), _pstart(pstart), _pend(pend),
+      _pdiff_cache(pend-pstart), _hstart(hstart), _hend(hend),
+      _hdiff_cache(hend-hstart), _is_wrt(true), _wrt_path(wrt) {}
+  qpPosHprLerpFunctor(qpNodePath np, float psx, float psy, float psz, float pex,
+                    float pey, float pez, float hsx, float hsy, float hsz,
+                    float hex, float hey, float hez, qpNodePath wrt)
+    : LerpFunctor(), _node_path(np), _pstart(psx, psy, psz),
+      _pend(pex, pey, pez), _pdiff_cache(_pend-_pstart),
+      _hstart(hsx, hsy, hsz), _hend(hex, hey, hez),
+      _hdiff_cache(_hend - _hstart), _is_wrt(true), _wrt_path(wrt) {}
+  void take_shortest(void);
+  void take_longest(void);
+
+public:
+  qpPosHprLerpFunctor(const qpPosHprLerpFunctor&);
+  virtual ~qpPosHprLerpFunctor(void);
+  qpPosHprLerpFunctor& operator=(const qpPosHprLerpFunctor&);
+  virtual void operator()(float);
+
+public:
+  // now for typehandle stuff
+  static TypeHandle get_class_type(void) {
+    return _type_handle;
+  }
+  static void init_type(void) {
+    LerpFunctor::init_type();
+    register_type(_type_handle, "qpPosHprLerpFunctor",
+                  LerpFunctor::get_class_type());
+  }
+  virtual TypeHandle get_type(void) const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type(void) {
+    init_type();
+    return get_class_type();
+  }
+private:
+  static TypeHandle _type_handle;
+};
+
+////////////////////////////////////////////////////////////////////
+//       Class : qpHprScaleLerpFunctor
+// Description : Class for Lerping between orientation
+//               and scale
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA qpHprScaleLerpFunctor : public LerpFunctor {
+private:
+  qpNodePath _node_path;
+  LVecBase3f _hstart;
+  LVecBase3f _hend;
+  LVecBase3f _hdiff_cache;
+  LVecBase3f _sstart;
+  LVecBase3f _send;
+  LVecBase3f _sdiff_cache;
+  bool _is_wrt;
+  qpNodePath _wrt_path;
+
+PUBLISHED:
+  qpHprScaleLerpFunctor(qpNodePath np, 
+		      LVecBase3f hstart, LVecBase3f hend, LVecBase3f sstart,
+		      LVecBase3f send)
+    : LerpFunctor(), _node_path(np),
+      _hstart(hstart), _hend(hend),
+      _hdiff_cache(hend-hstart), _sstart(sstart), _send(send),
+      _sdiff_cache(send-sstart), _is_wrt(false) {}
+  qpHprScaleLerpFunctor(qpNodePath np, float hsx, float hsy,
+                         float hsz, float hex, float hey, float hez, float ssx,
+                         float ssy, float ssz, float sex, float sey, float sez)
+    : LerpFunctor(), _node_path(np),
+      _hstart(hsx, hsy, hsz), _hend(hex, hey, hez),
+      _hdiff_cache(_hend-_hstart), _sstart(ssx, ssy, ssz),
+      _send(sex, sey, sez), _sdiff_cache(_send-_sstart), _is_wrt(false) {}
+  qpHprScaleLerpFunctor(qpNodePath np, 
+		      LVecBase3f hstart, LVecBase3f hend, LVecBase3f sstart,
+		      LVecBase3f send, qpNodePath wrt)
+    : LerpFunctor(), _node_path(np), _hstart(hstart), _hend(hend),
+      _hdiff_cache(hend-hstart), _sstart(sstart), _send(send),
+      _sdiff_cache(send-sstart), _is_wrt(true), _wrt_path(wrt) {}
+  qpHprScaleLerpFunctor(qpNodePath np, float hsx, float hsy,
+		      float hsz, float hex, float hey, float hez, float ssx,
+		      float ssy, float ssz, float sex, float sey, float sez,
+		      qpNodePath wrt)
+    : LerpFunctor(), _node_path(np),
+      _hstart(hsx, hsy, hsz), _hend(hex, hey, hez),
+      _hdiff_cache(_hend-_hstart), _sstart(ssx, ssy, ssz),
+      _send(sex, sey, sez), _sdiff_cache(_send-_sstart), _is_wrt(true),
+      _wrt_path(wrt) {}
+  void take_shortest(void);
+  void take_longest(void);
+
+public:
+  qpHprScaleLerpFunctor(const qpHprScaleLerpFunctor&);
+  virtual ~qpHprScaleLerpFunctor(void);
+  qpHprScaleLerpFunctor& operator=(const qpHprScaleLerpFunctor&);
+  virtual void operator()(float);
+
+public:
+  // now for typehandle stuff
+  static TypeHandle get_class_type(void) {
+    return _type_handle;
+  }
+  static void init_type(void) {
+    LerpFunctor::init_type();
+    register_type(_type_handle, "qpHprScaleLerpFunctor",
+                  LerpFunctor::get_class_type());
+  }
+  virtual TypeHandle get_type(void) const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type(void) {
+    init_type();
+    return get_class_type();
+  }
+private:
+  static TypeHandle _type_handle;
+};
+
+////////////////////////////////////////////////////////////////////
+//       Class : qpPosHprScaleLerpFunctor
+// Description : Class for Lerping between position, orientation,
+//               and scale
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA qpPosHprScaleLerpFunctor : public LerpFunctor {
+private:
+  qpNodePath _node_path;
+  LPoint3f _pstart;
+  LPoint3f _pend;
+  LPoint3f _pdiff_cache;
+  LVecBase3f _hstart;
+  LVecBase3f _hend;
+  LVecBase3f _hdiff_cache;
+  LVecBase3f _sstart;
+  LVecBase3f _send;
+  LVecBase3f _sdiff_cache;
+  bool _is_wrt;
+  qpNodePath _wrt_path;
+
+PUBLISHED:
+  qpPosHprScaleLerpFunctor(qpNodePath np, LPoint3f pstart, LPoint3f pend,
+                         LVecBase3f hstart, LVecBase3f hend, LVecBase3f sstart,
+                         LVecBase3f send)
+    : LerpFunctor(), _node_path(np), _pstart(pstart), _pend(pend),
+      _pdiff_cache(pend-pstart), _hstart(hstart), _hend(hend),
+      _hdiff_cache(hend-hstart), _sstart(sstart), _send(send),
+      _sdiff_cache(send-sstart), _is_wrt(false) {}
+  qpPosHprScaleLerpFunctor(qpNodePath np, float psx, float psy, float psz,
+                         float pex, float pey, float pez, float hsx, float hsy,
+                         float hsz, float hex, float hey, float hez, float ssx,
+                         float ssy, float ssz, float sex, float sey, float sez)
+    : LerpFunctor(), _node_path(np), _pstart(psx, psy, psz),
+      _pend(pex, pey, pez), _pdiff_cache(_pend-_pstart),
+      _hstart(hsx, hsy, hsz), _hend(hex, hey, hez),
+      _hdiff_cache(_hend-_hstart), _sstart(ssx, ssy, ssz),
+      _send(sex, sey, sez), _sdiff_cache(_send-_sstart), _is_wrt(false) {}
+  qpPosHprScaleLerpFunctor(qpNodePath np, LPoint3f pstart, LPoint3f pend,
+                         LVecBase3f hstart, LVecBase3f hend, LVecBase3f sstart,
+                         LVecBase3f send, qpNodePath wrt)
+    : LerpFunctor(), _node_path(np), _pstart(pstart), _pend(pend),
+      _pdiff_cache(pend-pstart), _hstart(hstart), _hend(hend),
+      _hdiff_cache(hend-hstart), _sstart(sstart), _send(send),
+      _sdiff_cache(send-sstart), _is_wrt(true), _wrt_path(wrt) {}
+  qpPosHprScaleLerpFunctor(qpNodePath np, float psx, float psy, float psz,
+                         float pex, float pey, float pez, float hsx, float hsy,
+                         float hsz, float hex, float hey, float hez, float ssx,
+                         float ssy, float ssz, float sex, float sey, float sez,
+                         qpNodePath wrt)
+    : LerpFunctor(), _node_path(np), _pstart(psx, psy, psz),
+      _pend(pex, pey, pez), _pdiff_cache(_pend-_pstart),
+      _hstart(hsx, hsy, hsz), _hend(hex, hey, hez),
+      _hdiff_cache(_hend-_hstart), _sstart(ssx, ssy, ssz),
+      _send(sex, sey, sez), _sdiff_cache(_send-_sstart), _is_wrt(true),
+      _wrt_path(wrt) {}
+  void take_shortest(void);
+  void take_longest(void);
+
+public:
+  qpPosHprScaleLerpFunctor(const qpPosHprScaleLerpFunctor&);
+  virtual ~qpPosHprScaleLerpFunctor(void);
+  qpPosHprScaleLerpFunctor& operator=(const qpPosHprScaleLerpFunctor&);
+  virtual void operator()(float);
+
+public:
+  // now for typehandle stuff
+  static TypeHandle get_class_type(void) {
+    return _type_handle;
+  }
+  static void init_type(void) {
+    LerpFunctor::init_type();
+    register_type(_type_handle, "qpPosHprScaleLerpFunctor",
+                  LerpFunctor::get_class_type());
+  }
+  virtual TypeHandle get_type(void) const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type(void) {
+    init_type();
+    return get_class_type();
+  }
+private:
+  static TypeHandle _type_handle;
+};
+
+////////////////////////////////////////////////////////////////////
+//       Class : qpColorScaleLerpFunctor
+// Description : Class for Lerping between color scales
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA qpColorScaleLerpFunctor : public LVecBase4fLerpFunctor {
+private:
+  qpNodePath _node_path;
+  bool _is_wrt;
+  qpNodePath _wrt_path;
+
+PUBLISHED:
+  qpColorScaleLerpFunctor(qpNodePath np, LVecBase4f start, LVecBase4f end)
+    : LVecBase4fLerpFunctor(start, end), _node_path(np), _is_wrt(false) {}
+  qpColorScaleLerpFunctor(qpNodePath np, float sr, float sg, float sb, float sa,
+                float er, float eg, float eb, float ea) : LVecBase4fLerpFunctor(LVecBase4f(sr, sg, sb, sa),
+                                                 LVecBase4f(er, eg, eb, ea)), _node_path(np), _is_wrt(false) {}
+  qpColorScaleLerpFunctor(qpNodePath np, LVecBase4f start, LVecBase4f end, qpNodePath wrt)
+    : LVecBase4fLerpFunctor(start, end), _node_path(np), _is_wrt(true),
+      _wrt_path(wrt) {}
+  qpColorScaleLerpFunctor(qpNodePath np, float sr, float sg, float sb, float sa, float er, float eg,
+                 float eb, float ea, qpNodePath wrt)
+    : LVecBase4fLerpFunctor(LVecBase4f(sr, sg, sb, sa), LVecBase4f(er, eg, eb, ea)),
+      _node_path(np), _is_wrt(true), _wrt_path(wrt) {}
+
+public:
+  qpColorScaleLerpFunctor(const qpColorScaleLerpFunctor&);
+  virtual ~qpColorScaleLerpFunctor(void);
+  qpColorScaleLerpFunctor& operator=(const qpColorScaleLerpFunctor&);
+  virtual void operator()(float);
+
+public:
+  // now for typehandle stuff
+  static TypeHandle get_class_type(void) {
+    return _type_handle;
+  }
+  static void init_type(void) {
+    LVecBase4fLerpFunctor::init_type();
+    register_type(_type_handle, "qpColorScaleLerpFunctor",
+                  LVecBase4fLerpFunctor::get_class_type());
+  }
+  virtual TypeHandle get_type(void) const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type(void) {
+    init_type();
+    return get_class_type();
+  }
+private:
+  static TypeHandle _type_handle;
+};
+
+#endif /* qpNODEPATHLERPS_H */
+
+
+
+
+