functional but slow
parent
8dce8be241
commit
8f04baeb65
|
@ -1,3 +1,3 @@
|
||||||
Start testing: Jan 25 10:57 EST
|
Start testing: Jan 25 14:42 EST
|
||||||
----------------------------------------------------------
|
----------------------------------------------------------
|
||||||
End testing: Jan 25 10:57 EST
|
End testing: Jan 25 14:42 EST
|
||||||
|
|
|
@ -125,8 +125,8 @@ void f_if(ARGS);
|
||||||
|
|
||||||
// NAME MIN MAX FUNC ALLOWED FUNC LIST
|
// NAME MIN MAX FUNC ALLOWED FUNC LIST
|
||||||
#define FUNC_FUNCTIONS \
|
#define FUNC_FUNCTIONS \
|
||||||
FUNC_DEFINE(Y, 0, 0, f_x, FUNC_ALLOW_NONE) \
|
FUNC_DEFINE(X, 0, 0, f_x, FUNC_ALLOW_NONE) \
|
||||||
FUNC_DEFINE(X, 0, 0, f_y, FUNC_ALLOW_NONE) \
|
FUNC_DEFINE(Y, 0, 0, f_y, FUNC_ALLOW_NONE) \
|
||||||
FUNC_DEFINE(RANDOM, 0, 0, f_random, FUNC_ALLOW_NONE) \
|
FUNC_DEFINE(RANDOM, 0, 0, f_random, FUNC_ALLOW_NONE) \
|
||||||
FUNC_DEFINE(NOISE, 0, 2, f_noise, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR) \
|
FUNC_DEFINE(NOISE, 0, 2, f_noise, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR) \
|
||||||
FUNC_DEFINE(CNOISE, 0, 6, f_cnoise, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR) \
|
FUNC_DEFINE(CNOISE, 0, 6, f_cnoise, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR) \
|
||||||
|
@ -215,6 +215,11 @@ DEF_FUNC_LIST(FUNC_ALLOW_TERMINALS, function_t::SCALAR, function_t::X, function_
|
||||||
FUNC_FUNCTIONS
|
FUNC_FUNCTIONS
|
||||||
};
|
};
|
||||||
#undef FUNC_DEFINE
|
#undef FUNC_DEFINE
|
||||||
|
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) #NAME,
|
||||||
|
[[maybe_unused]] static inline std::array<std::string, OPERATOR_COUNT> function_name_map = {
|
||||||
|
FUNC_FUNCTIONS
|
||||||
|
};
|
||||||
|
#undef FUNC_DEFINE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper functions
|
* Helper functions
|
||||||
|
|
|
@ -133,7 +133,7 @@ class image
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blt::vec3 get(blt::i32 x = 0, blt::i32 y = 0) const
|
[[nodiscard]] blt::vec3 get(blt::i32 x = 0, blt::i32 y = 0) const
|
||||||
{
|
{
|
||||||
return std::visit(blt::lambda_visitor{
|
return std::visit(blt::lambda_visitor{
|
||||||
[x, y](const image_data_t* d) -> blt::vec3 {
|
[x, y](const image_data_t* d) -> blt::vec3 {
|
||||||
|
|
|
@ -18,6 +18,42 @@
|
||||||
#include <functions.h>
|
#include <functions.h>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <blt/gfx/stb/stb_perlin.h>
|
#include <blt/gfx/stb/stb_perlin.h>
|
||||||
|
#include <blt/std/memory_util.h>
|
||||||
|
|
||||||
|
#define FUNCTION_COORD() \
|
||||||
|
int xi = static_cast<int>(x); \
|
||||||
|
int yi = static_cast<int>(y);
|
||||||
|
|
||||||
|
#define GET_IMAGE(name, pos) auto name = argv[pos]->get(xi, yi);
|
||||||
|
|
||||||
|
#define SINGLE_FUNCTION(op) \
|
||||||
|
FUNCTION_COORD() \
|
||||||
|
GET_IMAGE(i1, 0) \
|
||||||
|
img.set(blt::vec3{op(i1.x()), op(i1.y()), op(i1.z())}, xi, yi);
|
||||||
|
|
||||||
|
#define DOUBLE_FUNCTION(op) \
|
||||||
|
FUNCTION_COORD() \
|
||||||
|
GET_IMAGE(i1, 0) \
|
||||||
|
GET_IMAGE(i2, 1) \
|
||||||
|
img.set(blt::vec3{op(i1.x(), i2.x()), op(i1.y(), i2.y()), op(i1.z(), i2.z())}, xi, yi);
|
||||||
|
|
||||||
|
#define BITWISE_FUNCTION(op) \
|
||||||
|
FUNCTION_COORD() \
|
||||||
|
GET_IMAGE(i1, 0) \
|
||||||
|
GET_IMAGE(i2, 1) \
|
||||||
|
auto bitsRI1 = blt::mem::type_cast<blt::u32>(i1.x()); \
|
||||||
|
auto bitsGI1 = blt::mem::type_cast<blt::u32>(i1.y()); \
|
||||||
|
auto bitsBI1 = blt::mem::type_cast<blt::u32>(i1.z()); \
|
||||||
|
\
|
||||||
|
auto bitsRI2 = blt::mem::type_cast<blt::u32>(i2.x()); \
|
||||||
|
auto bitsGI2 = blt::mem::type_cast<blt::u32>(i2.y()); \
|
||||||
|
auto bitsBI2 = blt::mem::type_cast<blt::u32>(i2.z()); \
|
||||||
|
\
|
||||||
|
auto r = blt::mem::type_cast<float>(bitsRI1 op bitsRI2); \
|
||||||
|
auto g = blt::mem::type_cast<float>(bitsGI1 op bitsGI2); \
|
||||||
|
auto b = blt::mem::type_cast<float>(bitsBI1 op bitsBI2); \
|
||||||
|
\
|
||||||
|
img.set(blt::vec3{r, g, b}, xi, yi);
|
||||||
|
|
||||||
inline float protect_div(float x, float y, float d = 0)
|
inline float protect_div(float x, float y, float d = 0)
|
||||||
{
|
{
|
||||||
|
@ -108,65 +144,89 @@ void f_color(image& img, float x, float y, blt::size_t argc, const image** argv,
|
||||||
|
|
||||||
void f_log(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
void f_log(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
||||||
{
|
{
|
||||||
|
SINGLE_FUNCTION(std::log);
|
||||||
}
|
}
|
||||||
|
|
||||||
void f_sqrt(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
void f_sqrt(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
||||||
{
|
{
|
||||||
|
SINGLE_FUNCTION(std::sqrt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void f_sin(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
void f_sin(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
||||||
{
|
{
|
||||||
|
#define F_MOD_SIN(x) ((std::sin(x) + 1) * 0.5f)
|
||||||
|
SINGLE_FUNCTION(F_MOD_SIN);
|
||||||
|
#undef F_MOD_SIN
|
||||||
}
|
}
|
||||||
|
|
||||||
void f_cos(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
void f_cos(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
||||||
{
|
{
|
||||||
|
#define F_MOD_COS(x) ((std::cos(x) + 1) * 0.5f)
|
||||||
|
SINGLE_FUNCTION(F_MOD_COS);
|
||||||
|
#undef F_MOD_COS
|
||||||
}
|
}
|
||||||
|
|
||||||
void f_atan(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
void f_atan(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
||||||
{
|
{
|
||||||
|
#define F_MOD_ATAN(x) ((std::atan(x) + 1) * 0.5f)
|
||||||
|
SINGLE_FUNCTION(F_MOD_ATAN);
|
||||||
|
#undef F_MOD_ATAN
|
||||||
}
|
}
|
||||||
|
|
||||||
void f_add(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
void f_add(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
||||||
{
|
{
|
||||||
|
#define F_MOD(x, y) (x + y)
|
||||||
|
DOUBLE_FUNCTION(F_MOD);
|
||||||
|
#undef F_MOD
|
||||||
}
|
}
|
||||||
|
|
||||||
void f_sub(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
void f_sub(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
||||||
{
|
{
|
||||||
|
#define F_MOD(x, y) (x - y)
|
||||||
|
DOUBLE_FUNCTION(F_MOD);
|
||||||
|
#undef F_MOD
|
||||||
}
|
}
|
||||||
|
|
||||||
void f_mul(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
void f_mul(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
||||||
{
|
{
|
||||||
|
#define F_MOD(x, y) (x * y)
|
||||||
|
DOUBLE_FUNCTION(F_MOD);
|
||||||
|
#undef F_MOD
|
||||||
}
|
}
|
||||||
|
|
||||||
void f_div(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
void f_div(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
||||||
{
|
{
|
||||||
|
#define F_MOD(x, y) protect_div(x, y)
|
||||||
|
DOUBLE_FUNCTION(F_MOD);
|
||||||
|
#undef F_MOD
|
||||||
}
|
}
|
||||||
|
|
||||||
void f_or(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
void f_or(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
||||||
{
|
{
|
||||||
|
BITWISE_FUNCTION(|);
|
||||||
}
|
}
|
||||||
|
|
||||||
void f_and(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
void f_and(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
||||||
{
|
{
|
||||||
|
BITWISE_FUNCTION(&);
|
||||||
}
|
}
|
||||||
|
|
||||||
void f_xor(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
void f_xor(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
||||||
{
|
{
|
||||||
|
BITWISE_FUNCTION(^);
|
||||||
}
|
}
|
||||||
|
|
||||||
void f_if(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
void f_if(image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data)
|
||||||
{
|
{
|
||||||
|
FUNCTION_COORD();
|
||||||
|
GET_IMAGE(i1, 0);
|
||||||
|
GET_IMAGE(i2, 1);
|
||||||
|
GET_IMAGE(i3, 2);
|
||||||
|
|
||||||
|
constexpr float SCALE = 0.1;
|
||||||
|
|
||||||
|
if (i1.x() > SCALE || i1.x() < -SCALE)
|
||||||
|
img.set(i2, xi, yi);
|
||||||
|
else
|
||||||
|
img.set(i3, xi, yi);
|
||||||
}
|
}
|
||||||
|
|
85
src/main.cpp
85
src/main.cpp
|
@ -11,11 +11,15 @@
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
#include <queue>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
blt::gfx::matrix_state_manager global_matrices;
|
blt::gfx::matrix_state_manager global_matrices;
|
||||||
blt::gfx::resource_manager resources;
|
blt::gfx::resource_manager resources;
|
||||||
blt::gfx::batch_renderer_2d renderer_2d(resources);
|
blt::gfx::batch_renderer_2d renderer_2d(resources);
|
||||||
|
|
||||||
|
constexpr blt::i32 MAX_DEPTH = 25;
|
||||||
|
|
||||||
struct node;
|
struct node;
|
||||||
|
|
||||||
blt::area_allocator<node, 32000> node_allocator;
|
blt::area_allocator<node, 32000> node_allocator;
|
||||||
|
@ -49,7 +53,7 @@ struct node
|
||||||
|
|
||||||
std::optional<image> img;
|
std::optional<image> img;
|
||||||
|
|
||||||
void grow()
|
void grow(bool use_terminals)
|
||||||
{
|
{
|
||||||
auto min_children = function_arg_min_map[to_underlying(type)];
|
auto min_children = function_arg_min_map[to_underlying(type)];
|
||||||
auto max_children = function_arg_max_map[to_underlying(type)];
|
auto max_children = function_arg_max_map[to_underlying(type)];
|
||||||
|
@ -60,11 +64,13 @@ struct node
|
||||||
static std::uniform_int_distribution<int> choice(0, 1);
|
static std::uniform_int_distribution<int> choice(0, 1);
|
||||||
|
|
||||||
argc = dist(engine);
|
argc = dist(engine);
|
||||||
|
if (argc == 0)
|
||||||
|
return;
|
||||||
const auto& allowed_args_args = function_arg_allowed_map[to_underlying(type)];
|
const auto& allowed_args_args = function_arg_allowed_map[to_underlying(type)];
|
||||||
for (size_t i = 0; i < argc; i++)
|
for (size_t i = 0; i < argc; i++)
|
||||||
{
|
{
|
||||||
// 50/50 chance to either use a terminal or use from the function list.
|
// 50/50 chance to either use a terminal or use from the function list.
|
||||||
populate_node(i, engine, allowed_args_args[i], choice(engine));
|
populate_node(i, engine, allowed_args_args[i], choice(engine) || use_terminals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +80,9 @@ struct node
|
||||||
static thread_local std::mt19937_64 engine{dev()};
|
static thread_local std::mt19937_64 engine{dev()};
|
||||||
|
|
||||||
argc = function_arg_max_map[to_underlying(type)];
|
argc = function_arg_max_map[to_underlying(type)];
|
||||||
|
if (argc == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
const auto& allowed_args_args = function_arg_allowed_map[to_underlying(type)];
|
const auto& allowed_args_args = function_arg_allowed_map[to_underlying(type)];
|
||||||
for (size_t i = 0; i < argc; i++)
|
for (size_t i = 0; i < argc; i++)
|
||||||
populate_node(i, engine, allowed_args_args[i], use_terminals);
|
populate_node(i, engine, allowed_args_args[i], use_terminals);
|
||||||
|
@ -84,6 +93,13 @@ struct node
|
||||||
if (use_terminal)
|
if (use_terminal)
|
||||||
{
|
{
|
||||||
auto terminals = intersection(allowed_args, FUNC_ALLOW_TERMINALS_SET);
|
auto terminals = intersection(allowed_args, FUNC_ALLOW_TERMINALS_SET);
|
||||||
|
if (terminals.empty())
|
||||||
|
{
|
||||||
|
terminals = FUNC_ALLOW_TERMINALS;
|
||||||
|
// BLT_INFO("%s:", function_name_map[to_underlying(type)].c_str());
|
||||||
|
// for (auto v : allowed_args)
|
||||||
|
// BLT_INFO(function_name_map[to_underlying(v)]);
|
||||||
|
}
|
||||||
std::uniform_int_distribution<blt::size_t> select(0, terminals.size() - 1);
|
std::uniform_int_distribution<blt::size_t> select(0, terminals.size() - 1);
|
||||||
sub_nodes[i] = createNode(terminals[select(engine)]);
|
sub_nodes[i] = createNode(terminals[select(engine)]);
|
||||||
} else
|
} else
|
||||||
|
@ -102,6 +118,25 @@ struct node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_tree()
|
||||||
|
{
|
||||||
|
if (argc > 0)
|
||||||
|
std::cout << "(";
|
||||||
|
if (argc > 0)
|
||||||
|
std::cout << function_name_map[to_underlying(type)] << " ";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
evaluate();
|
||||||
|
if (type == function_t::SCALAR)
|
||||||
|
std::cout << img->get().x() << " ";
|
||||||
|
else
|
||||||
|
std::cout << '{' << img->get().x() << ", " << img->get().y() << ", " << img->get().z() << "} ";
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < argc; i++)
|
||||||
|
sub_nodes[i]->print_tree();
|
||||||
|
if (argc > 0)
|
||||||
|
std::cout << ") ";
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
explicit node(function_t type): type(type)
|
explicit node(function_t type): type(type)
|
||||||
{
|
{
|
||||||
|
@ -119,13 +154,31 @@ struct node
|
||||||
|
|
||||||
static node* construct_random_tree()
|
static node* construct_random_tree()
|
||||||
{
|
{
|
||||||
node* n = createNode(function_t::NOISE);
|
static std::random_device dev;
|
||||||
|
static std::mt19937_64 engine{dev()};
|
||||||
|
std::uniform_int_distribution<int> choice(0, 1);
|
||||||
|
std::uniform_int_distribution<int> select(0, OPERATOR_COUNT - 1);
|
||||||
|
|
||||||
std::random_device dev;
|
node* n = createNode(static_cast<function_t>(select(engine)));
|
||||||
std::mt19937_64 engine{dev()};
|
|
||||||
std::uniform_real_distribution<float> dist(0.0f, 1.0f);
|
|
||||||
|
|
||||||
n->full(true);
|
std::queue<std::pair<node*, size_t>> grow_queue;
|
||||||
|
size_t current_depth = 0;
|
||||||
|
grow_queue.emplace(n, current_depth);
|
||||||
|
while (!grow_queue.empty())
|
||||||
|
{
|
||||||
|
auto front = grow_queue.front();
|
||||||
|
if (front.second != current_depth)
|
||||||
|
current_depth++;
|
||||||
|
|
||||||
|
if (choice(engine))
|
||||||
|
front.first->grow(front.second >= MAX_DEPTH);
|
||||||
|
else
|
||||||
|
front.first->full(front.second >= MAX_DEPTH);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < front.first->argc; i++)
|
||||||
|
grow_queue.emplace(front.first->sub_nodes[i], current_depth + 1);
|
||||||
|
grow_queue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -169,6 +222,17 @@ struct node
|
||||||
evaluate();
|
evaluate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printTree()
|
||||||
|
{
|
||||||
|
print_tree();
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasImage()
|
||||||
|
{
|
||||||
|
return img.has_value();
|
||||||
|
}
|
||||||
|
|
||||||
image& getImage()
|
image& getImage()
|
||||||
{
|
{
|
||||||
return img.value();
|
return img.value();
|
||||||
|
@ -226,6 +290,7 @@ void update(std::int32_t w, std::int32_t h)
|
||||||
|
|
||||||
BLT_INFO("Uploading");
|
BLT_INFO("Uploading");
|
||||||
//delete texture;
|
//delete texture;
|
||||||
|
if (root->hasImage())
|
||||||
texture->upload((void*) root->getImage().getData().data(), GL_RGB, 0, 0, 0, -1, -1, GL_FLOAT);
|
texture->upload((void*) root->getImage().getData().data(), GL_RGB, 0, 0, 0, -1, -1, GL_FLOAT);
|
||||||
//texture->upload((void*) test.data(), GL_RGBA, 0, 0, 0, width, height, GL_UNSIGNED_BYTE);
|
//texture->upload((void*) test.data(), GL_RGBA, 0, 0, 0, width, height, GL_UNSIGNED_BYTE);
|
||||||
//texture->upload(file);
|
//texture->upload(file);
|
||||||
|
@ -233,6 +298,12 @@ void update(std::int32_t w, std::int32_t h)
|
||||||
resources.set("img", texture);
|
resources.set("img", texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::Button("Display"))
|
||||||
|
{
|
||||||
|
if (root)
|
||||||
|
root->printTree();
|
||||||
|
}
|
||||||
|
|
||||||
auto lw = 512.0f;
|
auto lw = 512.0f;
|
||||||
auto lh = 512.0f;
|
auto lh = 512.0f;
|
||||||
//renderer_2d.drawRectangle(blt::vec4{0.5, 0.0, 1.0, 1.0},
|
//renderer_2d.drawRectangle(blt::vec4{0.5, 0.0, 1.0, 1.0},
|
||||||
|
|
Loading…
Reference in New Issue