void XMLMesh::startElement(const xmlChar *name, const xmlChar **attrs) { switch (state) { case OUTSIDE: if (xmlStrcasecmp(name, (xmlChar *) "mesh") == 0) { readMesh(name, attrs); state = INSIDE_MESH; } break; case INSIDE_MESH: if (xmlStrcasecmp(name, (xmlChar *) "vertices") == 0) { readVertices(name, attrs); state = INSIDE_VERTICES; } else if (xmlStrcasecmp(name, (xmlChar *) "cells") == 0) { readCells(name, attrs); state = INSIDE_CELLS; } break; case INSIDE_VERTICES: if (xmlStrcasecmp(name, (xmlChar *) "vertex") == 0) readVertex(name, attrs); break; case INSIDE_CELLS: if (xmlStrcasecmp(name, (xmlChar *) "interval") == 0) { readInterval(name, attrs); } else if (xmlStrcasecmp(name, (xmlChar *) "triangle") == 0) { readTriangle(name, attrs); } else if (xmlStrcasecmp(name, (xmlChar *) "tetrahedron") == 0) { readTetrahedron(name, attrs); } break; default: break; } };
void MeshObject::getNextElement(const char* buffer) { switch(buffer[0]) { case PARSED_ELEMENT_VERTEX: switch(buffer[1]) { case PARSED_ELEMENT_TEXTURE: readTexCoord(buffer); break; case PARSED_ELEMENT_NORMAL: readNormal(buffer); break; default: readVertex(buffer); } break; case PARSED_ELEMENT_FACE: readFace(buffer); break; //ignore case PARSED_ELEMENT_SMOOTH: case PARSED_ELEMENT_COMMENT: case PARSED_ELEMENT_MATERIAL: default: //printf("%s",buffer); break; } }
void ObjLoader::readVertices(ifstream &in, char strLine[]) { while(!in.eof() && type_==string("v")) { readVertex(in,strLine); in >> type_; } }
void testApp::load() { ofxXmlSettings xml; xml.loadFile("settings.xml"); xml.pushTag("city"); for (int i=0;i<xml.getNumTags("screen"); i++) { screen s; s.index = xml.getAttribute("screen", "index",0, i); xml.pushTag("screen",i); for (int j=0;j<xml.getNumTags("index");j++) { s.indices.push_back(xml.getAttribute("index", "value", 0,j)); } readVertex(xml, s.origin,0); readVertex(xml,s.xVec, 1); readVertex(xml,s.yVec, 2); screens.push_back(s); xml.popTag(); } for (int i=0;i<xml.getNumTags("tent");i++) { tent t; t.first = xml.getAttribute("tent", "first",0,i); t.second = xml.getAttribute("tent", "second",0,i); tents.push_back(t); } for (int i=0;i<xml.getNumTags("rect");i++) { rects.push_back(ofRectangle(xml.getAttribute("rect", "x",0.0f,i),xml.getAttribute("rect", "y",0.0f,i),xml.getAttribute("rect", "w",0.0f,i),xml.getAttribute("rect", "h",0.0f,i))); } xml.popTag(); updateMatices(); }
void ObjLoader::decode(char* buf) { switch (buf[0]) { case '#': break; case 'v': readVertex(buf); break; case 'f': readFace(buf); break; default: break; } }
vector<Objet3D> ObjParser::readFile (const char * filename, vector<Objet3D> pObjets) { FILE* fichier; char ligne[255]; objets = pObjets; cptFaces = 0; cptObjects = 0; vObj = new Objet3D(); //Un objet par fichier vObj->setNom(filename); fichier = fopen(filename, "r"); while(!feof(fichier)) { ligne[0] = '\0'; fscanf(fichier, "%s", ligne); if(strcmp((const char*)ligne, (char*)"v") == 0) readVertex(fichier); if(strcmp((const char*)ligne, (char*)"vn") == 0) readVertexNormal(fichier); if(strcmp((const char*)ligne, (char*)"o") == 0) readObject(fichier); if(strcmp((const char*)ligne, (char*)"f") == 0) readFace(fichier); if(strcmp((const char*)ligne, (char*)"mtllib") == 0) { readMaterialLibrary(fichier); char mtlfilename[50]; sprintf(mtlfilename, ".\\ressources\\%s", nomMtlLib); readMtlFile(mtlfilename); } if(strcmp((const char*)ligne, (char*)"usemtl") == 0) readMaterialUsed(fichier); } //ASCH 02/08/15 - Insère le dernier objet lu en mémoire. insertObject(); cptFaces = 0; fclose(fichier); return objets; }
void readvertices(FILE *fp, Vertex *vertices, int numberOfvertices, Edge *ep, int numberOfEdges) { char buf[MEDIUM_BUFFER]; memset(buf, 0, MEDIUM_BUFFER); nextElement(buf, fp); int i; EdgePointer *EdgePointerStart = (EdgePointer *)(vertices + numberOfvertices); if (strcmp(buf, "vertices")) error(); for (i = 0; i < numberOfvertices; i++) { vertices[i] = readVertex(fp, ep, numberOfEdges, EdgePointerStart); } nextElement(buf, fp); }
static size_t readVertices(lua_State* state, bool *hasVertexColor, int base) { if(!lua_istable(state, base)) { lua_pushstring(state, "Need table of vertices"); lua_error(state); // does not return return 0; // hint the compiler } size_t count = lua_objlen(state, base); ensureBufferSize(count * sizeof(graphics_Vertex)); *hasVertexColor = false; for(size_t i = 0; i < count; ++i) { lua_rawgeti(state, base, i+1); readVertex(state, ((graphics_Vertex*)moduleData.buffer) + i, hasVertexColor); lua_pop(state, 1); } return count; }
int Model::readObj(string filename) { ifstream stream(filename); if (stream.is_open()) { string line, chunk; while (stream >> chunk) { getline(stream, line); if (chunk == "v") readVertex(line); else if (chunk == "vn") readNormal(line); else if (chunk == "vt") readTexture(line); else if (chunk == "f") readFace(line); } // If we have normals or texture coordinates, we need to rearrange everything to avoid multiple indices. // TODO: Do this without blowing up the size of the v/n/t buffers. if (nBuffer.size() > 0 || tBuffer.size() > 0) { vector<glm::vec4> vBuffer2; vector<glm::vec3> nBuffer2; vector<glm::vec2> tBuffer2; for (unsigned int i = 0; i < viBuffer.size(); i++) { vBuffer2.push_back(vBuffer[viBuffer[i]]); if (niBuffer.size() > 0) nBuffer2.push_back(nBuffer[niBuffer[i]]); if (tiBuffer.size() > 0) tBuffer2.push_back(tBuffer[tiBuffer[i]]); } vBuffer = vBuffer2; nBuffer = nBuffer2; tBuffer = tBuffer2; } stream.close(); return 0; }
void fbxLoader2::processMesh(FbxNode* node) { FbxMesh* mesh = node->GetMesh(); this->readAnimationWeigths(mesh); if(mesh!=NULL && mesh->IsTriangleMesh()) { for (int i = 0; i<mesh->GetControlPointsCount(); i++) { readVertex(mesh, i, &vertex[i]); vertexArray[i].position = D3DXVECTOR3(vertex[i]); } int a = mesh->GetPolygonVertexCount(); for (int i = 0; i<mesh->GetPolygonVertexCount(); i++) { readUV(mesh, i, 0, &uv[i]); readNormal(mesh, i, &normal[i]); indices[i].indice = mesh->GetPolygonVertices()[i]; indices[i].normal1 = normal[i]; indices[i].uv1 = uv[i]; indicesMeshCount++; } } //vertexLists.push_back(vertexArray); indiceLists.push_back(indices); FbxAnimStack* pAnimStack = FbxCast<FbxAnimStack>(scene->GetSrcObject(FBX_TYPE(FbxAnimStack))); int numAnimLayers = pAnimStack->GetMemberCount(FBX_TYPE(FbxAnimLayer)); this->setBindPoseCluster(node); for (int i = 0; i < numAnimLayers; i++) { FbxAnimLayer* pAnimLayer = pAnimStack->GetMember(FBX_TYPE(FbxAnimLayer), i); FbxAnimCurve* animCv = this->findSkeletonRootBone(scene->GetRootNode())->GetChild(0)->LclTranslation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_X); if (animCv) { FbxTimeSpan animationLength; int p = animCv->KeyGetCount(); animCv->GetTimeInterval(animationLength); for(int j = 0; j<animationStructure->GetFramesNumber();j++) { FbxTime timeKey = animCv->KeyGet(j).mTime; //FbxTime interval = (duration/p)*j + animationLength.GetStart(); //int intervalVal = (duration.GetSecondCount()/p)*j + animationLength.GetStart().GetSecondCount(); const FbxTime pTime = animCv->KeyGet(j).mTime; FbxAMatrix pGlobalPos = GetGlobalPosition(node, pTime, scene->GetPose(j)); ComputeSkinDeformation(pGlobalPos, mesh, timeKey, scene->GetPose(j), j); } } } for(int i = 0; i<node->GetChildCount(); i++) { processMesh(node->GetChild(i)); } }
void ArticulatedModel::initOBJ(const std::string& filename, const Preprocess& preprocess) { Stopwatch loadTimer; TextInput::Settings set; set.cppBlockComments = false; set.cppLineComments = false; set.otherCommentCharacter = '#'; set.generateNewlineTokens = true; // Notes on OBJ file format. See also: // // - http://www.martinreddy.net/gfx/3d/OBJ.spec // - http://en.wikipedia.org/wiki/Obj // - http://www.royriggs.com/obj.html // // OBJ indexing is 1-based. // Line breaks are significant. // The first token on a line indicates the contents of the line. // // Faces contain separate indices for normals and texcoords. // We load the raw vertices and then form our own optimized // gl indices from them. // // Negative indices are relative to the last coordinate seen. // Raw arrays with independent indexing, as imported from the file Array<Vector3> rawVertex; Array<Vector3> rawNormal; Array<Vector2> rawTexCoord; // part.geometry.vertexArray[i] = rawVertex[cookVertex[i]]; Array<int> cookVertex; Array<int> cookNormal; Array<int> cookTexCoord; // Put everything into a single part // Convert to a Part Part& part = partArray.next(); part.cframe = CoordinateFrame(); part.name = "root"; part.parent = -1; // v,t,n repeated for each vertex Array<int> faceTempIndex; // Count of errors from mismatched texcoord and vertex int texCoordChanged = 0; int normalChanged = 0; Table<std::string, Material::Ref> materialLibrary; Table<std::string, TriListSpec*> groupTable; TriListSpec* currentTriList = NULL; int numTris = 0; const Matrix3 normalXform = preprocess.xform.upper3x3().transpose().inverse(); const std::string& basePath = FilePath::parent(FileSystem::resolve(filename)); { TextInput ti(filename, set); while (ti.hasMore()) { // Consume comments/newlines while (ti.hasMore() && (ti.peek().type() == Token::NEWLINE)) { // Consume the newline ti.read(); } if (! ti.hasMore()) { break; } // Process one line const std::string& cmd = ti.readSymbol(); if (cmd == "mtllib") { // Specify material library const std::string& mtlFilename = ti.readUntilNewlineAsString(); loadMTL(FilePath::concat(basePath, mtlFilename), materialLibrary, preprocess); } else if (cmd == "g") { // New trilist const std::string& name = ti.readUntilNewlineAsString(); if (! groupTable.containsKey(name)) { currentTriList = new TriListSpec(); currentTriList->name = name; groupTable.set(name, currentTriList); } else { currentTriList = groupTable[name]; } } else if (cmd == "usemtl") { if (currentTriList) { currentTriList->materialName = ti.readUntilNewlineAsString(); } } else if (cmd == "v") { rawVertex.append(readVertex(ti, preprocess.xform)); } else if (cmd == "vt") { // Texcoord Vector2& t = rawTexCoord.next(); t.x = ti.readNumber(); t.y = 1.0f - ti.readNumber(); } else if (cmd == "vn") { // Normal rawNormal.append(readNormal(ti, normalXform)); } else if ((cmd == "f") && currentTriList) { // Face // Read each vertex while (ti.hasMore() && (ti.peek().type() != Token::NEWLINE)) { // Read one 3-part index int v = ti.readNumber(); if (v < 0) { v = rawVertex.size() + 1 + v; } int n = 0; int t = 0; if (ti.peek().type() == Token::SYMBOL) { ti.readSymbol("/"); if (ti.peek().type() == Token::NUMBER) { t = ti.readNumber(); if (t < 0) { t = rawTexCoord.size() + 1 + t; } } if (ti.peek().type() == Token::SYMBOL) { ti.readSymbol("/"); if (ti.peek().type() == Token::NUMBER) { n = ti.readNumber(); if (n < 0) { n = rawNormal.size() + 1 + n; } } } } // Switch to zero-based indexing --v; --n; --t; faceTempIndex.append(v, t, n); } alwaysAssertM(faceTempIndex.size() >= 3*3, "Face with fewer than three vertices in model."); numTris += (faceTempIndex.size()/3) - 2; // The faceTempIndex is now a triangle fan. Convert it to a triangle list and use unique vertices for (int i = 2; i < faceTempIndex.size()/3; ++i) { // Always start with vertex 0 cookVertex.append(faceTempIndex[0]); cookTexCoord.append(faceTempIndex[1]); cookNormal.append(faceTempIndex[2]); // The vertex just before the one we're adding int j = (i - 1) * 3; cookVertex.append(faceTempIndex[j]); cookTexCoord.append(faceTempIndex[j+1]); cookNormal.append(faceTempIndex[j+2]); // The vertex we're adding j = i * 3; cookVertex.append(faceTempIndex[j]); cookTexCoord.append(faceTempIndex[j+1]); cookNormal.append(faceTempIndex[j+2]); // Update the index array to contain the three vertices we just added currentTriList->cpuIndex.append(cookVertex.size() - 3, cookVertex.size() - 2, cookVertex.size() - 1); } faceTempIndex.fastClear(); } // Read until the end of the line while (ti.hasMore() && (ti.read().type() != Token::NEWLINE)); } } debugPrintf("Creating TriLists\n"); // Copy geometry const int N = cookVertex.size(); part.geometry.vertexArray.resize(N); for (int i = 0; i < N; ++i) { part.geometry.vertexArray[i] = rawVertex[cookVertex[i]]; } // Optional normals if (rawNormal.size() > 0) { part.geometry.normalArray.resize(N); for (int i = 0; i < N; ++i) { part.geometry.normalArray[i] = rawNormal[cookNormal[i]]; } } // Optional texcoords if (rawTexCoord.size() > 0) { part.texCoordArray.resize(N); for (int i = 0; i < N; ++i) { part.texCoordArray[i] = rawTexCoord[cookTexCoord[i]]; } } // Create trilists for (Table<std::string, TriListSpec*>::Iterator it = groupTable.begin(); it.hasMore(); ++it) { TriListSpec* s = it->value; Material::Ref material; if (materialLibrary.containsKey(s->materialName)) { material = materialLibrary[s->materialName]; } else { material = Material::createDiffuse(Color3::white() * 0.8f); debugPrintf("Warning: unrecognized material: %s\n", s->materialName.c_str()); } Part::TriList::Ref triList = part.newTriList(material); triList->twoSided = false; triList->indexArray = s->cpuIndex; } groupTable.deleteValues(); groupTable.clear(); debugPrintf("Done loading. %d vertices, %d faces, %d frames\n\n", cookVertex.size(), numTris, N); loadTimer.after("Loading"); }