Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/sg/base_camera

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/g4tools/include/tools/sg/base_camera (Version 11.3.0) and /externals/g4tools/include/tools/sg/base_camera (Version 11.1.2)


  1 // Copyright (C) 2010, Guy Barrand. All rights      1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.            2 // See the file tools.license for terms.
  3                                                     3 
  4 #ifndef tools_sg_base_camera                        4 #ifndef tools_sg_base_camera
  5 #define tools_sg_base_camera                        5 #define tools_sg_base_camera
  6                                                     6 
  7 #include "node"                                     7 #include "node"
  8                                                     8 
  9 #include "sf_vec3f"                                 9 #include "sf_vec3f"
 10 #include "sf_vec4f"                                10 #include "sf_vec4f"
 11 #include "sf_rotf"                                 11 #include "sf_rotf"
 12                                                    12 
 13 #include "render_action"                           13 #include "render_action"
 14 #include "pick_action"                             14 #include "pick_action"
 15 #include "event_action"                            15 #include "event_action"
 16 #include "visible_action"                          16 #include "visible_action"
 17 #include "enums"                                   17 #include "enums"
 18                                                    18 
 19 #include "../mathf" //astro                        19 #include "../mathf" //astro
 20                                                    20 
 21 namespace tools {                                  21 namespace tools {
 22 namespace sg {                                     22 namespace sg {
 23                                                    23 
 24 class base_camera : public node {                  24 class base_camera : public node {
 25   TOOLS_HEADER(base_camera,tools::sg::base_cam     25   TOOLS_HEADER(base_camera,tools::sg::base_camera,node)
 26 public:                                            26 public:
 27   sf<float> znear;                                 27   sf<float> znear;
 28   sf<float> zfar;                                  28   sf<float> zfar;
 29   sf_vec3f position;                               29   sf_vec3f position;
 30   //Camera orientation specified as a rotation     30   //Camera orientation specified as a rotation value from the default
 31   //orientation where the camera is pointing a     31   //orientation where the camera is pointing along the negative z-axis,
 32   //with "up" along the positive y-axis.           32   //with "up" along the positive y-axis.
 33   sf_rotf orientation;                             33   sf_rotf orientation;
 34                                                    34 
 35   //for viewers :                                  35   //for viewers :
 36   sf<float> dx;                                    36   sf<float> dx;
 37   sf<float> da;                                    37   sf<float> da;
 38   sf<float> ds;                                    38   sf<float> ds;
 39   sf<float> focal;                                 39   sf<float> focal;
 40 public:                                            40 public:
 41   virtual const desc_fields& node_desc_fields(     41   virtual const desc_fields& node_desc_fields() const {
 42     TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::bas     42     TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::base_camera)
 43     static const desc_fields s_v(parent::node_     43     static const desc_fields s_v(parent::node_desc_fields(),8, //WARNING : take care of count.
 44       TOOLS_ARG_FIELD_DESC(znear),                 44       TOOLS_ARG_FIELD_DESC(znear),
 45       TOOLS_ARG_FIELD_DESC(zfar),                  45       TOOLS_ARG_FIELD_DESC(zfar),
 46       TOOLS_ARG_FIELD_DESC(position),              46       TOOLS_ARG_FIELD_DESC(position),
 47       TOOLS_ARG_FIELD_DESC(orientation),           47       TOOLS_ARG_FIELD_DESC(orientation),
 48       TOOLS_ARG_FIELD_DESC(dx),                    48       TOOLS_ARG_FIELD_DESC(dx),
 49       TOOLS_ARG_FIELD_DESC(da),                    49       TOOLS_ARG_FIELD_DESC(da),
 50       TOOLS_ARG_FIELD_DESC(ds),                    50       TOOLS_ARG_FIELD_DESC(ds),
 51       TOOLS_ARG_FIELD_DESC(focal)                  51       TOOLS_ARG_FIELD_DESC(focal)
 52     );                                             52     );
 53     return s_v;                                    53     return s_v;
 54   }                                                54   }
 55 private:                                           55 private:
 56   void add_fields(){                               56   void add_fields(){
 57     add_field(&znear);                             57     add_field(&znear);
 58     add_field(&zfar);                              58     add_field(&zfar);
 59     add_field(&position);                          59     add_field(&position);
 60     add_field(&orientation);                       60     add_field(&orientation);
 61                                                    61 
 62     add_field(&dx);                                62     add_field(&dx);
 63     add_field(&da);                                63     add_field(&da);
 64     add_field(&ds);                                64     add_field(&ds);
 65     add_field(&focal);                             65     add_field(&focal);
 66   }                                                66   }
 67 public:                                            67 public:
 68   virtual float near_height() const = 0;           68   virtual float near_height() const = 0;
 69   virtual void zoom(float) = 0;                    69   virtual void zoom(float) = 0;
 70   virtual camera_type type() const = 0;            70   virtual camera_type type() const = 0;
 71   virtual void get_lrbt(unsigned int,unsigned      71   virtual void get_lrbt(unsigned int,unsigned int,
 72                         float&,float&,float&,f     72                         float&,float&,float&,float&) = 0;
 73 public:                                            73 public:
 74   virtual void render(render_action& a_action)     74   virtual void render(render_action& a_action) {
 75     _mult_matrix(a_action);                        75     _mult_matrix(a_action);
 76     set_state(a_action);                           76     set_state(a_action);
 77  //{mat4f& _mtx = a_action.projection_matrix()     77  //{mat4f& _mtx = a_action.projection_matrix();
 78  // a_action.out() << "debug : tools::sg::base     78  // a_action.out() << "debug : tools::sg::base_camera::render : proj :" << std::endl;
 79  // a_action.out() << _mtx << std::endl;}          79  // a_action.out() << _mtx << std::endl;}
 80     a_action.load_proj_matrix(a_action.project     80     a_action.load_proj_matrix(a_action.projection_matrix());
 81     a_action.load_model_matrix(a_action.model_     81     a_action.load_model_matrix(a_action.model_matrix());
 82   }                                                82   }
 83   virtual void pick(pick_action& a_action) {       83   virtual void pick(pick_action& a_action) {
 84     _mult_matrix(a_action);                        84     _mult_matrix(a_action);
 85     set_state(a_action);                           85     set_state(a_action);
 86   }                                                86   }
 87   virtual void event(event_action& a_action){      87   virtual void event(event_action& a_action){
 88     _mult_matrix(a_action);                        88     _mult_matrix(a_action);
 89     set_state(a_action);                           89     set_state(a_action);
 90   }                                                90   }
 91   virtual void get_matrix(get_matrix_action& a     91   virtual void get_matrix(get_matrix_action& a_action){
 92     _mult_matrix(a_action);                        92     _mult_matrix(a_action);
 93     set_state(a_action);                           93     set_state(a_action);
 94   }                                                94   }
 95   virtual void is_visible(visible_action& a_ac     95   virtual void is_visible(visible_action& a_action){
 96     _mult_matrix(a_action);                        96     _mult_matrix(a_action);
 97     set_state(a_action);                           97     set_state(a_action);
 98   }                                                98   }
 99 protected:                                         99 protected:
100   base_camera()                                   100   base_camera()
101   :parent()                                       101   :parent()
102   ,znear(1)                                       102   ,znear(1)
103   ,zfar(10)                                       103   ,zfar(10)
104   ,position(vec3f(0,0,1))                         104   ,position(vec3f(0,0,1))
105   ,orientation(rotf(vec3f(0,0,1),0)) //quat =     105   ,orientation(rotf(vec3f(0,0,1),0)) //quat = vec4f(0,0,0,1)
106   ,dx(0.01f)                                      106   ,dx(0.01f)
107   ,da(0.017f) //one degree.                       107   ,da(0.017f) //one degree.
108   ,ds(0.99f)                                      108   ,ds(0.99f)
109   ,focal(1)                                       109   ,focal(1)
110   {                                               110   {
111 #ifdef TOOLS_MEM                                  111 #ifdef TOOLS_MEM
112     mem::increment(s_class().c_str());            112     mem::increment(s_class().c_str());
113 #endif                                            113 #endif
114     add_fields();                                 114     add_fields();
115   }                                               115   }
116 public:                                           116 public:
117   virtual ~base_camera(){                         117   virtual ~base_camera(){
118 #ifdef TOOLS_MEM                                  118 #ifdef TOOLS_MEM
119     mem::decrement(s_class().c_str());            119     mem::decrement(s_class().c_str());
120 #endif                                            120 #endif
121   }                                               121   }
122 protected:                                        122 protected:
123   base_camera(const base_camera& a_from)          123   base_camera(const base_camera& a_from)
124   :parent(a_from)                                 124   :parent(a_from)
125   ,znear(a_from.znear)                            125   ,znear(a_from.znear)
126   ,zfar(a_from.zfar)                              126   ,zfar(a_from.zfar)
127   ,position(a_from.position)                      127   ,position(a_from.position)
128   ,orientation(a_from.orientation)                128   ,orientation(a_from.orientation)
129   ,dx(a_from.dx)                                  129   ,dx(a_from.dx)
130   ,da(a_from.da)                                  130   ,da(a_from.da)
131   ,ds(a_from.ds)                                  131   ,ds(a_from.ds)
132   ,focal(a_from.focal)                            132   ,focal(a_from.focal)
133   {                                               133   {
134 #ifdef TOOLS_MEM                                  134 #ifdef TOOLS_MEM
135     mem::increment(s_class().c_str());            135     mem::increment(s_class().c_str());
136 #endif                                            136 #endif
137     add_fields();                                 137     add_fields();
138   }                                               138   }
139   base_camera& operator=(const base_camera& a_    139   base_camera& operator=(const base_camera& a_from){
140     parent::operator=(a_from);                    140     parent::operator=(a_from);
141     znear = a_from.znear;                         141     znear = a_from.znear;
142     zfar = a_from.zfar;                           142     zfar = a_from.zfar;
143     position = a_from.position;                   143     position = a_from.position;
144     orientation = a_from.orientation;             144     orientation = a_from.orientation;
145     dx = a_from.dx;                               145     dx = a_from.dx;
146     da = a_from.da;                               146     da = a_from.da;
147     ds = a_from.ds;                               147     ds = a_from.ds;
148     focal = a_from.focal;                         148     focal = a_from.focal;
149     m_lrbt.set_value(0,0,0,0);                    149     m_lrbt.set_value(0,0,0,0);
150     return *this;                                 150     return *this;
151   }                                               151   }
152 protected: //operators:                           152 protected: //operators:
153   bool operator==(const base_camera& a_from) c    153   bool operator==(const base_camera& a_from) const{
154     if(znear!=a_from.znear) return false;         154     if(znear!=a_from.znear) return false;
155     if(zfar!=a_from.zfar) return false;           155     if(zfar!=a_from.zfar) return false;
156     if(position!=a_from.position) return false    156     if(position!=a_from.position) return false;
157     if(orientation!=a_from.orientation) return    157     if(orientation!=a_from.orientation) return false;
158     //we do not test dx,da,ds.                    158     //we do not test dx,da,ds.
159     return true;                                  159     return true;
160   }                                               160   }
161   //bool operator!=(const base_camera& a_from)    161   //bool operator!=(const base_camera& a_from) const {
162   //  return !operator==(a_from);                 162   //  return !operator==(a_from);
163   //}                                             163   //}
164 public:                                           164 public:
165   void direction(vec3f& a_dir) const {            165   void direction(vec3f& a_dir) const {
166     orientation.value().mul_vec(vec3f(0,0,-1),    166     orientation.value().mul_vec(vec3f(0,0,-1),a_dir);
167   }                                               167   }
168                                                   168 
169   void rotate_around_direction(float a_delta)     169   void rotate_around_direction(float a_delta) {
170   //vec3f dir;                                    170   //vec3f dir;
171   //orientation.value().mul_vec(vec3f(0,0,-1),    171   //orientation.value().mul_vec(vec3f(0,0,-1),dir);
172   //orientation.value(rotf(dir,a_delta) * orie    172   //orientation.value(rotf(dir,a_delta) * orientation.value());
173     orientation.value(rotf(vec3f(0,0,-1),a_del    173     orientation.value(rotf(vec3f(0,0,-1),a_delta) * orientation.value());
174   }                                               174   }
175                                                   175 
176   void rotate_around_z(float a_delta) {           176   void rotate_around_z(float a_delta) {
177   //vec3f z;                                      177   //vec3f z;
178   //orientation.value().mul_vec(vec3f(0,0,1),z    178   //orientation.value().mul_vec(vec3f(0,0,1),z);
179   //orientation.value(rotf(z,a_delta) * orient    179   //orientation.value(rotf(z,a_delta) * orientation.value());
180     orientation.value(rotf(vec3f(0,0,1),a_delt    180     orientation.value(rotf(vec3f(0,0,1),a_delta) * orientation.value());
181   }                                               181   }
182                                                   182 
183   void rotate_around_up(float a_delta){           183   void rotate_around_up(float a_delta){
184     vec3f up;                                     184     vec3f up;
185     orientation.value().mul_vec(vec3f(0,1,0),u    185     orientation.value().mul_vec(vec3f(0,1,0),up);
186   //orientation.value(rotf(up,a_delta) * orien    186   //orientation.value(rotf(up,a_delta) * orientation.value());
187     // must be the below so that rot-cam works    187     // must be the below so that rot-cam works for exlib/cbk/[astro,cfitsio] astro setup.
188     // (astro setup change camera orientation)    188     // (astro setup change camera orientation).
189     orientation.value(orientation.value() * ro    189     orientation.value(orientation.value() * rotf(up,a_delta));
190   }                                               190   }
191                                                   191 
192   void rotate_around_x(float a_delta){            192   void rotate_around_x(float a_delta){
193     orientation.value(rotf(vec3f(1,0,0),a_delt    193     orientation.value(rotf(vec3f(1,0,0),a_delta) * orientation.value());
194   }                                               194   }
195                                                   195 
196   void rotate_around_x_at_focal(float a_delta)    196   void rotate_around_x_at_focal(float a_delta){
197     //from coin SoGuiExaminerViewerP::rotXWhee    197     //from coin SoGuiExaminerViewerP::rotXWheelMotion.
198     vec3f dir;                                    198     vec3f dir;
199     orientation.value().mul_vec(vec3f(0,0,-1),    199     orientation.value().mul_vec(vec3f(0,0,-1),dir);
200     vec3f focalpoint = position.value() + foca    200     vec3f focalpoint = position.value() + focal * dir;
201     orientation.value(rotf(vec3f(1,0,0),a_delt    201     orientation.value(rotf(vec3f(1,0,0),a_delta) * orientation.value());
202     orientation.value().mul_vec(vec3f(0,0,-1),    202     orientation.value().mul_vec(vec3f(0,0,-1),dir);
203     position = focalpoint - focal * dir;          203     position = focalpoint - focal * dir;
204   }                                               204   }
205                                                   205 
206   void rotate_around_y_at_focal(float a_delta)    206   void rotate_around_y_at_focal(float a_delta){
207     //from coin SoGuiExaminerViewerP::rotYWhee    207     //from coin SoGuiExaminerViewerP::rotYWheelMotion.
208     vec3f dir;                                    208     vec3f dir;
209     orientation.value().mul_vec(vec3f(0,0,-1),    209     orientation.value().mul_vec(vec3f(0,0,-1),dir);
210     vec3f focalpoint = position.value() + foca    210     vec3f focalpoint = position.value() + focal * dir;
211     orientation.value(rotf(vec3f(0,1,0),a_delt    211     orientation.value(rotf(vec3f(0,1,0),a_delta) * orientation.value());
212     orientation.value().mul_vec(vec3f(0,0,-1),    212     orientation.value().mul_vec(vec3f(0,0,-1),dir);
213     position = focalpoint - focal * dir;          213     position = focalpoint - focal * dir;
214   }                                               214   }
215                                                   215 
216   void rotate_around_z_at_focal(float a_delta)    216   void rotate_around_z_at_focal(float a_delta){
217     //from coin SoGuiExaminerViewerP::rotYWhee    217     //from coin SoGuiExaminerViewerP::rotYWheelMotion.
218     vec3f dir;                                    218     vec3f dir;
219     orientation.value().mul_vec(vec3f(0,0,-1),    219     orientation.value().mul_vec(vec3f(0,0,-1),dir);
220     vec3f focalpoint = position.value() + foca    220     vec3f focalpoint = position.value() + focal * dir;
221     orientation.value(rotf(vec3f(0,0,1),a_delt    221     orientation.value(rotf(vec3f(0,0,1),a_delta) * orientation.value());
222     orientation.value().mul_vec(vec3f(0,0,-1),    222     orientation.value().mul_vec(vec3f(0,0,-1),dir);
223     position = focalpoint - focal * dir;          223     position = focalpoint - focal * dir;
224   }                                               224   }
225                                                   225 
226   void rotate_to_dir(const vec3f& a_dir) {        226   void rotate_to_dir(const vec3f& a_dir) {
227     //rotate around up so that a_dir is in (di    227     //rotate around up so that a_dir is in (dir,up) plane
228                                                   228 
229     //NOTE : it is the invert of orientation w    229     //NOTE : it is the invert of orientation which is used
230     //       in projection matrix.                230     //       in projection matrix.
231                                                   231 
232    {vec3f dir;                                    232    {vec3f dir;
233     orientation.value().mul_vec(vec3f(0,0,-1),    233     orientation.value().mul_vec(vec3f(0,0,-1),dir);
234     vec3f up;                                     234     vec3f up;
235     orientation.value().mul_vec(vec3f(0,1,0),u    235     orientation.value().mul_vec(vec3f(0,1,0),up);
236     vec3f side;dir.cross(up,side);                236     vec3f side;dir.cross(up,side);
237     vec3f v = side * (side.dot(a_dir)) + dir *    237     vec3f v = side * (side.dot(a_dir)) + dir * (dir.dot(a_dir));
238     if(v.normalize()) orientation.value(orient    238     if(v.normalize()) orientation.value(orientation.value()*rotf(dir,v));}
239                                                   239 
240     //rotate around dir^up so that a_dir match    240     //rotate around dir^up so that a_dir matches dir.
241    {vec3f dir;                                    241    {vec3f dir;
242     orientation.value().mul_vec(vec3f(0,0,-1),    242     orientation.value().mul_vec(vec3f(0,0,-1),dir);
243     orientation.value(orientation.value()*rotf    243     orientation.value(orientation.value()*rotf(dir,a_dir));}
244                                                   244 
245 /*                                                245 /*
246     //check that dir is on a_dir :                246     //check that dir is on a_dir :
247    {vec3f dir;                                    247    {vec3f dir;
248     orientation.value().mul_vec(vec3f(0,0,-1),    248     orientation.value().mul_vec(vec3f(0,0,-1),dir);
249     float cos_angle; //it should be 1             249     float cos_angle; //it should be 1
250     if(!dir.cos_angle(a_dir,cos_angle)) {         250     if(!dir.cos_angle(a_dir,cos_angle)) {
251       ::printf("debug : can't get angle\n");      251       ::printf("debug : can't get angle\n");
252       return;                                     252       return;
253     }                                             253     }
254     ::printf("debug : cos_angle %g\n",cos_angl    254     ::printf("debug : cos_angle %g\n",cos_angle);}
255 */                                                255 */
256   }                                               256   }
257                                                   257 
258   void pane_to(float a_x,float a_y,float a_z){    258   void pane_to(float a_x,float a_y,float a_z){
259     //translate in view plane so that (a_x,a_y    259     //translate in view plane so that (a_x,a_y,a_z) is on direction.
260                                                   260 
261     vec3f dir;                                    261     vec3f dir;
262     orientation.value().mul_vec(vec3f(0,0,-1),    262     orientation.value().mul_vec(vec3f(0,0,-1),dir);
263     vec3f up;                                     263     vec3f up;
264     orientation.value().mul_vec(vec3f(0,1,0),u    264     orientation.value().mul_vec(vec3f(0,1,0),up);
265     vec3f side;dir.cross(up,side);                265     vec3f side;dir.cross(up,side);
266                                                   266 
267     vec3f d(a_x,a_y,a_z);                         267     vec3f d(a_x,a_y,a_z);
268     d.subtract(position.value());                 268     d.subtract(position.value());
269                                                   269 
270     vec3f pos = position.value() + side * (sid    270     vec3f pos = position.value() + side * (side.dot(d)) + up * (up.dot(d));
271     position.value(pos);                          271     position.value(pos);
272   }                                               272   }
273                                                   273 
274   void translate_along_side(float a_delta){       274   void translate_along_side(float a_delta){
275     vec3f dir;                                    275     vec3f dir;
276     orientation.value().mul_vec(vec3f(0,0,-1),    276     orientation.value().mul_vec(vec3f(0,0,-1),dir);
277     vec3f up;                                     277     vec3f up;
278     orientation.value().mul_vec(vec3f(0,1,0),u    278     orientation.value().mul_vec(vec3f(0,1,0),up);
279     vec3f side;dir.cross(up,side);                279     vec3f side;dir.cross(up,side);
280     vec3f pos = position.value() + side * a_de    280     vec3f pos = position.value() + side * a_delta;
281     position.value(pos);                          281     position.value(pos);
282   }                                               282   }
283   void translate_along_up(float a_delta){         283   void translate_along_up(float a_delta){
284     vec3f dir;                                    284     vec3f dir;
285     orientation.value().mul_vec(vec3f(0,0,-1),    285     orientation.value().mul_vec(vec3f(0,0,-1),dir);
286     vec3f up;                                     286     vec3f up;
287     orientation.value().mul_vec(vec3f(0,1,0),u    287     orientation.value().mul_vec(vec3f(0,1,0),up);
288     vec3f pos = position.value() + up * a_delt    288     vec3f pos = position.value() + up * a_delta;
289     position.value(pos);                          289     position.value(pos);
290   }                                               290   }
291   void translate_along_dir(float a_delta){        291   void translate_along_dir(float a_delta){
292     vec3f dir;                                    292     vec3f dir;
293     orientation.value().mul_vec(vec3f(0,0,-1),    293     orientation.value().mul_vec(vec3f(0,0,-1),dir);
294     vec3f pos = position.value() + dir * a_del    294     vec3f pos = position.value() + dir * a_delta;
295     position.value(pos);                          295     position.value(pos);
296   }                                               296   }
297                                                   297 
298   bool look_at(const vec3f& a_dir,const vec3f&    298   bool look_at(const vec3f& a_dir,const vec3f& a_up) {
299     vec3f z = -a_dir;                             299     vec3f z = -a_dir;
300     vec3f y = a_up;                               300     vec3f y = a_up;
301     vec3f x;y.cross(z,x);                         301     vec3f x;y.cross(z,x);
302                                                   302 
303     // recompute y to create a valid coordinat    303     // recompute y to create a valid coordinate system
304     z.cross(x,y);                                 304     z.cross(x,y);
305                                                   305 
306     // normalize x and y to create an orthonor    306     // normalize x and y to create an orthonormal coord system
307     if(!x.normalize()) return false;              307     if(!x.normalize()) return false;
308     if(!y.normalize()) return false;              308     if(!y.normalize()) return false;
309     if(!z.normalize()) return false;              309     if(!z.normalize()) return false;
310                                                   310 
311     // create a rotation matrix                   311     // create a rotation matrix
312     mat4f rot;                                    312     mat4f rot;
313     rot.set_identity();                           313     rot.set_identity();
314     rot.set_value(0,0,x[0]);                      314     rot.set_value(0,0,x[0]);
315     rot.set_value(1,0,x[1]);                      315     rot.set_value(1,0,x[1]);
316     rot.set_value(2,0,x[2]);                      316     rot.set_value(2,0,x[2]);
317                                                   317 
318     rot.set_value(0,1,y[0]);                      318     rot.set_value(0,1,y[0]);
319     rot.set_value(1,1,y[1]);                      319     rot.set_value(1,1,y[1]);
320     rot.set_value(2,1,y[2]);                      320     rot.set_value(2,1,y[2]);
321                                                   321 
322     rot.set_value(0,2,z[0]);                      322     rot.set_value(0,2,z[0]);
323     rot.set_value(1,2,z[1]);                      323     rot.set_value(1,2,z[1]);
324     rot.set_value(2,2,z[2]);                      324     rot.set_value(2,2,z[2]);
325                                                   325 
326     orientation.value().set_value(rot);           326     orientation.value().set_value(rot);
327     return true;                                  327     return true;
328   }                                               328   }
329                                                   329 
330   //NOTE : print is a Python keyword.             330   //NOTE : print is a Python keyword.
331   void dump(std::ostream& a_out) {                331   void dump(std::ostream& a_out) {
332     a_out << " znear " << znear.value() << std    332     a_out << " znear " << znear.value() << std::endl;
333     a_out << " zfar " << zfar.value() << std::    333     a_out << " zfar " << zfar.value() << std::endl;
334     vec3f& pos = position.value();                334     vec3f& pos = position.value();
335     a_out << " pos " << pos[0] << " " << pos[1    335     a_out << " pos " << pos[0] << " " << pos[1] << " " << pos[2] << std::endl;
336     //FIXME : dump orientation.                   336     //FIXME : dump orientation.
337   }                                               337   }
338                                                   338 
339   bool is_type_ortho() const {return type()==c    339   bool is_type_ortho() const {return type()==camera_ortho?true:false;}
340                                                   340 
341   bool height_at_focal(float& a_h) const {        341   bool height_at_focal(float& a_h) const {
342     if(is_type_ortho()) {                         342     if(is_type_ortho()) {
343       a_h = near_height();                        343       a_h = near_height();
344     } else {                                      344     } else {
345       if(!znear.value()) {a_h = near_height();    345       if(!znear.value()) {a_h = near_height();return false;}
346       a_h = focal.value()*near_height()/znear.    346       a_h = focal.value()*near_height()/znear.value();
347     }                                             347     }
348     return true;                                  348     return true;
349   }                                               349   }
350                                                   350 
351   void astro_orientation(float a_ra,float a_de    351   void astro_orientation(float a_ra,float a_dec/*,const vec3f&  a_center*/) {
352     // a_ra, a_dec are in decimal degrees.        352     // a_ra, a_dec are in decimal degrees.
353                                                   353 
354     // Camera default point toward -z with up     354     // Camera default point toward -z with up along +y and +x at right.
355                                                   355 
356     // Arrange so that camera points toward x     356     // Arrange so that camera points toward x with up along +z :
357     rotf r(vec3f::s_y(),-fhalf_pi());             357     rotf r(vec3f::s_y(),-fhalf_pi());
358     r *= rotf(vec3f::s_x(),fhalf_pi());           358     r *= rotf(vec3f::s_x(),fhalf_pi());
359     // Now -y is at right.                        359     // Now -y is at right.
360                                                   360 
361     // Then rotate it so that it points toward    361     // Then rotate it so that it points toward given (ra,dec) by keeping up upward +z direction.
362     r *= rotf(vec3f::s_y(),-a_dec*fdeg2rad());    362     r *= rotf(vec3f::s_y(),-a_dec*fdeg2rad());
363     r *= rotf(vec3f::s_z(),a_ra*fdeg2rad());      363     r *= rotf(vec3f::s_z(),a_ra*fdeg2rad());
364     orientation = r;                              364     orientation = r;
365                                                   365 
366 /*                                                366 /*
367     position = a_center*0.99f;                    367     position = a_center*0.99f;
368     znear = 0.1f;                                 368     znear = 0.1f;
369     zfar = 200.0f;                                369     zfar = 200.0f;
370     focal = (a_center-position).length();         370     focal = (a_center-position).length();
371 */                                                371 */
372 /*                                                372 /*
373     position = vec3f(0,0,0);                      373     position = vec3f(0,0,0);
374     znear = 1.0f;                                 374     znear = 1.0f;
375     zfar = 2000.0f; //2*sky_radius.               375     zfar = 2000.0f; //2*sky_radius.
376     focal = a_center.length();                    376     focal = a_center.length();
377     da = 0.017f/100; //1/100 of a degree          377     da = 0.017f/100; //1/100 of a degree
378 */                                                378 */
379   }                                               379   }
380                                                   380 
381   bool update_motion(int a_move) {                381   bool update_motion(int a_move) {
382     float _dx = dx;                               382     float _dx = dx;
383     float _da = da;                               383     float _da = da;
384     float _ds = ds;                               384     float _ds = ds;
385                                                   385 
386     if(a_move==move_rotate_right) { //should m    386     if(a_move==move_rotate_right) { //should match camera_yaw().
387       rotate_around_up(_da);                      387       rotate_around_up(_da);
388       return true;                                388       return true;
389     }                                             389     }
390     if(a_move==move_rotate_left) {                390     if(a_move==move_rotate_left) {
391       rotate_around_up(-_da);                     391       rotate_around_up(-_da);
392       return true;                                392       return true;
393     }                                             393     }
394                                                   394 
395     if(a_move==move_rotate_up) {  //should mat    395     if(a_move==move_rotate_up) {  //should match camera_pitch().
396       rotate_around_x(_da);                       396       rotate_around_x(_da);
397       return true;                                397       return true;
398     }                                             398     }
399     if(a_move==move_rotate_down) {                399     if(a_move==move_rotate_down) {
400       rotate_around_x(-_da);                      400       rotate_around_x(-_da);
401       return true;                                401       return true;
402     }                                             402     }
403                                                   403 
404     if(a_move==move_roll_plus) {  //should mat    404     if(a_move==move_roll_plus) {  //should match camera_roll().
405       rotate_around_direction(-_da);  //direct    405       rotate_around_direction(-_da);  //direction = -z, then the minus.
406       return true;                                406       return true;
407     }                                             407     }
408     if(a_move==move_roll_minus) {                 408     if(a_move==move_roll_minus) {
409       rotate_around_direction(_da);               409       rotate_around_direction(_da);
410       return true;                                410       return true;
411     }                                             411     }
412                                                   412 
413     if(a_move==move_translate_right) {            413     if(a_move==move_translate_right) {
414       translate_along_side(_dx);                  414       translate_along_side(_dx);
415       return true;                                415       return true;
416     }                                             416     }
417     if(a_move==move_translate_left) {             417     if(a_move==move_translate_left) {
418       translate_along_side(-_dx);                 418       translate_along_side(-_dx);
419       return true;                                419       return true;
420     }                                             420     }
421                                                   421 
422     if(a_move==move_up) {                         422     if(a_move==move_up) {
423       translate_along_up(_dx);                    423       translate_along_up(_dx);
424       return true;                                424       return true;
425     }                                             425     }
426     if(a_move==move_down) {                       426     if(a_move==move_down) {
427       translate_along_up(-_dx);                   427       translate_along_up(-_dx);
428       return true;                                428       return true;
429     }                                             429     }
430     if(a_move==move_forward) {                    430     if(a_move==move_forward) {
431       translate_along_dir(_dx);                   431       translate_along_dir(_dx);
432       return true;                                432       return true;
433     }                                             433     }
434     if(a_move==move_backward) {                   434     if(a_move==move_backward) {
435       translate_along_dir(-_dx);                  435       translate_along_dir(-_dx);
436       return true;                                436       return true;
437     }                                             437     }
438     if(a_move==move_zoom_in) {                    438     if(a_move==move_zoom_in) {
439       zoom(_ds);                                  439       zoom(_ds);
440       return true;                                440       return true;
441     }                                             441     }
442     if(a_move==move_zoom_out) {                   442     if(a_move==move_zoom_out) {
443       zoom(1.0f/_ds);                             443       zoom(1.0f/_ds);
444       return true;                                444       return true;
445     }                                             445     }
446                                                   446 
447     if(a_move==move_rotate_around_focal_right)    447     if(a_move==move_rotate_around_focal_right) {  //yaw around focal.
448       rotate_around_y_at_focal(_da);              448       rotate_around_y_at_focal(_da);
449       return true;                                449       return true;
450     }                                             450     }
451     if(a_move==move_rotate_around_focal_left)     451     if(a_move==move_rotate_around_focal_left) {
452       rotate_around_y_at_focal(-_da);             452       rotate_around_y_at_focal(-_da);
453       return true;                                453       return true;
454     }                                             454     }
455     if(a_move==move_rotate_around_focal_up) {     455     if(a_move==move_rotate_around_focal_up) {  //pitch around focal.
456       rotate_around_x_at_focal(_da);              456       rotate_around_x_at_focal(_da);
457       return true;                                457       return true;
458     }                                             458     }
459     if(a_move==move_rotate_around_focal_down)     459     if(a_move==move_rotate_around_focal_down) {
460       rotate_around_x_at_focal(-_da);             460       rotate_around_x_at_focal(-_da);
461       return true;                                461       return true;
462     }                                             462     }
463     if(a_move==move_roll_around_focal_plus) {     463     if(a_move==move_roll_around_focal_plus) {
464       rotate_around_z_at_focal(_da);              464       rotate_around_z_at_focal(_da);
465       return true;                                465       return true;
466     }                                             466     }
467     if(a_move==move_roll_around_focal_minus) {    467     if(a_move==move_roll_around_focal_minus) {
468       rotate_around_z_at_focal(-_da);             468       rotate_around_z_at_focal(-_da);
469       return true;                                469       return true;
470     }                                             470     }
471                                                   471 
472     return false;                                 472     return false;
473   }                                               473   }
474 protected:                                        474 protected:
475   void update_sg(std::ostream& a_out) {           475   void update_sg(std::ostream& a_out) {
476                                                   476 
477    {const vec4f& v = m_lrbt.value();              477    {const vec4f& v = m_lrbt.value();
478     float l = v[0];                               478     float l = v[0];
479     float r = v[1];                               479     float r = v[1];
480     float b = v[2];                               480     float b = v[2];
481     float t = v[3];                               481     float t = v[3];
482     float n = znear.value();                      482     float n = znear.value();
483     float f = zfar.value();                       483     float f = zfar.value();
484     if(is_type_ortho()) {                         484     if(is_type_ortho()) {
485       m_proj.set_ortho(l,r,b,t,n,f);              485       m_proj.set_ortho(l,r,b,t,n,f);
486     } else {                                      486     } else {
487       m_proj.set_frustum(l,r,b,t,n,f);            487       m_proj.set_frustum(l,r,b,t,n,f);
488     }}                                            488     }}
489                                                   489 
490     if(orientation.value().quat()!=id_orientat    490     if(orientation.value().quat()!=id_orientation()) //OPTIMIZATION
491    {rotf rinv;                                    491    {rotf rinv;
492     if(orientation.value().inverse(rinv)) {       492     if(orientation.value().inverse(rinv)) {
493       mat4f mtx;                                  493       mat4f mtx;
494       rinv.value(mtx);                            494       rinv.value(mtx);
495       m_proj.mul_mtx(mtx,m_tmp);                  495       m_proj.mul_mtx(mtx,m_tmp);
496     } else {                                      496     } else {
497       a_out << "update_sg :"                      497       a_out << "update_sg :"
498             << " get orientation inverse faile    498             << " get orientation inverse failed."
499             << std::endl;                         499             << std::endl;
500     }}                                            500     }}
501                                                   501 
502     m_proj.mul_translate(-position.value()[0],    502     m_proj.mul_translate(-position.value()[0],
503                          -position.value()[1],    503                          -position.value()[1],
504                          -position.value()[2])    504                          -position.value()[2]);
505   }                                               505   }
506                                                   506 
507   void _mult_matrix(matrix_action& a_action) {    507   void _mult_matrix(matrix_action& a_action) {
508     float l,r,b,t;                                508     float l,r,b,t;
509     get_lrbt(a_action.ww(),a_action.wh(),l,r,b    509     get_lrbt(a_action.ww(),a_action.wh(),l,r,b,t);
510     m_lrbt.set_value(l,r,b,t);                    510     m_lrbt.set_value(l,r,b,t);
511                                                   511 
512     if(touched()||m_lrbt.touched()) {             512     if(touched()||m_lrbt.touched()) {
513       update_sg(a_action.out());                  513       update_sg(a_action.out());
514       reset_touched();                            514       reset_touched();
515       m_lrbt.reset_touched();                     515       m_lrbt.reset_touched();
516     }                                             516     }
517                                                   517 
518     a_action.projection_matrix().mul_mtx(m_pro    518     a_action.projection_matrix().mul_mtx(m_proj,m_tmp);
519   }                                               519   }
520                                                   520 
521   void set_state(matrix_action& a_action) {       521   void set_state(matrix_action& a_action) {
522     state& _state = a_action.state();             522     state& _state = a_action.state();
523     _state.m_camera_ortho = is_type_ortho();      523     _state.m_camera_ortho = is_type_ortho();
524     _state.m_camera_znear = znear;                524     _state.m_camera_znear = znear;
525     _state.m_camera_zfar = zfar;                  525     _state.m_camera_zfar = zfar;
526     _state.m_camera_position = position.value(    526     _state.m_camera_position = position.value();
527     _state.m_camera_orientation = orientation.    527     _state.m_camera_orientation = orientation.value();
528     //_state.m_camera_near_height = near_heigh    528     //_state.m_camera_near_height = near_height();
529     _state.m_camera_lrbt = m_lrbt.value();        529     _state.m_camera_lrbt = m_lrbt.value();
530     _state.m_proj = a_action.projection_matrix    530     _state.m_proj = a_action.projection_matrix();
531   }                                               531   }
532                                                   532 
533 #if defined(TOOLS_MEM) && !defined(TOOLS_MEM_A    533 #if defined(TOOLS_MEM) && !defined(TOOLS_MEM_ATEXIT)
534   static const vec4<float>& id_orientation() {    534   static const vec4<float>& id_orientation() {static const vec4<float> s_v(0,0,0,1,false);return s_v;}
535 #else                                             535 #else
536   static const vec4<float>& id_orientation() {    536   static const vec4<float>& id_orientation() {static const vec4<float> s_v(0,0,0,1);return s_v;}
537 #endif                                            537 #endif
538                                                   538 
539 protected:                                        539 protected:
540   //OPTIMIZATION :                                540   //OPTIMIZATION :
541   sf_vec4f m_lrbt;                                541   sf_vec4f m_lrbt;
542   mat4f m_proj;                                   542   mat4f m_proj;
543   float m_tmp[16];                                543   float m_tmp[16];
544 };                                                544 };
545                                                   545 
546 }}                                                546 }}
547                                                   547 
548 #endif                                            548 #endif