Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/sg/tex_quadrilateral is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_sg_tex_quadrilateral
0005 #define tools_sg_tex_quadrilateral
0006 
0007 #include "node"
0008 #include "mf"
0009 #include "render_action"
0010 #include "pick_action"
0011 #include "bbox_action"
0012 #include "event_action"
0013 #include "render_manager"
0014 #include "gstos"
0015 #include "base_tex"
0016 
0017 #include "../pointer"
0018 #include "../num2s"
0019 
0020 namespace tools {
0021 namespace sg {
0022 
0023 class tex_quadrilateral : public node, public gstos, public base_tex {
0024   TOOLS_NODE_NO_CAST(tex_quadrilateral,tools::sg::tex_quadrilateral,node)
0025 public:
0026   virtual void* cast(const std::string& a_class) const {
0027     {if(void* p = cmp_cast<tex_quadrilateral>(this,a_class)) return p;}
0028     {if(void* p = base_tex::cast(a_class)) return p;}
0029     return parent::cast(a_class);
0030   }
0031 public:
0032   sf<bool> show_border;
0033   mf_vec<vec3f,float> corners;
0034 public:
0035   virtual const desc_fields& node_desc_fields() const {
0036     TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::tex_quadrilateral)
0037     static const desc_fields s_v(parent::node_desc_fields(),6, //WARNING : take care of count.
0038       TOOLS_ARG_FIELD_DESC(img),
0039       TOOLS_ARG_FIELD_DESC(back_color),
0040       TOOLS_ARG_FIELD_DESC(expand),
0041       TOOLS_ARG_FIELD_DESC(limit),
0042       TOOLS_ARG_FIELD_DESC(show_border),
0043       TOOLS_ARG_FIELD_DESC(corners)
0044     );
0045     return s_v;
0046   }
0047 private:
0048   void add_fields(){
0049     add_field(&img);
0050     add_field(&back_color);
0051     add_field(&expand);
0052     add_field(&limit);
0053     add_field(&show_border);
0054     add_field(&corners);
0055   }
0056 public:
0057   virtual void render(render_action& a_action) {
0058     //a_action.out() << "tools::tex_quadrilateral::render : " << std::endl;
0059 
0060     //NOTE : we draw border (show_border is true) and background even if
0061     //       gen_texture() failed.
0062 
0063     if(touched()) {
0064       update_sg(a_action.out());
0065       reset_touched();
0066     }
0067     if(m_img.is_empty()) return;
0068     if(corners.size()!=4) return;
0069 
0070     unsigned int _id = get_tex_id(a_action.out(),a_action.render_manager(),m_img,nearest.value());
0071 
0072     const state& state = a_action.state();
0073 
0074     //image must be 2^n,2^m in size !
0075     // exa : 128x64
0076 
0077     f12 xyzs,nms;
0078 
0079     if(show_border.value()) {
0080       _front(xyzs,nms/*,0.01f*/); //have to revisit a_epsil.
0081 
0082       a_action.color4f(1,0,0,1);
0083     //a_action.line_width(4);
0084       a_action.line_width(1);
0085 
0086       a_action.draw_vertex_array(gl::line_loop(),12,xyzs);
0087 
0088       //pushes back the filled polygons to avoid z-fighting with lines
0089       a_action.set_polygon_offset(true);
0090 
0091       a_action.color4f(state.m_color);
0092       a_action.line_width(state.m_line_width);
0093     }
0094 
0095     //draw a back face pointing toward negative z :
0096    {a_action.color4f(back_color.value());
0097     f18 tris,_nms;
0098     _tris(tris,_nms);
0099     a_action.draw_vertex_normal_array(gl::triangles(),18,tris,_nms);
0100     a_action.color4f(state.m_color);}
0101 
0102     if(_id) {
0103       //a_action.color4f(back_color.value()); //do we want that ?
0104       _front(xyzs,nms);
0105       float tcs[8];
0106       set_tcs(tcs);
0107       a_action.draw_vertex_normal_array_texture(gl::triangle_fan(),12,xyzs,nms,_id,tcs);
0108       //a_action.color4f(state.m_color);
0109     }
0110     a_action.set_polygon_offset(state.m_GL_POLYGON_OFFSET_FILL);
0111   }
0112   virtual void pick(pick_action& a_action) {
0113     if(touched()) {
0114       update_sg(a_action.out());
0115       reset_touched();
0116     }
0117     if(m_pick_bbox_check_image) {if(m_img.is_empty()) return;}
0118     if(corners.size()!=4) return;
0119     f12 xyzs,nms;
0120     _front(xyzs,nms);
0121     a_action.add__primitive(*this,gl::triangle_fan(),12,xyzs,true);
0122   }
0123 
0124   virtual void bbox(bbox_action& a_action) {
0125     if(touched()) {
0126       update_sg(a_action.out());
0127       reset_touched();
0128     }
0129     if(m_pick_bbox_check_image) if(m_img.is_empty()) return;
0130     if(corners.size()!=4) return;
0131     f12 xyzs,nms;
0132     _front(xyzs,nms);
0133     a_action.add_points(12,xyzs);
0134   }
0135 public:
0136   virtual bool intersect_value(std::ostream&,intersect_type,const line<vec3f>& a_line,std::string& a_s) const {
0137     // a_line is in local world coordinate.
0138     float x,y;
0139     if(!line_2_img_ndc(a_line,x,y)) {a_s.clear();return false;}
0140     return img_ndc_value(x,y,a_s);
0141   }
0142 public:
0143   tex_quadrilateral()
0144   :parent()
0145   ,base_tex()
0146   ,show_border(false)
0147   ,corners()
0148   ,m_pick_bbox_check_image(true)
0149   {
0150     add_fields();
0151     corners.add(vec3f(-1,-1,0));
0152     corners.add(vec3f( 1,-1,0));
0153     corners.add(vec3f( 1, 1,0));
0154     corners.add(vec3f(-1, 1,0));
0155   }
0156   virtual ~tex_quadrilateral(){}
0157 public:
0158   tex_quadrilateral(const tex_quadrilateral& a_from)
0159   :parent(a_from)
0160   ,gstos(a_from)
0161   ,base_tex(a_from)
0162   ,show_border(a_from.show_border)
0163   ,corners(a_from.corners)
0164   ,m_pick_bbox_check_image(a_from.m_pick_bbox_check_image)
0165   {
0166     add_fields();
0167   }
0168   tex_quadrilateral& operator=(const tex_quadrilateral& a_from){
0169     parent::operator=(a_from);
0170     gstos::operator=(a_from);
0171     base_tex::operator=(a_from);
0172     if(&a_from==this) return *this;
0173     show_border = a_from.show_border;
0174     corners = a_from.corners;
0175     m_pick_bbox_check_image = a_from.m_pick_bbox_check_image;
0176     return *this;
0177   }
0178 public:
0179 
0180   //const img_byte& rendered_img() const {return m_img;}
0181 
0182 protected:
0183   void update_sg(std::ostream& a_out) {
0184     plane<vec3f> plane(corners[0],corners[1],corners[3]);
0185     m_normal = plane.normal();
0186     clean_gstos(); //must reset for all render_manager.
0187     base_tex::_update_sg_(a_out);
0188   }
0189 protected:
0190   bool img_ndc_value(float a_x,float a_y,std::string& a_s) const {
0191     const img_byte& _img = img.value();
0192     if(_img.is_empty()) {a_s.clear();return false;}
0193 
0194     int ix = int(float(_img.width())*a_x);
0195     int iy = int(float(_img.height())*a_y);
0196 
0197     //rgb of pixel :
0198     std::vector<unsigned char> pixel;
0199     if((ix<0)||(iy<0)||!_img.pixel(ix,iy,pixel)) {a_s.clear();return false;}
0200 
0201     a_s.clear();
0202     for(unsigned int ipix=0;ipix<pixel.size();ipix++) {
0203       if(ipix) a_s += " ";
0204       if(!numas<float>(float(pixel[ipix])/255.0f,a_s)){}
0205     }
0206 
0207     return true;
0208   }
0209 
0210   bool point_2_img_ndc(const vec3f& a_point,float& a_x,float& a_y) const {
0211     // a_point is assumed to be in the corners[0,1,3] plane.
0212 
0213     if(corners.size()!=4) {a_x = 0;a_y = 0;return false;}
0214     // In fact, in the below corners[2] is not used.
0215 
0216     // we assume that :
0217     //  corners[0] is the bottom-left of image
0218     //  corners[1] is the bottom-right of image
0219     //  corners[2] is the top-right of image
0220     //  corners[3] is the top-left of image
0221     vec3f x_axis = corners[1]-corners[0];
0222     float l_01 = x_axis.normalize();
0223     if(l_01==0.0f) {a_x = 0;a_y = 0;return false;}
0224     vec3f y_axis = corners[3]-corners[0];
0225     float l_03 = y_axis.normalize();
0226     if(l_03==0.0f) {a_x = 0;a_y = 0;return false;}
0227 
0228     float alpha = x_axis.dot(y_axis);
0229     float alpha_sq = alpha*alpha;
0230     if(alpha_sq==1.0f) {a_x = 0;a_y = 0;return false;}
0231 
0232     vec3f Op = a_point-corners[0];
0233 
0234     float px = Op.dot(x_axis);
0235     float py = Op.dot(y_axis);
0236 
0237     float lambda = (px-alpha*py)/(1.0f-alpha_sq);
0238     float mu = (py-alpha*px)/(1-alpha_sq);
0239 
0240     // We must have : Op = lambda*x_axis+mu*y_axis;
0241 
0242     a_x = lambda/l_01;
0243     a_y = mu/l_03;
0244 
0245     return true;
0246   }
0247 
0248   bool line_2_img_ndc(const line<vec3f>& a_line,float& a_x,float& a_y) const {
0249     // a_line is in local world coordinate.
0250     if(corners.size()!=4) {a_x = 0;a_y = 0;return false;}
0251     // In fact corners[2] is not used, only [0,1,3].
0252     plane<vec3f> plane(corners[0],corners[1],corners[3]);
0253     vec3f p;
0254     if(!plane.intersect(a_line,p)) {a_x = 0;a_y = 0;return false;}
0255     return point_2_img_ndc(p,a_x,a_y);
0256   }
0257 
0258   bool img_ndc_2_point(float a_x,float a_y,vec3f& a_point) const {
0259     if(corners.size()!=4) {a_point.set_value(0,0,0);return false;}
0260     // In fact, in the below corners[2] is not used.
0261 
0262     // we assume that :
0263     //  corners[0] is the bottom-left of image
0264     //  corners[1] is the bottom-right of image
0265     //  corners[2] is the top-right of image
0266     //  corners[3] is the top-left of image
0267     vec3f x_axis = corners[1]-corners[0];
0268     float l_01 = x_axis.normalize();
0269     if(l_01==0.0f) {a_point.set_value(0,0,0);return false;}
0270     vec3f y_axis = corners[3]-corners[0];
0271     float l_03 = y_axis.normalize();
0272     if(l_03==0.0f) {a_point.set_value(0,0,0);return false;}
0273 
0274     float alpha = x_axis.dot(y_axis);
0275     //float alpha_sq = alpha*alpha;
0276     //if(alpha_sq==1.0f) {a_point.set_value(0,0,0);return false;}
0277 
0278     float lambda = a_x*l_01;
0279     float mu = a_y*l_03;
0280 
0281     // px-alpha*py = lambda*(1.0f-alpha_sq);
0282     // py-alpha*px = mu*(1-alpha_sq);
0283 
0284     // px-alpha*(alpha*px+mu*(1-alpha_sq)) = lambda*(1-alpha_sq)
0285     // px*(1-alpha_sq)-mu*alpha*(1-alpha_sq)) = lambda*(1-alpha_sq)
0286     // px*(1-alpha_sq) = lambda*(1-alpha_sq)+mu*alpha*(1-alpha_sq));
0287     // px = lambda+mu*alpha;
0288 
0289     // py = lambda*alpha+mu;
0290 
0291     float px = lambda+mu*alpha;
0292     float py = lambda*alpha+mu;
0293 
0294     vec3f Op = px*x_axis+py*y_axis;
0295 
0296     a_point = Op+corners[0];
0297 
0298     return true;
0299   }
0300 
0301 /*
0302   float max_height() const {
0303     const std::vector<vec3f>& cs = corners.values();
0304     float _mn = cs[0].y();
0305     _mn = mn<float>(_mn,cs[1].y());
0306     _mn = mn<float>(_mn,cs[2].y());
0307     _mn = mn<float>(_mn,cs[3].y());
0308     float _mx = cs[0].y();
0309     _mx = mx<float>(_mx,cs[1].y());
0310     _mx = mx<float>(_mx,cs[2].y());
0311     _mx = mx<float>(_mx,cs[3].y());
0312     return (_mx-_mn);
0313   }
0314 
0315   float max_width() const {
0316     const std::vector<vec3f>& cs = corners.values();
0317     float _mn = cs[0].x();
0318     _mn = mn<float>(_mn,cs[1].x());
0319     _mn = mn<float>(_mn,cs[2].x());
0320     _mn = mn<float>(_mn,cs[3].x());
0321     float _mx = cs[0].x();
0322     _mx = mx<float>(_mx,cs[1].x());
0323     _mx = mx<float>(_mx,cs[2].x());
0324     _mx = mx<float>(_mx,cs[3].x());
0325     return (_mx-_mn);
0326   }
0327 */
0328 
0329   typedef float f12[12];
0330   void _front(f12& a_front,f12& a_nms,float a_epsil = 0.0f) {
0331     const std::vector<vec3f>& cs = corners.values();
0332 
0333     a_front[0] =  cs[0].x()-a_epsil;
0334     a_front[1] =  cs[0].y()-a_epsil;
0335     a_front[2] =  cs[0].z();
0336 
0337     a_front[3] =  cs[1].x()+a_epsil;
0338     a_front[4] =  cs[1].y()-a_epsil;
0339     a_front[5] =  cs[1].z();
0340 
0341     a_front[6] =  cs[2].x()+a_epsil;
0342     a_front[7] =  cs[2].y()+a_epsil;
0343     a_front[8] =  cs[2].z();
0344 
0345     a_front[ 9] = cs[3].x()-a_epsil;
0346     a_front[10] = cs[3].y()+a_epsil;
0347     a_front[11] = cs[3].z();
0348 
0349     a_nms[0] = m_normal.x();
0350     a_nms[1] = m_normal.y();
0351     a_nms[2] = m_normal.z();
0352 
0353     a_nms[3] = m_normal.x();
0354     a_nms[4] = m_normal.y();
0355     a_nms[5] = m_normal.z();
0356 
0357     a_nms[6] = m_normal.x();
0358     a_nms[7] = m_normal.y();
0359     a_nms[8] = m_normal.z();
0360 
0361     a_nms[9]  = m_normal.x();
0362     a_nms[10] = m_normal.y();
0363     a_nms[11] = m_normal.z();
0364   }
0365 
0366   void _back(f12& a_back) {
0367     const std::vector<vec3f>& cs = corners.values();
0368 
0369     a_back[0] =  cs[1].x();
0370     a_back[1] =  cs[1].y();
0371     a_back[2] =  cs[1].z();
0372 
0373     a_back[3] =  cs[0].x();
0374     a_back[4] =  cs[0].y();
0375     a_back[5] =  cs[0].z();
0376 
0377     a_back[6] =  cs[3].x();
0378     a_back[7] =  cs[3].y();
0379     a_back[8] =  cs[3].z();
0380 
0381     a_back[ 9] = cs[2].x();
0382     a_back[10] = cs[2].y();
0383     a_back[11] = cs[2].z();
0384   }
0385 
0386   typedef float f18[18];
0387   void _tris(f18& a_tris,f18& a_nms){
0388     f12 back;
0389     _back(back);
0390 
0391     a_tris[0] = back[0];
0392     a_tris[1] = back[1];
0393     a_tris[2] = back[2];
0394 
0395     a_tris[3] = back[3];
0396     a_tris[4] = back[4];
0397     a_tris[5] = back[5];
0398 
0399     a_tris[6] = back[6];
0400     a_tris[7] = back[7];
0401     a_tris[8] = back[8];
0402     //
0403     a_tris[9]  = back[6];
0404     a_tris[10] = back[7];
0405     a_tris[11] = back[8];
0406 
0407     a_tris[12] = back[9];
0408     a_tris[13] = back[10];
0409     a_tris[14] = back[11];
0410 
0411     a_tris[15] = back[0];
0412     a_tris[16] = back[1];
0413     a_tris[17] = back[2];
0414 
0415     ///////////////////// back
0416     a_nms[0] = -m_normal.x();
0417     a_nms[1] = -m_normal.y();
0418     a_nms[2] = -m_normal.z();
0419 
0420     a_nms[3] = -m_normal.x();
0421     a_nms[4] = -m_normal.y();
0422     a_nms[5] = -m_normal.z();
0423 
0424     a_nms[6] = -m_normal.x();
0425     a_nms[7] = -m_normal.y();
0426     a_nms[8] = -m_normal.z();
0427     //
0428     a_nms[9]  = -m_normal.x();
0429     a_nms[10] = -m_normal.y();
0430     a_nms[11] = -m_normal.z();
0431 
0432     a_nms[12] = -m_normal.x();
0433     a_nms[13] = -m_normal.y();
0434     a_nms[14] = -m_normal.z();
0435 
0436     a_nms[15] = -m_normal.x();
0437     a_nms[16] = -m_normal.y();
0438     a_nms[17] = -m_normal.z();
0439   }
0440 protected:
0441   vec3f m_normal;
0442   bool m_pick_bbox_check_image; //for SDSS_image.
0443 };
0444 
0445 }}
0446 
0447 #endif