polar snapping now very goood!
This commit is contained in:
+81
-61
@@ -1,14 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "button.h"
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
|
||||
#include "button.h"
|
||||
#include "graph-item.h"
|
||||
#include "midi-node.h"
|
||||
#include "node.h"
|
||||
#include "edge.h"
|
||||
#include "raymath.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -22,24 +26,26 @@ class GraphManager{
|
||||
|
||||
GraphManager() {}
|
||||
|
||||
std::vector<std::shared_ptr<Node>> nodes;
|
||||
std::vector<std::shared_ptr<Edge>> edges;
|
||||
VEC_SPTR_Node nodes;
|
||||
VEC_SPTR_Edge edges;
|
||||
|
||||
std::map<std::shared_ptr<Node>, int> counter;
|
||||
VEC_SPTR_Edge remove_edges;
|
||||
|
||||
std::shared_ptr<Node> getRandomNode(){
|
||||
std::vector<std::shared_ptr<GraphItem>> o;
|
||||
std::map<SPTR_Node, int> counter;
|
||||
|
||||
SPTR_Node getRandomNode(){
|
||||
VEC_SPTR_GraphItem o;
|
||||
std::ranges::sample(nodes, std::back_inserter(o), 1, std::mt19937{std::random_device{}()});
|
||||
return std::dynamic_pointer_cast<Node>(o.front());
|
||||
}
|
||||
|
||||
std::shared_ptr<Edge> getRandomEdge(){
|
||||
std::vector<std::shared_ptr<GraphItem>> o;
|
||||
SPTR_Edge getRandomEdge(){
|
||||
VEC_SPTR_GraphItem o;
|
||||
std::ranges::sample(edges, std::back_inserter(o), 1, std::mt19937{std::random_device{}()});
|
||||
return std::dynamic_pointer_cast<Edge>(o.front());
|
||||
}
|
||||
|
||||
void copyNodes(std::vector<std::shared_ptr<Node>> nodes, Vec2D<float> position){
|
||||
void copyNodes(VEC_SPTR_Node nodes, Vec2D<float> position){
|
||||
for(auto n: nodes){
|
||||
auto nc = std::make_shared<Node>(*n);
|
||||
nc->position = position + nc->drag_offset;
|
||||
@@ -57,7 +63,7 @@ class GraphManager{
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Node> copyNode(std::shared_ptr<Node> n, Vec2D<float> position){
|
||||
SPTR_Node copyNode(SPTR_Node n, Vec2D<float> position){
|
||||
auto nc = std::make_shared<Node>(*n);
|
||||
nc->setPosition(position);
|
||||
nodes.push_back(nc);
|
||||
@@ -70,17 +76,8 @@ class GraphManager{
|
||||
nodes.push_back(nc);
|
||||
return nc;
|
||||
}
|
||||
|
||||
/*std::shared_ptr<Node> addNode(float x, float y){*/
|
||||
/* return addNode(Vec2D<float>(x,y));*/
|
||||
/*}*/
|
||||
/**/
|
||||
/*std::shared_ptr<Node> addNode(Vec2D<float> position){*/
|
||||
/* nodes.emplace_back(std::make_shared<Node>(position));*/
|
||||
/* return nodes.back();*/
|
||||
/*}*/
|
||||
|
||||
std::shared_ptr<Node> addMidiNode(Vec2D<float> position){
|
||||
|
||||
SPTR_Node addMidiNode(Vec2D<float> position){
|
||||
nodes.emplace_back(std::make_shared<MidiNode>(position));
|
||||
return nodes.back();
|
||||
}
|
||||
@@ -95,12 +92,12 @@ class GraphManager{
|
||||
counter.clear();
|
||||
}
|
||||
|
||||
std::shared_ptr<Node> next(std::shared_ptr<Node> current, std::shared_ptr<Node> last){
|
||||
std::vector<std::shared_ptr<Edge>> possible_connections = current->connections | std::ranges::views::filter([current](std::shared_ptr<Edge> c){
|
||||
SPTR_Node next(SPTR_Node current, SPTR_Node last){
|
||||
VEC_SPTR_Edge possible_connections = current->connections | RANGE_FILTER([current](SPTR_Edge c){
|
||||
return (c->start == current && c->pass_forward) || (c->end == current && c->pass_backward);
|
||||
}) | std::ranges::to<std::vector<std::shared_ptr<Edge>>>();
|
||||
}) | std::ranges::to<VEC_SPTR_Edge>();
|
||||
|
||||
if(possible_connections.empty()) return std::shared_ptr<Node>(nullptr);
|
||||
if(possible_connections.empty()) return SPTR_Node(nullptr);
|
||||
|
||||
int return_path = 0;
|
||||
float angle = -1;
|
||||
@@ -108,7 +105,7 @@ class GraphManager{
|
||||
Vec2D<float> coming_from = (current->position - last->position).norm();
|
||||
int i = 0;
|
||||
for(auto n : possible_connections){
|
||||
std::shared_ptr<Node> next_node = n->getNextNode(current);
|
||||
SPTR_Node next_node = n->getNextNode(current);
|
||||
float angle_v1_v2 = coming_from.norm().dot((next_node->position - current->position).norm());
|
||||
if(angle_v1_v2 > angle) {
|
||||
return_path = i;
|
||||
@@ -131,11 +128,11 @@ class GraphManager{
|
||||
return_path = rand() % possible_connections.size();
|
||||
}
|
||||
|
||||
possible_connections.at(return_path)->active = true;
|
||||
//possible_connections.at(return_path)->active = true;
|
||||
return possible_connections.at(return_path)->getNextNode(current);
|
||||
}
|
||||
|
||||
void addConnection(std::shared_ptr<Node> from, std::shared_ptr<Node> to){
|
||||
void addConnection(SPTR_Node from, SPTR_Node to){
|
||||
edges.emplace_back(std::make_shared<Edge>());
|
||||
edges.back()->start = from;
|
||||
edges.back()->end = to;
|
||||
@@ -143,8 +140,25 @@ class GraphManager{
|
||||
to->connections.push_back(edges.back());
|
||||
}
|
||||
|
||||
void splitEdge(SPTR_Edge edge){
|
||||
|
||||
}
|
||||
|
||||
void removeEdge(SPTR_Edge edge){
|
||||
remove_edges.push_back(edge);
|
||||
}
|
||||
|
||||
void removeEdges(){
|
||||
for(auto edge : remove_edges){
|
||||
std::erase(edge->start->connections, edge);
|
||||
std::erase(edge->end->connections, edge);
|
||||
std::erase(edges, edge);
|
||||
}
|
||||
}
|
||||
|
||||
void drawEdges(Vec2D<float> mouse_pos, Camera2D cam){
|
||||
// std::erase_if(connections, [](Connection c){ return c.remove == true;});
|
||||
if(!remove_edges.empty()) removeEdges();
|
||||
for(auto& c : edges){
|
||||
Vec2D<float> v1_position = c->start->position - ((c->start->position - c->end->position)).norm() * (c->start->radius + c->connector_offset);
|
||||
Vec2D<float> v2_position = c->end->position - ((c->end->position - c->start->position)).norm() * (c->end->radius + c->connector_offset);
|
||||
@@ -178,56 +192,62 @@ class GraphManager{
|
||||
unsigned char opacity = 150.0f - Clamp(middle_handle.dist(mouse_pos), 0.0f, 150.0f);
|
||||
unsigned char opacity_from = 250.0f - Clamp(from_to_handle.dist(mouse_pos), 0.0f, 220.0f);
|
||||
unsigned char opacity_to = 250.0f - Clamp(to_from_handle.dist(mouse_pos), 0.0f, 220.0f);
|
||||
|
||||
// On/Off switches on both sides
|
||||
if(ViButton(mouse_pos, from_to_handle.x, from_to_handle.y, 8.0f, c->pass_forward ? (Color){120, 210, 115, opacity_from} : (Color){232, 50, 32, opacity_from} )) c->pass_forward = !c->pass_forward;
|
||||
if(ViButton(mouse_pos, to_from_handle.x, to_from_handle.y, 8.0f, c->pass_backward ? (Color){120, 210, 115, opacity_to} : (Color){232, 50, 32, opacity_to} )) c->pass_backward = !c->pass_backward;
|
||||
|
||||
if(!c->start->dragging && !c->end->dragging){
|
||||
// On/Off switches on both sides
|
||||
if(ViButton(mouse_pos, from_to_handle.x, from_to_handle.y, 8.0f, c->pass_forward ? (Color){120, 210, 115, opacity_from} : (Color){232, 50, 32, opacity_from} )) c->pass_forward = !c->pass_forward;
|
||||
if(ViButton(mouse_pos, to_from_handle.x, to_from_handle.y, 8.0f, c->pass_backward ? (Color){120, 210, 115, opacity_to} : (Color){232, 50, 32, opacity_to} )) c->pass_backward = !c->pass_backward;
|
||||
|
||||
if(!c->pass_forward){
|
||||
Vec2D<float> block_point1 = (v1_position - v2_position).norm().orth()*4.0f + from_to_handle;
|
||||
Vec2D<float> block_point2 = (v1_position - v2_position).norm().orth()*-4.0f + from_to_handle;
|
||||
DrawLineEx(block_point1, block_point2, 2.0f, (Color){232,232,232,opacity_from});
|
||||
}
|
||||
|
||||
if(!c->pass_backward){
|
||||
Vec2D<float> block_point1 = (v1_position - v2_position).norm().orth()*4.0f + to_from_handle;
|
||||
Vec2D<float> block_point2 = (v1_position - v2_position).norm().orth()*-4.0f + to_from_handle;
|
||||
DrawLineEx(block_point1, block_point2, 2.0f, (Color){232,232,232,opacity_to});
|
||||
}
|
||||
|
||||
if(!c->pass_forward){
|
||||
Vec2D<float> block_point1 = (v1_position - v2_position).norm().orth()*4.0f + from_to_handle;
|
||||
Vec2D<float> block_point2 = (v1_position - v2_position).norm().orth()*-4.0f + from_to_handle;
|
||||
DrawLineEx(block_point1, block_point2, 2.0f, (Color){232,232,232,opacity_from});
|
||||
}
|
||||
|
||||
if(!c->pass_backward){
|
||||
Vec2D<float> block_point1 = (v1_position - v2_position).norm().orth()*4.0f + to_from_handle;
|
||||
Vec2D<float> block_point2 = (v1_position - v2_position).norm().orth()*-4.0f + to_from_handle;
|
||||
DrawLineEx(block_point1, block_point2, 2.0f, (Color){232,232,232,opacity_to});
|
||||
}
|
||||
|
||||
|
||||
if(ViButton(mouse_pos, flip_handle.x, flip_handle.y, 8.0f, (Color){232, 50, 32, opacity} )) c->remove = true;
|
||||
if(ViButton(mouse_pos, flip_handle_2.x, flip_handle_2.y, 8.0f, (Color){232, 50, 32, opacity} )) c->split = true;
|
||||
if(ViButton(mouse_pos, flip_handle.x, flip_handle.y, 8.0f, (Color){232, 50, 32, opacity} )) removeEdge(c);
|
||||
if(ViButton(mouse_pos, flip_handle_2.x, flip_handle_2.y, 8.0f, (Color){232, 125, 62, opacity} )) splitEdge(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawNodes(Vec2D<float> mouse_pos, Camera2D camera){
|
||||
auto neighbors = nodes | std::ranges::views::filter([](std::shared_ptr<Node> n){ return !n->dragging && !n->selected;}) | std::ranges::to<std::vector<std::shared_ptr<Node>>>();
|
||||
auto neighbors = nodes | RANGE_FILTER([](SPTR_Node n){ return !n->dragging && !n->selected;}) | std::ranges::to<VEC_SPTR_Node>();
|
||||
float min_d = 480;
|
||||
for(auto n : nodes){
|
||||
if(n->dragging){
|
||||
std::sort(neighbors.begin(), neighbors.end(), [n](std::shared_ptr<Node> na, std::shared_ptr<Node> nb){ return na->position.dist(n->position) < nb->position.dist(n->position);});
|
||||
std::sort(neighbors.begin(), neighbors.end(), [n, mouse_pos](SPTR_Node na, SPTR_Node nb){ return na->position.dist(mouse_pos) < nb->position.dist(mouse_pos);});
|
||||
if(neighbors.size() > 1){
|
||||
min_d = neighbors.front()->position.dist(n->position);
|
||||
n->neighbor = neighbors.at(1);
|
||||
int i = 0;
|
||||
min_d = neighbors.front()->position.dist(mouse_pos);
|
||||
n->neighbor = neighbors.front();
|
||||
DrawCircleLinesV(n->neighbor->position, 20.0f, VS_COLOR_PINK);
|
||||
for(auto nb : neighbors){
|
||||
float d = nb->position.dist(n->position);
|
||||
float d = nb->position.dist(mouse_pos);
|
||||
float dn = nb->position.dist(n->position);
|
||||
if(d > 0 && d < min_d*1.5 && d < 960) {
|
||||
std::string frac = MIDI::Fractions.at((int)Clamp(round(d/60) - 1, 0, 31));
|
||||
Vector2 text_length = MeasureTextEx(GetFontDefault(), std::format("{:.1f}",d).c_str(), 10.0f, 2.0f);
|
||||
std::string frac = MIDI::Fractions.at((int)Clamp(round(dn/60) - 1, 0, 31));
|
||||
Vector2 text_length = MeasureTextEx(GetFontDefault(), std::format("{:.1f}",dn).c_str(), 10.0f, 2.0f);
|
||||
Vector2 text_length_frac = MeasureTextEx(GetFontDefault(), frac.c_str(), 10.0f, 2.0f);
|
||||
|
||||
Vec2D<float> middle_handle = nb->position + (n->position - nb->position) * ((d - text_length.x)*0.5f)/d;
|
||||
Vec2D<float> middle_handle_frac = nb->position + (n->position - nb->position) * ((d - text_length_frac.x)*0.5f)/d;
|
||||
Vec2D<float> middle_handle = nb->position + (n->position - nb->position) * ((dn - text_length.x)*0.5f)/dn;
|
||||
Vec2D<float> middle_handle_frac = nb->position + (n->position - nb->position) * ((dn - text_length_frac.x)*0.5f)/dn;
|
||||
Vec2D<float> text_position = middle_handle + (nb->position - n->position).norm().orth() * 12.0f;
|
||||
Vec2D<float> text_position_frac = middle_handle_frac - (nb->position - n->position).norm().orth() * 4.0f;
|
||||
|
||||
float rotation = Vector2Angle((Vector2){1,0}, (n->position - nb->position)) * RAD2DEG;
|
||||
DrawTextPro(GetFontDefault(), std::format("{:.1f}",d).c_str(), text_position, (Vector2){0,0}, rotation, 10.0f, 2.0f, VS_COLOR_PINK);
|
||||
if(i == 0 && IsKeyDown(KEY_LEFT_SHIFT)) DrawTextPro(GetFontDefault(), frac.c_str(), text_position_frac, (Vector2){0,0}, rotation, 10.0f, 2.0f, VS_COLOR_PINK);
|
||||
DrawLineV(n->position, nb->position, VS_COLOR_PINK);
|
||||
DrawTextPro(GetFontDefault(), std::format("{:.1f}",dn).c_str(), text_position, (Vector2){0,0}, rotation, 10.0f, 2.0f, VS_COLOR_PINK);
|
||||
if(nb == neighbors.front() && IsKeyDown(KEY_LEFT_SHIFT)) DrawTextPro(GetFontDefault(), frac.c_str(), text_position_frac, (Vector2){0,0}, rotation, 10.0f, 2.0f, VS_COLOR_PINK);
|
||||
Vec2D<float> n_position = n->position - ((n->position - nb->position)).norm() * 20.0f;
|
||||
Vec2D<float> nb_position = nb->position - ((nb->position - n->position)).norm() * 20.0f;
|
||||
DrawLineV(n_position, nb_position, VS_COLOR_PINK);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user