From 99413ba1b33387a868345609f18c9109f5f7a580 Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 13 Jun 2002 21:11:16 +0000 Subject: [PATCH] use NodePath interface --- panda/src/distort/nonlinearImager.I | 27 +--- panda/src/distort/nonlinearImager.cxx | 47 ++++-- panda/src/distort/nonlinearImager.h | 18 ++- panda/src/distort/projectionScreen.I | 24 +-- panda/src/distort/projectionScreen.cxx | 195 +++++++++++++++---------- panda/src/distort/projectionScreen.h | 39 +++-- 6 files changed, 199 insertions(+), 151 deletions(-) diff --git a/panda/src/distort/nonlinearImager.I b/panda/src/distort/nonlinearImager.I index bf4633b980..48f5e575a6 100644 --- a/panda/src/distort/nonlinearImager.I +++ b/panda/src/distort/nonlinearImager.I @@ -18,28 +18,15 @@ //////////////////////////////////////////////////////////////////// -// Function: NonlinearImager::set_camera +// Function: NonlinearImager::get_viewer // Access: Published -// Description: Specifies the virtual camera that will be used to -// view the various ProjectionScreens. It should be in -// the same scene graph with the ProjectionScreens, to -// establish a relative coordinate system with them. +// Description: Returns the NodePath to the LensNode that is to serve +// as the viewer for this screen, or empty if no +// viewer is associated. //////////////////////////////////////////////////////////////////// -INLINE void NonlinearImager:: -set_camera(LensNode *camera) { - _camera = camera; - _stale = true; -} - -//////////////////////////////////////////////////////////////////// -// Function: NonlinearImager::get_camera -// Access: Published -// Description: Returns the virtual camera that will be used to -// view the various ProjectionScreens. -//////////////////////////////////////////////////////////////////// -INLINE LensNode *NonlinearImager:: -get_camera() const { - return _camera; +INLINE const NodePath &NonlinearImager:: +get_viewer() const { + return _viewer; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/distort/nonlinearImager.cxx b/panda/src/distort/nonlinearImager.cxx index a62d28c686..603ebd79a5 100644 --- a/panda/src/distort/nonlinearImager.cxx +++ b/panda/src/distort/nonlinearImager.cxx @@ -249,6 +249,28 @@ get_active(int index) const { return _screens[index]._active; } +//////////////////////////////////////////////////////////////////// +// Function: NonlinearImager::set_viewer +// Access: Published +// Description: Specifies the LensNode that is to serve as the +// viewer for this screen. The relative position of +// the LensNode to the NonlinearImager, as well as the +// properties of the lens associated with the LensNode, +// determines the UV's that will be assigned to the +// geometry within the NonlinearImager. +// +// The NodePath must refer to a LensNode (or a Camera). +//////////////////////////////////////////////////////////////////// +void NonlinearImager:: +set_viewer(const NodePath &viewer) { + _viewer_node = (LensNode *)NULL; + _viewer = viewer; + _stale = true; + nassertv(!viewer.is_empty() && + viewer.node()->is_of_type(LensNode::get_class_type())); + _viewer_node = DCAST(LensNode, viewer.node()); +} + //////////////////////////////////////////////////////////////////// // Function: NonlinearImager::recompute // Access: Published @@ -263,8 +285,9 @@ recompute() { } } - if (_camera != (LensNode *)NULL && _camera->get_lens() != (Lens *)NULL) { - _camera_lens_change = _camera->get_lens()->get_last_change(); + if (_viewer_node != (LensNode *)NULL && + _viewer_node->get_lens() != (Lens *)NULL) { + _viewer_lens_change = _viewer_node->get_lens()->get_last_change(); } _stale = false; } @@ -298,10 +321,10 @@ render(GraphicsEngine *engine) { //////////////////////////////////////////////////////////////////// void NonlinearImager:: recompute_if_stale() { - if (_camera != (LensNode *)NULL && - _camera->get_lens() != (Lens *)NULL) { - UpdateSeq lens_change = _camera->get_lens()->get_last_change(); - if (_stale || lens_change != _camera_lens_change) { + if (_viewer_node != (LensNode *)NULL && + _viewer_node->get_lens() != (Lens *)NULL) { + UpdateSeq lens_change = _viewer_node->get_lens()->get_last_change(); + if (_stale || lens_change != _viewer_lens_change) { recompute(); } else { // We're not overall stale, but maybe we need to recompute one @@ -328,12 +351,12 @@ void NonlinearImager:: recompute_screen(NonlinearImager::Screen &screen) { screen._mesh.remove_node(); screen._texture.clear(); - if (_camera == (LensNode *)NULL || !screen._active) { - // Not much we can do without a camera. + if (_viewer_node == (LensNode *)NULL || !screen._active) { + // Not much we can do without a viewer. return; } - PT(PandaNode) mesh = screen._screen->make_flat_mesh(_camera); + PT(PandaNode) mesh = screen._screen->make_flat_mesh(_viewer); screen._mesh = _internal_scene.attach_new_node(mesh); PT(Texture) texture = new Texture; @@ -383,7 +406,7 @@ render_screen(GraphicsEngine *engine, NonlinearImager::Screen &screen) { screen._texture->copy(gsg, scratch_region, gsg->get_render_buffer(RenderBuffer::T_back)); - // It might be nice if we didn't through away the scratch region - // every time, which prevents us from preserving cull state from one - // frame to the next. + // It might be nice if we didn't throw away the scratch region every + // time, which prevents us from preserving cull state from one frame + // to the next. } diff --git a/panda/src/distort/nonlinearImager.h b/panda/src/distort/nonlinearImager.h index 143496eb81..66f25e1ac2 100644 --- a/panda/src/distort/nonlinearImager.h +++ b/panda/src/distort/nonlinearImager.h @@ -46,10 +46,11 @@ class GraphicsEngine; // // A NonlinearImager may be visualized as a theater room // into which a number of projection screens have been -// placed, at any arbitrary position and orientation to -// each other. Each of these projection screens -// displays the view seen by a normal perspective camera -// that exists in the world (that is, under render). +// placed, of arbitrary size and shape and at any +// arbitrary position and orientation to each other. +// Onto each of these screens is projected the view as +// seen by a normal perspective camera that exists in +// the world (that is, under render). // // There is also in the theater a single, possibly // nonlinear, camera that observes these screens. The @@ -74,8 +75,8 @@ PUBLISHED: void set_active(int index, bool active); bool get_active(int index) const; - INLINE void set_camera(LensNode *camera); - INLINE LensNode *get_camera() const; + void set_viewer(const NodePath &viewer); + INLINE const NodePath &get_viewer() const; INLINE NodePath get_internal_scene() const; @@ -103,13 +104,14 @@ private: typedef pvector Screens; Screens _screens; - PT(LensNode) _camera; + NodePath _viewer; + PT(LensNode) _viewer_node; PT(Camera) _internal_camera; NodePath _internal_scene; bool _stale; - UpdateSeq _camera_lens_change; + UpdateSeq _viewer_lens_change; }; #include "nonlinearImager.I" diff --git a/panda/src/distort/projectionScreen.I b/panda/src/distort/projectionScreen.I index f2366d79bb..a97782760b 100644 --- a/panda/src/distort/projectionScreen.I +++ b/panda/src/distort/projectionScreen.I @@ -17,31 +17,15 @@ //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Function: ProjectionScreen::set_projector -// Access: Published -// Description: Specifies the LensNode that is to serve as the -// projector for this screen. The relative position of -// the LensNode to the ProjectionScreen, as well as the -// properties of the lens associated with the LensNode, -// determines the UV's that will be assigned to the -// geometry within the ProjectionScreen. -//////////////////////////////////////////////////////////////////// -INLINE void ProjectionScreen:: -set_projector(LensNode *projector) { - _projector = projector; - _stale = true; -} - //////////////////////////////////////////////////////////////////// // Function: ProjectionScreen::get_projector // Access: Published -// Description: Returns the LensNode that is to serve as the -// projector for this screen, or NULL if no LensNode is -// associated. +// Description: Returns the NodePath to the LensNode that is to serve +// as the projector for this screen, or empty if no +// projector is associated. //////////////////////////////////////////////////////////////////// -INLINE LensNode *ProjectionScreen:: +INLINE const NodePath &ProjectionScreen:: get_projector() const { return _projector; } diff --git a/panda/src/distort/projectionScreen.cxx b/panda/src/distort/projectionScreen.cxx index 326cbce794..e6b994d472 100644 --- a/panda/src/distort/projectionScreen.cxx +++ b/panda/src/distort/projectionScreen.cxx @@ -21,6 +21,7 @@ #include "geom.h" #include "geomTristrip.h" #include "transformState.h" +#include "workingNodePath.h" TypeHandle ProjectionScreen::_type_handle; @@ -57,6 +58,7 @@ ProjectionScreen:: ProjectionScreen(const ProjectionScreen ©) : PandaNode(copy), _projector(copy._projector), + _projector_node(copy._projector_node), _vignette_on(copy._vignette_on), _vignette_color(copy._vignette_color), _frame_color(copy._frame_color) @@ -117,6 +119,28 @@ cull_callback(CullTraverser *, CullTraverserData &) { return true; } +//////////////////////////////////////////////////////////////////// +// Function: ProjectionScreen::set_projector +// Access: Published +// Description: Specifies the LensNode that is to serve as the +// projector for this screen. The relative position of +// the LensNode to the ProjectionScreen, as well as the +// properties of the lens associated with the LensNode, +// determines the UV's that will be assigned to the +// geometry within the ProjectionScreen. +// +// The NodePath must refer to a LensNode (or a Camera). +//////////////////////////////////////////////////////////////////// +void ProjectionScreen:: +set_projector(const NodePath &projector) { + _projector_node = (LensNode *)NULL; + _projector = projector; + _stale = true; + nassertv(!projector.is_empty() && + projector.node()->is_of_type(LensNode::get_class_type())); + _projector_node = DCAST(LensNode, projector.node()); +} + //////////////////////////////////////////////////////////////////// // Function: ProjectionScreen::generate_screen // Access: Published @@ -138,21 +162,23 @@ cull_callback(CullTraverser *, CullTraverserData &) { // distance of the screen from the lens center. //////////////////////////////////////////////////////////////////// PT(GeomNode) ProjectionScreen:: -generate_screen(LensNode *projector, const string &screen_name, +generate_screen(const NodePath &projector, const string &screen_name, int num_x_verts, int num_y_verts, float distance) { - nassertr(projector != (LensNode *)NULL, NULL); - nassertr(projector->get_lens() != NULL, NULL); + nassertr(!projector.is_empty() && + projector.node()->is_of_type(LensNode::get_class_type()), + NULL); + LensNode *projector_node = DCAST(LensNode, projector.node()); + nassertr(projector_node->get_lens() != NULL, NULL); // First, get the relative coordinate space of the projector. LMatrix4f rel_mat; - NodePath projector_np(projector); NodePath this_np(this); - rel_mat = projector_np.get_mat(this_np); + rel_mat = projector.get_mat(this_np); // Now compute all the vertices for the screen. These are arranged // in order from left to right and bottom to top. int num_verts = num_x_verts * num_y_verts; - Lens *lens = projector->get_lens(); + Lens *lens = projector_node->get_lens(); float t = (distance - lens->get_near()) / (lens->get_far() - lens->get_near()); PTA_Vertexf coords; @@ -234,7 +260,7 @@ generate_screen(LensNode *projector, const string &screen_name, // generate_screen(). //////////////////////////////////////////////////////////////////// void ProjectionScreen:: -regenerate_screen(LensNode *projector, const string &screen_name, +regenerate_screen(const NodePath &projector, const string &screen_name, int num_x_verts, int num_y_verts, float distance) { // First, remove all existing children. remove_all_children(); @@ -261,23 +287,27 @@ regenerate_screen(LensNode *projector, const string &screen_name, // lens, to generate the effect of seeing the image // through the specified non-linear lens. // -// The returned node has no parent; it is up to the user -// to caller to parent it somewhere or store it so that -// it does not get dereferenced and deleted. +// The returned node has no parent; it is up to the +// caller to parent it somewhere or store it so that it +// does not get dereferenced and deleted. //////////////////////////////////////////////////////////////////// PT(PandaNode) ProjectionScreen:: -make_flat_mesh(LensNode *camera) { - nassertr(camera != (LensNode *)NULL, NULL); - nassertr(camera->get_lens() != (Lens *)NULL, NULL); +make_flat_mesh(const NodePath &camera) { + nassertr(!camera.is_empty() && + camera.node()->is_of_type(LensNode::get_class_type()), + NULL); + LensNode *camera_node = DCAST(LensNode, camera.node()); + nassertr(camera_node->get_lens() != (Lens *)NULL, NULL); // First, ensure the UV's are up-to-date. recompute_if_stale(); PT(PandaNode) top = new PandaNode(get_name()); + NodePath this_np(this); LMatrix4f rel_mat; bool computed_rel_mat = false; - make_mesh_children(top, this, camera, rel_mat, computed_rel_mat); + make_mesh_children(top, this_np, camera, rel_mat, computed_rel_mat); return top; } @@ -297,19 +327,8 @@ make_flat_mesh(LensNode *camera) { //////////////////////////////////////////////////////////////////// void ProjectionScreen:: recompute() { - if (_projector != (LensNode *)NULL && - _projector->get_lens() != (Lens *)NULL) { - _colors.clear(); - _colors.push_back(_vignette_color); - _colors.push_back(_frame_color); - - recompute_node(this, _rel_top_mat, _computed_rel_top_mat); - // Make sure this flag is set to false for next time. - _computed_rel_top_mat = false; - - _projector_lens_change = _projector->get_lens()->get_last_change(); - _stale = false; - } + NodePath this_np(this); + do_recompute(this_np); } //////////////////////////////////////////////////////////////////// @@ -322,26 +341,47 @@ recompute() { //////////////////////////////////////////////////////////////////// void ProjectionScreen:: recompute_if_stale() { - if (_projector != (LensNode *)NULL && - _projector->get_lens() != (Lens *)NULL) { - UpdateSeq lens_change = _projector->get_lens()->get_last_change(); + if (_projector_node != (LensNode *)NULL && + _projector_node->get_lens() != (Lens *)NULL) { + UpdateSeq lens_change = _projector_node->get_lens()->get_last_change(); if (_stale || lens_change != _projector_lens_change) { recompute(); } else { // Get the relative transform to ensure it hasn't changed. NodePath this_np(this); - NodePath projector_np(_projector); - const LMatrix4f &top_mat = this_np.get_mat(projector_np); + const LMatrix4f &top_mat = this_np.get_mat(_projector); if (!_rel_top_mat.almost_equal(top_mat)) { _rel_top_mat = top_mat; _computed_rel_top_mat = true; - recompute(); + do_recompute(this_np); } } } } +//////////////////////////////////////////////////////////////////// +// Function: ProjectionScreen::do_recompute +// Access: Private +// Description: Starts the recomputation process. +//////////////////////////////////////////////////////////////////// +void ProjectionScreen:: +do_recompute(const NodePath &this_np) { + if (_projector_node != (LensNode *)NULL && + _projector_node->get_lens() != (Lens *)NULL) { + _colors.clear(); + _colors.push_back(_vignette_color); + _colors.push_back(_frame_color); + + recompute_node(this_np, _rel_top_mat, _computed_rel_top_mat); + // Make sure this flag is set to false for next time. + _computed_rel_top_mat = false; + + _projector_lens_change = _projector_node->get_lens()->get_last_change(); + _stale = false; + } +} + //////////////////////////////////////////////////////////////////// // Function: ProjectionScreen::recompute_node // Access: Private @@ -351,9 +391,11 @@ recompute_if_stale() { // encountered, a new relative matrix is computed. //////////////////////////////////////////////////////////////////// void ProjectionScreen:: -recompute_node(PandaNode *node, LMatrix4f &rel_mat, bool &computed_rel_mat) { +recompute_node(const WorkingNodePath &np, LMatrix4f &rel_mat, + bool &computed_rel_mat) { + PandaNode *node = np.node(); if (node->is_geom_node()) { - recompute_geom_node(DCAST(GeomNode, node), rel_mat, computed_rel_mat); + recompute_geom_node(np, rel_mat, computed_rel_mat); } // Now recurse on children. @@ -361,20 +403,20 @@ recompute_node(PandaNode *node, LMatrix4f &rel_mat, bool &computed_rel_mat) { for (int i = 0; i < num_children; i++) { PandaNode *child = node->get_child(i); - /* - This needs to be ported to new scene graph. - if (arc->has_transition(TransformTransition::get_class_type())) { - // This arc has a transform; therefore, we must recompute the - // relative matrix from this point. + const TransformState *transform = child->get_transform(); + if (!transform->is_identity()) { + // This child node has a transform; therefore, we must recompute + // the relative matrix from this point. LMatrix4f new_rel_mat; bool computed_new_rel_mat = false; - recompute_node(arc->get_child(), new_rel_mat, computed_new_rel_mat); - } else - */ + recompute_node(WorkingNodePath(np, child), new_rel_mat, + computed_new_rel_mat); - // This arc has no transform, so we can use the same transform - // space from before. - recompute_node(child, rel_mat, computed_rel_mat); + } else { + // This child has no transform, so we can use the same transform + // space from before. + recompute_node(WorkingNodePath(np, child), rel_mat, computed_rel_mat); + } } } @@ -384,13 +426,13 @@ recompute_node(PandaNode *node, LMatrix4f &rel_mat, bool &computed_rel_mat) { // Description: Recomputes the UV's just for the indicated GeomNode. //////////////////////////////////////////////////////////////////// void ProjectionScreen:: -recompute_geom_node(GeomNode *node, LMatrix4f &rel_mat, +recompute_geom_node(const WorkingNodePath &np, LMatrix4f &rel_mat, bool &computed_rel_mat) { + GeomNode *node = DCAST(GeomNode, np.node()); if (!computed_rel_mat) { // All right, time to compute the matrix. - NodePath node_np(node); - NodePath projector_np(_projector); - rel_mat = node_np.get_mat(projector_np); + NodePath true_np = np.get_node_path(); + rel_mat = true_np.get_mat(_projector); computed_rel_mat = true; } @@ -415,7 +457,7 @@ recompute_geom(Geom *geom, const LMatrix4f &rel_mat) { PTA_TexCoordf uvs; PTA_ushort color_index; - Lens *lens = _projector->get_lens(); + Lens *lens = _projector_node->get_lens(); nassertv(lens != (Lens *)NULL); // Iterate through all the vertices in the Geom. @@ -455,11 +497,13 @@ recompute_geom(Geom *geom, const LMatrix4f &rel_mat) { // below, and generates a corresponding node hierarchy // with all the geometry copied, but flattened into 2-d, // as seen from the indicated camera. Returns the newly -// created, arc, or NULL if no arc was created. +// created node, or NULL if no node was created. //////////////////////////////////////////////////////////////////// PandaNode *ProjectionScreen:: -make_mesh_node(PandaNode *result_parent, PandaNode *node, LensNode *camera, +make_mesh_node(PandaNode *result_parent, const WorkingNodePath &np, + const NodePath &camera, LMatrix4f &rel_mat, bool &computed_rel_mat) { + PandaNode *node = np.node(); if (!node->safe_to_flatten()) { // If we can't safely flatten this node, ignore it (and all of its // children) completely. It's got no business being here anyway. @@ -468,16 +512,14 @@ make_mesh_node(PandaNode *result_parent, PandaNode *node, LensNode *camera, PT(PandaNode) new_node; if (node->is_geom_node()) { - new_node = - make_mesh_geom_node(DCAST(GeomNode, node), camera, - rel_mat, computed_rel_mat); + new_node = make_mesh_geom_node(np, camera, rel_mat, computed_rel_mat); } else { new_node = node->make_copy(); } // Now attach the new node to the result. result_parent->add_child(new_node); - make_mesh_children(new_node, node, camera, rel_mat, computed_rel_mat); + make_mesh_children(new_node, np, camera, rel_mat, computed_rel_mat); return new_node; } @@ -488,28 +530,30 @@ make_mesh_node(PandaNode *result_parent, PandaNode *node, LensNode *camera, // node, calling make_mesh_node() on each one. //////////////////////////////////////////////////////////////////// void ProjectionScreen:: -make_mesh_children(PandaNode *new_node, PandaNode *node, LensNode *camera, +make_mesh_children(PandaNode *new_node, const WorkingNodePath &np, + const NodePath &camera, LMatrix4f &rel_mat, bool &computed_rel_mat) { + PandaNode *node = np.node(); int num_children = node->get_num_children(); for (int i = 0; i < num_children; i++) { PandaNode *child = node->get_child(i); PandaNode *new_child; - /* - if (arc->has_transition(TransformTransition::get_class_type())) { - // This arc has a transform; therefore, we must recompute the - // relative matrix from this point. + const TransformState *transform = child->get_transform(); + if (!transform->is_identity()) { + // This child node has a transform; therefore, we must recompute + // the relative matrix from this point. LMatrix4f new_rel_mat; bool computed_new_rel_mat = false; - new_arc = make_mesh_node(new_node, arc->get_child(), camera, - new_rel_mat, computed_new_rel_mat); - } else - */ + new_child = make_mesh_node(new_node, WorkingNodePath(np, child), camera, + new_rel_mat, computed_new_rel_mat); - // This arc has no transform, so we can use the same transform - // space from before. - new_child = make_mesh_node(new_node, child, camera, - rel_mat, computed_rel_mat); + } else { + // This child has no transform, so we can use the same transform + // space from before. + new_child = make_mesh_node(new_node, WorkingNodePath(np, child), camera, + rel_mat, computed_rel_mat); + } // Copy all of the render state (except TransformState) to the // new arc. @@ -525,15 +569,16 @@ make_mesh_children(PandaNode *new_node, PandaNode *node, LensNode *camera, // indicated camera. //////////////////////////////////////////////////////////////////// PT(GeomNode) ProjectionScreen:: -make_mesh_geom_node(GeomNode *node, LensNode *camera, +make_mesh_geom_node(const WorkingNodePath &np, const NodePath &camera, LMatrix4f &rel_mat, bool &computed_rel_mat) { + GeomNode *node = DCAST(GeomNode, np.node()); PT(GeomNode) new_node = new GeomNode(node->get_name()); + LensNode *lens_node = DCAST(LensNode, camera.node()); if (!computed_rel_mat) { // All right, time to compute the matrix. - NodePath node_np(node); - NodePath camera_np(camera); - rel_mat = node_np.get_mat(camera_np); + NodePath true_np = np.get_node_path(); + rel_mat = true_np.get_mat(camera); computed_rel_mat = true; } @@ -541,7 +586,7 @@ make_mesh_geom_node(GeomNode *node, LensNode *camera, for (int i = 0; i < num_geoms; i++) { Geom *geom = node->get_geom(i); PT(Geom) new_geom = - make_mesh_geom(geom, camera->get_lens(), rel_mat); + make_mesh_geom(geom, lens_node->get_lens(), rel_mat); if (new_geom != (Geom *)NULL) { new_node->add_geom(new_geom, node->get_geom_state(i)); } diff --git a/panda/src/distort/projectionScreen.h b/panda/src/distort/projectionScreen.h index 42d71dc99b..5fc37ffb7d 100644 --- a/panda/src/distort/projectionScreen.h +++ b/panda/src/distort/projectionScreen.h @@ -24,8 +24,10 @@ #include "pandaNode.h" #include "lensNode.h" #include "geomNode.h" +#include "nodePath.h" class Geom; +class WorkingNodePath; //////////////////////////////////////////////////////////////////// // Class : ProjectionScreen @@ -59,16 +61,16 @@ public: virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data); PUBLISHED: - INLINE void set_projector(LensNode *projector); - INLINE LensNode *get_projector() const; + void set_projector(const NodePath &projector); + INLINE const NodePath &get_projector() const; - PT(GeomNode) generate_screen(LensNode *projector, - const string &screen_name, - int num_x_verts, int num_y_verts, - float distance); - void regenerate_screen(LensNode *projector, const string &screen_name, + PT(GeomNode) generate_screen(const NodePath &projector, + const string &screen_name, + int num_x_verts, int num_y_verts, + float distance); + void regenerate_screen(const NodePath &projector, const string &screen_name, int num_x_verts, int num_y_verts, float distance); - PT(PandaNode) make_flat_mesh(LensNode *camera); + PT(PandaNode) make_flat_mesh(const NodePath &camera); INLINE void set_vignette_on(bool vignette_on); INLINE bool get_vignette_on() const; @@ -85,22 +87,27 @@ public: private: void recompute_if_stale(); - void recompute_node(PandaNode *node, LMatrix4f &rel_mat, bool &computed_rel_mat); - void recompute_geom_node(GeomNode *node, LMatrix4f &rel_mat, bool &computed_rel_mat); + void do_recompute(const NodePath &this_np); + void recompute_node(const WorkingNodePath &np, LMatrix4f &rel_mat, bool &computed_rel_mat); + void recompute_geom_node(const WorkingNodePath &np, LMatrix4f &rel_mat, bool &computed_rel_mat); void recompute_geom(Geom *geom, const LMatrix4f &rel_mat); PandaNode * - make_mesh_node(PandaNode *result_parent, PandaNode *node, LensNode *camera, + make_mesh_node(PandaNode *result_parent, const WorkingNodePath &np, + const NodePath &camera, LMatrix4f &rel_mat, bool &computed_rel_mat); - void make_mesh_children(PandaNode *new_node, PandaNode *node, - LensNode *camera, + void make_mesh_children(PandaNode *new_node, const WorkingNodePath &np, + const NodePath &camera, LMatrix4f &rel_mat, bool &computed_rel_mat); - PT(GeomNode) make_mesh_geom_node(GeomNode *node, LensNode *camera, - LMatrix4f &rel_mat, bool &computed_rel_mat); + PT(GeomNode) make_mesh_geom_node(const WorkingNodePath &np, + const NodePath &camera, + LMatrix4f &rel_mat, + bool &computed_rel_mat); PT(Geom) make_mesh_geom(Geom *geom, Lens *lens, LMatrix4f &rel_mat); - PT(LensNode) _projector; + NodePath _projector; + PT(LensNode) _projector_node; bool _vignette_on; Colorf _vignette_color; Colorf _frame_color;