godot_voxel/generators/graph/voxel_graph_node_db.cpp

440 lines
12 KiB
C++

#include "voxel_graph_node_db.h"
namespace {
VoxelGraphNodeDB *g_node_type_db = nullptr;
}
VoxelGraphNodeDB *VoxelGraphNodeDB::get_singleton() {
CRASH_COND(g_node_type_db == nullptr);
return g_node_type_db;
}
void VoxelGraphNodeDB::create_singleton() {
CRASH_COND(g_node_type_db != nullptr);
g_node_type_db = memnew(VoxelGraphNodeDB());
}
void VoxelGraphNodeDB::destroy_singleton() {
CRASH_COND(g_node_type_db == nullptr);
memdelete(g_node_type_db);
g_node_type_db = nullptr;
}
const char *VoxelGraphNodeDB::get_category_name(Category category) {
switch (category) {
case CATEGORY_INPUT:
return "Input";
case CATEGORY_OUTPUT:
return "Output";
case CATEGORY_MATH:
return "Math";
case CATEGORY_CONVERT:
return "Convert";
case CATEGORY_GENERATE:
return "Generate";
case CATEGORY_SDF:
return "Sdf";
case CATEGORY_DEBUG:
return "Debug";
default:
CRASH_NOW_MSG("Unhandled category");
}
return "";
}
VoxelGraphNodeDB::VoxelGraphNodeDB() {
FixedArray<NodeType, VoxelGeneratorGraph::NODE_TYPE_COUNT> &types = _types;
{
NodeType &t = types[VoxelGeneratorGraph::NODE_CONSTANT];
t.name = "Constant";
t.category = CATEGORY_INPUT;
t.outputs.push_back(Port("value"));
t.params.push_back(Param("value", Variant::REAL));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_INPUT_X];
t.name = "InputX";
t.category = CATEGORY_INPUT;
t.outputs.push_back(Port("x"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_INPUT_Y];
t.name = "InputY";
t.category = CATEGORY_INPUT;
t.outputs.push_back(Port("y"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_INPUT_Z];
t.name = "InputZ";
t.category = CATEGORY_INPUT;
t.outputs.push_back(Port("z"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_OUTPUT_SDF];
t.name = "OutputSDF";
t.category = CATEGORY_OUTPUT;
t.inputs.push_back(Port("sdf"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_ADD];
t.name = "Add";
t.category = CATEGORY_MATH;
t.inputs.push_back(Port("a"));
t.inputs.push_back(Port("b"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_SUBTRACT];
t.name = "Subtract";
t.category = CATEGORY_MATH;
t.inputs.push_back(Port("a"));
t.inputs.push_back(Port("b"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_MULTIPLY];
t.name = "Multiply";
t.category = CATEGORY_MATH;
t.inputs.push_back(Port("a"));
t.inputs.push_back(Port("b"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_DIVIDE];
t.name = "Divide";
t.category = CATEGORY_MATH;
t.inputs.push_back(Port("a"));
t.inputs.push_back(Port("b"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_SIN];
t.name = "Sin";
t.category = CATEGORY_MATH;
t.inputs.push_back(Port("x"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_FLOOR];
t.name = "Floor";
t.category = CATEGORY_MATH;
t.inputs.push_back(Port("x"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_ABS];
t.name = "Abs";
t.category = CATEGORY_MATH;
t.inputs.push_back(Port("x"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_SQRT];
t.name = "Sqrt";
t.category = CATEGORY_MATH;
t.inputs.push_back(Port("x"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_FRACT];
t.name = "Fract";
t.category = CATEGORY_MATH;
t.inputs.push_back(Port("x"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_STEPIFY];
t.name = "Stepify";
t.category = CATEGORY_CONVERT;
t.inputs.push_back(Port("x"));
t.inputs.push_back(Port("step"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_WRAP];
t.name = "Wrap";
t.category = CATEGORY_MATH;
t.inputs.push_back(Port("x"));
t.inputs.push_back(Port("length"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_MIN];
t.name = "Min";
t.category = CATEGORY_MATH;
t.inputs.push_back(Port("a"));
t.inputs.push_back(Port("b"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_MAX];
t.name = "Max";
t.category = CATEGORY_MATH;
t.inputs.push_back(Port("a"));
t.inputs.push_back(Port("b"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_DISTANCE_2D];
t.name = "Distance2D";
t.category = CATEGORY_MATH;
t.inputs.push_back(Port("x0"));
t.inputs.push_back(Port("y0"));
t.inputs.push_back(Port("x1"));
t.inputs.push_back(Port("y1"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_DISTANCE_3D];
t.name = "Distance3D";
t.category = CATEGORY_MATH;
t.inputs.push_back(Port("x0"));
t.inputs.push_back(Port("y0"));
t.inputs.push_back(Port("z0"));
t.inputs.push_back(Port("x1"));
t.inputs.push_back(Port("y1"));
t.inputs.push_back(Port("z1"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_CLAMP];
t.name = "Clamp";
t.category = CATEGORY_CONVERT;
t.inputs.push_back(Port("x"));
t.outputs.push_back(Port("out"));
t.params.push_back(Param("min", Variant::REAL, -1.f));
t.params.push_back(Param("max", Variant::REAL, 1.f));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_MIX];
t.name = "Mix";
t.category = CATEGORY_CONVERT;
t.inputs.push_back(Port("a"));
t.inputs.push_back(Port("b"));
t.inputs.push_back(Port("ratio"));
t.outputs.push_back(Port("out"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_REMAP];
t.name = "Remap";
t.category = CATEGORY_CONVERT;
t.inputs.push_back(Port("x"));
t.outputs.push_back(Port("out"));
t.params.push_back(Param("min0", Variant::REAL, -1.f));
t.params.push_back(Param("max0", Variant::REAL, 1.f));
t.params.push_back(Param("min1", Variant::REAL, -1.f));
t.params.push_back(Param("max1", Variant::REAL, 1.f));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_SMOOTHSTEP];
t.name = "Smoothstep";
t.category = CATEGORY_CONVERT;
t.inputs.push_back(Port("x"));
t.outputs.push_back(Port("out"));
t.params.push_back(Param("edge0", Variant::REAL, 0.f));
t.params.push_back(Param("edge1", Variant::REAL, 1.f));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_CURVE];
t.name = "Curve";
t.category = CATEGORY_CONVERT;
t.inputs.push_back(Port("x"));
t.outputs.push_back(Port("out"));
t.params.push_back(Param("curve", "Curve"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_NOISE_2D];
t.name = "Noise2D";
t.category = CATEGORY_GENERATE;
t.inputs.push_back(Port("x"));
t.inputs.push_back(Port("y"));
t.outputs.push_back(Port("out"));
t.params.push_back(Param("noise", "OpenSimplexNoise"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_NOISE_3D];
t.name = "Noise3D";
t.category = CATEGORY_GENERATE;
t.inputs.push_back(Port("x"));
t.inputs.push_back(Port("y"));
t.inputs.push_back(Port("z"));
t.outputs.push_back(Port("out"));
t.params.push_back(Param("noise", "OpenSimplexNoise"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_IMAGE_2D];
t.name = "Image";
t.category = CATEGORY_GENERATE;
t.inputs.push_back(Port("x"));
t.inputs.push_back(Port("y"));
t.outputs.push_back(Port("out"));
t.params.push_back(Param("image", "Image"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_SDF_PLANE];
t.name = "SdfPlane";
t.category = CATEGORY_SDF;
t.inputs.push_back(Port("y"));
t.inputs.push_back(Port("height"));
t.outputs.push_back(Port("sdf"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_SDF_BOX];
t.name = "SdfBox";
t.category = CATEGORY_SDF;
t.inputs.push_back(Port("x"));
t.inputs.push_back(Port("y"));
t.inputs.push_back(Port("z"));
t.inputs.push_back(Port("size_x"));
t.inputs.push_back(Port("size_y"));
t.inputs.push_back(Port("size_z"));
t.outputs.push_back(Port("sdf"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_SDF_SPHERE];
t.name = "SdfSphere";
t.category = CATEGORY_SDF;
t.inputs.push_back(Port("x"));
t.inputs.push_back(Port("y"));
t.inputs.push_back(Port("z"));
t.inputs.push_back(Port("radius"));
t.outputs.push_back(Port("sdf"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_SDF_TORUS];
t.name = "SdfTorus";
t.category = CATEGORY_SDF;
t.inputs.push_back(Port("x"));
t.inputs.push_back(Port("y"));
t.inputs.push_back(Port("z"));
t.inputs.push_back(Port("radius1", 16.f));
t.inputs.push_back(Port("radius2", 4.f));
t.outputs.push_back(Port("sdf"));
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_SDF_PREVIEW];
t.name = "SdfPreview";
t.category = CATEGORY_DEBUG;
t.inputs.push_back(Port("value"));
t.params.push_back(Param("min_value", Variant::REAL, -1.f));
t.params.push_back(Param("max_value", Variant::REAL, 1.f));
t.debug_only = true;
}
{
NodeType &t = types[VoxelGeneratorGraph::NODE_SELECT];
t.name = "Select";
t.category = CATEGORY_CONVERT;
t.inputs.push_back(Port("a"));
t.inputs.push_back(Port("b"));
t.inputs.push_back(Port("threshold"));
t.inputs.push_back(Port("t"));
t.outputs.push_back(Port("out"));
}
for (unsigned int i = 0; i < _types.size(); ++i) {
NodeType &t = _types[i];
_type_name_to_id.set(t.name, (VoxelGeneratorGraph::NodeTypeID)i);
for (size_t param_index = 0; param_index < t.params.size(); ++param_index) {
Param &p = t.params[param_index];
t.param_name_to_index.set(p.name, param_index);
p.index = param_index;
switch (p.type) {
case Variant::REAL:
if (p.default_value.get_type() == Variant::NIL) {
p.default_value = 0.f;
}
break;
case Variant::OBJECT:
break;
default:
CRASH_NOW();
break;
}
}
for (size_t input_index = 0; input_index < t.inputs.size(); ++input_index) {
const Port &p = t.inputs[input_index];
t.input_name_to_index.set(p.name, input_index);
}
}
}
Dictionary VoxelGraphNodeDB::get_type_info_dict(uint32_t id) const {
const NodeType &type = _types[id];
Dictionary type_dict;
type_dict["name"] = type.name;
Array inputs;
inputs.resize(type.inputs.size());
for (size_t i = 0; i < type.inputs.size(); ++i) {
const Port &input = type.inputs[i];
Dictionary d;
d["name"] = input.name;
inputs[i] = d;
}
Array outputs;
outputs.resize(type.outputs.size());
for (size_t i = 0; i < type.outputs.size(); ++i) {
const Port &output = type.outputs[i];
Dictionary d;
d["name"] = output.name;
outputs[i] = d;
}
Array params;
params.resize(type.params.size());
for (size_t i = 0; i < type.params.size(); ++i) {
const Param &p = type.params[i];
Dictionary d;
d["name"] = p.name;
d["type"] = p.type;
d["class_name"] = p.class_name;
d["default_value"] = p.default_value;
params[i] = d;
}
type_dict["inputs"] = inputs;
type_dict["outputs"] = outputs;
type_dict["params"] = params;
return type_dict;
}
bool VoxelGraphNodeDB::try_get_type_id_from_name(const String &name, VoxelGeneratorGraph::NodeTypeID &out_type_id) const {
const VoxelGeneratorGraph::NodeTypeID *p = _type_name_to_id.getptr(name);
if (p == nullptr) {
return false;
}
out_type_id = *p;
return true;
}
bool VoxelGraphNodeDB::try_get_param_index_from_name(uint32_t type_id, const String &name, uint32_t &out_param_index) const {
ERR_FAIL_INDEX_V(type_id, _types.size(), false);
const NodeType &t = _types[type_id];
const uint32_t *p = t.param_name_to_index.getptr(name);
if (p == nullptr) {
return false;
}
out_param_index = *p;
return true;
}
bool VoxelGraphNodeDB::try_get_input_index_from_name(uint32_t type_id, const String &name, uint32_t &out_input_index) const {
ERR_FAIL_INDEX_V(type_id, _types.size(), false);
const NodeType &t = _types[type_id];
const uint32_t *p = t.input_name_to_index.getptr(name);
if (p == nullptr) {
return false;
}
out_input_index = *p;
return true;
}