im scared now
This commit is contained in:
parent
68d06aa660
commit
2438b8b89d
12 changed files with 190 additions and 164 deletions
|
@ -16,7 +16,7 @@ add_executable (Keishiki ${IMGUI_SRC} ${IMPLOT_SRC}
|
||||||
|
|
||||||
set_property(TARGET Keishiki PROPERTY CXX_STANDARD 23)
|
set_property(TARGET Keishiki PROPERTY CXX_STANDARD 23)
|
||||||
|
|
||||||
include_directories ("include" "include/ext" "ext/imgui" "ext/implot")
|
include_directories ("include" "include/ext" "ext/imgui" "ext/implot" "ext/plf_colony")
|
||||||
|
|
||||||
add_subdirectory("ext/freetype")
|
add_subdirectory("ext/freetype")
|
||||||
add_subdirectory("ext/bgfx")
|
add_subdirectory("ext/bgfx")
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
namespace K::Plugboard {
|
namespace K::Plugboard {
|
||||||
bool DetectCycle(const NodeInstanceP n, Vector<NodeInstanceP> nodes) { // true if cycle found
|
bool DetectCycle(const NodeInstanceP n, Vector<NodeInstanceP> nodes) { // true if cycle found
|
||||||
return !DFS(n, [&nodes](ConnectInfo info){
|
return !DFS(n, [&nodes](ConnectInfo info){
|
||||||
if (std::find(nodes.begin(), nodes.end(), info.p) == nodes.end()) {
|
if (std::ranges::find(nodes, info.p) == nodes.end()) {
|
||||||
nodes.push_back(info.p);
|
nodes.push_back(info.p);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -37,57 +37,11 @@ namespace K::Plugboard {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Disconnect(NodeInstanceP from_instance, u8 input_index) {
|
void Disconnect(NodeInstanceP from_instance, u8 input_index) {
|
||||||
std::visit([&](auto&& from) {
|
std::visit([&input_index](auto&& from) {
|
||||||
std::visit([&](auto &&arg) {
|
Disconnect(*from, input_index);
|
||||||
using T = std::decay_t<decltype(arg)>;
|
|
||||||
if constexpr (std::is_same_v<T, ConnectInfo>) {
|
|
||||||
std::visit([&](auto&& a) {
|
|
||||||
auto& v = a->out[arg.index].outgoing;
|
|
||||||
for (auto it = v.begin(); it != v.end(); it++) {
|
|
||||||
if (it->p == from_instance) {
|
|
||||||
v.erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, arg.p);
|
|
||||||
from->in[input_index].value = ExpandVariant(from->in[input_index].type);
|
|
||||||
}
|
|
||||||
else if constexpr (std::is_same_v<T, T_Map<Type::T_Count>::type>)
|
|
||||||
; // already disconnected
|
|
||||||
}, from->in[input_index].value);
|
|
||||||
}, from_instance);
|
}, from_instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NodeInstance MakeInstance(K_P_Nodes i) {
|
|
||||||
static NodeInstance table[] = {
|
|
||||||
Add{},
|
|
||||||
Negate{},
|
|
||||||
Subtract{},
|
|
||||||
Multiply{},
|
|
||||||
Divide{},
|
|
||||||
Sign{},
|
|
||||||
Sin{},
|
|
||||||
Cos{},
|
|
||||||
Tan{},
|
|
||||||
Arcsin{},
|
|
||||||
Arccos{},
|
|
||||||
Arctan{},
|
|
||||||
Atan2{},
|
|
||||||
Minimum{},
|
|
||||||
Maximum{},
|
|
||||||
Power{},
|
|
||||||
SquareRoot{},
|
|
||||||
NaturalLogarithm{},
|
|
||||||
AbsoluteValue{},
|
|
||||||
Interpolation{},
|
|
||||||
Chain{},
|
|
||||||
CompositionIn{},
|
|
||||||
CompositionOut{}
|
|
||||||
};
|
|
||||||
static_assert(sizeof(table)/sizeof(table[0]) == K_P_Count);
|
|
||||||
return table[i];
|
|
||||||
}*/
|
|
||||||
|
|
||||||
T_Map<T_Count>::type ExpandVariant(u32 i) {
|
T_Map<T_Count>::type ExpandVariant(u32 i) {
|
||||||
static T_Map<T_Count>::type table[] = { f32{}, i32{}, RGBA{}, XY{}, XYZ{}, String{} };
|
static T_Map<T_Count>::type table[] = { f32{}, i32{}, RGBA{}, XY{}, XYZ{}, String{} };
|
||||||
return table[i];
|
return table[i];
|
||||||
|
|
226
Keishiki/UI.cpp
226
Keishiki/UI.cpp
|
@ -58,7 +58,7 @@ namespace ImGui {
|
||||||
|
|
||||||
namespace K::UI {
|
namespace K::UI {
|
||||||
|
|
||||||
void AddTransformLayer(CompState& s, const std::string& name) {
|
void AddTransformLayer(CompState& s, const String& name) {
|
||||||
auto l = Layer{
|
auto l = Layer{
|
||||||
VisualTrack{},
|
VisualTrack{},
|
||||||
name,
|
name,
|
||||||
|
@ -188,8 +188,7 @@ namespace K::UI {
|
||||||
|
|
||||||
template <Plugboard::Node N>
|
template <Plugboard::Node N>
|
||||||
void PlugboardNodeDrawSockets(CompState& s, N& n, ImGuiStyle& style,
|
void PlugboardNodeDrawSockets(CompState& s, N& n, ImGuiStyle& style,
|
||||||
bool& dragging_on_socket, ImVec2& source, Dict<Plugboard::ConnectInfo, Plugboard::LinksFromSource, Plugboard::ConnectInfoHasher>& link_pos,
|
bool& dragging_on_socket, ImVec2& source, bool dummy = true) {
|
||||||
bool dummy = true) {
|
|
||||||
i32 row = 1;
|
i32 row = 1;
|
||||||
for (u32 out = 0; out < n.out.size(); out++, row++) {
|
for (u32 out = 0; out < n.out.size(); out++, row++) {
|
||||||
ImGui::PushID(row);
|
ImGui::PushID(row);
|
||||||
|
@ -224,7 +223,7 @@ namespace K::UI {
|
||||||
|
|
||||||
// Update link info if needed
|
// Update link info if needed
|
||||||
if (!n.out[out].outgoing.empty()) {\
|
if (!n.out[out].outgoing.empty()) {\
|
||||||
link_pos[{&n, out}].source = ImGui::GetCursorScreenPos() + ImVec2{ImGui::GetFrameHeight() / 2,
|
s.plugboard.links_pos[{&n, out}].source = ImGui::GetCursorScreenPos() + ImVec2{ImGui::GetFrameHeight() / 2,
|
||||||
-ImGui::GetFrameHeight() / 2 -
|
-ImGui::GetFrameHeight() / 2 -
|
||||||
style.ItemInnerSpacing.y};
|
style.ItemInnerSpacing.y};
|
||||||
}
|
}
|
||||||
|
@ -255,13 +254,13 @@ namespace K::UI {
|
||||||
ImGui::TextUnformatted(n.in[in].name.c_str());
|
ImGui::TextUnformatted(n.in[in].name.c_str());
|
||||||
|
|
||||||
// Update link info
|
// Update link info
|
||||||
std::visit([&socket_link_pos, &dragging_on_socket, &source, &link_pos](auto&& arg) {
|
std::visit([&socket_link_pos, &dragging_on_socket, &source, &s](auto&& arg) {
|
||||||
using T = std::decay_t<decltype(arg)>;
|
using T = std::decay_t<decltype(arg)>;
|
||||||
if constexpr (std::is_same_v<T, Plugboard::ConnectInfo>) {
|
if constexpr (std::is_same_v<T, Plugboard::ConnectInfo>) {
|
||||||
if (ImGui::IsItemActive())
|
if (ImGui::IsItemActive())
|
||||||
link_pos[arg].sinks.push_back(ImGui::GetMousePos());
|
s.plugboard.links_pos[arg].sinks.push_back(ImGui::GetMousePos());
|
||||||
else
|
else
|
||||||
link_pos[arg].sinks.push_back(socket_link_pos);
|
s.plugboard.links_pos[arg].sinks.push_back(socket_link_pos);
|
||||||
}
|
}
|
||||||
else if (ImGui::IsItemActive()) {
|
else if (ImGui::IsItemActive()) {
|
||||||
dragging_on_socket = true;
|
dragging_on_socket = true;
|
||||||
|
@ -279,15 +278,16 @@ namespace K::UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <Plugboard::Node N>
|
template <Plugboard::Node N>
|
||||||
bool PlugboardDrawNode(CompState& s, N& n, ImVec2& view_pos, ImGuiIO& io, ImGuiStyle& style,
|
void PlugboardDrawNode(CompState& s, N& n, ImVec2& view_pos, ImGuiIO& io, ImGuiStyle& style,
|
||||||
bool& dragging_on_socket, ImVec2& source, Dict<Plugboard::ConnectInfo, Plugboard::LinksFromSource, Plugboard::ConnectInfoHasher>& link_pos) {
|
bool& dragging_on_socket, ImVec2& source, bool& delete_request) {
|
||||||
bool stat = false;
|
Plugboard::NodeInstanceP ptr{&n};
|
||||||
|
bool selected = std::ranges::find(s.plugboard.selected_nodes, ptr) != s.plugboard.selected_nodes.end();
|
||||||
const auto& pos = n.pos;
|
const auto& pos = n.pos;
|
||||||
const auto& name = n.name;
|
const auto& name = n.name;
|
||||||
|
|
||||||
ImGui::SetCursorPos(view_pos + pos);
|
ImGui::SetCursorPos(view_pos + pos);
|
||||||
ImGui::PushID(&n);
|
ImGui::PushID(&n);
|
||||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, 0xAA080813);
|
ImGui::PushStyleColor(ImGuiCol_ChildBg, selected ? 0xAA202040 : 0xAA080813);
|
||||||
static ImVec2 old_pos{};
|
static ImVec2 old_pos{};
|
||||||
if (ImGui::BeginChild(name, {}, ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_Border)) {
|
if (ImGui::BeginChild(name, {}, ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_Border)) {
|
||||||
if (ImGui::BeginTable(name, 3)) {
|
if (ImGui::BeginTable(name, 3)) {
|
||||||
|
@ -295,9 +295,22 @@ namespace K::UI {
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Button(name, {100.0f , 0.0f});
|
ImGui::Button(name, {100.0f , 0.0f});
|
||||||
|
if (ImGui::BeginPopupContextItem()) {
|
||||||
|
if (!s.plugboard.selected_nodes.empty() && ImGui::Button("Delete")) {
|
||||||
|
delete_request = true;
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
if (ImGui::IsItemClicked()) {
|
if (ImGui::IsItemClicked()) {
|
||||||
old_pos = pos;
|
old_pos = pos;
|
||||||
stat = true;
|
if (io.KeyCtrl && !selected) {
|
||||||
|
s.plugboard.selected_nodes.push_back(ptr);
|
||||||
|
}
|
||||||
|
else if (!selected) {
|
||||||
|
s.plugboard.selected_nodes.clear();
|
||||||
|
s.plugboard.selected_nodes.push_back(ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemActive()) {
|
if (ImGui::IsItemActive()) {
|
||||||
n.pos = old_pos + ImGui::GetMouseDragDelta();
|
n.pos = old_pos + ImGui::GetMouseDragDelta();
|
||||||
|
@ -312,7 +325,7 @@ namespace K::UI {
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
PlugboardNodeDrawSockets<N>(s, n, style, dragging_on_socket, source, link_pos);
|
PlugboardNodeDrawSockets<N>(s, n, style, dragging_on_socket, source);
|
||||||
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
@ -320,7 +333,6 @@ namespace K::UI {
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
return stat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TogglePlay() {
|
void TogglePlay() {
|
||||||
|
@ -352,7 +364,7 @@ namespace K::UI {
|
||||||
view_count++;
|
view_count++;
|
||||||
|
|
||||||
for (u32 i = s.layers.size() - 1; i != u32(-1); i--) {
|
for (u32 i = s.layers.size() - 1; i != u32(-1); i--) {
|
||||||
if (std::find(s.disabled.begin(), s.disabled.end(), i) != s.disabled.end()) continue;
|
if (std::ranges::find(s.disabled, i) != s.disabled.end()) continue;
|
||||||
if (s.current_frame > s.layers[i].out || s.current_frame < s.layers[i].in) continue;
|
if (s.current_frame > s.layers[i].out || s.current_frame < s.layers[i].in) continue;
|
||||||
|
|
||||||
s.layers[i].track.GetFrame(s, Graphics::K_VIEW_COMP_COMPOSITE + view_count++, render_fb, s.width,
|
s.layers[i].track.GetFrame(s, Graphics::K_VIEW_COMP_COMPOSITE + view_count++, render_fb, s.width,
|
||||||
|
@ -417,6 +429,51 @@ namespace K::UI {
|
||||||
};
|
};
|
||||||
|
|
||||||
void Composition(CompState& s) {
|
void Composition(CompState& s) {
|
||||||
|
static bool layer_delete_requested = false;
|
||||||
|
if (layer_delete_requested) {
|
||||||
|
if (std::ranges::find(s.selected, s.active) != s.selected.end()) // unset active if active is selected
|
||||||
|
s.active = -1;
|
||||||
|
u32 deleted = 0, before_active = 0; // stupid counting tricks
|
||||||
|
const u32 sz = s.layers.size();
|
||||||
|
for (u32 j = 0; j < sz; j++) { // im sure this isn't the best way to go about this
|
||||||
|
if (std::ranges::find(s.selected, j) != s.selected.end()) {
|
||||||
|
s.layers[j - deleted].track.Clear();
|
||||||
|
for (auto& u : s.layers[j - deleted].track.uniforms)
|
||||||
|
VisualTrack::HideUniform(s, u);
|
||||||
|
s.layers.erase(s.layers.begin() + j - deleted);
|
||||||
|
std::erase(s.disabled, j);
|
||||||
|
if (static_cast<i32>(j) < s.active)
|
||||||
|
before_active++;
|
||||||
|
deleted++;
|
||||||
|
}
|
||||||
|
else if (auto it = std::ranges::find(s.disabled, j); it != s.disabled.end())
|
||||||
|
*it -= deleted;
|
||||||
|
}
|
||||||
|
s.selected.clear();
|
||||||
|
if (s.active != -1)
|
||||||
|
s.active -= static_cast<i32>(before_active);
|
||||||
|
|
||||||
|
layer_delete_requested = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool node_delete_requested = false;
|
||||||
|
if (node_delete_requested) {
|
||||||
|
for (auto p : s.plugboard.selected_nodes) {
|
||||||
|
std::visit([&s](auto&& arg){
|
||||||
|
for (u32 i = 0; i < arg->in.size(); i++)
|
||||||
|
Plugboard::Disconnect(arg, i);
|
||||||
|
for (auto& socket : arg->out)
|
||||||
|
for (Plugboard::ConnectInfo& connection : socket.outgoing)
|
||||||
|
Plugboard::Disconnect(connection.p, connection.index);
|
||||||
|
|
||||||
|
s.plugboard.nodes.Remove(arg);
|
||||||
|
}, p);
|
||||||
|
s.plugboard.RecollectChains();
|
||||||
|
}
|
||||||
|
s.plugboard.selected_nodes.clear();
|
||||||
|
node_delete_requested = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ImGui::Begin("Composition", &draw_comp, ImGuiWindowFlags_NoScrollbar)) {
|
if (!ImGui::Begin("Composition", &draw_comp, ImGuiWindowFlags_NoScrollbar)) {
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
return;
|
return;
|
||||||
|
@ -456,38 +513,12 @@ namespace K::UI {
|
||||||
const bool no_selection = s.selected.empty();
|
const bool no_selection = s.selected.empty();
|
||||||
|
|
||||||
static String name{};
|
static String name{};
|
||||||
if (ImGui::Button("Add Layer") && !name.empty()) {
|
if (ImGui::Button("Add Layer") && !name.empty())
|
||||||
AddTransformLayer(s, name);
|
AddTransformLayer(s, name);
|
||||||
}
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::SetNextItemWidth(250.0f);
|
ImGui::SetNextItemWidth(250.0f);
|
||||||
ImGui::InputText("##LayerName", &name);
|
ImGui::InputText("##LayerName", &name);
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::BeginDisabled(no_selection);
|
|
||||||
if (ImGui::Button("Delete Layer")) { // todo unregister from plugboard beforehand
|
|
||||||
if (std::find(s.selected.begin(), s.selected.end(), s.active) != s.selected.end())
|
|
||||||
s.active = -1;
|
|
||||||
u32 deleted = 0, before_active = 0;
|
|
||||||
const u32 sz = s.layers.size();
|
|
||||||
for (u32 i = 0; i < sz; i++) {
|
|
||||||
if (std::find(s.selected.begin(), s.selected.end(), i) != s.selected.end()) {
|
|
||||||
s.layers[i - deleted].track.Clear();
|
|
||||||
s.layers.erase(s.layers.begin() + i - deleted);
|
|
||||||
std::erase(s.disabled, i);
|
|
||||||
if (static_cast<i32>(i) < s.active)
|
|
||||||
before_active++;
|
|
||||||
deleted++;
|
|
||||||
}
|
|
||||||
else if (std::find(s.disabled.begin(), s.disabled.end(), i) != s.disabled.end()) {
|
|
||||||
std::erase(s.disabled, i);
|
|
||||||
s.disabled.push_back(i - deleted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s.selected.clear();
|
|
||||||
s.active -= static_cast<i32>(before_active);
|
|
||||||
}
|
|
||||||
ImGui::EndDisabled();
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
ImGui::Checkbox("Chain Editor", &show_curve_editor);
|
ImGui::Checkbox("Chain Editor", &show_curve_editor);
|
||||||
|
@ -526,6 +557,8 @@ namespace K::UI {
|
||||||
for (f32 y = std::fmodf(view_pos.y, grid_inc); y < h; y += grid_inc)
|
for (f32 y = std::fmodf(view_pos.y, grid_inc); y < h; y += grid_inc)
|
||||||
window->DrawList->AddLine(window_pos + ImVec2(0.0f, y), window_pos + ImVec2(w, y), 0xFF222222, 1.0f);
|
window->DrawList->AddLine(window_pos + ImVec2(0.0f, y), window_pos + ImVec2(w, y), 0xFF222222, 1.0f);
|
||||||
|
|
||||||
|
// why are we re-getting positions on each frame?
|
||||||
|
// this is just convenient because sometimes we would be dragging on a socket!
|
||||||
s.plugboard.links_pos.clear();
|
s.plugboard.links_pos.clear();
|
||||||
|
|
||||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
||||||
|
@ -539,7 +572,7 @@ namespace K::UI {
|
||||||
(([&](auto&& arg){
|
(([&](auto&& arg){
|
||||||
for (auto& node : arg) {
|
for (auto& node : arg) {
|
||||||
PlugboardDrawNode<std::decay_t<decltype(node)>>(s, node, view_pos, io, style, dragging_on_socket,
|
PlugboardDrawNode<std::decay_t<decltype(node)>>(s, node, view_pos, io, style, dragging_on_socket,
|
||||||
drag_source, s.plugboard.links_pos);
|
drag_source, node_delete_requested);
|
||||||
}
|
}
|
||||||
}(args)), ...);
|
}(args)), ...);
|
||||||
}, s.plugboard.nodes.nodes);
|
}, s.plugboard.nodes.nodes);
|
||||||
|
@ -551,8 +584,7 @@ namespace K::UI {
|
||||||
ImGuiChildFlags_AutoResizeY);
|
ImGuiChildFlags_AutoResizeY);
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
if (ImGui::BeginTable("Composition In", 3)) {
|
if (ImGui::BeginTable("Composition In", 3)) {
|
||||||
PlugboardNodeDrawSockets(s, s.plugboard.in, style, dragging_on_socket, drag_source,
|
PlugboardNodeDrawSockets(s, s.plugboard.in, style, dragging_on_socket, drag_source, false);
|
||||||
s.plugboard.links_pos, false);
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,15 +610,13 @@ namespace K::UI {
|
||||||
f32 view_amt = view_right - view_left, mouse_tl_x;
|
f32 view_amt = view_right - view_left, mouse_tl_x;
|
||||||
f32 fr_step;
|
f32 fr_step;
|
||||||
|
|
||||||
static Vector<Plugboard::NodeInstanceP> selected_chains{};
|
|
||||||
|
|
||||||
// Mouse Handlers
|
// Mouse Handlers
|
||||||
// Drag playhead/pan
|
// Drag playhead/pan
|
||||||
static bool tl_clear_selection_request = false;
|
static bool tl_clear_selection_request = false;
|
||||||
bool tl_clear_selection_request_this_frame = tl_clear_selection_request;
|
bool tl_clear_selection_request_this_frame = tl_clear_selection_request;
|
||||||
static bool bg_drag_select_active = false;
|
static bool bg_drag_select_active = false;
|
||||||
static Vector<Plugboard::ChainSegment*> keys_selected_by_bg_drag{};
|
static Vector<Plugboard::ChainSegment*> keys_selected_by_bg_drag{};
|
||||||
auto draw_tl_bg_drag_area = [&view_width, &style, &view_amt, &s, &mouse_tl_x, &io](f32 h = 0.0f, f32 w = 0.0f) {
|
auto tl_bg_handler = [&view_width, &style, &view_amt, &s, &mouse_tl_x, &io](f32 h = 0.0f, f32 w = 0.0f) {
|
||||||
static f32 pan_x, view_left_old, view_right_old;
|
static f32 pan_x, view_left_old, view_right_old;
|
||||||
ImGui::InvisibleButton("##TL_BG", ImVec2{ w == 0.0f ? view_width + style.CellPadding.x * 2 : w, h == 0.0f ? row_height + style.CellPadding.y : h});
|
ImGui::InvisibleButton("##TL_BG", ImVec2{ w == 0.0f ? view_width + style.CellPadding.x * 2 : w, h == 0.0f ? row_height + style.CellPadding.y : h});
|
||||||
if (ImGui::IsItemClicked()) {
|
if (ImGui::IsItemClicked()) {
|
||||||
|
@ -620,6 +650,16 @@ namespace K::UI {
|
||||||
view_right = 1.0f;
|
view_right = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ImGui::IsKeyPressed(ImGuiKey_Delete) && ImGui::IsItemHovered()) {
|
||||||
|
for (auto& chain : s.plugboard.selected_nodes) {
|
||||||
|
if (auto *c = std::get_if<Plugboard::Chain*>(&chain)) {
|
||||||
|
auto& [segments, selected] = (*c)->extra.chain;
|
||||||
|
for (u32 i : selected)
|
||||||
|
segments.erase(segments.begin() + i);
|
||||||
|
selected.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr static f32 knob_width = 8.0f;
|
constexpr static f32 knob_width = 8.0f;
|
||||||
|
@ -649,7 +689,8 @@ namespace K::UI {
|
||||||
|
|
||||||
if (is_sel)
|
if (is_sel)
|
||||||
chain.selected.push_back(pos_index);
|
chain.selected.push_back(pos_index);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (ImGui::IsItemClicked()) {
|
if (ImGui::IsItemClicked()) {
|
||||||
started_dragging = true; // setup dragging & start on next frame
|
started_dragging = true; // setup dragging & start on next frame
|
||||||
|
|
||||||
|
@ -665,8 +706,7 @@ namespace K::UI {
|
||||||
&(key_loop_target->segments)[ii]); // This sucks pretty bad...
|
&(key_loop_target->segments)[ii]); // This sucks pretty bad...
|
||||||
chain.selected.push_back(ii);
|
chain.selected.push_back(ii);
|
||||||
}
|
}
|
||||||
auto bg_drag_sel_it = std::find(keys_selected_by_bg_drag.begin(),
|
auto bg_drag_sel_it = std::ranges::find(keys_selected_by_bg_drag,
|
||||||
keys_selected_by_bg_drag.end(),
|
|
||||||
&(key_loop_target->segments)[ii]);
|
&(key_loop_target->segments)[ii]);
|
||||||
if (is_sel && bg_drag_sel_it != keys_selected_by_bg_drag.end() &&
|
if (is_sel && bg_drag_sel_it != keys_selected_by_bg_drag.end() &&
|
||||||
!drag_rect.Contains(k_pos)) {
|
!drag_rect.Contains(k_pos)) {
|
||||||
|
@ -779,8 +819,8 @@ namespace K::UI {
|
||||||
|
|
||||||
for (u32 i = 0; i < s.layers.size(); i++) {
|
for (u32 i = 0; i < s.layers.size(); i++) {
|
||||||
auto& current_layer = s.layers[i];
|
auto& current_layer = s.layers[i];
|
||||||
const bool selected = std::find(s.selected.begin(), s.selected.end(), i) != s.selected.end(),
|
const bool selected = std::ranges::find(s.selected, i) != s.selected.end(),
|
||||||
disabled = std::find(s.disabled.begin(), s.disabled.end(), i) != s.disabled.end();
|
disabled = std::ranges::find(s.disabled, i) != s.disabled.end();
|
||||||
ImGui::PushID(static_cast<i32>(i));
|
ImGui::PushID(static_cast<i32>(i));
|
||||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
||||||
|
|
||||||
|
@ -796,6 +836,13 @@ namespace K::UI {
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,
|
||||||
{0.0f, (row_height - ImGui::GetTextLineHeight()) / 2.0f});
|
{0.0f, (row_height - ImGui::GetTextLineHeight()) / 2.0f});
|
||||||
bool layer_open = ImGui::TreeNodeEx(current_layer.name.c_str(), flags);
|
bool layer_open = ImGui::TreeNodeEx(current_layer.name.c_str(), flags);
|
||||||
|
if (ImGui::BeginPopupContextItem()) {
|
||||||
|
if (!s.selected.empty() && ImGui::Button("Delete")) {
|
||||||
|
layer_delete_requested = true;
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) {
|
if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) {
|
||||||
if (io.KeyCtrl) {
|
if (io.KeyCtrl) {
|
||||||
if (selected)
|
if (selected)
|
||||||
|
@ -970,7 +1017,7 @@ namespace K::UI {
|
||||||
auto& c = s.plugboard.nodes.Store(Plugboard::Chain{});
|
auto& c = s.plugboard.nodes.Store(Plugboard::Chain{});
|
||||||
Plugboard::Connect(u.connection.p, u.connection.index, &c, 0);
|
Plugboard::Connect(u.connection.p, u.connection.index, &c, 0);
|
||||||
Plugboard::Connect(&c, 0, &s.plugboard.in, 0);
|
Plugboard::Connect(&c, 0, &s.plugboard.in, 0);
|
||||||
auto& nodes = std::get<Plugboard::CompositionOut*>(u.connection.p)->show_nodes[u.connection.index];
|
auto& nodes = s.plugboard.out.show_nodes[u.connection.index];
|
||||||
nodes.clear();
|
nodes.clear();
|
||||||
nodes.emplace_back(&c, 0);
|
nodes.emplace_back(&c, 0);
|
||||||
}
|
}
|
||||||
|
@ -993,24 +1040,12 @@ namespace K::UI {
|
||||||
ImGui::SetNextItemWidth(-FLT_MIN);
|
ImGui::SetNextItemWidth(-FLT_MIN);
|
||||||
|
|
||||||
|
|
||||||
if (connected_v.index() == 0)
|
if (auto *v = std::get_if<Plugboard::T_Map<Plugboard::T_Count>::type>(&connected_v))
|
||||||
std::visit([](auto&& arg) {
|
DrawPlugboardVariableEditWidget(*v);
|
||||||
using T = std::decay_t<decltype(arg)>;
|
|
||||||
if constexpr (std::is_same_v<T, Plugboard::T_Map<Plugboard::T_Float>::type>)
|
|
||||||
ImGui::DragFloat("##", &arg, 0.005f);
|
|
||||||
else if constexpr (std::is_same_v<T, Plugboard::T_Map<Plugboard::T_Int>::type>)
|
|
||||||
ImGui::DragInt("##", &arg, 0.005f);
|
|
||||||
else if constexpr (std::is_same_v<T, Plugboard::T_Map<Plugboard::T_RGBA>::type>)
|
|
||||||
ImGui::DragFloat4("##", &arg.r, 0.005f);
|
|
||||||
else if constexpr (std::is_same_v<T, Plugboard::T_Map<Plugboard::T_XY>::type>)
|
|
||||||
ImGui::DragFloat2("##", &arg.x, 0.005f);
|
|
||||||
else if constexpr (std::is_same_v<T, Plugboard::T_Map<Plugboard::T_XYZ>::type>)
|
|
||||||
ImGui::DragFloat3("##", &arg.x, 0.005f);
|
|
||||||
}, std::get<0>(connected_v));
|
|
||||||
|
|
||||||
ImGui::TableSetColumnIndex(3);
|
ImGui::TableSetColumnIndex(3);
|
||||||
ImGui::TableSetColumnIndex(4);
|
ImGui::TableSetColumnIndex(4);
|
||||||
auto p = ImGui::GetCursorScreenPos();
|
auto p = ImGui::GetCursorScreenPos(); // restored later
|
||||||
|
|
||||||
// plot uniform if connected
|
// plot uniform if connected
|
||||||
ImPlot::PushStyleVar(ImPlotStyleVar_PlotPadding, {0.0f, 0.0f});
|
ImPlot::PushStyleVar(ImPlotStyleVar_PlotPadding, {0.0f, 0.0f});
|
||||||
|
@ -1049,10 +1084,10 @@ namespace K::UI {
|
||||||
|
|
||||||
ImGui::SetCursorScreenPos(p);
|
ImGui::SetCursorScreenPos(p);
|
||||||
|
|
||||||
draw_tl_bg_drag_area();
|
tl_bg_handler();
|
||||||
|
|
||||||
if (uniform_open && connected_v.index() == 1) {
|
if (uniform_open && connected_v.index() == 1) {
|
||||||
for (const auto& info: std::get<Plugboard::CompositionOut*>(u.connection.p)->show_nodes[u.connection.index]) {
|
for (const auto& info: s.plugboard.out.show_nodes[u.connection.index]) {
|
||||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
ImGui::TableSetColumnIndex(1);
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
@ -1060,15 +1095,15 @@ namespace K::UI {
|
||||||
auto n_flags = ImGuiTreeNodeFlags_SpanFullWidth |
|
auto n_flags = ImGuiTreeNodeFlags_SpanFullWidth |
|
||||||
ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_Leaf |
|
ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_Leaf |
|
||||||
ImGuiTreeNodeFlags_FramePadding;
|
ImGuiTreeNodeFlags_FramePadding;
|
||||||
auto chain_sel_it = std::find(selected_chains.begin(), selected_chains.end(), info.p);
|
auto chain_sel_it = std::ranges::find(s.plugboard.selected_nodes, info.p);
|
||||||
if (chain_sel_it != selected_chains.end())
|
if (chain_sel_it != s.plugboard.selected_nodes.end())
|
||||||
n_flags |= ImGuiTreeNodeFlags_Selected;
|
n_flags |= ImGuiTreeNodeFlags_Selected;
|
||||||
ImGui::TreeNodeEx(std::visit([](auto&& arg){ return arg->name; }, info.p), n_flags);
|
ImGui::TreeNodeEx(std::visit([](auto&& arg){ return arg->name; }, info.p), n_flags);
|
||||||
if (ImGui::IsItemClicked()) {
|
if (ImGui::IsItemClicked()) {
|
||||||
if (chain_sel_it != selected_chains.end())
|
if (chain_sel_it != s.plugboard.selected_nodes.end())
|
||||||
selected_chains.erase(chain_sel_it);
|
s.plugboard.selected_nodes.erase(chain_sel_it);
|
||||||
else
|
else
|
||||||
selected_chains.push_back(info.p);
|
s.plugboard.selected_nodes.push_back(info.p);
|
||||||
}
|
}
|
||||||
ImGui::TableSetColumnIndex(2);
|
ImGui::TableSetColumnIndex(2);
|
||||||
|
|
||||||
|
@ -1094,8 +1129,8 @@ namespace K::UI {
|
||||||
f32 v = std::get<Plugboard::T_Map<Plugboard::T_Float>::type>(
|
f32 v = std::get<Plugboard::T_Map<Plugboard::T_Float>::type>(
|
||||||
Plugboard::Eval(s, info));
|
Plugboard::Eval(s, info));
|
||||||
if (ImGui::DragFloat("##value", &v, 0.005f)) {
|
if (ImGui::DragFloat("##value", &v, 0.005f)) {
|
||||||
if (std::find(selected_chains.begin(), selected_chains.end(), info.p) == selected_chains.end())
|
if (std::ranges::find(s.plugboard.selected_nodes, info.p) == s.plugboard.selected_nodes.end())
|
||||||
selected_chains.push_back(info.p);
|
s.plugboard.selected_nodes.push_back(info.p);
|
||||||
|
|
||||||
auto l = std::lower_bound(chain.segments.begin(), chain.segments.end(), s.current_frame,
|
auto l = std::lower_bound(chain.segments.begin(), chain.segments.end(), s.current_frame,
|
||||||
[](const Plugboard::ChainSegment& a, i32 b) { return a.frame < b; });
|
[](const Plugboard::ChainSegment& a, i32 b) { return a.frame < b; });
|
||||||
|
@ -1137,7 +1172,7 @@ namespace K::UI {
|
||||||
const auto& [k, val, segment] = (key_loop_target->segments)[ii];
|
const auto& [k, val, segment] = (key_loop_target->segments)[ii];
|
||||||
ImGui::PushID(k);
|
ImGui::PushID(k);
|
||||||
|
|
||||||
auto sel_it = std::find(key_loop_target->selected.begin(), key_loop_target->selected.end(), ii);
|
auto sel_it = std::ranges::find(key_loop_target->selected, ii);
|
||||||
bool is_sel = sel_it != key_loop_target->selected.end();
|
bool is_sel = sel_it != key_loop_target->selected.end();
|
||||||
|
|
||||||
i32 frame = k;
|
i32 frame = k;
|
||||||
|
@ -1166,13 +1201,13 @@ namespace K::UI {
|
||||||
begin_tl.y + row_height / 2.0f - 2.0f}, {TimelineFrameToScreenView(view_left, view_amt, view_width, nit->frame,
|
begin_tl.y + row_height / 2.0f - 2.0f}, {TimelineFrameToScreenView(view_left, view_amt, view_width, nit->frame,
|
||||||
s.frame_max) + begin_tl.x - kf_tab_width / 2.0f,
|
s.frame_max) + begin_tl.x - kf_tab_width / 2.0f,
|
||||||
begin_tl.y + row_height / 2.0f + 2.0f},
|
begin_tl.y + row_height / 2.0f + 2.0f},
|
||||||
std::find(chain.selected.begin(), chain.selected.end(), std::distance(chain.segments.begin(), it)) != chain.selected.end() &&
|
std::ranges::find(chain.selected, std::distance(chain.segments.begin(), it)) != chain.selected.end() &&
|
||||||
std::find(chain.selected.begin(), chain.selected.end(), std::distance(chain.segments.begin(), nit)) != chain.selected.end() ? 0x88FFAAAA : 0x44AAAAAA);
|
std::ranges::find(chain.selected, std::distance(chain.segments.begin(), nit)) != chain.selected.end() ? 0x88FFAAAA : 0x44AAAAAA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::SetCursorScreenPos(begin_tl);
|
ImGui::SetCursorScreenPos(begin_tl);
|
||||||
draw_tl_bg_drag_area();
|
tl_bg_handler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
|
@ -1184,7 +1219,7 @@ namespace K::UI {
|
||||||
std::visit([table_left, &s](auto &&arg) {
|
std::visit([table_left, &s](auto &&arg) {
|
||||||
using T = std::decay_t<decltype(arg)>;
|
using T = std::decay_t<decltype(arg)>;
|
||||||
if constexpr (std::is_same_v<T, Plugboard::ConnectInfo>)
|
if constexpr (std::is_same_v<T, Plugboard::ConnectInfo>)
|
||||||
s.plugboard.links_pos[arg].sinks.push_back(
|
s.plugboard.links_pos[arg].sinks.push_back( // make nodes connect to collapsed layer row
|
||||||
{table_left, ImGui::GetCursorScreenPos().y - row_height / 2.0f});
|
{table_left, ImGui::GetCursorScreenPos().y - row_height / 2.0f});
|
||||||
}, std::visit([&u](auto&& arg) -> auto& { return arg->in[u.connection.index].value; }, u.connection.p));
|
}, std::visit([&u](auto&& arg) -> auto& { return arg->in[u.connection.index].value; }, u.connection.p));
|
||||||
|
|
||||||
|
@ -1200,7 +1235,7 @@ namespace K::UI {
|
||||||
|
|
||||||
tl_end_begin = {tl_init_pos.x, ImGui::GetCursorScreenPos().y};
|
tl_end_begin = {tl_init_pos.x, ImGui::GetCursorScreenPos().y};
|
||||||
|
|
||||||
if (move_from != -1 && move_to != -1) {
|
if (move_from != -1 && move_to != -1) { // do layer move
|
||||||
if (no_selection)
|
if (no_selection)
|
||||||
std::swap(s.layers[move_to], s.layers[move_from]);
|
std::swap(s.layers[move_to], s.layers[move_from]);
|
||||||
else {
|
else {
|
||||||
|
@ -1243,7 +1278,7 @@ namespace K::UI {
|
||||||
|
|
||||||
ImGui::SetCursorScreenPos(tl_end_begin);
|
ImGui::SetCursorScreenPos(tl_end_begin);
|
||||||
if (ImGui::BeginChild("TL Bottom Unfilled Drag Overlay")) {
|
if (ImGui::BeginChild("TL Bottom Unfilled Drag Overlay")) {
|
||||||
draw_tl_bg_drag_area(ImGui::GetContentRegionAvail().y);
|
tl_bg_handler(ImGui::GetContentRegionAvail().y);
|
||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
|
|
||||||
|
@ -1275,9 +1310,12 @@ namespace K::UI {
|
||||||
dragging = false;
|
dragging = false;
|
||||||
}
|
}
|
||||||
u32 keys = 0;
|
u32 keys = 0;
|
||||||
for (const auto& n : selected_chains) {
|
for (const auto& n : s.plugboard.selected_nodes) {
|
||||||
Plugboard::ConnectInfo i {n, 0}; // it's a chain -- 0 is out
|
if (!std::holds_alternative<Plugboard::Chain*>(n))
|
||||||
|
continue;
|
||||||
|
|
||||||
auto& [chain, chain_copy] = std::get<Plugboard::Chain*>(n)->extra;
|
auto& [chain, chain_copy] = std::get<Plugboard::Chain*>(n)->extra;
|
||||||
|
Plugboard::ConnectInfo i {n, 0}; // it's a chain -- 0 is out
|
||||||
|
|
||||||
if (started_dragging)
|
if (started_dragging)
|
||||||
chain_copy = chain;
|
chain_copy = chain;
|
||||||
|
@ -1293,9 +1331,9 @@ namespace K::UI {
|
||||||
auto& [k, val, segment] = (key_loop_target->segments)[ii];
|
auto& [k, val, segment] = (key_loop_target->segments)[ii];
|
||||||
ImGui::PushID(keys++);
|
ImGui::PushID(keys++);
|
||||||
|
|
||||||
auto sel_it = std::find(key_loop_target->selected.begin(), key_loop_target->selected.end(), ii);
|
auto sel_it = std::ranges::find(key_loop_target->selected, ii);
|
||||||
bool is_sel = sel_it != key_loop_target->selected.end();
|
bool is_sel = sel_it != key_loop_target->selected.end();
|
||||||
bool is_nxt_sel = ii + 1 < key_loop_target->segments.size() && std::find(key_loop_target->selected.begin(), key_loop_target->selected.end(), ii + 1) != key_loop_target->selected.end();
|
bool is_nxt_sel = ii + 1 < key_loop_target->segments.size() && std::ranges::find(key_loop_target->selected, ii + 1) != key_loop_target->selected.end();
|
||||||
|
|
||||||
i32 frame = k;
|
i32 frame = k;
|
||||||
f64 v = val;
|
f64 v = val;
|
||||||
|
@ -1401,7 +1439,7 @@ namespace K::UI {
|
||||||
ImPlot::PopStyleColor(3);
|
ImPlot::PopStyleColor(3);
|
||||||
ImPlot::PopStyleVar(2);
|
ImPlot::PopStyleVar(2);
|
||||||
ImGui::SetCursorScreenPos(ImGui::GetCursorStartPos());
|
ImGui::SetCursorScreenPos(ImGui::GetCursorStartPos());
|
||||||
draw_tl_bg_drag_area(ImGui::GetContentRegionAvail().y, ImGui::GetContentRegionAvail().x);
|
tl_bg_handler(ImGui::GetContentRegionAvail().y, ImGui::GetContentRegionAvail().x);
|
||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
@ -1602,12 +1640,12 @@ namespace K::UI {
|
||||||
if (ImGui::Button("Apply"))
|
if (ImGui::Button("Apply"))
|
||||||
for (auto& layer : s.layers)
|
for (auto& layer : s.layers)
|
||||||
for (auto& u : layer.track.uniforms)
|
for (auto& u : layer.track.uniforms)
|
||||||
for (auto& n : std::get<Plugboard::CompositionOut*>(u.connection.p)->show_nodes[u.connection.index]) {
|
for (auto& n : s.plugboard.out.show_nodes[u.connection.index]) {
|
||||||
auto& [chain, _] = std::get<Plugboard::Chain*>(n.p)->extra;
|
auto& [chain, _] = std::get<Plugboard::Chain*>(n.p)->extra;
|
||||||
for (auto it = chain.segments.begin(); it != chain.segments.end(); it++) {
|
for (auto it = chain.segments.begin(); it != chain.segments.end(); it++) {
|
||||||
auto nit = std::next(it);
|
auto nit = std::next(it);
|
||||||
if (nit != chain.segments.end() && std::find(chain.selected.begin(), chain.selected.end(), std::distance(chain.segments.begin(), it)) != chain.selected.end() &&
|
if (nit != chain.segments.end() && std::ranges::find(chain.selected, std::distance(chain.segments.begin(), it)) != chain.selected.end() &&
|
||||||
std::find(chain.selected.begin(), chain.selected.end(), std::distance(chain.segments.begin(), nit)) != chain.selected.end()) {
|
std::ranges::find(chain.selected, std::distance(chain.segments.begin(), nit)) != chain.selected.end()) {
|
||||||
it->interp = {type_current, {p2.x, p2.y, p3.x, p3.y}};
|
it->interp = {type_current, {p2.x, p2.y, p3.x, p3.y}};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,17 +192,22 @@ namespace K {
|
||||||
ExposeUniform(s, uniforms[i]);
|
ExposeUniform(s, uniforms[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* void VisualTrack::HideUniform(CompState& s, Uniform& uu) {
|
void VisualTrack::HideUniform(CompState& s, Uniform& uu) {
|
||||||
uu.connection.p->disconnect(uu.connection.index);
|
Plugboard::Disconnect(uu.connection.p, uu.connection.index);
|
||||||
|
|
||||||
|
// decrement indices of uniforms referencing CompositionOut whose index is greater
|
||||||
for (auto& l : s.layers)
|
for (auto& l : s.layers)
|
||||||
for (auto& u_other : l.track.uniforms)
|
for (auto& u_other : l.track.uniforms)
|
||||||
if (u_other.connection.index > uu.connection.index)
|
if (u_other.connection.index > uu.connection.index)
|
||||||
u_other.connection.index--;
|
u_other.connection.index--;
|
||||||
s.plugboard.comp_out.in.erase(s.plugboard.out_instance.node->in.begin() + uu.connection.index);
|
|
||||||
s.plugboard.out_instance.inputs_fed.erase(s.plugboard.out_instance.inputs_fed.begin() + uu.connection.index);
|
if (std::holds_alternative<Plugboard::ConnectInfo>(s.plugboard.out.in[uu.connection.index].value)) {
|
||||||
uu.connection = {nullptr, 0};
|
Plugboard::Disconnect(s.plugboard.out, uu.connection.index);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
s.plugboard.out.in.erase(s.plugboard.out.in.begin() + uu.connection.index);
|
||||||
|
uu.connection = {(Plugboard::Add*)(nullptr), 0};
|
||||||
|
}
|
||||||
|
|
||||||
void VisualTrack::AddUniform(const String& s, ShaderGraph::T_Map<ShaderGraph::T_Count>::type&& val) {
|
void VisualTrack::AddUniform(const String& s, ShaderGraph::T_Map<ShaderGraph::T_Count>::type&& val) {
|
||||||
for (auto& u : uniforms)
|
for (auto& u : uniforms)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit fdc084f532189fda8474079f79e74fa5e3541c9f
|
Subproject commit 7237d3e5c3a6b837b7b457460877cf5eea8c3745
|
1
Keishiki/ext/plf_colony
Submodule
1
Keishiki/ext/plf_colony
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit fbc8483fb785c431dc4410396815abf886728c40
|
|
@ -22,7 +22,7 @@ namespace K {
|
||||||
using String = std::string;
|
using String = std::string;
|
||||||
using Byte = u8;
|
using Byte = u8;
|
||||||
using Char = char;
|
using Char = char;
|
||||||
template <typename T> using Vector = std::vector<T>;
|
template <typename T, typename... Ts> using Vector = std::vector<T, Ts...>;
|
||||||
template <typename... Ts> using Dict = std::unordered_map<Ts...>;
|
template <typename... Ts> using Dict = std::unordered_map<Ts...>;
|
||||||
|
|
||||||
inline void LogBase(const std::string_view& s, u8 level) {
|
inline void LogBase(const std::string_view& s, u8 level) {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <Resource.h>
|
#include <Resource.h>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <numbers>
|
#include <numbers>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include <bgfx/bgfx.h>
|
#include <bgfx/bgfx.h>
|
||||||
|
|
||||||
|
@ -129,11 +130,11 @@ namespace K::Graphics {
|
||||||
Qcubed = Q * Q * Q,
|
Qcubed = Q * Q * Q,
|
||||||
D = Qcubed - R * R;
|
D = Qcubed - R * R;
|
||||||
|
|
||||||
f64 theta = acos(R / sqrt(Qcubed));
|
f64 theta = acos(R / std::sqrt(Qcubed));
|
||||||
f64 sqrtQ = sqrt(Q);
|
f64 sqrtQ = std::sqrt(Q);
|
||||||
f64 r1 = -2.0 * sqrtQ * cos( theta / 3.0) - a1 / 3.0,
|
f64 r1 = -2.0 * sqrtQ * std::cos( theta / 3.0) - a1 / 3.0,
|
||||||
r2 = -2.0 * sqrtQ * cos((theta + 2.0 * std::numbers::pi) / 3.0) - a1 / 3.0,
|
r2 = -2.0 * sqrtQ * std::cos((theta + 2.0 * std::numbers::pi) / 3.0) - a1 / 3.0,
|
||||||
r3 = -2.0 * sqrtQ * cos((theta + 4.0 * std::numbers::pi) / 3.0) - a1 / 3.0;
|
r3 = -2.0 * sqrtQ * std::cos((theta + 4.0 * std::numbers::pi) / 3.0) - a1 / 3.0;
|
||||||
f64 e = std::pow(std::sqrt(-D) + std::abs(R), 1.0 / 3.0);
|
f64 e = std::pow(std::sqrt(-D) + std::abs(R), 1.0 / 3.0);
|
||||||
e = (R > 0.0) ? -e : e;
|
e = (R > 0.0) ? -e : e;
|
||||||
return Q == 0.0 && D == 0.0 ? -a1 / 3. : (D >= 0 ? CubicRealAccept(r1) ? r1 : (CubicRealAccept(r2) ? r2 : r3) : (e + Q / e) - a1 / 3.);
|
return Q == 0.0 && D == 0.0 ? -a1 / 3. : (D >= 0 ? CubicRealAccept(r1) ? r1 : (CubicRealAccept(r2) ? r2 : r3) : (e + Q / e) - a1 / 3.);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <list>
|
#include <plf_colony.h>
|
||||||
#include <any>
|
#include <any>
|
||||||
#include <bx/easing.h>
|
#include <bx/easing.h>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
@ -583,11 +583,11 @@ namespace K::Plugboard {
|
||||||
|
|
||||||
template <SameAsAny<Ns...> N>
|
template <SameAsAny<Ns...> N>
|
||||||
auto& Store(const N& v) {
|
auto& Store(const N& v) {
|
||||||
return std::get<std::list<N>>(nodes).push_back(v);
|
return std::get<plf::colony<N>>(nodes).insert(v);
|
||||||
}
|
}
|
||||||
template <SameAsAny<Ns...> N>
|
template <SameAsAny<Ns...> N>
|
||||||
auto& Store(N&& v) {
|
auto& Store(N&& v) {
|
||||||
return std::get<std::list<N>>(nodes).emplace_back(std::forward<N>(v));
|
return *std::get<plf::colony<N>>(nodes).emplace(std::forward<N>(v));
|
||||||
}
|
}
|
||||||
auto& Store(const std::variant<Ns...>& v) {
|
auto& Store(const std::variant<Ns...>& v) {
|
||||||
return std::visit([this](auto&& arg) { return store(arg); }, v);
|
return std::visit([this](auto&& arg) { return store(arg); }, v);
|
||||||
|
@ -596,7 +596,13 @@ namespace K::Plugboard {
|
||||||
return std::visit([this](auto&& arg) { return store(std::forward<decltype(arg)>(arg)); }, std::move(v));
|
return std::visit([this](auto&& arg) { return store(std::forward<decltype(arg)>(arg)); }, std::move(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<std::list<Ns>...> nodes;
|
template <SameAsAny<Ns...> N>
|
||||||
|
auto Remove(N *p) {
|
||||||
|
auto& colony = std::get<plf::colony<N>>(nodes);
|
||||||
|
return colony.erase(colony.get_iterator(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<plf::colony<Ns>...> nodes;
|
||||||
|
|
||||||
template<int N, typename... Ts> using NthTypeOf =
|
template<int N, typename... Ts> using NthTypeOf =
|
||||||
typename std::tuple_element<N, std::tuple<Ts...>>::type;
|
typename std::tuple_element<N, std::tuple<Ts...>>::type;
|
||||||
|
@ -653,11 +659,31 @@ namespace K::Plugboard {
|
||||||
Dict<ConnectInfo, LinksFromSource, ConnectInfoHasher> links_pos; // this is hilariously bad
|
Dict<ConnectInfo, LinksFromSource, ConnectInfoHasher> links_pos; // this is hilariously bad
|
||||||
CompositionIn in;
|
CompositionIn in;
|
||||||
CompositionOut out;
|
CompositionOut out;
|
||||||
|
|
||||||
|
Vector<NodeInstanceP> selected_nodes{};
|
||||||
|
|
||||||
void RecollectChains();
|
void RecollectChains();
|
||||||
};
|
};
|
||||||
|
|
||||||
void Connect(NodeInstanceP from_instance, u8 input_index, NodeInstanceP to_instance, u8 to_out_index);
|
void Connect(NodeInstanceP from_instance, u8 input_index, NodeInstanceP to_instance, u8 to_out_index);
|
||||||
|
|
||||||
|
template <Node N>
|
||||||
|
void Disconnect(N& instance, u8 input_index) {
|
||||||
|
if (auto *info = std::get_if<ConnectInfo>(&instance.in[input_index].value)) {
|
||||||
|
std::visit([&](auto&& a) {
|
||||||
|
auto& v = a->out[info->index].outgoing;
|
||||||
|
for (auto it = v.begin(); it != v.end(); it++) {
|
||||||
|
if (N **p = std::get_if<N*>(&it->p)) {
|
||||||
|
if (*p == &instance) {
|
||||||
|
v.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, info->p);
|
||||||
|
instance.in[input_index].value = ExpandVariant(instance.in[input_index].type);
|
||||||
|
}
|
||||||
|
}
|
||||||
void Disconnect(NodeInstanceP from_instance, u8 input_index);
|
void Disconnect(NodeInstanceP from_instance, u8 input_index);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace K {
|
||||||
f32 view[16], f32 transform[16]);
|
f32 view[16], f32 transform[16]);
|
||||||
static void ExposeUniform(CompState& s, Uniform& uu);
|
static void ExposeUniform(CompState& s, Uniform& uu);
|
||||||
void ExposeUniform(CompState& s, u32 i);
|
void ExposeUniform(CompState& s, u32 i);
|
||||||
// static void HideUniform(CompState& s, Uniform& uu);
|
static void HideUniform(CompState& s, Uniform& uu);
|
||||||
|
|
||||||
void AddUniform(const String& s, ShaderGraph::T_Map<ShaderGraph::T_Count>::type&& val);
|
void AddUniform(const String& s, ShaderGraph::T_Map<ShaderGraph::T_Count>::type&& val);
|
||||||
void AddSampler(const String& s);
|
void AddSampler(const String& s);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
- [SDL2](https://www.libsdl.org/)
|
- [SDL2](https://www.libsdl.org/)
|
||||||
- [stb](https://github.com/nothings/stb)
|
- [stb](https://github.com/nothings/stb)
|
||||||
- [SRELL](https://www.akenotsuki.com/misc/srell/en/)
|
- [SRELL](https://www.akenotsuki.com/misc/srell/en/)
|
||||||
|
- [plf::colony](https://plflib.org/colony.htm)
|
||||||
|
|
||||||
## Runtime Dependency
|
## Runtime Dependency
|
||||||
- [ffmpeg](https://ffmpeg.org/)
|
- [ffmpeg](https://ffmpeg.org/)
|
||||||
|
|
4
TODO.md
4
TODO.md
|
@ -7,11 +7,11 @@
|
||||||
- Blender previews resource
|
- Blender previews resource
|
||||||
- Data models
|
- Data models
|
||||||
- Dump and read back state, (de)serialization!!!
|
- Dump and read back state, (de)serialization!!!
|
||||||
- Pre-compose/Layer Groups (jokes -- can be completely UI side)
|
- Pre-compose/Layer Groups
|
||||||
- Undo's
|
- Undo's
|
||||||
- Node groups
|
- Node groups
|
||||||
- Deleting layers/nodes/keys/etc upkeep
|
|
||||||
- Motion blur
|
- Motion blur
|
||||||
|
|
||||||
- Text (idea: index-based evaluation in plugboard)
|
- Text (idea: index-based evaluation in plugboard)
|
||||||
- Shapes (idea: embed glisp :mmtroll:, need to inquire -- still a lot of friction for simple shapes if we don't also get the glisp gizmos)
|
- Shapes (idea: embed glisp :mmtroll:, need to inquire -- still a lot of friction for simple shapes if we don't also get the glisp gizmos)
|
||||||
- External data driving (csv, json or something else?) -- use a node to select source
|
- External data driving (csv, json or something else?) -- use a node to select source
|
||||||
|
|
Loading…
Add table
Reference in a new issue