Warning, /include/Geant4/tools/sg/tex_rect 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_rect
0005 #define tools_sg_tex_rect
0006
0007 // node to render an RGB tools::img_byte with ::glTexImage2D.
0008
0009 //#define TOOLS_SG_TEX_RECT_DEBUG
0010
0011 #include "node"
0012 #include "render_action"
0013 #include "pick_action"
0014 #include "bbox_action"
0015 #include "event_action"
0016 #include "render_manager"
0017 #include "gstos"
0018 #include "base_tex"
0019
0020 #include "../pointer"
0021 #include "../num2s"
0022
0023 namespace tools {
0024 namespace sg {
0025
0026 class tex_rect : public node, public gstos, public base_tex {
0027 TOOLS_NODE_NO_CAST(tex_rect,tools::sg::tex_rect,node)
0028 public:
0029 virtual void* cast(const std::string& a_class) const {
0030 {if(void* p = cmp_cast<tex_rect>(this,a_class)) return p;}
0031 {if(void* p = base_tex::cast(a_class)) return p;}
0032 return parent::cast(a_class);
0033 }
0034 public:
0035 sf<bool> show_border;
0036 sf<float> height;
0037 public:
0038 virtual const desc_fields& node_desc_fields() const {
0039 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::tex_rect)
0040 static const desc_fields s_v(parent::node_desc_fields(),6, //WARNING : take care of count.
0041 TOOLS_ARG_FIELD_DESC(img),
0042 TOOLS_ARG_FIELD_DESC(back_color),
0043 TOOLS_ARG_FIELD_DESC(expand),
0044 TOOLS_ARG_FIELD_DESC(limit),
0045 TOOLS_ARG_FIELD_DESC(show_border),
0046 TOOLS_ARG_FIELD_DESC(height)
0047 );
0048 return s_v;
0049 }
0050 private:
0051 void add_fields(){
0052 add_field(&img);
0053 add_field(&back_color);
0054 add_field(&expand);
0055 add_field(&limit);
0056 add_field(&show_border);
0057 add_field(&height);
0058 }
0059 public:
0060 virtual void render(render_action& a_action) {
0061 #ifdef TOOLS_SG_TEX_RECT_DEBUG
0062 a_action.out() << "tools::tex_rect::render : begin : 001 : " << std::endl;
0063 #endif
0064
0065 //NOTE : we draw border (show_border is true) and background even if
0066 // gen_texture() failed.
0067
0068 if(touched()) {
0069 #ifdef TOOLS_SG_TEX_RECT_DEBUG
0070 a_action.out() << "tools::tex_rect::render : touched." << std::endl;
0071 #endif
0072 update_sg(a_action.out());
0073 reset_touched();
0074 }
0075 if(m_img.is_empty()) {
0076 #ifdef TOOLS_SG_TEX_RECT_DEBUG
0077 a_action.out() << "tools::tex_rect::render : m_img is empty." << std::endl;
0078 #endif
0079 return;
0080 }
0081
0082 #ifdef TOOLS_SG_TEX_RECT_DEBUG
0083 a_action.out() << "tools::tex_rect::render : have a m_img. get_tex_id ..." << std::endl;
0084 #endif
0085
0086 unsigned int _id = get_tex_id(a_action.out(),a_action.render_manager(),m_img,nearest.value());
0087
0088 #ifdef TOOLS_SG_TEX_RECT_DEBUG
0089 a_action.out() << "tools::tex_rect::render : get_tex_id : " << _id << "." << std::endl;
0090 #endif
0091
0092 const state& state = a_action.state();
0093
0094 //image must be 2^n,2^m in size !
0095 // exa : 128x64
0096
0097 f12 xyzs;
0098
0099 if(show_border.value()) {
0100 #ifdef TOOLS_SG_TEX_RECT_DEBUG
0101 a_action.out() << "tools::tex_rect::render : show_border." << std::endl;
0102 #endif
0103 f12 nms;
0104 _front(xyzs,nms,0.01f);
0105
0106 a_action.color4f(1,0,0,1);
0107 a_action.line_width(4);
0108
0109 a_action.draw_vertex_array(gl::line_loop(),12,xyzs);
0110
0111 //pushes back the filled polygons to avoid z-fighting with lines
0112 a_action.set_polygon_offset(true);
0113
0114 a_action.color4f(state.m_color);
0115 a_action.line_width(state.m_line_width);
0116 }
0117
0118 #ifdef TOOLS_SG_TEX_RECT_DEBUG
0119 a_action.out() << "tools::tex_rect::render : draw back face." << std::endl;
0120 #endif
0121
0122 //draw a back face pointing toward negative z :
0123 {a_action.color4f(back_color.value());
0124 f18 tris,nms;
0125 _tris(tris,nms);
0126 a_action.draw_vertex_normal_array(gl::triangles(),18,tris,nms);
0127 a_action.color4f(state.m_color);}
0128
0129 if(_id) {
0130 #ifdef TOOLS_SG_TEX_RECT_DEBUG
0131 a_action.out() << "tools::tex_rect::render : draw_vertex_normal_array_texture." << std::endl;
0132 #endif
0133 f12 nms;
0134 _front(xyzs,nms);
0135 float tcs[8];
0136 set_tcs(tcs);
0137 a_action.draw_vertex_normal_array_texture(gl::triangle_fan(),12,xyzs,nms,_id,tcs);
0138 }
0139 a_action.set_polygon_offset(state.m_GL_POLYGON_OFFSET_FILL);
0140 }
0141 virtual void pick(pick_action& a_action) {
0142 if(touched()) {
0143 update_sg(a_action.out());
0144 reset_touched();
0145 }
0146 if(m_img.is_empty()) return;
0147 f12 xyzs,nms;
0148 _front(xyzs,nms);
0149 a_action.add__primitive(*this,gl::triangle_fan(),12,xyzs,true);
0150 }
0151
0152 virtual void bbox(bbox_action& a_action) {
0153 if(touched()) {
0154 update_sg(a_action.out());
0155 reset_touched();
0156 }
0157 if(m_img.is_empty()) return;
0158 f12 xyzs,nms;
0159 _front(xyzs,nms);
0160 a_action.add_points(12,xyzs);
0161 }
0162 public:
0163 virtual bool intersect_value(std::ostream&,intersect_type,const line<vec3f>& a_line,std::string& a_s) const {
0164 // a_line is in local world coordinate.
0165
0166 const img_byte& _img = img.value();
0167 if(_img.is_empty()) {a_s.clear();return false;}
0168
0169 float aspect = float(_img.width())/float(_img.height());
0170 float h2 = height.value()*0.5f;
0171 float w2 = aspect*h2;
0172
0173 plane<vec3f> plane(vec3f(w2,h2,0),vec3f(-w2,h2,0),vec3f(-w2,-h2,0));
0174 vec3f p;
0175 if(!plane.intersect(a_line,p)) {a_s.clear();return false;}
0176
0177 float imw = (float)_img.width();
0178 float imh = (float)_img.height();
0179
0180 //image coordinates :
0181 int ix = int((imw*p.x()/w2+imw)*0.5f);
0182 int iy = int((imh*p.y()/h2+imh)*0.5f);
0183
0184 //rgb of pixel :
0185 std::vector<unsigned char> pixel;
0186 if((ix<0)||(iy<0)||!_img.pixel(ix,iy,pixel)) {a_s.clear();return false;}
0187
0188 a_s.clear();
0189 for(unsigned int ipix=0;ipix<pixel.size();ipix++) {
0190 if(ipix) a_s += " ";
0191 if(!numas<float>(float(pixel[ipix])/255.0f,a_s)){}
0192 }
0193
0194 return true;
0195 }
0196 public:
0197 tex_rect()
0198 :parent()
0199 ,base_tex()
0200 ,show_border(false)
0201 ,height(1)
0202 {
0203 add_fields();
0204 }
0205 virtual ~tex_rect(){}
0206 public:
0207 tex_rect(const tex_rect& a_from)
0208 :parent(a_from)
0209 ,gstos(a_from)
0210 ,base_tex(a_from)
0211 ,show_border(a_from.show_border)
0212 ,height(a_from.height)
0213 {
0214 add_fields();
0215 }
0216 tex_rect& operator=(const tex_rect& a_from){
0217 parent::operator=(a_from);
0218 gstos::operator=(a_from);
0219 base_tex::operator=(a_from);
0220 if(&a_from==this) return *this;
0221 show_border = a_from.show_border;
0222 height = a_from.height;
0223 return *this;
0224 }
0225 public:
0226
0227 //const img_byte& rendered_img() const {return m_img;}
0228
0229 void rendered_size(std::ostream& a_out,unsigned int& a_w,unsigned int& a_h) {
0230 update_sg(a_out);
0231 reset_touched();
0232 a_w = m_img.width();
0233 a_h = m_img.height();
0234 }
0235
0236 protected:
0237 //virtual //NOTE : virtual for diaporama node. (but warning with clang -g4flags).
0238 void update_sg(std::ostream& a_out) {
0239 clean_gstos(); //must reset for all render_manager.
0240 if(height.value()<=0) {
0241 m_img.make_empty();
0242 return;
0243 }
0244 base_tex::_update_sg_(a_out);
0245 }
0246 protected:
0247
0248 typedef float f12[12];
0249 void _front(f12& front,f12& nms,float a_epsil = 0.0f) { //[12]
0250 float aspect = float(img.value().width())/float(img.value().height());
0251 float h2 = height*0.5f;
0252 float w2 = aspect*h2;
0253
0254 h2 += a_epsil;
0255 w2 += a_epsil;
0256
0257 front[0] = -w2;
0258 front[1] = -h2;
0259 front[2] = 0;
0260
0261 front[3] = w2;
0262 front[4] = -h2;
0263 front[5] = 0;
0264
0265 front[6] = w2;
0266 front[7] = h2;
0267 front[8] = 0;
0268
0269 front[ 9] = -w2;
0270 front[10] = h2;
0271 front[11] = 0;
0272
0273 nms[0] = 0;
0274 nms[1] = 0;
0275 nms[2] = 1;
0276
0277 nms[3] = 0;
0278 nms[4] = 0;
0279 nms[5] = 1;
0280
0281 nms[6] = 0;
0282 nms[7] = 0;
0283 nms[8] = 1;
0284
0285 nms[9] = 0;
0286 nms[10] = 0;
0287 nms[11] = 1;
0288 }
0289
0290 void _back(f12& back) { //[12]
0291 float aspect = float(img.value().width())/float(img.value().height());
0292 float h2 = height*0.5f;
0293 float w2 = aspect*h2;
0294 float d2 = 0;
0295
0296 back[0] = w2;back[ 1] = -h2;back[ 2] = d2;
0297 back[3] = -w2;back[ 4] = -h2;back[ 5] = d2;
0298 back[6] = -w2;back[ 7] = h2;back[ 8] = d2;
0299 back[9] = w2;back[10] = h2;back[11] = d2;
0300 }
0301
0302 typedef float f18[18];
0303 void _tris(f18& tris,f18& nms){
0304 f12 back;
0305 _back(back);
0306
0307 tris[0] = back[0];
0308 tris[1] = back[1];
0309 tris[2] = back[2];
0310
0311 tris[3] = back[3];
0312 tris[4] = back[4];
0313 tris[5] = back[5];
0314
0315 tris[6] = back[6];
0316 tris[7] = back[7];
0317 tris[8] = back[8];
0318 //
0319 tris[9] = back[6];
0320 tris[10] = back[7];
0321 tris[11] = back[8];
0322
0323 tris[12] = back[9];
0324 tris[13] = back[10];
0325 tris[14] = back[11];
0326
0327 tris[15] = back[0];
0328 tris[16] = back[1];
0329 tris[17] = back[2];
0330
0331 ///////////////////// back
0332 nms[0] = 0;
0333 nms[1] = 0;
0334 nms[2] = -1;
0335
0336 nms[3] = 0;
0337 nms[4] = 0;
0338 nms[5] = -1;
0339
0340 nms[6] = 0;
0341 nms[7] = 0;
0342 nms[8] = -1;
0343 //
0344 nms[9] = 0;
0345 nms[10] = 0;
0346 nms[11] = -1;
0347
0348 nms[12] = 0;
0349 nms[13] = 0;
0350 nms[14] = -1;
0351
0352 nms[15] = 0;
0353 nms[16] = 0;
0354 nms[17] = -1;
0355 }
0356 };
0357
0358 }}
0359
0360 #endif