void Surface_mesh:: flip(Edge e) { // CAUTION : Flipping a halfedge may result in // a non-manifold mesh, hence check for yourself // whether this operation is allowed or not! //let's make it sure it is actually checked assert(is_flip_ok(e)); Halfedge a0 = halfedge(e, 0); Halfedge b0 = halfedge(e, 1); Halfedge a1 = next_halfedge(a0); Halfedge a2 = next_halfedge(a1); Halfedge b1 = next_halfedge(b0); Halfedge b2 = next_halfedge(b1); Vertex va0 = to_vertex(a0); Vertex va1 = to_vertex(a1); Vertex vb0 = to_vertex(b0); Vertex vb1 = to_vertex(b1); Face fa = face(a0); Face fb = face(b0); set_vertex(a0, va1); set_vertex(b0, vb1); set_next_halfedge(a0, a2); set_next_halfedge(a2, b1); set_next_halfedge(b1, a0); set_next_halfedge(b0, b2); set_next_halfedge(b2, a1); set_next_halfedge(a1, b0); set_face(a1, fb); set_face(b1, fa); set_halfedge(fa, a0); set_halfedge(fb, b0); if (halfedge(va0) == b0) set_halfedge(va0, a1); if (halfedge(vb0) == a0) set_halfedge(vb0, b1); }
void Surface_mesh:: split(Face f, Vertex v) { /* Split an arbitrary face into triangles by connecting each vertex of fh to vh. - fh will remain valid (it will become one of the triangles) - the halfedge handles of the new triangles will point to the old halfeges */ Halfedge hend = halfedge(f); Halfedge h = next_halfedge(hend); Halfedge hold = new_edge(to_vertex(hend), v); set_next_halfedge(hend, hold); set_face(hold, f); hold = opposite_halfedge(hold); while (h != hend) { Halfedge hnext = next_halfedge(h); Face fnew = new_face(); set_halfedge(fnew, h); Halfedge hnew = new_edge(to_vertex(h), v); set_next_halfedge(hnew, hold); set_next_halfedge(hold, h); set_next_halfedge(h, hnew); set_face(hnew, fnew); set_face(hold, fnew); set_face(h, fnew); hold = opposite_halfedge(hnew); h = hnext; } set_next_halfedge(hold, hend); set_next_halfedge(next_halfedge(hend), hold); set_face(hold, f); set_halfedge(v, hold); }
void Surface_mesh:: triangulate(Face f) { /* Split an arbitrary face into triangles by connecting each vertex of fh after its second to vh. - fh will remain valid (it will become one of the triangles) - the halfedge handles of the new triangles will point to the old halfedges */ Halfedge base_h = halfedge(f); Vertex start_v = from_vertex(base_h); Halfedge next_h = next_halfedge(base_h); while (to_vertex(next_halfedge(next_h)) != start_v) { Halfedge next_next_h(next_halfedge(next_h)); Face new_f = new_face(); set_halfedge(new_f, base_h); Halfedge new_h = new_edge(to_vertex(next_h), start_v); set_next_halfedge(base_h, next_h); set_next_halfedge(next_h, new_h); set_next_halfedge(new_h, base_h); set_face(base_h, new_f); set_face(next_h, new_f); set_face(new_h, new_f); base_h = opposite_halfedge(new_h); next_h = next_next_h; } set_halfedge(f, base_h); //the last face takes the handle _fh set_next_halfedge(base_h, next_h); set_next_halfedge(next_halfedge(next_h), base_h); set_face(base_h, f); }
CharLook::CharLook(const LookEntry& entry) { reset(); set_body(entry.skin); set_hair(entry.hairid); set_face(entry.faceid); for (auto& equip : entry.equips) { add_equip(equip.second); } }
void Surface_mesh:: remove_loop(Halfedge h) { Halfedge h0 = h; Halfedge h1 = next_halfedge(h0); Halfedge o0 = opposite_halfedge(h0); Halfedge o1 = opposite_halfedge(h1); Vertex v0 = to_vertex(h0); Vertex v1 = to_vertex(h1); Face fh = face(h0); Face fo = face(o0); // is it a loop ? assert ((next_halfedge(h1) == h0) && (h1 != o0)); // halfedge -> halfedge set_next_halfedge(h1, next_halfedge(o0)); set_next_halfedge(prev_halfedge(o0), h1); // halfedge -> face set_face(h1, fo); // vertex -> halfedge set_halfedge(v0, h1); adjust_outgoing_halfedge(v0); set_halfedge(v1, o1); adjust_outgoing_halfedge(v1); // face -> halfedge if (fo.is_valid() && halfedge(fo) == o0) set_halfedge(fo, h1); // delete stuff if (!edeleted_) edeleted_ = edge_property<bool>("e:deleted", false); if (!fdeleted_) fdeleted_ = face_property<bool>("f:deleted", false); if (fh.is_valid()) { fdeleted_[fh] = true; ++deleted_faces_; } edeleted_[edge(h0)] = true; ++deleted_edges_; garbage_ = true; }
void Cubelet::init() { // define geometry // Red //printf("Initiating cubelet with side %d=%d\n", TOP, GREEN); face[RED]->setFace(TOP, RED); // Green face[GREEN]->setFace(LEFT, GREEN); // white face[WHITE]->setFace(FRONT, WHITE); // Blue face[BLUE]->setFace(RIGHT, BLUE); // yellow face[YELLOW]->setFace(REAR, YELLOW); // orange face[ORANGE]->setFace(BASE, ORANGE); // set face colours to grey for(int i = 0; i < 6; i++) { set_face(i, -1); } }
Cylinder :: Cylinder(float r, float h, int vs, int rs) { // set radius radius = r; // set height height = h/2.0; // set stack interval float stack = h / vs; // set slice interval float slice = (2 * M_PI) / rs; // define the number of vertices verts_size = (vs + 1) * (rs) + 2; verts = new GLfloat*[verts_size]; // define the number of faces faces_size = (vs + 1) * rs * 2; faces = new int*[faces_size]; // define arrays for normals v_norms = new GLfloat*[verts_size]; f_norms = new GLfloat*[faces_size]; // define to keep track of faces // for vertex normal calculation int vert_faces[verts_size]; // VERTICES ///////////////////////////////////////////// GLfloat* v; // current position of the stack on the y-axis float curr_stack; // current angle of rotation for slice float curr_slice; // current positions in the array int pos, pos2, pos3; // loop to set "body" vertices for( int i = 0; i < vs + 1; i ++ ) { // calculate stack angle curr_stack = -i * stack; for( int j = 0; j < rs; j++ ) { // calculate slice angle curr_slice = j * slice; // calculate position in the array pos = i * rs + j; // allocate a new vertex v = new GLfloat[4]; // set vertex at north pole v[0] = radius; v[1] = height; v[2] = 0; v[3] = 1; // rotate by stack angle v_translate(v, 0.0, curr_stack, 0.0); // rotate by slice angle v_rotate_y(v, curr_slice); // store in verts array verts[pos] = v; // initialize vertex normal v_norms[pos] = new GLfloat[4]; init_vector(v_norms[pos]); // initalize vertex face count vert_faces[pos] = 0; } } pos = verts_size - 2; // allocate a new vertex v = new GLfloat[4]; // set vertex at north pole v[0] = 0; v[1] = height; v[2] = 0; v[3] = 1; // store in verts array verts[pos] = v; // initialize vertex normal v_norms[pos] = new GLfloat[4]; init_vector(v_norms[pos]); // initalize vertex face count vert_faces[pos] = 0; pos = verts_size - 1; // allocate a new vertex v = new GLfloat[4]; // set vertex at south pole v[0] = 0; v[1] = -height; v[2] = 0; v[3] = 1; // store in verts array verts[pos] = v; // initialize vertex normal v_norms[pos] = new GLfloat[4]; init_vector(v_norms[pos]); // initalize vertex face count vert_faces[pos] = 0; // FACES + NORMALS ///////////////////////////////////////////// // position of face in array int f_pos; // first loop sets the body for( int i = 0; i < vs; i++ ) { for( int j = 0; j < 2*(rs-1); j+= 2 ) { // calculate position in the array pos = i * rs + j/2; pos2 = (i + 1) * rs +j/2; pos3 = pos2 + 1; f_pos = i * 2 * rs + j; set_face(f_pos, pos, pos2, pos3, vert_faces); f_pos++; pos2++; pos3 = pos + 1; set_face(f_pos, pos, pos2, pos3, vert_faces); } // calculate position in the array pos = (i * rs)+ rs - 1; pos2 = (i + 1) * rs + rs - 1; pos3 = (i + 1) * rs; f_pos++; set_face(f_pos, pos, pos2, pos3, vert_faces); f_pos++; pos2 = (i+1) * rs; pos3 = i * rs; set_face(f_pos, pos, pos2, pos3, vert_faces); } // second loop sets the top endcap //////////////////////////////////////// for( int i = 0; i < rs - 1; i++ ) { // set positions in arrays pos = verts_size-2; pos2 = i; pos3 = i + 1; f_pos++; set_face(f_pos, pos, pos2, pos3, vert_faces); } // set positions in arrays pos = verts_size-2; pos2 = pos3; pos3 = 0; f_pos++; set_face(f_pos, pos, pos2, pos3, vert_faces); // third loop sets the bottom endcap //////////////////////////////////////// for( int i = 0; i < rs - 1; i++ ) { // set positions in arrays pos = verts_size-1; pos3 = (vs) * rs + i; pos2 = pos3 + 1; f_pos++; set_face(f_pos, pos, pos2, pos3, vert_faces); } // set positions in arrays pos = verts_size-1; pos2 = pos3; pos3 = (vs) * rs; f_pos++; set_face(f_pos, pos, pos2, pos3, vert_faces); // VERTEX NORMALS ///////////////////////////////////////////// for( int i = 0; i < verts_size; i++ ) { normalize(v_norms[i]); } v_norms[verts_size-2][0] = 0.0; v_norms[verts_size-2][1] = 1.0; v_norms[verts_size-2][2] = 0.0; v_norms[verts_size-2][3] = 1.0; v_norms[verts_size-1][0] = 0.0; v_norms[verts_size-1][1] = -1.0; v_norms[verts_size-1][2] = 0.0; v_norms[verts_size-1][3] = 1.0; }
void Cube::set_front(int *face) { int positions[8] = { 0, 1, 5, 4, // corners 0, 5, 8, 4 }; // edges set_face(face, positions); }
void Surface_mesh:: split(Edge e, Vertex v) { Halfedge h0 = halfedge(e, 0); Halfedge o0 = halfedge(e, 1); Vertex v2 = to_vertex(o0); Halfedge e1 = new_edge(v, v2); Halfedge t1 = opposite_halfedge(e1); Face f0 = face(h0); Face f3 = face(o0); set_halfedge(v, h0); set_vertex(o0, v); if (!is_boundary(h0)) { Halfedge h1 = next_halfedge(h0); Halfedge h2 = next_halfedge(h1); Vertex v1 = to_vertex(h1); Halfedge e0 = new_edge(v, v1); Halfedge t0 = opposite_halfedge(e0); Face f1 = new_face(); set_halfedge(f0, h0); set_halfedge(f1, h2); set_face(h1, f0); set_face(t0, f0); set_face(h0, f0); set_face(h2, f1); set_face(t1, f1); set_face(e0, f1); set_next_halfedge(h0, h1); set_next_halfedge(h1, t0); set_next_halfedge(t0, h0); set_next_halfedge(e0, h2); set_next_halfedge(h2, t1); set_next_halfedge(t1, e0); } else { set_next_halfedge(prev_halfedge(h0), t1); set_next_halfedge(t1, h0); // halfedge handle of _vh already is h0 } if (!is_boundary(o0)) { Halfedge o1 = next_halfedge(o0); Halfedge o2 = next_halfedge(o1); Vertex v3 = to_vertex(o1); Halfedge e2 = new_edge(v, v3); Halfedge t2 = opposite_halfedge(e2); Face f2 = new_face(); set_halfedge(f2, o1); set_halfedge(f3, o0); set_face(o1, f2); set_face(t2, f2); set_face(e1, f2); set_face(o2, f3); set_face(o0, f3); set_face(e2, f3); set_next_halfedge(e1, o1); set_next_halfedge(o1, t2); set_next_halfedge(t2, e1); set_next_halfedge(o0, e2); set_next_halfedge(e2, o2); set_next_halfedge(o2, o0); } else { set_next_halfedge(e1, next_halfedge(o0)); set_next_halfedge(o0, e1); set_halfedge(v, e1); } if (halfedge(v2) == h0) set_halfedge(v2, t1); }
Surface_mesh::Face Surface_mesh:: add_face(const std::vector<Vertex>& vertices) { Vertex v; unsigned int i, ii, n((int)vertices.size()), id; std::vector<Halfedge> halfedges(n); std::vector<bool> is_new(n), needs_adjust(n, false); Halfedge inner_next, inner_prev, outer_next, outer_prev, boundary_next, boundary_prev, patch_start, patch_end; // cache for set_next_halfedge and vertex' set_halfedge typedef std::pair<Halfedge, Halfedge> NextCacheEntry; typedef std::vector<NextCacheEntry> NextCache; NextCache next_cache; next_cache.reserve(3*n); // don't allow degenerated faces assert (n > 2); // test for topological errors for (i=0, ii=1; i<n; ++i, ++ii, ii%=n) { if ( !is_boundary(vertices[i]) ) { std::cerr << "Surface_meshT::add_face: complex vertex\n"; return Face(); } halfedges[i] = find_halfedge(vertices[i], vertices[ii]); is_new[i] = !halfedges[i].is_valid(); if (!is_new[i] && !is_boundary(halfedges[i])) { std::cerr << "Surface_meshT::add_face: complex edge\n"; return Face(); } } // re-link patches if necessary for (i=0, ii=1; i<n; ++i, ++ii, ii%=n) { if (!is_new[i] && !is_new[ii]) { inner_prev = halfedges[i]; inner_next = halfedges[ii]; if (next_halfedge(inner_prev) != inner_next) { // here comes the ugly part... we have to relink a whole patch // search a free gap // free gap will be between boundary_prev and boundary_next outer_prev = opposite_halfedge(inner_next); outer_next = opposite_halfedge(inner_prev); boundary_prev = outer_prev; do boundary_prev = opposite_halfedge(next_halfedge(boundary_prev)); while (!is_boundary(boundary_prev) || boundary_prev==inner_prev); boundary_next = next_halfedge(boundary_prev); assert(is_boundary(boundary_prev)); assert(is_boundary(boundary_next)); // ok ? if (boundary_next == inner_next) { std::cerr << "Surface_meshT::add_face: patch re-linking failed\n"; return Face(); } // other halfedges' handles patch_start = next_halfedge(inner_prev); patch_end = prev_halfedge(inner_next); // relink next_cache.push_back(NextCacheEntry(boundary_prev, patch_start)); next_cache.push_back(NextCacheEntry(patch_end, boundary_next)); next_cache.push_back(NextCacheEntry(inner_prev, inner_next)); } } } // create missing edges for (i=0, ii=1; i<n; ++i, ++ii, ii%=n) if (is_new[i]) halfedges[i] = new_edge(vertices[i], vertices[ii]); // create the face Face f(new_face()); set_halfedge(f, halfedges[n-1]); // setup halfedges for (i=0, ii=1; i<n; ++i, ++ii, ii%=n) { v = vertices[ii]; inner_prev = halfedges[i]; inner_next = halfedges[ii]; id = 0; if (is_new[i]) id |= 1; if (is_new[ii]) id |= 2; if (id) { outer_prev = opposite_halfedge(inner_next); outer_next = opposite_halfedge(inner_prev); // set outer links switch (id) { case 1: // prev is new, next is old boundary_prev = prev_halfedge(inner_next); next_cache.push_back(NextCacheEntry(boundary_prev, outer_next)); set_halfedge(v, outer_next); break; case 2: // next is new, prev is old boundary_next = next_halfedge(inner_prev); next_cache.push_back(NextCacheEntry(outer_prev, boundary_next)); set_halfedge(v, boundary_next); break; case 3: // both are new if (!halfedge(v).is_valid()) { set_halfedge(v, outer_next); next_cache.push_back(NextCacheEntry(outer_prev, outer_next)); } else { boundary_next = halfedge(v); boundary_prev = prev_halfedge(boundary_next); next_cache.push_back(NextCacheEntry(boundary_prev, outer_next)); next_cache.push_back(NextCacheEntry(outer_prev, boundary_next)); } break; } // set inner link next_cache.push_back(NextCacheEntry(inner_prev, inner_next)); } else needs_adjust[ii] = (halfedge(v) == inner_next); // set face handle set_face(halfedges[i], f); } // process next halfedge cache NextCache::const_iterator ncIt(next_cache.begin()), ncEnd(next_cache.end()); for (; ncIt != ncEnd; ++ncIt) set_next_halfedge(ncIt->first, ncIt->second); // adjust vertices' halfedge handle for (i=0; i<n; ++i) if (needs_adjust[i]) adjust_outgoing_halfedge(vertices[i]); return f; }
void Cube::set_back(int *face) { int positions[8] = { 2, 3, 7, 6, // corners 2, 7, 10, 6 }; // edges set_face(face, positions); }
void Cube::set_right(int *face) { int positions[8] = { 1, 2, 6, 5, // corners 1, 6, 9, 5 }; // edges set_face(face, positions); }
void Surface_mesh:: garbage_collection() { if (!garbage_) return; int i, i0, i1, nV(vertices_size()), nE(edges_size()), nH(halfedges_size()), nF(faces_size()); Vertex v; Halfedge h; Face f; if (!vdeleted_) vdeleted_ = vertex_property<bool>("v:deleted", false); if (!edeleted_) edeleted_ = edge_property<bool>("e:deleted", false); if (!fdeleted_) fdeleted_ = face_property<bool>("f:deleted", false); // setup handle mapping Vertex_property<Vertex> vmap = add_vertex_property<Vertex>("v:garbage-collection"); Halfedge_property<Halfedge> hmap = add_halfedge_property<Halfedge>("h:garbage-collection"); Face_property<Face> fmap = add_face_property<Face>("f:garbage-collection"); for (i=0; i<nV; ++i) vmap[Vertex(i)] = Vertex(i); for (i=0; i<nH; ++i) hmap[Halfedge(i)] = Halfedge(i); for (i=0; i<nF; ++i) fmap[Face(i)] = Face(i); // remove deleted vertices if (nV > 0) { i0=0; i1=nV-1; while (1) { // find first deleted and last un-deleted while (!vdeleted_[Vertex(i0)] && i0 < i1) ++i0; while ( vdeleted_[Vertex(i1)] && i0 < i1) --i1; if (i0 >= i1) break; // swap vprops_.swap(i0, i1); //add for(unsigned int j = 0;j<map_2skel.size();j++) { if(map_2skel[j] == i0) map_2skel[j] = i1; else if(map_2skel[j] == i1) map_2skel[j] = i0; } //end }; // remember new size nV = vdeleted_[Vertex(i0)] ? i0 : i0+1; } // remove deleted edges if (nE > 0) { i0=0; i1=nE-1; while (1) { // find first deleted and last un-deleted while (!edeleted_[Edge(i0)] && i0 < i1) ++i0; while ( edeleted_[Edge(i1)] && i0 < i1) --i1; if (i0 >= i1) break; // swap eprops_.swap(i0, i1); hprops_.swap(2*i0, 2*i1); hprops_.swap(2*i0+1, 2*i1+1); }; // remember new size nE = edeleted_[Edge(i0)] ? i0 : i0+1; nH = 2*nE; } // remove deleted faces if (nF > 0) { i0=0; i1=nF-1; while (1) { // find 1st deleted and last un-deleted while (!fdeleted_[Face(i0)] && i0 < i1) ++i0; while ( fdeleted_[Face(i1)] && i0 < i1) --i1; if (i0 >= i1) break; // swap fprops_.swap(i0, i1); }; // remember new size nF = fdeleted_[Face(i0)] ? i0 : i0+1; } // update vertex connectivity for (i=0; i<nV; ++i) { v = Vertex(i); if (!is_isolated(v)) set_halfedge(v, hmap[halfedge(v)]); } // update halfedge connectivity for (i=0; i<nH; ++i) { h = Halfedge(i); set_vertex(h, vmap[to_vertex(h)]); set_next_halfedge(h, hmap[next_halfedge(h)]); if (!is_boundary(h)) set_face(h, fmap[face(h)]); } // update handles of faces for (i=0; i<nF; ++i) { f = Face(i); set_halfedge(f, hmap[halfedge(f)]); } // remove handle maps remove_vertex_property(vmap); remove_halfedge_property(hmap); remove_face_property(fmap); // finally resize arrays vprops_.resize(nV); vprops_.free_memory(); hprops_.resize(nH); hprops_.free_memory(); eprops_.resize(nE); eprops_.free_memory(); fprops_.resize(nF); fprops_.free_memory(); deleted_vertices_ = deleted_edges_ = deleted_faces_ = 0; garbage_ = false; }
void Cube::set_left(int *face) { int positions[8] = { 3, 0, 4, 7, // corners 3, 4, 11, 7 }; // edges set_face(face, positions); }
void test_validity(Mesh& mesh) { typedef typename boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits<Mesh>::edge_descriptor edge_descriptor; typedef typename boost::graph_traits<Mesh>::face_descriptor face_descriptor; typedef typename boost::property_map<Mesh, CGAL::vertex_point_t>::type VPMap; VPMap vpmap = get(CGAL::vertex_point, mesh); vertex_descriptor vertices[4]; edge_descriptor edges[4]; vertices[0] = add_vertex(mesh); vertices[1] = add_vertex(mesh); vertices[2] = add_vertex(mesh); vertices[3] = add_vertex(mesh); put(vpmap, vertices[0], Point_3(0,0,0)); put(vpmap, vertices[1], Point_3(1,0,0)); put(vpmap, vertices[2], Point_3(1,1,0)); put(vpmap, vertices[3], Point_3(0,1,0)); edges[0] = add_edge(mesh); edges[1] = add_edge(mesh); edges[2] = add_edge(mesh); edges[3] = add_edge(mesh); assert(!CGAL::is_valid_halfedge_graph(mesh)); for(int i=0; i<4; ++i) { set_target(halfedge(edges[i], mesh), vertices[i], mesh); set_halfedge(vertices[i], halfedge(edges[i], mesh), mesh); } for(int i=0; i<4; ++i) set_target(opposite(halfedge(edges[i], mesh), mesh), vertices[(i+1)%4], mesh); for(int i=0; i<4; ++i) { set_next(halfedge(edges[(i+1)%4], mesh), halfedge(edges[i], mesh), mesh); set_next(opposite(halfedge(edges[i], mesh), mesh), opposite(halfedge(edges[(i+1)%4], mesh), mesh), mesh); } assert(CGAL::is_valid_halfedge_graph(mesh)); face_descriptor faces[1]; faces[0] = add_face(mesh); assert(!CGAL::is_valid_face_graph(mesh)); for(int i=0; i<4; ++i) { set_face(opposite(halfedge(edges[i], mesh), mesh), faces[0], mesh); } set_halfedge(faces[0], opposite(halfedge(edges[0], mesh), mesh), mesh); assert(CGAL::is_valid_face_graph(mesh)); assert(CGAL::is_valid_polygon_mesh(mesh)); Mesh dummy; vertices[0] = add_vertex(dummy); vertices[1] = add_vertex(dummy); edges[0] = add_edge(dummy); set_target(halfedge(edges[0], dummy), vertices[0], dummy); set_halfedge(vertices[0], halfedge(edges[0], dummy), dummy); set_target(opposite(halfedge(edges[0], dummy), dummy), vertices[1], dummy); set_halfedge(vertices[1], opposite(halfedge(edges[0], dummy), dummy), dummy); set_next(halfedge(edges[0], dummy), opposite(halfedge(edges[0], dummy), dummy), dummy); set_next(opposite(halfedge(edges[0], dummy), dummy), halfedge(edges[0], dummy), dummy); faces[0] = add_face(dummy); set_halfedge(faces[0], opposite(halfedge(edges[0], dummy), dummy), dummy); set_face(halfedge(edges[0], dummy), faces[0], dummy); set_face(opposite(halfedge(edges[0], dummy), dummy), faces[0], dummy); assert(CGAL::is_valid_face_graph(dummy)); assert(!CGAL::is_valid_polygon_mesh(dummy)); }
Torus :: Torus(float r, float r2, int vs, int rs) { // set radii radius = r; radius2 = r2; // set stack interval float stack = (2 * M_PI) / vs; // set slice interval float slice = (2 * M_PI) / rs; // define the number of vertices verts_size = vs * rs; verts = new GLfloat*[verts_size]; // define the number of faces faces_size = verts_size * 2; faces = new int*[faces_size]; // define arrays for normals v_norms = new GLfloat*[verts_size]; f_norms = new GLfloat*[faces_size]; // define to keep track of faces // for vertex normal calculation int vert_faces[verts_size]; // VERTICES ///////////////////////////////////////////// GLfloat* v; // current angle of rotation for stack float curr_stack; // current angle of rotation for slice float curr_slice; // current positions in the array int pos, pos2, pos3; // loop to set vertices for( int i = 0; i < vs; i++ ) { // calculate stack angle curr_stack = -i * stack; for( int j = 0; j < rs; j++ ) { // calculate slice angle curr_slice = j * slice; // calculate position in the array pos = i * rs + j; // allocate new vertex v = new GLfloat[4]; v[0] = 0; v[1] = r2; v[2] = 0; v[3] = 1; // rotate by stack angle v_rotate_z(v, curr_stack); // translate to edge of the ring v_translate(v, r, 0.0, 0.0); // rotate by slice angle v_rotate_y(v, curr_slice); // store in verts array verts[pos] = v; // initialize vertex normal v_norms[pos] = new GLfloat[4]; init_vector(v_norms[pos]); // initalize vertex face count vert_faces[pos] = 0; } } // FACES + NORMALS ///////////////////////////////////////////// // position of face in array int f_pos; // first loop sets the body for( int i = 0; i < vs; i++ ) { for( int j = 0; j < 2*(rs-1); j+= 2 ) { // calculate position in the array pos = i * rs + j/2; if(i == vs-1) { pos2 = j/2; } else { pos2 = (i + 1) * rs +j/2; } pos3 = pos2 + 1; f_pos = i * 2 * rs + j; set_face(f_pos, pos, pos2, pos3, vert_faces); f_pos++; pos2++; pos3 = pos + 1; set_face(f_pos, pos, pos2, pos3, vert_faces); } // calculate position in the array pos = (i * rs)+ rs - 1; if(i == vs-1) { pos2 = rs - 1; pos3 = 0; } else { pos2 = (i + 1) * rs + rs - 1; pos3 = (i + 1) * rs; } f_pos++; set_face(f_pos, pos, pos2, pos3, vert_faces); f_pos++; if(i == vs-1) { pos2 = 0; } else { pos2 = (i+1) * rs; } pos3 = i * rs; set_face(f_pos, pos, pos2, pos3, vert_faces); } // VERTEX NORMALS ///////////////////////////////////////////// // loop through vertices for( int i = 0; i < verts_size; i++ ) { v_norms[i][0] = v_norms[i][0] / vert_faces[i]; v_norms[i][1] = v_norms[i][1] / vert_faces[i]; v_norms[i][2] = v_norms[i][2] / vert_faces[i]; v_norms[i][3] = 1.0; normalize(v_norms[i]); } }
void Cube::set_down(int *face) { int positions[8] = { 7, 4, 5, 6, // corners 8, 9, 10, 11 };// edges set_face(face, positions); }
void Cube::set_top(int *face) { int positions[8] = { 0, 3, 2, 1, // corners 2, 1, 0, 3 }; // edges set_face(face, positions); }