diff --git a/include/maker/ocean.hpp b/include/maker/ocean.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1788316101652da317d2dafcb054fcd8f2f477aa --- /dev/null +++ b/include/maker/ocean.hpp @@ -0,0 +1,59 @@ +#ifndef MAKER_OCEAN_HPP_INCLUDED +# define MAKER_OCEAN_HPP_INCLUDED + +# include <gfx/buffer.hpp> +# include <math/math.hpp> + +namespace mak { + +class Ocean +{ +public: + Ocean(std::uint8_t dimension, scalar amplitude, scalar gravity, vec2 const& wind, scalar length) + : m_dimension { dimension } + , m_buffer_size { dimension + 1U } + , m_amplitude { amplitude } + , m_gravity { gravity } + , m_wind { wind } + , m_wind_length { len(wind) } + , m_length { length } + , m_positions { } + , m_normals { } + { + m_positions.resize(m_buffer_size * m_buffer_size); + m_normals.resize(m_buffer_size * m_buffer_size); + } + + gfx::Buffer::PositionsVec const& positions() const { return m_positions; } + gfx::Buffer::PositionsVec const& normals() const { return m_normals; } + + void update_buffers(scalar t); + + ~Ocean() {} + +private: + vec2 wave_number(vec2i const& coords) const; + scalar dispersion(scalar wave_length) const; + scalar philips_spectrum(vec2 const& k, scalar wave_length) const; + + void update_point(vec2i const& coords, scalar t); + + vec2 wave_height(vec2 const& k, scalar wave_length) const; + vec2 wave_height(vec2 const& k, scalar wave_length, scalar t) const; + + gfx::Buffer::PositionsVec m_positions; + gfx::Buffer::NormalsVec m_normals; + + std::uint8_t const m_dimension; + std::uint8_t const m_buffer_size; + scalar const m_amplitude; + scalar const m_gravity; + vec2 const m_wind; + scalar const m_wind_length; + scalar const m_length; + +}; + +} + +#endif diff --git a/include/maker/updater.hpp b/include/maker/updater.hpp index 1f9ce8a9c6b52a7ae7872139a9be271c600500b2..f6e5692b8c65d8c8d12adb9d82a15642d0403ef1 100644 --- a/include/maker/updater.hpp +++ b/include/maker/updater.hpp @@ -2,6 +2,7 @@ # define MAKER_UPDATER_HPP_INCLUDED # include <com/runner.hpp> +# include <maker/ocean.hpp> # include <math/math.hpp> namespace com { struct Frame; } @@ -19,6 +20,11 @@ struct Updater : public com::Runner protected: + Ocean ocean {16U, 2.0f, 9.81f, { 2.0f, 3.0f }, 5.0f }; + + gfx::Buffer* plane_buffer = nullptr; + gfx::Buffer::PositionsVec default_plane_positions; + void initialize() override; void release() override; }; diff --git a/src/ocean.cpp b/src/ocean.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a40514b031c49e90c1ed71fd7eef9c0171e5997e --- /dev/null +++ b/src/ocean.cpp @@ -0,0 +1,82 @@ +#include <maker/ocean.hpp> + +namespace mak { + +void Ocean::update_buffers(scalar t) +{ + for (std::uint8_t x = 0; x < m_dimension; ++x) + for (std::uint8_t y = 0; y < m_dimension; ++y) + update_point(vec2i(x, y), t); +} + +vec2 Ocean::wave_number(vec2i const& coords) const +{ + return vec2( + Num::pi * (2.0f * get<0>(coords) - m_dimension) / m_length, + Num::pi * (2.0f * get<1>(coords) - m_dimension) / m_length + ); +} + +scalar Ocean::dispersion(scalar wave_length) const +{ + return std::sqrtf(this->m_gravity * wave_length); +} + +scalar Ocean::philips_spectrum(vec2 const& k, scalar wave_length) const +{ + if (wave_length < 1e-4f) return 0.0f; + + scalar L = m_wind_length * m_wind_length / m_gravity; + scalar kdotw = dot(k, m_wind); + scalar k4 = wave_length * wave_length * wave_length * wave_length; + scalar middle = std::expf(-1 / ((wave_length * L) * (wave_length * L))) / k4; + return m_amplitude * middle * kdotw * kdotw; +} + +void Ocean::update_point(vec2i const& coords, scalar t) +{ + vec3 displacement; + for (std::uint8_t x = 0U; x < m_dimension; ++x) + for (std::uint8_t y = 0U; y < m_dimension; ++y) + { + // Can be quickly precalculated into a vector as most of the stuff + vec2 k = wave_number(vec2i(x, y)); + scalar wave_length = len(k); + + if (wave_length < 1e-4f) continue; + + scalar wave_number_dot_coords = dot(k, coords); + vec2 xy = vec2(x, y); + vec2 height = + wave_height(xy, len(xy), t) * + vec2( + std::cosf(wave_number_dot_coords), + std::sinf(wave_number_dot_coords) + ); + + vec2 xy_displacement = normalized(k) * get<1>(height); + displacement += vec3(-get<0>(xy_displacement), -get<1>(xy_displacement), get<0>(height)); + } + + m_positions[get<0>(coords) * m_dimension + get<1>(coords)] = displacement; +} + +vec2 Ocean::wave_height(vec2 const& k, scalar wave_length) const +{ + scalar rand1 = 0.5f; + scalar rand2 = 0.5f; + vec2 first = vec2{ (1.0f / std::sqrtf(2.0f)) * std::sqrtf(philips_spectrum(k, wave_length)) }; + return first * vec2(rand1, rand2); +} + +vec2 Ocean::wave_height(vec2 const& k, scalar wave_length, scalar t) const +{ + scalar omegat = dispersion(wave_length) * t; + scalar cosine = std::cosf(omegat); + scalar sinus = std::sinf(omegat); + vec2 first = wave_height(k, wave_length) * vec2(cosine, sinus); + vec2 second = wave_height(-k, wave_length) * vec2(cosine, -sinus); + return first + vec2(get<0>(second), -get<1>(second)); +} + +} \ No newline at end of file diff --git a/src/presenter.cpp b/src/presenter.cpp index c6ad96ef136b79efc2669e99784b77e01d6fc249..3c8aa84a9c47edbe70837ff6c11cd877881f01ac 100644 --- a/src/presenter.cpp +++ b/src/presenter.cpp @@ -46,6 +46,20 @@ void Presenter::initialize() // --- END test_box --- + // --- BEGIN plane --- + + com::Folder* const test_plane = gfx::object_system()->insert_object( + { "maker", "test_plane" }, + gfx::material_system()->insert_material("plane_material", gfx::shader_system()->forward_unlit_vertex_color_shader(), { "maker" }), + gfx::buffer_generators()->insert_procedural_plane({ 0.5f, 0.5f }, 17U, 17U, "test_plane", { "maker" }) + ); + + com::Frame* const frame3 = root()->push_back<com::Folder>("test_plane")->push_back<com::Frame>(); + frame3->move_origin({ 1.0f, 1.0f, 0.0f }); + gfx::object_system()->push_frame_back(test_plane, frame3); + + // --- END plane --- + // --- BEGIN directional light --- com::Frame* const frame_light = root()->push_back<com::Folder>("directional_light")->push_back<com::Frame>(); @@ -66,6 +80,7 @@ void Presenter::release() osi::presenters()->find<com::Folder>("maker")->erase(self_name() + ".link"); root()->erase("test_box"); + root()->erase("test_plane"); } void Presenter::next_round() diff --git a/src/updater.cpp b/src/updater.cpp index 63502e7f0b095d79d0d6ca34a156249ef2f5a08a..d547dded85fa92d24ec05557ed91acb14fedf43a 100644 --- a/src/updater.cpp +++ b/src/updater.cpp @@ -29,35 +29,56 @@ void Updater::release() osi::updaters()->find<com::Folder>("maker")->erase(self_name() + ".link"); } -void Updater::next_round() +static void camera_movement() { + scalar const linear_speed = 10.0f; + basis3 const camera_basis{ to_mat3x3(camera_frame()->frame().rotation()) }; + if (osi::keyboard()->down().contains("W") || osi::keyboard()->down().contains("Up")) + camera_frame()->move_origin((-linear_speed * osi::timer()->dt()) * camera_basis.axis<2>()); + else if (osi::keyboard()->down().contains("S") || osi::keyboard()->down().contains("Down")) + camera_frame()->move_origin((linear_speed * osi::timer()->dt()) * camera_basis.axis<2>()); + + if (osi::keyboard()->down().contains("A") || osi::keyboard()->down().contains("Left")) + camera_frame()->move_origin((-linear_speed * osi::timer()->dt()) * camera_basis.axis<0>()); + else if (osi::keyboard()->down().contains("D") || osi::keyboard()->down().contains("Right")) + camera_frame()->move_origin((linear_speed * osi::timer()->dt()) * camera_basis.axis<0>()); + + if (osi::keyboard()->down().contains("Q")) + camera_frame()->move_origin((-linear_speed * osi::timer()->dt()) * camera_basis.axis<1>()); + else if (osi::keyboard()->down().contains("E")) + camera_frame()->move_origin((linear_speed * osi::timer()->dt()) * camera_basis.axis<1>()); + if (osi::mouse()->down().contains("MouseRight")) { - scalar const linear_speed = 5.0f; - scalar const rotation_speed_mult = 5.0f; + scalar const rotation_speed_mult = 10.0f; vec2 const mouse_angle = (rotation_speed_mult / gfx::camera_system()->default_camera()->near()) * (vec2{ osi::mouse()->pos_delta() } * osi::window()->pixel_size_in_meters()); - basis3 const camera_basis{ to_mat3x3(camera_frame()->frame().rotation()) }; - if (osi::keyboard()->down().contains("W") || osi::keyboard()->down().contains("Up")) - camera_frame()->move_origin((-linear_speed * osi::timer()->dt()) * camera_basis.axis<2>()); - else if (osi::keyboard()->down().contains("S") || osi::keyboard()->down().contains("Down")) - camera_frame()->move_origin((linear_speed * osi::timer()->dt()) * camera_basis.axis<2>()); - - if (osi::keyboard()->down().contains("A") || osi::keyboard()->down().contains("Left")) - camera_frame()->move_origin((-linear_speed * osi::timer()->dt()) * camera_basis.axis<0>()); - else if (osi::keyboard()->down().contains("D") || osi::keyboard()->down().contains("Right")) - camera_frame()->move_origin((linear_speed * osi::timer()->dt()) * camera_basis.axis<0>()); - - if (osi::keyboard()->down().contains("Q")) - camera_frame()->move_origin((-linear_speed * osi::timer()->dt()) * camera_basis.axis<1>()); - else if (osi::keyboard()->down().contains("E")) - camera_frame()->move_origin((linear_speed * osi::timer()->dt()) * camera_basis.axis<1>()); - camera_frame()->move_rotation(to_quat(-get<1>(mouse_angle), camera_basis.axis<0>())); camera_frame()->move_rotation(to_quat(-get<0>(mouse_angle), axis<vec3, 2>())); } } +void Updater::next_round() +{ + camera_movement(); + + // if (plane_buffer == nullptr) { + // plane_buffer = gfx::buffer_system()->folder()->find<com::Folder>("buffers")->find<com::Folder>("maker")->find<gfx::Buffer>("test_plane"); + // default_plane_positions = (*plane_buffer->positions()); + // } + + // ocean.update_buffers(osi::timer()->dt()); + // plane_buffer->erase_positions(); + // gfx::Buffer::PositionsVec new_positions = default_plane_positions; + // for (std::size_t i = 0; i < ocean.positions().size() - 1; ++i) { + // new_positions[i * 4U] += ocean.positions()[i] / vec3(1.0, 1.0, 100.0); + // new_positions[i * 4U + 1U] += ocean.positions()[i + 1U] / vec3(1.0, 1.0, 100.0); + // new_positions[i * 4U + 2U] += ocean.positions()[i] / vec3(1.0, 1.0, 100.0); + // new_positions[i * 4U + 3U] += ocean.positions()[i] / vec3(1.0, 1.0, 100.0); + // } + // plane_buffer->insert_positions(new_positions); +} + }