Scene *readHeights(char* fn) { int width, height; unsigned char *height_map; height_map = readBMP(fn, width, height); if (!height_map) { fl_alert("Error loading height map\n"); return false; } Scene * ret = new Scene(); //TODO: customize mat Material * mat = new Material(); mat->kd = vec3f(1.0, 1.0, 1.0); //extract the points Trimesh * trimesh = new Trimesh(ret, mat, &ret->transformRoot); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { int pos = y * width + x; unsigned char pixel[3]; memcpy(pixel, height_map + pos * 3, 3); double height = double(pixel[0] + pixel[1] + pixel[2]) / 3 / 128; vec3f point(x, y, height); trimesh->addVertex(point); if (x > 0 && y > 0) { //link the points trimesh->addFace(pos, pos - 1, pos - 1 - width); trimesh->addFace(pos, pos - 1 - width, pos - width); } } } char *error; if (error = trimesh->doubleCheck()) throw ParseError(error); //add a trimesh ret->add(trimesh); //add a pointlight PointLight* point_light = new PointLight(ret, vec3f(width, height, 10), vec3f(1.0, 1.0, 1.0)); ret->add(point_light); //set the camerea //TODO: calculate the correct viewing distance; vec3f map_center((double)width / 2 - 0.5, (double)height / 2 - 0.5, 0.5); double camera_distance = (double)width + 3.0; vec3f camera_pos(0, -camera_distance, 2 * camera_distance); camera_pos += map_center; ret->getCamera()->setEye(camera_pos); ret->getCamera()->setLook((map_center - camera_pos).normalize(), vec3f(0, 0, 1).normalize()); return ret; }
static void processTrimesh( string name, Obj *child, Scene *scene, const mmap& materials, TransformNode *transform ) { Material *mat; if( hasField( child, "material" ) ) mat = getMaterial( getField( child, "material" ), materials ); else mat = new Material(); Trimesh *tmesh = new Trimesh( scene, mat, transform); const mytuple &points = getField( child, "points" )->getTuple(); for( mytuple::const_iterator pi = points.begin(); pi != points.end(); ++pi ) tmesh->addVertex( tupleToVec( *pi ) ); const mytuple &faces = getField( child, "faces" )->getTuple(); for( mytuple::const_iterator fi = faces.begin(); fi != faces.end(); ++fi ) { const mytuple &pointids = (*fi)->getTuple(); // triangulate here and now. assume the poly is // concave and we can triangulate using an arbitrary fan if( pointids.size() < 3 ) throw ParseError( "Faces must have at least 3 vertices." ); mytuple::const_iterator i = pointids.begin(); int a = (int) (*i++)->getScalar(); int b = (int) (*i++)->getScalar(); while( i != pointids.end() ) { int c = (int) (*i++)->getScalar(); if( !tmesh->addFace(a,b,c) ) throw ParseError( "Bad face in trimesh." ); b = c; } } bool generateNormals = false; maybeExtractField( child, "gennormals", generateNormals ); if( generateNormals ) tmesh->generateNormals(); if( hasField( child, "materials" ) ) { const mytuple &mats = getField( child, "materials" )->getTuple(); for( mytuple::const_iterator mi = mats.begin(); mi != mats.end(); ++mi ) tmesh->addMaterial( getMaterial( *mi, materials ) ); } if( hasField( child, "normals" ) ) { const mytuple &norms = getField( child, "normals" )->getTuple(); for( mytuple::const_iterator ni = norms.begin(); ni != norms.end(); ++ni ) tmesh->addNormal( tupleToVec( *ni ) ); } char *error; if( error = tmesh->doubleCheck() ) throw ParseError( error ); scene->add(tmesh); }
void Parser::parseTrimesh(Scene* scene, TransformNode* transform, const Material& mat) { Trimesh* tmesh = new Trimesh( scene, new Material(mat), transform); _tokenizer.Read( TRIMESH ); _tokenizer.Read( LBRACE ); bool generateNormals( true ); list<Vec3d> faces; char* error; for( ;; ) { const Token* t = _tokenizer.Peek(); switch( t->kind() ) { case GENNORMALS: _tokenizer.Read( GENNORMALS ); _tokenizer.Read( SEMICOLON ); generateNormals = true; break; case MATERIAL: tmesh->setMaterial( parseMaterialExpression( scene, mat ) ); break; case NAME: parseIdentExpression(); break; case MATERIALS: _tokenizer.Read( MATERIALS ); _tokenizer.Read( EQUALS ); _tokenizer.Read( LPAREN ); if( RPAREN != _tokenizer.Peek()->kind() ) { tmesh->addMaterial( parseMaterial( scene, tmesh->getMaterial() ) ); for( ;; ) { const Token* nextToken = _tokenizer.Peek(); if( RPAREN == nextToken->kind() ) break; _tokenizer.Read( COMMA ); tmesh->addMaterial( parseMaterial( scene, tmesh->getMaterial() ) ); } } _tokenizer.Read( RPAREN ); _tokenizer.Read( SEMICOLON ); break; case NORMALS: _tokenizer.Read( NORMALS ); _tokenizer.Read( EQUALS ); _tokenizer.Read( LPAREN ); if( RPAREN != _tokenizer.Peek()->kind() ) { tmesh->addNormal( parseVec3d() ); for( ;; ) { const Token* nextToken = _tokenizer.Peek(); if( RPAREN == nextToken->kind() ) break; _tokenizer.Read( COMMA ); tmesh->addNormal( parseVec3d() ); } } _tokenizer.Read( RPAREN ); _tokenizer.Read( SEMICOLON ); break; case FACES: _tokenizer.Read( FACES ); _tokenizer.Read( EQUALS ); _tokenizer.Read( LPAREN ); if( RPAREN != _tokenizer.Peek()->kind() ) { parseFaces( faces ); for( ;; ) { const Token* nextToken = _tokenizer.Peek(); if( RPAREN == nextToken->kind() ) break; _tokenizer.Read( COMMA ); parseFaces( faces ); } } _tokenizer.Read( RPAREN ); _tokenizer.Read( SEMICOLON ); break; case POLYPOINTS: _tokenizer.Read( POLYPOINTS ); _tokenizer.Read( EQUALS ); _tokenizer.Read( LPAREN ); if( RPAREN != _tokenizer.Peek()->kind() ) { tmesh->addVertex( parseVec3d() ); for( ;; ) { const Token* nextToken = _tokenizer.Peek(); if( RPAREN == nextToken->kind() ) break; _tokenizer.Read( COMMA ); tmesh->addVertex( parseVec3d() ); } } _tokenizer.Read( RPAREN ); _tokenizer.Read( SEMICOLON ); break; case RBRACE: { _tokenizer.Read( RBRACE ); // Now add all the faces into the trimesh, since hopefully // the vertices have been parsed out for( list<Vec3d>::const_iterator vitr = faces.begin(); vitr != faces.end(); vitr++ ) { if( !tmesh->addFace( (*vitr)[0], (*vitr)[1], (*vitr)[2] ) ) { ostringstream oss; oss << "Bad face in trimesh: (" << (*vitr)[0] << ", " << (*vitr)[1] << ", " << (*vitr)[2] << ")"; throw ParserException( oss.str() ); } } if( generateNormals ) tmesh->generateNormals(); if( error = tmesh->doubleCheck() ) throw ParserException( error ); scene->add( tmesh ); return; } default: throw SyntaxErrorException( "Expected: trimesh attributes", _tokenizer ); } } }
void Parser::parseObj(string inputfile, Scene* scene, const Material& parent, TransformNode* transform){ // Trimesh* tmesh = new Trimesh( scene, new Material(mat), transform); std::cout << inputfile << std::endl; std::vector<tinyobj::shape_t> shapes; std::vector<tinyobj::material_t> materials; std::string err; bool ret = tinyobj::LoadObj(shapes, materials, err, inputfile.c_str()); if (!err.empty()) { // `err` may contain warning message. std::cerr << err << std::endl; } if (!ret) { exit(1); } //Else successful now add the objects to the scene for(int i = 0; i < shapes.size(); i++){ //Will only support one material per object // Get Materials Trimesh* tmesh; if(!shapes[i].mesh.material_ids.empty()){ auto mtr = materials[shapes[i].mesh.material_ids[0]]; // float ambient[3]; // float diffuse[3]; // float specular[3]; // float transmittance[3]; // float emission[3]; // float shininess; // float ior; Vec3d ke(mtr.emission[0], mtr.emission[1], mtr.emission[2] ); Vec3d ka(mtr.ambient[0], mtr.ambient[1], mtr.ambient[2] ); Vec3d ks(mtr.specular[0], mtr.specular[1], mtr.specular[2] ); Vec3d kd(mtr.diffuse[0], mtr.diffuse[1], mtr.diffuse[2] ); // Vec3d kt(mtr.transmittance[0], mtr.transmittance[1], mtr.transmittance[2]); Vec3d kt(1.0 - mtr.dissolve, 1.0 - mtr.dissolve,1.0 - mtr.dissolve); std::cout << "Tr " << mtr.transmittance[0]<< " " << mtr.transmittance[1] << " " << mtr.transmittance[2] << " :d->: "<< mtr.dissolve << std::endl; Vec3d kr = Vec3d(0.0,0.0,0.0); // if(mtr.dissolve < 1.0) kr = ks; if(mtr.dissolve < 1.0) kr = Vec3d(0.2,0.2,0.2); tmesh = new Trimesh( scene, new Material(ke, ka, ks, kd, kr,kt, mtr.shininess, mtr.ior), transform); }else{ std::cerr << "Note: OBJ file missing material" << std::endl; tmesh = new Trimesh( scene, new Material(parent), transform); } for (size_t v = 0; v < shapes[i].mesh.positions.size() / 3; v++) { //First Add Vertices Vec3d vert(shapes[i].mesh.positions[3*v+0], shapes[i].mesh.positions[3*v+1], shapes[i].mesh.positions[3*v+2]); tmesh->addVertex(vert); } for (size_t f = 0; f < shapes[i].mesh.indices.size() / 3; f++) { //Then Add Faces tmesh->addFace(shapes[i].mesh.indices[3*f+0], shapes[i].mesh.indices[3*f+1], shapes[i].mesh.indices[3*f+2]); } tmesh->generateNormals(); // tmesh->buildKdTree(); scene->addBB( tmesh ); } }