Skip to content

Commit

Permalink
4th dimension
Browse files Browse the repository at this point in the history
finished i think? probably some bugs lingering
I need to add an example
  • Loading branch information
GDBobby committed Sep 28, 2023
1 parent 04de89a commit 5504597
Show file tree
Hide file tree
Showing 10 changed files with 545 additions and 2 deletions.
20 changes: 19 additions & 1 deletion noiz/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,25 @@ target_sources(${PROJECT_NAME} PUBLIC FILE_SET HEADERS BASE_DIRS include FILES
include/noiz/noise2.hpp
include/noiz/seed.hpp
include/noiz/vec2.hpp
)


include/noiz/detail/data3.hpp
include/noiz/detail/grid3.hpp

include/noiz/cell3.hpp
include/noiz/index3.hpp
include/noiz/noise3.hpp
include/noiz/vec3.hpp


include/noiz/detail/data4.hpp
include/noiz/detail/grid4.hpp

include/noiz/cell4.hpp
include/noiz/index4.hpp
include/noiz/noise4.hpp
include/noiz/vec4.hpp
)

target_include_directories(${PROJECT_NAME} INTERFACE
include
Expand Down
23 changes: 23 additions & 0 deletions noiz/include/noiz/cell4.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once
#include <span>
#include "index4.hpp"
#include "vec4.hpp"

namespace noiz {
template <std::floating_point Type>
struct Corner4 {
Vec4<Type> location{};
Vec4<Type> gradient{};
};

template <typename Type>
struct TCell4 {
std::array<Type, 16> corners;
};

template <std::floating_point Type>
using Cell4 = TCell4<Vec4<Type>>;

template <std::floating_point Type>
using CornerCell4 = TCell4<Corner4<Type>>;
} // namespace noiz
67 changes: 67 additions & 0 deletions noiz/include/noiz/detail/data4.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#pragma once
#include "generator.hpp"
#include "grid4.hpp"

namespace noiz::detail {
template <std::floating_point Type>
auto make_populated_grid(Index4 const grid_extent, Seed seed = Generator::make_random_seed()) -> Grid4<Type> {
auto ret = make_grid4<Type>(grid_extent);
auto generator = Generator{seed};
for (auto& corner : ret.corners) { generator.next(corner.gradient); }
return ret;
}

template <std::floating_point Type>
constexpr auto compute_offsets(CornerCell4<Type> const& corner, Vec4<Type> const point) -> Cell4<Type> {

Cell4<Type> ret;
for(uint8_t i = 0; i < 16; i++){
ret.corners[i] = point - corner.corners[i];
}
return ret;
}

template <std::floating_point Type>
constexpr auto compute_dot_products(CornerCell4<Type> const& corner, Cell4<Type> const& offset) -> TCell4<Type> {

TCell4<Type> ret;
for(int i = 0; i < 16; i++){
ret.corners[i] = dot(corner.corners[i].gradient, offset.corners[i]);
}
return ret;
}

template <std::floating_point Type>
constexpr auto interpolate(Vec4<Type> const point, TCell4<Type> const& dot_products) -> Type {
auto const cell_interpolated_position = point.fract().fade();

//1st dimension
auto const below_a = std::lerp(dot_products.corners[0], dot_products.corners[1], cell_interpolated_position.x);
//2nd dimension
auto const below_b = std::lerp(dot_products.corners[2], dot_products.corners[3], cell_interpolated_position.x);
auto const below = std::lerp(below_a, below_b, cell_interpolated_position.y);

//3rd dimension
auto const above_a = std::lerp(dot_products.corners[4], dot_products.corners[5], cell_interpolated_position.x);
auto const above_b = std::lerp(dot_products.corners[6], dot_products.corners[7], cell_interpolated_position.x);
auto const above = std::lerp(above_a, above_b, cell_interpolated_position.y);

auto const third_lerp_a = std::lerp(below, above, cell_interpolated_position.z);

//4th dimension
auto const fourth_below_a = std::lerp(dot_products.corners[8], dot_products.corners[9], cell_interpolated_position.x);
auto const fourth_below_b = std::lerp(dot_products.corners[10], dot_products.corners[11], cell_interpolated_position.x);
auto const fourth_below = std::lerp(fourth_below_a, fourth_below_b, cell_interpolated_position.y);

auto const fourth_above_a = std::lerp(dot_products.corners[12], dot_products.corners[13], cell_interpolated_position.x);
auto const fourth_above_b = std::lerp(dot_products.corners[14], dot_products.corners[15], cell_interpolated_position.x);
auto const fourth_above = std::lerp(fourth_above_a, fourth_above_b, cell_interpolated_position.y);

auto const third_lerp_b = std::lerp(fourth_below, fourth_above, cell_interpolated_position.z);



//i might need to swap the position of below and above, not really sure
return std::lerp(third_lerp_a, third_lerp_b, cell_interpolated_position.w);
}
} // namespace noiz::detail
13 changes: 13 additions & 0 deletions noiz/include/noiz/detail/generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "../seed.hpp"
#include "../vec2.hpp"
#include "../vec3.hpp"
#include "../vec4.hpp"

namespace noiz::detail {
///
Expand Down Expand Up @@ -43,6 +44,12 @@ class Generator {
out = Vec3<Type>{.x = distribution(m_engine), .y = distribution(m_engine), .z = distribution(m_engine)}.normalized();
}

template <std::floating_point Type>
void next(Vec4<Type>& out) {
auto distribution = std::uniform_real_distribution<Type>{Type{-1}, Type{1}};
out = Vec4<Type>{.x = distribution(m_engine), .y = distribution(m_engine), .z = distribution(m_engine), .w = distribution(m_engine)}.normalized();
}

///
/// \brief Obtain the next random unit Vec.
/// \returns The next random unit Vec.
Expand All @@ -59,6 +66,12 @@ class Generator {
next(ret);
return ret;
}
template <std::floating_point Type>
auto next4() -> Vec4<Type> {
auto ret = Vec4<Type>{};
next(ret);
return ret;
}

private:
std::default_random_engine m_engine{};
Expand Down
57 changes: 57 additions & 0 deletions noiz/include/noiz/detail/grid4.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once
#include <cassert>
#include <vector>
#include "../cell4.hpp"

namespace noiz::detail {
template <std::floating_point Type>
[[nodiscard]] constexpr auto to_index4(Vec4<Type> const point) -> Index4 {
return Index4{.x = static_cast<int>(point.x), .y = static_cast<int>(point.y), .z = static_cast<int>(point.z), .w = static_cast<int>(point.w)};
}

template <std::floating_point Type>
[[nodiscard]] constexpr auto to_vec4(Index4 const index) -> Vec4<Type> {
return Vec4<Type>{.x = static_cast<Type>(index.x), .y = static_cast<Type>(index.y), .z = static_cast<Type>(index.z), .w = static_cast<Type>(index.w)};
}

template <std::floating_point Type>
struct Grid4 {
std::vector<Corner4<Type>> corners{};
Index4 grid_extent{};

[[nodiscard]] auto at(CellIndex4 const index) const -> CornerCell4<Type> {
return CornerCell4<Type>{
corners.at(index.at(0)), corners.at(index.at(1)), corners.at(index.at(2), corners.at(index.at(3)),
corners.at(index.at(4)), corners.at(index.at(5)), corners.at(index.at(6)), corners.at(index.at(7)),
corners.at(index.at(8)), corners.at(index.at(9)), corners.at(index.at(10), corners.at(index.at(11)),
corners.at(index.at(12)), corners.at(index.at(13)), corners.at(index.at(14)), corners.at(index.at(15))
};
}

[[nodiscard]] auto at(Index4 index) const -> CornerCell4<Type> { return at(CellIndex4::make(index, grid_extent)); }
};

template <std::floating_point Type>
[[nodiscard]] auto make_grid4(Index4 grid_extent) -> Grid4<Type> {
auto const corner_count = (grid_extent.x + 1) * (grid_extent.y + 1) * (grid_extent.z + 1) * (grid_extent.w + 1);
if (corner_count <= 0) { return {}; }

auto ret = Grid4<Type>{
.corners = std::vector<Corner4<Type>>(static_cast<std::size_t>(corner_count)),
.grid_extent = grid_extent,
};

for(int fourth = 0; fourth <= grid_extent.w; ++fourth){ //fourth dimension???
for(int depth = 0; depth <= grid_extent.z; ++depth) {
for (int row = 0; row <= grid_extent.y; ++row) {
for (int col = 0; col <= grid_extent.x; ++col) {
auto const index4 = Index4{.x = col, .y = row, .z = depth, .w = fourth};
auto const index = static_cast<std::size_t>(index4.flatten(grid_extent));
ret.corners.at(index).location = to_vec4<Type>(Index4{.x = col, .y = row, .z = depth, .w = fourth});
}
}
}
}
return ret;
}
} // namespace noiz::detail
2 changes: 1 addition & 1 deletion noiz/include/noiz/index3.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ struct Index3 {
int z{};

[[nodiscard]] constexpr auto modulo(Index3 const extent) const -> Index3 {
assert(extent.x > 0 && extent.y > 0);
assert(extent.x > 0 && extent.y > 0 && extent.z > 0);
return Index3{.x = x % extent.x, .y = y % extent.y, .z = z % extent.z};
}

Expand Down
61 changes: 61 additions & 0 deletions noiz/include/noiz/index4.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#pragma once
#include <cassert>
#include <cstdint>

namespace noiz {
struct Index4 {
int x{};
int y{};
int z{};
int w{};

[[nodiscard]] constexpr auto modulo(Index4 const extent) const -> Index4 {
assert(extent.x > 0 && extent.y > 0 && extent.z > 0 && extent.w > 0);
return Index4{.x = x % extent.x, .y = y % extent.y, .z = z % extent.z, .w = w % extent.w};
}

[[nodiscard]] constexpr auto flatten(Index4 const extent) const -> int64_t {
return w * ((extent.z + 1) * (extent.y + 1) * (extent.x + 1))
+ z * ((extent.x + 1) * (extent.y + 1))
+ y * (extent.x + 1)
+ x;
}
};

struct CellIndex4 {

//16 is 2^4
std::array<std::size_t, 16> positions; //NOLINT

static constexpr auto make(Index4 index, Index4 const grid_extent) -> CellIndex4 {
index = index.modulo(grid_extent);
auto const cell_index = index.flatten(grid_extent);
assert(cell_index >= 0);
auto ret = CellIndex4{};


//1st dimension
ret.positions[0] = static_cast<std::size_t>(cell_index);
ret.positions[1] = ret.positions[0] + 1;

//2nd dimension
for(int i = 2; i < 4; i++){
ret.positions.at(i) = ret.positions.at(i - 2) + static_cast<std::size_t>(grid_extent.x + 1);
}

//3rd dimension
const auto dimension_offset3 = static_cast<std::size_t>((grid_extent.x + 1) * (grid_extent.y + 1));
for(int i = 4; i < 8; i++){
ret.positions.at(i) = ret.positions.at(i - 4) + dimension_offset3;
}

//4th dimension
const auto dimension_offset4 = dimension_offset3 * static_cast<std::size_t>(grid_extent.z + 1);
for(int i = 8; i < 16; i++){
ret.positions.at(i) = ret.positions.at(i - 8) + dimension_offset4;
}

return ret;
}
};
} // namespace noiz
Loading

0 comments on commit 5504597

Please sign in to comment.