static vector<VertexPN> getMeshVertices(Mesh &mesh) { vector<VertexPN> vertices; for (int i = 0, n = mesh.getNumFaces(); i < n; i++) { Mesh::Face face = mesh.getFace(i); Cvec3 normals[3]; for (int j = 1; j < face.getNumVertices() - 1; j++) { if (g_smoothShadeOn) { normals[0] = face.getVertex(0).getNormal(); normals[1] = face.getVertex(j).getNormal(); normals[2] = face.getVertex(j+1).getNormal(); } else { normals[0] = normals[1] = normals[2] = face.getNormal(); } vertices.push_back(VertexPN(face.getVertex(0).getPosition(), normals[0])); vertices.push_back(VertexPN(face.getVertex(j).getPosition(), normals[1])); vertices.push_back(VertexPN(face.getVertex(j+1).getPosition(), normals[2])); } } return vertices; }
static void simpleShadeCube(Mesh& mesh) { Cvec3 normal = Cvec3(0, 1, 0); for (int i = 0; i < mesh.getNumFaces(); ++i) { const Mesh::Face f = mesh.getFace(i); Cvec3 facenorm = f.getNormal(); for (int j = 0; j < f.getNumVertices(); ++j) { const Mesh::Vertex v = f.getVertex(j); v.setNormal(facenorm); } } }
static void initCubeMesh() { if (!meshLoaded) { cubeMesh.load("./cube.mesh"); meshLoaded = true; } // set normals shadeCube(cubeMesh); // collect vertices from each face and map quads to triangles vector<VertexPN> verts; for (int i = 0; i < cubeMesh.getNumFaces(); ++i) { const Mesh::Face f = cubeMesh.getFace(i); Cvec3 pos; Cvec3 normal; if (g_flat) normal = f.getNormal(); for (int j = 0; j < f.getNumVertices(); ++j) { const Mesh::Vertex v = f.getVertex(j); pos = v.getPosition(); if (!g_flat) normal = v.getNormal(); verts.push_back(VertexPN(pos, normal)); if (j == 2) { verts.push_back(VertexPN(pos, normal)); } } const Mesh::Vertex v = f.getVertex(0); pos = v.getPosition(); if (!g_flat) normal = v.getNormal(); verts.push_back(VertexPN(pos, normal)); } // add vertices to cube geometry int numVertices = verts.size(); if (!g_cubeGeometryPN) { g_cubeGeometryPN.reset(new SimpleGeometryPN()); } g_cubeGeometryPN->upload(&verts[0], numVertices); }
static void initBunnyMeshes() { g_bunnyMesh.load("bunny.mesh"); // TODO: Init the per vertex normal of g_bunnyMesh, using codes from asst7 // ... shadeCube(g_bunnyMesh); // cout << "Finished shading bunny" << endl; // TODO: Initialize g_bunnyGeometry from g_bunnyMesh, similar to vector<VertexPN> verts; for (int i = 0; i < g_bunnyMesh.getNumFaces(); ++i) { const Mesh::Face f = g_bunnyMesh.getFace(i); Cvec3 pos; Cvec3 normal; if (g_flat) normal = f.getNormal(); for (int j = 0; j < f.getNumVertices(); ++j) { const Mesh::Vertex v = f.getVertex(j); pos = v.getPosition(); if (!g_flat) normal = v.getNormal(); verts.push_back(VertexPN(pos, normal)); } } // add vertices to bunny geometry int numVertices = verts.size(); g_bunnyGeometry.reset(new SimpleGeometryPN()); g_bunnyGeometry->upload(&verts[0], numVertices); // Now allocate array of SimpleGeometryPNX to for shells, one per layer g_bunnyShellGeometries.resize(g_numShells); for (int i = 0; i < g_numShells; ++i) { g_bunnyShellGeometries[i].reset(new SimpleGeometryPNX()); } }
static void shadeCube(Mesh& mesh) { Cvec3 normal = Cvec3(0, 0, 0); for (int i = 0; i < mesh.getNumVertices(); ++i) { mesh.getVertex(i).setNormal(normal); } for (int i = 0; i < mesh.getNumFaces(); ++i) { const Mesh::Face f = mesh.getFace(i); Cvec3 facenorm = f.getNormal(); for (int j = 0; j < f.getNumVertices(); ++j) { const Mesh::Vertex v = f.getVertex(j); v.setNormal(facenorm + v.getNormal()); } } for (int i = 0; i < mesh.getNumVertices(); ++i) { const Mesh::Vertex v = mesh.getVertex(i); if (norm2(v.getNormal()) > .001) { v.setNormal(normalize(v.getNormal())); } } }
static void animateCube(int ms) { float t = (float) ms / (float) g_msBetweenKeyFrames; // scale all vertices in cube for (int i = 0; i < cubeMesh.getNumVertices(); ++i) { const Mesh::Vertex v = cubeMesh.getVertex(i); Cvec3 pos = v.getPosition(); double factor = (1 + (float(g_div_level)/10)) * ((-1 * sin((double) (g_horiz_scale * ms) / (1000 * (vertex_speeds[i] + .5))) + 1) / 2 + .5); pos[0] = vertex_signs[i][0] * (factor / sqrt(3)); pos[1] = vertex_signs[i][1] * (factor / sqrt(3)); pos[2] = vertex_signs[i][2] * (factor / sqrt(3)); v.setPosition(pos); } // copy mesh to temporary mesh for rendering Mesh renderMesh = cubeMesh; // subdivision for (int i = 0; i < g_div_level; ++i) { collectFaceVertices(renderMesh); collectEdgeVertices(renderMesh); collectVertexVertices(renderMesh); renderMesh.subdivide(); } // set normals shadeCube(renderMesh); // collect vertices for each face vector<VertexPN> verts; int q = 0; for (int i = 0; i < renderMesh.getNumFaces(); ++i) { const Mesh::Face f = renderMesh.getFace(i); Cvec3 pos; Cvec3 normal; for (int j = 0; j < f.getNumVertices(); ++j) { const Mesh::Vertex v = f.getVertex(j); pos = v.getPosition(); if (!g_flat) normal = v.getNormal(); else normal = f.getNormal(); verts.push_back(VertexPN(pos, normal)); if (j == 2) { verts.push_back(VertexPN(pos, normal)); } } const Mesh::Vertex v = f.getVertex(0); pos = v.getPosition(); if (!g_flat) normal = v.getNormal(); else normal = f.getNormal(); verts.push_back(VertexPN(pos, normal)); } // dump into geometry int numVertices = verts.size(); g_cubeGeometryPN->upload(&verts[0], numVertices); glutPostRedisplay(); glutTimerFunc(1000/g_animateFramesPerSecond, animateCube, ms + 1000/g_animateFramesPerSecond); }