Panda3D
|
00001 // Filename: lens.h 00002 // Created by: drose (18Feb99) 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 LENS_H 00016 #define LENS_H 00017 00018 #include "pandabase.h" 00019 00020 #include "typedWritableReferenceCount.h" 00021 #include "luse.h" 00022 #include "geom.h" 00023 #include "updateSeq.h" 00024 #include "geomVertexData.h" 00025 #include "pointerTo.h" 00026 #include "cycleData.h" 00027 #include "cycleDataReader.h" 00028 #include "cycleDataWriter.h" 00029 #include "pipelineCycler.h" 00030 00031 class BoundingVolume; 00032 00033 //////////////////////////////////////////////////////////////////// 00034 // Class : Lens 00035 // Description : A base class for any number of different kinds of 00036 // lenses, linear and otherwise. Presently, this 00037 // includes perspective and orthographic lenses. 00038 // 00039 // A Lens object is the main part of a Camera node, 00040 // which defines the fundamental interface to 00041 // point-of-view for rendering. Lenses are also used in 00042 // other contexts, however; for instance, a Spotlight is 00043 // also defined using a lens. 00044 //////////////////////////////////////////////////////////////////// 00045 class EXPCL_PANDA_GOBJ Lens : public TypedWritableReferenceCount { 00046 public: 00047 Lens(); 00048 Lens(const Lens ©); 00049 void operator = (const Lens ©); 00050 00051 PUBLISHED: 00052 enum StereoChannel { 00053 SC_mono = 0x00, 00054 SC_left = 0x01, 00055 SC_right = 0x02, 00056 SC_stereo = 0x03, // == SC_left | SC_right 00057 }; 00058 00059 virtual PT(Lens) make_copy() const=0; 00060 00061 INLINE bool extrude(const LPoint2 &point2d, 00062 LPoint3 &near_point, LPoint3 &far_point) const; 00063 INLINE bool extrude(const LPoint3 &point2d, 00064 LPoint3 &near_point, LPoint3 &far_point) const; 00065 INLINE bool extrude_vec(const LPoint2 &point2d, LVector3 &vec3d) const; 00066 INLINE bool extrude_vec(const LPoint3 &point2d, LVector3 &vec3d) const; 00067 INLINE bool project(const LPoint3 &point3d, LPoint3 &point2d) const; 00068 INLINE bool project(const LPoint3 &point3d, LPoint2 &point2d) const; 00069 00070 INLINE void set_change_event(const string &event); 00071 INLINE const string &get_change_event() const; 00072 00073 void set_coordinate_system(CoordinateSystem cs); 00074 INLINE CoordinateSystem get_coordinate_system() const; 00075 00076 void clear(); 00077 00078 INLINE void set_film_size(PN_stdfloat width); 00079 INLINE void set_film_size(PN_stdfloat width, PN_stdfloat height); 00080 INLINE void set_film_size(const LVecBase2 &film_size); 00081 INLINE const LVecBase2 &get_film_size() const; 00082 00083 INLINE void set_film_offset(PN_stdfloat x, PN_stdfloat y); 00084 INLINE void set_film_offset(const LVecBase2 &film_offset); 00085 INLINE const LVector2 &get_film_offset() const; 00086 00087 INLINE void set_focal_length(PN_stdfloat focal_length); 00088 INLINE PN_stdfloat get_focal_length() const; 00089 00090 void set_min_fov(PN_stdfloat min_fov); 00091 INLINE void set_fov(PN_stdfloat fov); 00092 INLINE void set_fov(PN_stdfloat hfov, PN_stdfloat vfov); 00093 INLINE void set_fov(const LVecBase2 &fov); 00094 INLINE const LVecBase2 &get_fov() const; 00095 INLINE PN_stdfloat get_hfov() const; 00096 INLINE PN_stdfloat get_vfov() const; 00097 PN_stdfloat get_min_fov() const; 00098 00099 INLINE void set_aspect_ratio(PN_stdfloat aspect_ratio); 00100 INLINE PN_stdfloat get_aspect_ratio() const; 00101 00102 INLINE void set_near(PN_stdfloat near_distance); 00103 INLINE PN_stdfloat get_near() const; 00104 INLINE void set_far(PN_stdfloat far_distance); 00105 INLINE PN_stdfloat get_far() const; 00106 INLINE void set_near_far(PN_stdfloat near_distance, PN_stdfloat far_distance); 00107 00108 static PN_stdfloat get_default_near(); 00109 static PN_stdfloat get_default_far(); 00110 00111 INLINE void set_view_hpr(PN_stdfloat h, PN_stdfloat p, PN_stdfloat r); 00112 void set_view_hpr(const LVecBase3 &view_hpr); 00113 const LVecBase3 &get_view_hpr() const; 00114 INLINE void set_view_vector(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat i, PN_stdfloat j, PN_stdfloat k); 00115 void set_view_vector(const LVector3 &view_vector, const LVector3 &up_vector); 00116 const LVector3 &get_view_vector() const; 00117 const LVector3 &get_up_vector() const; 00118 LPoint3 get_nodal_point() const; 00119 00120 INLINE void set_interocular_distance(PN_stdfloat interocular_distance); 00121 INLINE PN_stdfloat get_interocular_distance() const; 00122 INLINE void set_convergence_distance(PN_stdfloat convergence_distance); 00123 INLINE PN_stdfloat get_convergence_distance() const; 00124 00125 INLINE void set_view_mat(const LMatrix4 &view_mat); 00126 INLINE const LMatrix4 &get_view_mat() const; 00127 void clear_view_mat(); 00128 00129 void set_keystone(const LVecBase2 &keystone); 00130 INLINE const LVecBase2 &get_keystone() const; 00131 void clear_keystone(); 00132 00133 // These flags are passed in as the last parameter to control the 00134 // behavior of set_frustum_from_corners(). See the documentation 00135 // for that method for an explanation of each flag. 00136 enum FromCorners { 00137 FC_roll = 0x0001, 00138 FC_camera_plane = 0x0002, 00139 FC_off_axis = 0x0004, 00140 FC_aspect_ratio = 0x0008, 00141 FC_shear = 0x0010, 00142 FC_keystone = 0x0020, 00143 }; 00144 void set_frustum_from_corners(const LVecBase3 &ul, const LVecBase3 &ur, 00145 const LVecBase3 &ll, const LVecBase3 &lr, 00146 int flags); 00147 00148 void recompute_all(); 00149 00150 virtual bool is_linear() const; 00151 virtual bool is_perspective() const; 00152 virtual bool is_orthographic() const; 00153 virtual PT(Geom) make_geometry(); 00154 00155 virtual PT(BoundingVolume) make_bounds() const; 00156 00157 INLINE const LMatrix4 &get_projection_mat(StereoChannel channel = SC_mono) const; 00158 INLINE const LMatrix4 &get_projection_mat_inv(StereoChannel channel = SC_mono) const; 00159 00160 INLINE const LMatrix4 &get_film_mat() const; 00161 INLINE const LMatrix4 &get_film_mat_inv() const; 00162 00163 INLINE const LMatrix4 &get_lens_mat() const; 00164 INLINE const LMatrix4 &get_lens_mat_inv() const; 00165 00166 virtual void output(ostream &out) const; 00167 virtual void write(ostream &out, int indent_level = 0) const; 00168 00169 INLINE UpdateSeq get_last_change() const; 00170 00171 protected: 00172 class CData; 00173 00174 INLINE void do_adjust_user_flags(CData *cdata, int clear_flags, int set_flags); 00175 INLINE void do_adjust_comp_flags(CData *cdata, int clear_flags, int set_flags); 00176 00177 void do_set_film_size(CData *cdata, PN_stdfloat width); 00178 void do_set_film_size(CData *cdata, const LVecBase2 &film_size); 00179 const LVecBase2 &do_get_film_size(const CData *cdata) const; 00180 00181 INLINE void do_set_film_offset(CData *cdata, const LVecBase2 &film_offset); 00182 INLINE const LVector2 &do_get_film_offset(const CData *cdata) const; 00183 00184 void do_set_focal_length(CData *cdata, PN_stdfloat focal_length); 00185 PN_stdfloat do_get_focal_length(const CData *cdata) const; 00186 00187 void do_set_fov(CData *cdata, PN_stdfloat fov); 00188 void do_set_fov(CData *cdata, const LVecBase2 &fov); 00189 const LVecBase2 &do_get_fov(const CData *cdata) const; 00190 00191 void do_set_aspect_ratio(CData *cdata, PN_stdfloat aspect_ratio); 00192 PN_stdfloat do_get_aspect_ratio(const CData *cdata) const; 00193 00194 INLINE void do_set_near(CData *cdata, PN_stdfloat near_distance); 00195 INLINE PN_stdfloat do_get_near(const CData *cdata) const; 00196 INLINE void do_set_far(CData *cdata, PN_stdfloat far_distance); 00197 INLINE PN_stdfloat do_get_far(const CData *cdata) const; 00198 INLINE void do_set_near_far(CData *cdata, PN_stdfloat near_distance, PN_stdfloat far_distance); 00199 00200 const LMatrix4 &do_get_projection_mat(const CData *cdata, StereoChannel channel = SC_mono) const; 00201 const LMatrix4 &do_get_projection_mat_inv(const CData *cdata, StereoChannel channel = SC_mono) const; 00202 00203 const LMatrix4 &do_get_film_mat(const CData *cdata) const; 00204 const LMatrix4 &do_get_film_mat_inv(const CData *cdata) const; 00205 00206 const LMatrix4 &do_get_lens_mat(const CData *cdata) const; 00207 const LMatrix4 &do_get_lens_mat_inv(const CData *cdata) const; 00208 00209 void do_set_interocular_distance(CData *cdata, PN_stdfloat interocular_distance); 00210 void do_set_convergence_distance(CData *cdata, PN_stdfloat convergence_distance); 00211 00212 void do_set_view_mat(CData *cdata, const LMatrix4 &view_mat); 00213 const LMatrix4 &do_get_view_mat(const CData *cdata) const; 00214 00215 void do_throw_change_event(CData *cdata); 00216 00217 virtual bool do_extrude(const CData *cdata, const LPoint3 &point2d, 00218 LPoint3 &near_point, LPoint3 &far_point) const; 00219 virtual bool do_extrude_vec(const CData *cdata, 00220 const LPoint3 &point2d, LVector3 &vec) const; 00221 virtual bool do_project(const CData *cdata, 00222 const LPoint3 &point3d, LPoint3 &point2d) const; 00223 00224 virtual void do_compute_film_size(CData *cdata); 00225 virtual void do_compute_focal_length(CData *cdata); 00226 virtual void do_compute_fov(CData *cdata); 00227 virtual void do_compute_aspect_ratio(CData *cdata); 00228 virtual void do_compute_view_hpr(CData *cdata); 00229 virtual void do_compute_view_vector(CData *cdata); 00230 virtual void do_compute_projection_mat(CData *cdata); 00231 virtual void do_compute_film_mat(CData *cdata); 00232 virtual void do_compute_lens_mat(CData *cdata); 00233 00234 virtual PN_stdfloat fov_to_film(PN_stdfloat fov, PN_stdfloat focal_length, bool horiz) const; 00235 virtual PN_stdfloat fov_to_focal_length(PN_stdfloat fov, PN_stdfloat film_size, bool horiz) const; 00236 virtual PN_stdfloat film_to_fov(PN_stdfloat film_size, PN_stdfloat focal_length, bool horiz) const; 00237 00238 private: 00239 void do_resequence_fov_triad(const CData *cdata, 00240 char &newest, char &older_a, char &older_b) const; 00241 int do_define_geom_data(CData *cdata); 00242 static void build_shear_mat(LMatrix4 &shear_mat, 00243 const LPoint3 &cul, const LPoint3 &cur, 00244 const LPoint3 &cll, const LPoint3 &clr); 00245 static PN_stdfloat sqr_dist_to_line(const LPoint3 &point, const LPoint3 &origin, 00246 const LVector3 &vec); 00247 00248 protected: 00249 enum UserFlags { 00250 // Parameters the user may have explicitly specified. 00251 UF_film_width = 0x0001, 00252 UF_film_height = 0x0002, 00253 UF_focal_length = 0x0004, 00254 UF_hfov = 0x0008, 00255 UF_vfov = 0x0010, 00256 UF_aspect_ratio = 0x0020, 00257 UF_view_hpr = 0x0040, 00258 UF_view_vector = 0x0080, 00259 UF_interocular_distance = 0x0100, 00260 UF_convergence_distance = 0x0200, 00261 UF_view_mat = 0x0400, 00262 UF_keystone = 0x0800, 00263 UF_min_fov = 0x1000, 00264 }; 00265 00266 enum CompFlags { 00267 // Values that may need to be recomputed. 00268 CF_film_mat = 0x0001, 00269 CF_film_mat_inv = 0x0002, 00270 CF_lens_mat = 0x0004, 00271 CF_lens_mat_inv = 0x0008, 00272 CF_projection_mat = 0x0010, 00273 CF_projection_mat_inv = 0x0020, 00274 CF_projection_mat_left_inv = 0x0040, 00275 CF_projection_mat_right_inv = 0x0080, 00276 CF_mat = 0x00ff, // all of the above. 00277 00278 CF_film_size = 0x0100, 00279 CF_aspect_ratio = 0x0200, 00280 CF_view_hpr = 0x0400, 00281 CF_view_vector = 0x0800, 00282 CF_focal_length = 0x1000, 00283 CF_fov = 0x2000, 00284 }; 00285 00286 // This is the data that must be cycled between pipeline stages. 00287 class EXPCL_PANDA_GOBJ CData : public CycleData { 00288 public: 00289 CData(); 00290 CData(const CData ©); 00291 ALLOC_DELETED_CHAIN(CData); 00292 virtual CycleData *make_copy() const; 00293 virtual void write_datagram(BamWriter *manager, Datagram &dg) const; 00294 virtual void fillin(DatagramIterator &scan, BamReader *manager); 00295 virtual TypeHandle get_parent_type() const { 00296 return Lens::get_class_type(); 00297 } 00298 00299 void clear(); 00300 00301 string _change_event; 00302 UpdateSeq _last_change; 00303 CoordinateSystem _cs; 00304 00305 LVecBase2 _film_size; 00306 LVector2 _film_offset; 00307 PN_stdfloat _focal_length; 00308 LVecBase2 _fov; 00309 PN_stdfloat _min_fov; 00310 PN_stdfloat _aspect_ratio; 00311 PN_stdfloat _near_distance, _far_distance; 00312 00313 LVecBase3 _view_hpr; 00314 LVector3 _view_vector, _up_vector; 00315 PN_stdfloat _interocular_distance; 00316 PN_stdfloat _convergence_distance; 00317 LVecBase2 _keystone; 00318 00319 LMatrix4 _film_mat, _film_mat_inv; 00320 LMatrix4 _lens_mat, _lens_mat_inv; 00321 LMatrix4 _projection_mat, _projection_mat_inv; 00322 LMatrix4 _projection_mat_left, _projection_mat_left_inv; 00323 LMatrix4 _projection_mat_right, _projection_mat_right_inv; 00324 00325 short _user_flags; 00326 short _comp_flags; 00327 00328 // The user may only specify two of these three parameters. 00329 // Specifying the third parameter wipes out the first one specified. 00330 // We therefore need to remember the order in which the user has 00331 // specified these three parameters. A bit of a mess. 00332 char _focal_length_seq, _fov_seq, _film_size_seq; 00333 00334 PT(GeomVertexData) _geom_data; 00335 00336 public: 00337 static TypeHandle get_class_type() { 00338 return _type_handle; 00339 } 00340 static void init_type() { 00341 register_type(_type_handle, "Lens::CData"); 00342 } 00343 00344 private: 00345 static TypeHandle _type_handle; 00346 }; 00347 00348 PipelineCycler<CData> _cycler; 00349 typedef CycleDataReader<CData> CDReader; 00350 typedef CycleDataWriter<CData> CDWriter; 00351 00352 public: 00353 virtual void write_datagram(BamWriter *manager, Datagram &dg); 00354 00355 protected: 00356 void fillin(DatagramIterator &scan, BamReader *manager); 00357 00358 public: 00359 virtual TypeHandle get_type() const { 00360 return get_class_type(); 00361 } 00362 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00363 static TypeHandle get_class_type() { 00364 return _type_handle; 00365 } 00366 static void init_type() { 00367 TypedWritableReferenceCount::init_type(); 00368 register_type(_type_handle, "Lens", 00369 TypedWritableReferenceCount::get_class_type()); 00370 CData::init_type(); 00371 } 00372 00373 private: 00374 static TypeHandle _type_handle; 00375 }; 00376 00377 EXPCL_PANDA_GOBJ INLINE ostream &operator << (ostream &out, const Lens &lens); 00378 00379 #include "lens.I" 00380 00381 #endif 00382