refinements to nonlinearImager

This commit is contained in:
David Rose 2001-12-14 21:45:43 +00:00
parent 3dc1786fda
commit 4a5d763b17
6 changed files with 114 additions and 18 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -23,7 +23,9 @@
#include "cullFaceProperty.h"
#include <onTransition.h>
#include "nodeTransition.h"
#include "pointerTo.h"
#include "onTransition.h"
////////////////////////////////////////////////////////////////////
// Class : CullFaceTransition