Geometry Nodes: Add Random Rotation node #109846
@ -1357,6 +1357,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
|
||||
#define FN_NODE_ROTATE_VECTOR 1229
|
||||
#define FN_NODE_ROTATE_ROTATION 1230
|
||||
#define FN_NODE_INVERT_ROTATION 1231
|
||||
#define FN_NODE_RANDOM_ROTATION 1232
|
||||
|
||||
/** \} */
|
||||
|
||||
|
@ -2031,17 +2031,19 @@ static void rna_GeometryNodeTree_is_type_point_cloud_set(PointerRNA *ptr, bool v
|
||||
geometry_node_asset_trait_flag_set(ptr, GEO_NODE_ASSET_POINT_CLOUD, value);
|
||||
}
|
||||
|
||||
static bool random_value_type_supported(const EnumPropertyItem *item)
|
||||
{
|
||||
return ELEM(item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_BOOL, CD_PROP_INT32);
|
||||
}
|
||||
static const EnumPropertyItem *rna_FunctionNodeRandomValue_type_itemf(bContext * /*C*/,
|
||||
PointerRNA * /*ptr*/,
|
||||
PropertyRNA * /*prop*/,
|
||||
bool *r_free)
|
||||
{
|
||||
*r_free = true;
|
||||
return itemf_function_check(rna_enum_attribute_type_items, random_value_type_supported);
|
||||
|
||||
const auto type_supported = [&](const EnumPropertyItem* item) -> bool {
|
||||
const eCustomDataType data_type = eCustomDataType(item->value);
|
||||
return ELEM(data_type, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_BOOL, CD_PROP_INT32);
|
||||
};
|
||||
|
||||
return itemf_function_check(rna_enum_attribute_type_items, type_supported);
|
||||
}
|
||||
|
||||
static bool accumulate_field_type_supported(const EnumPropertyItem *item)
|
||||
|
@ -279,6 +279,7 @@ DefNode(FunctionNode, FN_NODE_INPUT_STRING, def_fn_input_string, "INPUT_STRING",
|
||||
DefNode(FunctionNode, FN_NODE_INPUT_VECTOR, def_fn_input_vector, "INPUT_VECTOR", InputVector, "Vector", "")
|
||||
DefNode(FunctionNode, FN_NODE_INVERT_ROTATION, 0, "INVERT_ROTATION", InvertRotation, "Invert Rotation", "")
|
||||
DefNode(FunctionNode, FN_NODE_RANDOM_VALUE, def_fn_random_value, "RANDOM_VALUE", RandomValue, "Random Value", "")
|
||||
DefNode(FunctionNode, FN_NODE_RANDOM_ROTATION, 0, "RANDOM_ROTATION", RandomRotation, "Random Rotation", "")
|
||||
DefNode(FunctionNode, FN_NODE_REPLACE_STRING, 0, "REPLACE_STRING", ReplaceString, "Replace String", "")
|
||||
DefNode(FunctionNode, FN_NODE_ROTATE_EULER, def_fn_rotate_euler, "ROTATE_EULER", RotateEuler, "Rotate Euler", "")
|
||||
DefNode(FunctionNode, FN_NODE_ROTATE_VECTOR, 0, "ROTATE_VECTOR", RotateVector, "Rotate Vector", "")
|
||||
|
@ -34,6 +34,7 @@ set(SRC
|
||||
nodes/node_fn_invert_rotation.cc
|
||||
nodes/node_fn_quaternion_to_rotation.cc
|
||||
nodes/node_fn_random_value.cc
|
||||
nodes/node_fn_random_rotation.cc
|
||||
nodes/node_fn_replace_string.cc
|
||||
nodes/node_fn_rotate_euler.cc
|
||||
nodes/node_fn_rotate_vector.cc
|
||||
|
@ -0,0 +1,57 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_noise.hh"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
|
||||
#include "BLI_math_quaternion.hh"
|
||||
|
||||
namespace blender::nodes::node_fn_random_rotation_cc {
|
||||
|
||||
NODE_STORAGE_FUNCS(NodeRandomValue)
|
||||
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Int>("ID").implicit_field(implicit_field_inputs::id_or_index);
|
||||
b.add_input<decl::Int>("Seed").default_value(0).min(-10000).max(10000).supports_field();
|
||||
|
||||
b.add_output<decl::Rotation>("Rotation").dependent_field();
|
||||
}
|
||||
|
||||
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
|
||||
{
|
||||
static auto fn = mf::build::SI2_SO<int, int, math::Quaternion>(
|
||||
"Random Rotation",
|
||||
[](int id, int seed) -> math::Quaternion {
|
||||
const float s = noise::hash_to_float(seed, id, 0);
|
||||
const float sigma1 = math::sqrt(1.0f - s);
|
||||
const float sigma2 = math::sqrt(s);
|
||||
const float theta1 = M_PI * 2 * noise::hash_to_float(seed, id, 1);
|
||||
const float theta2 = M_PI * 2 * noise::hash_to_float(seed, id, 2);
|
||||
const float w = math::cos(theta2) * sigma2;
|
||||
const float x = math::sin(theta1) * sigma1;
|
||||
const float y = math::cos(theta1) * sigma1;
|
||||
const float z = math::sin(theta2) * sigma2;
|
||||
return math::Quaternion(w, x, y, z);
|
||||
},
|
||||
mf::build::exec_presets::SomeSpanOrSingle<2>()
|
||||
);
|
||||
builder.set_matching_fn(fn);
|
||||
}
|
||||
|
||||
static void node_register()
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
fn_node_type_base(&ntype, FN_NODE_RANDOM_ROTATION, "Random Rotation", NODE_CLASS_CONVERTER);
|
||||
ntype.declare = node_declare;
|
||||
ntype.build_multi_function = node_build_multi_function;
|
||||
node_type_storage(
|
||||
&ntype, "NodeRandomRotation", node_free_standard_storage, node_copy_standard_storage);
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
NOD_REGISTER_NODE(node_register)
|
||||
|
||||
} // namespace blender::nodes::node_fn_random_value_cc
|
@ -2,7 +2,6 @@
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
// #include "BLI_hash.h"
|
||||
#include "BLI_noise.hh"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
@ -44,7 +43,7 @@ static void node_declare(NodeDeclarationBuilder &b)
|
||||
b.add_output<decl::Bool>("Value", "Value_003").dependent_field();
|
||||
}
|
||||
|
||||
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
|
||||
static void node_layout(uiLayout* layout, bContext* /*C*/, PointerRNA* ptr)
|
||||
{
|
||||
uiItemR(layout, ptr, "data_type", UI_ITEM_NONE, "", ICON_NONE);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user