SmoothGroundMap::SmoothGroundMap(bounds2f bounds, std::unique_ptr<Image>&& image) : _heightMap{bounds}, _bounds{bounds}, _image{std::move(image)} { UpdateHeightMap(); }
bounds2f SmoothGroundMap::Paint(TerrainFeature feature, glm::vec2 position, float pressure, float radius) { glm::vec2 scale = _bounds.size() / glm::vec2(_image->size()); float abs_pressure = glm::abs(pressure); glm::ivec2 center = ToGroundmapCoordinate(position); float value = pressure > 0 ? 1 : 0; float delta = pressure > 0 ? -0.015f : 0.015f; for (int x = -10; x <= 10; ++x) for (int y = -10; y <= 10; ++y) { glm::ivec2 p = center + glm::ivec2(x, y); float d = glm::distance(position, scale * glm::vec2(p)) / radius; float k = 1.0f - d * d; if (k > 0) { glm::vec4 c = _image->GetPixel(p.x, p.y); switch (feature) { case TerrainFeature::Hills: c.a = glm::mix(c.a, c.a + delta, k * abs_pressure); break; case TerrainFeature::Trees: c.g = glm::mix(c.g, value, k * abs_pressure); break; case TerrainFeature::Water: c.b = glm::mix(c.b, value, k * abs_pressure); break; case TerrainFeature::Fords: c.r = glm::mix(c.r, value, k * abs_pressure); break; } _image->SetPixel(p.x, p.y, c); } } UpdateHeightMap(); return bounds2f(position).add_radius(radius + 1); }
bounds2f SmoothGroundMap::Paint(TerrainFeature feature, glm::vec2 position, float pressure, const Image& brush) { glm::vec2 scale = _bounds.size() / glm::vec2(_image->size()); glm::ivec2 size = brush.size(); glm::ivec2 center = ToGroundmapCoordinate(position); glm::ivec2 origin = center - size / 2; float radius = size.x / 2.0f; for (int x = 0; x < size.x; ++x) for (int y = 0; y < size.y; ++y) { glm::ivec2 p = origin + glm::ivec2(x, y); float d = glm::distance(position, scale * glm::vec2(p)) / radius; float k = 1.0f - d * d; if (k > 0) { glm::vec4 b = brush.GetPixel(x, y); glm::vec4 c = _image->GetPixel(p.x, p.y); switch (feature) { case TerrainFeature::Hills: c.a = glm::mix(c.a, b.a, k * pressure); break; case TerrainFeature::Trees: c.g = glm::mix(c.g, b.g, k * pressure); break; case TerrainFeature::Water: c.b = glm::mix(c.b, b.b, k * pressure); break; case TerrainFeature::Fords: c.r = glm::mix(c.r, b.r, k * pressure); break; } _image->SetPixel(p.x, p.y, c); } } UpdateHeightMap(); return bounds2f(position).add_radius(radius + 1); }
void Patch::Init(CSMFGroundDrawer* _drawer, int patchX, int patchZ) { coors.x = patchX; coors.y = patchZ; smfGroundDrawer = _drawer; // Store pointer to first byte of the height data for this patch. heightMap = &(readMap->GetCornerHeightMapUnsynced())[coors.y * mapDims.mapxp1 + coors.x]; // Attach the two m_Base triangles together baseLeft.BaseNeighbor = &baseRight; baseRight.BaseNeighbor = &baseLeft; // Create used OpenGL objects triList = glGenLists(1); if (GLEW_ARB_vertex_buffer_object) { glGenBuffersARB(1, &vertexBuffer); glGenBuffersARB(1, &vertexIndexBuffer); } UpdateHeightMap(); }
void Patch::Init(CSMFGroundDrawer* _drawer, int worldX, int worldZ) { smfGroundDrawer = _drawer; heightData = readmap->GetCornerHeightMapUnsynced();; m_WorldX = worldX; m_WorldY = worldZ; // Attach the two m_Base triangles together m_BaseLeft.BaseNeighbor = &m_BaseRight; m_BaseRight.BaseNeighbor = &m_BaseLeft; // Store pointer to first byte of the height data for this patch. m_HeightMap = &heightData[worldZ * gs->mapxp1 + worldX]; // Create used OpenGL objects triList = glGenLists(1); if (GLEW_ARB_vertex_buffer_object) { glGenBuffersARB(1, &vertexBuffer); glGenBuffersARB(1, &vertexIndexBuffer); } UpdateHeightMap(); }