liquid
This commit is contained in:
@@ -248,6 +248,7 @@ static const std::vector<NodeMenuItem> NODE_MENU = {
|
||||
{ "QueryTile", "Query", [] { return std::make_unique<QueryTileNode>(0, -1, 1); } },
|
||||
{ "QueryRange", "Query", [] { return std::make_unique<QueryRangeNode>(-1, -1, 1, 1, 1); } },
|
||||
{ "QueryDistance", "Query", [] { return std::make_unique<QueryDistanceNode>(1, 4); } },
|
||||
{ "QueryLiquid", "Query", [] { return std::make_unique<LiquidNode>(8, 4); } },
|
||||
// ── Noise ───────────────────────────────────────────────────────────────
|
||||
{ "Random", "Noise", [] { return std::make_unique<RandomNode>(); } },
|
||||
{ "PerlinNoise", "Noise", [] { return std::make_unique<PerlinNoiseNode>(0.01f); } },
|
||||
@@ -678,13 +679,19 @@ private:
|
||||
ImNodes::SetNodeGridSpacePos(WORLD_OUTPUT_IMNODES_ID, ImVec2(400.0f, 0.0f));
|
||||
}
|
||||
|
||||
// IsLinkHovered must be called outside BeginNodeEditor/EndNodeEditor.
|
||||
// s_linkWasHovered carries the previous frame's result so the canvas
|
||||
// right-click menu can be suppressed when the cursor is over a link.
|
||||
static bool s_linkWasHovered = false;
|
||||
|
||||
ImNodes::BeginNodeEditor();
|
||||
|
||||
// Right-click blank canvas → add node menu
|
||||
if (ImGui::IsWindowHovered(ImGuiFocusedFlags_RootAndChildWindows) &&
|
||||
ImNodes::IsEditorHovered() &&
|
||||
ImGui::IsMouseReleased(ImGuiMouseButton_Right) &&
|
||||
!ImGui::IsAnyItemHovered())
|
||||
!ImGui::IsAnyItemHovered() &&
|
||||
!s_linkWasHovered)
|
||||
{
|
||||
ImGui::OpenPopup("##add_node_menu");
|
||||
}
|
||||
@@ -778,6 +785,11 @@ private:
|
||||
|
||||
ImNodes::EndNodeEditor();
|
||||
|
||||
// Query link hover state here — must be outside Begin/End editor.
|
||||
int hoveredLink = -1;
|
||||
bool linkIsHovered = ImNodes::IsLinkHovered(&hoveredLink);
|
||||
s_linkWasHovered = linkIsHovered;
|
||||
|
||||
// ── Handle new connections ────────────────────────────────────────────
|
||||
|
||||
int fromAttr, toAttr;
|
||||
@@ -834,11 +846,9 @@ private:
|
||||
|
||||
// ── Handle link deletion ──────────────────────────────────────────────
|
||||
|
||||
int destroyedLink;
|
||||
if (ImNodes::IsLinkDestroyed(&destroyedLink)) {
|
||||
if (destroyedLink >= WORLD_OUTPUT_LINK_BASE) {
|
||||
// World Output link
|
||||
int passIdx = destroyedLink - WORLD_OUTPUT_LINK_BASE;
|
||||
auto destroyLink = [&](int linkId) {
|
||||
if (linkId >= WORLD_OUTPUT_LINK_BASE) {
|
||||
int passIdx = linkId - WORLD_OUTPUT_LINK_BASE;
|
||||
if (passIdx >= 0 && passIdx < static_cast<int>(tab.worldOutputPasses.size())) {
|
||||
tab.worldOutputPasses[passIdx] = Graph::INVALID_ID;
|
||||
tab.worldOutputDirty = true;
|
||||
@@ -853,7 +863,7 @@ private:
|
||||
if (!node) continue;
|
||||
for (int slot = 0; slot < static_cast<int>(node->GetInputCount()); ++slot) {
|
||||
if (tab.graph.GetInput(id, slot).has_value()) {
|
||||
if (idx == destroyedLink) {
|
||||
if (idx == linkId) {
|
||||
tab.graph.Disconnect(id, slot);
|
||||
MarkAllDirty();
|
||||
found = true;
|
||||
@@ -864,6 +874,25 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int destroyedLink;
|
||||
if (ImNodes::IsLinkDestroyed(&destroyedLink))
|
||||
destroyLink(destroyedLink);
|
||||
|
||||
// ── Right-click a link → disconnect popup ─────────────────────────────
|
||||
|
||||
static int s_rightClickedLink = -1;
|
||||
if (linkIsHovered && ImGui::IsMouseReleased(ImGuiMouseButton_Right)) {
|
||||
s_rightClickedLink = hoveredLink;
|
||||
ImGui::OpenPopup("##link_ctx");
|
||||
}
|
||||
if (ImGui::BeginPopup("##link_ctx")) {
|
||||
if (ImGui::MenuItem("Disconnect") && s_rightClickedLink >= 0) {
|
||||
destroyLink(s_rightClickedLink);
|
||||
s_rightClickedLink = -1;
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
// ── Delete selected nodes ─────────────────────────────────────────────
|
||||
@@ -1101,6 +1130,19 @@ private:
|
||||
return changed;
|
||||
}
|
||||
|
||||
static bool DrawLiquidNodeParams(NodeEditorApp& /*app*/, Node* node)
|
||||
{
|
||||
auto* n = static_cast<LiquidNode*>(node);
|
||||
bool changed = false;
|
||||
ImGui::PushItemWidth(70);
|
||||
ImGui::Text("max width");
|
||||
changed |= ImGui::DragInt("##lw", &n->maxWidth, 1, 1, 64);
|
||||
ImGui::Text("max depth");
|
||||
changed |= ImGui::DragInt("##ld", &n->maxDepth, 1, 1, 64);
|
||||
ImGui::PopItemWidth();
|
||||
return changed;
|
||||
}
|
||||
|
||||
static bool DrawMapParams(NodeEditorApp& /*app*/, Node* node)
|
||||
{
|
||||
auto* n = static_cast<MapNode*>(node);
|
||||
@@ -1139,6 +1181,7 @@ private:
|
||||
{ typeid(QueryTileNode), DrawQueryTileParams },
|
||||
{ typeid(QueryRangeNode), DrawQueryRangeParams },
|
||||
{ typeid(QueryDistanceNode), DrawQueryDistanceParams },
|
||||
{ typeid(LiquidNode), DrawLiquidNodeParams },
|
||||
{ typeid(MapNode), DrawMapParams },
|
||||
{ typeid(PerlinNoiseNode), DrawPerlinNoiseParams },
|
||||
{ typeid(SimplexNoiseNode), DrawSimplexNoiseParams },
|
||||
|
||||
Reference in New Issue
Block a user