parker is silly
parent
c49e42194d
commit
e927954d6a
|
@ -29,7 +29,7 @@
|
||||||
class force_equation
|
class force_equation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using node_pair = const std::pair<blt::size_t, node>&;
|
using node_pair = const std::pair<blt::size_t, node_t>&;
|
||||||
protected:
|
protected:
|
||||||
float cooling_rate = conf::DEFAULT_COOLING_FACTOR;
|
float cooling_rate = conf::DEFAULT_COOLING_FACTOR;
|
||||||
float min_cooling = conf::DEFAULT_MIN_COOLING;
|
float min_cooling = conf::DEFAULT_MIN_COOLING;
|
||||||
|
@ -53,7 +53,7 @@ class force_equation
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
[[nodiscard]] virtual blt::vec2 attr(node_pair v1, node_pair v2, const edge& edge) const = 0;
|
[[nodiscard]] virtual blt::vec2 attr(node_pair v1, node_pair v2, const edge_t& edge) const = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual blt::vec2 rep(node_pair v1, node_pair v2) const = 0;
|
[[nodiscard]] virtual blt::vec2 rep(node_pair v1, node_pair v2) const = 0;
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ class Eades_equation : public force_equation
|
||||||
protected:
|
protected:
|
||||||
float spring_constant = 12.0;
|
float spring_constant = 12.0;
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] blt::vec2 attr(node_pair v1, node_pair v2, const edge& edge) const final;
|
[[nodiscard]] blt::vec2 attr(node_pair v1, node_pair v2, const edge_t& edge) const final;
|
||||||
|
|
||||||
[[nodiscard]] blt::vec2 rep(node_pair v1, node_pair v2) const final;
|
[[nodiscard]] blt::vec2 rep(node_pair v1, node_pair v2) const final;
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ class Eades_equation : public force_equation
|
||||||
class Fruchterman_Reingold_equation : public force_equation
|
class Fruchterman_Reingold_equation : public force_equation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] blt::vec2 attr(node_pair v1, node_pair v2, const edge& edge) const final;
|
[[nodiscard]] blt::vec2 attr(node_pair v1, node_pair v2, const edge_t& edge) const final;
|
||||||
|
|
||||||
[[nodiscard]] blt::vec2 rep(node_pair v1, node_pair v2) const final;
|
[[nodiscard]] blt::vec2 rep(node_pair v1, node_pair v2) const final;
|
||||||
|
|
||||||
|
|
|
@ -54,9 +54,9 @@ class graph_t
|
||||||
{
|
{
|
||||||
friend struct loader_t;
|
friend struct loader_t;
|
||||||
private:
|
private:
|
||||||
std::vector<node> nodes;
|
std::vector<node_t> nodes;
|
||||||
blt::hashmap_t<std::string, blt::u64> names_to_node;
|
blt::hashmap_t<std::string, blt::u64> names_to_node;
|
||||||
blt::hashset_t<edge, edge_hash, edge_eq> edges;
|
blt::hashset_t<edge_t, edge_hash, edge_eq> edges;
|
||||||
blt::hashmap_t<blt::u64, blt::hashset_t<blt::u64>> connected_nodes;
|
blt::hashmap_t<blt::u64, blt::hashset_t<blt::u64>> connected_nodes;
|
||||||
bool sim = false;
|
bool sim = false;
|
||||||
bool run_infinitely = true;
|
bool run_infinitely = true;
|
||||||
|
@ -67,7 +67,10 @@ class graph_t
|
||||||
int max_iterations = 5000;
|
int max_iterations = 5000;
|
||||||
std::unique_ptr<force_equation> equation;
|
std::unique_ptr<force_equation> equation;
|
||||||
|
|
||||||
blt::i32 selected_node = -1;
|
blt::i64 last_selected_node = -1;
|
||||||
|
blt::i64 last_selected_node2 = -1;
|
||||||
|
bool is_edge = false;
|
||||||
|
|
||||||
blt::quad_easing easing;
|
blt::quad_easing easing;
|
||||||
blt::quint_easing highlight_easing;
|
blt::quint_easing highlight_easing;
|
||||||
|
|
||||||
|
@ -100,6 +103,7 @@ class graph_t
|
||||||
nodes.clear();
|
nodes.clear();
|
||||||
edges.clear();
|
edges.clear();
|
||||||
connected_nodes.clear();
|
connected_nodes.clear();
|
||||||
|
names_to_node.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void connect(const blt::u64 n1, const blt::u64 n2)
|
void connect(const blt::u64 n1, const blt::u64 n2)
|
||||||
|
@ -109,16 +113,16 @@ class graph_t
|
||||||
edges.insert({n1, n2});
|
edges.insert({n1, n2});
|
||||||
}
|
}
|
||||||
|
|
||||||
void connect(const edge& edge)
|
void connect(const edge_t& edge)
|
||||||
{
|
{
|
||||||
connected_nodes[edge.getFirst()].insert(edge.getSecond());
|
connected_nodes[edge.getFirst()].insert(edge.getSecond());
|
||||||
connected_nodes[edge.getSecond()].insert(edge.getFirst());
|
connected_nodes[edge.getSecond()].insert(edge.getFirst());
|
||||||
edges.insert(edge);
|
edges.insert(edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::optional<blt::ref<const edge>> connected(blt::u64 n1, blt::u64 n2) const
|
[[nodiscard]] std::optional<blt::ref<const edge_t>> connected(blt::u64 n1, blt::u64 n2) const
|
||||||
{
|
{
|
||||||
auto itr = edges.find(edge{n1, n2});
|
auto itr = edges.find(edge_t{n1, n2});
|
||||||
if (itr == edges.end())
|
if (itr == edges.end())
|
||||||
return {};
|
return {};
|
||||||
return *itr;
|
return *itr;
|
||||||
|
@ -126,15 +130,7 @@ class graph_t
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
void reset_mouse_drag()
|
void reset_mouse_drag();
|
||||||
{
|
|
||||||
if (selected_node != -1)
|
|
||||||
{
|
|
||||||
nodes[selected_node].outline_color = conf::POINT_OUTLINE_COLOR;
|
|
||||||
easing.reset();
|
|
||||||
}
|
|
||||||
selected_node = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset_mouse_highlight()
|
void reset_mouse_highlight()
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,10 +24,17 @@
|
||||||
#include <blt/std/assert.h>
|
#include <blt/std/assert.h>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
struct node
|
inline blt::size_t last_node = 0;
|
||||||
|
|
||||||
|
inline std::string get_name()
|
||||||
|
{
|
||||||
|
return "unnamed" + std::to_string(last_node++);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct node_t
|
||||||
{
|
{
|
||||||
float repulsiveness = 24.0f;
|
float repulsiveness = 24.0f;
|
||||||
std::string name = "unnamed";
|
std::string name;
|
||||||
std::string description;
|
std::string description;
|
||||||
std::string texture = conf::DEFAULT_IMAGE;
|
std::string texture = conf::DEFAULT_IMAGE;
|
||||||
|
|
||||||
|
@ -36,9 +43,14 @@ struct node
|
||||||
float outline_scale = 1.25f;
|
float outline_scale = 1.25f;
|
||||||
blt::color4 outline_color = conf::POINT_OUTLINE_COLOR;
|
blt::color4 outline_color = conf::POINT_OUTLINE_COLOR;
|
||||||
|
|
||||||
explicit node(const blt::gfx::point2d_t& point): point(point)
|
explicit node_t(const blt::gfx::point2d_t& point): name(get_name()), point(point)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
explicit node_t(const blt::gfx::point2d_t& point, std::string name): name(std::move(name)), point(point)
|
||||||
|
{
|
||||||
|
BLT_ASSERT(!this->name.empty() && "Name should not be empty!");
|
||||||
|
}
|
||||||
|
|
||||||
blt::vec2& getVelocityRef()
|
blt::vec2& getVelocityRef()
|
||||||
{
|
{
|
||||||
return velocity;
|
return velocity;
|
||||||
|
@ -61,19 +73,19 @@ struct node
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct edge
|
struct edge_t
|
||||||
{
|
{
|
||||||
float ideal_spring_length = conf::DEFAULT_SPRING_LENGTH;
|
float ideal_spring_length = conf::DEFAULT_SPRING_LENGTH;
|
||||||
float thickness = conf::DEFAULT_THICKNESS;
|
float thickness = conf::DEFAULT_THICKNESS;
|
||||||
blt::color4 color = conf::EDGE_COLOR;
|
blt::color4 color = conf::EDGE_COLOR;
|
||||||
std::string description;
|
std::string description;
|
||||||
|
|
||||||
edge(blt::u64 i1, blt::u64 i2): i1(i1), i2(i2)
|
edge_t(blt::u64 i1, blt::u64 i2): i1(i1), i2(i2)
|
||||||
{
|
{
|
||||||
BLT_ASSERT(i1 != i2 && "Indices cannot be equal!");
|
BLT_ASSERT(i1 != i2 && "Indices cannot be equal!");
|
||||||
}
|
}
|
||||||
|
|
||||||
inline friend bool operator==(edge e1, edge e2)
|
inline friend bool operator==(edge_t e1, edge_t e2)
|
||||||
{
|
{
|
||||||
return (e1.i1 == e2.i1 || e1.i1 == e2.i2) && (e1.i2 == e2.i1 || e1.i2 == e2.i2);
|
return (e1.i1 == e2.i1 || e1.i1 == e2.i2) && (e1.i2 == e2.i1 || e1.i2 == e2.i2);
|
||||||
}
|
}
|
||||||
|
@ -95,7 +107,7 @@ struct edge
|
||||||
|
|
||||||
struct edge_hash
|
struct edge_hash
|
||||||
{
|
{
|
||||||
blt::u64 operator()(const edge& e) const
|
blt::u64 operator()(const edge_t& e) const
|
||||||
{
|
{
|
||||||
return e.getFirst() * e.getSecond();
|
return e.getFirst() * e.getSecond();
|
||||||
}
|
}
|
||||||
|
@ -103,7 +115,7 @@ struct edge_hash
|
||||||
|
|
||||||
struct edge_eq
|
struct edge_eq
|
||||||
{
|
{
|
||||||
bool operator()(const edge& e1, const edge& e2) const
|
bool operator()(const edge_t& e1, const edge_t& e2) const
|
||||||
{
|
{
|
||||||
return e1 == e2;
|
return e1 == e2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ BLT_ATTRIB_NO_SIDE_EFFECTS inline float mix(const float v1, const float v2)
|
||||||
* --------------------------------------------------------
|
* --------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
force_equation::equation_data force_equation::calc_data(const std::pair<blt::size_t, node>& v1, const std::pair<blt::size_t, node>& v2)
|
force_equation::equation_data force_equation::calc_data(const std::pair<blt::size_t, node_t>& v1, const std::pair<blt::size_t, node_t>& v2)
|
||||||
{
|
{
|
||||||
auto dir = dir_v(v1, v2);
|
auto dir = dir_v(v1, v2);
|
||||||
auto dir2 = dir_v(v2, v1);
|
auto dir2 = dir_v(v2, v1);
|
||||||
|
@ -57,13 +57,13 @@ void force_equation::draw_inputs_base()
|
||||||
* --------------------------------------------------------
|
* --------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
blt::vec2 Eades_equation::attr(const std::pair<blt::size_t, node>& v1, const std::pair<blt::size_t, node>& v2, const edge& edge) const
|
blt::vec2 Eades_equation::attr(const std::pair<blt::size_t, node_t>& v1, const std::pair<blt::size_t, node_t>& v2, const edge_t& edge) const
|
||||||
{
|
{
|
||||||
auto data = calc_data(v1, v2);
|
auto data = calc_data(v1, v2);
|
||||||
return (spring_constant * std::log(data.mag / edge.ideal_spring_length) * data.unit) - rep(v1, v2);
|
return (spring_constant * std::log(data.mag / edge.ideal_spring_length) * data.unit) - rep(v1, v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
blt::vec2 Eades_equation::rep(const std::pair<blt::size_t, node>& v1, const std::pair<blt::size_t, node>& v2) const
|
blt::vec2 Eades_equation::rep(const std::pair<blt::size_t, node_t>& v1, const std::pair<blt::size_t, node_t>& v2) const
|
||||||
{
|
{
|
||||||
auto data = calc_data(v1, v2);
|
auto data = calc_data(v1, v2);
|
||||||
// scaling factor included because of the scales this algorithm is working on (large viewport)
|
// scaling factor included because of the scales this algorithm is working on (large viewport)
|
||||||
|
@ -83,14 +83,14 @@ void Eades_equation::draw_inputs()
|
||||||
* --------------------------------------------------------
|
* --------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
blt::vec2 Fruchterman_Reingold_equation::attr(const std::pair<blt::size_t, node>& v1, const std::pair<blt::size_t, node>& v2, const edge& edge) const
|
blt::vec2 Fruchterman_Reingold_equation::attr(const std::pair<blt::size_t, node_t>& v1, const std::pair<blt::size_t, node_t>& v2, const edge_t& edge) const
|
||||||
{
|
{
|
||||||
auto data = calc_data(v1, v2);
|
auto data = calc_data(v1, v2);
|
||||||
float scale = data.mag_sq / edge.ideal_spring_length;
|
float scale = data.mag_sq / edge.ideal_spring_length;
|
||||||
return (scale * data.unit);
|
return (scale * data.unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
blt::vec2 Fruchterman_Reingold_equation::rep(const std::pair<blt::size_t, node>& v1, const std::pair<blt::size_t, node>& v2) const
|
blt::vec2 Fruchterman_Reingold_equation::rep(const std::pair<blt::size_t, node_t>& v1, const std::pair<blt::size_t, node_t>& v2) const
|
||||||
{
|
{
|
||||||
auto data = calc_data(v1, v2);
|
auto data = calc_data(v1, v2);
|
||||||
const auto ideal_spring_length = conf::DEFAULT_SPRING_LENGTH;
|
const auto ideal_spring_length = conf::DEFAULT_SPRING_LENGTH;
|
||||||
|
|
|
@ -83,13 +83,14 @@ void graph_t::render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// called every frame as long as imgui doesn't require the mouse.
|
||||||
void graph_t::process_mouse_drag(const blt::i32 width, const blt::i32 height)
|
void graph_t::process_mouse_drag(const blt::i32 width, const blt::i32 height)
|
||||||
{
|
{
|
||||||
const auto mouse_pos = blt::make_vec2(blt::gfx::calculateRay2D(width, height, global_matrices.getScale2D(), global_matrices.getView2D(),
|
const auto mouse_pos = blt::make_vec2(blt::gfx::calculateRay2D(width, height, global_matrices.getScale2D(), global_matrices.getView2D(),
|
||||||
global_matrices.getOrtho()));
|
global_matrices.getOrtho()));
|
||||||
|
|
||||||
bool mouse_pressed = blt::gfx::isMousePressed(0);
|
bool mouse_pressed = blt::gfx::isMousePressed(0);
|
||||||
blt::i32 new_selection = -1;
|
blt::i64 new_selection = -1;
|
||||||
|
|
||||||
for (const auto& [index, node] : blt::enumerate(nodes))
|
for (const auto& [index, node] : blt::enumerate(nodes))
|
||||||
{
|
{
|
||||||
|
@ -98,34 +99,34 @@ void graph_t::process_mouse_drag(const blt::i32 width, const blt::i32 height)
|
||||||
|
|
||||||
const auto mag = dist.magnitude();
|
const auto mag = dist.magnitude();
|
||||||
|
|
||||||
if (mag < conf::POINT_SIZE && mouse_pressed)
|
if (mag < node.getRenderObj().scale && mouse_pressed)
|
||||||
{
|
{
|
||||||
new_selection = static_cast<blt::i32>(index);
|
new_selection = static_cast<blt::i64>(index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_selection != selected_node)
|
if (new_selection != last_selected_node)
|
||||||
{
|
{
|
||||||
if (selected_node != -1)
|
if (last_selected_node != -1)
|
||||||
nodes[selected_node].outline_color = conf::POINT_OUTLINE_COLOR;
|
nodes[last_selected_node].outline_color = conf::POINT_OUTLINE_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mouse_pressed && new_selection == -1 && selected_node != -1)
|
if (mouse_pressed && new_selection == -1 && last_selected_node != -1)
|
||||||
{
|
{
|
||||||
selected_node = -1;
|
last_selected_node = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
selected_node = new_selection;
|
last_selected_node = new_selection;
|
||||||
|
|
||||||
if (!mouse_pressed && blt::gfx::mouseReleaseLastFrame())
|
if (!mouse_pressed && blt::gfx::mouseReleaseLastFrame())
|
||||||
{
|
{
|
||||||
reset_mouse_drag();
|
reset_mouse_drag();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected_node != -1 && mouse_pressed)
|
if (last_selected_node != -1 && mouse_pressed)
|
||||||
{
|
{
|
||||||
auto& node = nodes[selected_node];
|
auto& node = nodes[last_selected_node];
|
||||||
easing.progress(8 * static_cast<float>(blt::gfx::getFrameDeltaSeconds()));
|
easing.progress(8 * static_cast<float>(blt::gfx::getFrameDeltaSeconds()));
|
||||||
node.outline_color = conf::POINT_SELECT_COLOR;
|
node.outline_color = conf::POINT_SELECT_COLOR;
|
||||||
node.getPositionRef() = mouse_pos;
|
node.getPositionRef() = mouse_pos;
|
||||||
|
@ -177,7 +178,8 @@ void graph_t::create_random_graph(bounding_box bb, const blt::size_t min_nodes,
|
||||||
if (can_break)
|
if (can_break)
|
||||||
break;
|
break;
|
||||||
} while (true);
|
} while (true);
|
||||||
nodes.push_back(node({x, y, conf::POINT_SIZE}));
|
nodes.push_back(node_t({x, y, conf::POINT_SIZE}));
|
||||||
|
names_to_node.insert({nodes.back().name, nodes.size() - 1});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& [index1, node1] : blt::enumerate(nodes))
|
for (const auto& [index1, node1] : blt::enumerate(nodes))
|
||||||
|
@ -219,10 +221,22 @@ void graph_t::create_random_graph(bounding_box bb, const blt::size_t min_nodes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void graph_t::reset_mouse_drag()
|
||||||
|
{
|
||||||
|
if (last_selected_node != -1)
|
||||||
|
{
|
||||||
|
nodes[last_selected_node].outline_color = conf::POINT_OUTLINE_COLOR;
|
||||||
|
easing.reset();
|
||||||
|
}
|
||||||
|
last_selected_node = -1;
|
||||||
|
}
|
||||||
|
|
||||||
void engine_t::draw_gui(const blt::gfx::window_data& data)
|
void engine_t::draw_gui(const blt::gfx::window_data& data)
|
||||||
{
|
{
|
||||||
double ft = blt::gfx::getFrameDeltaSeconds();
|
double ft = blt::gfx::getFrameDeltaSeconds();
|
||||||
if (im::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
|
im::SetNextWindowPos({0, 0}, ImGuiCond_Always);
|
||||||
|
im::SetNextWindowSize({350, static_cast<float>(data.height)});
|
||||||
|
if (im::Begin("Info", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
|
||||||
{
|
{
|
||||||
static int min_nodes = 5;
|
static int min_nodes = 5;
|
||||||
static int max_nodes = 25;
|
static int max_nodes = 25;
|
||||||
|
@ -235,7 +249,6 @@ void engine_t::draw_gui(const blt::gfx::window_data& data)
|
||||||
|
|
||||||
//im::SetNextItemOpen(true, ImGuiCond_Once);
|
//im::SetNextItemOpen(true, ImGuiCond_Once);
|
||||||
im::Text("FPS: %lf Frame-time (ms): %lf Frame-time (S): %lf", 1.0 / ft, ft * 1000.0, ft);
|
im::Text("FPS: %lf Frame-time (ms): %lf Frame-time (S): %lf", 1.0 / ft, ft * 1000.0, ft);
|
||||||
im::Text("Number of Nodes: %d", graph.numberOfNodes());
|
|
||||||
im::SetNextItemOpen(true, ImGuiCond_Once);
|
im::SetNextItemOpen(true, ImGuiCond_Once);
|
||||||
if (im::CollapsingHeader("Help"))
|
if (im::CollapsingHeader("Help"))
|
||||||
{
|
{
|
||||||
|
@ -244,6 +257,7 @@ void engine_t::draw_gui(const blt::gfx::window_data& data)
|
||||||
}
|
}
|
||||||
if (im::CollapsingHeader("Graph Generation Settings"))
|
if (im::CollapsingHeader("Graph Generation Settings"))
|
||||||
{
|
{
|
||||||
|
im::Text("Current number of Nodes: %d", graph.numberOfNodes());
|
||||||
im::Checkbox("Screen Auto-Scale", &bb.is_screen);
|
im::Checkbox("Screen Auto-Scale", &bb.is_screen);
|
||||||
if (im::CollapsingHeader("Spawning Area"))
|
if (im::CollapsingHeader("Spawning Area"))
|
||||||
{
|
{
|
||||||
|
@ -273,7 +287,6 @@ void engine_t::draw_gui(const blt::gfx::window_data& data)
|
||||||
graph.reset(bb, min_nodes, max_nodes, connectivity, scaling_connectivity, distance_factor);
|
graph.reset(bb, min_nodes, max_nodes, connectivity, scaling_connectivity, distance_factor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
im::SetNextItemOpen(true, ImGuiCond_Once);
|
|
||||||
if (im::CollapsingHeader("Simulation Settings"))
|
if (im::CollapsingHeader("Simulation Settings"))
|
||||||
{
|
{
|
||||||
im::InputInt("Max Iterations", &graph.getMaxIterations());
|
im::InputInt("Max Iterations", &graph.getMaxIterations());
|
||||||
|
@ -318,6 +331,11 @@ void engine_t::draw_gui(const blt::gfx::window_data& data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
im::SetNextItemOpen(true, ImGuiCond_Once);
|
||||||
|
if (im::CollapsingHeader("Node Information"))
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
im::End();
|
im::End();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#include <loader.h>
|
#include <loader.h>
|
||||||
#include <blt/std/logging.h>
|
#include <blt/std/logging.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <istream>
|
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
@ -70,12 +69,12 @@ std::optional<loader_t> loader_t::load_for(engine_t& engine, const blt::gfx::win
|
||||||
auto x = static_cast<blt::f32>(load_with_default(node, "x", pos_x_dist(dev)));
|
auto x = static_cast<blt::f32>(load_with_default(node, "x", pos_x_dist(dev)));
|
||||||
auto y = static_cast<blt::f32>(load_with_default(node, "y", pos_y_dist(dev)));
|
auto y = static_cast<blt::f32>(load_with_default(node, "y", pos_y_dist(dev)));
|
||||||
auto size = static_cast<blt::f32>(load_with_default(node, "size", static_cast<blt::f64>(conf::POINT_SIZE)));
|
auto size = static_cast<blt::f32>(load_with_default(node, "size", static_cast<blt::f64>(conf::POINT_SIZE)));
|
||||||
auto name = load_with_default<std::string>(node, "name", "unnamed");
|
auto name = load_with_default<std::string>(node, "name", get_name());
|
||||||
auto texture = load_with_default<std::string>(node, "texture", conf::DEFAULT_IMAGE);
|
auto texture = load_with_default<std::string>(node, "texture", conf::DEFAULT_IMAGE);
|
||||||
|
|
||||||
|
BLT_ASSERT(!graph.names_to_node.contains(name) && "Graph node name must be unique!");
|
||||||
graph.names_to_node.insert({name, static_cast<blt::u64>(graph.nodes.size())});
|
graph.names_to_node.insert({name, static_cast<blt::u64>(graph.nodes.size())});
|
||||||
graph.nodes.emplace_back(blt::gfx::point2d_t{x, y, size});
|
graph.nodes.emplace_back(blt::gfx::point2d_t{x, y, size}, std::move(name));
|
||||||
graph.nodes.back().name = std::move(name);
|
|
||||||
graph.nodes.back().texture = std::move(texture);
|
graph.nodes.back().texture = std::move(texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +98,7 @@ std::optional<loader_t> loader_t::load_for(engine_t& engine, const blt::gfx::win
|
||||||
auto ideal_length = load_with_default(edge, "length", conf::DEFAULT_SPRING_LENGTH);
|
auto ideal_length = load_with_default(edge, "length", conf::DEFAULT_SPRING_LENGTH);
|
||||||
auto thickness = load_with_default(edge, "thickness", conf::DEFAULT_THICKNESS);
|
auto thickness = load_with_default(edge, "thickness", conf::DEFAULT_THICKNESS);
|
||||||
|
|
||||||
::edge e{graph.names_to_node[index1], graph.names_to_node[index2]};
|
::edge_t e{graph.names_to_node[index1], graph.names_to_node[index2]};
|
||||||
e.ideal_spring_length = ideal_length;
|
e.ideal_spring_length = ideal_length;
|
||||||
e.thickness = thickness;
|
e.thickness = thickness;
|
||||||
|
|
||||||
|
@ -113,6 +112,8 @@ std::optional<loader_t> loader_t::load_for(engine_t& engine, const blt::gfx::win
|
||||||
{
|
{
|
||||||
if (auto node = graph.names_to_node.find(desc["name"].get<std::string>()); node != graph.names_to_node.end())
|
if (auto node = graph.names_to_node.find(desc["name"].get<std::string>()); node != graph.names_to_node.end())
|
||||||
graph.nodes[node->second].description = desc["description"];
|
graph.nodes[node->second].description = desc["description"];
|
||||||
|
else
|
||||||
|
BLT_WARN("Node %s doesn't exist!", desc["name"].get<std::string>().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,14 +123,15 @@ std::optional<loader_t> loader_t::load_for(engine_t& engine, const blt::gfx::win
|
||||||
{
|
{
|
||||||
auto nodes = desc["nodes"];
|
auto nodes = desc["nodes"];
|
||||||
auto n1 = graph.names_to_node[nodes[0].get<std::string>()];
|
auto n1 = graph.names_to_node[nodes[0].get<std::string>()];
|
||||||
auto n2 = graph.names_to_node[nodes[2].get<std::string>()];
|
auto n2 = graph.names_to_node[nodes[1].get<std::string>()];
|
||||||
if (auto node = graph.edges.find({n1, n2}); node != graph.edges.end())
|
if (auto node = graph.edges.find({n1, n2}); node != graph.edges.end())
|
||||||
{
|
{
|
||||||
edge e = *node;
|
edge_t e = *node;
|
||||||
e.description = desc["description"];
|
e.description = desc["description"];
|
||||||
graph.edges.erase({n1, n2});
|
graph.edges.erase({n1, n2});
|
||||||
graph.edges.insert(e);
|
graph.edges.insert(e);
|
||||||
}
|
} else
|
||||||
|
BLT_WARN("Edge %s -> %s doesn't exist!", nodes[0].get<std::string>().c_str(), nodes[1].get<std::string>().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,5 +140,50 @@ std::optional<loader_t> loader_t::load_for(engine_t& engine, const blt::gfx::win
|
||||||
|
|
||||||
void loader_t::save_for(engine_t& engine, const loader_t& loader, std::string_view path)
|
void loader_t::save_for(engine_t& engine, const loader_t& loader, std::string_view path)
|
||||||
{
|
{
|
||||||
|
auto& graph = engine.graph;
|
||||||
|
json data;
|
||||||
|
data["textures"] = json::array();
|
||||||
|
data["nodes"] = json::array();
|
||||||
|
data["edges"] = json::array();
|
||||||
|
data["descriptions"] = json::array();
|
||||||
|
data["relationships"] = json::array();
|
||||||
|
|
||||||
|
for (const auto& [key, t_path] : loader.textures)
|
||||||
|
{
|
||||||
|
data["textures"].push_back(json{
|
||||||
|
{"name", key},
|
||||||
|
{"path", t_path}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& node : graph.nodes)
|
||||||
|
{
|
||||||
|
data["nodes"].push_back(json{
|
||||||
|
{"name", node.name},
|
||||||
|
{"texture", node.texture},
|
||||||
|
{"size", node.getRenderObj().scale},
|
||||||
|
{"x", node.getPosition().x()},
|
||||||
|
{"y", node.getPosition().y()},
|
||||||
|
});
|
||||||
|
data["descriptions"].push_back(json{
|
||||||
|
{"name", node.name},
|
||||||
|
{"description", node.description}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& edge : graph.edges)
|
||||||
|
{
|
||||||
|
data["edges"].push_back(json{
|
||||||
|
{"nodes", json::array_t{graph.nodes[edge.getFirst()].name, graph.nodes[edge.getSecond()].name}},
|
||||||
|
{"length", edge.ideal_spring_length},
|
||||||
|
{"thickness", edge.thickness}
|
||||||
|
});
|
||||||
|
data["relationships"].push_back(json{
|
||||||
|
{"nodes", json::array_t{graph.nodes[edge.getFirst()].name, graph.nodes[edge.getSecond()].name}},
|
||||||
|
{"description", edge.description}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ofstream file{std::string(path)};
|
||||||
|
file << data.dump(4);
|
||||||
}
|
}
|
|
@ -60,13 +60,12 @@ void init(const blt::gfx::window_data& data)
|
||||||
loader_data = *loader;
|
loader_data = *loader;
|
||||||
for (const auto& [key, path] : loader_data.textures)
|
for (const auto& [key, path] : loader_data.textures)
|
||||||
resources.enqueue(path, key);
|
resources.enqueue(path, key);
|
||||||
}
|
} else
|
||||||
|
engine.init(data);
|
||||||
|
|
||||||
global_matrices.create_internals();
|
global_matrices.create_internals();
|
||||||
resources.load_resources();
|
resources.load_resources();
|
||||||
renderer_2d.create();
|
renderer_2d.create();
|
||||||
|
|
||||||
engine.init(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(const blt::gfx::window_data& data)
|
void update(const blt::gfx::window_data& data)
|
||||||
|
|
Loading…
Reference in New Issue