Panda3D
|
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