// ---------------------------------------------------------------------------------------------------
//
float ofApp::getTerrainHeightAtWorldSpaceCoordinate( float _x, float _y )
{
	if( heightmap.size() == 0 ) 
	{
		return 0.0f;
	}

	_x -= terrainMeshRenderingPosition.x;
	_y -= terrainMeshRenderingPosition.z;
	
	_x = ofMap( _x, dimension.get().x * -0.5, dimension.get().x * 0.5, 0, heightmapRes-1, true );
	_y = ofMap( _y, dimension.get().z * -0.5, dimension.get().z * 0.5, 0, heightmapRes-1, true );
	
	int indexX = _x;
	int indexY = _y;
	
	float fX = _x - indexX;
	float fY = _y - indexY;
	
	float A = getHeightmapValue( indexX, 		indexY 		);
	float B = getHeightmapValue( indexX + 1, 	indexY 		);
	float C = getHeightmapValue( indexX, 		indexY + 1 	);
	float D = getHeightmapValue( indexX + 1, 	indexY + 1	);
	
	return ((A + (B -A) * fX) + ((C + (D - C) * fX) - (A + (B - A) * fX)) * fY) * dimension.get().y;
}
// ---------------------------------------------------------------------------------------------------
//
ofVec3f ofApp::getTerrainNormalAtWorldSpaceCoordinate( float _x, float _y )
{
	_x -= terrainMeshRenderingPosition.x;
	_y -= terrainMeshRenderingPosition.z;
	
	_x = ofMap( _x, dimension.get().x * -0.5, dimension.get().x * 0.5, 0, heightmapRes-1, true );
	_y = ofMap( _y, dimension.get().z * -0.5, dimension.get().z * 0.5, 0, heightmapRes-1, true );
	
	int indexX = _x;
	int indexY = _y;
	
	// Todo: pulling scale out of my ass
	float scale = 0.1f; //dimension.y / ( dimension.x / resolutionX ); //dimension.x; // / dimension.y; //hf.GetXYScale();
	float z0 = getHeightmapValue( indexX, indexY ); //paV[ 0 ].m_Z;
	
	float Az = ( indexX + 1 < heightmapRes	) ? ( getHeightmapValue( indexX + 1, 	indexY ) )		: z0;
	float Bz = ( indexY + 1 < heightmapRes	) ? ( getHeightmapValue( indexX, 		indexY + 1 ) )	: z0;
	float Cz = ( indexX - 1 >= 0			) ? ( getHeightmapValue( indexX - 1, 	indexY ) )		: z0;
	float Dz = ( indexY - 1 >= 0			) ? ( getHeightmapValue( indexX, 		indexY - 1)  )	: z0;
	
	return ofVec3f( Cz - Az, 2.f * scale, Dz - Bz ).getNormalized();
}
Пример #3
0
void demo_7_main_core_0() {

	int threads = TOTAL_PROC_NUM;

	// Initialize obstacle map from heightmap
	if (1) {
		logStart("initialize obstacle map");

		// Recode heightmap to global_obstacles
		int a, b, c;

		for (a = 0; a < WORLD_SIZE_X; a++) {
			for (b = 0; b < WORLD_SIZE_Y; b++) {
				int height = getHeightmapValue(a, b);

				// some regions cannot be flown over
				if (height > 174)
					height = 255;

				for (c = 0; c < height; c++) {
					global_obstacles[a][b][c] = 1;
				}
				for (c = height; c < WORLD_SIZE_Z; c++) {
					global_obstacles[a][b][c] = 0;
				}
			}
		}

		logEnd("initialize obstacle map");
	}

	// Set goal
	setGoal(WORLD_SIZE_X - 3, WORLD_SIZE_Y - 3, getHeightmapValue(WORLD_SIZE_X - 3, WORLD_SIZE_Y - 3) + 2);

	// Set current position
	setPosition(3, 3, getHeightmapValue(3, 3) + 2);

	// Init weightmap from obstacle map
	if (1) {
		int a, b, c;

		logStart("initialize weightmap from obstacle map");

		for (a = 0; a < WORLD_SIZE_X; a++) {
			for (b = 0; b < WORLD_SIZE_Y; b++) {
				for (c = 0; c < WORLD_SIZE_Z; c++) {
					if (isGoal(a, b, c)) {
						world[a][b][c] = WEIGHT_SINK;
					} else if (isObstacle(a, b, c)) {
						world[a][b][c] = WEIGHT_OBSTACLE;
					} else {
						world[a][b][c] = WEIGHT_INIT;
					}
				}
			}
		}

		logEnd("initialize weightmap from obstacle map");
	}

	// Propagate weights with selected algorithm
	promote_world(ITERATIONS, threads);

	// Find waypoints to goal
	findWaypoints();

	printf("Iterations: %i\n", ITERATIONS);

	return;
}
//--------------------------------------------------------------
void ofApp::generateTerrainMesh()
{
	if( heightmap.size() != heightmapRes*heightmapRes )
	{
		heightmap.resize(heightmapRes*heightmapRes);
		for( int i = 0; i < heightmap.size(); i++ ) heightmap[i] = 0;
	}
	
	float currTime = ofGetElapsedTimef();
	
	int res = heightmapRes;
	ofVec3f step = dimension.get() / (float)(res-1);
	
	//ofVec3f startPos( noisePositionX * step.x, 0 , noisePositionZ * step.z);
	ofVec3f startPos( noisePositionX * step.x, 0 , noisePositionZ * step.z);
	
	
	// Update heightmap
	
	float perlinSpaceDivider = 8000.0f;
	
	int octaves			= 5;
	
	int tmpIndex = 0;
	for( int indexZ = 0; indexZ < res; indexZ++ )
	{
		for( int indexX = 0; indexX < res; indexX++ )
		{
			float frequency		= 0.7f;
			float persistence	= 0.8f;
			float amplitude		= 0.6f;
			
			//ofVec2f perlinLookup( terrainMeshRenderingPosition.x + (indexX * step.x), terrainMeshRenderingPosition.z + (indexZ * step.z) );
			ofVec2f perlinLookup( startPos.x + (indexX * step.x), startPos.z + (indexZ * step.z) );
			perlinLookup /= perlinSpaceDivider;
			
			float tmpHeight = 0.0f;
			for(int k = 0; k < octaves; k++)
			{
				tmpHeight += ofNoise(perlinLookup.x, perlinLookup.y) * amplitude;
				amplitude *= persistence;
				frequency *= 2.0f;
			}
			
			heightmap[tmpIndex] = tmpHeight;
			tmpIndex++;
		}
	}
	
	// Fill mesh with terrain vertices
	
	terrainMesh.clear();
	terrainMesh.setMode( OF_PRIMITIVE_TRIANGLES );
	
	
	//float startX = dimension.x * -0.5f;
	//float startZ = dimension.z * -0.5f;
	
	ofVec3f meshStartPos = terrainMeshRenderingPosition + (dimension.get() * -0.5f);
	//ofVec3f meshStartPos = (dimension.get() * -0.5f);
	
	tmpIndex = 0;
	for( int indexZ = 0; indexZ < res; indexZ++ )
	{
		for( int indexX = 0; indexX < res; indexX++ )
		{
			/*
			 ofVec3f tmpPos( startPos.x + (indexX * step.x),
			 heightmap[tmpIndex] * dimension.get().y,
			 startPos.z + (indexZ * step.z) );
			 */
			ofVec3f tmpPos( meshStartPos.x + (indexX * step.x),
						   heightmap[tmpIndex] * dimension.get().y,
						   meshStartPos.z + (indexZ * step.z) );
			
			terrainMesh.addVertex( tmpPos );
			terrainMesh.addNormal( ofVec3f(0,0,0) );
			tmpIndex++;
		}
	}
	
	// Compute normals
	
	vector<ofVec3f>& normals = terrainMesh.getNormals();
	
	float fracX = 0.0f;
	float fracY = 0.0f;
	
	for( int indexY = 1; indexY < res-1; indexY++ )
	{
		int tmpIndex = indexY * res;
		
		for( int indexX = 1; indexX < res-1; indexX++ )
		{
			float scale = 0.1f;
			float z0 = getHeightmapValue( indexX, indexY ); //paV[ 0 ].m_Z;
			
			float Az = ( indexX + 1 < res	) ? ( getHeightmapValue( indexX + 1, 	indexY ) )		: z0;
			float Bz = ( indexY + 1 < res	) ? ( getHeightmapValue( indexX, 		indexY + 1 ) )	: z0;
			float Cz = ( indexX - 1 >= 0			) ? ( getHeightmapValue( indexX - 1, 	indexY ) )		: z0;
			float Dz = ( indexY - 1 >= 0			) ? ( getHeightmapValue( indexX, 		indexY - 1)  )	: z0;
			
			normals[tmpIndex] = ofVec3f( Cz - Az, 2.f * scale, Dz - Bz ).getNormalized();
			
			tmpIndex++;
		}
	}
	
	// Add indices to draw triangles with our mesh
	
	for( int indexY = 0; indexY < res-1; indexY++ )
	{
		int tmpIndex = indexY * res;
		
		for( int indexX = 0; indexX < res-1; indexX++ )
		{
			terrainMesh.addTriangle( tmpIndex, tmpIndex + 1, tmpIndex + res + 1 );
			terrainMesh.addTriangle( tmpIndex, tmpIndex + res + 1, tmpIndex + res );
			
			tmpIndex++;
		}
	}
	
	// If we want to have a look at the normals
	
	debugDrawNormals = false;
	
	if( debugDrawNormals )
	{
		debugNormalsMesh.clear();
		debugNormalsMesh.setMode( OF_PRIMITIVE_LINES );
		for( unsigned int i = 0; i < terrainMesh.getNumNormals(); i++ )
		{
			ofVec3f tmpPos = terrainMesh.getVertex(i);
			debugNormalsMesh.addVertex( tmpPos );
			debugNormalsMesh.addVertex( tmpPos + (terrainMesh.getNormal(i) * 10.0f));
		}
	}
	
}