Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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 );
    }
  }
}
Exemplo n.º 4
0
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 );


  }
}