void loadObj(const std::string &filename, VertexData &vd, IndexedFaceMesh &mesh, const Vector3r &scale) { std::vector<OBJLoader::Vec3f> x; std::vector<OBJLoader::Vec3f> normals; std::vector<OBJLoader::Vec2f> texCoords; std::vector<MeshFaceIndices> faces; OBJLoader::Vec3f s = { (float)scale[0], (float)scale[1], (float)scale[2] }; OBJLoader::loadObj(filename, &x, &faces, &normals, &texCoords, s); mesh.release(); const unsigned int nPoints = (unsigned int)x.size(); const unsigned int nFaces = (unsigned int)faces.size(); const unsigned int nTexCoords = (unsigned int)texCoords.size(); mesh.initMesh(nPoints, nFaces * 2, nFaces); vd.reserve(nPoints); for (unsigned int i = 0; i < nPoints; i++) { vd.addVertex(Vector3r(x[i][0], x[i][1], x[i][2])); } for (unsigned int i = 0; i < nTexCoords; i++) { mesh.addUV(texCoords[i][0], texCoords[i][1]); } for (unsigned int i = 0; i < nFaces; i++) { // Reduce the indices by one int posIndices[3]; int texIndices[3]; for (int j = 0; j < 3; j++) { posIndices[j] = faces[i].posIndices[j] - 1; if (nTexCoords > 0) { texIndices[j] = faces[i].texIndices[j] - 1; mesh.addUVIndex(texIndices[j]); } } mesh.addFace(&posIndices[0]); } mesh.buildNeighbors(); mesh.updateNormals(vd, 0); mesh.updateVertexNormals(vd); LOG_INFO << "Number of triangles: " << nFaces; LOG_INFO << "Number of vertices: " << nPoints; }
// @todo templetize void Box::create(float width, float height, float depth, VertexData& vd) { float x = width * 0.5; float y = height * 0.5; float z = depth * 0.5; // back // ------------------- vd.addVertex(x,-y,-z); vd.addVertex(-x,-y,-z); vd.addVertex(-x,y,-z); vd.addVertex(x,y,-z); // vd.addVertex(-x,-y,-z); // vd.addVertex(-x, y,-z); // vd.addVertex(x,y,-z); // vd.addVertex(x,-y,-z); vd.addTexCoord(0,0); vd.addTexCoord(1,0); vd.addTexCoord(1,1); vd.addTexCoord(0,1); vd.addNormal(0,0,-1); vd.addNormal(0,0,-1); vd.addNormal(0,0,-1); vd.addNormal(0,0,-1); vd.addQuad(0,1,2,3); // left // ------------------- vd.addVertex(-x, -y, -z); vd.addVertex(-x, -y, z); vd.addVertex(-x, y, z); vd.addVertex(-x, y, -z); // vd.addVertex(-x, -y, -z); // vd.addVertex(-x, -y, z); // vd.addVertex(-x, y, z); // vd.addVertex(-x, y, -z); vd.addTexCoord(0,0); vd.addTexCoord(1,0); vd.addTexCoord(1,1); vd.addTexCoord(0,1); vd.addNormal(-1,0,0); vd.addNormal(-1,0,0); vd.addNormal(-1,0,0); vd.addNormal(-1,0,0); vd.addQuad(4,5,6,7); // right // ------------------- vd.addVertex(x, -y, z); vd.addVertex(x, -y, -z); vd.addVertex(x, y, -z); vd.addVertex(x, y, z); // vd.addVertex(x, -y, -z); // vd.addVertex(x, -y, z); // vd.addVertex(x, y, z); // vd.addVertex(x, y, -z); vd.addTexCoord(0,0); vd.addTexCoord(1,0); vd.addTexCoord(1,1); vd.addTexCoord(0,1); vd.addNormal(1,0,0); vd.addNormal(1,0,0); vd.addNormal(1,0,0); vd.addNormal(1,0,0); vd.addQuad(8,9,10,11); // front // ------------------- vd.addVertex(-x, -y, z); vd.addVertex(x, -y, z); vd.addVertex(x, y, z); vd.addVertex(-x, y, z); // vd.addVertex(-x, -y, z); // vd.addVertex(-x, y, z); // vd.addVertex(x, y, z); // vd.addVertex(x, -y, z); vd.addTexCoord(0,0); vd.addTexCoord(1,0); vd.addTexCoord(1,1); vd.addTexCoord(0,1); vd.addNormal(0,0,1); vd.addNormal(0,0,1); vd.addNormal(0,0,1); vd.addNormal(0,0,1); vd.addQuad(12,13,14,15); // bottom // ------------------- vd.addVertex(-x, -y, -z); vd.addVertex(-x, -y, z); vd.addVertex(x, -y, z); vd.addVertex(x, -y, -z); // vd.addVertex(-x, -y, z); // vd.addVertex(x, -y, z); // vd.addVertex(x, -y, -z); // vd.addVertex(-x, -y, -z); vd.addTexCoord(0,0); vd.addTexCoord(1,0); vd.addTexCoord(1,1); vd.addTexCoord(0,1); vd.addNormal(0,-1,0); vd.addNormal(0,-1,0); vd.addNormal(0,-1,0); vd.addNormal(0,-1,0); vd.addQuad(16,17,18,19); // top // ------------------- vd.addVertex(-x, y, z); vd.addVertex(x, y, z); vd.addVertex(x, y, -z); vd.addVertex(-x, y, -z); // vd.addVertex(-x, y, -z); // vd.addVertex(-x, y, z); // vd.addVertex(x, y, z); // vd.addVertex(x, y, -z); vd.addTexCoord(0,0); vd.addTexCoord(1,0); vd.addTexCoord(1,1); vd.addTexCoord(0,1); vd.addNormal(0,1,0); vd.addNormal(0,1,0); vd.addNormal(0,1,0); vd.addNormal(0,1,0); vd.addQuad(20,21,22,23); }
void UVSphere::create(float radius, int numSlices, int numStacks, VertexData& vertex_data) { slices = numSlices; stacks = numStacks; // this code works; though as with all 4 other tested methods I get a wierd // lines when using a texture. See git history for old code. for (int j = 0; j < stacks; j++) { double latitude1 = (PI/stacks) * j - PI/2; double latitude2 = (PI/stacks) * (j+1) -PI/2; double sin1 = sin(latitude1); double cos1 = cos(latitude1); double sin2 = sin(latitude2); double cos2 = cos(latitude2); for (int i = 0; i <= slices; i++) { double longitude = (2*PI/slices) * i; double sin_long = sin(longitude); double cos_long = cos(longitude); double x1 = cos_long * cos1; double y1 = sin_long * cos1; double z1 = sin1; double x2 = cos_long * cos2; double y2 = sin_long * cos2; double z2 = sin2; vertex_data.addVertex(Vec3(x1 * radius, y1*radius, z1 * radius)); vertex_data.addTexCoord(1-1.0/slices * i, 1.0/stacks * j); vertex_data.addNormal(Vec3(x1, y1, z1)); vertex_data.addVertex(Vec3(x2 * radius, y2*radius, z2 * radius)); vertex_data.addTexCoord(1-1.0/slices * i, 1.0/stacks * (j+1)); vertex_data.addNormal(Vec3(x2, y2, z2)); } } int n = vertex_data.getNumVertices(); for(int i = 0; i < n-2; i+=2) { vertex_data.addQuad(i+1, i+3, i+2, i); } /* int nv = stacks; int nu = slices; vector<Vec3> vertices; vector<Vec2> texcoords; vertices.push_back(Vec3(0,0,radius)); vertices.push_back(Vec3(0,0,-radius)); for(int i = 0; i < stacks; ++i) { float t = i / (float) stacks; float sin_v = sin(TWO_PI * t); float cos_v = cos(TWO_PI * t); for(int j = 1; j < slices; ++j) { float s = j / (float) slices; float sin_u = sin(PI * s); float cos_u = cos(PI * s); vertices.push_back(Vec3( cos_v * sin_u * radius ,sin_v * sin_u * radius ,cos_u * radius )); texcoords.push_back(Vec2(s,t)); } } vector<int> indices; for(int k = 0; k < nv; ++k) { indices.push_back(0); indices.push_back(2 + k * (nu - 1)); indices.push_back(2 + ((k + 1) % nv) * (nu - 1)); indices.push_back(1); indices.push_back(((k + 1) % nv) * (nu - 1) + nu); indices.push_back(k * (nu - 1) + nu); for(int l = 0; l < (nu-2); ++l) { indices.push_back(2 + k * (nu - 1) + l); indices.push_back(2 + k * (nu - 1) + l + 1); indices.push_back( 2 + ((k + 1) % nv) * (nu - 1) + l); indices.push_back(2 + k * (nu - 1) + l + 1); indices.push_back(2 + ((k + 1) % nv) * (nu - 1) + l + 1); indices.push_back(2 + ((k + 1) % nv) * (nu - 1) + l); } } for(int i = 0; i < indices.size(); ++i) { vertex_data.addVertex(vertices[indices[i]]); vertex_data.addTexCoord(texcoords[indices[i]]); } printf("Num indices: %d\n", indices.size()); */ /* int num_vertices = (stacks + 1) * (slices + 1); vector<Vec3>vertices; vector<Vec2>texcoords; vertices.assign(num_vertices, Vec3()); texcoords.assign(num_vertices, Vec2()); // calculate vertex + texcoords for(float stack = 0; stack <= stacks; ++stack) { float theta = stack/(stacks) * PI; float sin_theta = sinf(theta); float cos_theta = cosf(theta); for(float slice = 0; slice <= slices; ++slice) { float phi = slice/(slices) * TWO_PI; float sin_phi = sinf(phi); float cos_phi = cosf(phi); float x = sin_theta * cos_phi; float y = sin_theta * sin_phi; float z = cos_theta; float u = (sin_theta * cos_phi * 0.5) + 0.5; float v = (sin_theta * sin_phi * 0.5) + 0.5; int index = (int)(slice + (stack * (slices+1))); vertices[index].set(x * radius,y * radius, z * radius); texcoords[index].set(u,v); } } // Create the quads int dx = 0; int num_index_elements = (stacks) * (slices) * 4; num_index_elements = (stacks) * (slices) * 4; int* index_elements = new int[num_index_elements]; for(int i = 0; i < slices; ++i) { for(int j = 0; j < stacks; ++j) { index_elements[dx++] = getAt(i,j); index_elements[dx++] = getAt(i+1,j); index_elements[dx++] = getAt(i+1,j+1); index_elements[dx++] = getAt(i,j+1); } } for(int i = 0; i < num_index_elements;++i) { Vec3 v = vertices[index_elements[i]]; vertex_data.addVertex(v); vertex_data.addTexCoord(texcoords[index_elements[i]]); } */ }
void IcoSphere::create(int detail, float radius, VertexData& vertex_data) { // how we got these values: // http://www.bobchapman.co.uk/The_Geometry_of_the_Singapore_Ball.pdf float x = 0.525731112119133606; float z = 0.850650808352039932; // default icosahedron vector<Vec3> tmp_verts; tmp_verts.push_back(Vec3( -x, 0, z )); tmp_verts.push_back(Vec3( x, 0, z )); tmp_verts.push_back(Vec3( -x, 0, -z )); tmp_verts.push_back(Vec3( x, 0, -z )); tmp_verts.push_back(Vec3( 0, z, x )); tmp_verts.push_back(Vec3( 0, z, -x )); tmp_verts.push_back(Vec3( 0, -z, x )); tmp_verts.push_back(Vec3( 0, -z, -z )); tmp_verts.push_back(Vec3( z, x, 0 )); tmp_verts.push_back(Vec3( -z, x, 0 )); tmp_verts.push_back(Vec3( z, -x, 0 )); tmp_verts.push_back(Vec3( -z, -x, 0 )); // triangle indices int idxs[] = { 1,4,0, 4,9,0, 4,5,9, 8,5,4, 1,8,4, 1,10,8, 10,3,8, 8,3,5, 3,2,5, 3,7,2, 3,10,7, 10,6,7, 6,11,7, 6,0,11, 6,1,0, 10,1,6, 11,0,9, 2,11,9, 5,2,9, 11,2,7 }; int num = 4 * 5 * 3; for(int i = 0; i < num; ++i) { vertex_data.indices.push_back(idxs[i]); } if(detail > 8) { detail = 8; } else if (detail < 0) { detail = 0; } // iterator over the number of detail level and for(int i = 0; i < detail; ++i) { vector<int> indices2; vector<Vec3> tmp_verts2; for(int j = 0, idx = 0; j < vertex_data.indices.size(); j+=3) { // add triangle indices indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++); indices2.push_back(idx++); // split triangle. Vec3 v1 = tmp_verts[vertex_data.indices[j+0]]; Vec3 v2 = tmp_verts[vertex_data.indices[j+1]]; Vec3 v3 = tmp_verts[vertex_data.indices[j+2]]; v1.normalize(); v2.normalize(); v3.normalize(); Vec3 a = (v1 + v2) * 0.5f; Vec3 b = (v2 + v3) * 0.5f; Vec3 c = (v3 + v1) * 0.5f; a.normalize(); b.normalize(); c.normalize(); tmp_verts2.push_back(v1); tmp_verts2.push_back(a); tmp_verts2.push_back(c); tmp_verts2.push_back(a); tmp_verts2.push_back(v2); tmp_verts2.push_back(b); tmp_verts2.push_back(a); tmp_verts2.push_back(b); tmp_verts2.push_back(c); tmp_verts2.push_back(c); tmp_verts2.push_back(b); tmp_verts2.push_back(v3); } tmp_verts = tmp_verts2; vertex_data.indices = indices2; } vector<Vec3>::iterator it = tmp_verts.begin(); while(it != tmp_verts.end()) { vertex_data.addVertex((*it) * radius); ++it; } // add the triangles size_t len = vertex_data.indices.size(); for(int i = 0; i < len; i += 3) { vertex_data.addTriangle( vertex_data.indices[i] ,vertex_data.indices[i+1] ,vertex_data.indices[i+2] ); } }