std::vector<double> DiamondSquare(int n, double scale, int maxelevation) { // Initialize random generators std::mt19937 rng; rng.seed(std::random_device()()); randomdist elevationdist(1, maxelevation); int sidelen = std::pow(2, n) + 1; int area = sidelen * sidelen; std::vector<double> heightmap(area); // First populate the four corners with random values double seed = elevationdist(rng); heightmap[CoordsToIdx(0, 0, sidelen)] = seed; heightmap[CoordsToIdx(sidelen - 1, 0, sidelen)] = seed; heightmap[CoordsToIdx(0, sidelen - 1, sidelen)] = seed; heightmap[CoordsToIdx(sidelen - 1, sidelen - 1, sidelen)] = seed; // First Diamond step(heightmap, sidelen, sidelen, maxelevation, rng); // Smooth MovingAverageSmooth(heightmap, sidelen); MovingAverageSmooth(heightmap, sidelen); //MovingAverageSmooth(heightmap, sidelen); return heightmap; }
void CreateWaterMesh(unsigned int size, Mesh& outM) { //Just create a flat terrain and let it do the math. Terrain terr(Vector2u(size, size)); std::vector<WaterVertex> verts; std::vector<unsigned int> indices; { Array2D<float> heightmap(size, size, 0.0f); terr.SetHeightmap(heightmap); terr.GenerateTrianglesFull<WaterVertex>( verts, indices, [](WaterVertex& v) { return &v.Pos; }, [](WaterVertex& v) { return &v.TexCoord; }); } //Convert the terrain vertices into water vertices. float invSize = 1.0f / (float)size; for (unsigned int i = 0; i < verts.size(); ++i) { verts[i].Pos = Vector3f(verts[i].Pos.x * invSize, verts[i].Pos.y * invSize, verts[i].Pos.z); } //Upload the mesh data into vertex/index buffers. outM.SetVertexData(verts, Mesh::BUF_STATIC, WaterVertex::GetVertexAttributes()); outM.SetIndexData(indices, Mesh::BUF_STATIC); }
int main(int argc, char * argv []) { int layers; if (argc < 2) layers = 10; else layers = atoi(argv[1]); worldgen::HeightMap heightmap(layers, 1<<(layers-1), 10); heightmap.calculate(); octree<int> tree (layers, 0); int x, y, z; std::cout << std::endl; /* tree.setblock(1,0,0,0,layers - 1); tree.setblock(1,0,1<<layers-1,0, layers -1); tree.setblock(1,1<<layers-1,0,0, layers -1); tree.setblock(1,1<<layers-1,1<<layers-1,0, layers -1); */ std::cout << "Flush\n"; for (x = 0; x < 1<<layers; x++) { std::cout << "Progress: " << 100. * (x)/ (1<<layers) << "\n"; for (y = 0; y < 1<<layers; y++) { for (z = 0; z < (1<<layers - 1) + heightmap.landscape.get(worldgen::point {x,y}); z++) { tree.set(1, x, y, z); } /* for (; z < 64; z++) { tree.set(0, x, y, z); } */ } } std::cout << tree.getsize() * sizeof(oc_node<int>) << " VS " << (1<<layers) * (1<<layers) * (1<<layers) * sizeof(int) << std::endl; }
/// <summary> /// Carga los valores del Heightmap en una matriz /// </summary> IntMatrix TgcSimpleTerrain::loadHeightMap(Device d3dDevice, string path) { Texture bitmap = TextureLoader::FromFile(d3dDevice,path.c_str(),0,0,1,Usage_None, Format_X8R8G8B8,Pool_Managed,Filter_None,Filter_None,0); SurfaceDescription desc = bitmap.GetSurfaceDescription(0); int pitch; byte * bdata = (byte*)bitmap.LockRectangle(0,LockFlags_ReadOnly,pitch); int width = desc.Width; int height = desc.Height; IntMatrix heightmap(width, height); for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { //(j, i) invertido para primero barrer filas y despues columnas int offset = j*pitch + i*4; byte r = bdata[offset + 0]; byte g = bdata[offset + 1]; byte b = bdata[offset + 2]; float intensity = r * 0.299f + g * 0.587f + b * 0.114f; heightmap.SetItem(i, j, (int)intensity); } } bitmap.Dispose(); return heightmap; }
void Trees::initTrees(QString _pathToHeightmap){ QImage heightmap(_pathToHeightmap); // load model m_tree = new Model("models/tree.obj"); m_leaves = new Model("models/leaves.obj"); glBindVertexArray(m_tree->getVAO()); // Instance offset buffer GLfloat m_offset[m_numTrees*3]; srand(time(NULL)); // COULD BE SPED UP USING TRANSFORM FEEDBACK !! for (int i=0; i<m_numTrees*3; i+=3){ float x = -(0.0) + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/((1.0)-(0.0)))); float z = -(0.0) + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/((1.0)-(0.0)))); float y = getHeight((int)(x * heightmap.width()), (int)(z * heightmap.height()), heightmap); while (y < 0.09 || y > 0.13){ x = -(0.0) + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/((1.0)-(0.0)))); z = -(0.0) + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/((1.0)-(0.0)))); y = getHeight((int)(x * heightmap.width()), (int)(z * heightmap.height()), heightmap); } m_offset[i] = x; m_offset[i+1] = y; m_offset[i+2] = z; m_positions.push_back(glm::vec2(x, z)); } GLuint positionBuffer; glGenBuffers(1, &positionBuffer); glBindBuffer(GL_ARRAY_BUFFER, positionBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(m_offset), &m_offset[0], GL_STATIC_DRAW); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); glVertexAttribDivisor(3, 1); glBindBuffer(GL_ARRAY_BUFFER,0); glBindVertexArray(0); glBindVertexArray(m_leaves->getVAO()); GLuint leavesPositionBuffer; glGenBuffers(1, &leavesPositionBuffer); glBindBuffer(GL_ARRAY_BUFFER, leavesPositionBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(m_offset), &m_offset[0], GL_STATIC_DRAW); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); glVertexAttribDivisor(3, 1); glBindBuffer(GL_ARRAY_BUFFER,0); glBindVertexArray(0); glDeleteBuffers(1, &positionBuffer); glDeleteBuffers(1, &leavesPositionBuffer); }
int main(int argc, char** argv) { Image* image = ppm_create(1024, 1024); Image* smaller = ppm_create(128, 128); int x, y; for(y = 0; y < image->header.height; y++) { for(x = 0; x < image->header.width; x++) { Point2D pix = point2(x, y); float x_scale = image->header.width / 8.0f; float y_scale = image->header.height / 8.0f; Point2D samp = point2((pix.x + 512) / x_scale, (pix.y + 512) / y_scale); //ColorRGB color = color_field(samp); ColorRGB height = heightmap(samp); //ColorRGB blended = blend(color, height, 0.1f); draw_point(image, pix, height); } } for(y = 0; y < smaller->header.height; y++) { for(x = 0; x < image->header.width; x++) { Point2D pix = point2(x, y); float x_scale = image->header.width / 8.0f; float y_scale = image->header.height / 8.0f; Point2D sample = point2((pix.x) / x_scale, (pix.y) / y_scale); ColorRGB color = heightmap(sample); draw_point(smaller, pix, color); } } Rect2D src_rect, dest_rect; src_rect = (Rect2D) { point2(0, 0), point2(smaller->header.width, smaller->header.height) }; dest_rect = (Rect2D) { point2(128, 128), point2(448, 448) }; blit_alpha(image, dest_rect, smaller, src_rect, 0.1f); ppm_save(image, "overlay.ppm"); ppm_destroy(smaller); ppm_destroy(image); return 0; }
int main(int argc, char **argv) // argv are the command-line arguments { char infname[512], outfname[512]; // file names for input and output IMAGE *data; IMAGE *target; if(argc<5) // too few command-line arguments? { printf("Command-line usage:\n"); printf(" %s (inf) (outf) (x) (y)\n",argv[0]); printf(" (inf) is the input file name\n"); printf(" (outf) is the output file name\n"); printf(" (x), (y) are the image dimensions\n"); //printf(" (x), (y), (z) are the image dimensions\n"); exit(0); } // Allocate local memory for struct pointers data = malloc(sizeof(IMAGE)); // Handle Command Line args strcpy(infname,nextargs); // read input file name strcpy(outfname,nextargs); // read output file name data->xmax = nextargi; // Read image dimensions data->ymax = nextargi; data->zmax = 1; //nextargi; // Read Image, Allocate Img mem printf("Reading image %s with dimensions %d, %d, %d\n",infname,data->xmax,data->ymax,data->zmax); if(read_raw(infname, data)){ printf("Error reading file\n"); exit (1); } // Set target params, Allocate local memory target = malloc(sizeof(IMAGE)); if(copyimage(target, data)){ fprintf(stderr,"Could not Create Image: target\n"); exit(-1); } /* Image Processing calls here */ printf(" Drawing AutoStereogram...\n"); if(heightmap(data)){ printf("Error Making Height Map\n"); exit(3); } if(DrawAutoStereogram(target, data)){ printf("Error Generating SIRDS\n"); exit(3); } // Write Image printf("Writing processed image %s with dimensions %d, %d, %d\n",outfname,target->xmax,target->ymax,target->zmax); if(write_raw(outfname, target)){ printf("Error writing file\n"); exit (4); } // Free All Memory removeimage(data); removeimage(target); printf("Program completed successfully\n"); exit (0); }
void HeightMapEditor::onRenderButtonClicked() { { boost::recursive_mutex::scoped_lock guard(myMutex); for (auto task : myTasks) task->cancellationFlag.store(true); myTasks.clear(); } myUi->renderView->scene()->clear(); Json::Value graphJson = myUi->graphBuilder->toJson(); myGraph.reset(new NoiseGraph); PhysFS::ifstream fs("map/heightmap.png"); std::vector<char> data; data.assign(std::istreambuf_iterator<char>(fs), std::istreambuf_iterator<char>()); QImage heightmapImage; heightmapImage.loadFromData((const uchar *)data.data(), data.size()); boost::multi_array<double, 2> heights; heights.resize(boost::extents[heightmapImage.width()][heightmapImage.height()]); for (int y = 0; y < heightmapImage.height(); y++) for (int x = 0; x < heightmapImage.width(); x++) { QColor col(heightmapImage.pixel(x, y)); int height = col.red() | col.green() | col.blue(); heights[x][y] = (height / 256.0) * 2 - 1; } std::shared_ptr<HeightMapModule> heightmap(new HeightMapModule(heights, 400, 240)); try { myGraph->module = buildNoiseGraph(graphJson, myGraph->modules, myGraph->defs, heightmap, 0); } catch (std::exception & e) { QMessageBox::critical(this, "Error", e.what()); myGraph.reset(); return; } catch (noise::ExceptionInvalidParam & e) { QMessageBox::critical(this, "Error", "Invalid parameter"); myGraph.reset(); return; } catch (noise::ExceptionNoModule & e) { QMessageBox::critical(this, "Error", "Missing module"); myGraph.reset(); return; } catch (noise::ExceptionOutOfMemory & e) { QMessageBox::critical(this, "Error", "Out of memory"); myGraph.reset(); return; } catch (noise::ExceptionUnknown & e) { QMessageBox::critical(this, "Error", "Unknown exception"); myGraph.reset(); return; } generateRect(myUi->renderView->sceneRect()); }
void World::updateNaviMap(bool full_recompute) { FWK_PROFILE("updateNaviMap"); //TODO: what about static entities that are added during the game? if(full_recompute) { vector<IBox> bboxes, blockers; bboxes.reserve(m_tile_map.size() + m_entity_map.size()); for(int n = 0; n < m_tile_map.size(); n++) { const Tile *tile = m_tile_map[n].ptr; if(!tile || !Flags::test(tile->flags(), Flags::all | Flags::colliding)) continue; bool is_walkable = Flags::test(tile->flags(), Flags::walkable_tile | Flags::wall_tile); (is_walkable? bboxes : blockers).push_back((IBox)m_tile_map[n].bbox); } for(int n = 0; n < m_entity_map.size(); n++) if(m_entity_map[n].ptr && Flags::test(m_entity_map[n].flags, Flags::static_entity | Flags::colliding)) blockers.push_back(enclosingIBox(m_entity_map[n].ptr->boundingBox())); NaviHeightmap heightmap(m_tile_map.dimensions()); heightmap.update(bboxes, blockers); //heightmap.saveLevels(); //heightmap.printInfo(); for(int m = 0; m < (int)m_navi_maps.size(); m++) { m_navi_maps[m].update(heightmap); //m_navi_maps[m].printInfo(); } } for(int m = 0; m < (int)m_navi_maps.size(); m++) { NaviMap &navi_map = m_navi_maps[m]; navi_map.removeColliders(); for(int n = 0; n < m_entity_map.size(); n++) { auto &object = m_entity_map[n]; if(!object.ptr) continue; if(Flags::test(object.flags, Flags::dynamic_entity | Flags::colliding)) { const IBox &box = enclosingIBox(object.ptr->boundingBox()); navi_map.addCollider(box, n); } } navi_map.updateReachability(); } }
void HeightMapEditor::onRenderButtonClicked() { Json::Value graphJson = myUi->graphBuilder->toJson(); std::cerr << graphJson.toStyledString() << std::endl; std::vector<std::shared_ptr<noise::module::Module>> modules; std::map<std::string, std::shared_ptr<noise::module::Module>> defs; PhysFS::ifstream fs("map/heightmap.png"); std::vector<char> data; data.assign(std::istreambuf_iterator<char>(fs), std::istreambuf_iterator<char>()); QImage heightmapImage; heightmapImage.loadFromData((const uchar *)data.data(), data.size()); boost::multi_array<double, 2> heights; heights.resize(boost::extents[heightmapImage.width()][heightmapImage.height()]); for (int y = 0; y < heightmapImage.height(); y++) for (int x = 0; x < heightmapImage.width(); x++) { QColor col(heightmapImage.pixel(x, y)); int height = col.red() | col.green() | col.blue(); heights[x][y] = (height / 256.0) * 2 - 1; } std::shared_ptr<HeightMapModule> heightmap(new HeightMapModule(heights, 400, 240)); std::shared_ptr<noise::module::Module> graph = buildNoiseGraph(graphJson, modules, defs, heightmap, 0); QImage img(400 * 4, 240*4, QImage::Format::Format_ARGB32); for (int y = 0; y < img.height(); y++) for (int x = 0; x < img.width(); x++) { double value = graph->GetValue((double)x, (double)y, 0.0); double height = (value + 1.0) * 0.5; // std::cerr << value << std::endl; if (height < 0) height = 0; if (height > 1) height = 1; QColor col (height * 255.0, height * 255.0, height * 255.0); img.setPixel(x, y, col.rgb()); } myUi->renderView->scene()->clear(); myUi->renderView->scene()->addPixmap(QPixmap::fromImage(img, Qt::ColorOnly)); }
//////////////////////////////////// // Methods //////////////////////////////////// void TerrainMesh::GenerateVertexes(float initial_x, float diff_x, float initial_z, float diff_z) { float scale = 0.1f; for (int i = 0; i < columns; i++) { for (int j = 0; j < rows; j++) { vertexes.push_back(Vertex(D3DXVECTOR3(initial_x + (i * diff_x), (inverted ? -1 : 1) * heightmap(i, j), initial_z + (j * diff_z)), color, D3DXVECTOR2((float)i, (float) j) * scale )); } } // Let's use the parameters to initialize the decorations too! int trees = 0; while (trees < treeCount) { int i = rand() % columns; int j = rand() % rows; float treeHeight = (float) this->heightmap(i, j) - 2.5f; if (treeHeight < -2.0f) { math::Vector3D pos = math::Vector3D(initial_x + (i * diff_x), (inverted ? -1 : 1) * treeHeight, initial_z + (j * diff_z)); decorations.push_back(new Billboard(pos, "BillboardTech", 8, 8, treeFilename)); trees++; } } }