lens.h

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 
00027 class BoundingVolume;
00028 
00029 ////////////////////////////////////////////////////////////////////
00030 //       Class : Lens
00031 // Description : A base class for any number of different kinds of
00032 //               lenses, linear and otherwise.  Presently, this
00033 //               includes perspective and orthographic lenses.
00034 //
00035 //               A Lens object is the main part of a Camera node
00036 //               (defined in sgraph), which defines the fundamental
00037 //               interface to point-of-view for rendering.  Lenses are
00038 //               also used in other contexts, however; for instance, a
00039 //               Spotlight is also defined using a lens.
00040 ////////////////////////////////////////////////////////////////////
00041 class EXPCL_PANDA_GOBJ Lens : public TypedWritableReferenceCount {
00042 public:
00043   Lens();
00044   Lens(const Lens &copy);
00045   void operator = (const Lens &copy);
00046 
00047 PUBLISHED:
00048   enum StereoChannel {
00049     SC_mono    = 0x00,
00050     SC_left    = 0x01,
00051     SC_right   = 0x02,
00052     SC_stereo  = 0x03,  // == SC_left | SC_right
00053   };
00054 
00055   virtual PT(Lens) make_copy() const=0;
00056 
00057   INLINE bool extrude(const LPoint2f &point2d,
00058                       LPoint3f &near_point, LPoint3f &far_point) const;
00059   INLINE bool extrude(const LPoint3f &point2d,
00060                       LPoint3f &near_point, LPoint3f &far_point) const;
00061   INLINE bool extrude_vec(const LPoint2f &point2d, LVector3f &vec3d) const;
00062   INLINE bool extrude_vec(const LPoint3f &point2d, LVector3f &vec3d) const;
00063   INLINE bool project(const LPoint3f &point3d, LPoint3f &point2d) const;
00064   INLINE bool project(const LPoint3f &point3d, LPoint2f &point2d) const;
00065 
00066   INLINE void set_change_event(const string &event);
00067   INLINE const string &get_change_event() const;
00068 
00069   void set_coordinate_system(CoordinateSystem cs);
00070   INLINE CoordinateSystem get_coordinate_system() const;
00071 
00072   void clear();
00073 
00074   void set_film_size(float width);
00075   INLINE void set_film_size(float width, float height);
00076   void set_film_size(const LVecBase2f &film_size);
00077   const LVecBase2f &get_film_size() const;
00078 
00079   INLINE void set_film_offset(float x, float y);
00080   INLINE void set_film_offset(const LVecBase2f &film_offset);
00081   INLINE const LVector2f &get_film_offset() const;
00082 
00083   void set_focal_length(float focal_length);
00084   float get_focal_length() const;
00085 
00086   void set_min_fov(float min_fov);
00087   void set_fov(float fov);
00088   INLINE void set_fov(float hfov, float vfov);
00089   void set_fov(const LVecBase2f &fov);
00090   const LVecBase2f &get_fov() const;
00091   INLINE float get_hfov() const;
00092   INLINE float get_vfov() const;
00093   float get_min_fov() const;
00094 
00095   void set_aspect_ratio(float aspect_ratio);
00096   float get_aspect_ratio() const;
00097 
00098   INLINE void set_near(float near_distance);
00099   INLINE float get_near() const;
00100   INLINE void set_far(float far_distance);
00101   INLINE float get_far() const;
00102   INLINE void set_near_far(float near_distance, float far_distance);
00103 
00104   static float get_default_near();
00105   static float get_default_far();
00106   
00107   INLINE void set_view_hpr(float h, float p, float r);
00108   void set_view_hpr(const LVecBase3f &view_hpr);
00109   const LVecBase3f &get_view_hpr() const;
00110   INLINE void set_view_vector(float x, float y, float z, float i, float j, float k);
00111   void set_view_vector(const LVector3f &view_vector, const LVector3f &up_vector);
00112   const LVector3f &get_view_vector() const;
00113   const LVector3f &get_up_vector() const;
00114   LPoint3f get_nodal_point() const;
00115 
00116   void set_interocular_distance(float interocular_distance);
00117   float get_interocular_distance() const;
00118   void set_convergence_distance(float convergence_distance);
00119   float get_convergence_distance() const;
00120 
00121   void set_view_mat(const LMatrix4f &view_mat);
00122   const LMatrix4f &get_view_mat() const;
00123   void clear_view_mat();
00124 
00125   void set_keystone(const LVecBase2f &keystone);
00126   INLINE const LVecBase2f &get_keystone() const;
00127   void clear_keystone();
00128   
00129   // These flags are passed in as the last parameter to control the
00130   // behavior of set_frustum_from_corners().  See the documentation
00131   // for that method for an explanation of each flag.
00132   enum FromCorners {
00133     FC_roll         = 0x0001,
00134     FC_camera_plane = 0x0002,
00135     FC_off_axis     = 0x0004,
00136     FC_aspect_ratio = 0x0008,
00137     FC_shear        = 0x0010,
00138     FC_keystone     = 0x0020,
00139   };
00140   void set_frustum_from_corners(const LVecBase3f &ul, const LVecBase3f &ur,
00141                                 const LVecBase3f &ll, const LVecBase3f &lr,
00142                                 int flags);
00143 
00144   void recompute_all();
00145 
00146   virtual bool is_linear() const;
00147   virtual bool is_perspective() const;
00148   virtual bool is_orthographic() const;
00149   virtual PT(Geom) make_geometry();
00150 
00151   virtual PT(BoundingVolume) make_bounds() const;
00152 
00153   const LMatrix4f &get_projection_mat(StereoChannel channel = SC_mono) const;
00154   const LMatrix4f &get_projection_mat_inv(StereoChannel channel = SC_mono) const;
00155 
00156   const LMatrix4f &get_film_mat() const;
00157   const LMatrix4f &get_film_mat_inv() const;
00158 
00159   const LMatrix4f &get_lens_mat() const;
00160   const LMatrix4f &get_lens_mat_inv() const;
00161 
00162   virtual void output(ostream &out) const;
00163   virtual void write(ostream &out, int indent_level = 0) const;
00164 
00165 public:
00166   INLINE const UpdateSeq &get_last_change() const;
00167 
00168 protected:
00169   INLINE void adjust_user_flags(int clear_flags, int set_flags);
00170   INLINE void adjust_comp_flags(int clear_flags, int set_flags);
00171 
00172   void throw_change_event();
00173 
00174   virtual bool extrude_impl(const LPoint3f &point2d,
00175                             LPoint3f &near_point, LPoint3f &far_point) const;
00176   virtual bool extrude_vec_impl(const LPoint3f &point2d, LVector3f &vec) const;
00177   virtual bool project_impl(const LPoint3f &point3d, LPoint3f &point2d) const;
00178 
00179   virtual void compute_film_size();
00180   virtual void compute_focal_length();
00181   virtual void compute_fov();
00182   virtual void compute_aspect_ratio();
00183   virtual void compute_view_hpr();
00184   virtual void compute_view_vector();
00185   virtual void compute_projection_mat();
00186   virtual void compute_film_mat();
00187   virtual void compute_lens_mat();
00188 
00189   virtual float fov_to_film(float fov, float focal_length, bool horiz) const;
00190   virtual float fov_to_focal_length(float fov, float film_size, bool horiz) const;
00191   virtual float film_to_fov(float film_size, float focal_length, bool horiz) const;
00192 
00193 private:
00194   static void resequence_fov_triad(char &newest, char &older_a, char &older_b);
00195   int define_geom_data();
00196   static void build_shear_mat(LMatrix4f &shear_mat,
00197                               const LPoint3f &cul, const LPoint3f &cur,
00198                               const LPoint3f &cll, const LPoint3f &clr);
00199   static float sqr_dist_to_line(const LPoint3f &point, const LPoint3f &origin, 
00200                                 const LVector3f &vec);
00201 
00202 protected:
00203   string _change_event;
00204   UpdateSeq _last_change;
00205   CoordinateSystem _cs;
00206 
00207   LVecBase2f _film_size;
00208   LVector2f _film_offset;
00209   float _focal_length;
00210   LVecBase2f _fov;
00211   float _min_fov;
00212   float _aspect_ratio;
00213   float _near_distance, _far_distance;
00214 
00215   LVecBase3f _view_hpr;
00216   LVector3f _view_vector, _up_vector;
00217   float _interocular_distance;
00218   float _convergence_distance;
00219   LVecBase2f _keystone;
00220 
00221   LMatrix4f _film_mat, _film_mat_inv;
00222   LMatrix4f _lens_mat, _lens_mat_inv;
00223   LMatrix4f _projection_mat, _projection_mat_inv;
00224   LMatrix4f _projection_mat_left, _projection_mat_left_inv;
00225   LMatrix4f _projection_mat_right, _projection_mat_right_inv;
00226 
00227   enum UserFlags {
00228     // Parameters the user may have explicitly specified.
00229     UF_film_width           = 0x0001,
00230     UF_film_height          = 0x0002,
00231     UF_focal_length         = 0x0004,
00232     UF_hfov                 = 0x0008,
00233     UF_vfov                 = 0x0010,
00234     UF_aspect_ratio         = 0x0020,
00235     UF_view_hpr             = 0x0040,
00236     UF_view_vector          = 0x0080,
00237     UF_interocular_distance = 0x0100,
00238     UF_convergence_distance = 0x0200,
00239     UF_view_mat             = 0x0400,
00240     UF_keystone             = 0x0800,
00241     UF_min_fov              = 0x1000,
00242   };
00243 
00244   enum CompFlags {
00245     // Values that may need to be recomputed.
00246     CF_film_mat            = 0x0001,
00247     CF_film_mat_inv        = 0x0002,
00248     CF_lens_mat            = 0x0004,
00249     CF_lens_mat_inv        = 0x0008,
00250     CF_projection_mat      = 0x0010,
00251     CF_projection_mat_inv  = 0x0020,
00252     CF_projection_mat_left_inv  = 0x0040,
00253     CF_projection_mat_right_inv = 0x0080,
00254     CF_mat                 = 0x00ff,  // all of the above.
00255 
00256     CF_film_size           = 0x0100,
00257     CF_aspect_ratio        = 0x0200,
00258     CF_view_hpr            = 0x0400,
00259     CF_view_vector         = 0x0800,
00260     CF_focal_length        = 0x1000,
00261     CF_fov                 = 0x2000,
00262   };
00263   short _user_flags;
00264   short _comp_flags;
00265 
00266   // The user may only specify two of these three parameters.
00267   // Specifying the third parameter wipes out the first one specified.
00268   // We therefore need to remember the order in which the user has
00269   // specified these three parameters.  A bit of a mess.
00270   char _focal_length_seq, _fov_seq, _film_size_seq;
00271 
00272   PT(GeomVertexData) _geom_data;
00273 
00274 public:
00275   virtual void write_datagram(BamWriter *manager, Datagram &dg);
00276 
00277 protected:
00278   void fillin(DatagramIterator &scan, BamReader *manager);
00279 
00280 public:
00281   virtual TypeHandle get_type() const {
00282     return get_class_type();
00283   }
00284   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00285   static TypeHandle get_class_type() {
00286     return _type_handle;
00287   }
00288   static void init_type() {
00289     TypedWritableReferenceCount::init_type();
00290     register_type(_type_handle, "Lens",
00291                   TypedWritableReferenceCount::get_class_type());
00292   }
00293 
00294 private:
00295   static TypeHandle _type_handle;
00296 };
00297 
00298 EXPCL_PANDA_GOBJ INLINE ostream &operator << (ostream &out, const Lens &lens);
00299 
00300 #include "lens.I"
00301 
00302 #endif
00303