// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_sg_atb_vertices #define tools_sg_atb_vertices #include "vertices" #include "gstos" namespace tools { namespace sg { class atb_vertices : public vertices, public gstos { TOOLS_NODE(atb_vertices,tools::sg::atb_vertices,vertices) public: mf rgbas; mf nms; sf do_back; sf epsilon; public: virtual const std::vector& node_fields() const { TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::atb_vertices) static std::vector s_v; if(s_v.empty()) { s_v = parent::node_fields(); TOOLS_ADD_FIELD_DESC(rgbas) TOOLS_ADD_FIELD_DESC(nms) TOOLS_ADD_FIELD_DESC(do_back) TOOLS_ADD_FIELD_DESC(epsilon) } return s_v; } private: void add_fields(){ add_field(&rgbas); add_field(&nms); add_field(&do_back); add_field(&epsilon); } protected: //gstos virtual unsigned int create_gsto(std::ostream&,sg::gl_manager& a_mgr) { //unsigned int npt = xyzs.values().size()/3; //::printf("debug : atb_vertices : %lu : create_gsto : %u\n",this,npt); std::vector gsto_data; if(rgbas.size()) { if(nms.size()) { if(do_back.value()) { append(gsto_data,xyzs.values()); append(gsto_data,nms.values()); append(gsto_data,m_back_xyzs); append(gsto_data,m_back_nms); append(gsto_data,rgbas.values()); } else { append(gsto_data,xyzs.values()); append(gsto_data,nms.values()); append(gsto_data,rgbas.values()); } } else { append(gsto_data,xyzs.values()); append(gsto_data,rgbas.values()); } } else { if(nms.size()) { append(gsto_data,xyzs.values()); append(gsto_data,nms.values()); } else { append(gsto_data,xyzs.values()); } } return a_mgr.create_gsto_from_data(gsto_data); } public: virtual void render(render_action& a_action) { if(touched()) { if(do_back.value()) gen_back(); reset_touched(); } if(xyzs.empty()) return; const state& state = a_action.state(); if(state.m_use_gsto) { unsigned int _id = get_gsto_id(a_action.out(),a_action.gl_manager()); if(_id) { a_action.begin_gsto(_id); if(rgbas.size()) { if(nms.size()) { size_t npt = xyzs.values().size()/3; bufpos pos_xyzs = 0; bufpos pos_nms = 0; bufpos pos_back_xyzs = 0; bufpos pos_back_nms = 0; bufpos pos_rgbas = 0; {size_t sz = npt*3; if(do_back.value()) { pos_xyzs = 0; pos_nms = pos_xyzs+sz*sizeof(float); //bytes pos_back_xyzs = pos_nms+sz*sizeof(float); pos_back_nms = pos_back_xyzs+sz*sizeof(float); pos_rgbas = pos_back_nms+sz*sizeof(float); } else { pos_xyzs = 0; pos_nms = pos_xyzs+sz*sizeof(float); pos_rgbas = pos_nms+sz*sizeof(float); }} if(gl::is_line(mode.value())) { //Same logic as Inventor SoLightModel.model = BASE_COLOR. a_action.set_lighting(false); if(do_back.value()) a_action.draw_gsto_vcn(mode.value(),npt,pos_back_xyzs,pos_rgbas,pos_back_nms); a_action.draw_gsto_vcn(mode.value(),npt,pos_xyzs,pos_rgbas,pos_nms); a_action.set_lighting(state.m_GL_LIGHTING); } else { if(do_back.value()) a_action.draw_gsto_vcn(mode.value(),npt,pos_back_xyzs,pos_rgbas,pos_back_nms); a_action.draw_gsto_vcn(mode.value(),npt,pos_xyzs,pos_rgbas,pos_nms); } } else { size_t npt = xyzs.values().size()/3; bufpos pos_xyzs = 0; bufpos pos_rgbas = npt*3*sizeof(float); if(gl::is_line(mode.value())) { //Same logic as Inventor SoLightModel.model = BASE_COLOR. a_action.set_lighting(false); a_action.draw_gsto_vc(mode.value(),npt,pos_xyzs,pos_rgbas); a_action.set_lighting(state.m_GL_LIGHTING); } else { a_action.draw_gsto_vc(mode.value(),npt,pos_xyzs,pos_rgbas); } } } else { //rgbas.empty() if(nms.size()) { size_t npt = xyzs.values().size()/3; bufpos pos_xyzs = 0; bufpos pos_nms = npt*3*sizeof(float); if(gl::is_line(mode.value())) { //Same logic as Inventor SoLightModel.model = BASE_COLOR. a_action.set_lighting(false); a_action.draw_gsto_vn(mode.value(),npt,pos_xyzs,pos_nms); a_action.set_lighting(state.m_GL_LIGHTING); } else { a_action.draw_gsto_vn(mode.value(),npt,pos_xyzs,pos_nms); } } else { size_t npt = xyzs.values().size()/3; bufpos pos = 0; if(gl::is_line(mode.value())) { //Same logic as Inventor SoLightModel.model = BASE_COLOR. a_action.set_lighting(false); a_action.draw_gsto_v(mode.value(),npt,pos); a_action.set_lighting(state.m_GL_LIGHTING); } else { a_action.draw_gsto_v(mode.value(),npt,pos); } } } a_action.end_gsto(); return; } else { //!_id // use immediate rendering. } } else { clean_gstos(&a_action.gl_manager()); } // immediate rendering : if(rgbas.size()) { if(nms.size()) { if(gl::is_line(mode.value())) { //Same logic as Inventor SoLightModel.model = BASE_COLOR. a_action.set_lighting(false); if(do_back.value()) a_action.draw_vertex_color_normal_array(mode.value(),m_back_xyzs,rgbas.values(),m_back_nms); a_action.draw_vertex_color_normal_array(mode.value(),xyzs.values(),rgbas.values(),nms.values()); a_action.set_lighting(state.m_GL_LIGHTING); } else { if(do_back.value()) a_action.draw_vertex_color_normal_array(mode.value(),m_back_xyzs,rgbas.values(),m_back_nms); a_action.draw_vertex_color_normal_array(mode.value(),xyzs.values(),rgbas.values(),nms.values()); } } else { if(gl::is_line(mode.value())) { //Same logic as Inventor SoLightModel.model = BASE_COLOR. a_action.set_lighting(false); a_action.draw_vertex_color_array(mode.value(),xyzs.values(),rgbas.values()); a_action.set_lighting(state.m_GL_LIGHTING); } else { a_action.draw_vertex_color_array(mode.value(),xyzs.values(),rgbas.values()); } } } else { //rgbas.empty() if(nms.size()) { if(gl::is_line(mode.value())) { //Same logic as Inventor SoLightModel.model = BASE_COLOR. a_action.set_lighting(false); a_action.draw_vertex_normal_array(mode.value(),xyzs.values(),nms.values()); a_action.set_lighting(state.m_GL_LIGHTING); } else { a_action.draw_vertex_normal_array(mode.value(),xyzs.values(),nms.values()); } } else { if(gl::is_line(mode.value())) { //Same logic as Inventor SoLightModel.model = BASE_COLOR. a_action.set_lighting(false); a_action.draw_vertex_array(mode.value(),xyzs.values()); a_action.set_lighting(state.m_GL_LIGHTING); } else { a_action.draw_vertex_array(mode.value(),xyzs.values()); } } } } public: atb_vertices() :parent() ,do_back(false) ,epsilon(0) ,m_xyzs_pos(0) ,m_rgbas_pos(0) ,m_nms_pos(0) { #ifdef TOOLS_MEM mem::increment(s_class().c_str()); #endif add_fields(); } virtual ~atb_vertices(){ #ifdef TOOLS_MEM mem::decrement(s_class().c_str()); #endif } public: atb_vertices(const atb_vertices& a_from) :parent(a_from) ,gstos(a_from) ,rgbas(a_from.rgbas) ,nms(a_from.nms) ,do_back(a_from.do_back) ,epsilon(a_from.epsilon) ,m_xyzs_pos(a_from.m_xyzs_pos) ,m_rgbas_pos(a_from.m_rgbas_pos) ,m_nms_pos(a_from.m_nms_pos) { #ifdef TOOLS_MEM mem::increment(s_class().c_str()); #endif add_fields(); } atb_vertices& operator=(const atb_vertices& a_from){ parent::operator=(a_from); gstos::operator=(a_from); rgbas = a_from.rgbas; nms = a_from.nms; do_back = a_from.do_back; epsilon = a_from.epsilon; m_xyzs_pos = a_from.m_xyzs_pos; m_rgbas_pos = a_from.m_rgbas_pos; m_nms_pos = a_from.m_nms_pos; return *this; } public: void add_pos_color(float a_x,float a_y,float a_z,float a_r,float a_g,float a_b,float a_a) { xyzs.add(a_x); xyzs.add(a_y); xyzs.add(a_z); rgbas.add(a_r); rgbas.add(a_g); rgbas.add(a_b); rgbas.add(a_a); } template void add_pos_color(const VEC& a_pos,const COLOR& a_col) { xyzs.add(a_pos.x()); xyzs.add(a_pos.y()); xyzs.add(a_pos.z()); rgbas.add(a_col.r()); rgbas.add(a_col.g()); rgbas.add(a_col.b()); rgbas.add(a_col.a()); } void allocate_pos_color(size_t a_npt) { xyzs.values().resize(a_npt*3); rgbas.values().resize(a_npt*4); m_xyzs_pos = 0; m_rgbas_pos = 0; } template void add_pos_color_allocated(const VEC& a_pos,const COLOR& a_col) { {std::vector& v = xyzs.values(); v[m_xyzs_pos] = a_pos.x();m_xyzs_pos++; v[m_xyzs_pos] = a_pos.y();m_xyzs_pos++; v[m_xyzs_pos] = a_pos.z();m_xyzs_pos++; xyzs.touch();} {std::vector& v = rgbas.values(); v[m_rgbas_pos] = a_col.r();m_rgbas_pos++; v[m_rgbas_pos] = a_col.g();m_rgbas_pos++; v[m_rgbas_pos] = a_col.b();m_rgbas_pos++; v[m_rgbas_pos] = a_col.a();m_rgbas_pos++; rgbas.touch();} } template void add_pos_color_normal(const VEC& a_pos,const COLOR& a_col,const VEC& a_nm) { xyzs.add(a_pos.x()); xyzs.add(a_pos.y()); xyzs.add(a_pos.z()); rgbas.add(a_col.r()); rgbas.add(a_col.g()); rgbas.add(a_col.b()); rgbas.add(a_col.a()); nms.add(a_nm.x()); nms.add(a_nm.y()); nms.add(a_nm.z()); } void allocate_pos_color_normal(size_t a_npt) { xyzs.values().resize(a_npt*3); rgbas.values().resize(a_npt*4); nms.values().resize(a_npt*3); m_xyzs_pos = 0; m_rgbas_pos = 0; m_nms_pos = 0; } template void add_pos_color_normal_allocated(const VEC& a_pos,const COLOR& a_col,const VEC& a_nm) { {std::vector& v = xyzs.values(); v[m_xyzs_pos] = a_pos.x();m_xyzs_pos++; v[m_xyzs_pos] = a_pos.y();m_xyzs_pos++; v[m_xyzs_pos] = a_pos.z();m_xyzs_pos++; xyzs.touch();} {std::vector& v = rgbas.values(); v[m_rgbas_pos] = a_col.r();m_rgbas_pos++; v[m_rgbas_pos] = a_col.g();m_rgbas_pos++; v[m_rgbas_pos] = a_col.b();m_rgbas_pos++; v[m_rgbas_pos] = a_col.a();m_rgbas_pos++; rgbas.touch();} {std::vector& v = nms.values(); v[m_nms_pos] = a_nm.x();m_nms_pos++; v[m_nms_pos] = a_nm.y();m_nms_pos++; v[m_nms_pos] = a_nm.z();m_nms_pos++; nms.touch();} } void add_rgba(float a_r,float a_g,float a_b,float a_a) { rgbas.add(a_r); rgbas.add(a_g); rgbas.add(a_b); rgbas.add(a_a); } void add_color(const colorf& a_col) { rgbas.add(a_col.r()); rgbas.add(a_col.g()); rgbas.add(a_col.b()); rgbas.add(a_col.a()); } void add_normal(float a_x,float a_y,float a_z) { nms.add(a_x); nms.add(a_y); nms.add(a_z); } template void add_normal(const VEC& a_nm) { nms.add(a_nm.x()); nms.add(a_nm.y()); nms.add(a_nm.z()); } void add_rgba_allocated(size_t& a_pos,float a_r,float a_g,float a_b,float a_a) { std::vector& v = rgbas.values(); v[a_pos] = a_r;a_pos++; v[a_pos] = a_g;a_pos++; v[a_pos] = a_b;a_pos++; v[a_pos] = a_a;a_pos++; rgbas.touch(); } void add_normal_allocated(size_t& a_pos,float a_x,float a_y,float a_z) { std::vector& v = nms.values(); v[a_pos] = a_x;a_pos++; v[a_pos] = a_y;a_pos++; v[a_pos] = a_z;a_pos++; nms.touch(); } template void add_pos_normal(const VEC& a_pos,const VEC& a_nm) { xyzs.add(a_pos.x()); xyzs.add(a_pos.y()); xyzs.add(a_pos.z()); nms.add(a_nm.x()); nms.add(a_nm.y()); nms.add(a_nm.z()); } bool add_dashed_line_rgba(float a_bx,float a_by,float a_bz, float a_ex,float a_ey,float a_ez, unsigned int a_num_dash, float a_r,float a_g,float a_b,float a_a) { if(!parent::add_dashed_line(a_bx,a_by,a_bz,a_ex,a_ey,a_ez,a_num_dash)) return false; for(unsigned int index=0;index& _xyzs = xyzs.values(); std::vector& _nms = nms.values(); if(_xyzs.empty()) return; m_back_xyzs.resize(_xyzs.size(),0); m_back_nms.resize(_nms.size(),0); float epsil = epsilon.value(); if(mode.value()==gl::triangle_fan()) { //reverse after first point. m_back_xyzs[0] = _xyzs[0] - _nms[0] * epsil; m_back_xyzs[1] = _xyzs[1] - _nms[1] * epsil; m_back_xyzs[2] = _xyzs[2] - _nms[2] * epsil; {std::vector::const_iterator it = _xyzs.begin()+3; std::vector::const_iterator _end = _xyzs.end(); std::vector::const_iterator itn = _nms.begin()+3; std::vector::reverse_iterator it2 = m_back_xyzs.rbegin(); for(;it!=_end;it2+=3) { *(it2+2) = *it - *itn * epsil; it++;itn++; //x *(it2+1) = *it - *itn * epsil; it++;itn++; //y *(it2+0) = *it - *itn * epsil; it++;itn++; //z }} m_back_nms[0] = _nms[0] * -1.0f; m_back_nms[1] = _nms[1] * -1.0f; m_back_nms[2] = _nms[2] * -1.0f; {std::vector::const_iterator it = _nms.begin()+3; std::vector::const_iterator _end = _nms.end(); std::vector::reverse_iterator it2 = m_back_nms.rbegin(); for(;it!=_end;it2+=3) { *(it2+2) = *it * -1.0f; it++; *(it2+1) = *it * -1.0f; it++; *(it2+0) = *it * -1.0f; it++; }} } else { {std::vector::const_iterator it = _xyzs.begin(); std::vector::const_iterator _end = _xyzs.end(); std::vector::const_iterator itn = _nms.begin(); std::vector::reverse_iterator it2 = m_back_xyzs.rbegin(); for(;it!=_end;it2+=3) { *(it2+2) = *it - *itn * epsil; it++;itn++; //x *(it2+1) = *it - *itn * epsil; it++;itn++; //y *(it2+0) = *it - *itn * epsil; it++;itn++; //z }} {std::vector::const_iterator it = _nms.begin(); std::vector::const_iterator _end = _nms.end(); std::vector::reverse_iterator it2 = m_back_nms.rbegin(); for(;it!=_end;it2+=3) { *(it2+2) = *it * -1.0f; it++; *(it2+1) = *it * -1.0f; it++; *(it2+0) = *it * -1.0f; it++; }} } } protected: std::vector m_back_xyzs; std::vector m_back_nms; std::vector m_edges; protected: size_t m_xyzs_pos; size_t m_rgbas_pos; size_t m_nms_pos; }; }} #endif