Skip to content

Commit

Permalink
lost the 3rd dimension in the rebase?
Browse files Browse the repository at this point in the history
  • Loading branch information
GDBobby committed Sep 28, 2023
1 parent 78b6eb2 commit 04de89a
Show file tree
Hide file tree
Showing 14 changed files with 796 additions and 5 deletions.
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
add_subdirectory(histogram)
add_subdirectory(texture2d)
add_subdirectory(point-cloud)
2 changes: 0 additions & 2 deletions examples/common/argument_parsing.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#include <noiz/noise2.hpp>

#include <charconv>
#include <format>
#include <iostream>
Expand Down
16 changes: 16 additions & 0 deletions examples/point-cloud/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
project(noiz-point-cloud)

add_executable(${PROJECT_NAME})

target_link_libraries(${PROJECT_NAME} PRIVATE
noiz::noiz-lib
noiz::noiz-compile-options
)

target_sources(${PROJECT_NAME} PRIVATE
pointcloud.cpp
)

target_include_directories(${PROJECT_NAME} PRIVATE
../common
)
137 changes: 137 additions & 0 deletions examples/point-cloud/pointcloud.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#include <noiz/noise3.hpp>
#include <noiz/noise-processing3.hpp>

#include <argument_parsing.hpp>


#include <charconv>
#include <filesystem>
#include <format>
#include <iostream>
#include <vector>
#include <fstream>

constexpr int32_t constant_base_resolution = 128;
constexpr int32_t constant_max_resolution_factor = 32;

struct Config {
noiz::Seed seed{noiz::detail::Generator::make_random_seed()};
noiz::GridExtent3 grid_extent{256, 256, 256}; // NOLINT
float step{0.1f}; // NOLINT
int image_size_factor{1};

// syntax: [count] [step]
auto parse_args(Args args) -> bool {
if (!args.next_as(step, "step")) { return false; }
if (!args.next_as(image_size_factor, "image_size_factor")) { return false; }
if (image_size_factor < 0 || image_size_factor > constant_max_resolution_factor) {
std::cerr << std::format("invalid image size factor: '{}'\n", image_size_factor);
return false;
}
if (!args.args.empty()) {
return false;
}
const int scaled_resolution = constant_base_resolution * image_size_factor;
grid_extent.x = scaled_resolution;
grid_extent.y = scaled_resolution;
grid_extent.z = scaled_resolution;
return true;
}
};

// pulls noise from noiz::lib, writes a pixel to ppm file
class Point_Cloud {
public:
explicit Point_Cloud(int image_size_factor) : image_size{static_cast<uint16_t>(constant_base_resolution * image_size_factor)} {}

void build_and_write_object_with_noise(noiz::Noise3f& noise, float const& step) const {

std::ofstream out_file{"hybrid_multifractal_noise.obj", std::ios::binary};

float vertex_z;
float vertex_y;

noiz::Noise_Processor3<float> noise_processor{noise};

#if 0 //internal testing
noiz::Noise2f noise2;
noiz::Noise_Processor2<float> noise_processor2{noise2};

noiz::Vec3f testing_point;
noise_processor.basic_processing(testing_point);
noise_processor.billowy_processing(testing_point);
noise_processor.hybrid_multi_fractal_processing(testing_point);
noise_processor.rigid_processing(testing_point);
noise_processor.turbulence_processing(testing_point);
noise_processor.raw_noise(testing_point);

noiz::Vec2f testing_point2;
noise_processor2.basic_processing(testing_point2);
noise_processor2.billowy_processing(testing_point2);
noise_processor2.hybrid_multi_fractal_processing(testing_point2);
noise_processor2.rigid_processing(testing_point2);
noise_processor2.turbulence_processing(testing_point2);
noise_processor2.raw_noise(testing_point2);
#endif

for(int z = 0; z < image_size; z++){
vertex_z = (static_cast<float>(z) / static_cast<float>(image_size)) - 0.5f;

for (int y = 0; y < image_size; y++) {
vertex_y = (static_cast<float>(y) / static_cast<float>(image_size)) - 0.5f;
for(int x = 0; x < image_size; x++) {
// add noise at point
//raw noise
#if 0 //raw noise
const float noise_value = noise.at(noiz::Vec3f{.x = static_cast<float>(x) * step, .y = static_cast<float>(y) * step, .z = static_cast<float>(z) * step});
if(noise_value > 0.0f){ //this should render a half of the points with raw noise

//no point in assigning x here? just write it directly to
out_file << "v " << ((static_cast<float>(x) / static_cast<float>(image_size)) - 0.5f) << " " << vertex_y << " " << vertex_z << '\n';
}
#else //hybrid multi fractal noise
const float noise_value = noise_processor.hybrid_multi_fractal_processing(
noiz::Vec3f{.x = static_cast<float>(x) * step, .y = static_cast<float>(y) * step, .z = static_cast<float>(z) * step}
);
if(noise_value > 2.0f){ //this should render a half of the points with hmf noise

//no point in assigning x here? just write it directly to
out_file << "v " << ((static_cast<float>(x) / static_cast<float>(image_size)) - 0.5f) << " " << vertex_y << " " << vertex_z << '\n';
}
#endif
}
}
}
out_file.close();
}

private:
uint16_t image_size;
};

auto main(int argc, char** argv) -> int {
auto config = Config{};

// skip exe name (argv[0])
auto const args = Args{std::span{argv, static_cast<std::size_t>(argc)}.subspan(1)};

// handle --help
if (!args.args.empty() && args.args.front() == std::string_view{"--help"}) {
std::cout << std::format("Usage: {} [step(=0.1)] [image_size_factor(=1)]\n", std::filesystem::path{*argv}.stem().string());
std::cout << "\t output image resolution is 128x128, with each dimension multiplied by image_size_factor, maximum scaling factor is 32[image size of 4096]" << std::endl;
return EXIT_SUCCESS;
}

// parse args, if any
if (!config.parse_args(args)) {
std::cout << args.args.front() << std::endl;
return EXIT_FAILURE;
}


auto noise = noiz::Noise3f{noiz::Seed{config.seed}, config.grid_extent};

// build and write noise to image
auto point_cloud = Point_Cloud{config.image_size_factor};
point_cloud.build_and_write_object_with_noise(noise, config.step);
}
31 changes: 31 additions & 0 deletions noiz/include/noiz/cell3.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once
#include <span>
#include "index3.hpp"
#include "vec3.hpp"

namespace noiz {
template <std::floating_point Type>
struct Corner3 {
Vec3<Type> location{};
Vec3<Type> gradient{};
};

template <typename Type>
struct TCell3 {
Type left_top_below{};
Type right_top_below{};
Type left_bottom_below{};
Type right_bottom_below{};

Type left_top_above{};
Type right_top_above{};
Type left_bottom_above{};
Type right_bottom_above{};
};

template <std::floating_point Type>
using Cell3 = TCell3<Vec3<Type>>;

template <std::floating_point Type>
using CornerCell3 = TCell3<Corner3<Type>>;
} // namespace noiz
58 changes: 58 additions & 0 deletions noiz/include/noiz/detail/data3.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#pragma once
#include "generator.hpp"
#include "grid3.hpp"

namespace noiz::detail {
template <std::floating_point Type>
auto make_populated_grid(Index3 const grid_extent, Seed seed = Generator::make_random_seed()) -> Grid3<Type> {
auto ret = make_grid3<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(CornerCell3<Type> const& corner, Vec3<Type> const point) -> Cell3<Type> {
return Cell3<Type>{
.left_top_below = point - corner.left_top_below.location,
.right_top_below = point - corner.right_top_below.location,
.left_bottom_below = point - corner.left_bottom_below.location,
.right_bottom_below = point - corner.right_bottom_below.location,
.left_top_above = point - corner.left_top_above.location,
.right_top_above = point - corner.right_top_above.location,
.left_bottom_above = point - corner.left_bottom_above.location,
.right_bottom_above = point - corner.right_bottom_above.location,
};
}

template <std::floating_point Type>
constexpr auto compute_dot_products(CornerCell3<Type> const& corner, Cell3<Type> const& offset) -> TCell3<Type> {
return TCell3<Type>{
.left_top_below = dot(corner.left_top_below.gradient, offset.left_top_below),
.right_top_below = dot(corner.right_top_below.gradient, offset.right_top_below),
.left_bottom_below = dot(corner.left_bottom_below.gradient, offset.left_bottom_below),
.right_bottom_below = dot(corner.right_bottom_below.gradient, offset.right_bottom_below),

.left_top_above = dot(corner.left_top_above.gradient, offset.left_top_above),
.right_top_above = dot(corner.right_top_above.gradient, offset.right_top_above),
.left_bottom_above = dot(corner.left_bottom_above.gradient, offset.left_bottom_above),
.right_bottom_above = dot(corner.right_bottom_above.gradient, offset.right_bottom_above),
};
}

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

auto const below_a = std::lerp(dot_products.left_top_below, dot_products.right_top_below, uvw.x);
auto const below_b = std::lerp(dot_products.left_bottom_below, dot_products.right_bottom_below, uvw.x);
auto const below = std::lerp(below_a, below_b, uvw.y);

auto const above_a = std::lerp(dot_products.left_top_above, dot_products.right_top_above, uvw.x);
auto const above_b = std::lerp(dot_products.left_bottom_above, dot_products.right_bottom_above, uvw.x);
auto const above = std::lerp(above_a, above_b, uvw.y);

//i might need to swap the position of below and above, not really sure
return std::lerp(below, above, uvw.z);
}
} // namespace noiz::detail
15 changes: 14 additions & 1 deletion noiz/include/noiz/detail/generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <random>
#include "../seed.hpp"
#include "../vec2.hpp"
#include "../vec3.hpp"

namespace noiz::detail {
///
Expand Down Expand Up @@ -36,16 +37,28 @@ class Generator {
out = Vec2<Type>{.x = distribution(m_engine), .y = distribution(m_engine)}.normalized();
}

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

///
/// \brief Obtain the next random unit Vec.
/// \returns The next random unit Vec.
///
template <std::floating_point Type>
auto next() -> Vec2<Type> {
auto next2() -> Vec2<Type> {
auto ret = Vec2<Type>{};
next(ret);
return ret;
}
template <std::floating_point Type>
auto next3() -> Vec3<Type> {
auto ret = Vec3<Type>{};
next(ret);
return ret;
}

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

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

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

template <std::floating_point Type>
struct Grid3 {
std::vector<Corner3<Type>> corners{};
Index3 grid_extent{};

[[nodiscard]] auto at(CellIndex3 const index) const -> CornerCell3<Type> {
return CornerCell3<Type>{
corners.at(index.ltb), corners.at(index.rtb), corners.at(index.lbb), corners.at(index.rbb),
corners.at(index.lta), corners.at(index.rta), corners.at(index.lba), corners.at(index.rba)
};
}

[[nodiscard]] auto at(Index3 index) const -> CornerCell3<Type> { return at(CellIndex3::make(index, grid_extent)); }
};

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

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

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 index3 = Index3{.x = col, .y = row, .z = depth};
auto const index = static_cast<std::size_t>(index3.flatten(grid_extent));
ret.corners.at(index).location = to_vec3<Type>(Index3{.x = col, .y = row, .z = depth});
}
}
}

return ret;
}
} // namespace noiz::detail
49 changes: 49 additions & 0 deletions noiz/include/noiz/index3.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#pragma once
#include <cassert>
#include <cstdint>

namespace noiz {
struct Index3 {
int x{};
int y{};
int z{};

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

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

struct CellIndex3 {
std::size_t ltb{};
std::size_t rtb{};
std::size_t lbb{};
std::size_t rbb{};

std::size_t lta{};
std::size_t rta{};
std::size_t lba{};
std::size_t rba{};

static constexpr auto make(Index3 index, Index3 const grid_extent) -> CellIndex3 {
index = index.modulo(grid_extent);
auto const cell_index = index.flatten(grid_extent);
assert(cell_index >= 0);
auto ret = CellIndex3{};
ret.ltb = static_cast<std::size_t>(cell_index);
ret.rtb = ret.ltb + 1;
ret.lbb = ret.ltb + static_cast<std::size_t>(grid_extent.x + 1);
ret.rbb = ret.rtb + static_cast<std::size_t>(grid_extent.x + 1);

ret.lta = ret.ltb + static_cast<std::size_t>((grid_extent.x + 1) * (grid_extent.y + 1));
ret.rta = ret.rtb + static_cast<std::size_t>((grid_extent.x + 1) * (grid_extent.y + 1));
ret.lba = ret.lbb + static_cast<std::size_t>((grid_extent.x + 1) * (grid_extent.y + 1));
ret.rba = ret.rbb + static_cast<std::size_t>((grid_extent.x + 1) * (grid_extent.y + 1));
return ret;
}
};
} // namespace noiz
Loading

0 comments on commit 04de89a

Please sign in to comment.