Пример #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;
}
Пример #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);
}
Пример #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 );
    }
  }
}