Geometry Nodes: Mix Rotations #109084
|
@ -10,6 +10,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
mod_moder marked this conversation as resolved
Outdated
|
||||
|
||||
|
@ -513,6 +514,14 @@ static const EnumPropertyItem rna_node_combsep_color_items[] = {
|
|||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem rna_enum_mix_data_type_items[] = {
|
||||
{SOCK_FLOAT, "FLOAT", 0, "Float", ""},
|
||||
{SOCK_VECTOR, "VECTOR", 0, "Vector", ""},
|
||||
{SOCK_RGBA, "RGBA", 0, "Color", ""},
|
||||
{SOCK_ROTATION, "ROTATION", 0, "Rotation", ""},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
#ifndef RNA_RUNTIME
|
||||
static const EnumPropertyItem node_sampler_type_items[] = {
|
||||
{0, "NEAREST", 0, "Nearest", ""},
|
||||
|
@ -2062,7 +2071,7 @@ static StructRNA *rna_Node_register(Main *bmain,
|
|||
|
||||
static const EnumPropertyItem *itemf_function_check(
|
||||
const EnumPropertyItem *original_item_array,
|
||||
bool (*value_supported)(const EnumPropertyItem *item))
|
||||
blender::FunctionRef<bool(const EnumPropertyItem *item)> value_supported)
|
||||
{
|
||||
EnumPropertyItem *item_array = nullptr;
|
||||
int items_len = 0;
|
||||
|
@ -3793,6 +3802,27 @@ static const EnumPropertyItem *renderresult_layers_add_enum(RenderLayer *rl)
|
|||
return item;
|
||||
}
|
||||
|
||||
static const EnumPropertyItem *rna_ShaderNodeMix_data_type_itemf(bContext * /*C*/,
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA * /*prop*/,
|
||||
bool *r_free)
|
||||
{
|
||||
*r_free = true;
|
||||
|
||||
const auto rotation_supported_mix = [&](const EnumPropertyItem *item) -> bool {
|
||||
const eNodeSocketDatatype data_type = eNodeSocketDatatype(item->value);
|
||||
mod_moder marked this conversation as resolved
Outdated
Hans Goudey
commented
`[ptr]` -> `[&]`
|
||||
if (U.experimental.use_rotation_socket && data_type == SOCK_ROTATION) {
|
||||
const bNodeTree *tree = reinterpret_cast<const bNodeTree *>(ptr->owner_id);
|
||||
if (tree->type == NTREE_GEOMETRY) {
|
||||
return true;
|
||||
mod_moder marked this conversation as resolved
Hans Goudey
commented
This assert is unnecessary IMO, the pointer is de-referenced in the next line which shows it's not expected to be null. This assert is unnecessary IMO, the pointer is de-referenced in the next line which shows it's not expected to be null.
|
||||
}
|
||||
}
|
||||
return ELEM(data_type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA);
|
||||
};
|
||||
|
||||
return itemf_function_check(rna_enum_mix_data_type_items, rotation_supported_mix);
|
||||
}
|
||||
|
||||
static const EnumPropertyItem *rna_Node_image_layer_itemf(bContext * /*C*/,
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA * /*prop*/,
|
||||
|
@ -5206,13 +5236,6 @@ static void def_compare(StructRNA *srna)
|
|||
|
||||
static void def_sh_mix(StructRNA *srna)
|
||||
{
|
||||
static const EnumPropertyItem rna_enum_mix_data_type_items[] = {
|
||||
{SOCK_FLOAT, "FLOAT", 0, "Float", ""},
|
||||
{SOCK_VECTOR, "VECTOR", 0, "Vector", ""},
|
||||
{SOCK_RGBA, "RGBA", 0, "Color", ""},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem rna_enum_mix_mode_items[] = {
|
||||
{NODE_MIX_MODE_UNIFORM, "UNIFORM", 0, "Uniform", "Use a single factor for all components"},
|
||||
{NODE_MIX_MODE_NON_UNIFORM, "NON_UNIFORM", 0, "Non-Uniform", "Per component factor"},
|
||||
|
@ -5224,6 +5247,7 @@ static void def_sh_mix(StructRNA *srna)
|
|||
RNA_def_struct_sdna_from(srna, "NodeShaderMix", "storage");
|
||||
|
||||
prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_funcs(prop, nullptr, nullptr, "rna_ShaderNodeMix_data_type_itemf");
|
||||
RNA_def_property_enum_items(prop, rna_enum_mix_data_type_items);
|
||||
RNA_def_property_enum_default(prop, SOCK_FLOAT);
|
||||
RNA_def_property_ui_text(prop, "Data Type", "");
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "BLI_math_quaternion.hh"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
|
@ -62,26 +64,37 @@ static void sh_node_mix_declare(NodeDeclarationBuilder &b)
|
|||
.default_value({0.5f, 0.5f, 0.5f, 1.0f})
|
||||
.translation_context(BLT_I18NCONTEXT_ID_NODETREE);
|
||||
|
||||
b.add_input<decl::Rotation>("A", "A_Rotation")
|
||||
.is_default_link_socket()
|
||||
.translation_context(BLT_I18NCONTEXT_ID_NODETREE);
|
||||
b.add_input<decl::Rotation>("B", "B_Rotation").translation_context(BLT_I18NCONTEXT_ID_NODETREE);
|
||||
|
||||
b.add_output<decl::Float>("Result", "Result_Float");
|
||||
b.add_output<decl::Vector>("Result", "Result_Vector");
|
||||
b.add_output<decl::Color>("Result", "Result_Color");
|
||||
b.add_output<decl::Rotation>("Result", "Result_Rotation");
|
||||
};
|
||||
|
||||
static void sh_node_mix_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
|
||||
{
|
||||
const NodeShaderMix &data = node_storage(*static_cast<const bNode *>(ptr->data));
|
||||
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
|
||||
if (data.data_type == SOCK_VECTOR) {
|
||||
uiItemR(layout, ptr, "factor_mode", 0, "", ICON_NONE);
|
||||
}
|
||||
if (data.data_type == SOCK_RGBA) {
|
||||
uiItemR(layout, ptr, "blend_type", 0, "", ICON_NONE);
|
||||
uiItemR(layout, ptr, "clamp_result", 0, nullptr, ICON_NONE);
|
||||
uiItemR(layout, ptr, "clamp_factor", 0, nullptr, ICON_NONE);
|
||||
}
|
||||
else {
|
||||
uiItemR(layout, ptr, "clamp_factor", 0, nullptr, ICON_NONE);
|
||||
switch (data.data_type) {
|
||||
case SOCK_FLOAT:
|
||||
break;
|
||||
case SOCK_VECTOR:
|
||||
uiItemR(layout, ptr, "factor_mode", 0, "", ICON_NONE);
|
||||
break;
|
||||
case SOCK_RGBA:
|
||||
uiItemR(layout, ptr, "blend_type", 0, "", ICON_NONE);
|
||||
uiItemR(layout, ptr, "clamp_result", 0, nullptr, ICON_NONE);
|
||||
break;
|
||||
case SOCK_ROTATION:
|
||||
break;
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
uiItemR(layout, ptr, "clamp_factor", 0, nullptr, ICON_NONE);
|
||||
}
|
||||
|
||||
static void sh_node_mix_label(const bNodeTree * /*ntree*/,
|
||||
|
@ -167,6 +180,9 @@ static void node_mix_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
|||
case SOCK_RGBA:
|
||||
type = SOCK_RGBA;
|
||||
break;
|
||||
case SOCK_ROTATION:
|
||||
type = SOCK_ROTATION;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -210,15 +226,21 @@ static void node_mix_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
|||
weight);
|
||||
weight--;
|
||||
}
|
||||
params.add_item(
|
||||
IFACE_("Factor"),
|
||||
[type](LinkSearchOpParams ¶ms) {
|
||||
bNode &node = params.add_node("ShaderNodeMix");
|
||||
node_storage(node).data_type = type;
|
||||
params.update_and_connect_available_socket(node, "Factor");
|
||||
},
|
||||
weight);
|
||||
weight--;
|
||||
if (type != SOCK_ROTATION) {
|
||||
params.add_item(
|
||||
IFACE_("Factor"),
|
||||
[type](LinkSearchOpParams ¶ms) {
|
||||
bNode &node = params.add_node("ShaderNodeMix");
|
||||
node_storage(node).data_type = type;
|
||||
params.update_and_connect_available_socket(node, "Factor");
|
||||
},
|
||||
weight);
|
||||
weight--;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == SOCK_ROTATION) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type != SOCK_RGBA) {
|
||||
|
@ -309,6 +331,8 @@ static const char *gpu_shader_get_name(eNodeSocketDatatype data_type,
|
|||
BLI_assert_unreachable();
|
||||
return nullptr;
|
||||
}
|
||||
case SOCK_ROTATION:
|
||||
return nullptr;
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
return nullptr;
|
||||
|
@ -480,6 +504,26 @@ static const mf::MultiFunction *get_multi_function(const bNode &node)
|
|||
}
|
||||
}
|
||||
}
|
||||
case SOCK_ROTATION: {
|
||||
if (clamp_factor) {
|
||||
static auto fn =
|
||||
mf::build::SI3_SO<float, math::Quaternion, math::Quaternion, math::Quaternion>(
|
||||
"Clamp Mix Rotation",
|
||||
[](const float t, const math::Quaternion &a, const math::Quaternion &b) {
|
||||
return math::interpolate(a, b, math::clamp(t, 0.0f, 1.0f));
|
||||
});
|
||||
return &fn;
|
||||
}
|
||||
else {
|
||||
static auto fn =
|
||||
mf::build::SI3_SO<float, math::Quaternion, math::Quaternion, math::Quaternion>(
|
||||
"Mix Rotation",
|
||||
[](const float t, const math::Quaternion &a, const math::Quaternion &b) {
|
||||
return math::interpolate(a, b, t);
|
||||
});
|
||||
return &fn;
|
||||
}
|
||||
}
|
||||
}
|
||||
BLI_assert_unreachable();
|
||||
return nullptr;
|
||||
|
|
Loading…
Reference in New Issue
Group this with the other BLI includes