static ParsedData parse(Allocator* alloc, unsigned char* data, unsigned data_size) { ParserState ps = {}; ps.data = data; ps.head = data; ps.end = (unsigned char*)mem_ptr_add(data, data_size); ParsedData pd = {}; pd.vertices = dynamic_array_create<Vector3>(alloc); pd.normals = dynamic_array_create<Vector3>(alloc); pd.uvs = dynamic_array_create<Vector2>(alloc); pd.faces = dynamic_array_create<ParsedFace>(alloc); ps.head = ps.data; while (ps.head < ps.end) { unsigned char c = *ps.head; bool first_on_line = ps.head == ps.data || (ps.head > ps.data && (*(ps.head - 1)) == '\n'); if (!first_on_line) skip_line(&ps); else if (c == 'v' && ps.head + 1 < ps.end && (*(ps.head+1)) == 't') parse_uv(&ps, &pd); else if (c == 'v' && ps.head + 1 < ps.end && (*(ps.head+1)) == 'n') parse_normal(&ps, &pd); else if (c == 'v') parse_vertex(&ps, &pd); else if (c == 'f') parse_face(&ps, &pd); else skip_line(&ps); } return pd; }
static ats_err_t parse_line(const char *line, struct ats_wft *wft) { switch (line[0]) { case 'v': return parse_vertex(line, wft); case 'f': return parse_face(line, wft); default: /* Skip this line. */ return ATS_NO_ERROR; } }
void parse_world(FILE *fp, World *w) { char tokenbuf[STRING_TOKEN_MAX_LENGTH]; while (get_string_token(fp, tokenbuf) != Token_EOF) { if (strcmp(tokenbuf, "texture") == 0) parse_texture(fp, w); else if (strcmp(tokenbuf, "wall") == 0) parse_wall(fp, w); else if (strcmp(tokenbuf, "region") == 0) parse_region(fp, w); else if (strcmp(tokenbuf, "vertex") == 0) parse_vertex(fp, w); else parse_error("unknown structure type"); } }
int wavefront_parse(wavefront_obj_t *obj, char *data) { char *line, *save; assert(obj != NULL && data != NULL); line = strtok_r(data, "\n", &save); do { if (line[1] == ' ') { switch (line[0]) { case 'v': wavefront_add_vertex(obj, parse_vertex(line+2)); break; case 'f': wavefront_add_face(obj, parse_face(line+2)); break; default: break; } } } while((line = strtok_r(NULL, "\n", &save))); #ifdef OPTIMIZE obj->vertices = realloc(obj->vertices, obj->_nvertex * sizeof(vertex_t)); obj->_vsize = obj->_nvertex; obj->faces = realloc(obj->faces, obj->_nface * sizeof(face_t)); obj->_fsize = obj->_nface; #ifdef DEBUG_MEM puts("*** OPTIMIZED ***"); #endif // DEBUG_MEM #endif // OPTIMIZE #ifdef DEBUG_MEM puts("*** Wavefront stats ***"); printf("V: %d (cap %d)\n", obj->_nvertex, obj->_vsize); printf("F: %d (cap %d)\n", obj->_nface, obj->_fsize); #endif // DEBUG_MEM return 0; }
vector<std1::shared_ptr<Mesh> > load_from_file(const string& path) { ifstream file(path.c_str(), ios::in); vector<std1::shared_ptr<Mesh> > meshes; if (!file.is_open()) return meshes; vector<vec3> vertex; vector<vec3> normal; vector<vec2> tex; vector<Vertex> vertices; // Texture cache. map<string, std1::shared_ptr<Texture> > textures; Material current_material; map<string, Material> materials; for (string line; getline(file, line); ) { line = String::strip(line); size_t split_point = line.find_first_of(' '); string type = line.substr(0, split_point); string data = split_point != string::npos ? line.substr(split_point + 1) : string(); if (type == "v") vertex.push_back(parse_line<vec3>(data)); else if (type == "vn") normal.push_back(parse_line<vec3>(data)); else if (type == "vt") tex.push_back(parse_line<vec2>(data)); else if (type == "f") parse_vertex(data, vertices, vertex, normal, tex); else if (type == "texture") // Not standard OBJ, but do it like this for simplicity ... { if (vertices.size()) // Different texture, new mesh. { std1::shared_ptr<Mesh> mesh(new Mesh()); mesh->set_vertices(vertices); vertices.clear(); mesh->set_material(current_material); meshes.push_back(mesh); } if (!textures[data]) { string texture_path = Path::join(Path::basedir(path), data + ".png"); textures[data] = std1::shared_ptr<Texture>(new Texture(texture_path)); } current_material = Material(); current_material.diffuse_map = textures[data]; current_material.ambient_map = textures[data]; } else if (type == "usemtl") { if (vertices.size()) // Different texture, new mesh. { std1::shared_ptr<Mesh> mesh(new Mesh()); mesh->set_vertices(vertices); vertices.clear(); mesh->set_material(current_material); meshes.push_back(mesh); } current_material = materials[data]; } else if (type == "mtllib") materials = parse_mtllib(Path::join(Path::basedir(path), data), textures); } if (vertices.size()) { std1::shared_ptr<Mesh> mesh(new Mesh()); mesh->set_vertices(vertices); vertices.clear(); mesh->set_material(current_material); meshes.push_back(mesh); } return meshes; }
static int parse_clump( BotRwxClump *clump, tokenize_t *tok ) { // get clump name parse_require( tok, "#Layer" ); parse_require( tok, ":" ); tokenize_next( tok ); clump->name = strdup( tok->token ); // defaults clump->color[0] = clump->color[1] = clump->color[2] = 0; clump->opacity = 1; clump->ambient = 1; clump->diffuse = 1; clump->specular = 0; int nvbuf = 20000; BotRwxVertex *vbuf = (BotRwxVertex*)calloc(1, nvbuf*sizeof(BotRwxVertex)); // clump color tokenize_next( tok ); while( 0 != strcmp( tok->token, "#texbegin" ) ) { if( ! strcmp( tok->token, "Color" ) ) { tokenize_next( tok ); parse_double( tok, &clump->color[0] ); parse_double( tok, &clump->color[1] ); parse_double( tok, &clump->color[2] ); } else if( ! strcmp( tok->token, "Surface" ) ) { tokenize_next( tok ); // parse_double( tok, &clump->surface[0] ); // parse_double( tok, &clump->surface[1] ); // parse_double( tok, &clump->surface[2] ); parse_double( tok, &clump->ambient ); parse_double( tok, &clump->diffuse ); parse_double( tok, &clump->specular ); } else if( ! strcmp( tok->token, "Diffuse" ) ) { tokenize_next( tok ); parse_double( tok, &clump->diffuse ); } else if( ! strcmp( tok->token, "Specular" ) ) { tokenize_next( tok ); parse_double( tok, &clump->specular ); } else if( ! strcmp( tok->token, "Opacity" ) ) { tokenize_next( tok ); parse_double( tok, &clump->opacity ); } else { tokenize_next( tok ); } } // expect the clump name parse_require( tok, clump->name ); // start with a single vertex that should never be used. clump->nvertices = 1; // parse the list of vertices while( tokenize_next( tok ) != EOF ) { if( ! strcmp( tok->token, "Vertex" ) ) { parse_vertex( tok, vbuf + clump->nvertices ); if( vbuf[clump->nvertices].id != clump->nvertices ) { parse_error( tok, "expected vertex %d (got %d)!\n", clump->nvertices, vbuf[clump->nvertices].id ); } clump->nvertices++; if( clump->nvertices >= nvbuf ) { nvbuf += 10000; vbuf = (BotRwxVertex*)realloc(vbuf, nvbuf*sizeof(BotRwxVertex)); } } else if( ! strcmp( tok->token, "#texend" ) ) { // expect the clump name parse_require( tok, clump->name ); break; } else { parse_error( tok, "expected Vertex or #texend token!" ); } } clump->vertices = (BotRwxVertex*)malloc(clump->nvertices*sizeof(BotRwxVertex)); memcpy( clump->vertices, vbuf, clump->nvertices*sizeof(BotRwxVertex) ); free( vbuf ); int ntbuf = 20000; BotRwxTriangle *tbuf = (BotRwxTriangle*)calloc(1, ntbuf*sizeof(BotRwxTriangle)); // parse the list of triangles tokenize_next( tok ); while( 1 ) { // while( tokenize_next( tok ) != EOF ) { if( ! strcmp( tok->token, "Triangle" ) ) { parse_triangle( tok, tbuf + clump->ntriangles ); clump->ntriangles++; if( clump->ntriangles >= ntbuf ) { ntbuf += 10000; tbuf = (BotRwxTriangle*)realloc(tbuf, ntbuf*sizeof(BotRwxTriangle)); } } else if( ! strcmp( tok->token, "ClumpEnd" ) ) { break; } } clump->triangles = (BotRwxTriangle*)malloc(clump->ntriangles*sizeof(BotRwxTriangle)); memcpy( clump->triangles, tbuf, clump->ntriangles*sizeof(BotRwxTriangle) ); free( tbuf ); return 0; }