Geant4 Cross Reference |
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