From 4a5d763b17ed369ad0bc43d37ea7ad0728c4888a Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 14 Dec 2001 21:45:43 +0000 Subject: [PATCH] refinements to nonlinearImager --- panda/src/distort/nonlinearImager.I | 12 +++++ panda/src/distort/nonlinearImager.cxx | 63 +++++++++++++++++++++++-- panda/src/distort/nonlinearImager.h | 7 +++ panda/src/distort/projectionScreen.cxx | 40 ++++++++++++---- panda/src/distort/projectionScreen.h | 6 ++- panda/src/sgattrib/cullFaceTransition.h | 4 +- 6 files changed, 114 insertions(+), 18 deletions(-) diff --git a/panda/src/distort/nonlinearImager.I b/panda/src/distort/nonlinearImager.I index f84824bcea..2d5f4b28ea 100644 --- a/panda/src/distort/nonlinearImager.I +++ b/panda/src/distort/nonlinearImager.I @@ -41,3 +41,15 @@ INLINE LensNode *NonlinearImager:: get_camera() const { return _camera; } + +//////////////////////////////////////////////////////////////////// +// Function: NonlinearImager::get_internal_scene +// Access: Published +// Description: Returns a pointer to the root node of the internal +// scene graph, which is used to render all of the +// screen meshes. +//////////////////////////////////////////////////////////////////// +INLINE Node *NonlinearImager:: +get_internal_scene() const { + return _internal_scene_top; +} diff --git a/panda/src/distort/nonlinearImager.cxx b/panda/src/distort/nonlinearImager.cxx index 44f98a5f9b..5d6c2540da 100644 --- a/panda/src/distort/nonlinearImager.cxx +++ b/panda/src/distort/nonlinearImager.cxx @@ -24,6 +24,7 @@ #include "matrixLens.h" #include "renderRelation.h" #include "graphicsWindow.h" +#include "cullFaceTransition.h" //////////////////////////////////////////////////////////////////// // Function: NonlinearImager::Constructor @@ -40,10 +41,20 @@ NonlinearImager(DisplayRegion *dr) { _internal_camera = new Camera("NonlinearImager"); _internal_camera->set_lens(new MatrixLens); - _internal_scene = new NamedNode("NonlinearImager"); - _internal_camera->set_scene(_internal_scene); + _internal_scene_top = new NamedNode("NonlinearImager"); + _internal_scene = new NamedNode("screens"); + _internal_camera->set_scene(_internal_scene_top); _dr->set_camera(_internal_camera); + RenderRelation *top_arc = + new RenderRelation(_internal_scene_top, _internal_scene); + + // Enable face culling on the wireframe mesh. This will help us to + // cull out invalid polygons that result from vertices crossing a + // singularity (for instance, at the back of a fisheye lens). + CullFaceTransition *cfa = new CullFaceTransition(CullFaceProperty::M_cull_clockwise); + top_arc->set_transition(cfa); + _stale = true; } @@ -93,6 +104,7 @@ add_screen(ProjectionScreen *screen) { new_screen._texture = (Texture *)NULL; new_screen._tex_width = 256; new_screen._tex_height = 256; + new_screen._active = true; // If the LensNode associated with the ProjectionScreen is an actual // Camera, then it has a scene associated. Otherwise, the user will @@ -232,6 +244,43 @@ set_source(int index, Camera *source) { _screens[index]._scene = source->get_scene(); } +//////////////////////////////////////////////////////////////////// +// Function: NonlinearImager::set_active +// Access: Published +// Description: Sets the active flag on the indicated screen. If the +// active flag is true, the screen will be used; +// otherwise, it will not appear. +//////////////////////////////////////////////////////////////////// +void NonlinearImager:: +set_active(int index, bool active) { + nassertv(index >= 0 && index < (int)_screens.size()); + _screens[index]._active = active; + + if (!active) { + Screen &screen = _screens[index]; + // If we've just made this screen inactive, remove its mesh. + if (screen._mesh_arc != (NodeRelation *)NULL) { + remove_arc(screen._mesh_arc); + screen._mesh_arc = (NodeRelation *)NULL; + } + screen._texture.clear(); + } else { + // If we've just made it active, it needs to be recomputed. + _stale = true; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: NonlinearImager::get_active +// Access: Published +// Description: Returns the active flag on the indicated screen. +//////////////////////////////////////////////////////////////////// +bool NonlinearImager:: +get_active(int index) const { + nassertr(index >= 0 && index < (int)_screens.size(), false); + return _screens[index]._active; +} + //////////////////////////////////////////////////////////////////// // Function: NonlinearImager::recompute // Access: Published @@ -241,7 +290,9 @@ void NonlinearImager:: recompute() { Screens::iterator si; for (si = _screens.begin(); si != _screens.end(); ++si) { - recompute_screen(*si); + if ((*si)._active) { + recompute_screen(*si); + } } if (_camera != (LensNode *)NULL && _camera->get_lens() != (Lens *)NULL) { @@ -266,7 +317,9 @@ render() { Screens::iterator si; for (si = _screens.begin(); si != _screens.end(); ++si) { - render_screen(*si); + if ((*si)._active) { + render_screen(*si); + } } } @@ -299,7 +352,7 @@ recompute_screen(NonlinearImager::Screen &screen) { screen._mesh_arc = (NodeRelation *)NULL; } screen._texture.clear(); - if (_camera == (LensNode *)NULL) { + if (_camera == (LensNode *)NULL || !screen._active) { // Not much we can do without a camera. return; } diff --git a/panda/src/distort/nonlinearImager.h b/panda/src/distort/nonlinearImager.h index 8739dcd2af..6327e46b8a 100644 --- a/panda/src/distort/nonlinearImager.h +++ b/panda/src/distort/nonlinearImager.h @@ -61,9 +61,14 @@ PUBLISHED: void set_source(int index, LensNode *source, Node *scene); void set_source(int index, Camera *source); + void set_active(int index, bool active); + bool get_active(int index) const; + INLINE void set_camera(LensNode *camera); INLINE LensNode *get_camera() const; + INLINE Node *get_internal_scene() const; + void recompute(); void render(); @@ -76,6 +81,7 @@ private: PT(LensNode) _source; PT_Node _scene; int _tex_width, _tex_height; + bool _active; }; void recompute_if_stale(); @@ -90,6 +96,7 @@ private: PT(LensNode) _camera; PT(Camera) _internal_camera; + PT_Node _internal_scene_top; PT_Node _internal_scene; bool _stale; diff --git a/panda/src/distort/projectionScreen.cxx b/panda/src/distort/projectionScreen.cxx index 9920a7fa3f..763a0f8295 100644 --- a/panda/src/distort/projectionScreen.cxx +++ b/panda/src/distort/projectionScreen.cxx @@ -109,10 +109,10 @@ app_traverse(const ArcChain &) { // Function: ProjectionScreen::generate_screen // Access: Published // Description: Synthesizes a polygon mesh based on the projection -// area of the indicated projector. This generates a -// new GeomNode and automatically parents it to the -// ProjectionScreen; the new GeomNode is also returned -// for reference. +// area of the indicated projector. This generates and +// returns a new GeomNode but does not automatically +// parent it to the ProjectionScreen node; see +// regenerate_screen(). // // The specified projector need not be the same as the // projector given to the ProjectionScreen with @@ -125,7 +125,7 @@ app_traverse(const ArcChain &) { // respectively; distance represents the approximate // distance of the screen from the lens center. //////////////////////////////////////////////////////////////////// -GeomNode *ProjectionScreen:: +PT(GeomNode) ProjectionScreen:: generate_screen(LensNode *projector, const string &screen_name, int num_x_verts, int num_y_verts, float distance) { nassertr(projector != (LensNode *)NULL, NULL); @@ -204,16 +204,35 @@ generate_screen(LensNode *projector, const string &screen_name, geom->set_colors(colors, G_OVERALL); // Now create a GeomNode to hold this mesh. - GeomNode *geom_node = new GeomNode(screen_name); + PT(GeomNode) geom_node = new GeomNode(screen_name); geom_node->add_geom(geom); - // And parent it to ourselves. - new RenderRelation(this, geom_node); _stale = true; - return geom_node; } +//////////////////////////////////////////////////////////////////// +// Function: ProjectionScreen::regenerate_screen +// Access: Published +// Description: Removes all the children from the ProjectionScreen +// node, and adds the newly generated child returned by +// generate_screen(). +//////////////////////////////////////////////////////////////////// +void ProjectionScreen:: +regenerate_screen(LensNode *projector, const string &screen_name, + int num_x_verts, int num_y_verts, float distance) { + // First, remove all existing children. + while (get_num_children(RenderRelation::get_class_type()) > 0) { + remove_arc(get_child(RenderRelation::get_class_type(), 0)); + } + + // And attach a new child. + PT(GeomNode) geom_node = + generate_screen(projector, screen_name, num_x_verts, num_y_verts, + distance); + new RenderRelation(this, geom_node); +} + //////////////////////////////////////////////////////////////////// // Function: ProjectionScreen::make_flat_mesh // Access: Published @@ -518,7 +537,8 @@ make_mesh_geom_node(GeomNode *node, LensNode *camera, // Access: Private // Description: Makes a new Geom, just like the given one, except // flattened into two dimensions as seen by the -// indicated lens. +// indicated lens. Any triangle in the original mesh +// that involves an unprojectable vertex is eliminated. //////////////////////////////////////////////////////////////////// PT(dDrawable) ProjectionScreen:: make_mesh_geom(Geom *geom, Lens *lens, LMatrix4f &rel_mat) { diff --git a/panda/src/distort/projectionScreen.h b/panda/src/distort/projectionScreen.h index 1f1280c809..627b4a24bb 100644 --- a/panda/src/distort/projectionScreen.h +++ b/panda/src/distort/projectionScreen.h @@ -61,8 +61,10 @@ PUBLISHED: INLINE void set_projector(LensNode *projector); INLINE LensNode *get_projector() const; - GeomNode *generate_screen(LensNode *projector, const string &screen_name, - int num_x_verts, int num_y_verts, float distance); + 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, + int num_x_verts, int num_y_verts, float distance); PT_Node make_flat_mesh(LensNode *camera); INLINE void set_vignette_on(bool vignette_on); diff --git a/panda/src/sgattrib/cullFaceTransition.h b/panda/src/sgattrib/cullFaceTransition.h index b88707c6c3..62de63455c 100644 --- a/panda/src/sgattrib/cullFaceTransition.h +++ b/panda/src/sgattrib/cullFaceTransition.h @@ -23,7 +23,9 @@ #include "cullFaceProperty.h" -#include +#include "nodeTransition.h" +#include "pointerTo.h" +#include "onTransition.h" //////////////////////////////////////////////////////////////////// // Class : CullFaceTransition