Esempio n. 1
0
float Terrain::getHeightAt(float *map, int res_x, int res_y, float x, float y)
{
	// interpolate height
	int ix,iy;
	ix = (int) x;
	iy = (int) y;
	
	
	float tx = x-ix;
	float ty = y-iy;
	float h3 = (1-ty)*getHeightAt(map, res_x, res_y, ix,iy) + ty*getHeightAt(map, res_x, res_y, ix, iy+1);
	float h4 = (1-ty)*getHeightAt(map, res_x, res_y, ix+1,iy) + ty*getHeightAt(map, res_x, res_y, ix+1, iy+1); 
	return (1-tx)*h3 + (tx)*h4;
}
Esempio n. 2
0
void Terrain::loadHeightMap(string filename, int res_x, int res_y)
{
	PNG inputFile;
	inputFile.load(filename);
	dim_x = inputFile.width;
	dim_y = inputFile.height;
	unsigned char * data = inputFile.getData();

	int size = dim_x*dim_y;
	float * originalHeightMap = new float[size];
	int i,x,y;

	for (i=0; i<size; i++){
		originalHeightMap[i] = 256*data[2*i]+data[2*i + 1];
	}
	// recalculate to the given resolution (use linear interpolation...)
	size = res_x*res_y;
	heightMap = new float[size];
	float step_x = float(dim_x)/float(res_x);
	float step_y = float(dim_y)/float(res_y);
	
	for(x=0; x<res_x; x++)
	{
		for(y=0; y<res_y; y++)
		{
			heightMap[x*res_y + y] = getHeightAt(originalHeightMap, dim_x, dim_y, float(x*step_x), float(y*step_y));
		}
	}
	SAFE_DELETE_ARRAY_PTR(originalHeightMap);

}
Esempio n. 3
0
 /** Addition from SongOfTheWeave */
 Vector3 TerrainInfo::getTangentAt(float x, float z) const
 {
   Ogre::Vector3 v3Return;
   int flip = 1;
   Vector3 here (x, getHeightAt(x, z), z);
   Vector3 left (x - 1, getHeightAt(x - 1, z), z);
   if (left.x < 0.0)
   {
     flip *= -1;
     left = Vector3(x + 1, getHeightAt(x + 1, z), z);
   }
   left -= here;
   v3Return = flip * left;
   v3Return.normalise();
   return v3Return;
 }
Esempio n. 4
0
float Terrain::getHeightAt(float x, float y)
{
	//x+=5.f;
	//y+=5.f;
	// recalc in raster position from space coords
	x *= red_x;
	y *= red_y;
	
	// interpolate height
	int ix,iy;
	ix = (int) x;
	iy = (int) y;
	
	//return getHeightAt(ix,iy);	
	
	float tx = x-ix;
	float ty = y-iy;
	float h3 = (1-ty)*getHeightAt(ix,iy)   + ty*getHeightAt(ix, iy+1);
	float h4 = (1-ty)*getHeightAt(ix+1,iy) + ty*getHeightAt(ix+1, iy+1); 
	return (1-tx)*h3 + (tx)*h4;
}
Esempio n. 5
0
float Heightmap::getInterpolatedHeightAt(float x, float z) {
    if(0.0f <= x && x <= 1.0f && 0.0f <= z && z <= 1.0f) {
        int col1 = floor<int>(x * (float)(columns + 1));
        int col2 = col1 + 1;
        float dx = x * (float)(columns + 1) - (float)col1;
        int row1 = floor<int>(z * (float)(rows + 1));
        int row2 = row1 + 1;
        float dz = z * (float)(rows + 1) - (float)row1;
        float x1 = x - dx;
        float x2 = x1 + 1.0f;
        float z1 = z - dz;
        float z2 = z1 + 1.0f;
        float height = 0.0f;
        if(dx + dz < 1) {
            triangle_intersection(vec3(x1, getHeightAt(col1, row1), z1), vec3(x1, getHeightAt(col1, row2), z2), vec3(x2, getHeightAt(col2, row1), z1), vec3(x, 0, z), vec3(0, 1, 0), &height);
        } else {
            triangle_intersection(vec3(x2, getHeightAt(col2, row1), z1), vec3(x1, getHeightAt(col1, row2), z2), vec3(x2, getHeightAt(col2, row2), z2), vec3(x, 0, z), vec3(0, 1, 0), &height);
        }
        return height;
    }
    return 0.0f;
}
Esempio n. 6
0
  Vector3 TerrainInfo::getNormalAt(float x, float z) const
  {
    int flip = 1;
    Vector3 here (x, getHeightAt(x, z), z);
    Vector3 left (x-1, getHeightAt(x-1, z), z);
    Vector3 down (x, getHeightAt(x, z+1), z+1);
    if (left.x < 0.0)
    {
      flip *= -1;
      left = Vector3(x+1, getHeightAt(x+1, z), z);
    }
    if (down.z >= mOffset.z + mScale.z*(mHeight-1))
    {
      flip *= -1;
      down = Vector3(x, getHeightAt(x, z-1), z-1);
    }
    left -= here;
    down -= here;

    Vector3 norm = flip * left.crossProduct(down);
    norm.normalise();

    return norm;
  }
Esempio n. 7
0
  std::pair<bool, Vector3> TerrainInfo::rayIntersects(const Ray& ray) const
  {
    AxisAlignedBox box = getExtents();
    Vector3 point = ray.getOrigin();
    Vector3 dir = ray.getDirection();

    // first, does the ray start from inside the terrain extents?
    if (!box.contains(point))
    {
      // not inside the box, so let's see if we are actually
      // colliding with it
      pair<bool, Real> res = ray.intersects(box);
      if (!res.first)
        return make_pair(false, Vector3::ZERO);
      // update point to the collision position
      point = ray.getPoint(res.second);
    }

    // now move along the ray until we intersect or leave the bounding box
    while (true)
    {
      // have we arived at or under the terrain height?
      // note that this approach means that ray queries from below won't work
      // correctly, but then again, that shouldn't be a usual case...
      float height = getHeightAt(point.x, point.z);
      if (point.y <= height)
      {
        point.y = height;
        return make_pair(true, point);
      }

      // move further...
      point += dir;

      // check if we are still inside the boundaries
      if (point.x < box.getMinimum().x || point.z < box.getMinimum().z
        || point.x > box.getMaximum().x || point.z > box.getMaximum().z)
        return make_pair(false, Vector3::ZERO);

    }
  }
Esempio n. 8
0
void Terrain::init()
{
	// material
	material = new Material(v4(0.2), v4(0.7), v4(0.0), 0.5);

	// load & create shaders
	int shaderID = shaderManager->loadShader("Terrain", TERRAIN_VS_FILENAME, TERRAIN_FS_FILENAME);
	shader = shaderManager->getShader(shaderID);
	border_values_location = shader->getLocation("border_values");
	border_widths_location = shader->getLocation("border_widths");
	heightInterval_location = shader->getLocation("visibleHeightInterval");

	// load heightmap
	int resolution_x = TERRAIN_RESOLUTION_X;
	int resolution_y = TERRAIN_RESOLUTION_Y;
	float size_x = TERRAIN_SIZE_X;
	float size_y = TERRAIN_SIZE_Y;
	float step_x =size_x/float(resolution_x);
	float step_y =size_y/float(resolution_y);
	red_x = 1.f/step_x;
	red_y = 1.f/step_y;

	loadHeightMap(HEIGHTMAP_SOURCE, resolution_x, resolution_y);

	// load textures
	loadTextures(TERRAIN_TEX_NAME, TERRAIN_TEX_COUNT);

	// shadow map
	shader->linkTexture(textureManager->getTexture(textureManager->shadowMapID));
	LCmatrixLoc					= shader->getLocation("LightMVPCameraVInverseMatrix");
	shadowMappingEnabledLoc		= shader->getLocation("shadowMappingEnabled");
	fastModeLoc					= shader->getLocation("fastMode");
	LMV_CVImatrixLoc			= shader->getLocation("LightMViewCameraViewInverseMatrix");
	LPmatrixLoc					= shader->getLocation("LightProjectionMatrix");

	dim_x = resolution_x;
	dim_y = resolution_y;
	drawingMethod = GL_TRIANGLE_STRIP;
	
	// create grid of triangles
	glGenBuffers(1, &eboId);
	glGenBuffers(1, &vboId);
	int ch = 3;

	
	vertices = new GLfloat[dim_x*dim_y*ch];
	normals  = new GLfloat[dim_x*dim_y*ch];
	texCoords  = new GLfloat[dim_x*dim_y*2];
	elements = new GLuint[(dim_x-1)*2*dim_y];

	channels	[INDEX]		= 1;
	channels	[VERTEX]	= 3;
	channels	[NORMAL]	= 3;
	channels	[TEXCOORD0] = 2;

	typeSizes	[INDEX]		= sizeof(GLuint);
	typeSizes	[VERTEX]	= sizeof(GLfloat);
	typeSizes	[NORMAL]	= sizeof(GLfloat);
	typeSizes	[TEXCOORD0] = sizeof(GLfloat);

	glTypes		[INDEX]		= GL_UNSIGNED_INT;
	glTypes		[VERTEX]	= GL_FLOAT;
	glTypes		[NORMAL]	= GL_FLOAT;
	glTypes		[TEXCOORD0] = GL_FLOAT;

	for (int k = 0; k < VBO_ATR_COUNT; k++){
			sizes[k]=0;
	}
	sizes		[INDEX]		= (dim_x-1)*2*dim_y * channels[INDEX]	* typeSizes[INDEX];
	sizes		[VERTEX]	= dim_x * dim_y * channels[VERTEX]	* typeSizes[VERTEX];
	sizes		[NORMAL]	= dim_x * dim_y * channels[NORMAL]	* typeSizes[NORMAL];
	sizes		[TEXCOORD0] = dim_x * dim_y * channels[TEXCOORD0]* typeSizes[TEXCOORD0];

	offsets		[INDEX]		= 0;
	offsets		[VERTEX]	= 0;
	offsets		[NORMAL]	= offsets [VERTEX] + sizes [VERTEX];
	offsets		[TEXCOORD0] = offsets [NORMAL] + sizes [NORMAL];
	
	int x,y,n;
	vboCount = 0;
	float tex_cnt_x = 100.f;
	float tex_cnt_y = 100.f;

	sz_x = size_x;
	sz_y = size_y;
	float sx2 = sz_x/2.f;
	float sy2 = sz_y/2.f;
	int hx, hy;
	for (x=0; x<dim_x; x++){
		for (y=0; y<dim_y; y++){

			vertices[(x*dim_y + y)*ch + 0] = x*step_x - sx2;//x
			vertices[(x*dim_y + y)*ch + 1] = getHeightAt(x,y);//height
			vertices[(x*dim_y + y)*ch + 2] = y*step_y - sy2;//y
			
			// normals
			v3 normal;
			
			normal.x = getHeightAt(x-1,y) - getHeightAt(x+1,y);
			normal.y = step_x;
			normal.z = getHeightAt(x,y-1) - getHeightAt(x,y+1);
			normal.normalize();

			if (normal.y<0){
				normal = -normal;
			}
			
			normals[(x*dim_y + y)*ch + 0] = normal.x;
			normals[(x*dim_y + y)*ch + 1] = normal.y;
			normals[(x*dim_y + y)*ch + 2] = normal.z;

			// texCoords
			texCoords[(x*dim_y + y)*2 + 0] = x * tex_cnt_x / dim_x;
			texCoords[(x*dim_y + y)*2 + 1] = y * tex_cnt_y / dim_y;

			vboCount += 3;
		}
	}
	int eli = 0;
	bool reverse = false;
	for (x=0; x<dim_x-1; x++){
		if (!reverse){
			for (y=0; y<dim_y; y++){
				elements[eli] = (x+1)*dim_y + y;
				eli++;
				elements[eli] = (x)*dim_y + y;
				eli++;
			}
		} else {
			for (y=dim_y-1; y>=0; y--){
				elements[eli] = (x)*dim_y + y;
				eli++;
				elements[eli] = (x+1)*dim_y + y;
				eli++;
			}
		}
		reverse = !reverse;
	}
	eboCount = eli;

	// total vbo buffer size
	int vboSize=0;
	for (int b = 0; b < VBO_ATR_COUNT; b++){
		if (b!=INDEX){
			vboSize+=sizes[b];
		}
	}

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eboId);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizes[INDEX], elements, GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, vboId);
		// alloc space
		glBufferData(GL_ARRAY_BUFFER, vboSize, 0, GL_STATIC_DRAW); 
		// fill vertices
		glBufferSubData(GL_ARRAY_BUFFER, offsets[VERTEX], sizes[VERTEX], vertices); 
		// fill normals
		glBufferSubData(GL_ARRAY_BUFFER, offsets[NORMAL], sizes[NORMAL], normals);
		// fill texcoords
		glBufferSubData(GL_ARRAY_BUFFER, offsets[TEXCOORD0], sizes[TEXCOORD0], texCoords);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
}