2026-03-09 13:17:15 +01:00
|
|
|
|
|
|
|
|
#include "../global.h"
|
|
|
|
|
|
2026-03-06 12:56:38 +01:00
|
|
|
void vector_math2_node_init() {
|
2026-03-31 18:47:10 +02:00
|
|
|
|
|
|
|
|
char *vector_math_operation_data =
|
2026-04-03 13:32:16 +02:00
|
|
|
string("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", _tr("Add"), _tr("Subtract"), _tr("Multiply"),
|
2026-03-31 18:47:10 +02:00
|
|
|
_tr("Divide"), _tr("Average"), _tr("Cross Product"), _tr("Project"), _tr("Reflect"), _tr("Dot Product"), _tr("Distance"), _tr("Length"),
|
2026-04-03 13:32:16 +02:00
|
|
|
_tr("Scale"), _tr("Normalize"), _tr("Absolute"), _tr("Power"), _tr("Sign"), _tr("Minimum"), _tr("Maximum"), _tr("Floor"), _tr("Ceil"),
|
|
|
|
|
_tr("Fraction"), _tr("Modulo"), _tr("Snap"), _tr("Sine"), _tr("Cosine"), _tr("Tangent"));
|
2026-03-31 18:47:10 +02:00
|
|
|
vector_math2_node_def =
|
|
|
|
|
GC_ALLOC_INIT(ui_node_t, {.id = 0,
|
|
|
|
|
.name = _tr("Vector Math"),
|
|
|
|
|
.type = "VECT_MATH",
|
|
|
|
|
.x = 0,
|
|
|
|
|
.y = 0,
|
|
|
|
|
.color = 0xff62676d,
|
|
|
|
|
.inputs = any_array_create_from_raw(
|
|
|
|
|
(void *[]){
|
|
|
|
|
GC_ALLOC_INIT(ui_node_socket_t, {.id = 0,
|
|
|
|
|
.node_id = 0,
|
|
|
|
|
.name = _tr("Vector"),
|
|
|
|
|
.type = "VECTOR",
|
|
|
|
|
.color = 0xff6363c7,
|
|
|
|
|
.default_value = f32_array_create_xyz(0.0, 0.0, 0.0),
|
|
|
|
|
.min = 0.0,
|
|
|
|
|
.max = 1.0,
|
|
|
|
|
.precision = 100,
|
|
|
|
|
.display = 1}),
|
|
|
|
|
GC_ALLOC_INIT(ui_node_socket_t, {.id = 0,
|
|
|
|
|
.node_id = 0,
|
|
|
|
|
.name = _tr("Vector"),
|
|
|
|
|
.type = "VECTOR",
|
|
|
|
|
.color = 0xff6363c7,
|
|
|
|
|
.default_value = f32_array_create_xyz(0.0, 0.0, 0.0),
|
|
|
|
|
.min = 0.0,
|
|
|
|
|
.max = 1.0,
|
|
|
|
|
.precision = 100,
|
|
|
|
|
.display = 1}),
|
|
|
|
|
},
|
|
|
|
|
2),
|
|
|
|
|
.outputs = any_array_create_from_raw(
|
|
|
|
|
(void *[]){
|
|
|
|
|
GC_ALLOC_INIT(ui_node_socket_t, {.id = 0,
|
|
|
|
|
.node_id = 0,
|
|
|
|
|
.name = _tr("Vector"),
|
|
|
|
|
.type = "VECTOR",
|
|
|
|
|
.color = 0xff6363c7,
|
|
|
|
|
.default_value = f32_array_create_xyz(0.0, 0.0, 0.0),
|
|
|
|
|
.min = 0.0,
|
|
|
|
|
.max = 1.0,
|
|
|
|
|
.precision = 100,
|
|
|
|
|
.display = 0}),
|
|
|
|
|
GC_ALLOC_INIT(ui_node_socket_t, {.id = 0,
|
|
|
|
|
.node_id = 0,
|
|
|
|
|
.name = _tr("Value"),
|
|
|
|
|
.type = "VALUE",
|
|
|
|
|
.color = 0xffa1a1a1,
|
|
|
|
|
.default_value = f32_array_create_x(0.0),
|
|
|
|
|
.min = 0.0,
|
|
|
|
|
.max = 1.0,
|
|
|
|
|
.precision = 100,
|
|
|
|
|
.display = 0}),
|
|
|
|
|
},
|
|
|
|
|
2),
|
|
|
|
|
.buttons = any_array_create_from_raw(
|
|
|
|
|
(void *[]){
|
|
|
|
|
GC_ALLOC_INIT(ui_node_button_t, {.name = _tr("operation"),
|
|
|
|
|
.type = "ENUM",
|
|
|
|
|
.output = 0,
|
|
|
|
|
.default_value = f32_array_create_x(0),
|
|
|
|
|
.data = u8_array_create_from_string(vector_math_operation_data),
|
|
|
|
|
.min = 0.0,
|
|
|
|
|
.max = 1.0,
|
|
|
|
|
.precision = 100,
|
|
|
|
|
.height = 0}),
|
|
|
|
|
},
|
|
|
|
|
1),
|
|
|
|
|
.width = 0,
|
|
|
|
|
.flags = 0});
|
|
|
|
|
gc_root(vector_math2_node_def);
|
|
|
|
|
|
2026-03-06 12:56:38 +01:00
|
|
|
any_array_push(nodes_material_utilities, vector_math2_node_def);
|
|
|
|
|
any_map_set(parser_material_node_vectors, "VECT_MATH", vector_math2_node_vector);
|
|
|
|
|
any_map_set(parser_material_node_values, "VECT_MATH", vector_math2_node_value);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-07 21:12:59 +01:00
|
|
|
char *vector_math2_node_vector(ui_node_t *node, ui_node_socket_t *socket) {
|
2026-03-10 11:49:57 +01:00
|
|
|
char *vec1 = parser_material_parse_vector_input(node->inputs->buffer[0]);
|
|
|
|
|
char *vec2 = parser_material_parse_vector_input(node->inputs->buffer[1]);
|
2026-03-06 12:56:38 +01:00
|
|
|
ui_node_button_t *but = node->buttons->buffer[0]; // operation;
|
2026-03-10 11:49:57 +01:00
|
|
|
char *op = to_upper_case(u8_array_string_at(but->data, but->default_value->buffer[0]));
|
2026-03-06 12:56:38 +01:00
|
|
|
op = string_copy(string_replace_all(op, " ", "_"));
|
|
|
|
|
if (string_equals(op, "ADD")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("(%s + %s)", vec1, vec2);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "SUBTRACT")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("(%s - %s)", vec1, vec2);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "AVERAGE")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("((%s + %s) / 2.0)", vec1, vec2);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "DOT_PRODUCT")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return parser_material_to_vec3(string("dot(%s, %s)", vec1, vec2));
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "LENGTH")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return parser_material_to_vec3(string("length(%s)", vec1));
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "DISTANCE")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return parser_material_to_vec3(string("distance(%s, %s)", vec1, vec2));
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "CROSS_PRODUCT")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("cross(%s, %s)", vec1, vec2);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "NORMALIZE")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("normalize(%s)", vec1);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "MULTIPLY")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("(%s * %s)", vec1, vec2);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "DIVIDE")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
char *store = string("%s_vec2", parser_material_store_var_name(node));
|
|
|
|
|
parser_material_write(parser_material_kong, string("var %s: float3 = %s;", store, vec2));
|
|
|
|
|
parser_material_write(parser_material_kong, string("if (%s.x == 0.0) { %s.x = 0.000001; }", store, store));
|
|
|
|
|
parser_material_write(parser_material_kong, string("if (%s.y == 0.0) { %s.y = 0.000001; }", store, store));
|
|
|
|
|
parser_material_write(parser_material_kong, string("if (%s.z == 0.0) { %s.z = 0.000001; }", store, store));
|
|
|
|
|
return string("(%s / %s)", vec1, vec2);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "PROJECT")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("(dot(%s, %s) / dot(%s, %s) * %s)", vec1, vec2, vec2, vec2, vec2);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "REFLECT")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("reflect(%s, normalize(%s))", vec1, vec2);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "SCALE")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("(%s.x * %s)", vec2, vec1);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "ABSOLUTE")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("abs3(%s)", vec1);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
2026-04-03 13:32:16 +02:00
|
|
|
else if (string_equals(op, "POWER")) {
|
|
|
|
|
return string("float3(pow(%s.x, %s.x), pow(%s.y, %s.y), pow(%s.z, %s.z))", vec1, vec2, vec1, vec2, vec1, vec2);
|
|
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "SIGN")) {
|
|
|
|
|
return string("float3(sign(%s.x), sign(%s.y), sign(%s.z))", vec1, vec1, vec1);
|
|
|
|
|
}
|
2026-03-06 12:56:38 +01:00
|
|
|
else if (string_equals(op, "MINIMUM")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("min3(%s, %s)", vec1, vec2);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "MAXIMUM")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("max3(%s, %s)", vec1, vec2);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "FLOOR")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("floor3(%s)", vec1);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "CEIL")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("ceil3(%s)", vec1);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "FRACTION")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("frac3(%s)", vec1);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "MODULO")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("(%s %% %s)", vec1, vec2);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "SNAP")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("(floor3(%s / %s) * %s)", vec1, vec2, vec2);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "SINE")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("float3(sin(%s.x), sin(%s.y), sin(%s.z))", vec1, vec1, vec1);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "COSINE")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("float3(cos(%s.x), cos(%s.y), cos(%s.z))", vec1, vec1, vec1);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else { // TANGENT
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("float3(tan(%s.x), tan(%s.y), tan(%s.z))", vec1, vec1, vec1);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-07 21:12:59 +01:00
|
|
|
char *vector_math2_node_value(ui_node_t *node, ui_node_socket_t *socket) {
|
2026-03-10 11:49:57 +01:00
|
|
|
char *vec1 = parser_material_parse_vector_input(node->inputs->buffer[0]);
|
|
|
|
|
char *vec2 = parser_material_parse_vector_input(node->inputs->buffer[1]);
|
2026-03-06 12:56:38 +01:00
|
|
|
ui_node_button_t *but = node->buttons->buffer[0]; // operation;
|
2026-03-10 11:49:57 +01:00
|
|
|
char *op = to_upper_case(u8_array_string_at(but->data, but->default_value->buffer[0]));
|
2026-03-06 12:56:38 +01:00
|
|
|
op = string_copy(string_replace_all(op, " ", "_"));
|
|
|
|
|
if (string_equals(op, "DOT_PRODUCT")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("dot(%s, %s)", vec1, vec2);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "LENGTH")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("length(%s)", vec1);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else if (string_equals(op, "DISTANCE")) {
|
2026-03-10 11:49:57 +01:00
|
|
|
return string("distance(%s, %s)", vec1, vec2);
|
2026-03-06 12:56:38 +01:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return "0.0";
|
|
|
|
|
}
|
|
|
|
|
}
|