inlib
1.2.0
|
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved. 00002 // See the file inlib.license for terms. 00003 00004 #ifndef inlib_sg_base_camera 00005 #define inlib_sg_base_camera 00006 00007 // inheritance : 00008 #include "node" 00009 00010 #include "sfs" 00011 #include "../vec3f" 00012 #include "../rotf" 00013 00014 #include <ostream> 00015 00016 namespace inlib { 00017 namespace sg { 00018 00019 class base_camera : public inlib::sg::node { 00020 void add_fields(){ 00021 add_field(&znear); 00022 add_field(&zfar); 00023 add_field(&position); 00024 add_field(&orientation); 00025 00026 add_field(&dx); 00027 add_field(&da); 00028 add_field(&ds); 00029 add_field(&focal); 00030 } 00031 public: 00032 static const std::string& s_class() { 00033 static const std::string s_v("inlib::sg::base_camera"); 00034 return s_v; 00035 } 00036 virtual void* cast(const std::string& a_class) const { 00037 if(void* p = inlib::cmp_cast<base_camera>(this,a_class)) {return p;} 00038 else return inlib::sg::node::cast(a_class); 00039 } 00040 public: 00041 virtual float near_height() const = 0; 00042 virtual void zoom(float) = 0; 00043 public: 00044 sf<float> znear; 00045 sf<float> zfar; 00046 sf_vec<inlib::vec3f,float> position; 00047 //Camera orientation specified as a rotation value from the default 00048 //orientation where the camera is pointing along the negative z-axis, 00049 //with "up" along the positive y-axis. 00050 sf_rotf orientation; 00051 00052 //for viewers : 00053 sf<float> dx; 00054 sf<float> da; 00055 sf<float> ds; 00056 sf<float> focal; 00057 protected: 00058 base_camera() 00059 : node() 00060 ,znear(1) 00061 ,zfar(10) 00062 ,position(inlib::vec3f(0,0,1)) 00063 ,orientation(inlib::rotf(inlib::vec3f(0,0,1),0)) 00064 ,dx(0.01f) 00065 ,da(0.017f) //one degree. 00066 ,ds(0.99f) 00067 ,focal(0) 00068 { 00069 #ifdef INLIB_MEM 00070 mem::increment(s_class().c_str()); 00071 #endif 00072 add_fields(); 00073 } 00074 public: 00075 virtual ~base_camera(){ 00076 #ifdef INLIB_MEM 00077 mem::decrement(s_class().c_str()); 00078 #endif 00079 } 00080 protected: 00081 base_camera(const base_camera& a_from) 00082 : node(a_from) 00083 ,znear(a_from.znear) 00084 ,zfar(a_from.zfar) 00085 ,position(a_from.position) 00086 ,orientation(a_from.orientation) 00087 ,dx(a_from.dx) 00088 ,da(a_from.da) 00089 ,ds(a_from.ds) 00090 ,focal(a_from.focal) 00091 { 00092 #ifdef INLIB_MEM 00093 mem::increment(s_class().c_str()); 00094 #endif 00095 add_fields(); 00096 } 00097 base_camera& operator=(const base_camera& a_from){ 00098 node::operator=(a_from); 00099 znear = a_from.znear; 00100 zfar = a_from.zfar; 00101 position = a_from.position; 00102 orientation = a_from.orientation; 00103 dx = a_from.dx; 00104 da = a_from.da; 00105 ds = a_from.ds; 00106 focal = a_from.focal; 00107 return *this; 00108 } 00109 protected: //operators: 00110 bool operator==(const base_camera& a_from) const{ 00111 if(znear!=a_from.znear) return false; 00112 if(zfar!=a_from.zfar) return false; 00113 if(position!=a_from.position) return false; 00114 if(orientation!=a_from.orientation) return false; 00115 //we do not test dx,da,ds. 00116 return true; 00117 } 00118 //bool operator!=(const base_camera& a_from) const { 00119 // return !operator==(a_from); 00120 //} 00121 public: 00122 void rotate_camera_around_direction(float a_delta){ 00123 inlib::vec3f dir; 00124 orientation.value().mult_vec(inlib::vec3f(0,0,-1),dir); 00125 orientation.value(inlib::rotf(dir,a_delta) * orientation.value()); 00126 } 00127 void rotate_camera_around_up(float a_delta){ 00128 inlib::vec3f up; 00129 orientation.value().mult_vec(inlib::vec3f(0,1,0),up); 00130 orientation.value(inlib::rotf(up,a_delta) * orientation.value()); 00131 } 00132 00133 void rotate_camera_around_y_at_focal(float a_delta){ 00134 //from coin SoGuiExaminerViewerP::rotYWheelMotion. 00135 inlib::vec3f dir; 00136 orientation.value().mult_vec(inlib::vec3f(0,0,-1),dir); 00137 inlib::vec3f focalpoint = position.value() + focal * dir; 00138 orientation.value 00139 (inlib::rotf(inlib::vec3f(0,1,0),a_delta) * orientation.value()); 00140 orientation.value().mult_vec(inlib::vec3f(0,0,-1),dir); 00141 position = focalpoint - focal * dir; 00142 } 00143 00144 void rotate_camera_around_x_at_focal(float a_delta){ 00145 //from coin SoGuiExaminerViewerP::rotXWheelMotion. 00146 inlib::vec3f dir; 00147 orientation.value().mult_vec(inlib::vec3f(0,0,-1),dir); 00148 inlib::vec3f focalpoint = position.value() + focal * dir; 00149 orientation.value 00150 (inlib::rotf(inlib::vec3f(1,0,0),a_delta) * orientation.value()); 00151 orientation.value().mult_vec(inlib::vec3f(0,0,-1),dir); 00152 position = focalpoint - focal * dir; 00153 } 00154 00155 void translate_camera_along_side(float a_delta){ 00156 inlib::vec3f dir; 00157 orientation.value().mult_vec(inlib::vec3f(0,0,-1),dir); 00158 inlib::vec3f up; 00159 orientation.value().mult_vec(inlib::vec3f(0,1,0),up); 00160 inlib::vec3f side = dir.cross(up); 00161 inlib::vec3f pos = position.value() + side * a_delta; 00162 position.value(pos); 00163 } 00164 void translate_camera_along_up(float a_delta){ 00165 inlib::vec3f dir; 00166 orientation.value().mult_vec(inlib::vec3f(0,0,-1),dir); 00167 inlib::vec3f up; 00168 orientation.value().mult_vec(inlib::vec3f(0,1,0),up); 00169 inlib::vec3f pos = position.value() + up * a_delta; 00170 position.value(pos); 00171 } 00172 void translate_camera_along_dir(float a_delta){ 00173 inlib::vec3f dir; 00174 orientation.value().mult_vec(inlib::vec3f(0,0,-1),dir); 00175 inlib::vec3f pos = position.value() + dir * a_delta; 00176 position.value(pos); 00177 } 00178 00179 //NOTE : print is a Python keyword. 00180 void dump(std::ostream& a_out) { 00181 a_out << " znear " << znear.value() << std::endl; 00182 a_out << " zfar " << zfar.value() << std::endl; 00183 inlib::vec3f& pos = position.value(); 00184 a_out << " pos " << pos[0] << " " << pos[1] << " " << pos[2] << std::endl; 00185 //FIXME : dump orientation. 00186 } 00187 00188 }; 00189 00190 class camera_factory { 00191 public: 00192 virtual ~camera_factory(){} 00193 public: 00194 enum camera_type { 00195 camera_ortho, 00196 camera_perspective 00197 }; 00198 virtual base_camera* create(camera_type,float a_height) = 0; 00199 virtual camera_factory* copy() const = 0; 00200 }; 00201 00202 }} 00203 00204 #endif