TerraForge3D  2.3.1
3D Terrain And Landscape Generator
MathFunctionNode.cpp
1#include "Generators/CPUNodeEditor/Nodes/MathFunctionNode.h"
2#include "Generators/CPUNodeEditor/CPUNodeEditor.h"
3
4#include "muParser.h"
5#include "Utils.h"
6
7#include <locale>
8#include <codecvt>
9#include <string>
10#include <iostream>
11
12
13static void SetupParser(mu::Parser *parser)
14{
15 // TODO
16}
17
18NodeOutput MathFunctionNode::Evaluate(NodeInputParam input, NodeEditorPin *pin)
19{
20 try
21 {
22 if (input.maxZ == 0)
23 {
24 input.maxZ = 1;
25 }
26
27 x = (input.x / input.maxX) * 2 - 1;
28 y = (input.y / input.maxY) * 2 - 1;
29 z = (input.z / input.maxZ) * 2 - 1;
30 return NodeOutput({(float)parser->Eval() * factor});
31 }
32
33 catch (...)
34 {
35 }
36
37 return NodeOutput({0.0f});
38}
39
40void MathFunctionNode::Load(nlohmann::json data)
41{
42 std::string expr = data["expr"];
43 memcpy(inputExpression, expr.data(), data.size());
44 mathInputWidth = data["mathInputWidth"];
45 factor = data["factor"];
46 /*
47 vars.clear();
48 parser->ClearVar();
49 parser->DefineVar(L"x", &x);
50 parser->DefineVar(L"y", &y);
51 parser->DefineVar(L"z", &z);
52 for (auto& tmp : data["vars"])
53 {
54 vars.push_back(std::make_pair<std::string, double>(tmp["name"], tmp["value"]));
55 parser->DefineVar(s2ws(vars.back().first), &vars.back().second);
56 }
57 */
58}
59
60nlohmann::json MathFunctionNode::Save()
61{
62 nlohmann::json data;
64 nlohmann::json tmp2;
65 data["type"] = MeshNodeEditor::MeshNodeType::MathFunction;
66 data["expr"] = std::string(inputExpression);
67 data["mathInputWidth"] = mathInputWidth;
68 data["factor"] = factor;
69 /*
70 for (int i = 0; i < vars.size(); i++)
71 {
72 tmp2.clear();
73 tmp2["name"] = vars[i].first;
74 tmp2["value"] = vars[i].second;
75 tmp.push_back(tmp2);
76 }
77 data["vars"] = tmp;
78 */
79 return data;
80}
81
82void MathFunctionNode::OnRender()
83{
84 DrawHeader("Custom Math Function");
85 ImGui::Dummy(ImVec2(mathInputWidth + 20, 10));
86 ImGui::SameLine();
87 ImGui::Text("Out");
88 outputPins[0]->Render();
89 ImGui::NewLine();
90 ImGui::Text("Math Input Size : ");
91 ImGui::SameLine();
92 ImGui::PushItemWidth(100);
93 ImGui::DragInt(MAKE_IMGUI_ID(outputPins[0]->id), &mathInputWidth, 0.5f);
94 ImGui::PopItemWidth();
95 inputPins[0]->Render();
96
97 if (inputPins[0]->IsLinked())
98 {
99 ImGui::Text("Factor");
100 }
101
102 else
103 {
104 ImGui::PushItemWidth(100);
105 ImGui::DragFloat(MAKE_IMGUI_ID(inputPins[0]->id), &factor, 0.01f);
106 ImGui::PopItemWidth();
107 }
108
109 ImGui::NewLine();
110 /*
111 ImGui::Text("Varaibles : ");
112 for (int i = 0;i<vars.size();i++)
113 {
114 ImGui::PushItemWidth(200);
115 ImGui::InputDouble(MAKE_IMGUI_LABEL(i, vars[i].first.c_str()), &vars[i].second, 0.01f);
116 ImGui::PopItemWidth();
117 ImGui::SameLine();
118 if (ImGui::Button("X"))
119 {
120 parser->RemoveVar(s2ws(vars[i].first));
121 vars.erase(vars.begin() + i);
122 break;
123 }
124 }
125
126 ImGui::Text("Add Variable : ");
127 ImGui::SameLine();
128 ImGui::PushItemWidth(100);
129 ImGui::InputTextWithHint(MAKE_IMGUI_ID(tid), "Name", varname, sizeof(varname));
130 ImGui::SameLine();
131 ImGui::PopItemWidth();
132 ImGui::SameLine();
133 if (ImGui::Button("Add") && strlen(varname) >= 1)
134 {
135 vars.push_back(std::make_pair<std::string, double>(varname, 0.0f));
136 parser->DefineVar(s2ws(std::string(varname)), &vars.back().second);
137 memset(varname, 0, sizeof(varname));
138 }
139
140 */
141 ImGui::Text("Expression : ");
142 ImGui::SameLine();
143 ImGui::PushItemWidth(mathInputWidth);
144
145 if (ImGui::InputText(MAKE_IMGUI_ID(id), inputExpression, 1024*4))
146 {
147 compiled = false;
148 }
149
150 ImGui::PopItemWidth();
151
152 if (!compiled)
153 {
154 if (ImGui::Button("Compile"))
155 {
156 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
157 std::wstring wide = converter.from_bytes(inputExpression);
158
159 try
160 {
161#ifdef TERR3D_WIN32
162 parser->SetExpr(wide);
163#else
164 parser->SetExpr(std::string(inputExpression));
165#endif
166 compiled = true;
167 }
168
169 catch (...)
170 {
171 }
172 }
173 }
174}
175
176MathFunctionNode::MathFunctionNode()
177{
178 headerColor = ImColor(VALUE_NODE_COLOR);
179 inputPins.push_back(new NodeEditorPin());
180 outputPins.push_back(new NodeEditorPin(NodeEditorPinType::Output));
181 parser = new mu::Parser();
182 memset(inputExpression, 0, sizeof(inputExpression));
183 memset(varname, 0, sizeof(varname));
184 x = y = z = 0;
185 factor = 1;
186 mathInputWidth = 150;
187 compiled = false;
188 SetupParser(parser);
189#ifdef TERR3D_WIN32
190 parser->DefineVar(L"x", &x);
191 parser->DefineVar(L"y", &y);
192 parser->DefineVar(L"z", &z);
193#else
194 parser->DefineVar("x", &x);
195 parser->DefineVar("y", &y);
196 parser->DefineVar("z", &z);
197#endif
198}
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:22912
a class to store JSON values
Definition: json.hpp:17860