// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_sg_primitive_visitor #define tools_sg_primitive_visitor #include "../glprims" #include "../vdata" namespace tools { namespace sg { class primitive_visitor { protected: virtual bool project(float& a_x,float& a_y,float& a_z,float& a_w) = 0; // xyzw virtual bool add_point(float,float,float,float) = 0; // xyzw & rgba virtual bool add_point(float,float,float,float, float,float,float,float) = 0; // 2 xyzw virtual bool add_line(float,float,float,float, float,float,float,float) = 0; // 2 (xyzw & rgba) virtual bool add_line(float,float,float,float, float,float,float,float, float,float,float,float, float,float,float,float) = 0; // 3 xyzw virtual bool add_triangle(float,float,float,float, float,float,float,float, float,float,float,float) = 0; // 3 (xywz & rgba) virtual bool add_triangle(float,float,float,float, float,float,float,float, float,float,float,float, float,float,float,float, float,float,float,float, float,float,float,float) = 0; public: primitive_visitor():m_mode(gl::points()){} virtual ~primitive_visitor(){} public: primitive_visitor(const primitive_visitor&):m_mode(gl::points()){} primitive_visitor& operator=(const primitive_visitor&){return *this;} public: void add_one_point(float a_x,float a_y,float a_z) { float w; project(a_x,a_y,a_z,w); add_point(a_x,a_y,a_z,w); } bool add_triangle_fan(size_t a_floatn,const float* a_xyzs,bool a_stop = false){ size_t num = a_floatn/3; if(num<3) return false; m_mode = gl::triangle_fan(); float p1x,p1y,p1z,w1=1; float p2x,p2y,p2z,w2=1; float p3x,p3y,p3z,w3=1; const float* pos1 = a_xyzs+3*0; p1x = *(pos1+0); p1y = *(pos1+1); p1z = *(pos1+2); project(p1x,p1y,p1z,w1); const float* pos2 = a_xyzs+3*1; p2x = *(pos2+0); p2y = *(pos2+1); p2z = *(pos2+2); project(p2x,p2y,p2z,w2); for(size_t index=2;index& a_xyzs,bool a_stop = false){ const float* _xyzs = tools::vec_data(a_xyzs); return add_primitive(a_mode,a_xyzs.size(),_xyzs,a_stop); } bool add_primitive_xy(gl::mode_t a_mode,const std::vector& a_xys,bool a_stop = false,bool a_triangle_revert = false){ const float* _xys = tools::vec_data(a_xys); return add_primitive_xy(a_mode,a_xys.size(),_xys,a_stop,a_triangle_revert); } bool add_line_strip(const std::vector& a_xyzs,bool a_stop = false){ const float* _xyzs = tools::vec_data(a_xyzs); return add_line_strip(a_xyzs.size(),_xyzs,a_stop); } bool add_line_loop(const std::vector& a_xyzs,bool a_stop = false){ const float* _xyzs = tools::vec_data(a_xyzs); return add_line_loop(a_xyzs.size(),_xyzs,a_stop); } bool add_lines(const std::vector& a_xyzs,bool a_stop = false){ const float* _xyzs = tools::vec_data(a_xyzs); return add_lines(a_xyzs.size(),_xyzs,a_stop); } bool add_points(const std::vector& a_xyzs,bool a_stop = false){ const float* _xyzs = tools::vec_data(a_xyzs); return add_points(a_xyzs.size(),_xyzs,a_stop); } bool add_triangle_strip(const std::vector& a_xyzs,bool a_stop = false){ const float* _xyzs = tools::vec_data(a_xyzs); return add_triangle_strip(a_xyzs.size(),_xyzs,a_stop); } bool add_points_xy(const std::vector& a_xys,bool a_stop = false){ const float* _xys = tools::vec_data(a_xys); return add_points_xy(a_xys.size(),_xys,a_stop); } bool add_lines_xy(const std::vector& a_xys,bool a_stop = false){ const float* _xys = tools::vec_data(a_xys); return add_lines_xy(a_xys.size(),_xys,a_stop); } bool add_triangle_strip_xy(const std::vector& a_xys,bool a_stop = false){ const float* _xys = tools::vec_data(a_xys); return add_triangle_strip_xy(a_xys.size(),_xys,a_stop); } public: //for sg::[tex_]sphere::visit() template : bool add_triangle_fan(size_t a_floatn,const float* a_xyzs,const float* /*a_nms*/) { return add_triangle_fan(a_floatn,a_xyzs); } bool add_triangle_fan(size_t a_floatn,const float* a_xyzs,const float* /*a_rgbas*/,const float* /*a_nms*/) { return add_triangle_fan(a_floatn,a_xyzs); } /* bool add_triangles_texture(size_t a_floatn,const float* a_xyzs,unsigned int,const float*){ return add_triangles(a_floatn,a_xyzs); } bool add_triangle_fan_texture(size_t a_floatn,const float* a_xyzs,unsigned int,const float*){ return add_triangle_fan(a_floatn,a_xyzs); } bool add_triangle_strip_texture(size_t a_floatn,const float* a_xyzs,unsigned int,const float*){ return add_triangle_strip(a_floatn,a_xyzs,false); } */ bool add_triangle_fan_texture(size_t a_floatn,const float* a_xyzs,const float* /*a_nms*/,unsigned int,const float*){ return add_triangle_fan(a_floatn,a_xyzs); } bool add_triangle_strip_texture(size_t a_floatn,const float* a_xyzs,const float* /*a_nms*/,unsigned int,const float*){ return add_triangle_strip(a_floatn,a_xyzs,false); } bool add_triangle_strip(size_t a_floatn,const float* a_xyzs,const float* /*a_nms*/) { return add_triangle_strip(a_floatn,a_xyzs,false); } bool add_triangle_strip(size_t a_floatn,const float* a_xyzs,const float* /*a_rgbas*/,const float* /*a_nms*/) { return add_triangle_strip(a_floatn,a_xyzs,false); } protected: gl::mode_t m_mode; }; }} #endif