瀏覽代碼

*** empty log message ***

David Rose 25 年之前
父節點
當前提交
563ba074d8

+ 1 - 1
panda/src/collide/Sources.pp

@@ -4,7 +4,7 @@
 #begin lib_target
   #define TARGET collide
   #define LOCAL_LIBS \
-    light tform sgraphutil gobj graph putil
+    sgmanip light tform sgraphutil gobj graph putil
 
   #define SOURCES \
     collisionEntry.I collisionEntry.cxx collisionEntry.h \

+ 18 - 0
panda/src/collide/collisionEntry.I

@@ -86,12 +86,30 @@ get_from_space() const {
 //               that was collided into.  This returns a NamedNode
 //               pointer instead of something more specific, because
 //               it might be either a CollisionNode or a GeomNode.
+//
+//               Also see get_into_node_path().
 ////////////////////////////////////////////////////////////////////
 INLINE NamedNode *CollisionEntry::
 get_into_node() const {
   return _into_node;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionEntry::get_into_node_path
+//       Access: Public
+//  Description: Returns the NodePath that represents the specific
+//               CollisionNode or GeomNode instance that was collided
+//               into.  This is the same node returned by
+//               get_into_node(), represented as a NodePath; however,
+//               it may be more useful because the NodePath can
+//               resolve the particular instance of the node, if there
+//               is more than one.
+////////////////////////////////////////////////////////////////////
+INLINE const NodePath &CollisionEntry::
+get_into_node_path() const {
+  return _into_node_path;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionEntry::get_into_space
 //       Access: Public

+ 2 - 0
panda/src/collide/collisionEntry.cxx

@@ -18,6 +18,7 @@ CollisionEntry(const CollisionEntry &copy) :
   _into(copy._into),
   _from_node(copy._from_node),
   _into_node(copy._into_node),
+  _into_node_path(copy._into_node_path),
   _from_space(copy._from_space),
   _into_space(copy._into_space),
   _wrt_space(copy._wrt_space),
@@ -40,6 +41,7 @@ operator = (const CollisionEntry &copy) {
   _into = copy._into;
   _from_node = copy._from_node;
   _into_node = copy._into_node;
+  _into_node_path = copy._into_node_path;
   _from_space = copy._from_space;
   _into_space = copy._into_space;
   _wrt_space = copy._wrt_space;

+ 3 - 0
panda/src/collide/collisionEntry.h

@@ -15,6 +15,7 @@
 #include <luse.h>
 #include <pointerTo.h>
 #include <pt_NamedNode.h>
+#include <nodePath.h>
 
 ///////////////////////////////////////////////////////////////////
 // 	 Class : CollisionEntry
@@ -42,6 +43,7 @@ PUBLISHED:
 
   INLINE CollisionNode *get_from_node() const;
   INLINE NamedNode *get_into_node() const;
+  INLINE const NodePath &get_into_node_path() const;
 
   INLINE const LMatrix4f &get_from_space() const;
   INLINE const LMatrix4f &get_into_space() const;
@@ -69,6 +71,7 @@ private:
 
   PT(CollisionNode) _from_node;
   PT_NamedNode _into_node;
+  NodePath _into_node_path;
   LMatrix4f _from_space;
   LMatrix4f _into_space;
   LMatrix4f _wrt_space;

+ 63 - 0
panda/src/collide/collisionLevelState.I

@@ -3,6 +3,69 @@
 // 
 ////////////////////////////////////////////////////////////////////
 
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionLevelState::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE CollisionLevelState::
+CollisionLevelState(const ArcChain &arc_chain) :
+  _arc_chain(arc_chain)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionLevelState::Copy Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE CollisionLevelState::
+CollisionLevelState(const CollisionLevelState &copy) :
+  _arc_chain(copy._arc_chain),
+  _colliders(copy._colliders),
+  _current(copy._current),
+  _colliders_with_geom(copy._colliders_with_geom),
+  _local_bounds(copy._local_bounds)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionLevelState::Copy Assignment
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE void CollisionLevelState::
+operator = (const CollisionLevelState &copy) {
+  _arc_chain = copy._arc_chain;
+  _colliders = copy._colliders;
+  _current = copy._current;
+  _colliders_with_geom = copy._colliders_with_geom;
+  _local_bounds = copy._local_bounds;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionLevelState::forward_arc
+//       Access: Public
+//  Description: Records that we have traversed past another arc in
+//               the scene graph.
+////////////////////////////////////////////////////////////////////
+INLINE void CollisionLevelState::
+forward_arc(NodeRelation *arc) {
+  _arc_chain.push_back(arc);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionLevelState::get_arc_chain
+//       Access: Public
+//  Description: Returns the chain of arcs traversed from the top of
+//               the scene graph.
+////////////////////////////////////////////////////////////////////
+INLINE const ArcChain &CollisionLevelState::
+get_arc_chain() const {
+  return _arc_chain;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionLevelState::get_num_colliders
 //       Access: Public

+ 10 - 0
panda/src/collide/collisionLevelState.h

@@ -11,6 +11,7 @@
 #include <luse.h>
 #include <pointerToArray.h>
 #include <geometricBoundingVolume.h>
+#include <arcChain.h>
 
 #include <list>
 
@@ -33,11 +34,18 @@ public:
     LMatrix4f _inv_space;
   };
 
+  INLINE CollisionLevelState(const ArcChain &arc_chain);
+  INLINE CollisionLevelState(const CollisionLevelState &copy);
+  INLINE void operator = (const CollisionLevelState &copy);
+
   void clear();
   void reserve(int max_colliders);
   void prepare_collider(const ColliderDef &def);
   void xform(const LMatrix4f &mat);
 
+  INLINE void forward_arc(NodeRelation *arc);
+  INLINE const ArcChain &get_arc_chain() const;
+
   INLINE int get_num_colliders() const;
   INLINE bool has_collider(int n) const;
   INLINE bool has_collider_with_geom(int n) const;
@@ -59,6 +67,8 @@ private:
 
   INLINE ColliderMask get_mask(int n) const;
 
+  ArcChain _arc_chain;
+
   typedef PTA(ColliderDef) Colliders;
   Colliders _colliders;
   ColliderMask _current;

+ 20 - 5
panda/src/collide/collisionTraverser.cxx

@@ -16,6 +16,7 @@
 #include <pStatTimer.h>
 #include <geomNode.h>
 #include <geom.h>
+#include <nodePath.h>
 
 
 PStatCollector CollisionTraverser::_collisions_pcollector =
@@ -210,7 +211,6 @@ clear_colliders() {
 }
 
 
-
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::traverse
 //       Access: Public
@@ -218,9 +218,21 @@ clear_colliders() {
 ////////////////////////////////////////////////////////////////////
 void CollisionTraverser::
 traverse(Node *root) {
+  traverse(NodePath(root, _graph_type));
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionTraverser::traverse
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void CollisionTraverser::
+traverse(const NodePath &root) {
+  nassertv(root.get_graph_type() == _graph_type);
+
   PStatTimer timer(_collisions_pcollector);
 
-  CollisionLevelState level_state;
+  CollisionLevelState level_state(root);
   prepare_colliders(level_state);
 
   Handlers::iterator hi;
@@ -228,8 +240,8 @@ traverse(Node *root) {
     (*hi).first->begin_group();
   }
 
-  df_traverse(root, *this, NullAttributeWrapper(), level_state,
-	      _graph_type);
+  df_traverse(root.get_bottom_node(), *this, NullAttributeWrapper(), 
+	      level_state, _graph_type);
 
   for (hi = _handlers.begin(); hi != _handlers.end(); ++hi) {
     (*hi).first->end_group();
@@ -336,7 +348,8 @@ reached_node(Node *node, NullAttributeWrapper &,
 
     CollisionEntry entry;
     entry._into_node = cnode;
-    get_rel_mat(node, NULL, entry._into_space, _graph_type);
+    entry._into_node_path = NodePath(level_state.get_arc_chain(), _graph_type);
+    entry._into_space = entry._into_node_path.get_mat(NodePath());
 
     int num_colliders = level_state.get_num_colliders();
     for (int c = 0; c < num_colliders; c++) {
@@ -448,6 +461,8 @@ forward_arc(NodeRelation *arc, NullTransitionWrapper &,
     level_state.xform(inv_mat);
   }
 
+  level_state.forward_arc(arc);
+
   return true;
 }
 

+ 2 - 0
panda/src/collide/collisionTraverser.h

@@ -23,6 +23,7 @@
 
 class CollisionNode;
 class Geom;
+class NodePath;
 
 ////////////////////////////////////////////////////////////////////
 // 	 Class : CollisionTraverser
@@ -43,6 +44,7 @@ PUBLISHED:
   void clear_colliders();
 
   void traverse(Node *root);
+  void traverse(const NodePath &root);
 
   void output(ostream &out) const;
   void write(ostream &out, int indent_level = 0) const;

+ 1 - 1
panda/src/graph/arcChain.h

@@ -35,7 +35,7 @@
 //               wrt's).
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA ArcChain {
-private:
+protected:
   // We maintain our own linked list structure here instead of using
   // some STL structure, so we can efficiently copy-construct these
   // things by sharing the initial part of the list.

+ 2 - 1
panda/src/linmath/lmatrix3.I

@@ -733,7 +733,8 @@ invert_from(const LMatrix3<NumType> &other) {
   NumType d = other.determinant();
 
   if (IS_NEARLY_ZERO(d)) {
-    nout << "Tried to invert singular LMatrix3.\n";
+    linmath_cat.warning()
+      << "Tried to invert singular LMatrix3.\n";
     (*this) = ident_mat();
     return false;
   }

+ 2 - 1
panda/src/linmath/lmatrix4.I

@@ -887,7 +887,8 @@ invert_from(const LMatrix4<NumType> &other) {
   int index[4];
 
   if (!decompose_mat(index)) {
-    nout << "Tried to invert singular LMatrix4.\n";
+    linmath_cat.warning()
+      << "Tried to invert singular LMatrix4.\n";
     return false;
   }
   

+ 1 - 1
panda/src/particlesystem/particleSystem.cxx

@@ -340,7 +340,7 @@ resize_pool(int size) {
     if (po_delta > 0) {
       for (i = 0; i < po_delta; i++)
       {
-        int free_index = _physics_objects.size();
+	//        int free_index = _physics_objects.size();
 
         BaseParticle *new_particle = _factory->alloc_particle();
         if (new_particle) {

+ 4 - 3
panda/src/physics/linearCylinderVortexForce.cxx

@@ -16,8 +16,9 @@ TypeHandle LinearCylinderVortexForce::_type_handle;
 LinearCylinderVortexForce::
 LinearCylinderVortexForce(float radius, float length, float coef, 
 		    float a, bool md) :
-  _radius(radius), _length(length), _coef(coef), 
-  LinearForce(a, md) {
+  LinearForce(a, md),
+  _radius(radius), _length(length), _coef(coef)
+{
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -63,7 +64,7 @@ get_child_vector(const PhysicsObject *po) {
   // get the force-space transform- this MUST be the relative matrix
   // from the point's local coordinate system to the attached node's
   // local system.
-  LMatrix4f force_space_xform = LMatrix4f::ident_mat();
+  //  LMatrix4f force_space_xform = LMatrix4f::ident_mat();
   LVector3f force_vec(0.0f, 0.0f, 0.0f);
 
   // project the point into force_space

+ 3 - 2
panda/src/physics/linearDistanceForce.cxx

@@ -14,8 +14,9 @@ TypeHandle LinearDistanceForce::_type_handle;
 ////////////////////////////////////////////////////////////////////
 LinearDistanceForce::
 LinearDistanceForce(const LPoint3f& p, FalloffType ft, float r, float a, bool m) :
-  _falloff(ft), _radius(r), _force_center(p),
-  LinearForce(a, m) {
+  LinearForce(a, m),
+  _force_center(p), _falloff(ft), _radius(r)
+{
 }
 
 ////////////////////////////////////////////////////////////////////

+ 3 - 1
panda/src/physics/linearUserDefinedForce.cxx

@@ -15,7 +15,9 @@ TypeHandle LinearUserDefinedForce::_type_handle;
 LinearUserDefinedForce::
 LinearUserDefinedForce(LVector3f (*proc)(const PhysicsObject *),
 		 float a, bool md) :
-  _proc(proc), LinearForce(a, md) {
+  LinearForce(a, md), 
+  _proc(proc) 
+{
 }
 
 ////////////////////////////////////////////////////////////////////

+ 3 - 1
panda/src/physics/linearVectorForce.cxx

@@ -19,7 +19,9 @@ TypeHandle LinearVectorForce::_type_handle;
 ////////////////////////////////////////////////////////////////////
 LinearVectorForce::
 LinearVectorForce(const LVector3f& vec, float a, bool mass) : 
-  _fvec(vec), LinearForce(a, mass) {
+  LinearForce(a, mass),
+  _fvec(vec) 
+{
 }
 
 ////////////////////////////////////////////////////////////////////

+ 2 - 2
panda/src/physics/physical.I

@@ -175,7 +175,7 @@ get_num_linear_forces(void) const {
 ////////////////////////////////////////////////////////////////////
 INLINE PT(LinearForce) Physical::
 get_linear_force(int index) const {
-  nassertr(index >= 0 && index < _linear_forces.size(), NULL);
+  nassertr(index >= 0 && index < (int)_linear_forces.size(), NULL);
   return _linear_forces[index];
 }
 
@@ -194,6 +194,6 @@ get_num_angular_forces(void) const {
 ////////////////////////////////////////////////////////////////////
 INLINE PT(AngularForce) Physical::
 get_angular_force(int index) const {
-  nassertr(index >= 0 && index < _angular_forces.size(), NULL);
+  nassertr(index >= 0 && index < (int)_angular_forces.size(), NULL);
   return _angular_forces[index];
 }

+ 5 - 2
panda/src/physics/physicsObject.cxx

@@ -14,8 +14,11 @@ TypeHandle PhysicsObject::_type_handle;
 ////////////////////////////////////////////////////////////////////
 PhysicsObject::
 PhysicsObject(void) :
-  _process_me(false), _mass(1.0f), _oriented(true),
-  _terminal_velocity(_default_terminal_velocity) {
+  _terminal_velocity(_default_terminal_velocity),
+  _mass(1.0f),
+  _process_me(false),
+  _oriented(true)
+{
   _position.set(0, 0, 0);
   _last_position = _position;
   _velocity.set(0, 0, 0);

+ 21 - 66
panda/src/sgmanip/nodePath.I

@@ -101,13 +101,16 @@ NodePath(Node *top_node, TypeHandle graph_type) : NodePathBase(graph_type) {
 ////////////////////////////////////////////////////////////////////
 //     Function: NodePath::Constructor
 //       Access: Public
-//  Description: Creates a NodePath that contains two nodes and one
-//               arc: the top arc.
+//  Description: This constructor creates a new NodePath given an
+//               ArcChain, which is a more primitive version of a
+//               NodePath.  Some graph-traversal operations generate
+//               ArcChains, so it's useful to be able to use one of
+//               these to create a NodePath.
 ////////////////////////////////////////////////////////////////////
 INLINE NodePath::
-NodePath(NodeRelation *top_arc) : NodePathBase(top_arc->get_type()) {
-  _top_node = top_arc->get_parent();
-  _head = new ArcComponent(top_arc, NULL);
+NodePath(const ArcChain &chain, TypeHandle graph_type) :
+  NodePathBase(chain, graph_type)
+{
   nassertv(verify_connectivity());
 }
 
@@ -119,64 +122,6 @@ NodePath(NodeRelation *top_arc) : NodePathBase(top_arc->get_type()) {
 INLINE NodePath::
 NodePath(const NodePathBase &copy) : NodePathBase(copy) {
 }
-
-////////////////////////////////////////////////////////////////////
-//     Function: NodePath::Copy-and-shorten constructor
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE NodePath::
-NodePath(const NodePath &copy, int shorten_count) : NodePathBase(copy) {
-  shorten(shorten_count);
-  nassertv(verify_connectivity());
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: NodePath::Copy-and-extend constructor
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE NodePath::
-NodePath(const NodePath &copy, NodeRelation *arc) :
-  NodePathBase(copy) 
-{
-  nassertv(verify_connectivity());
-  if (!extend_by(arc)) {
-    clear();
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: NodePath::Copy-and-extend-down constructor
-//       Access: Public
-//  Description: This implicitly does an extend_down_to() on the
-//               indicated node, so that it is not necessary that the
-//               node be an immediate child of the path.
-////////////////////////////////////////////////////////////////////
-INLINE NodePath::
-NodePath(const NodePath &copy, Node *node) :
-  NodePathBase(copy) 
-{
-  nassertv(verify_connectivity());
-  if (!extend_down_to(node)) {
-    clear();
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: NodePath::Copy-and-extend constructor
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE NodePath::
-NodePath(const NodePath &copy, const string &path) :
-  NodePathBase(copy) 
-{
-  nassertv(verify_connectivity());
-  if (!extend_by(path)) {
-    clear();
-  }
-}
   
 ////////////////////////////////////////////////////////////////////
 //     Function: NodePath::Copy Assignment Operator
@@ -412,7 +357,9 @@ get_child(int n) const {
   nassertr(!is_empty(), NodePath());
   nassertr(n >= 0 && n < get_num_children(), NodePath());
 
-  return NodePath(*this, get_bottom_node()->get_child(_graph_type, n));
+  NodePath result(*this);
+  result.extend_by(get_bottom_node()->get_child(_graph_type, n));
+  return result;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -451,7 +398,11 @@ get_parent() const {
 ////////////////////////////////////////////////////////////////////
 INLINE NodePath NodePath::
 find_path_down_to(Node *node) const {
-  return NodePath(*this, node);
+  NodePath result(*this);
+  if (result.extend_down_to(node)) {
+    return result;
+  }
+  return NodePath();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -464,7 +415,11 @@ find_path_down_to(Node *node) const {
 ////////////////////////////////////////////////////////////////////
 INLINE NodePath NodePath::
 find(const string &path) const {
-  return NodePath(*this, path);
+  NodePath result(*this);
+  if (result.extend_by(path)) {
+    return result;
+  }
+  return NodePath();
 }
 
 ////////////////////////////////////////////////////////////////////

+ 16 - 7
panda/src/sgmanip/nodePath.cxx

@@ -272,7 +272,9 @@ get_children() const {
     DownRelationPointers::const_iterator drpi;
     for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
       NodeRelation *arc = (*drpi);
-      result.add_path(NodePath(*this, arc));
+      NodePath child(*this);
+      child.extend_by(arc);
+      result.add_path(child);
     }
   }
 
@@ -306,7 +308,9 @@ get_siblings() const {
     for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
       NodeRelation *arc = (*drpi);
       if (arc != my_arc) {
-	result.add_path(NodePath(parent, arc));
+	NodePath sib(parent);
+	sib.extend_by(arc);
+	result.add_path(sib);
       }
     }
   }
@@ -1747,7 +1751,8 @@ look_at(const NodePath &other, const LPoint3f &point, const LVector3f &up) {
 
   LPoint3f pos = get_pos();
 
-  NodePath parent(*this, 1);
+  NodePath parent(*this);
+  parent.shorten(1);
   LPoint3f rel_point = point * other.get_mat(parent);
 
   LMatrix4f mat;
@@ -1770,7 +1775,8 @@ heads_up(const NodePath &other, const LPoint3f &point, const LVector3f &up) {
 
   LPoint3f pos = get_pos();
 
-  NodePath parent(*this, 1);
+  NodePath parent(*this);
+  parent.shorten(1);
   LPoint3f rel_point = point * other.get_mat(parent);
 
   LMatrix4f mat;
@@ -2268,7 +2274,8 @@ get_bounds() const {
     // matrix.  We'd rather return a bounding volume in the node's
     // space, so we have to untransform it now.  Ick.
     GeometricBoundingVolume *gbv = DCAST(GeometricBoundingVolume, bv);
-    NodePath parent(*this, 1);
+    NodePath parent(*this);
+    parent.shorten(1);
     LMatrix4f mat = parent.get_mat(*this);
     gbv->xform(mat);
   }
@@ -2564,7 +2571,8 @@ r_list_descendants(ostream &out, int indent_level) const {
     DownRelationPointers::const_iterator drpi;
     for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
       NodeRelation *arc = (*drpi);
-      NodePath next(*this, arc);
+      NodePath next(*this);
+      next.extend_by(arc);
       next.r_list_descendants(out, indent_level + 2);
     }
   }
@@ -2591,7 +2599,8 @@ r_list_transitions(ostream &out, int indent_level) const {
     DownRelationPointers::const_iterator drpi;
     for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
       NodeRelation *arc = (*drpi);
-      NodePath next(*this, arc);
+      NodePath next(*this);
+      next.extend_by(arc);
 
       indent(out, indent_level + 2) << *arc << ":\n";
       arc->write_transitions(out, indent_level + 2);

+ 2 - 5
panda/src/sgmanip/nodePath.h

@@ -100,12 +100,9 @@ class EXPCL_PANDA NodePath : public NodePathBase {
 PUBLISHED:
   INLINE NodePath(TypeHandle graph_type = RenderRelation::get_class_type());
   INLINE NodePath(Node *top_node, TypeHandle graph_type = RenderRelation::get_class_type());
-  INLINE NodePath(NodeRelation *top_arc);
+  INLINE NodePath(const ArcChain &chain, TypeHandle graph_type);
+
   INLINE NodePath(const NodePathBase &copy);
-  INLINE NodePath(const NodePath &copy, int shorten_count);
-  INLINE NodePath(const NodePath &copy, NodeRelation *arc);
-  INLINE NodePath(const NodePath &copy, Node *node);
-  INLINE NodePath(const NodePath &copy, const string &path);
   INLINE void operator = (const NodePath &copy);
   INLINE ~NodePath();
 

+ 13 - 9
panda/src/sgmanip/nodePathBase.I

@@ -5,24 +5,28 @@
 
 
 ////////////////////////////////////////////////////////////////////
-//     Function: NodePathBase::ArcComponent::Constructor
+//     Function: NodePathBase::Constructor
 //       Access: Public
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-INLINE NodePathBase::ArcComponent::
-ArcComponent(NodeRelation *arc, ArcComponent *next) :
-  _arc(arc),
-  _next(next)
+INLINE NodePathBase::
+NodePathBase(TypeHandle graph_type) :
+  _graph_type(graph_type)
 {
 }
 
 ////////////////////////////////////////////////////////////////////
 //     Function: NodePathBase::Constructor
 //       Access: Public
-//  Description: 
+//  Description: This constructor creates a new NodePathBase given an
+//               ArcChain, which is a more primitive version of a
+//               NodePath.  Some graph-traversal operations generate
+//               ArcChains, so it's useful to be able to use one of
+//               these to create a NodePath.
 ////////////////////////////////////////////////////////////////////
 INLINE NodePathBase::
-NodePathBase(TypeHandle graph_type) :
+NodePathBase(const ArcChain &chain, TypeHandle graph_type) :
+  ArcChain(chain),
   _graph_type(graph_type)
 {
 }
@@ -34,7 +38,7 @@ NodePathBase(TypeHandle graph_type) :
 ////////////////////////////////////////////////////////////////////
 INLINE NodePathBase::
 NodePathBase(const NodePathBase &copy) :
-  _head(copy._head),
+  ArcChain(copy),
   _top_node(copy._top_node),
   _graph_type(copy._graph_type)
 {
@@ -47,7 +51,7 @@ NodePathBase(const NodePathBase &copy) :
 ////////////////////////////////////////////////////////////////////
 INLINE void NodePathBase::
 operator = (const NodePathBase &copy) {
-  _head = copy._head;
+  ArcChain::operator = (copy);
   _top_node = copy._top_node;
   _graph_type = copy._graph_type;
 }

+ 8 - 26
panda/src/sgmanip/nodePathBase.h

@@ -10,13 +10,9 @@
 
 #include <node.h>
 #include <pt_Node.h>
-#include <nodeRelation.h>
-#include <pointerTo.h>
-#include <referenceCount.h>
+#include <arcChain.h>
 #include <renderRelation.h>
 
-#include <vector>
-
 ////////////////////////////////////////////////////////////////////
 //       Class : NodePathBase
 // Description : This is the base class for NodePath so we can defined
@@ -25,33 +21,19 @@
 //               level; this just defines the things that are stored
 //               here.
 ////////////////////////////////////////////////////////////////////
-class EXPCL_PANDA NodePathBase {
+class EXPCL_PANDA NodePathBase : public ArcChain {
 public:
   INLINE NodePathBase(TypeHandle graph_type = RenderRelation::get_class_type());
+  INLINE NodePathBase(const ArcChain &chain, TypeHandle graph_type);
   INLINE NodePathBase(const NodePathBase &copy);
   INLINE void operator = (const NodePathBase &copy);
 
 protected:
-  // We maintain our own linked list structure here instead of using
-  // some STL structure, so we can efficiently copy-construct these
-  // things by sharing the initial part of the list.
-
-  // We have a singly-linked list whose head is the bottom arc of the
-  // path, and whose tail is the top arc of the path.  Thus, we can
-  // copy the entire path by simply copying the head pointer, and we
-  // can then append to or shorten our own path without affecting the
-  // paths we're sharing ArcComponents with.  Very LISPy.
-  class ArcComponent : public ReferenceCount {
-  public:
-    INLINE ArcComponent(NodeRelation *arc, ArcComponent *next);
-    PT(NodeRelation) _arc;
-    PT(ArcComponent) _next;
-  };
-
-  PT(ArcComponent) _head;
-
-  // This is only used when the NodePath is a singleton.  If there is
-  // at least one arc, this is ignored.
+  // Most of the interesting part of NodePathBase is inherited from
+  // ArcChain.  This gives us a sharable linked list of arcs.
+
+  // The _top_node pointer is only used when the NodePath is a
+  // singleton.  If there is at least one arc, this is ignored.
   PT_Node _top_node;
 
   TypeHandle _graph_type;

+ 7 - 7
panda/src/sgmanip/nodePathLerps.cxx

@@ -15,7 +15,7 @@ TypeHandle ColorScaleLerpFunctor::_type_handle;
 
 
 PosLerpFunctor::PosLerpFunctor(const PosLerpFunctor& c)
-  : _node_path(c._node_path), LPoint3fLerpFunctor(c) {}
+  : LPoint3fLerpFunctor(c), _node_path(c._node_path) {}
 
 PosLerpFunctor::~PosLerpFunctor(void)
 {
@@ -35,7 +35,7 @@ void PosLerpFunctor::operator()(float t) {
 }
 
 HprLerpFunctor::HprLerpFunctor(const HprLerpFunctor& c)
-  : _node_path(c._node_path), LVecBase3fLerpFunctor(c) {}
+  : LVecBase3fLerpFunctor(c), _node_path(c._node_path) {}
 
 HprLerpFunctor::~HprLerpFunctor(void)
 {
@@ -55,7 +55,7 @@ void HprLerpFunctor::operator()(float t) {
 }
 
 ScaleLerpFunctor::ScaleLerpFunctor(const ScaleLerpFunctor& c)
-  : _node_path(c._node_path), LVecBase3fLerpFunctor(c) {}
+  : LVecBase3fLerpFunctor(c), _node_path(c._node_path) {}
 
 ScaleLerpFunctor::~ScaleLerpFunctor(void)
 {
@@ -75,7 +75,7 @@ void ScaleLerpFunctor::operator()(float t) {
 }
 
 ColorLerpFunctor::ColorLerpFunctor(const ColorLerpFunctor& c)
-  : _node_path(c._node_path), LVecBase4fLerpFunctor(c) {}
+  : LVecBase4fLerpFunctor(c), _node_path(c._node_path) {}
 
 ColorLerpFunctor::~ColorLerpFunctor(void)
 {
@@ -93,7 +93,7 @@ void ColorLerpFunctor::operator()(float t) {
 
 
 PosHprLerpFunctor::PosHprLerpFunctor(const PosHprLerpFunctor& c)
-  : _node_path(c._node_path), LerpFunctor(c) {}
+  : LerpFunctor(c), _node_path(c._node_path) {}
 
 PosHprLerpFunctor::~PosHprLerpFunctor(void)
 {
@@ -121,7 +121,7 @@ void PosHprLerpFunctor::operator()(float t) {
 }
 
 PosHprScaleLerpFunctor::PosHprScaleLerpFunctor(const PosHprScaleLerpFunctor& c)
-  : _node_path(c._node_path), LerpFunctor(c) {}
+  : LerpFunctor(c), _node_path(c._node_path) {}
 
 PosHprScaleLerpFunctor::~PosHprScaleLerpFunctor(void)
 {
@@ -154,7 +154,7 @@ void PosHprScaleLerpFunctor::operator()(float t) {
 }
 
 ColorScaleLerpFunctor::ColorScaleLerpFunctor(const ColorScaleLerpFunctor& c)
-  : _node_path(c._node_path), LVecBase4fLerpFunctor(c) {}
+  : LVecBase4fLerpFunctor(c), _node_path(c._node_path) {}
 
 ColorScaleLerpFunctor::~ColorScaleLerpFunctor(void)
 {

+ 7 - 7
panda/src/sgmanip/nodePathLerps.h

@@ -16,8 +16,8 @@
 class EXPCL_PANDA PosLerpFunctor : public LPoint3fLerpFunctor {
 private:
   NodePath _node_path;
-  NodePath _wrt_path;
   bool _is_wrt;
+  NodePath _wrt_path;
 
 PUBLISHED:
   PosLerpFunctor(NodePath np, LPoint3f start, LPoint3f end)
@@ -70,8 +70,8 @@ private:
 class EXPCL_PANDA HprLerpFunctor : public LVecBase3fLerpFunctor {
 private:
   NodePath _node_path;
-  NodePath _wrt_path;
   bool _is_wrt;
+  NodePath _wrt_path;
 
 PUBLISHED:
   HprLerpFunctor(NodePath np, LVecBase3f start, LVecBase3f end)
@@ -122,8 +122,8 @@ private:
 class EXPCL_PANDA ScaleLerpFunctor : public LVecBase3fLerpFunctor {
 private:
   NodePath _node_path;
-  NodePath _wrt_path;
   bool _is_wrt;
+  NodePath _wrt_path;
 
 PUBLISHED:
   ScaleLerpFunctor(NodePath np, LVecBase3f start, LVecBase3f end)
@@ -174,8 +174,8 @@ private:
 class EXPCL_PANDA ColorLerpFunctor : public LVecBase4fLerpFunctor {
 private:
   NodePath _node_path;
-  NodePath _wrt_path;
   bool _is_wrt;
+  NodePath _wrt_path;
 
 PUBLISHED:
   ColorLerpFunctor(NodePath np, LVecBase4f start, LVecBase4f end)
@@ -232,8 +232,8 @@ private:
   LVecBase3f _hstart;
   LVecBase3f _hend;
   LVecBase3f _hdiff_cache;
-  NodePath _wrt_path;
   bool _is_wrt;
+  NodePath _wrt_path;
 
 PUBLISHED:
   PosHprLerpFunctor(NodePath np, LPoint3f pstart, LPoint3f pend,
@@ -305,8 +305,8 @@ private:
   LVecBase3f _sstart;
   LVecBase3f _send;
   LVecBase3f _sdiff_cache;
-  NodePath _wrt_path;
   bool _is_wrt;
+  NodePath _wrt_path;
 
 PUBLISHED:
   PosHprScaleLerpFunctor(NodePath np, LPoint3f pstart, LPoint3f pend,
@@ -378,8 +378,8 @@ private:
 class EXPCL_PANDA ColorScaleLerpFunctor : public LVecBase4fLerpFunctor {
 private:
   NodePath _node_path;
-  NodePath _wrt_path;
   bool _is_wrt;
+  NodePath _wrt_path;
 
 PUBLISHED:
   ColorScaleLerpFunctor(NodePath np, LVecBase4f start, LVecBase4f end)

+ 2 - 2
panda/src/testbed/demo.cxx

@@ -474,7 +474,7 @@ event_v(CPT_Event) {
   attach_sky();
 
   NodePath search(sky);
-  NodePath sky_search(search, "**/sun");
+  NodePath sky_search = search.find("**/sun");
 
   if (!is_color_scale) {
     sky_search.set_color_scale(1, 0.5, 0.5, 0.5);
@@ -536,7 +536,7 @@ event_L(CPT_Event) {
     flare->set_flare_falloff(45);
 
     NodePath search(sky);
-    NodePath sky_search(search, "**/sun");
+    NodePath sky_search = search.find("**/sun");
     PT_Node light = sky_search.get_bottom_node();
 
     flare->set_light_source(light);