mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
pgraph NodePath
This commit is contained in:
parent
533f6043ca
commit
c7d0e2d117
@ -108,7 +108,7 @@ get_camera() const {
|
||||
// Description: Returns the camera associated with this
|
||||
// DisplayRegion, or NULL if no camera is associated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const NodeChain &DisplayRegion::
|
||||
INLINE const qpNodePath &DisplayRegion::
|
||||
get_qpcamera() const {
|
||||
return _qpcamera;
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ operator = (const DisplayRegion&) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DisplayRegion::
|
||||
~DisplayRegion() {
|
||||
set_qpcamera(NodeChain());
|
||||
set_qpcamera(qpNodePath());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -193,12 +193,12 @@ set_camera(Camera *camera) {
|
||||
// was already associated with a different
|
||||
// DisplayRegion, that association is removed.
|
||||
//
|
||||
// The camera is actually set via a NodeChain, which
|
||||
// The camera is actually set via a qpNodePath, which
|
||||
// clarifies which instance of the camera (if there
|
||||
// happen to be multiple instances) we should use.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DisplayRegion::
|
||||
set_qpcamera(const NodeChain &camera) {
|
||||
set_qpcamera(const qpNodePath &camera) {
|
||||
qpCamera *camera_node = (qpCamera *)NULL;
|
||||
if (!camera.is_empty()) {
|
||||
DCAST_INTO_V(camera_node, camera.node());
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#include "referenceCount.h"
|
||||
#include "camera.h"
|
||||
#include "nodeChain.h"
|
||||
#include "qpnodePath.h"
|
||||
#include "cullResult.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
@ -69,8 +69,8 @@ PUBLISHED:
|
||||
void set_camera(Camera *camera);
|
||||
INLINE Camera *get_camera() const;
|
||||
|
||||
void set_qpcamera(const NodeChain &camera);
|
||||
INLINE const NodeChain &get_qpcamera() const;
|
||||
void set_qpcamera(const qpNodePath &camera);
|
||||
INLINE const qpNodePath &get_qpcamera() const;
|
||||
|
||||
INLINE void set_cull_frustum(LensNode *cull_frustum);
|
||||
INLINE LensNode *get_cull_frustum() const;
|
||||
@ -104,7 +104,7 @@ protected:
|
||||
|
||||
GraphicsLayer *_layer;
|
||||
PT(Camera) _camera;
|
||||
NodeChain _qpcamera;
|
||||
qpNodePath _qpcamera;
|
||||
qpCamera *_camera_node;
|
||||
PT(LensNode) _cull_frustum;
|
||||
|
||||
|
@ -197,7 +197,7 @@ cull_bin_draw(GraphicsWindow *win, DisplayRegion *dr) {
|
||||
// Description: Fires off a cull traversal using the indicated camera.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsEngine::
|
||||
do_cull(CullHandler *cull_handler, const NodeChain &camera,
|
||||
do_cull(CullHandler *cull_handler, const qpNodePath &camera,
|
||||
GraphicsStateGuardian *gsg) {
|
||||
if (camera.is_empty()) {
|
||||
// No camera, no draw.
|
||||
@ -218,7 +218,7 @@ do_cull(CullHandler *cull_handler, const NodeChain &camera,
|
||||
return;
|
||||
}
|
||||
|
||||
NodeChain scene = camera_node->get_scene();
|
||||
qpNodePath scene = camera_node->get_scene();
|
||||
if (scene.is_empty()) {
|
||||
// No scene, no draw.
|
||||
return;
|
||||
@ -298,7 +298,7 @@ do_draw(CullResult *cull_result, GraphicsStateGuardian *gsg,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsEngine::
|
||||
set_gsg_lens(GraphicsStateGuardian *gsg, DisplayRegion *dr) {
|
||||
const NodeChain &camera = dr->get_qpcamera();
|
||||
const qpNodePath &camera = dr->get_qpcamera();
|
||||
if (camera.is_empty()) {
|
||||
// No camera, no draw.
|
||||
return false;
|
||||
|
@ -57,7 +57,7 @@ private:
|
||||
void cull_bin_draw();
|
||||
void cull_bin_draw(GraphicsWindow *win, DisplayRegion *dr);
|
||||
|
||||
void do_cull(CullHandler *cull_handler, const NodeChain &camera,
|
||||
void do_cull(CullHandler *cull_handler, const qpNodePath &camera,
|
||||
GraphicsStateGuardian *gsg);
|
||||
void do_draw(CullResult *cull_result, GraphicsStateGuardian *gsg,
|
||||
DisplayRegion *dr);
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include "qpeggLoader.h"
|
||||
#include "config_egg2pg.h"
|
||||
#include "nodeChain.h"
|
||||
#include "qpnodePath.h"
|
||||
#include "renderState.h"
|
||||
#include "transformState.h"
|
||||
#include "textureAttrib.h"
|
||||
@ -154,14 +154,14 @@ reparent_decals() {
|
||||
PandaNode *node = (*di);
|
||||
nassertv(node != (PandaNode *)NULL);
|
||||
|
||||
// The NodeChain interface is best for this.
|
||||
NodeChain parent(node);
|
||||
// The qpNodePath interface is best for this.
|
||||
qpNodePath parent(node);
|
||||
|
||||
// First, search for the GeomNode.
|
||||
NodeChain geom_parent;
|
||||
qpNodePath geom_parent;
|
||||
int num_children = parent.get_num_children();
|
||||
for (int i = 0; i < num_children; i++) {
|
||||
NodeChain child = parent.get_child(i);
|
||||
qpNodePath child = parent.get_child(i);
|
||||
|
||||
if (child.node()->is_of_type(qpGeomNode::get_class_type())) {
|
||||
if (!geom_parent.is_empty()) {
|
||||
@ -187,7 +187,7 @@ reparent_decals() {
|
||||
// list.
|
||||
int i = 0;
|
||||
while (i < num_children) {
|
||||
NodeChain child = parent.get_child(i);
|
||||
qpNodePath child = parent.get_child(i);
|
||||
|
||||
if (child.node()->is_of_type(qpGeomNode::get_class_type())) {
|
||||
i++;
|
||||
|
@ -31,8 +31,9 @@
|
||||
qplensNode.h qplensNode.I \
|
||||
qplodNode.h qplodNode.I \
|
||||
materialAttrib.h materialAttrib.I \
|
||||
nodeChain.h nodeChain.I \
|
||||
nodeChainComponent.h nodeChainComponent.I \
|
||||
qpnodePath.h qpnodePath.I \
|
||||
qpnodePathCollection.h qpnodePathCollection.I \
|
||||
qpnodePathComponent.h qpnodePathComponent.I \
|
||||
pandaNode.h pandaNode.I \
|
||||
renderAttrib.h renderAttrib.I \
|
||||
renderState.h renderState.I \
|
||||
@ -70,8 +71,9 @@
|
||||
qplensNode.cxx \
|
||||
qplodNode.cxx \
|
||||
materialAttrib.cxx \
|
||||
nodeChain.cxx \
|
||||
nodeChainComponent.cxx \
|
||||
qpnodePath.cxx \
|
||||
qpnodePathCollection.cxx \
|
||||
qpnodePathComponent.cxx \
|
||||
pandaNode.cxx \
|
||||
renderAttrib.cxx \
|
||||
renderState.cxx \
|
||||
@ -114,8 +116,9 @@
|
||||
qplensNode.h qplensNode.I \
|
||||
qplodNode.h qplodNode.I \
|
||||
materialAttrib.h materialAttrib.I \
|
||||
nodeChain.h nodeChain.I \
|
||||
nodeChainComponent.h nodeChainComponent.I \
|
||||
qpnodePath.h qpnodePath.I \
|
||||
qpnodePathCollection.h qpnodePathCollection.I \
|
||||
qpnodePathComponent.h qpnodePathComponent.I \
|
||||
pandaNode.h pandaNode.I \
|
||||
renderAttrib.h renderAttrib.I \
|
||||
renderState.h renderState.I \
|
||||
|
@ -37,7 +37,7 @@ BillboardAttrib() {
|
||||
INLINE CPT(RenderAttrib) BillboardAttrib::
|
||||
make_axis() {
|
||||
return make(LVector3f::up(), false, true,
|
||||
0.0f, NodeChain(), LPoint3f(0.0f, 0.0f, 0.0f));
|
||||
0.0f, qpNodePath(), LPoint3f(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -49,7 +49,7 @@ make_axis() {
|
||||
INLINE CPT(RenderAttrib) BillboardAttrib::
|
||||
make_point_eye() {
|
||||
return make(LVector3f::up(), true, false,
|
||||
0.0f, NodeChain(), LPoint3f(0.0f, 0.0f, 0.0f));
|
||||
0.0f, qpNodePath(), LPoint3f(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -61,7 +61,7 @@ make_point_eye() {
|
||||
INLINE CPT(RenderAttrib) BillboardAttrib::
|
||||
make_point_world() {
|
||||
return make(LVector3f::up(), false, false,
|
||||
0.0f, NodeChain(), LPoint3f(0.0f, 0.0f, 0.0f));
|
||||
0.0f, qpNodePath(), LPoint3f(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -73,7 +73,7 @@ make_point_world() {
|
||||
// particularly useful and isn't normally created or
|
||||
// stored in the graph; it might be implicitly
|
||||
// discovered as the result of a
|
||||
// NodeChain::get_rel_state().
|
||||
// qpNodePath::get_rel_state().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool BillboardAttrib::
|
||||
is_off() const {
|
||||
@ -135,7 +135,7 @@ get_offset() const {
|
||||
// will rotate towards the current camera node, wherever
|
||||
// that might be.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const NodeChain &BillboardAttrib::
|
||||
INLINE const qpNodePath &BillboardAttrib::
|
||||
get_look_at() const {
|
||||
return _look_at;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ TypeHandle BillboardAttrib::_type_handle;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) BillboardAttrib::
|
||||
make(const LVector3f &up_vector, bool eye_relative,
|
||||
bool axial_rotate, float offset, const NodeChain &look_at,
|
||||
bool axial_rotate, float offset, const qpNodePath &look_at,
|
||||
const LPoint3f &look_at_point) {
|
||||
BillboardAttrib *attrib = new BillboardAttrib;
|
||||
attrib->_up_vector = up_vector;
|
||||
@ -228,7 +228,7 @@ write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
dg.add_float32(_offset);
|
||||
_look_at_point.write_datagram(dg);
|
||||
|
||||
// *** We don't write out the _look_at NodeChain right now. Maybe
|
||||
// *** We don't write out the _look_at qpNodePath right now. Maybe
|
||||
// we should.
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#include "renderAttrib.h"
|
||||
#include "luse.h"
|
||||
#include "nodeChain.h"
|
||||
#include "qpnodePath.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : BillboardAttrib
|
||||
@ -40,7 +40,7 @@ PUBLISHED:
|
||||
bool eye_relative,
|
||||
bool axial_rotate,
|
||||
float offset,
|
||||
const NodeChain &look_at,
|
||||
const qpNodePath &look_at,
|
||||
const LPoint3f &look_at_point);
|
||||
INLINE static CPT(RenderAttrib) make_axis();
|
||||
INLINE static CPT(RenderAttrib) make_point_eye();
|
||||
@ -51,7 +51,7 @@ PUBLISHED:
|
||||
INLINE bool get_eye_relative() const;
|
||||
INLINE bool get_axial_rotate() const;
|
||||
INLINE float get_offset() const;
|
||||
INLINE const NodeChain &get_look_at() const;
|
||||
INLINE const qpNodePath &get_look_at() const;
|
||||
INLINE const LPoint3f &get_look_at_point() const;
|
||||
|
||||
public:
|
||||
@ -70,7 +70,7 @@ private:
|
||||
bool _eye_relative;
|
||||
bool _axial_rotate;
|
||||
float _offset;
|
||||
NodeChain _look_at;
|
||||
qpNodePath _look_at;
|
||||
LPoint3f _look_at_point;
|
||||
|
||||
public:
|
||||
|
@ -35,8 +35,8 @@
|
||||
#include "qplensNode.h"
|
||||
#include "qplodNode.h"
|
||||
#include "materialAttrib.h"
|
||||
#include "nodeChain.h"
|
||||
#include "nodeChainComponent.h"
|
||||
#include "qpnodePath.h"
|
||||
#include "qpnodePathComponent.h"
|
||||
#include "pandaNode.h"
|
||||
#include "renderAttrib.h"
|
||||
#include "renderState.h"
|
||||
@ -95,8 +95,8 @@ init_libpgraph() {
|
||||
qpLensNode::init_type();
|
||||
qpLODNode::init_type();
|
||||
MaterialAttrib::init_type();
|
||||
NodeChain::init_type();
|
||||
NodeChainComponent::init_type();
|
||||
qpNodePath::init_type();
|
||||
qpNodePathComponent::init_type();
|
||||
PandaNode::init_type();
|
||||
RenderAttrib::init_type();
|
||||
RenderState::init_type();
|
||||
|
@ -36,7 +36,7 @@ private:
|
||||
INLINE MaterialAttrib();
|
||||
|
||||
PUBLISHED:
|
||||
static CPT(RenderAttrib) make(const Material *tex);
|
||||
static CPT(RenderAttrib) make(const Material *material);
|
||||
static CPT(RenderAttrib) make_off();
|
||||
|
||||
INLINE bool is_off() const;
|
||||
|
@ -1,348 +0,0 @@
|
||||
// Filename: nodeChain.I
|
||||
// Created by: drose (25Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::Default Constructor
|
||||
// Access: Published
|
||||
// Description: This constructs an empty NodeChain with no nodes. It
|
||||
// cannot be extended, since you cannot add nodes without
|
||||
// first specifying the top node. Use the constructor
|
||||
// that receives a node if you ever want to do anything
|
||||
// with this chain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChain::
|
||||
NodeChain() :
|
||||
_error_type(ET_ok)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::Constructor
|
||||
// Access: Published
|
||||
// Description: This constructs an empty NodeChain with a single node.
|
||||
// This chain may now be extended by repeatedly calling
|
||||
// push_back() with each node below that node in
|
||||
// sequence.
|
||||
//
|
||||
// If the Node pointer is NULL, this quietly creates an
|
||||
// empty NodeChain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChain::
|
||||
NodeChain(PandaNode *top_node) :
|
||||
_error_type(ET_ok)
|
||||
{
|
||||
if (top_node != (PandaNode *)NULL) {
|
||||
_head = top_node->get_generic_component();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChain::
|
||||
NodeChain(const NodeChain ©) :
|
||||
_head(copy._head),
|
||||
_error_type(copy._error_type)
|
||||
{
|
||||
uncollapse_head();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodeChain::
|
||||
operator = (const NodeChain ©) {
|
||||
_head = copy._head;
|
||||
_error_type = copy._error_type;
|
||||
uncollapse_head();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::not_found named constructor
|
||||
// Access: Published, Static
|
||||
// Description: Creates a NodeChain with the ET_not_found error type
|
||||
// set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChain NodeChain::
|
||||
not_found() {
|
||||
NodeChain result;
|
||||
result._error_type = ET_not_found;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::removed named constructor
|
||||
// Access: Published, Static
|
||||
// Description: Creates a NodeChain with the ET_removed error type
|
||||
// set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChain NodeChain::
|
||||
removed() {
|
||||
NodeChain result;
|
||||
result._error_type = ET_removed;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::fail named constructor
|
||||
// Access: Published, Static
|
||||
// Description: Creates a NodeChain with the ET_fail error type
|
||||
// set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChain NodeChain::
|
||||
fail() {
|
||||
NodeChain result;
|
||||
result._error_type = ET_fail;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::is_empty
|
||||
// Access: Published
|
||||
// Description: Returns true if the NodeChain contains no nodes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodeChain::
|
||||
is_empty() const {
|
||||
return (_head == (NodeChainComponent *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::is_singleton
|
||||
// Access: Published
|
||||
// Description: Returns true if the NodeChain contains exactly one
|
||||
// node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodeChain::
|
||||
is_singleton() const {
|
||||
uncollapse_head();
|
||||
return (_head != (NodeChainComponent *)NULL && _head->is_top_node());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::get_error_type
|
||||
// Access: Published
|
||||
// Description: If is_empty() is true, this returns a code that
|
||||
// represents the reason why the NodeChain is empty.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChain::ErrorType NodeChain::
|
||||
get_error_type() const {
|
||||
return _error_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::node
|
||||
// Access: Published
|
||||
// Description: Returns the bottom node of the path, or NULL if the
|
||||
// path is empty.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *NodeChain::
|
||||
node() const {
|
||||
if (is_empty()) {
|
||||
return (PandaNode *)NULL;
|
||||
}
|
||||
return _head->get_node();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::get_num_children
|
||||
// Access: Published
|
||||
// Description: Returns the number of children of the bottom node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int NodeChain::
|
||||
get_num_children() const {
|
||||
nassertr(!is_empty(), 0);
|
||||
return _head->get_node()->get_num_children();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::get_child
|
||||
// Access: Published
|
||||
// Description: Returns a NodeChain representing the nth child of the
|
||||
// bottom node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChain NodeChain::
|
||||
get_child(int n) const {
|
||||
nassertr(n >= 0 && n < get_num_children(), NodeChain());
|
||||
NodeChain child;
|
||||
child._head = PandaNode::get_component(_head, _head->get_node()->get_child(n));
|
||||
return child;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::has_parent
|
||||
// Access: Published
|
||||
// Description: Returns true if the node at the bottom of the
|
||||
// NodeChain has a parent; i.e. the NodeChain contains at
|
||||
// least two nodes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodeChain::
|
||||
has_parent() const {
|
||||
return !is_empty() && !is_singleton();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::get_parent
|
||||
// Access: Published
|
||||
// Description: Returns the NodeChain to the parent of the bottom
|
||||
// node: that is, this NodeChain, shortened by one node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChain NodeChain::
|
||||
get_parent() const {
|
||||
nassertr(has_parent(), NodeChain::fail());
|
||||
NodeChain parent;
|
||||
parent._head = _head->get_next();
|
||||
return parent;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::attach_new_node
|
||||
// Access: Published
|
||||
// Description: Creates an ordinary PandaNode and attaches it below
|
||||
// the current NodeChain, returning a new NodeChain that
|
||||
// references it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChain NodeChain::
|
||||
attach_new_node(const string &name, int sort) const {
|
||||
nassertr(verify_complete(), NodeChain::fail());
|
||||
nassertr(!is_empty(), *this);
|
||||
|
||||
return attach_new_node(new PandaNode(name), sort);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::get_net_state
|
||||
// Access: Published
|
||||
// Description: Returns the net state on this node from the root.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(RenderState) NodeChain::
|
||||
get_net_state() const {
|
||||
uncollapse_head();
|
||||
return r_get_net_state(_head);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::get_net_transform
|
||||
// Access: Published
|
||||
// Description: Returns the net transform on this node from the root.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(TransformState) NodeChain::
|
||||
get_net_transform() const {
|
||||
uncollapse_head();
|
||||
return r_get_net_transform(_head);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::get_mat
|
||||
// Access: Published
|
||||
// Description: Returns the matrix that describes the coordinate
|
||||
// space of this node, relative to the other
|
||||
// node's coordinate space. If either NodeChain is
|
||||
// empty, it is taken to indicate the top of the graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LMatrix4f &NodeChain::
|
||||
get_mat(const NodeChain &other) const {
|
||||
CPT(TransformState) transform = get_rel_transform(other);
|
||||
// We can safely assume the transform won't go away when the
|
||||
// function returns, since its reference count is also held in the
|
||||
// cache. This assumption allows us to return a reference to the
|
||||
// matrix, instead of having to return a matrix on the stack.
|
||||
nassertr(transform->get_ref_count() > 1, LMatrix4f::ident_mat());
|
||||
return transform->get_mat();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::operator ==
|
||||
// Access: Published
|
||||
// Description: Returns true if the two chains are equivalent; that
|
||||
// is, if they contain the same list of nodes in the same
|
||||
// order.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodeChain::
|
||||
operator == (const NodeChain &other) const {
|
||||
return (compare_to(other) == 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::operator !=
|
||||
// Access: Published
|
||||
// Description: Returns true if the two chains are not equivalent.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodeChain::
|
||||
operator != (const NodeChain &other) const {
|
||||
return (compare_to(other) != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::operator <
|
||||
// Access: Published
|
||||
// Description: Returns true if this NodeChain sorts before the other
|
||||
// one, false otherwise. The sorting order of two
|
||||
// nonequivalent NodeChains is consistent but undefined,
|
||||
// and is useful only for storing NodeChains in a sorted
|
||||
// container like an STL set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodeChain::
|
||||
operator < (const NodeChain &other) const {
|
||||
return (compare_to(other) < 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::compare_to
|
||||
// Access: Published
|
||||
// Description: Returns a number less than zero if this NodeChain
|
||||
// sorts before the other one, greater than zero if it
|
||||
// sorts after, or zero if they are equivalent.
|
||||
//
|
||||
// Two NodeChains are considered equivalent if they
|
||||
// consist of exactly the same list of nodes in the same
|
||||
// order. Otherwise, they are different; different
|
||||
// NodeChains will be ranked in a consistent but
|
||||
// undefined ordering; the ordering is useful only for
|
||||
// placing the NodeChains in a sorted container like an
|
||||
// STL set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int NodeChain::
|
||||
compare_to(const NodeChain &other) const {
|
||||
return r_compare_to(_head, other._head);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::output
|
||||
// Access: Published
|
||||
// Description: Writes a sensible description of the NodeChain to the
|
||||
// indicated output stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodeChain::
|
||||
output(ostream &out) const {
|
||||
if (_head == (NodeChainComponent *)NULL) {
|
||||
out << "(empty)";
|
||||
} else {
|
||||
r_output(out, _head);
|
||||
}
|
||||
}
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const NodeChain &node_chain) {
|
||||
node_chain.output(out);
|
||||
return out;
|
||||
}
|
||||
|
@ -1,514 +0,0 @@
|
||||
// Filename: nodeChain.cxx
|
||||
// Created by: drose (25Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "nodeChain.h"
|
||||
#include "node.h"
|
||||
#include "namedNode.h"
|
||||
#include "config_pgraph.h"
|
||||
#include "plist.h"
|
||||
|
||||
TypeHandle NodeChain::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::get_num_nodes
|
||||
// Access: Published
|
||||
// Description: Returns the number of nodes in the path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int NodeChain::
|
||||
get_num_nodes() const {
|
||||
if (is_empty()) {
|
||||
return 0;
|
||||
}
|
||||
uncollapse_head();
|
||||
return _head->get_length();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::get_node
|
||||
// Access: Published
|
||||
// Description: Returns the nth node of the path, where 0 is the
|
||||
// bottom node and get_num_nodes() - 1 is the top node.
|
||||
// This requires iterating through the path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode *NodeChain::
|
||||
get_node(int index) const {
|
||||
nassertr(index >= 0 && index < get_num_nodes(), NULL);
|
||||
|
||||
uncollapse_head();
|
||||
NodeChainComponent *comp = _head;
|
||||
while (index > 0) {
|
||||
// If this assertion fails, the index was out of range; the
|
||||
// component's length must have been invalid.
|
||||
nassertr(comp != (NodeChainComponent *)NULL, NULL);
|
||||
comp = comp->get_next();
|
||||
index--;
|
||||
}
|
||||
|
||||
// If this assertion fails, the index was out of range; the
|
||||
// component's length must have been invalid.
|
||||
nassertr(comp != (NodeChainComponent *)NULL, NULL);
|
||||
return comp->get_node();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::get_top_node
|
||||
// Access: Published
|
||||
// Description: Returns the top node of the path, or NULL if the path
|
||||
// is empty. This requires iterating through the path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode *NodeChain::
|
||||
get_top_node() const {
|
||||
if (is_empty()) {
|
||||
return (PandaNode *)NULL;
|
||||
}
|
||||
|
||||
uncollapse_head();
|
||||
NodeChainComponent *comp = _head;
|
||||
while (!comp->is_top_node()) {
|
||||
comp = comp->get_next();
|
||||
nassertr(comp != (NodeChainComponent *)NULL, NULL);
|
||||
}
|
||||
|
||||
return comp->get_node();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::reparent_to
|
||||
// Access: Published
|
||||
// Description: Removes the bottom node of the NodeChain from its
|
||||
// current parent and attaches it to the bottom node of
|
||||
// the indicated NodeChain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodeChain::
|
||||
reparent_to(const NodeChain &other, int sort) {
|
||||
nassertv(other.verify_complete());
|
||||
nassertv_always(!is_empty());
|
||||
nassertv_always(!other.is_empty());
|
||||
|
||||
uncollapse_head();
|
||||
other.uncollapse_head();
|
||||
PandaNode::reparent(other._head, _head, sort);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::wrt_reparent_to
|
||||
// Access: Published
|
||||
// Description: This functions identically to reparent_to(), except
|
||||
// the transform on this node is also adjusted so that
|
||||
// the node remains in the same place in world
|
||||
// coordinates, even if it is reparented into a
|
||||
// different coordinate system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodeChain::
|
||||
wrt_reparent_to(const NodeChain &other, int sort) {
|
||||
nassertv(other.verify_complete());
|
||||
nassertv_always(!is_empty());
|
||||
nassertv_always(!other.is_empty());
|
||||
|
||||
//****
|
||||
/*
|
||||
LMatrix4f mat = get_mat(other);
|
||||
set_mat(mat);
|
||||
*/
|
||||
|
||||
reparent_to(other, sort);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::instance_to
|
||||
// Access: Published
|
||||
// Description: Adds the bottom node of the NodeChain as a child of
|
||||
// the bottom node of the indicated other NodeChain. Any
|
||||
// other parent-child relations of the node are
|
||||
// unchanged; in particular, the node is not removed
|
||||
// from its existing parent, if any.
|
||||
//
|
||||
// If the node already had an existing parent, this
|
||||
// method will create a new instance of the node within
|
||||
// the scene graph.
|
||||
//
|
||||
// This does not change the NodeChain itself, but does
|
||||
// return a new NodeChain that reflects the new instance
|
||||
// node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
NodeChain NodeChain::
|
||||
instance_to(const NodeChain &other, int sort) const {
|
||||
nassertr(verify_complete(), NodeChain::fail());
|
||||
nassertr(!is_empty(), NodeChain::fail());
|
||||
nassertr(!other.is_empty(), NodeChain::fail());
|
||||
|
||||
uncollapse_head();
|
||||
other.uncollapse_head();
|
||||
|
||||
NodeChain new_instance;
|
||||
new_instance._head = PandaNode::attach(other._head, node(), sort);
|
||||
|
||||
return new_instance;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::copy_to
|
||||
// Access: Published
|
||||
// Description: Functions exactly like instance_to(), except a deep
|
||||
// copy is made of the bottom node and all of its
|
||||
// descendents, which is then parented to the indicated
|
||||
// node. A NodeChain to the newly created copy is
|
||||
// returned.
|
||||
//
|
||||
// Certain kinds of nodes may not be copied; if one of
|
||||
// these is encountered, the node will be "copied" as
|
||||
// the nearest copyable base class. For instance, a
|
||||
// Camera node in the graph will become a simple
|
||||
// NamedNode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
NodeChain NodeChain::
|
||||
copy_to(const NodeChain &other, int sort) const {
|
||||
//*****
|
||||
return instance_to(other, sort);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::attach_new_node
|
||||
// Access: Published
|
||||
// Description: Attaches a new node, with or without existing
|
||||
// parents, to the scene graph below the bottom node of
|
||||
// this NodeChain. This is the preferred way to add
|
||||
// nodes to the graph.
|
||||
//
|
||||
// This does *not* automatically extend the current
|
||||
// NodeChain to reflect the attachment; however, a
|
||||
// NodeChain that does reflect this extension is
|
||||
// returned.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
NodeChain NodeChain::
|
||||
attach_new_node(PandaNode *node, int sort) const {
|
||||
nassertr(verify_complete(), NodeChain::fail());
|
||||
nassertr(!is_empty(), NodeChain());
|
||||
nassertr(node != (PandaNode *)NULL, NodeChain());
|
||||
|
||||
uncollapse_head();
|
||||
NodeChain new_path(*this);
|
||||
new_path._head = PandaNode::attach(_head, node, sort);
|
||||
return new_path;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::remove_node
|
||||
// Access: Published
|
||||
// Description: Disconnects the bottom node from the scene graph.
|
||||
// This will also delete the node if there are no other
|
||||
// pointers to it.
|
||||
//
|
||||
// Normally, this should be called only when you are
|
||||
// really done with the node. If you want to remove a
|
||||
// node from the scene graph but keep it around for
|
||||
// later, you should probably use reparent_to() and put
|
||||
// it under a holding node instead.
|
||||
//
|
||||
// After the node is removed, the NodeChain will have
|
||||
// been cleared.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodeChain::
|
||||
remove_node() {
|
||||
nassertv(_error_type != ET_not_found);
|
||||
if (is_empty()) {
|
||||
// If we have no arcs (maybe we were already removed), quietly do
|
||||
// nothing except to ensure the NodeChain is clear.
|
||||
(*this) = NodeChain::removed();
|
||||
return;
|
||||
}
|
||||
|
||||
uncollapse_head();
|
||||
PandaNode::detach(_head);
|
||||
|
||||
(*this) = NodeChain::removed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::get_rel_state
|
||||
// Access: Published
|
||||
// Description: Returns the state changes that must be made to
|
||||
// transition from the render state of this node to the
|
||||
// render state of the other node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderState) NodeChain::
|
||||
get_rel_state(const NodeChain &other) const {
|
||||
if (is_empty()) {
|
||||
return other.get_net_state();
|
||||
}
|
||||
if (other.is_empty()) {
|
||||
return get_net_state()->invert_compose(RenderState::make_empty());
|
||||
}
|
||||
|
||||
nassertr(verify_complete(), RenderState::make_empty());
|
||||
nassertr(other.verify_complete(), RenderState::make_empty());
|
||||
|
||||
int a_count, b_count;
|
||||
find_common_ancestor(*this, other, a_count, b_count);
|
||||
|
||||
CPT(RenderState) a_state = r_get_partial_state(_head, a_count);
|
||||
CPT(RenderState) b_state = r_get_partial_state(other._head, b_count);
|
||||
return a_state->invert_compose(b_state);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::get_rel_transform
|
||||
// Access: Published
|
||||
// Description: Returns the relative transform from this node to the
|
||||
// other node; i.e. the transformation of the other node
|
||||
// as seen from this node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(TransformState) NodeChain::
|
||||
get_rel_transform(const NodeChain &other) const {
|
||||
if (is_empty()) {
|
||||
return other.get_net_transform();
|
||||
}
|
||||
if (other.is_empty()) {
|
||||
return get_net_transform()->invert_compose(TransformState::make_identity());
|
||||
}
|
||||
|
||||
nassertr(verify_complete(), TransformState::make_identity());
|
||||
nassertr(other.verify_complete(), TransformState::make_identity());
|
||||
|
||||
int a_count, b_count;
|
||||
find_common_ancestor(*this, other, a_count, b_count);
|
||||
|
||||
CPT(TransformState) a_transform = r_get_partial_transform(_head, a_count);
|
||||
CPT(TransformState) b_transform = r_get_partial_transform(other._head, b_count);
|
||||
return a_transform->invert_compose(b_transform);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::verify_complete
|
||||
// Access: Published
|
||||
// Description: Returns true if all of the nodes described in the
|
||||
// NodeChain are connected *and* the top node is the top
|
||||
// of the graph, or false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool NodeChain::
|
||||
verify_complete() const {
|
||||
if (is_empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uncollapse_head();
|
||||
const NodeChainComponent *comp = _head;
|
||||
nassertr(comp != (const NodeChainComponent *)NULL, false);
|
||||
|
||||
PandaNode *node = comp->get_node();
|
||||
nassertr(node != (const PandaNode *)NULL, false);
|
||||
int length = comp->get_length();
|
||||
|
||||
comp = comp->get_next();
|
||||
length--;
|
||||
while (comp != (const NodeChainComponent *)NULL) {
|
||||
PandaNode *next_node = comp->get_node();
|
||||
nassertr(next_node != (const PandaNode *)NULL, false);
|
||||
|
||||
if (next_node->find_child(node) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (comp->get_length() != length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
node = next_node;
|
||||
comp = comp->get_next();
|
||||
length--;
|
||||
}
|
||||
|
||||
// Now that we've reached the top, we should have no parents.
|
||||
return length == 0 && node->get_num_parents() == 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::uncollapse_head
|
||||
// Access: Private
|
||||
// Description: Quietly and transparently uncollapses the _head
|
||||
// pointer if it needs it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodeChain::
|
||||
uncollapse_head() const {
|
||||
if (_head != (NodeChainComponent *)NULL && _head->is_collapsed()) {
|
||||
((NodeChain *)this)->_head = _head->uncollapse();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::find_common_ancestor
|
||||
// Access: Private, Static
|
||||
// Description: Walks up from both NodeChains to find the first node
|
||||
// that both have in common, if any. Fills a_count and
|
||||
// b_count with the number of nodes below the common
|
||||
// node in each chain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodeChain::
|
||||
find_common_ancestor(const NodeChain &a, const NodeChain &b,
|
||||
int &a_count, int &b_count) {
|
||||
nassertv(!a.is_empty() && !b.is_empty());
|
||||
a.uncollapse_head();
|
||||
b.uncollapse_head();
|
||||
|
||||
NodeChainComponent *ac = a._head;
|
||||
NodeChainComponent *bc = b._head;
|
||||
a_count = 0;
|
||||
b_count = 0;
|
||||
|
||||
// Shorten up the longer one until they are the same length.
|
||||
while (ac->get_length() > bc->get_length()) {
|
||||
nassertv(ac != (NodeChainComponent *)NULL);
|
||||
ac = ac->get_next();
|
||||
a_count++;
|
||||
}
|
||||
while (bc->get_length() > ac->get_length()) {
|
||||
nassertv(bc != (NodeChainComponent *)NULL);
|
||||
bc = bc->get_next();
|
||||
b_count++;
|
||||
}
|
||||
|
||||
// Now shorten them both up until we reach the same component.
|
||||
while (ac != bc) {
|
||||
// These shouldn't go to NULL unless they both go there together.
|
||||
nassertv(ac != (NodeChainComponent *)NULL);
|
||||
nassertv(bc != (NodeChainComponent *)NULL);
|
||||
ac = ac->get_next();
|
||||
a_count++;
|
||||
bc = bc->get_next();
|
||||
b_count++;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::r_get_net_state
|
||||
// Access: Private
|
||||
// Description: Recursively determines the net state chnages to the
|
||||
// indicated component node from the root of the graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderState) NodeChain::
|
||||
r_get_net_state(NodeChainComponent *comp) const {
|
||||
if (comp == (NodeChainComponent *)NULL) {
|
||||
return RenderState::make_empty();
|
||||
} else {
|
||||
CPT(RenderState) state = comp->get_node()->get_state();
|
||||
return r_get_net_state(comp->get_next())->compose(state);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::r_get_partial_state
|
||||
// Access: Private
|
||||
// Description: Recursively determines the net state changes to the
|
||||
// indicated component node from the nth node above it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderState) NodeChain::
|
||||
r_get_partial_state(NodeChainComponent *comp, int n) const {
|
||||
nassertr(comp != (NodeChainComponent *)NULL, RenderState::make_empty());
|
||||
if (n == 0) {
|
||||
return RenderState::make_empty();
|
||||
} else {
|
||||
CPT(RenderState) state = comp->get_node()->get_state();
|
||||
return r_get_partial_state(comp->get_next(), n - 1)->compose(state);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::r_get_net_transform
|
||||
// Access: Private
|
||||
// Description: Recursively determines the net transform to the
|
||||
// indicated component node from the root of the graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(TransformState) NodeChain::
|
||||
r_get_net_transform(NodeChainComponent *comp) const {
|
||||
if (comp == (NodeChainComponent *)NULL) {
|
||||
return TransformState::make_identity();
|
||||
} else {
|
||||
CPT(TransformState) transform = comp->get_node()->get_transform();
|
||||
return r_get_net_transform(comp->get_next())->compose(transform);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::r_get_partial_transform
|
||||
// Access: Private
|
||||
// Description: Recursively determines the net transform to the
|
||||
// indicated component node from the nth node above it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(TransformState) NodeChain::
|
||||
r_get_partial_transform(NodeChainComponent *comp, int n) const {
|
||||
nassertr(comp != (NodeChainComponent *)NULL, TransformState::make_identity());
|
||||
if (n == 0) {
|
||||
return TransformState::make_identity();
|
||||
} else {
|
||||
CPT(TransformState) transform = comp->get_node()->get_transform();
|
||||
return r_get_partial_transform(comp->get_next(), n - 1)->compose(transform);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::r_output
|
||||
// Access: Private
|
||||
// Description: The recursive implementation of output(), this writes
|
||||
// the names of each node component in order from
|
||||
// beginning to end, by first walking to the end of the
|
||||
// linked list and then outputting from there.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodeChain::
|
||||
r_output(ostream &out, NodeChainComponent *comp) const {
|
||||
NodeChainComponent *next = comp->get_next();
|
||||
if (next != (NodeChainComponent *)NULL) {
|
||||
// This is not the head of the list; keep going up.
|
||||
r_output(out, next);
|
||||
out << "/";
|
||||
}
|
||||
|
||||
// Now output this component.
|
||||
PandaNode *node = comp->get_node();
|
||||
if (node->has_name()) {
|
||||
out << node->get_name();
|
||||
} else {
|
||||
out << "+" << node->get_type();
|
||||
}
|
||||
out << "[" << comp->get_length() << "]";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChain::r_compare_to
|
||||
// Access: Private, Static
|
||||
// Description: The recursive implementation of compare_to(). Returns
|
||||
// < 0 if a sorts before b, > 0 if b sorts before a, or
|
||||
// == 0 if they are equivalent.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int NodeChain::
|
||||
r_compare_to(const NodeChainComponent *a, const NodeChainComponent *b) {
|
||||
if (a == b) {
|
||||
return 0;
|
||||
|
||||
} else if (a == (const NodeChainComponent *)NULL) {
|
||||
return -1;
|
||||
|
||||
} else if (b == (const NodeChainComponent *)NULL) {
|
||||
return 1;
|
||||
|
||||
} else if (a->get_node() != b->get_node()) {
|
||||
return a->get_node() - b->get_node();
|
||||
|
||||
} else {
|
||||
return r_compare_to(a->get_next(), b->get_next());
|
||||
}
|
||||
}
|
@ -1,176 +0,0 @@
|
||||
// Filename: nodeChain.h
|
||||
// Created by: drose (25Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef NODECHAIN_H
|
||||
#define NODECHAIN_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "pandaNode.h"
|
||||
#include "renderState.h"
|
||||
#include "transformState.h"
|
||||
#include "nodeChainComponent.h"
|
||||
|
||||
#include "pointerTo.h"
|
||||
#include "referenceCount.h"
|
||||
#include "notify.h"
|
||||
#include "typedObject.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : NodeChain
|
||||
// Description : A NodeChain is the fundamental system for
|
||||
// disambiguating instances and manipulating the scene
|
||||
// graph. NodeChain is the base class of NodePath,
|
||||
// which adds a bit more high-level functionality, but
|
||||
// the fundamental scene graph manipulations are defined
|
||||
// at the NodeChain level.
|
||||
//
|
||||
// A NodeChain is a list of connected nodes from the
|
||||
// root of the graph to any sub-node. Each NodeChain
|
||||
// therefore unqiuely describes one instance of a node.
|
||||
//
|
||||
// NodeChains themselves are lightweight objects that
|
||||
// may easily be copied and passed by value. Their data
|
||||
// is stored as a series of NodeChainComponents that are
|
||||
// stored on the nodes. Holding a NodeChain will keep a
|
||||
// reference count to all the nodes in the chain.
|
||||
// However, if any node in the chain is removed or
|
||||
// reparented (perhaps through a different NodeChain),
|
||||
// the NodeChain will automatically be updated to
|
||||
// reflect the changes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA NodeChain {
|
||||
PUBLISHED:
|
||||
// This enumeration is returned by get_error_type() for an empty
|
||||
// NodeChain to report the reason it's empty.
|
||||
enum ErrorType {
|
||||
ET_ok = 0, // i.e. not empty, or never assigned to anything.
|
||||
ET_not_found, // returned from a failed find() or similar function.
|
||||
ET_removed, // remove_node() was previously called on this NodeChain.
|
||||
ET_fail, // general failure return from some function.
|
||||
};
|
||||
|
||||
INLINE NodeChain();
|
||||
INLINE NodeChain(PandaNode *top_node);
|
||||
INLINE NodeChain(const NodeChain ©);
|
||||
INLINE void operator = (const NodeChain ©);
|
||||
|
||||
INLINE static NodeChain not_found();
|
||||
INLINE static NodeChain removed();
|
||||
INLINE static NodeChain fail();
|
||||
|
||||
// Methods to query a NodeChain's contents.
|
||||
INLINE bool is_empty() const;
|
||||
INLINE bool is_singleton() const;
|
||||
int get_num_nodes() const;
|
||||
PandaNode *get_node(int index) const;
|
||||
|
||||
INLINE ErrorType get_error_type() const;
|
||||
|
||||
PandaNode *get_top_node() const;
|
||||
INLINE PandaNode *node() const;
|
||||
|
||||
// Methods that return collections of NodePaths derived from or
|
||||
// related to this one.
|
||||
|
||||
/*
|
||||
NodeChainCollection get_siblings() const;
|
||||
NodeChainCollection get_children() const;
|
||||
*/
|
||||
INLINE int get_num_children() const;
|
||||
INLINE NodeChain get_child(int n) const;
|
||||
|
||||
INLINE bool has_parent() const;
|
||||
INLINE NodeChain get_parent() const;
|
||||
|
||||
/*
|
||||
INLINE NodeChain find_path_down_to(Node *dnode) const;
|
||||
INLINE NodeChain find(const string &chain) const;
|
||||
|
||||
NodeChainCollection
|
||||
find_all_paths_down_to(Node *dnode) const;
|
||||
|
||||
NodeChainCollection
|
||||
find_all_matches(const string &chain) const;
|
||||
*/
|
||||
|
||||
// Methods that actually move nodes around in the scene graph. The
|
||||
// optional "sort" parameter can be used to force a particular
|
||||
// ordering between sibling nodes, useful when dealing with LOD's
|
||||
// and similar switch nodes. If the sort value is the same, nodes
|
||||
// will be arranged in the order they were added.
|
||||
void reparent_to(const NodeChain &other, int sort = 0);
|
||||
void wrt_reparent_to(const NodeChain &other, int sort = 0);
|
||||
NodeChain instance_to(const NodeChain &other, int sort = 0) const;
|
||||
NodeChain copy_to(const NodeChain &other, int sort = 0) const;
|
||||
NodeChain attach_new_node(PandaNode *node, int sort = 0) const;
|
||||
INLINE NodeChain attach_new_node(const string &name, int sort = 0) const;
|
||||
void remove_node();
|
||||
|
||||
|
||||
// Relative transform and state changes between nodes.
|
||||
CPT(RenderState) get_rel_state(const NodeChain &other) const;
|
||||
INLINE CPT(RenderState) get_net_state() const;
|
||||
|
||||
CPT(TransformState) get_rel_transform(const NodeChain &other) const;
|
||||
INLINE CPT(TransformState) get_net_transform() const;
|
||||
|
||||
INLINE const LMatrix4f &get_mat(const NodeChain &other) const;
|
||||
|
||||
bool verify_complete() const;
|
||||
|
||||
public:
|
||||
INLINE bool operator == (const NodeChain &other) const;
|
||||
INLINE bool operator != (const NodeChain &other) const;
|
||||
INLINE bool operator < (const NodeChain &other) const;
|
||||
INLINE int compare_to(const NodeChain &other) const;
|
||||
|
||||
INLINE void output(ostream &out) const;
|
||||
|
||||
private:
|
||||
void uncollapse_head() const;
|
||||
static void find_common_ancestor(const NodeChain &a, const NodeChain &b,
|
||||
int &a_count, int &b_count);
|
||||
|
||||
CPT(RenderState) r_get_net_state(NodeChainComponent *comp) const;
|
||||
CPT(RenderState) r_get_partial_state(NodeChainComponent *comp, int n) const;
|
||||
CPT(TransformState) r_get_net_transform(NodeChainComponent *comp) const;
|
||||
CPT(TransformState) r_get_partial_transform(NodeChainComponent *comp, int n) const;
|
||||
void r_output(ostream &out, NodeChainComponent *comp) const;
|
||||
static int r_compare_to(const NodeChainComponent *a, const NodeChainComponent *v);
|
||||
|
||||
PT(NodeChainComponent) _head;
|
||||
ErrorType _error_type;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
register_type(_type_handle, "NodeChain");
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const NodeChain &node_chain);
|
||||
|
||||
#include "nodeChain.I"
|
||||
|
||||
#endif
|
@ -271,6 +271,20 @@ get_attrib(TypeHandle type) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::has_attrib
|
||||
// Access: Published
|
||||
// Description: Returns true if there is a render attribute of the
|
||||
// indicated type defined on this node, or false if
|
||||
// there is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool PandaNode::
|
||||
has_attrib(TypeHandle type) const {
|
||||
CDReader cdata(_cycler);
|
||||
int index = cdata->_state->find_attrib(type);
|
||||
return (index >= 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::clear_attrib
|
||||
// Access: Published
|
||||
@ -370,17 +384,6 @@ clear_transform() {
|
||||
cdata->_transform = TransformState::make_identity();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::ls
|
||||
// Access: Published
|
||||
// Description: Lists all the nodes at and below the current path
|
||||
// hierarchically.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::
|
||||
ls() const {
|
||||
ls(nout);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::ls
|
||||
// Access: Published
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#include "pandaNode.h"
|
||||
#include "config_pgraph.h"
|
||||
#include "nodeChainComponent.h"
|
||||
#include "qpnodePathComponent.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
#include "indent.h"
|
||||
@ -369,7 +369,7 @@ add_child(PandaNode *child_node, int sort) {
|
||||
cdata->_down.insert(DownConnection(child_node, sort));
|
||||
cdata_child->_up.insert(UpConnection(this));
|
||||
|
||||
// We also have to adjust any NodeChainComponents the child might
|
||||
// We also have to adjust any qpNodePathComponents the child might
|
||||
// have that reference the child as a top node. Any other
|
||||
// components we can leave alone, because we are making a new
|
||||
// instance of the child.
|
||||
@ -402,24 +402,24 @@ remove_child(int n) {
|
||||
int num_erased = cdata_child->_up.erase(UpConnection(this));
|
||||
nassertv(num_erased == 1);
|
||||
|
||||
// Now sever any NodeChainComponents on the child that reference
|
||||
// Now sever any qpNodePathComponents on the child that reference
|
||||
// this node. If we have multiple of these, we have to collapse
|
||||
// them together.
|
||||
NodeChainComponent *collapsed = (NodeChainComponent *)NULL;
|
||||
qpNodePathComponent *collapsed = (qpNodePathComponent *)NULL;
|
||||
Chains::iterator ci;
|
||||
ci = cdata_child->_chains.begin();
|
||||
while (ci != cdata_child->_chains.end()) {
|
||||
Chains::iterator cnext = ci;
|
||||
++cnext;
|
||||
if (!(*ci)->is_top_node() && (*ci)->get_next()->get_node() == this) {
|
||||
if (collapsed == (NodeChainComponent *)NULL) {
|
||||
if (collapsed == (qpNodePathComponent *)NULL) {
|
||||
(*ci)->set_top_node();
|
||||
collapsed = (*ci);
|
||||
} else {
|
||||
// This is a different component that used to reference a
|
||||
// different instance, but now it's all just the same topnode.
|
||||
// We have to collapse this and the previous one together.
|
||||
// However, there might be some NodeChains out there that
|
||||
// However, there might be some qpNodePaths out there that
|
||||
// still keep a pointer to this one, so we can't remove it
|
||||
// altogether.
|
||||
(*ci)->collapse_with(collapsed);
|
||||
@ -453,17 +453,17 @@ remove_child(PandaNode *child_node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now sever any NodeChainComponents on the child that reference
|
||||
// Now sever any qpNodePathComponents on the child that reference
|
||||
// this node. If we have multiple of these, we have to collapse
|
||||
// them together (see above).
|
||||
NodeChainComponent *collapsed = (NodeChainComponent *)NULL;
|
||||
qpNodePathComponent *collapsed = (qpNodePathComponent *)NULL;
|
||||
Chains::iterator ci;
|
||||
ci = cdata_child->_chains.begin();
|
||||
while (ci != cdata_child->_chains.end()) {
|
||||
Chains::iterator cnext = ci;
|
||||
++cnext;
|
||||
if (!(*ci)->is_top_node() && (*ci)->get_next()->get_node() == this) {
|
||||
if (collapsed == (NodeChainComponent *)NULL) {
|
||||
if (collapsed == (qpNodePathComponent *)NULL) {
|
||||
(*ci)->set_top_node();
|
||||
collapsed = (*ci);
|
||||
} else {
|
||||
@ -506,17 +506,17 @@ remove_all_children() {
|
||||
CDWriter cdata_child(child_node->_cycler);
|
||||
cdata_child->_up.erase(UpConnection(this));
|
||||
|
||||
// Now sever any NodeChainComponents on the child that reference
|
||||
// Now sever any qpNodePathComponents on the child that reference
|
||||
// this node. If we have multiple of these, we have to collapse
|
||||
// them together (see above).
|
||||
NodeChainComponent *collapsed = (NodeChainComponent *)NULL;
|
||||
qpNodePathComponent *collapsed = (qpNodePathComponent *)NULL;
|
||||
Chains::iterator ci;
|
||||
ci = cdata_child->_chains.begin();
|
||||
while (ci != cdata_child->_chains.end()) {
|
||||
Chains::iterator cnext = ci;
|
||||
++cnext;
|
||||
if (!(*ci)->is_top_node() && (*ci)->get_next()->get_node() == this) {
|
||||
if (collapsed == (NodeChainComponent *)NULL) {
|
||||
if (collapsed == (qpNodePathComponent *)NULL) {
|
||||
(*ci)->set_top_node();
|
||||
collapsed = (*ci);
|
||||
} else {
|
||||
@ -675,19 +675,19 @@ recompute_internal_bound() {
|
||||
// Function: PandaNode::attach
|
||||
// Access: Private, Static
|
||||
// Description: Creates a new parent-child relationship, and returns
|
||||
// the new NodeChainComponent. If the child was already
|
||||
// the new qpNodePathComponent. If the child was already
|
||||
// attached to the indicated parent, repositions it and
|
||||
// returns the original NodeChainComponent.
|
||||
// returns the original qpNodePathComponent.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(NodeChainComponent) PandaNode::
|
||||
attach(NodeChainComponent *parent, PandaNode *child_node, int sort) {
|
||||
nassertr(parent != (NodeChainComponent *)NULL, (NodeChainComponent *)NULL);
|
||||
PT(qpNodePathComponent) PandaNode::
|
||||
attach(qpNodePathComponent *parent, PandaNode *child_node, int sort) {
|
||||
nassertr(parent != (qpNodePathComponent *)NULL, (qpNodePathComponent *)NULL);
|
||||
|
||||
// See if the child was already attached to the parent. If it was,
|
||||
// we'll use that same NodeChainComponent.
|
||||
PT(NodeChainComponent) child = get_component(parent, child_node);
|
||||
// we'll use that same qpNodePathComponent.
|
||||
PT(qpNodePathComponent) child = get_component(parent, child_node);
|
||||
|
||||
if (child == (NodeChainComponent *)NULL) {
|
||||
if (child == (qpNodePathComponent *)NULL) {
|
||||
// The child was not already attached to the parent, so get a new
|
||||
// component.
|
||||
child = get_top_component(child_node);
|
||||
@ -703,13 +703,13 @@ attach(NodeChainComponent *parent, PandaNode *child_node, int sort) {
|
||||
// Description: Breaks a parent-child relationship.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
detach(NodeChainComponent *child) {
|
||||
nassertv(child != (NodeChainComponent *)NULL);
|
||||
detach(qpNodePathComponent *child) {
|
||||
nassertv(child != (qpNodePathComponent *)NULL);
|
||||
nassertv(!child->is_top_node());
|
||||
PandaNode *child_node = child->get_node();
|
||||
PandaNode *parent_node = child->get_next()->get_node();
|
||||
|
||||
// Break the NodeChainComponent connection.
|
||||
// Break the qpNodePathComponent connection.
|
||||
child->set_top_node();
|
||||
|
||||
CDWriter cdata_child(child_node->_cycler);
|
||||
@ -762,15 +762,15 @@ detach(NodeChainComponent *child) {
|
||||
// Description: Switches a node from one parent to another.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
reparent(NodeChainComponent *new_parent, NodeChainComponent *child, int sort) {
|
||||
nassertv(new_parent != (NodeChainComponent *)NULL);
|
||||
nassertv(child != (NodeChainComponent *)NULL);
|
||||
reparent(qpNodePathComponent *new_parent, qpNodePathComponent *child, int sort) {
|
||||
nassertv(new_parent != (qpNodePathComponent *)NULL);
|
||||
nassertv(child != (qpNodePathComponent *)NULL);
|
||||
|
||||
if (!child->is_top_node()) {
|
||||
detach(child);
|
||||
}
|
||||
|
||||
// Adjust the NodeChainComponents.
|
||||
// Adjust the qpNodePathComponents.
|
||||
child->set_next(new_parent);
|
||||
|
||||
PandaNode *child_node = child->get_node();
|
||||
@ -790,19 +790,19 @@ reparent(NodeChainComponent *new_parent, NodeChainComponent *child, int sort) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::get_component
|
||||
// Access: Private, Static
|
||||
// Description: Returns the NodeChainComponent based on the indicated
|
||||
// Description: Returns the qpNodePathComponent based on the indicated
|
||||
// child of the given parent, or NULL if there is no
|
||||
// such parent-child relationship.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(NodeChainComponent) PandaNode::
|
||||
get_component(NodeChainComponent *parent, PandaNode *child_node) {
|
||||
nassertr(parent != (NodeChainComponent *)NULL, (NodeChainComponent *)NULL);
|
||||
PT(qpNodePathComponent) PandaNode::
|
||||
get_component(qpNodePathComponent *parent, PandaNode *child_node) {
|
||||
nassertr(parent != (qpNodePathComponent *)NULL, (qpNodePathComponent *)NULL);
|
||||
PandaNode *parent_node = parent->get_node();
|
||||
|
||||
{
|
||||
CDReader cdata_child(child_node->_cycler);
|
||||
|
||||
// First, walk through the list of NodeChainComponents we already
|
||||
// First, walk through the list of qpNodePathComponents we already
|
||||
// have on the child, looking for one that already exists,
|
||||
// referencing the indicated parent component.
|
||||
Chains::const_iterator ci;
|
||||
@ -816,13 +816,13 @@ get_component(NodeChainComponent *parent, PandaNode *child_node) {
|
||||
}
|
||||
}
|
||||
|
||||
// We don't already have a NodeChainComponent referring to this
|
||||
// We don't already have a qpNodePathComponent referring to this
|
||||
// parent-child relationship. Are they actually related?
|
||||
int child_index = child_node->find_parent(parent_node);
|
||||
if (child_index >= 0) {
|
||||
// They are. Create and return a new one.
|
||||
PT(NodeChainComponent) child =
|
||||
new NodeChainComponent(child_node, parent);
|
||||
PT(qpNodePathComponent) child =
|
||||
new qpNodePathComponent(child_node, parent);
|
||||
CDWriter cdata_child(child_node->_cycler);
|
||||
cdata_child->_chains.insert(child);
|
||||
return child;
|
||||
@ -835,18 +835,18 @@ get_component(NodeChainComponent *parent, PandaNode *child_node) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::get_top_component
|
||||
// Access: Private, Static
|
||||
// Description: Returns a NodeChainComponent referencing the
|
||||
// Description: Returns a qpNodePathComponent referencing the
|
||||
// indicated node as a singleton. It is invalid to call
|
||||
// this for a node that has parents, unless you are
|
||||
// about to create a new instance (and immediately
|
||||
// reconnect the NodeChainComponent elsewhere).
|
||||
// reconnect the qpNodePathComponent elsewhere).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(NodeChainComponent) PandaNode::
|
||||
PT(qpNodePathComponent) PandaNode::
|
||||
get_top_component(PandaNode *child_node) {
|
||||
{
|
||||
CDReader cdata_child(child_node->_cycler);
|
||||
|
||||
// Walk through the list of NodeChainComponents we already have on
|
||||
// Walk through the list of qpNodePathComponents we already have on
|
||||
// the child, looking for one that already exists as a top node.
|
||||
Chains::const_iterator ci;
|
||||
for (ci = cdata_child->_chains.begin();
|
||||
@ -859,10 +859,10 @@ get_top_component(PandaNode *child_node) {
|
||||
}
|
||||
}
|
||||
|
||||
// We don't already have such a NodeChainComponent; create and
|
||||
// We don't already have such a qpNodePathComponent; create and
|
||||
// return a new one.
|
||||
PT(NodeChainComponent) child =
|
||||
new NodeChainComponent(child_node, (NodeChainComponent *)NULL);
|
||||
PT(qpNodePathComponent) child =
|
||||
new qpNodePathComponent(child_node, (qpNodePathComponent *)NULL);
|
||||
CDWriter cdata_child(child_node->_cycler);
|
||||
cdata_child->_chains.insert(child);
|
||||
|
||||
@ -872,13 +872,13 @@ get_top_component(PandaNode *child_node) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::get_generic_component
|
||||
// Access: Private
|
||||
// Description: Returns a NodeChainComponent referencing this node as
|
||||
// Description: Returns a qpNodePathComponent referencing this node as
|
||||
// a chain from the root. It is only valid to call this
|
||||
// if there is an unambiguous path from the root;
|
||||
// otherwise, a warning will be issued and one path will
|
||||
// be chosen arbitrarily.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(NodeChainComponent) PandaNode::
|
||||
PT(qpNodePathComponent) PandaNode::
|
||||
get_generic_component() {
|
||||
int num_parents = get_num_parents();
|
||||
if (num_parents == 0) {
|
||||
@ -890,7 +890,7 @@ get_generic_component() {
|
||||
<< *this << " has " << num_parents
|
||||
<< " parents; choosing arbitrary path to root.\n";
|
||||
}
|
||||
PT(NodeChainComponent) parent = get_parent(0)->get_generic_component();
|
||||
PT(qpNodePathComponent) parent = get_parent(0)->get_generic_component();
|
||||
return get_component(parent, this);
|
||||
}
|
||||
}
|
||||
@ -898,12 +898,12 @@ get_generic_component() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PandaNode::delete_component
|
||||
// Access: Private
|
||||
// Description: Removes a NodeChainComponent from the set prior to
|
||||
// Description: Removes a qpNodePathComponent from the set prior to
|
||||
// its deletion. This should only be called by the
|
||||
// NodeChainComponent destructor.
|
||||
// qpNodePathComponent destructor.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PandaNode::
|
||||
delete_component(NodeChainComponent *component) {
|
||||
delete_component(qpNodePathComponent *component) {
|
||||
// We have to remove the component from all of the pipeline stages,
|
||||
// not just the current one.
|
||||
int max_num_erased = 0;
|
||||
@ -924,7 +924,7 @@ delete_component(NodeChainComponent *component) {
|
||||
// Function: PandaNode::fix_chain_lengths
|
||||
// Access: Private
|
||||
// Description: Recursively fixes the _length member of each
|
||||
// NodeChainComponent at this level and below, after an
|
||||
// qpNodePathComponent at this level and below, after an
|
||||
// add or delete child operation that might have messed
|
||||
// these up.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include "pointerTo.h"
|
||||
#include "notify.h"
|
||||
|
||||
class NodeChainComponent;
|
||||
class qpNodePathComponent;
|
||||
class CullTraverserData;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -98,6 +98,7 @@ PUBLISHED:
|
||||
|
||||
INLINE void set_attrib(const RenderAttrib *attrib, int override = 0);
|
||||
INLINE const RenderAttrib *get_attrib(TypeHandle type) const;
|
||||
INLINE bool has_attrib(TypeHandle type) const;
|
||||
INLINE void clear_attrib(TypeHandle type);
|
||||
|
||||
INLINE void set_state(const RenderState *state);
|
||||
@ -111,8 +112,7 @@ PUBLISHED:
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
INLINE void ls() const;
|
||||
INLINE void ls(ostream &out, int indent_level = 0) const;
|
||||
INLINE void ls(ostream &out, int indent_level) const;
|
||||
|
||||
// A node has two bounding volumes: the BoundedObject it inherits
|
||||
// from is the "external" bound and represnts the node and all of
|
||||
@ -149,18 +149,18 @@ protected:
|
||||
BoundedObject _internal_bound;
|
||||
|
||||
private:
|
||||
// parent-child manipulation for NodeChain support. Don't try to
|
||||
// parent-child manipulation for qpNodePath support. Don't try to
|
||||
// call these directly.
|
||||
static PT(NodeChainComponent) attach(NodeChainComponent *parent,
|
||||
static PT(qpNodePathComponent) attach(qpNodePathComponent *parent,
|
||||
PandaNode *child, int sort);
|
||||
static void detach(NodeChainComponent *child);
|
||||
static void reparent(NodeChainComponent *new_parent,
|
||||
NodeChainComponent *child, int sort);
|
||||
static PT(NodeChainComponent) get_component(NodeChainComponent *parent,
|
||||
static void detach(qpNodePathComponent *child);
|
||||
static void reparent(qpNodePathComponent *new_parent,
|
||||
qpNodePathComponent *child, int sort);
|
||||
static PT(qpNodePathComponent) get_component(qpNodePathComponent *parent,
|
||||
PandaNode *child);
|
||||
static PT(NodeChainComponent) get_top_component(PandaNode *child);
|
||||
PT(NodeChainComponent) get_generic_component();
|
||||
void delete_component(NodeChainComponent *component);
|
||||
static PT(qpNodePathComponent) get_top_component(PandaNode *child);
|
||||
PT(qpNodePathComponent) get_generic_component();
|
||||
void delete_component(qpNodePathComponent *component);
|
||||
void fix_chain_lengths();
|
||||
void r_list_descendants(ostream &out, int indent_level) const;
|
||||
|
||||
@ -194,12 +194,12 @@ private:
|
||||
};
|
||||
typedef ov_set<UpConnection> Up;
|
||||
|
||||
// We also maintain a set of NodeChainComponents in the node. This
|
||||
// We also maintain a set of qpNodePathComponents in the node. This
|
||||
// represents the set of instances of this node that we have
|
||||
// requested a NodeChain for. We don't keep reference counts; when
|
||||
// each NodeChainComponent destructs, it removes itself from this
|
||||
// requested a qpNodePath for. We don't keep reference counts; when
|
||||
// each qpNodePathComponent destructs, it removes itself from this
|
||||
// set.
|
||||
typedef pset<NodeChainComponent *> Chains;
|
||||
typedef pset<qpNodePathComponent *> Chains;
|
||||
|
||||
// This is the data that must be cycled between pipeline stages.
|
||||
class EXPCL_PANDA CData : public CycleData {
|
||||
@ -271,8 +271,8 @@ private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class PandaNode::Children;
|
||||
friend class NodeChain;
|
||||
friend class NodeChainComponent;
|
||||
friend class qpNodePath;
|
||||
friend class qpNodePathComponent;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const PandaNode &node) {
|
||||
|
@ -6,8 +6,9 @@
|
||||
#include "qplensNode.cxx"
|
||||
#include "qplodNode.cxx"
|
||||
#include "materialAttrib.cxx"
|
||||
#include "nodeChain.cxx"
|
||||
#include "nodeChainComponent.cxx"
|
||||
#include "qpnodePath.cxx"
|
||||
#include "qpnodePathCollection.cxx"
|
||||
#include "qpnodePathComponent.cxx"
|
||||
#include "pandaNode.cxx"
|
||||
#include "renderAttrib.cxx"
|
||||
#include "renderState.cxx"
|
||||
|
@ -48,7 +48,7 @@ is_active() const {
|
||||
// represent the root of any subgraph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpCamera::
|
||||
set_scene(const NodeChain &scene) {
|
||||
set_scene(const qpNodePath &scene) {
|
||||
_scene = scene;
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ set_scene(const NodeChain &scene) {
|
||||
// Description: Returns the scene that will be rendered by the
|
||||
// camera. See set_scene().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const NodeChain &qpCamera::
|
||||
INLINE const qpNodePath &qpCamera::
|
||||
get_scene() const {
|
||||
return _scene;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "qplensNode.h"
|
||||
#include "nodeChain.h"
|
||||
#include "qpnodePath.h"
|
||||
|
||||
class DisplayRegion;
|
||||
|
||||
@ -49,8 +49,8 @@ PUBLISHED:
|
||||
INLINE void set_active(bool active);
|
||||
INLINE bool is_active() const;
|
||||
|
||||
INLINE void set_scene(const NodeChain &scene);
|
||||
INLINE const NodeChain &get_scene() const;
|
||||
INLINE void set_scene(const qpNodePath &scene);
|
||||
INLINE const qpNodePath &get_scene() const;
|
||||
|
||||
INLINE int get_num_display_regions() const;
|
||||
INLINE DisplayRegion *get_display_region(int n) const;
|
||||
@ -60,7 +60,7 @@ private:
|
||||
void remove_display_region(DisplayRegion *display_region);
|
||||
|
||||
bool _active;
|
||||
NodeChain _scene;
|
||||
qpNodePath _scene;
|
||||
|
||||
typedef pvector<DisplayRegion *> DisplayRegions;
|
||||
DisplayRegions _display_regions;
|
||||
|
@ -29,6 +29,7 @@
|
||||
class PandaNode;
|
||||
class CullHandler;
|
||||
class CullTraverserData;
|
||||
class CullableObject;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : CullTraverser
|
||||
|
1086
panda/src/pgraph/qpnodePath.I
Normal file
1086
panda/src/pgraph/qpnodePath.I
Normal file
File diff suppressed because it is too large
Load Diff
2284
panda/src/pgraph/qpnodePath.cxx
Normal file
2284
panda/src/pgraph/qpnodePath.cxx
Normal file
File diff suppressed because it is too large
Load Diff
427
panda/src/pgraph/qpnodePath.h
Normal file
427
panda/src/pgraph/qpnodePath.h
Normal file
@ -0,0 +1,427 @@
|
||||
// Filename: qpnodePath.h
|
||||
// Created by: drose (25Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef qpNODEPATH_H
|
||||
#define qpNODEPATH_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "pandaNode.h"
|
||||
#include "renderState.h"
|
||||
#include "transformState.h"
|
||||
#include "qpnodePathComponent.h"
|
||||
|
||||
#include "pointerTo.h"
|
||||
#include "referenceCount.h"
|
||||
#include "notify.h"
|
||||
#include "typedObject.h"
|
||||
|
||||
class qpNodePathCollection;
|
||||
class Texture;
|
||||
class Material;
|
||||
class Fog;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : NodePath
|
||||
// Description : NodePath is the fundamental system for disambiguating
|
||||
// instances, and also provides a higher-level interface
|
||||
// for manipulating the scene graph.
|
||||
//
|
||||
// A NodePath is a list of connected nodes from the root
|
||||
// of the graph to any sub-node. Each NodePath
|
||||
// therefore unqiuely describes one instance of a node.
|
||||
//
|
||||
// NodePaths themselves are lightweight objects that may
|
||||
// easily be copied and passed by value. Their data is
|
||||
// stored as a series of NodePathComponents that are
|
||||
// stored on the nodes. Holding a NodePath will keep a
|
||||
// reference count to all the nodes in the chain.
|
||||
// However, if any node in the chain is removed or
|
||||
// reparented (perhaps through a different NodePath),
|
||||
// the NodePath will automatically be updated to reflect
|
||||
// the changes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpNodePath {
|
||||
PUBLISHED:
|
||||
// This enumeration is returned by get_error_type() for an empty
|
||||
// qpNodePath to report the reason it's empty.
|
||||
enum ErrorType {
|
||||
ET_ok = 0, // i.e. not empty, or never assigned to anything.
|
||||
ET_not_found, // returned from a failed find() or similar function.
|
||||
ET_removed, // remove_node() was previously called on this qpNodePath.
|
||||
ET_fail, // general failure return from some function.
|
||||
};
|
||||
|
||||
INLINE qpNodePath();
|
||||
INLINE qpNodePath(PandaNode *top_node);
|
||||
INLINE qpNodePath(const qpNodePath ©);
|
||||
INLINE void operator = (const qpNodePath ©);
|
||||
|
||||
INLINE static qpNodePath not_found();
|
||||
INLINE static qpNodePath removed();
|
||||
INLINE static qpNodePath fail();
|
||||
|
||||
// Methods to query a qpNodePath's contents.
|
||||
INLINE bool is_empty() const;
|
||||
INLINE bool is_singleton() const;
|
||||
int get_num_nodes() const;
|
||||
PandaNode *get_node(int index) const;
|
||||
|
||||
INLINE ErrorType get_error_type() const;
|
||||
|
||||
PandaNode *get_top_node() const;
|
||||
INLINE PandaNode *node() const;
|
||||
|
||||
// Methods that return collections of NodePaths derived from or
|
||||
// related to this one.
|
||||
|
||||
qpNodePathCollection get_children() const;
|
||||
INLINE int get_num_children() const;
|
||||
INLINE qpNodePath get_child(int n) const;
|
||||
|
||||
INLINE bool has_parent() const;
|
||||
INLINE qpNodePath get_parent() const;
|
||||
|
||||
/*
|
||||
INLINE qpNodePath find(const string &path) const;
|
||||
|
||||
qpNodePathCollection
|
||||
find_all_matches(const string &path) const;
|
||||
*/
|
||||
|
||||
// Methods that actually move nodes around in the scene graph. The
|
||||
// optional "sort" parameter can be used to force a particular
|
||||
// ordering between sibling nodes, useful when dealing with LOD's
|
||||
// and similar switch nodes. If the sort value is the same, nodes
|
||||
// will be arranged in the order they were added.
|
||||
void reparent_to(const qpNodePath &other, int sort = 0);
|
||||
void wrt_reparent_to(const qpNodePath &other, int sort = 0);
|
||||
qpNodePath instance_to(const qpNodePath &other, int sort = 0) const;
|
||||
qpNodePath copy_to(const qpNodePath &other, int sort = 0) const;
|
||||
qpNodePath attach_new_node(PandaNode *node, int sort = 0) const;
|
||||
INLINE qpNodePath attach_new_node(const string &name, int sort = 0) const;
|
||||
void remove_node();
|
||||
|
||||
// Handy ways to look at what's there, and other miscellaneous
|
||||
// operations.
|
||||
|
||||
INLINE void output(ostream &out) const;
|
||||
|
||||
INLINE void ls() const;
|
||||
INLINE void ls(ostream &out, int indent_level = 0) const;
|
||||
INLINE void ls_transitions() const;
|
||||
INLINE void ls_transforms() const;
|
||||
|
||||
|
||||
// Aggregate transform and state information.
|
||||
INLINE CPT(RenderState) get_state() const;
|
||||
INLINE void set_state(const RenderState *state) const;
|
||||
CPT(RenderState) get_state(const qpNodePath &other) const;
|
||||
void set_state(const qpNodePath &other, const RenderState *state) const;
|
||||
INLINE CPT(RenderState) get_net_state() const;
|
||||
|
||||
INLINE CPT(TransformState) get_transform() const;
|
||||
INLINE void set_transform(const TransformState *transform) const;
|
||||
CPT(TransformState) get_transform(const qpNodePath &other) const;
|
||||
void set_transform(const qpNodePath &other, const TransformState *transform) const;
|
||||
INLINE CPT(TransformState) get_net_transform() const;
|
||||
|
||||
|
||||
// Methods that get and set the matrix transform: pos, hpr, scale,
|
||||
// in the local coordinate system.
|
||||
|
||||
INLINE void set_pos(float x, float y, float z);
|
||||
void set_pos(const LVecBase3f &pos);
|
||||
void set_x(float x);
|
||||
void set_y(float y);
|
||||
void set_z(float z);
|
||||
LPoint3f get_pos() const;
|
||||
INLINE float get_x() const;
|
||||
INLINE float get_y() const;
|
||||
INLINE float get_z() const;
|
||||
|
||||
INLINE void set_hpr(float h, float p, float r);
|
||||
void set_hpr(const LVecBase3f &hpr);
|
||||
void set_h(float h);
|
||||
void set_p(float p);
|
||||
void set_r(float r);
|
||||
LVecBase3f get_hpr() const;
|
||||
LVecBase3f get_hpr(float roll) const;
|
||||
INLINE float get_h() const;
|
||||
INLINE float get_p() const;
|
||||
INLINE float get_r() const;
|
||||
|
||||
INLINE void set_scale(float scale);
|
||||
INLINE void set_scale(float sx, float sy, float sz);
|
||||
void set_scale(const LVecBase3f &sv3);
|
||||
void set_sx(float sx);
|
||||
void set_sy(float sy);
|
||||
void set_sz(float sz);
|
||||
LVecBase3f get_scale() const;
|
||||
INLINE float get_sx() const;
|
||||
INLINE float get_sy() const;
|
||||
INLINE float get_sz() const;
|
||||
|
||||
INLINE void set_pos_hpr(float x, float y, float z,
|
||||
float h, float p, float r);
|
||||
void set_pos_hpr(const LVecBase3f &pos,
|
||||
const LVecBase3f &hpr);
|
||||
|
||||
INLINE void set_hpr_scale(float h, float p, float r,
|
||||
float sx, float sy, float sz);
|
||||
void set_hpr_scale(const LVecBase3f &hpr,
|
||||
const LVecBase3f &scale);
|
||||
INLINE void set_pos_hpr_scale(float x, float y, float z,
|
||||
float h, float p, float r,
|
||||
float sx, float sy, float sz);
|
||||
void set_pos_hpr_scale(const LVecBase3f &pos,
|
||||
const LVecBase3f &hpr,
|
||||
const LVecBase3f &scale);
|
||||
|
||||
void set_mat(const LMatrix4f &mat);
|
||||
INLINE void clear_mat();
|
||||
INLINE bool has_mat() const;
|
||||
INLINE const LMatrix4f &get_mat() const;
|
||||
|
||||
INLINE bool has_color_scale() const;
|
||||
INLINE void clear_color_scale();
|
||||
|
||||
void set_color_scale(const LVecBase4f &sv4);
|
||||
INLINE void set_color_scale(float sx, float sy, float sz, float sa);
|
||||
INLINE void set_sr(float sr);
|
||||
INLINE void set_sg(float sg);
|
||||
INLINE void set_sb(float sb);
|
||||
INLINE void set_sa(float sa);
|
||||
|
||||
LVecBase4f get_color_scale() const;
|
||||
INLINE float get_sr() const;
|
||||
INLINE float get_sg() const;
|
||||
INLINE float get_sb() const;
|
||||
INLINE float get_sa() const;
|
||||
|
||||
INLINE void look_at(float x, float y, float z);
|
||||
void look_at(const LPoint3f &point, const LVector3f &up = LVector3f::up());
|
||||
INLINE void heads_up(float x, float y, float z);
|
||||
void heads_up(const LPoint3f &point, const LVector3f &up = LVector3f::up());
|
||||
|
||||
INLINE void look_at_preserve_scale(float x, float y, float z);
|
||||
void look_at_preserve_scale(const LPoint3f &point, const LVector3f &up = LVector3f::up());
|
||||
INLINE void heads_up_preserve_scale(float x, float y, float z);
|
||||
void heads_up_preserve_scale(const LPoint3f &point, const LVector3f &up = LVector3f::up());
|
||||
|
||||
// Methods that get and set the matrix transforms relative to some
|
||||
// other node in the scene graph. These perform an implicit wrt().
|
||||
|
||||
INLINE void set_pos(const qpNodePath &other, float x, float y, float z);
|
||||
void set_pos(const qpNodePath &other, const LVecBase3f &pos);
|
||||
void set_x(const qpNodePath &other, float x);
|
||||
void set_y(const qpNodePath &other, float y);
|
||||
void set_z(const qpNodePath &other, float z);
|
||||
INLINE LPoint3f get_pos(const qpNodePath &other) const;
|
||||
INLINE float get_x(const qpNodePath &other) const;
|
||||
INLINE float get_y(const qpNodePath &other) const;
|
||||
INLINE float get_z(const qpNodePath &other) const;
|
||||
|
||||
INLINE void set_hpr(const qpNodePath &other, float h, float p, float r);
|
||||
void set_hpr(const qpNodePath &other, const LVecBase3f &hpr);
|
||||
void set_h(const qpNodePath &other, float h);
|
||||
void set_p(const qpNodePath &other, float p);
|
||||
void set_r(const qpNodePath &other, float r);
|
||||
LVecBase3f get_hpr(const qpNodePath &other) const;
|
||||
LVecBase3f get_hpr(const qpNodePath &other, float roll) const;
|
||||
INLINE float get_h(const qpNodePath &other) const;
|
||||
INLINE float get_p(const qpNodePath &other) const;
|
||||
INLINE float get_r(const qpNodePath &other) const;
|
||||
|
||||
INLINE void set_scale(const qpNodePath &other, float sx, float sy, float sz);
|
||||
void set_scale(const qpNodePath &other, const LVecBase3f &scale);
|
||||
void set_sx(const qpNodePath &other, float sx);
|
||||
void set_sy(const qpNodePath &other, float sy);
|
||||
void set_sz(const qpNodePath &other, float sz);
|
||||
LVecBase3f get_scale(const qpNodePath &other) const;
|
||||
INLINE float get_sx(const qpNodePath &other) const;
|
||||
INLINE float get_sy(const qpNodePath &other) const;
|
||||
INLINE float get_sz(const qpNodePath &other) const;
|
||||
|
||||
INLINE void set_pos_hpr(const qpNodePath &other,
|
||||
float x, float y, float z,
|
||||
float h, float p, float r);
|
||||
void set_pos_hpr(const qpNodePath &other,
|
||||
const LVecBase3f &pos,
|
||||
const LVecBase3f &hpr);
|
||||
INLINE void set_hpr_scale(const qpNodePath &other,
|
||||
float h, float p, float r,
|
||||
float sx, float sy, float sz);
|
||||
void set_hpr_scale(const qpNodePath &other,
|
||||
const LVecBase3f &hpr,
|
||||
const LVecBase3f &scale);
|
||||
INLINE void set_pos_hpr_scale(const qpNodePath &other,
|
||||
float x, float y, float z,
|
||||
float h, float p, float r,
|
||||
float sx, float sy, float sz);
|
||||
void set_pos_hpr_scale(const qpNodePath &other,
|
||||
const LVecBase3f &pos,
|
||||
const LVecBase3f &hpr,
|
||||
const LVecBase3f &scale);
|
||||
|
||||
const LMatrix4f &get_mat(const qpNodePath &other) const;
|
||||
void set_mat(const qpNodePath &other, const LMatrix4f &mat);
|
||||
|
||||
LPoint3f get_relative_point(const qpNodePath &other, const LVecBase3f &point);
|
||||
|
||||
INLINE void look_at(const qpNodePath &other,
|
||||
float x, float y, float z);
|
||||
void look_at(const qpNodePath &other,
|
||||
const LPoint3f &point = LPoint3f(0.0, 0.0, 0.0),
|
||||
const LVector3f &up = LVector3f::up());
|
||||
INLINE void heads_up(const qpNodePath &other,
|
||||
float x, float y, float z);
|
||||
void heads_up(const qpNodePath &other,
|
||||
const LPoint3f &point = LPoint3f(0.0, 0.0, 0.0),
|
||||
const LVector3f &up = LVector3f::up());
|
||||
|
||||
INLINE void look_at_preserve_scale(const qpNodePath &other,
|
||||
float x, float y, float z);
|
||||
void look_at_preserve_scale(const qpNodePath &other,
|
||||
const LPoint3f &point = LPoint3f(0.0, 0.0, 0.0),
|
||||
const LVector3f &up = LVector3f::up());
|
||||
INLINE void heads_up_preserve_scale(const qpNodePath &other,
|
||||
float x, float y, float z);
|
||||
void heads_up_preserve_scale(const qpNodePath &other,
|
||||
const LPoint3f &point = LPoint3f(0.0, 0.0, 0.0),
|
||||
const LVector3f &up = LVector3f::up());
|
||||
|
||||
INLINE float get_distance(const qpNodePath &other) const;
|
||||
|
||||
|
||||
// Methods that affect appearance of geometry: color, texture, etc.
|
||||
// These affect the state at the bottom level only.
|
||||
|
||||
void set_color(float r, float g, float b, float a = 1.0,
|
||||
int priority = 0);
|
||||
void set_color(const Colorf &color, int priority = 0);
|
||||
void set_color_off(int priority = 0);
|
||||
void clear_color();
|
||||
bool has_color() const;
|
||||
Colorf get_color() const;
|
||||
|
||||
void set_bin(const string &bin_name, int draw_order, int priority = 0);
|
||||
void clear_bin();
|
||||
bool has_bin() const;
|
||||
string get_bin_name() const;
|
||||
int get_bin_draw_order() const;
|
||||
|
||||
void set_texture(Texture *tex, int priority = 0);
|
||||
void set_texture_off(int priority = 0);
|
||||
void clear_texture();
|
||||
bool has_texture() const;
|
||||
bool has_texture_off() const;
|
||||
Texture *get_texture() const;
|
||||
|
||||
void set_material(Material *tex, int priority = 0);
|
||||
void set_material_off(int priority = 0);
|
||||
void clear_material();
|
||||
bool has_material() const;
|
||||
PT(Material) get_material() const;
|
||||
|
||||
void set_fog(Fog *fog, int priority = 0);
|
||||
void set_fog_off(int priority = 0);
|
||||
void clear_fog();
|
||||
bool has_fog() const;
|
||||
bool has_fog_off() const;
|
||||
Fog *get_fog() const;
|
||||
|
||||
void set_render_mode_wireframe(int priority = 0);
|
||||
void set_render_mode_filled(int priority = 0);
|
||||
void clear_render_mode();
|
||||
bool has_render_mode() const;
|
||||
|
||||
void set_two_sided(bool two_sided, int priority = 0);
|
||||
void clear_two_sided();
|
||||
bool has_two_sided() const;
|
||||
bool get_two_sided() const;
|
||||
|
||||
void do_billboard_axis(const qpNodePath &camera, float offset);
|
||||
void do_billboard_point_eye(const qpNodePath &camera, float offset);
|
||||
void do_billboard_point_world(const qpNodePath &camera, float offset);
|
||||
void set_billboard_axis(float offset = 0.0);
|
||||
void set_billboard_point_eye(float offset = 0.0);
|
||||
void set_billboard_point_world(float offset = 0.0);
|
||||
void clear_billboard();
|
||||
bool has_billboard() const;
|
||||
|
||||
void set_transparency(bool transparency, int priority = 0);
|
||||
void clear_transparency();
|
||||
bool has_transparency() const;
|
||||
bool get_transparency() const;
|
||||
|
||||
INLINE void adjust_all_priorities(int adjustment);
|
||||
|
||||
// Variants on show and hide
|
||||
INLINE void show();
|
||||
INLINE void hide();
|
||||
INLINE void show_collision_solids();
|
||||
INLINE void hide_collision_solids();
|
||||
INLINE bool is_hidden() const;
|
||||
qpNodePath get_hidden_ancestor() const;
|
||||
|
||||
INLINE void stash();
|
||||
INLINE void unstash();
|
||||
INLINE bool is_stashed() const;
|
||||
qpNodePath get_stashed_ancestor() const;
|
||||
|
||||
// Comparison methods
|
||||
INLINE bool operator == (const qpNodePath &other) const;
|
||||
INLINE bool operator != (const qpNodePath &other) const;
|
||||
INLINE bool operator < (const qpNodePath &other) const;
|
||||
INLINE int compare_to(const qpNodePath &other) const;
|
||||
|
||||
bool verify_complete() const;
|
||||
|
||||
private:
|
||||
void uncollapse_head() const;
|
||||
static void find_common_ancestor(const qpNodePath &a, const qpNodePath &b,
|
||||
int &a_count, int &b_count);
|
||||
|
||||
CPT(RenderState) r_get_net_state(qpNodePathComponent *comp) const;
|
||||
CPT(RenderState) r_get_partial_state(qpNodePathComponent *comp, int n) const;
|
||||
CPT(TransformState) r_get_net_transform(qpNodePathComponent *comp) const;
|
||||
CPT(TransformState) r_get_partial_transform(qpNodePathComponent *comp, int n) const;
|
||||
void r_output(ostream &out, qpNodePathComponent *comp) const;
|
||||
static int r_compare_to(const qpNodePathComponent *a, const qpNodePathComponent *v);
|
||||
|
||||
PT(qpNodePathComponent) _head;
|
||||
ErrorType _error_type;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
register_type(_type_handle, "qpNodePath");
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const qpNodePath &node_path);
|
||||
|
||||
#include "qpnodePath.I"
|
||||
|
||||
#endif
|
38
panda/src/pgraph/qpnodePathCollection.I
Normal file
38
panda/src/pgraph/qpnodePathCollection.I
Normal file
@ -0,0 +1,38 @@
|
||||
// Filename: qpnodePathCollection.I
|
||||
// Created by: drose (06Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::Destructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpNodePathCollection::
|
||||
~qpNodePathCollection() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::ls
|
||||
// Access: Published
|
||||
// Description: Lists all the nodes at and below each node in the
|
||||
// collection hierarchically.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpNodePathCollection::
|
||||
ls() const {
|
||||
ls(nout);
|
||||
}
|
397
panda/src/pgraph/qpnodePathCollection.cxx
Normal file
397
panda/src/pgraph/qpnodePathCollection.cxx
Normal file
@ -0,0 +1,397 @@
|
||||
// Filename: qpnodePathCollection.cxx
|
||||
// Created by: drose (06Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "qpnodePathCollection.h"
|
||||
//#include "findApproxPath.h"
|
||||
//#include "findApproxLevel.h"
|
||||
|
||||
#include "indent.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpNodePathCollection::
|
||||
qpNodePathCollection() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpNodePathCollection::
|
||||
qpNodePathCollection(const qpNodePathCollection ©) :
|
||||
_node_paths(copy._node_paths)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathCollection::
|
||||
operator = (const qpNodePathCollection ©) {
|
||||
_node_paths = copy._node_paths;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::add_path
|
||||
// Access: Published
|
||||
// Description: Adds a new qpNodePath to the collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathCollection::
|
||||
add_path(const qpNodePath &node_path) {
|
||||
// If the pointer to our internal array is shared by any other
|
||||
// NodePathCollections, we have to copy the array now so we won't
|
||||
// inadvertently modify any of our brethren NodePathCollection
|
||||
// objects.
|
||||
|
||||
if (_node_paths.get_ref_count() > 1) {
|
||||
PTA(qpNodePath) old_node_paths = _node_paths;
|
||||
_node_paths = PTA(qpNodePath)::empty_array(0);
|
||||
_node_paths.v() = old_node_paths.v();
|
||||
}
|
||||
|
||||
_node_paths.push_back(node_path);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::remove_path
|
||||
// Access: Published
|
||||
// Description: Removes the indicated qpNodePath from the collection.
|
||||
// Returns true if the path was removed, false if it was
|
||||
// not a member of the collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpNodePathCollection::
|
||||
remove_path(const qpNodePath &node_path) {
|
||||
int path_index = -1;
|
||||
for (int i = 0; path_index == -1 && i < (int)_node_paths.size(); i++) {
|
||||
if (_node_paths[i] == node_path) {
|
||||
path_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (path_index == -1) {
|
||||
// The indicated path was not a member of the collection.
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the pointer to our internal array is shared by any other
|
||||
// NodePathCollections, we have to copy the array now so we won't
|
||||
// inadvertently modify any of our brethren NodePathCollection
|
||||
// objects.
|
||||
|
||||
if (_node_paths.get_ref_count() > 1) {
|
||||
PTA(qpNodePath) old_node_paths = _node_paths;
|
||||
_node_paths = PTA(qpNodePath)::empty_array(0);
|
||||
_node_paths.v() = old_node_paths.v();
|
||||
}
|
||||
|
||||
_node_paths.erase(_node_paths.begin() + path_index);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::add_paths_from
|
||||
// Access: Published
|
||||
// Description: Adds all the qpNodePaths indicated in the other
|
||||
// collection to this path. The other paths are simply
|
||||
// appended to the end of the paths in this list;
|
||||
// duplicates are not automatically removed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathCollection::
|
||||
add_paths_from(const qpNodePathCollection &other) {
|
||||
int other_num_paths = other.get_num_paths();
|
||||
for (int i = 0; i < other_num_paths; i++) {
|
||||
add_path(other.get_path(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::remove_paths_from
|
||||
// Access: Published
|
||||
// Description: Removes from this collection all of the qpNodePaths
|
||||
// listed in the other collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathCollection::
|
||||
remove_paths_from(const qpNodePathCollection &other) {
|
||||
NodePaths new_paths;
|
||||
int num_paths = get_num_paths();
|
||||
for (int i = 0; i < num_paths; i++) {
|
||||
qpNodePath path = get_path(i);
|
||||
if (!other.has_path(path)) {
|
||||
new_paths.push_back(path);
|
||||
}
|
||||
}
|
||||
_node_paths = new_paths;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::remove_duplicate_paths
|
||||
// Access: Published
|
||||
// Description: Removes any duplicate entries of the same NodePaths
|
||||
// on this collection. If a qpNodePath appears multiple
|
||||
// times, the first appearance is retained; subsequent
|
||||
// appearances are removed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathCollection::
|
||||
remove_duplicate_paths() {
|
||||
NodePaths new_paths;
|
||||
|
||||
int num_paths = get_num_paths();
|
||||
for (int i = 0; i < num_paths; i++) {
|
||||
qpNodePath path = get_path(i);
|
||||
bool duplicated = false;
|
||||
|
||||
for (int j = 0; j < i && !duplicated; j++) {
|
||||
duplicated = (path == get_path(j));
|
||||
}
|
||||
|
||||
if (!duplicated) {
|
||||
new_paths.push_back(path);
|
||||
}
|
||||
}
|
||||
|
||||
_node_paths = new_paths;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::has_path
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated qpNodePath appears in
|
||||
// this collection, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpNodePathCollection::
|
||||
has_path(const qpNodePath &path) const {
|
||||
for (int i = 0; i < get_num_paths(); i++) {
|
||||
if (path == get_path(i)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::clear
|
||||
// Access: Published
|
||||
// Description: Removes all NodePaths from the collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathCollection::
|
||||
clear() {
|
||||
_node_paths.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::is_empty
|
||||
// Access: Published
|
||||
// Description: Returns true if there are no NodePaths in the
|
||||
// collection, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpNodePathCollection::
|
||||
is_empty() const {
|
||||
return _node_paths.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::get_num_paths
|
||||
// Access: Published
|
||||
// Description: Returns the number of NodePaths in the collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpNodePathCollection::
|
||||
get_num_paths() const {
|
||||
return _node_paths.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::get_path
|
||||
// Access: Published
|
||||
// Description: Returns the nth qpNodePath in the collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpNodePath qpNodePathCollection::
|
||||
get_path(int index) const {
|
||||
nassertr(index >= 0 && index < (int)_node_paths.size(), qpNodePath());
|
||||
|
||||
return _node_paths[index];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::operator []
|
||||
// Access: Published
|
||||
// Description: Returns the nth qpNodePath in the collection. This is
|
||||
// the same as get_path(), but it may be a more
|
||||
// convenient way to access it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpNodePath qpNodePathCollection::
|
||||
operator [] (int index) const {
|
||||
nassertr(index >= 0 && index < (int)_node_paths.size(), qpNodePath());
|
||||
|
||||
return _node_paths[index];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::ls
|
||||
// Access: Published
|
||||
// Description: Lists all the nodes at and below each node in the
|
||||
// collection hierarchically.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathCollection::
|
||||
ls(ostream &out, int indent_level) const {
|
||||
for (int i = 0; i < get_num_paths(); i++) {
|
||||
qpNodePath path = get_path(i);
|
||||
indent(out, indent_level) << path << "\n";
|
||||
path.ls(out, indent_level + 2);
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::find_all_matches
|
||||
// Access: Published
|
||||
// Description: Returns the complete set of all NodePaths that begin
|
||||
// with any qpNodePath in this collection and can be
|
||||
// extended by path. The shortest paths will be listed
|
||||
// first.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpNodePathCollection qpNodePathCollection::
|
||||
find_all_matches(const string &path) const {
|
||||
qpNodePathCollection result;
|
||||
|
||||
FindApproxPath approx_path;
|
||||
if (approx_path.add_string(path)) {
|
||||
if (!is_empty()) {
|
||||
FindApproxLevel level;
|
||||
for (int i = 0; i < get_num_paths(); i++) {
|
||||
FindApproxLevelEntry start(get_path(i), approx_path);
|
||||
level.add_entry(start);
|
||||
}
|
||||
get_path(0).r_find_matches(result, level, -1,
|
||||
qpNodePath::get_max_search_depth());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::reparent_to
|
||||
// Access: Published
|
||||
// Description: Reparents all the NodePaths in the collection to the
|
||||
// indicated node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathCollection::
|
||||
reparent_to(const qpNodePath &other) {
|
||||
for (int i = 0; i < get_num_paths(); i++) {
|
||||
get_path(i).reparent_to(other);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::wrt_reparent_to
|
||||
// Access: Published
|
||||
// Description: Reparents all the NodePaths in the collection to the
|
||||
// indicated node, adjusting each transform so as not to
|
||||
// move in world coordinates.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathCollection::
|
||||
wrt_reparent_to(const qpNodePath &other) {
|
||||
for (int i = 0; i < get_num_paths(); i++) {
|
||||
get_path(i).wrt_reparent_to(other);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::show
|
||||
// Access: Published
|
||||
// Description: Shows all NodePaths in the collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathCollection::
|
||||
show() {
|
||||
for (int i = 0; i < get_num_paths(); i++) {
|
||||
get_path(i).show();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::show
|
||||
// Access: Published
|
||||
// Description: Hides all NodePaths in the collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathCollection::
|
||||
hide() {
|
||||
for (int i = 0; i < get_num_paths(); i++) {
|
||||
get_path(i).hide();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::stash
|
||||
// Access: Published
|
||||
// Description: Stashes all NodePaths in the collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathCollection::
|
||||
stash() {
|
||||
for (int i = 0; i < get_num_paths(); i++) {
|
||||
get_path(i).stash();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::unstash
|
||||
// Access: Published
|
||||
// Description: Unstashes all NodePaths in the collection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathCollection::
|
||||
unstash() {
|
||||
for (int i = 0; i < get_num_paths(); i++) {
|
||||
get_path(i).unstash();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::output
|
||||
// Access: Published
|
||||
// Description: Writes a brief one-line description of the
|
||||
// qpNodePathCollection to the indicated output stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathCollection::
|
||||
output(ostream &out) const {
|
||||
if (get_num_paths() == 1) {
|
||||
out << "1 NodePath";
|
||||
} else {
|
||||
out << get_num_paths() << " NodePaths";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpNodePathCollection::write
|
||||
// Access: Published
|
||||
// Description: Writes a complete multi-line description of the
|
||||
// qpNodePathCollection to the indicated output stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpNodePathCollection::
|
||||
write(ostream &out, int indent_level) const {
|
||||
for (int i = 0; i < get_num_paths(); i++) {
|
||||
indent(out, indent_level) << get_path(i) << "\n";
|
||||
}
|
||||
}
|
83
panda/src/pgraph/qpnodePathCollection.h
Normal file
83
panda/src/pgraph/qpnodePathCollection.h
Normal file
@ -0,0 +1,83 @@
|
||||
// Filename: qpnodePathCollection.h
|
||||
// Created by: drose (06Mar02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef qpNODEPATHCOLLECTION_H
|
||||
#define qpNODEPATHCOLLECTION_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "qpnodePath.h"
|
||||
#include "pointerToArray.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : NodePathCollection
|
||||
// Description : This is a set of zero or more NodePaths. It's handy
|
||||
// for returning from functions that need to return
|
||||
// multiple NodePaths (for instance,
|
||||
// NodePaths::get_children).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpNodePathCollection {
|
||||
PUBLISHED:
|
||||
qpNodePathCollection();
|
||||
qpNodePathCollection(const qpNodePathCollection ©);
|
||||
void operator = (const qpNodePathCollection ©);
|
||||
INLINE ~qpNodePathCollection();
|
||||
|
||||
void add_path(const qpNodePath &node_path);
|
||||
bool remove_path(const qpNodePath &node_path);
|
||||
void add_paths_from(const qpNodePathCollection &other);
|
||||
void remove_paths_from(const qpNodePathCollection &other);
|
||||
void remove_duplicate_paths();
|
||||
bool has_path(const qpNodePath &path) const;
|
||||
void clear();
|
||||
|
||||
bool is_empty() const;
|
||||
int get_num_paths() const;
|
||||
qpNodePath get_path(int index) const;
|
||||
qpNodePath operator [] (int index) const;
|
||||
|
||||
// Handy operations on many NodePaths at once.
|
||||
INLINE void ls() const;
|
||||
void ls(ostream &out, int indent_level = 0) const;
|
||||
|
||||
// qpNodePathCollection find_all_matches(const string &path) const;
|
||||
void reparent_to(const qpNodePath &other);
|
||||
void wrt_reparent_to(const qpNodePath &other);
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
void stash();
|
||||
void unstash();
|
||||
|
||||
void output(ostream &out) const;
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
private:
|
||||
typedef PTA(qpNodePath) NodePaths;
|
||||
NodePaths _node_paths;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const qpNodePathCollection &col) {
|
||||
col.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#include "qpnodePathCollection.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Filename: nodeChainComponent.I
|
||||
// Filename: qpnodePathComponent.I
|
||||
// Created by: drose (25Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -18,36 +18,36 @@
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::CData::Constructor
|
||||
// Function: qpNodePathComponent::CData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChainComponent::CData::
|
||||
INLINE qpNodePathComponent::CData::
|
||||
CData() {
|
||||
_length = 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::CData::Copy Constructor
|
||||
// Function: qpNodePathComponent::CData::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChainComponent::CData::
|
||||
CData(const NodeChainComponent::CData ©) :
|
||||
INLINE qpNodePathComponent::CData::
|
||||
CData(const qpNodePathComponent::CData ©) :
|
||||
_next(copy._next),
|
||||
_length(copy._length)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::Constructor
|
||||
// Function: qpNodePathComponent::Constructor
|
||||
// Access: Private
|
||||
// Description: Constructs a new NodeChainComponent from the
|
||||
// Description: Constructs a new qpNodePathComponent from the
|
||||
// indicated node. Don't try to call this directly; ask
|
||||
// the PandaNode to do it for you.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChainComponent::
|
||||
NodeChainComponent(PandaNode *node, NodeChainComponent *next) :
|
||||
INLINE qpNodePathComponent::
|
||||
qpNodePathComponent(PandaNode *node, qpNodePathComponent *next) :
|
||||
_node(node)
|
||||
{
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
@ -56,85 +56,85 @@ NodeChainComponent(PandaNode *node, NodeChainComponent *next) :
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_next = next;
|
||||
|
||||
if (next != (NodeChainComponent *)NULL) {
|
||||
if (next != (qpNodePathComponent *)NULL) {
|
||||
cdata->_length = next->get_length() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::Copy Constructor
|
||||
// Function: qpNodePathComponent::Copy Constructor
|
||||
// Access: Private
|
||||
// Description: NodeChainComponents should not be copied.
|
||||
// Description: qpNodePathComponents should not be copied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChainComponent::
|
||||
NodeChainComponent(const NodeChainComponent ©) {
|
||||
INLINE qpNodePathComponent::
|
||||
qpNodePathComponent(const qpNodePathComponent ©) {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::Copy Assignment Operator
|
||||
// Function: qpNodePathComponent::Copy Assignment Operator
|
||||
// Access: Private
|
||||
// Description: NodeChainComponents should not be copied.
|
||||
// Description: qpNodePathComponents should not be copied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodeChainComponent::
|
||||
operator = (const NodeChainComponent ©) {
|
||||
INLINE void qpNodePathComponent::
|
||||
operator = (const qpNodePathComponent ©) {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::Destructor
|
||||
// Function: qpNodePathComponent::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChainComponent::
|
||||
~NodeChainComponent() {
|
||||
INLINE qpNodePathComponent::
|
||||
~qpNodePathComponent() {
|
||||
nassertv(_node != (PandaNode *)NULL);
|
||||
_node->delete_component(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::get_node
|
||||
// Function: qpNodePathComponent::get_node
|
||||
// Access: Public
|
||||
// Description: Returns the node referenced by this component.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *NodeChainComponent::
|
||||
INLINE PandaNode *qpNodePathComponent::
|
||||
get_node() const {
|
||||
return _node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::is_top_node
|
||||
// Function: qpNodePathComponent::is_top_node
|
||||
// Access: Public
|
||||
// Description: Returns true if this component represents the top
|
||||
// node in the chain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodeChainComponent::
|
||||
INLINE bool qpNodePathComponent::
|
||||
is_top_node() const {
|
||||
CDReader cdata(_cycler);
|
||||
return (cdata->_next == (NodeChainComponent *)NULL);
|
||||
return (cdata->_next == (qpNodePathComponent *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::is_collapsed
|
||||
// Function: qpNodePathComponent::is_collapsed
|
||||
// Access: Public
|
||||
// Description: Returns true if this component has been collapsed
|
||||
// with another component. In this case, the component
|
||||
// itself is invalid, and the collapsed component should
|
||||
// be used instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodeChainComponent::
|
||||
INLINE bool qpNodePathComponent::
|
||||
is_collapsed() const {
|
||||
CDReader cdata(_cycler);
|
||||
return (cdata->_length == 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::get_length
|
||||
// Function: qpNodePathComponent::get_length
|
||||
// Access: Public
|
||||
// Description: Returns the length of the chain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int NodeChainComponent::
|
||||
INLINE int qpNodePathComponent::
|
||||
get_length() const {
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(!is_collapsed(), 0);
|
||||
@ -142,59 +142,59 @@ get_length() const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::get_collapsed
|
||||
// Function: qpNodePathComponent::get_collapsed
|
||||
// Access: Public
|
||||
// Description: If is_collapsed() returns true, this is the component
|
||||
// that this one has been collapsed with, and should be
|
||||
// replaced with.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeChainComponent *NodeChainComponent::
|
||||
INLINE qpNodePathComponent *qpNodePathComponent::
|
||||
get_collapsed() const {
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(is_collapsed(), (NodeChainComponent *)NULL);
|
||||
nassertr(is_collapsed(), (qpNodePathComponent *)NULL);
|
||||
return cdata->_next;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::set_next
|
||||
// Function: qpNodePathComponent::set_next
|
||||
// Access: Private
|
||||
// Description: Sets the next pointer in the chain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodeChainComponent::
|
||||
set_next(NodeChainComponent *next) {
|
||||
INLINE void qpNodePathComponent::
|
||||
set_next(qpNodePathComponent *next) {
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(!is_collapsed());
|
||||
nassertv(next != (NodeChainComponent *)NULL);
|
||||
nassertv(next != (qpNodePathComponent *)NULL);
|
||||
cdata->_next = next;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::set_top_node
|
||||
// Function: qpNodePathComponent::set_top_node
|
||||
// Access: Private
|
||||
// Description: Severs any connection to the next pointer in the
|
||||
// chain and makes this component a top node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodeChainComponent::
|
||||
INLINE void qpNodePathComponent::
|
||||
set_top_node() {
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(!is_collapsed());
|
||||
cdata->_next = (NodeChainComponent *)NULL;
|
||||
cdata->_next = (qpNodePathComponent *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::collapse_with
|
||||
// Function: qpNodePathComponent::collapse_with
|
||||
// Access: Private
|
||||
// Description: Indicates that this component pointer is no longer
|
||||
// valid, and that the indicated component should be
|
||||
// used instead. This is done whenever two
|
||||
// NodeChainComponents have been collapsed together due
|
||||
// qpNodePathComponents have been collapsed together due
|
||||
// to an instance being removed higher up in the graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodeChainComponent::
|
||||
collapse_with(NodeChainComponent *next) {
|
||||
INLINE void qpNodePathComponent::
|
||||
collapse_with(qpNodePathComponent *next) {
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(!is_collapsed());
|
||||
nassertv(next != (NodeChainComponent *)NULL);
|
||||
nassertv(next != (qpNodePathComponent *)NULL);
|
||||
cdata->_next = next;
|
||||
cdata->_length = 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Filename: nodeChainComponent.cxx
|
||||
// Filename: qpnodePathComponent.cxx
|
||||
// Created by: drose (25Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -16,54 +16,54 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "nodeChainComponent.h"
|
||||
#include "qpnodePathComponent.h"
|
||||
|
||||
TypeHandle NodeChainComponent::_type_handle;
|
||||
TypeHandle qpNodePathComponent::_type_handle;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::CData::make_copy
|
||||
// Function: qpNodePathComponent::CData::make_copy
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CycleData *NodeChainComponent::CData::
|
||||
CycleData *qpNodePathComponent::CData::
|
||||
make_copy() const {
|
||||
return new CData(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::get_next
|
||||
// Function: qpNodePathComponent::get_next
|
||||
// Access: Public
|
||||
// Description: Returns the next component in the chain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
NodeChainComponent *NodeChainComponent::
|
||||
qpNodePathComponent *qpNodePathComponent::
|
||||
get_next() const {
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(!is_collapsed(), (NodeChainComponent *)NULL);
|
||||
nassertr(!is_collapsed(), (qpNodePathComponent *)NULL);
|
||||
|
||||
NodeChainComponent *next = cdata->_next;
|
||||
qpNodePathComponent *next = cdata->_next;
|
||||
|
||||
// If the next component has been collapsed, transparently update
|
||||
// the pointer to get the actual node, and store the new pointer,
|
||||
// before we return. Collapsing can happen at any time to any
|
||||
// component in the chain and we have to deal with it.
|
||||
if (next != (NodeChainComponent *)NULL && next->is_collapsed()) {
|
||||
if (next != (qpNodePathComponent *)NULL && next->is_collapsed()) {
|
||||
next = next->uncollapse();
|
||||
((NodeChainComponent *)this)->set_next(next);
|
||||
((qpNodePathComponent *)this)->set_next(next);
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::fix_length
|
||||
// Function: qpNodePathComponent::fix_length
|
||||
// Access: Public
|
||||
// Description: Checks that the length indicated by the component is
|
||||
// one more than the length of its predecessor. If this
|
||||
// is broken, fixes it and returns true indicating the
|
||||
// component has been changed; otherwise, returns false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool NodeChainComponent::
|
||||
bool qpNodePathComponent::
|
||||
fix_length() {
|
||||
int length_should_be = 1;
|
||||
if (!is_top_node()) {
|
||||
@ -79,7 +79,7 @@ fix_length() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodeChainComponent::uncollapse
|
||||
// Function: qpNodePathComponent::uncollapse
|
||||
// Access: Public
|
||||
// Description: Returns this component pointer if the component is
|
||||
// not collapsed; or if it has been collapsed, returns
|
||||
@ -90,9 +90,9 @@ fix_length() {
|
||||
// when a node is removed further up the chain that
|
||||
// results in two instances becoming the same thing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
NodeChainComponent *NodeChainComponent::
|
||||
qpNodePathComponent *qpNodePathComponent::
|
||||
uncollapse() {
|
||||
NodeChainComponent *comp = this;
|
||||
qpNodePathComponent *comp = this;
|
||||
|
||||
while (comp->is_collapsed()) {
|
||||
comp = comp->get_collapsed();
|
@ -1,4 +1,4 @@
|
||||
// Filename: nodeChainComponent.h
|
||||
// Filename: qpnodePathComponent.h
|
||||
// Created by: drose (25Feb02)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -16,8 +16,8 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef NODECHAINCOMPONENT_H
|
||||
#define NODECHAINCOMPONENT_H
|
||||
#ifndef qpNODEPATHCOMPONENT_H
|
||||
#define qpNODEPATHCOMPONENT_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
@ -29,45 +29,45 @@
|
||||
#include "cycleDataWriter.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : NodeChainComponent
|
||||
// Description : This is one component of a NodeChain. These are
|
||||
// Class : qpNodePathComponent
|
||||
// Description : This is one component of a NodePath. These are
|
||||
// stored on each PandaNode, as many as one for each of
|
||||
// the possible instances of the node (but they only
|
||||
// exist when they are requested, to minimize memory
|
||||
// waste). A NodeChain represents a singly-linked list
|
||||
// waste). A NodePath represents a singly-linked list
|
||||
// of these from an arbitrary component in the graph to
|
||||
// the root.
|
||||
//
|
||||
// This whole NodeChain system is used to disambiguate
|
||||
// This whole NodePath system is used to disambiguate
|
||||
// instances in the scene graph, and the
|
||||
// NodeChainComponents are stored in the nodes
|
||||
// themselves to allow the nodes to keep these up to
|
||||
// date as the scene graph is manipulated.
|
||||
// NodePathComponents are stored in the nodes themselves
|
||||
// to allow the nodes to keep these up to date as the
|
||||
// scene graph is manipulated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA NodeChainComponent : public ReferenceCount {
|
||||
class EXPCL_PANDA qpNodePathComponent : public ReferenceCount {
|
||||
private:
|
||||
INLINE NodeChainComponent(PandaNode *node, NodeChainComponent *next = NULL);
|
||||
INLINE NodeChainComponent(const NodeChainComponent ©);
|
||||
INLINE void operator = (const NodeChainComponent ©);
|
||||
INLINE qpNodePathComponent(PandaNode *node, qpNodePathComponent *next = NULL);
|
||||
INLINE qpNodePathComponent(const qpNodePathComponent ©);
|
||||
INLINE void operator = (const qpNodePathComponent ©);
|
||||
|
||||
public:
|
||||
INLINE ~NodeChainComponent();
|
||||
INLINE ~qpNodePathComponent();
|
||||
|
||||
INLINE PandaNode *get_node() const;
|
||||
INLINE bool is_top_node() const;
|
||||
INLINE bool is_collapsed() const;
|
||||
|
||||
NodeChainComponent *get_next() const;
|
||||
qpNodePathComponent *get_next() const;
|
||||
INLINE int get_length() const;
|
||||
INLINE NodeChainComponent *get_collapsed() const;
|
||||
INLINE qpNodePathComponent *get_collapsed() const;
|
||||
|
||||
bool fix_length();
|
||||
NodeChainComponent *uncollapse();
|
||||
qpNodePathComponent *uncollapse();
|
||||
|
||||
private:
|
||||
INLINE void set_next(NodeChainComponent *next);
|
||||
INLINE void set_next(qpNodePathComponent *next);
|
||||
INLINE void set_top_node();
|
||||
INLINE void collapse_with(NodeChainComponent *next);
|
||||
INLINE void collapse_with(qpNodePathComponent *next);
|
||||
|
||||
PT(PandaNode) _node;
|
||||
|
||||
@ -78,7 +78,7 @@ private:
|
||||
CData(const CData ©);
|
||||
virtual CycleData *make_copy() const;
|
||||
|
||||
PT(NodeChainComponent) _next;
|
||||
PT(qpNodePathComponent) _next;
|
||||
int _length;
|
||||
};
|
||||
|
||||
@ -92,7 +92,7 @@ public:
|
||||
}
|
||||
static void init_type() {
|
||||
ReferenceCount::init_type();
|
||||
register_type(_type_handle, "NodeChainComponent",
|
||||
register_type(_type_handle, "qpNodePathComponent",
|
||||
ReferenceCount::get_class_type());
|
||||
}
|
||||
|
||||
@ -101,6 +101,6 @@ private:
|
||||
friend class PandaNode;
|
||||
};
|
||||
|
||||
#include "nodeChainComponent.I"
|
||||
#include "qpnodePathComponent.I"
|
||||
|
||||
#endif
|
@ -17,7 +17,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pandaNode.h"
|
||||
#include "nodeChain.h"
|
||||
#include "qpnodePath.h"
|
||||
#include "textureAttrib.h"
|
||||
#include "colorAttrib.h"
|
||||
#include "transformState.h"
|
||||
@ -74,20 +74,20 @@ main(int argc, char *argv[]) {
|
||||
cerr << "\n";
|
||||
list_hierarchy(root, 0);
|
||||
|
||||
NodeChain ch_g1(g1);
|
||||
qpNodePath ch_g1(g1);
|
||||
cerr << ch_g1 << "\n";
|
||||
|
||||
NodeChain ch_g2(g2);
|
||||
qpNodePath ch_g2(g2);
|
||||
cerr << ch_g2 << "\n";
|
||||
|
||||
cerr << *ch_g1.get_rel_transform(ch_g2) << "\n";
|
||||
cerr << *ch_g2.get_rel_transform(ch_g1) << "\n";
|
||||
cerr << *ch_g1.get_transform(ch_g2) << "\n";
|
||||
cerr << *ch_g2.get_transform(ch_g1) << "\n";
|
||||
|
||||
cerr << *ch_g1.get_rel_state(ch_g2) << "\n";
|
||||
cerr << *ch_g2.get_rel_state(ch_g1) << "\n";
|
||||
cerr << *ch_g1.get_state(ch_g2) << "\n";
|
||||
cerr << *ch_g2.get_state(ch_g1) << "\n";
|
||||
|
||||
cerr << *ch_g2.get_rel_transform(ch_g2) << "\n";
|
||||
cerr << *ch_g2.get_rel_state(ch_g2) << "\n";
|
||||
cerr << *ch_g2.get_transform(ch_g2) << "\n";
|
||||
cerr << *ch_g2.get_state(ch_g2) << "\n";
|
||||
|
||||
cerr << "\n";
|
||||
return 0;
|
||||
|
@ -128,17 +128,52 @@ has_components() const {
|
||||
return ((_flags & F_has_components) != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::has_pos
|
||||
// Access: Published
|
||||
// Description: Returns true if the transform's pos component can be
|
||||
// extracted out separately. This is generally always
|
||||
// true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool TransformState::
|
||||
has_pos() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::has_hpr
|
||||
// Access: Published
|
||||
// Description: Returns true if the transform's rotation component
|
||||
// can be extracted out separately and described as a
|
||||
// set of Euler angles. This is generally true only
|
||||
// when has_components() is true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool TransformState::
|
||||
has_hpr() const {
|
||||
return has_components();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::has_scale
|
||||
// Access: Published
|
||||
// Description: Returns true if the transform's scale component
|
||||
// can be extracted out separately. This is generally
|
||||
// true only when has_components() is true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool TransformState::
|
||||
has_scale() const {
|
||||
return has_components();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::get_pos
|
||||
// Access: Published
|
||||
// Description: Returns the pos component of the transform. It is an
|
||||
// error to call this if has_components() returned
|
||||
// false.
|
||||
// error to call this if has_pos() returned false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LVecBase3f &TransformState::
|
||||
get_pos() const {
|
||||
check_components();
|
||||
nassertr(has_components(), _pos);
|
||||
return _pos;
|
||||
}
|
||||
|
||||
@ -152,7 +187,7 @@ get_pos() const {
|
||||
INLINE const LVecBase3f &TransformState::
|
||||
get_hpr() const {
|
||||
check_components();
|
||||
nassertr(has_components(), _hpr);
|
||||
nassertr(has_hpr(), _hpr);
|
||||
return _hpr;
|
||||
}
|
||||
|
||||
@ -166,7 +201,7 @@ get_hpr() const {
|
||||
INLINE const LVecBase3f &TransformState::
|
||||
get_scale() const {
|
||||
check_components();
|
||||
nassertr(has_components(), _scale);
|
||||
nassertr(has_scale(), _scale);
|
||||
return _scale;
|
||||
}
|
||||
|
||||
|
@ -238,6 +238,54 @@ make_mat(const LMatrix4f &mat) {
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::set_pos
|
||||
// Access: Published
|
||||
// Description: Returns a new TransformState object that represents the
|
||||
// original TransformState with its pos component
|
||||
// replaced with the indicated value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(TransformState) TransformState::
|
||||
set_pos(const LVecBase3f &pos) const {
|
||||
if ((_flags & F_components_given) != 0) {
|
||||
// If we started with a componentwise transform, we keep it that
|
||||
// way.
|
||||
return make_pos_hpr_scale(pos, get_hpr(), get_scale());
|
||||
|
||||
} else {
|
||||
// Otherwise, we have a matrix transform, and we keep it that way.
|
||||
LMatrix4f mat = get_mat();
|
||||
mat.set_row(3, pos);
|
||||
return make_mat(mat);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::set_hpr
|
||||
// Access: Published
|
||||
// Description: Returns a new TransformState object that represents the
|
||||
// original TransformState with its hpr component
|
||||
// replaced with the indicated value, if possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(TransformState) TransformState::
|
||||
set_hpr(const LVecBase3f &hpr) const {
|
||||
nassertr(has_components(), this);
|
||||
return make_pos_hpr_scale(get_pos(), hpr, get_scale());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::set_scale
|
||||
// Access: Published
|
||||
// Description: Returns a new TransformState object that represents the
|
||||
// original TransformState with its scale component
|
||||
// replaced with the indicated value, if possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(TransformState) TransformState::
|
||||
set_scale(const LVecBase3f &scale) const {
|
||||
nassertr(has_components(), this);
|
||||
return make_pos_hpr_scale(get_pos(), get_scale(), get_hpr());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TransformState::compose
|
||||
// Access: Published
|
||||
@ -532,10 +580,14 @@ calc_components() {
|
||||
// other explanation is that we were constructed via a matrix.
|
||||
nassertv((_flags & F_mat_known) != 0);
|
||||
|
||||
bool possible = decompose_matrix(get_mat(), _scale, _hpr, _pos);
|
||||
const LMatrix4f &mat = get_mat();
|
||||
bool possible = decompose_matrix(mat, _scale, _hpr, _pos);
|
||||
if (possible) {
|
||||
// Some matrices can't be decomposed into scale, hpr, pos.
|
||||
_flags |= F_has_components;
|
||||
|
||||
// However, we can always get at least the pos.
|
||||
mat.get_row3(_pos, 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,11 +80,18 @@ PUBLISHED:
|
||||
INLINE bool is_identity() const;
|
||||
INLINE bool is_singular() const;
|
||||
INLINE bool has_components() const;
|
||||
INLINE bool has_pos() const;
|
||||
INLINE bool has_hpr() const;
|
||||
INLINE bool has_scale() const;
|
||||
INLINE const LVecBase3f &get_pos() const;
|
||||
INLINE const LVecBase3f &get_hpr() const;
|
||||
INLINE const LVecBase3f &get_scale() const;
|
||||
INLINE const LMatrix4f &get_mat() const;
|
||||
|
||||
CPT(TransformState) set_pos(const LVecBase3f &pos) const;
|
||||
CPT(TransformState) set_hpr(const LVecBase3f &hpr) const;
|
||||
CPT(TransformState) set_scale(const LVecBase3f &scale) const;
|
||||
|
||||
CPT(TransformState) compose(const TransformState *other) const;
|
||||
CPT(TransformState) invert_compose(const TransformState *other) const;
|
||||
|
||||
|
@ -144,7 +144,7 @@ make_camera(GraphicsWindow *window) {
|
||||
PT(Lens) lens = new PerspectiveLens;
|
||||
lens->set_film_size(win_width, win_height);
|
||||
camera->set_lens(lens);
|
||||
dr->set_qpcamera(NodeChain(camera));
|
||||
dr->set_qpcamera(qpNodePath(camera));
|
||||
|
||||
return camera;
|
||||
}
|
||||
@ -216,7 +216,7 @@ get_models(PandaNode *parent, int argc, char *argv[]) {
|
||||
cerr << "Unable to load " << filename << "\n";
|
||||
|
||||
} else {
|
||||
node->ls();
|
||||
node->ls(cerr, 0);
|
||||
parent->add_child(node);
|
||||
}
|
||||
}
|
||||
@ -277,7 +277,7 @@ main(int argc, char *argv[]) {
|
||||
// Now we just need to make a scene graph for the camera to render.
|
||||
PT(PandaNode) render = new PandaNode("render");
|
||||
render->add_child(camera);
|
||||
camera->set_scene(NodeChain(render));
|
||||
camera->set_scene(qpNodePath(render));
|
||||
|
||||
// Set up a data graph for tracking user input. For now, this uses
|
||||
// the old-style graph interface.
|
||||
|
Loading…
x
Reference in New Issue
Block a user