// --------------------------------------------------------------------------------------------------- // 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(); }
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)); } } }