Skip to content

Commit

Permalink
Terrain support for customizing amplitude, lacunarity, persistance an…
Browse files Browse the repository at this point in the history
…d octaves.

Added a Terrain to the starting scene and modified defaults to be more interesting.
  • Loading branch information
MStachowicz committed Oct 4, 2024
1 parent 3aef438 commit 082cfed
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 16 deletions.
47 changes: 38 additions & 9 deletions source/Component/Terrain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@

#include "imgui.h"

Component::Terrain::Terrain(const glm::vec3& p_position, int p_size_x, int p_size_z) noexcept
Component::Terrain::Terrain(const glm::vec3& p_position, int p_size_x, int p_size_z, float amplitude) noexcept
: m_position{p_position}
, m_size_x{p_size_x}
, m_size_z{p_size_z}
, m_scale_factor{1.f}
, m_scale_factor{0.03f}
, m_amplitude{amplitude}
, m_lacunarity{2.f}
, m_persistence{0.5f}
, m_octaves{4}
, m_texture{}
, m_seed{Utility::get_random_number<unsigned int>()}
, m_mesh{generate_mesh(m_seed)}
Expand All @@ -20,6 +24,10 @@ Component::Terrain::Terrain(const Terrain& p_other) noexcept
, m_size_x{p_other.m_size_x}
, m_size_z{p_other.m_size_z}
, m_scale_factor{p_other.m_scale_factor}
, m_amplitude{p_other.m_amplitude}
, m_lacunarity{p_other.m_lacunarity}
, m_persistence{p_other.m_persistence}
, m_octaves{p_other.m_octaves}
, m_texture{p_other.m_texture}
, m_seed{p_other.m_seed}
, m_mesh{generate_mesh(m_seed)} // TODO: Implement a Data::Mesh copy.
Expand All @@ -30,15 +38,32 @@ Component::Terrain& Component::Terrain::operator=(const Terrain& p_other) noexce
m_size_x = p_other.m_size_x;
m_size_z = p_other.m_size_z;
m_scale_factor = p_other.m_scale_factor;
m_amplitude = p_other.m_amplitude;
m_lacunarity = p_other.m_lacunarity;
m_persistence = p_other.m_persistence;
m_octaves = p_other.m_octaves;
m_texture = p_other.m_texture;
m_seed = p_other.m_seed;
m_mesh = generate_mesh(m_seed); // TODO: Implement a Data::Mesh copy.
return *this;
}

float compute_height(float p_x, float p_z, float p_scale_factor, const siv::PerlinNoise& perlin)
float Component::Terrain::compute_height(float p_x, float p_z, const siv::PerlinNoise& perlin)
{
return static_cast<float>(perlin.noise2D(p_x * p_scale_factor, p_z * p_scale_factor));
float accumulate = 0.f;
float octave_frequency = 1.f;
float octave_amplitude = 1.f;
float max_value = 0.f;

for (int i = 0; i < m_octaves; i++)
{
accumulate += static_cast<float>(perlin.noise2D(p_x * m_scale_factor * octave_frequency, p_z * m_scale_factor * octave_frequency)) * octave_amplitude;
max_value += octave_amplitude;
octave_amplitude *= m_persistence;
octave_frequency *= m_lacunarity;
}

return accumulate / max_value * m_amplitude;
}

Data::Mesh Component::Terrain::generate_mesh(unsigned int p_seed) noexcept
Expand All @@ -52,10 +77,10 @@ Data::Mesh Component::Terrain::generate_mesh(unsigned int p_seed) noexcept
for (float z = 0; z < m_size_z; z++)
{
mb.add_quad(
glm::vec3(x + 1, compute_height(x + 1, z, m_scale_factor, perlin), z),
glm::vec3(x + 1, compute_height(x + 1, z + 1, m_scale_factor, perlin), z + 1),
glm::vec3(x, compute_height(x, z, m_scale_factor, perlin), z),
glm::vec3(x, compute_height(x, z + 1, m_scale_factor, perlin), z + 1));
glm::vec3(x + 1, compute_height(x + 1, z, perlin), z),
glm::vec3(x + 1, compute_height(x + 1, z + 1, perlin), z + 1),
glm::vec3(x, compute_height(x, z, perlin), z),
glm::vec3(x, compute_height(x, z + 1, perlin), z + 1));
}

return mb.get_mesh();
Expand Down Expand Up @@ -83,7 +108,11 @@ void Component::Terrain::draw_UI(System::AssetManager& p_asset_manager)
changed |= ImGui::Slider("Position", m_position, -100.f, 100.f, "%.3fm");
changed |= ImGui::Slider("Size X", m_size_x, 1, 1000, "%dm");
changed |= ImGui::Slider("Size Z", m_size_z, 1, 1000, "%dm");
changed |= ImGui::Slider("Scale factor", m_scale_factor, 0.01f , 10.f);
changed |= ImGui::Slider("Scale factor", m_scale_factor, 0.01f , 0.15f);
changed |= ImGui::Slider("Amplitude", m_amplitude, 0.01f, 100.f);
changed |= ImGui::Slider("Lacunarity", m_lacunarity, 0.01f, 4.f);
changed |= ImGui::Slider("Persistence", m_persistence, 0.01f, 1.f);
changed |= ImGui::Slider("Octaves", m_octaves, 1, 10);
changed |= ImGui::InputScalar("Seed", ImGuiDataType_U32, &m_seed);
ImGui::SameLine();
if (ImGui::Button("Rand"))
Expand Down
11 changes: 10 additions & 1 deletion source/Component/Terrain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
#include "Component/Texture.hpp"
#include "Component/Mesh.hpp"

#include "Utility/PerlinNoise.hpp"



namespace System
{
class AssetManager;
Expand All @@ -20,18 +24,23 @@ namespace Component
int m_size_x;
int m_size_z;
float m_scale_factor;
float m_amplitude;
float m_lacunarity;
float m_persistence;
int m_octaves;
TextureRef m_texture;
unsigned int m_seed; // Seed used to generate m_mesh.
Data::Mesh m_mesh;

Terrain(const glm::vec3& p_position, int p_size_x, int p_size_z) noexcept;
Terrain(const glm::vec3& p_position, int p_size_x, int p_size_z, float amplitude) noexcept;
// Copy constructor has to be implemented because Data::Mesh GL members are not copyable.
Terrain(const Terrain& p_other) noexcept;
// Copy assignment operator has to be implemented because Data::Mesh GL members are not copyable.
Terrain& operator=(const Terrain& p_other) noexcept;
Terrain(Terrain&& p_other) noexcept = default;
Terrain& operator=(Terrain&& p_other) noexcept = default;

float compute_height(float p_x, float p_z, const siv::PerlinNoise& perlin);
void draw_UI(System::AssetManager& p_asset_manager);
};
} // namespace Component
11 changes: 6 additions & 5 deletions source/System/SceneSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ namespace System
set_current_scene(scene);
add_default_camera(scene);
construct_2_sphere_scene(scene);

Component::Terrain terrain({0.f, 5.f, -100.f}, 100, 100, 20);
terrain.m_texture = m_asset_manager.get_texture(Config::Texture_Directory / "GrassTile.png");
scene.m_entities.add_entity(terrain);
}

void SceneSystem::set_current_scene(const Scene& p_scene)
Expand Down Expand Up @@ -209,9 +213,6 @@ namespace System
auto particle_emitter = Component::ParticleEmitter{m_asset_manager.get_texture(Config::Texture_Directory / "smoke.png")};
p_scene.m_entities.add_entity(Component::Label{"Particle emitter"}, particle_emitter);
}
{ // Terrain
p_scene.m_entities.add_entity(Component::Label{"Terrain"}, Component::Terrain{glm::vec3(0.f), 100, 100});
}
}

void SceneSystem::constructBoxScene(Scene& p_scene)
Expand Down Expand Up @@ -283,15 +284,15 @@ namespace System
p_scene.m_entities.add_entity(
Component::Label{"Sphere 1"},
Component::RigidBody{},
Component::Transform{glm::vec3(2.f, 0.f, 0.f)},
Component::Transform{glm::vec3(50.f, 30.f, -50.f)},
Component::Mesh{icosphere_meshref},
Component::Texture{glm::vec4(0.5f, 0.5f, 0.5f, 0.6f)}, // Grey
Component::Collider{});

p_scene.m_entities.add_entity(
Component::Label{"Sphere 2"},
Component::RigidBody{},
Component::Transform{glm::vec3(5.f, 0.f, 0.f)},
Component::Transform{glm::vec3(55.f, 30.f, -50.f)},
Component::Mesh{icosphere_meshref},
Component::Texture{glm::vec4(1.f, 0.647f, 0.f, 0.6f)}, // Orange
Component::Collider{});
Expand Down
2 changes: 1 addition & 1 deletion source/UI/Editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ namespace UI
{
m_scene_system.get_current_scene_entities().add_entity(
Component::Label{"Terrain"},
Component::Terrain{*m_cursor_intersection, 10, 10});
Component::Terrain{*m_cursor_intersection, 10, 10, 5.f});
}
ImGui::EndMenu();
}
Expand Down

0 comments on commit 082cfed

Please sign in to comment.