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,26 +125,26 @@ void f_if(ARGS);
|
|||
|
||||
// NAME MIN MAX FUNC ALLOWED FUNC LIST
|
||||
#define FUNC_FUNCTIONS \
|
||||
FUNC_DEFINE(Y, 0, 0, f_x, FUNC_ALLOW_NONE) \
|
||||
FUNC_DEFINE(X, 0, 0, f_y, FUNC_ALLOW_NONE) \
|
||||
FUNC_DEFINE(X, 0, 0, f_x, 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(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(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(SCALAR, 0, 0, f_scalar, FUNC_ALLOW_NONE) \
|
||||
FUNC_DEFINE(COLOR, 0, 0, f_color, FUNC_ALLOW_NONE) \
|
||||
FUNC_DEFINE(LOG, 1, 1, f_log, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(SQRT, 1, 1, f_sqrt, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(SIN, 1, 1, f_sin, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(COS, 1, 1, f_cos, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(ATAN, 1, 1, f_atan, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(ADD, 2, 2, f_add, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(SUB, 2, 2, f_sub, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(MUL, 2, 2, f_mul, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(DIV, 2, 2, f_div, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(OR, 2, 2, f_or, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(AND, 2, 2, f_and, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(XOR, 2, 2, f_xor, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(IF, 3, 3, f_if, FUNC_ALLOW_BOOL, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(COLOR, 0, 0, f_color, FUNC_ALLOW_NONE) \
|
||||
FUNC_DEFINE(LOG, 1, 1, f_log, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(SQRT, 1, 1, f_sqrt, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(SIN, 1, 1, f_sin, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(COS, 1, 1, f_cos, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(ATAN, 1, 1, f_atan, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(ADD, 2, 2, f_add, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(SUB, 2, 2, f_sub, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(MUL, 2, 2, f_mul, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(DIV, 2, 2, f_div, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(OR, 2, 2, f_or, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(AND, 2, 2, f_and, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(XOR, 2, 2, f_xor, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
FUNC_DEFINE(IF, 3, 3, f_if, FUNC_ALLOW_BOOL, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
||||
|
||||
#undef FUNC_ALLOW_ANY
|
||||
#undef FUNC_ALLOW_NONE
|
||||
|
@ -215,6 +215,11 @@ DEF_FUNC_LIST(FUNC_ALLOW_TERMINALS, function_t::SCALAR, function_t::X, function_
|
|||
FUNC_FUNCTIONS
|
||||
};
|
||||
#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
|
||||
|
|
|
@ -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{
|
||||
[x, y](const image_data_t* d) -> blt::vec3 {
|
||||
|
|
|
@ -18,6 +18,42 @@
|
|||
#include <functions.h>
|
||||
#include <random>
|
||||
#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)
|
||||
{
|
||||
|
@ -85,14 +121,14 @@ void f_cnoise(image& img, float x, float y, blt::size_t argc, const image** argv
|
|||
scaleRY *= argv[5]->get().x();
|
||||
|
||||
auto valR = stb_perlin_noise3(protect_div(x, scaleRX, z),
|
||||
protect_div(y, scaleRY, z),
|
||||
z, 0, 0, 0);
|
||||
protect_div(y, scaleRY, z),
|
||||
z, 0, 0, 0);
|
||||
auto valG = stb_perlin_noise3(protect_div(x, scaleGX, z),
|
||||
protect_div(y, scaleGY, z),
|
||||
z, 0, 0, 0);
|
||||
protect_div(y, scaleGY, z),
|
||||
z, 0, 0, 0);
|
||||
auto valB = stb_perlin_noise3(protect_div(x, scaleBX, z),
|
||||
protect_div(y, scaleBY, z),
|
||||
z, 0, 0, 0);
|
||||
protect_div(y, scaleBY, z),
|
||||
z, 0, 0, 0);
|
||||
img.set({valR, valG, valB}, static_cast<int>(x), static_cast<int>(y));
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
#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)
|
||||
{
|
||||
|
||||
#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)
|
||||
{
|
||||
|
||||
#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)
|
||||
{
|
||||
|
||||
#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)
|
||||
{
|
||||
|
||||
#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)
|
||||
{
|
||||
|
||||
#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)
|
||||
{
|
||||
|
||||
#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)
|
||||
{
|
||||
|
||||
BITWISE_FUNCTION(|);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
BITWISE_FUNCTION(^);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
87
src/main.cpp
87
src/main.cpp
|
@ -11,11 +11,15 @@
|
|||
#include "imgui.h"
|
||||
#include <variant>
|
||||
#include <random>
|
||||
#include <queue>
|
||||
#include <stack>
|
||||
|
||||
blt::gfx::matrix_state_manager global_matrices;
|
||||
blt::gfx::resource_manager resources;
|
||||
blt::gfx::batch_renderer_2d renderer_2d(resources);
|
||||
|
||||
constexpr blt::i32 MAX_DEPTH = 25;
|
||||
|
||||
struct node;
|
||||
|
||||
blt::area_allocator<node, 32000> node_allocator;
|
||||
|
@ -49,7 +53,7 @@ struct node
|
|||
|
||||
std::optional<image> img;
|
||||
|
||||
void grow()
|
||||
void grow(bool use_terminals)
|
||||
{
|
||||
auto min_children = function_arg_min_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);
|
||||
|
||||
argc = dist(engine);
|
||||
if (argc == 0)
|
||||
return;
|
||||
const auto& allowed_args_args = function_arg_allowed_map[to_underlying(type)];
|
||||
for (size_t i = 0; i < argc; i++)
|
||||
{
|
||||
// 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()};
|
||||
|
||||
argc = function_arg_max_map[to_underlying(type)];
|
||||
if (argc == 0)
|
||||
return;
|
||||
|
||||
const auto& allowed_args_args = function_arg_allowed_map[to_underlying(type)];
|
||||
for (size_t i = 0; i < argc; i++)
|
||||
populate_node(i, engine, allowed_args_args[i], use_terminals);
|
||||
|
@ -84,6 +93,13 @@ struct node
|
|||
if (use_terminal)
|
||||
{
|
||||
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);
|
||||
sub_nodes[i] = createNode(terminals[select(engine)]);
|
||||
} 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:
|
||||
explicit node(function_t type): type(type)
|
||||
{
|
||||
|
@ -119,13 +154,31 @@ struct node
|
|||
|
||||
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;
|
||||
std::mt19937_64 engine{dev()};
|
||||
std::uniform_real_distribution<float> dist(0.0f, 1.0f);
|
||||
node* n = createNode(static_cast<function_t>(select(engine)));
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -169,6 +222,17 @@ struct node
|
|||
evaluate();
|
||||
}
|
||||
|
||||
void printTree()
|
||||
{
|
||||
print_tree();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
bool hasImage()
|
||||
{
|
||||
return img.has_value();
|
||||
}
|
||||
|
||||
image& getImage()
|
||||
{
|
||||
return img.value();
|
||||
|
@ -226,13 +290,20 @@ void update(std::int32_t w, std::int32_t h)
|
|||
|
||||
BLT_INFO("Uploading");
|
||||
//delete texture;
|
||||
texture->upload((void*) root->getImage().getData().data(), GL_RGB, 0, 0, 0, -1, -1, GL_FLOAT);
|
||||
if (root->hasImage())
|
||||
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(file);
|
||||
//texture = new blt::gfx::texture_gl2D(file);
|
||||
resources.set("img", texture);
|
||||
}
|
||||
|
||||
if (ImGui::Button("Display"))
|
||||
{
|
||||
if (root)
|
||||
root->printTree();
|
||||
}
|
||||
|
||||
auto lw = 512.0f;
|
||||
auto lh = 512.0f;
|
||||
//renderer_2d.drawRectangle(blt::vec4{0.5, 0.0, 1.0, 1.0},
|
||||
|
|
Loading…
Reference in New Issue