Panda3D

nonlinearImager.h

00001 // Filename: nonlinearImager.h
00002 // Created by:  drose (12Dec01)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #ifndef NONLINEARIMAGER_H
00016 #define NONLINEARIMAGER_H
00017 
00018 #include "pandabase.h"
00019 
00020 #include "projectionScreen.h"
00021 #include "displayRegion.h"
00022 #include "graphicsOutput.h"
00023 #include "camera.h"
00024 #include "texture.h"
00025 #include "pandaNode.h"
00026 #include "nodePath.h"
00027 #include "pointerTo.h"
00028 #include "pvector.h"
00029 #include "graphicsEngine.h"
00030 #include "callbackObject.h"
00031 #include "asyncTask.h"
00032 
00033 class GraphicsEngine;
00034 class GraphicsStateGuardian;
00035 class GraphicsOutput;
00036 class GenericAsyncTask;
00037 
00038 ////////////////////////////////////////////////////////////////////
00039 //       Class : NonlinearImager
00040 // Description : This class object combines the rendered output of a
00041 //               3-d from one or more linear (e.g. perspective)
00042 //               cameras, as seen through a single, possibly nonlinear
00043 //               camera.
00044 //
00045 //               This can be used to generate real-time imagery of a
00046 //               3-d scene using a nonlinear camera, for instance a
00047 //               fisheye camera, even though the underlying graphics
00048 //               engine may only support linear cameras.  It can also
00049 //               pre-distort imagery to compensate for off-axis
00050 //               projectors, and/or curved screens of any complexity.
00051 //
00052 //               
00053 //               A NonlinearImager may be visualized as a dark room
00054 //               into which a number of projection screens have been
00055 //               placed, of arbitrary size and shape and at any
00056 //               arbitrary position and orientation to each other.
00057 //               Onto each of these screens is projected the view as
00058 //               seen by a normal perspective camera that exists in
00059 //               the world (that is, under render).
00060 //
00061 //               There also exist in the room one or more (possibly
00062 //               nonlinear) cameras, called viewers, that observe
00063 //               these screens.  The image of the projection screens
00064 //               seen by each viewer is finally displayed on the
00065 //               viewer's associated DisplayRegion.  By placing the
00066 //               viewer(s) appropriately relative to the screens, and
00067 //               by choosing suitable lens properties for the
00068 //               viewer(s), you can achieve a wide variety of
00069 //               distortion effects.
00070 //
00071 //
00072 //               There are several different LensNode (Camera) objects
00073 //               involved at each stage in the process.  To help keep
00074 //               them all straight, different words are used to refer
00075 //               to each different kind of Camera used within this
00076 //               object.  The camera(s) under render, that capture the
00077 //               original view of the world to be projected onto the
00078 //               screens, are called source cameras, and are set per
00079 //               screen via set_source_camera().  The LensNode that is
00080 //               associated with each screen to project the image as
00081 //               seen from the screen's source camera is called a
00082 //               projector; these are set via the
00083 //               ProjectionScreen::set_projector() interface.
00084 //               Finally, the cameras that view the whole
00085 //               configuration of screens are called viewers; each of
00086 //               these is associated with a DisplayRegion, and they
00087 //               are set via set_viewer_camera().
00088 //
00089 //               Of all these lenses, only the source cameras must use
00090 //               linear (that is, perspective or orthographic) lenses.
00091 //               The projectors and viewers may be any arbitrary lens,
00092 //               linear or otherwise.
00093 ////////////////////////////////////////////////////////////////////
00094 class EXPCL_PANDAFX NonlinearImager {
00095 PUBLISHED:
00096   NonlinearImager();
00097   ~NonlinearImager();
00098 
00099   int add_screen(ProjectionScreen *screen);
00100   int add_screen(const NodePath &screen, const string &name);
00101   int find_screen(const NodePath &screen) const;
00102   void remove_screen(int index);
00103   void remove_all_screens();
00104 
00105   int get_num_screens() const;
00106   NodePath get_screen(int index) const;
00107   MAKE_SEQ(get_screens, get_num_screens, get_screen);
00108   GraphicsOutput *get_buffer(int index) const;
00109   MAKE_SEQ(get_buffers, get_num_screens, get_buffer);
00110 
00111   void set_texture_size(int index, int width, int height);
00112   void set_source_camera(int index, const NodePath &source_camera);
00113 
00114   void set_screen_active(int index, bool active);
00115   bool get_screen_active(int index) const;
00116 
00117   int add_viewer(DisplayRegion *dr);
00118   int find_viewer(DisplayRegion *dr) const;
00119   void remove_viewer(int index);
00120   void remove_all_viewers();
00121 
00122   void set_viewer_camera(int index, const NodePath &viewer_camera);
00123   NodePath get_viewer_camera(int index) const;
00124   NodePath get_viewer_scene(int index) const;
00125 
00126   int get_num_viewers() const;
00127   DisplayRegion *get_viewer(int index) const;
00128   MAKE_SEQ(get_viewers, get_num_viewers, get_viewer);
00129 
00130   NodePath get_dark_room() const;
00131   GraphicsEngine *get_graphics_engine() const;
00132 
00133   void recompute();
00134 
00135 public:
00136   static AsyncTask::DoneStatus recompute_callback(GenericAsyncTask *task, void *data);
00137   void recompute_if_stale();
00138 
00139 private:
00140   class Viewer {
00141   public:
00142     PT(DisplayRegion) _dr;
00143     PT(Camera) _internal_camera;
00144     NodePath _internal_scene;
00145     NodePath _viewer;
00146     PT(LensNode) _viewer_node;
00147     UpdateSeq _viewer_lens_change;
00148   };
00149   typedef pvector<Viewer> Viewers;
00150 
00151   class Mesh {
00152   public:
00153     NodePath _mesh;
00154     UpdateSeq _last_screen;
00155   };
00156   typedef pvector<Mesh> Meshes;
00157 
00158   class Screen {
00159   public:
00160     NodePath _screen;
00161     PT(ProjectionScreen) _screen_node;
00162     string _name;
00163     PT(GraphicsOutput) _buffer;
00164     NodePath _source_camera;
00165     int _tex_width, _tex_height;
00166     bool _active;
00167 
00168     // One mesh per viewer.
00169     Meshes _meshes;
00170   };
00171   typedef pvector<Screen> Screens;
00172 
00173   void recompute_screen(Screen &screen, size_t vi);
00174   void render_screen(GraphicsEngine *engine, Screen &screen);
00175 
00176   Viewers _viewers;
00177   Screens _screens;
00178 
00179   PT(GraphicsEngine) _engine;
00180   PT(AsyncTask) _recompute_task;
00181   NodePath _dark_room;
00182 
00183   bool _stale;
00184 };
00185 
00186 #include "nonlinearImager.I"
00187 
00188 #endif
 All Classes Functions Variables Enumerations