//---------------------------------------------------------- void CMesh::generateMeshInfo(void) { if ((mSceneNode == NULL) || (mEntity == NULL)) { std::cout << "Error in CMesh::generateMeshInfo()" << std::endl; return; } Utilities::getMeshInformation(mEntity->getMesh(), mVertexCount, mVertices, mIndexCount, mIndices, mEntity->getParentNode()->_getDerivedPosition(), mEntity->getParentNode()->_getDerivedOrientation(), mEntity->getParentNode()->_getDerivedScale()); mTriCount = mIndexCount / 3; // Allocate space for mNormals and mTriFlags mNormals = new Vector3[mTriCount]; mTriFlags = new int[mTriCount]; // Initialize mNormals memset(mTriFlags, 0, mTriCount*sizeof(int)); // Calculate face normals calculateFaceNormals(); }
void KHalfEdgeMeshPrivate::calculateVertexNormals() { std::vector<KVector3D> accumulator; calculateFaceNormals(); for (Vertex &v : m_vertices) { v.normal = calculateVertexNormal(&v, accumulator); } }
void Mesh::calculateVertexNormals() { std::vector<glm::vec3> faceNormals; calculateFaceNormals(faceNormals); //std::cout << "calculating vertex normals.. "; //std::cout.flush(); //aF contains indices of adjacend faces per vertex //interpolate normals of adjacend faces per vertex for(uint i = 0; i< vertices.size(); i++){ calculateVertexNormal(faceNormals, i); /* glm::vec3 vertexNormal = glm::vec3(0); for(uint j= 0; j < aF[i].size(); j++){ // find out which vertex of the current face is the vertex we are currently looking at // aF[i] is a list of faces (aka a list of indices of the indices-vector) // so indices[aF[i][j]] is a glm::vec3 that contains one face // and the current vertex is vertex[i] int thisVertexIndex = -1; for(int vIndex=0; vIndex < 3; vIndex++) { glm::vec3 pos1 = vertices[indices[aF[i][j]][vIndex]].Position; glm::vec3 pos2 = vertices[i].Position; if(glm::distance(pos1, pos2) < 0.0001f) { thisVertexIndex = vIndex; break; } } // we got index of our current vertex within the face, now get others int other1 = (thisVertexIndex+1) % 3; int other2 = (thisVertexIndex+2) % 3; // create the vectors the represent the edges from current vertex to the other 2 glm::vec3 edge1 = vertices[indices[aF[i][j]][thisVertexIndex]].Position - vertices[indices[aF[i][j]][other1]].Position; glm::vec3 edge2 = vertices[indices[aF[i][j]][thisVertexIndex]].Position - vertices[indices[aF[i][j]][other2]].Position; // get angle between the edges float incidentAngle = abs(glm::angle(glm::normalize(edge1), glm::normalize(edge2))); if(incidentAngle > 180) incidentAngle = 360 - incidentAngle; // use that angle as weighting vertexNormal += (faceNormals[aF[i][j]] * incidentAngle); } vertices[i].Normal = glm::normalize(vertexNormal);*/ } //std::cout << "done." << std::endl; }
int CObject::loadObject(std::string path){ std::fstream file(path, std::fstream::in | std::fstream::out); if (!file.is_open()){ std::cout << "No se pudo abrir el archivo" << std::endl; return 0; } int i, j, indexMinMax = 0, numF; GLfloat point; std::vector <GLuint> fc,ft; GLuint pt; std::string type; file >> type; j = 0; fc.clear(); while (!file.eof()){ std::string subtype = type.substr(0, 1); std::string line; if (subtype == "#"){ std::getline(file, line); } if (type == "vt"){ std::getline(file, line); } if (type == "vn"){ std::getline(file, line); } //List of Vertex if (type == "v"){ for (i = 0; i < 3; i++){ file >> point; mVertex.push_back(point); switch (i){ case 0: if (xmin == NULL){ xmin = point; } else{ if (point < xmin) xmin = point; } if (xmax == NULL){ xmax = point; } else{ if (point > xmax) xmax = point; } break; case 1: if (ymin == NULL){ ymin = point; } else{ if (point < ymin) ymin = point; } if (ymax == NULL){ ymax = point; } else{ if (point > ymax) ymax = point; } break; case 2: if (zmin == NULL){ zmin = point; } else{ if (point < zmin) zmin = point; } if (zmax == NULL){ zmax = point; } else{ if (point > zmax) zmax = point; } break; } } mColor.push_back(0); mColor.push_back(1); mColor.push_back(0); nVertex++; // //calculateMinMax(indexMinMax); indexMinMax++; // }//List of Faces if (type == "f"){ std::getline(file, line); char * tok = strtok(&line[0u], " "); while (tok != NULL){ std::string num = tok; std::size_t pos = num.find("/"); num = num.substr(0, pos); pt = stoi(num); fc.push_back(pt); tok = strtok(NULL, " "); } nFaces++; for (j = 1; j < fc.size() - 1; j++){ mIndexes.push_back(fc[0] - 1); mIndexes.push_back(fc[j] - 1); mIndexes.push_back(fc[j + 1] - 1); } fc.clear(); } file >> type; } xmid = (xmin + xmax) / 2; ymid = (ymin + ymax) / 2; zmid = (zmin + zmax) / 2; calculateFaceNormals(); calculateVertexNormals(); //Initialize buffer file.close(); std::cout << "Object loaded" << std::endl; return 1; }
IndexedFaceSetNode::IndexedFaceSetNode(VRMLParser& parser) :ccw(true),solid(true),convex(true), colorPerVertex(true), normalPerVertex(true),creaseAngle(0.0f) { /* Check for the opening brace: */ if(!parser.isToken("{")) Misc::throwStdErr("IndexedFaceSetNode::IndexedFaceSetNode: Missing opening brace in node definition"); parser.getNextToken(); /* Process attributes until closing brace: */ while(!parser.isToken("}")) { if(parser.isToken("ccw")) { parser.getNextToken(); ccw=SFBool::parse(parser); } else if(parser.isToken("solid")) { parser.getNextToken(); solid=SFBool::parse(parser); } else if(parser.isToken("convex")) { parser.getNextToken(); convex=SFBool::parse(parser); } else if(parser.isToken("colorPerVertex")) { parser.getNextToken(); colorPerVertex=SFBool::parse(parser); } else if(parser.isToken("normalPerVertex")) { parser.getNextToken(); normalPerVertex=SFBool::parse(parser); } else if(parser.isToken("creaseAngle")) { parser.getNextToken(); creaseAngle=SFFloat::parse(parser); } else if(parser.isToken("texCoord")) { /* Parse the texture coordinate node: */ parser.getNextToken(); texCoord=parser.getNextNode(); } else if(parser.isToken("color")) { /* Parse the color node: */ parser.getNextToken(); color=parser.getNextNode(); } else if(parser.isToken("normal")) { /* Parse the normal node: */ parser.getNextToken(); normal=parser.getNextNode(); } else if(parser.isToken("coord")) { /* Parse the coordinate node: */ parser.getNextToken(); coord=parser.getNextNode(); } else if(parser.isToken("texCoordIndex")) { /* Parse the texture coordinate index array: */ parser.getNextToken(); texCoordIndices=MFInt32::parse(parser); } else if(parser.isToken("colorIndex")) { /* Parse the color index array: */ parser.getNextToken(); colorIndices=MFInt32::parse(parser); } else if(parser.isToken("normalIndex")) { /* Parse the normal vector index array: */ parser.getNextToken(); normalIndices=MFInt32::parse(parser); } else if(parser.isToken("coordIndex")) { /* Parse the coordinate index array: */ parser.getNextToken(); coordIndices=MFInt32::parse(parser); /* Terminate the coordinate index array: */ if(coordIndices.back()>=0) coordIndices.push_back(-1); } else Misc::throwStdErr("IndexedFaceSetNode::IndexedFaceSetNode: unknown attribute \"%s\" in node definition",parser.getToken()); } /* Skip the closing brace: */ parser.getNextToken(); /* Create normal vectors if necessary: */ CoordinateNode* c=dynamic_cast<CoordinateNode*>(coord.getPointer()); NormalNode* n=dynamic_cast<NormalNode*>(normal.getPointer()); if(coord!=0&&n==0) { /* Create a new normal node and clear the normal index array: */ n=new NormalNode; normal=n; normalIndices.clear(); /* Create normal vectors and normal indices: */ if(normalPerVertex) calculateVertexNormals(c,coordIndices,Math::cos(creaseAngle),n,normalIndices); else calculateFaceNormals(c,coordIndices,n); } }
Model::Model(const char* filename) { char lineBuf[1024]; FILE* f = fopen(filename, "r"); // Initialize the extents - hopefully 1e10 is big enough! mExtents.minX = 1e10; mExtents.maxX = -1e10; mExtents.minY = 1e10; mExtents.maxY = -1e10; mExtents.minZ = 1e10; mExtents.maxZ = -1e10; // Read the list of points while(!feof(f)){ // Read the first character, ignoring whitespace char type1, type2; fscanf(f, " %c%c", &type1, &type2); if(type1 == 'v' && type2 == ' '){ // Vertex float x, y, z; fscanf(f, "%f %f %f", &x, &y, &z); // Read the three coordinates mVertices.push_back(point3(x, y, z)); // Save them in the vector if(x < mExtents.minX){ mExtents.minX = x; } if(y < mExtents.minY){ mExtents.minY = y; } if(z < mExtents.minZ){ mExtents.minZ = z; } if(x > mExtents.maxX){ mExtents.maxX = x; } if(y > mExtents.maxY){ mExtents.maxY = y; } if(z > mExtents.maxZ){ mExtents.maxZ = z; } } else if(type1 == 'v' && type2 == 'n'){ // Vertex normal float x, y, z; fscanf(f, "%f %f %f", &x, &y, &z); mVertexNormals.push_back(point3(x, y, z)); } else if(type1 == 'v' && type2 == 't'){ // Texture coordinate float x, y, z; fscanf(f, "%f %f %f", &x, &y, &z); mTextureCoords.push_back(point3(x, y, z)); } else if(type1 == 'f'){ // Face // This could be specified as either "f A B C" or as "f A/Anorm/Atex B/Bnorm/Btex ..." fscanf(f, " %[^\n]", lineBuf); if(strchr(lineBuf, '/')){ unsigned int a, aNorm, aTex, b, bNorm, bTex, c, cNorm, cTex; sscanf(lineBuf, "%d/%d/%d %d/%d/%d %d/%d/%d", &a, &aNorm, &aTex, &b, &bNorm, &bTex, &c, &cNorm, &cTex); mTriangles.push_back(triangle(a-1, b-1, c-1)); } else{ unsigned int a, b, c; sscanf(lineBuf, "%d %d %d", &a, &b, &c); // Read the three indices mTriangles.push_back(triangle(a-1, b-1, c-1)); // Save them in the vector } } else if(type1 == '#'){ // Comment; eat up the whole line fscanf(f, " %[^\n]", lineBuf); } else{ LOGI("Unexpected input character '%c' while reading OBJ file %s\n", type1, filename); fscanf(f, " %[^\n]", lineBuf); // Eat the whole line } } LOGI("Loaded model %s with %ld vertices, %ld faces\n", filename, mVertices.size(), mTriangles.size()); calculateFaceNormals(); if(mVertexNormals.size() == 0){ calculateVertexNormals(); } // Create buffer handles for all of our vertex attribute buffers glGenBuffers(4, mAttributeBuffers); loadVertexBuffers(); mFlatShading = true; mUseTexture = false; // Not ready to use texture until we've loaded one }