Panda3D

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 #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 &copy);
00049   void operator = (const Lens &copy);
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 &copy);
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 
 All Classes Functions Variables Enumerations