// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_sg_cube #define tools_sg_cube #include "node" #include "render_gstos" #include "sf" #include "pick_action" #include "bbox_action" namespace tools { namespace sg { class cube : public node, public render_gstos { TOOLS_NODE(cube,tools::sg::cube,node) public: sf width; sf height; sf depth; public: virtual const desc_fields& node_desc_fields() const { TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::cube) static const desc_fields s_v(parent::node_desc_fields(),3, //WARNING : take care of count. TOOLS_ARG_FIELD_DESC(width), TOOLS_ARG_FIELD_DESC(height), TOOLS_ARG_FIELD_DESC(depth) ); return s_v; } private: void add_fields(){ add_field(&width); add_field(&height); add_field(&depth); } protected: //render_gstos virtual void visit(gstos_add& a_visitor,draw_type a_style) { visit(a_visitor,a_style); } public: virtual void render(render_action& a_action) { if(gstos_render(a_action)) return; // immediate rendering : const state& state = a_action.state(); bool draw_edges = false; if(state.m_draw_type==draw_filled) draw_edges = state.m_GL_LIGHTING?false:true; if(draw_edges) { a_action.color4f(0,0,0,1); //if lighten, then rendered grey. a_action.line_width(1); visit(a_action,draw_lines); a_action.set_polygon_offset(true); a_action.color4f(state.m_color); a_action.line_width(state.m_line_width); } visit(a_action,state.m_draw_type); if(draw_edges) a_action.set_polygon_offset(state.m_GL_POLYGON_OFFSET_FILL); } virtual void pick(pick_action& a_action) { const state& state = a_action.state(); if(a_action.stop_at_first()){ visit(a_action,state.m_draw_type); if(a_action.done()) a_action.set_node(this); } else { a_action.set_done(false); a_action.zs().clear(); a_action.ws().clear(); visit(a_action,state.m_draw_type); if(a_action.done()) { a_action.add_pick(*this,a_action.zs(),a_action.ws(),a_action.state()); a_action.set_done(false); } } } virtual void bbox(bbox_action& a_action) { const state& state = a_action.state(); visit(a_action,state.m_draw_type); } public: cube() :parent() ,render_gstos() ,width(1.0f) ,height(1.0f) ,depth(1.0f) { add_fields(); } virtual ~cube(){} public: cube(const cube& a_from) :parent(a_from) ,render_gstos(a_from) ,width(a_from.width) ,height(a_from.height) ,depth(a_from.depth) { add_fields(); } cube& operator=(const cube& a_from){ parent::operator=(a_from); render_gstos::operator=(a_from); width = a_from.width; height = a_from.height; depth = a_from.depth; return *this; } protected: void _faces(float front[],float back[], //[12] float right[],float left[], float top[],float bottom[]){ float wh = width.value()*0.5f; float hh = height.value()*0.5f; float dh = depth.value()*0.5f; front[0] = wh;front[ 1] = -hh;front[ 2] = dh; front[3] = wh;front[ 4] = hh;front[ 5] = dh; front[6] = -wh;front[ 7] = hh;front[ 8] = dh; front[9] = -wh;front[10] = -hh;front[11] = dh; back[0] = wh;back[ 1] = -hh;back[ 2] = -dh; back[3] = -wh;back[ 4] = -hh;back[ 5] = -dh; back[6] = -wh;back[ 7] = hh;back[ 8] = -dh; back[9] = wh;back[10] = hh;back[11] = -dh; right[0] = wh;right[ 1] = -hh;right[ 2] = dh; right[3] = wh;right[ 4] = -hh;right[ 5] = -dh; right[6] = wh;right[ 7] = hh;right[ 8] = -dh; right[9] = wh;right[10] = hh;right[11] = dh; left[0] = -wh;left[ 1] = -hh;left[ 2] = dh; left[3] = -wh;left[ 4] = hh;left[ 5] = dh; left[6] = -wh;left[ 7] = hh;left[ 8] = -dh; left[9] = -wh;left[10] = -hh;left[11] = -dh; top[0] = wh;top[ 1] = hh;top[ 2] = dh; top[3] = wh;top[ 4] = hh;top[ 5] = -dh; top[6] = -wh;top[ 7] = hh;top[ 8] = -dh; top[9] = -wh;top[10] = hh;top[11] = dh; bottom[0] = wh;bottom[ 1] = -hh;bottom[ 2] = dh; bottom[3] = -wh;bottom[ 4] = -hh;bottom[ 5] = dh; bottom[6] = -wh;bottom[ 7] = -hh;bottom[ 8] = -dh; bottom[9] = wh;bottom[10] = -hh;bottom[11] = -dh; } void _tris(float tris[],float nms[]){ //[108] float front[12]; float back[12]; float right[12]; float left[12]; float top[12]; float bottom[12]; _faces(front,back,right,left,top,bottom); ///////////////////// tris[0] = front[0]; tris[1] = front[1]; tris[2] = front[2]; tris[3] = front[3]; tris[4] = front[4]; tris[5] = front[5]; tris[6] = front[6]; tris[7] = front[7]; tris[8] = front[8]; // tris[9] = front[6]; tris[10] = front[7]; tris[11] = front[8]; tris[12] = front[9]; tris[13] = front[10]; tris[14] = front[11]; tris[15] = front[0]; tris[16] = front[1]; tris[17] = front[2]; ///////////////////// tris[18] = back[0]; tris[19] = back[1]; tris[20] = back[2]; tris[21] = back[3]; tris[22] = back[4]; tris[23] = back[5]; tris[24] = back[6]; tris[25] = back[7]; tris[26] = back[8]; // tris[27] = back[6]; tris[28] = back[7]; tris[29] = back[8]; tris[30] = back[9]; tris[31] = back[10]; tris[32] = back[11]; tris[33] = back[0]; tris[34] = back[1]; tris[35] = back[2]; ///////////////////// tris[36] = right[0]; tris[37] = right[1]; tris[38] = right[2]; tris[39] = right[3]; tris[40] = right[4]; tris[41] = right[5]; tris[42] = right[6]; tris[43] = right[7]; tris[44] = right[8]; // tris[45] = right[6]; tris[46] = right[7]; tris[47] = right[8]; tris[48] = right[9]; tris[49] = right[10]; tris[50] = right[11]; tris[51] = right[0]; tris[52] = right[1]; tris[53] = right[2]; ///////////////////// tris[54] = left[0]; tris[55] = left[1]; tris[56] = left[2]; tris[57] = left[3]; tris[58] = left[4]; tris[59] = left[5]; tris[60] = left[6]; tris[61] = left[7]; tris[62] = left[8]; // tris[63] = left[6]; tris[64] = left[7]; tris[65] = left[8]; tris[66] = left[9]; tris[67] = left[10]; tris[68] = left[11]; tris[69] = left[0]; tris[70] = left[1]; tris[71] = left[2]; ///////////////////// tris[72] = top[0]; tris[73] = top[1]; tris[74] = top[2]; tris[75] = top[3]; tris[76] = top[4]; tris[77] = top[5]; tris[78] = top[6]; tris[79] = top[7]; tris[80] = top[8]; // tris[81] = top[6]; tris[82] = top[7]; tris[83] = top[8]; tris[84] = top[9]; tris[85] = top[10]; tris[86] = top[11]; tris[87] = top[0]; tris[88] = top[1]; tris[89] = top[2]; ///////////////////// tris[90] = bottom[0]; tris[91] = bottom[1]; tris[92] = bottom[2]; tris[93] = bottom[3]; tris[94] = bottom[4]; tris[95] = bottom[5]; tris[96] = bottom[6]; tris[97] = bottom[7]; tris[98] = bottom[8]; // tris[99] = bottom[6]; tris[100] = bottom[7]; tris[101] = bottom[8]; tris[102] = bottom[9]; tris[103] = bottom[10]; tris[104] = bottom[11]; tris[105] = bottom[0]; tris[106] = bottom[1]; tris[107] = bottom[2]; ///////////////////// ///////////////////// front nms[0] = 0; nms[1] = 0; nms[2] = 1; nms[3] = 0; nms[4] = 0; nms[5] = 1; nms[6] = 0; nms[7] = 0; nms[8] = 1; // nms[9] = 0; nms[10] = 0; nms[11] = 1; nms[12] = 0; nms[13] = 0; nms[14] = 1; nms[15] = 0; nms[16] = 0; nms[17] = 1; ///////////////////// back nms[18] = 0; nms[19] = 0; nms[20] = -1; nms[21] = 0; nms[22] = 0; nms[23] = -1; nms[24] = 0; nms[25] = 0; nms[26] = -1; // nms[27] = 0; nms[28] = 0; nms[29] = -1; nms[30] = 0; nms[31] = 0; nms[32] = -1; nms[33] = 0; nms[34] = 0; nms[35] = -1; ///////////////////// right nms[36] = 1; nms[37] = 0; nms[38] = 0; nms[39] = 1; nms[40] = 0; nms[41] = 0; nms[42] = 1; nms[43] = 0; nms[44] = 0; // nms[45] = 1; nms[46] = 0; nms[47] = 0; nms[48] = 1; nms[49] = 0; nms[50] = 0; nms[51] = 1; nms[52] = 0; nms[53] = 0; ///////////////////// left nms[54] = -1; nms[55] = 0; nms[56] = 0; nms[57] = -1; nms[58] = 0; nms[59] = 0; nms[60] = -1; nms[61] = 0; nms[62] = 0; // nms[63] = -1; nms[64] = 0; nms[65] = 0; nms[66] = -1; nms[67] = 0; nms[68] = 0; nms[69] = -1; nms[70] = 0; nms[71] = 0; ///////////////////// top nms[72] = 0; nms[73] = 1; nms[74] = 0; nms[75] = 0; nms[76] = 1; nms[77] = 0; nms[78] = 0; nms[79] = 1; nms[80] = 0; // nms[81] = 0; nms[82] = 1; nms[83] = 0; nms[84] = 0; nms[85] = 1; nms[86] = 0; nms[87] = 0; nms[88] = 1; nms[89] = 0; ///////////////////// bottom nms[90] = 0; nms[91] = -1; nms[92] = 0; nms[93] = 0; nms[94] = -1; nms[95] = 0; nms[96] = 0; nms[97] = -1; nms[98] = 0; // nms[99] = 0; nms[100] = -1; nms[101] = 0; nms[102] = 0; nms[103] = -1; nms[104] = 0; nms[105] = 0; nms[106] = -1; nms[107] = 0; ///////////////////// } void _lines(float lines[]) { //[144] float front[12]; float back[12]; float right[12]; float left[12]; float top[12]; float bottom[12]; _faces(front,back,right,left,top,bottom); //4 segs * 2 points * 3 coords * 6 faces. //4*2*3*6 = 24*6 = 144 lines[0] = front[0]; lines[1] = front[1]; lines[2] = front[2]; lines[3] = front[3]; lines[4] = front[4]; lines[5] = front[5]; lines[6] = front[3]; lines[7] = front[4]; lines[8] = front[5]; lines[9] = front[6]; lines[10] = front[7]; lines[11] = front[8]; lines[12] = front[6]; lines[13] = front[7]; lines[14] = front[8]; lines[15] = front[9]; lines[16] = front[10]; lines[17] = front[11]; lines[18] = front[9]; lines[19] = front[10]; lines[20] = front[11]; lines[21] = front[0]; lines[22] = front[1]; lines[23] = front[2]; lines[24] = back[0]; lines[25] = back[1]; lines[26] = back[2]; lines[27] = back[3]; lines[28] = back[4]; lines[29] = back[5]; lines[30] = back[3]; lines[31] = back[4]; lines[32] = back[5]; lines[33] = back[6]; lines[34] = back[7]; lines[35] = back[8]; lines[36] = back[6]; lines[37] = back[7]; lines[38] = back[8]; lines[39] = back[9]; lines[40] = back[10]; lines[41] = back[11]; lines[42] = back[9]; lines[43] = back[10]; lines[44] = back[11]; lines[45] = back[0]; lines[46] = back[1]; lines[47] = back[2]; lines[48] = left[0]; lines[49] = left[1]; lines[50] = left[2]; lines[51] = left[3]; lines[52] = left[4]; lines[53] = left[5]; lines[54] = left[3]; lines[55] = left[4]; lines[56] = left[5]; lines[57] = left[6]; lines[58] = left[7]; lines[59] = left[8]; lines[60] = left[6]; lines[61] = left[7]; lines[62] = left[8]; lines[63] = left[9]; lines[64] = left[10]; lines[65] = left[11]; lines[66] = left[9]; lines[67] = left[10]; lines[68] = left[11]; lines[69] = left[0]; lines[70] = left[1]; lines[71] = left[2]; lines[72] = right[0]; lines[73] = right[1]; lines[74] = right[2]; lines[75] = right[3]; lines[76] = right[4]; lines[77] = right[5]; lines[78] = right[3]; lines[79] = right[4]; lines[80] = right[5]; lines[81] = right[6]; lines[82] = right[7]; lines[83] = right[8]; lines[84] = right[6]; lines[85] = right[7]; lines[86] = right[8]; lines[87] = right[9]; lines[88] = right[10]; lines[89] = right[11]; lines[90] = right[9]; lines[91] = right[10]; lines[92] = right[11]; lines[93] = right[0]; lines[94] = right[1]; lines[95] = right[2]; lines[96] = top[0]; lines[97] = top[1]; lines[98] = top[2]; lines[99] = top[3]; lines[100] = top[4]; lines[101] = top[5]; lines[102] = top[3]; lines[103] = top[4]; lines[104] = top[5]; lines[105] = top[6]; lines[106] = top[7]; lines[107] = top[8]; lines[108] = top[6]; lines[109] = top[7]; lines[110] = top[8]; lines[111] = top[9]; lines[112] = top[10]; lines[113] = top[11]; lines[114] = top[9]; lines[115] = top[10]; lines[116] = top[11]; lines[117] = top[0]; lines[118] = top[1]; lines[119] = top[2]; lines[120] = bottom[0]; lines[121] = bottom[1]; lines[122] = bottom[2]; lines[123] = bottom[3]; lines[124] = bottom[4]; lines[125] = bottom[5]; lines[126] = bottom[3]; lines[127] = bottom[4]; lines[128] = bottom[5]; lines[129] = bottom[6]; lines[130] = bottom[7]; lines[131] = bottom[8]; lines[132] = bottom[6]; lines[133] = bottom[7]; lines[134] = bottom[8]; lines[135] = bottom[9]; lines[136] = bottom[10]; lines[137] = bottom[11]; lines[138] = bottom[9]; lines[139] = bottom[10]; lines[140] = bottom[11]; lines[141] = bottom[0]; lines[142] = bottom[1]; lines[143] = bottom[2]; } void _points(float points[]) { //[24] float wh = width.value()*0.5f; float hh = height.value()*0.5f; float dh = depth.value()*0.5f; points[0] = wh;points[ 1] = -hh;points[ 2] = dh; points[3] = wh;points[ 4] = hh;points[ 5] = dh; points[6] = -wh;points[ 7] = hh;points[ 8] = dh; points[9] = -wh;points[10] = -hh;points[11] = dh; points[12+0] = wh;points[12+ 1] = -hh;points[12+ 2] = -dh; points[12+3] = -wh;points[12+ 4] = -hh;points[12+ 5] = -dh; points[12+6] = -wh;points[12+ 7] = hh;points[12+ 8] = -dh; points[12+9] = wh;points[12+10] = hh;points[12+11] = -dh; } template void visit(T& a_visitor,draw_type a_style){ if(a_style==draw_points) { float points[24]; _points(points); a_visitor.add_points(24,points); } else if(a_style==draw_lines) { float lines[144]; //segments _lines(lines); a_visitor.add_lines(144,lines); } else if(a_style==draw_filled) { float tris[108];float nms[108]; _tris(tris,nms); a_visitor.add_triangles_normal(108,tris,nms); } } }; }} #endif