mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Compositor: Port rotation nodes from geometry nodes
This patch adds support for Rotation sockets as well as existing nodes from Geometry Nodes. This includes the Rotate Vector, Invert Rotation, Rotation to Euler, Euler to Rotation, Rotate Rotation, Rotation to Axis Angle, Axis Angle to Rotation, Mix Rotation, Rotation to Quaternion, Quaternion to Rotation, Align Rotation to Vector, and Axes to Rotation nodes. Pull Request: https://projects.blender.org/blender/blender/pulls/154845
This commit is contained in:
parent
88610c0b25
commit
f1185c873b
92 changed files with 1303 additions and 64 deletions
|
|
@ -48,6 +48,7 @@ class NODE_MT_compositor_node_input_constant_base(node_add_menu.NodeMenu):
|
|||
self.node_operator(layout, "FunctionNodeInputMenu")
|
||||
self.node_operator(layout, "CompositorNodeNormal")
|
||||
self.node_operator(layout, "GeometryNodeInputObject")
|
||||
self.node_operator(layout, "FunctionNodeInputRotation")
|
||||
self.node_operator(layout, "FunctionNodeInputString")
|
||||
self.node_operator(layout, "ShaderNodeValue")
|
||||
self.node_operator(layout, "FunctionNodeInputVector")
|
||||
|
|
@ -290,6 +291,7 @@ class NODE_MT_compositor_node_utilities_base(node_add_menu.NodeMenu):
|
|||
self.draw_menu(layout, path="Utilities/Math")
|
||||
self.draw_menu(layout, path="Utilities/Vector")
|
||||
self.draw_menu(layout, path="Utilities/Matrix")
|
||||
self.draw_menu(layout, path="Utilities/Rotation")
|
||||
self.draw_menu(layout, path="Utilities/Text")
|
||||
layout.separator()
|
||||
self.node_operator(layout, "CompositorNodeLevels")
|
||||
|
|
@ -401,6 +403,31 @@ class NODE_MT_compositor_utilities_matrix_base(node_add_menu.NodeMenu):
|
|||
self.draw_assets_for_catalog(layout, self.menu_path)
|
||||
|
||||
|
||||
class NODE_MT_compositor_node_rotation_base(node_add_menu.NodeMenu):
|
||||
bl_label = "Rotation"
|
||||
menu_path = "Utilities/Rotation"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
self.node_operator(layout, "FunctionNodeAlignRotationToVector")
|
||||
self.node_operator(layout, "FunctionNodeAxesToRotation")
|
||||
self.node_operator(layout, "FunctionNodeAxisAngleToRotation")
|
||||
self.node_operator(layout, "FunctionNodeEulerToRotation")
|
||||
self.node_operator(layout, "FunctionNodeInvertRotation")
|
||||
props = self.node_operator(layout, "ShaderNodeMix", label="Mix Rotation")
|
||||
ops = props.settings.add()
|
||||
ops.name = "data_type"
|
||||
ops.value = "'ROTATION'"
|
||||
self.node_operator(layout, "FunctionNodeRotateRotation")
|
||||
self.node_operator(layout, "FunctionNodeRotateVector")
|
||||
self.node_operator(layout, "FunctionNodeRotationToAxisAngle")
|
||||
self.node_operator(layout, "FunctionNodeRotationToEuler")
|
||||
self.node_operator(layout, "FunctionNodeRotationToQuaternion")
|
||||
self.node_operator(layout, "FunctionNodeQuaternionToRotation")
|
||||
|
||||
self.draw_assets_for_catalog(layout, self.menu_path)
|
||||
|
||||
|
||||
class NODE_MT_compositor_node_creative_base(node_add_menu.NodeMenu):
|
||||
bl_label = "Creative"
|
||||
|
||||
|
|
@ -467,6 +494,7 @@ add_menus = {
|
|||
"NODE_MT_category_compositor_math": NODE_MT_compositor_node_math_base,
|
||||
"NODE_MT_category_compositor_text": NODE_MT_compositor_node_text_base,
|
||||
"NODE_MT_category_compositor_matrix": NODE_MT_compositor_utilities_matrix_base,
|
||||
"NODE_MT_category_compositor_rotation": NODE_MT_compositor_node_rotation_base,
|
||||
"NODE_MT_compositor_node_add_all": NODE_MT_compositor_node_all_base,
|
||||
}
|
||||
add_menus = node_add_menu.generate_menus(
|
||||
|
|
@ -497,6 +525,7 @@ swap_menus = {
|
|||
"NODE_MT_compositor_node_math_swap": NODE_MT_compositor_node_math_base,
|
||||
"NODE_MT_compositor_node_text_swap": NODE_MT_compositor_node_text_base,
|
||||
"NODE_MT_compositor_node_matrix_swap": NODE_MT_compositor_utilities_matrix_base,
|
||||
"NODE_MT_compositor_node_rotation_swap": NODE_MT_compositor_node_rotation_base,
|
||||
"NODE_MT_compositor_node_swap_all": NODE_MT_compositor_node_all_base,
|
||||
}
|
||||
swap_menus = node_add_menu.generate_menus(
|
||||
|
|
|
|||
|
|
@ -136,6 +136,10 @@ static ColorGeometry4b float2_to_byte_color(const float2 &a)
|
|||
{
|
||||
return color::encode(float2_to_color(a));
|
||||
}
|
||||
static math::Quaternion float2_to_quaternion(const float2 &a)
|
||||
{
|
||||
return math::to_quaternion(math::EulerXYZ(float3(a.x, a.y, 0.0f)));
|
||||
}
|
||||
|
||||
static bool float3_to_bool(const float3 &a)
|
||||
{
|
||||
|
|
@ -601,6 +605,10 @@ static math::Quaternion float4x4_to_quaternion(const float4x4 &a)
|
|||
return math::normalized_to_quaternion_safe(math::normalize(float3x3(a)));
|
||||
}
|
||||
|
||||
static float2 quaternion_to_float2(const math::Quaternion &a)
|
||||
{
|
||||
return float2(math::to_euler(a).xyz().xy());
|
||||
}
|
||||
static float3 quaternion_to_float3(const math::Quaternion &a)
|
||||
{
|
||||
return float3(math::to_euler(a).xyz());
|
||||
|
|
@ -642,6 +650,7 @@ static DataTypeConversions create_implicit_conversions()
|
|||
add_implicit_conversion<float2, int8_t, float2_to_int8>(conversions);
|
||||
add_implicit_conversion<float2, ColorGeometry4f, float2_to_color>(conversions);
|
||||
add_implicit_conversion<float2, ColorGeometry4b, float2_to_byte_color>(conversions);
|
||||
add_implicit_conversion<float2, math::Quaternion, float2_to_quaternion>(conversions);
|
||||
|
||||
add_implicit_conversion<float3, bool, float3_to_bool>(conversions);
|
||||
add_implicit_conversion<float3, int8_t, float3_to_int8>(conversions);
|
||||
|
|
@ -767,6 +776,7 @@ static DataTypeConversions create_implicit_conversions()
|
|||
|
||||
add_implicit_conversion<float4x4, math::Quaternion, float4x4_to_quaternion>(conversions);
|
||||
|
||||
add_implicit_conversion<math::Quaternion, float2, quaternion_to_float2>(conversions);
|
||||
add_implicit_conversion<math::Quaternion, float3, quaternion_to_float3>(conversions);
|
||||
add_implicit_conversion<math::Quaternion, float4, quaternion_to_float4>(conversions);
|
||||
add_implicit_conversion<math::Quaternion, float4x4, quaternion_to_float4x4>(conversions);
|
||||
|
|
|
|||
|
|
@ -79,6 +79,18 @@ template<typename T> struct QuaternionBase {
|
|||
return {this->w, this->x, this->y, this->z};
|
||||
}
|
||||
|
||||
/** C-style pointer dereference. */
|
||||
|
||||
operator const T *() const
|
||||
{
|
||||
return reinterpret_cast<const T *>(this);
|
||||
}
|
||||
|
||||
operator T *()
|
||||
{
|
||||
return reinterpret_cast<T *>(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an exponential map representation of this quaternion.
|
||||
* An exponential map is basically the rotation axis multiplied by the rotation angle.
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "BLI_implicit_sharing.hh"
|
||||
#include "BLI_math_interp.hh"
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
#include "BLI_math_quaternion_types.hh"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_math_vector.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
|
|
@ -59,6 +60,7 @@ enum class ResultType : uint8_t {
|
|||
Bool,
|
||||
Float4x4,
|
||||
Menu,
|
||||
Quaternion,
|
||||
|
||||
/* Single value only types. See Result::is_single_value_only_type. */
|
||||
String,
|
||||
|
|
@ -169,6 +171,7 @@ class Result {
|
|||
bool,
|
||||
float4x4,
|
||||
nodes::MenuValue,
|
||||
math::Quaternion,
|
||||
std::string,
|
||||
Object *,
|
||||
Image *,
|
||||
|
|
@ -669,8 +672,8 @@ BLI_INLINE_METHOD T Result::sample(const float2 &coordinates,
|
|||
const int2 size = domain_.data_size;
|
||||
const float2 texel_coordinates = coordinates * float2(size);
|
||||
|
||||
if constexpr (is_same_any_v<T, float, float2, float3, float4, Color>) {
|
||||
T pixel_value = T(0);
|
||||
if constexpr (is_same_any_v<T, float, float2, float3, float4, Color, math::Quaternion>) {
|
||||
T pixel_value;
|
||||
const float *buffer = static_cast<const float *>(this->cpu_data().data());
|
||||
float *output = nullptr;
|
||||
if constexpr (std::is_same_v<T, float>) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "BLI_index_mask.hh"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_base.hh"
|
||||
#include "BLI_math_euler.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
|
@ -290,6 +291,15 @@ mf::Variable *MultiFunctionProcedureOperation::get_constant_input_variable(
|
|||
value);
|
||||
break;
|
||||
}
|
||||
case SOCK_ROTATION: {
|
||||
const bNodeSocketValueRotation *rotation =
|
||||
input.default_value_typed<bNodeSocketValueRotation>();
|
||||
const math::EulerXYZ euler(float3(rotation->value_euler));
|
||||
const math::Quaternion value = math::to_quaternion(euler);
|
||||
constant_function = &procedure_.construct_function<mf::CustomMF_Constant<math::Quaternion>>(
|
||||
value);
|
||||
break;
|
||||
}
|
||||
case SOCK_OBJECT: {
|
||||
Object *value = input.default_value_typed<bNodeSocketValueObject>()->value;
|
||||
constant_function = &procedure_.construct_function<mf::CustomMF_Constant<Object *>>(value);
|
||||
|
|
|
|||
|
|
@ -169,6 +169,8 @@ const char *RealizeOnDomainOperation::get_realization_shader_name()
|
|||
return "compositor_realize_on_domain_float4x4";
|
||||
case ResultType::Menu:
|
||||
return "compositor_realize_on_domain_menu";
|
||||
case ResultType::Quaternion:
|
||||
return "compositor_realize_on_domain_bicubic_float4";
|
||||
case ResultType::String:
|
||||
case ResultType::Object:
|
||||
case ResultType::Image:
|
||||
|
|
@ -210,6 +212,8 @@ const char *RealizeOnDomainOperation::get_realization_shader_name()
|
|||
return "compositor_realize_on_domain_float4x4";
|
||||
case ResultType::Menu:
|
||||
return "compositor_realize_on_domain_menu";
|
||||
case ResultType::Quaternion:
|
||||
return "compositor_realize_on_domain_float4";
|
||||
case ResultType::String:
|
||||
case ResultType::Object:
|
||||
case ResultType::Image:
|
||||
|
|
@ -262,7 +266,8 @@ void RealizeOnDomainOperation::realize_on_domain_cpu(const float3x3 &transformat
|
|||
int4,
|
||||
bool,
|
||||
float4x4,
|
||||
nodes::MenuValue>(
|
||||
nodes::MenuValue,
|
||||
math::Quaternion>(
|
||||
[&]<typename T>() { realize_on_domain<T>(input, output, transformation); });
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "BLI_generic_pointer.hh"
|
||||
#include "BLI_generic_span.hh"
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
#include "BLI_math_quaternion_types.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
#include "GPU_shader.hh"
|
||||
|
|
@ -55,6 +56,7 @@ bool Result::is_single_value_only_type(ResultType type)
|
|||
case ResultType::Bool:
|
||||
case ResultType::Float4x4:
|
||||
case ResultType::Menu:
|
||||
case ResultType::Quaternion:
|
||||
return false;
|
||||
case ResultType::String:
|
||||
case ResultType::Object:
|
||||
|
|
@ -106,6 +108,8 @@ gpu::TextureFormat Result::gpu_texture_format(ResultType type, ResultPrecision p
|
|||
/* Menu values are technically stored in 32-bit integers, but 8 is sufficient in
|
||||
* practice. */
|
||||
return gpu::TextureFormat::SINT_8;
|
||||
case ResultType::Quaternion:
|
||||
return gpu::TextureFormat::SFLOAT_16_16_16_16;
|
||||
case ResultType::String:
|
||||
case ResultType::Object:
|
||||
case ResultType::Image:
|
||||
|
|
@ -152,6 +156,8 @@ gpu::TextureFormat Result::gpu_texture_format(ResultType type, ResultPrecision p
|
|||
/* Menu values are technically stored in 32-bit integers, but 8 is sufficient in
|
||||
* practice. */
|
||||
return gpu::TextureFormat::SINT_8;
|
||||
case ResultType::Quaternion:
|
||||
return gpu::TextureFormat::SFLOAT_32_32_32_32;
|
||||
case ResultType::String:
|
||||
case ResultType::Object:
|
||||
case ResultType::Image:
|
||||
|
|
@ -176,6 +182,7 @@ eGPUDataFormat Result::gpu_data_format(ResultType type)
|
|||
switch (type) {
|
||||
case ResultType::Float:
|
||||
case ResultType::Color:
|
||||
case ResultType::Quaternion:
|
||||
case ResultType::Float4:
|
||||
case ResultType::Float3:
|
||||
case ResultType::Float2:
|
||||
|
|
@ -373,6 +380,8 @@ const CPPType &Result::cpp_type(const ResultType type)
|
|||
return CPPType::get<float4x4>();
|
||||
case ResultType::Menu:
|
||||
return CPPType::get<nodes::MenuValue>();
|
||||
case ResultType::Quaternion:
|
||||
return CPPType::get<math::Quaternion>();
|
||||
case ResultType::String:
|
||||
return CPPType::get<std::string>();
|
||||
case ResultType::Object:
|
||||
|
|
@ -420,6 +429,8 @@ const char *Result::type_name(const ResultType type)
|
|||
return "float4x4";
|
||||
case ResultType::Menu:
|
||||
return "menu";
|
||||
case ResultType::Quaternion:
|
||||
return "quaternion";
|
||||
case ResultType::String:
|
||||
return "string";
|
||||
case ResultType::Object:
|
||||
|
|
@ -543,6 +554,9 @@ void Result::allocate_single_value()
|
|||
case ResultType::Menu:
|
||||
this->set_single_value(nodes::MenuValue(0));
|
||||
break;
|
||||
case ResultType::Quaternion:
|
||||
this->set_single_value(math::Quaternion(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
break;
|
||||
case ResultType::String:
|
||||
this->set_single_value(std::string(""));
|
||||
break;
|
||||
|
|
@ -584,6 +598,7 @@ Result Result::upload_to_gpu(const bool from_pool) const
|
|||
switch (this->type()) {
|
||||
case ResultType::Float:
|
||||
case ResultType::Color:
|
||||
case ResultType::Quaternion:
|
||||
case ResultType::Float4:
|
||||
case ResultType::Float2:
|
||||
case ResultType::Int:
|
||||
|
|
@ -659,6 +674,7 @@ Result Result::download_to_cpu() const
|
|||
switch (this->type()) {
|
||||
case ResultType::Float:
|
||||
case ResultType::Color:
|
||||
case ResultType::Quaternion:
|
||||
case ResultType::Float4:
|
||||
case ResultType::Float2:
|
||||
case ResultType::Int:
|
||||
|
|
@ -996,6 +1012,7 @@ int64_t Result::channels_count() const
|
|||
case ResultType::Color:
|
||||
case ResultType::Float4:
|
||||
case ResultType::Int4:
|
||||
case ResultType::Quaternion:
|
||||
return 4;
|
||||
case ResultType::Float4x4:
|
||||
return 16;
|
||||
|
|
@ -1053,6 +1070,7 @@ void Result::update_single_value_data()
|
|||
case ResultType::Int4:
|
||||
case ResultType::Bool:
|
||||
case ResultType::Menu:
|
||||
case ResultType::Quaternion:
|
||||
GPU_texture_update(
|
||||
this->gpu_texture(), this->get_gpu_data_format(), this->single_value().get());
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ static GPUType gpu_type_from_socket(const bNodeSocket &socket)
|
|||
return GPU_NONE;
|
||||
}
|
||||
case SOCK_RGBA:
|
||||
case SOCK_ROTATION:
|
||||
return GPU_VEC4;
|
||||
case SOCK_MATRIX:
|
||||
return GPU_MAT4;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
#include "BLI_assert.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_euler.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_ustring.hh"
|
||||
#include "BLI_vector_set.hh"
|
||||
|
|
@ -235,6 +237,14 @@ static void initialize_input_stack_value(const bNodeSocket &input, GPUNodeStack
|
|||
stack.vec[0] = int(value);
|
||||
break;
|
||||
}
|
||||
case SOCK_ROTATION: {
|
||||
const bNodeSocketValueRotation *rotation =
|
||||
input.default_value_typed<bNodeSocketValueRotation>();
|
||||
const math::EulerXYZ euler(float3(rotation->value_euler));
|
||||
const math::Quaternion value = math::to_quaternion(euler);
|
||||
copy_v4_v4(stack.vec, float4(value));
|
||||
break;
|
||||
}
|
||||
case SOCK_MATRIX:
|
||||
/* Matrix sockets do not have default values. */
|
||||
BLI_assert_unreachable();
|
||||
|
|
@ -289,6 +299,8 @@ static const char *get_set_function_name(const ResultType type)
|
|||
case ResultType::Menu:
|
||||
/* GPUMaterial doesn't support int, so it is passed as a float. */
|
||||
return "set_float";
|
||||
case ResultType::Quaternion:
|
||||
return "set_quaternion";
|
||||
case ResultType::String:
|
||||
case ResultType::Object:
|
||||
case ResultType::Image:
|
||||
|
|
@ -524,6 +536,8 @@ static const char *get_store_function_name(ResultType type)
|
|||
return "node_compositor_store_output_float4x4";
|
||||
case ResultType::Menu:
|
||||
return "node_compositor_store_output_menu";
|
||||
case ResultType::Quaternion:
|
||||
return "node_compositor_store_output_quaternion";
|
||||
case ResultType::String:
|
||||
case ResultType::Object:
|
||||
case ResultType::Image:
|
||||
|
|
@ -724,6 +738,8 @@ static const char *glsl_store_expression_from_result_type(ResultType type)
|
|||
/* GPUMaterial doesn't support int, so it is passed as a float, and we need to convert it
|
||||
* back to int before writing it. */
|
||||
return "ivec4(int(value))";
|
||||
case ResultType::Quaternion:
|
||||
return "value";
|
||||
case ResultType::String:
|
||||
case ResultType::Object:
|
||||
case ResultType::Image:
|
||||
|
|
@ -749,6 +765,7 @@ static ImageType gpu_image_type_from_result_type(const ResultType type)
|
|||
case ResultType::Float3:
|
||||
case ResultType::Color:
|
||||
case ResultType::Float4:
|
||||
case ResultType::Quaternion:
|
||||
return ImageType::Float2D;
|
||||
case ResultType::Int:
|
||||
case ResultType::Int2:
|
||||
|
|
@ -797,6 +814,8 @@ std::string ShaderOperation::generate_code_for_outputs(ShaderCreateInfo &shader_
|
|||
"void store_float4x4(const uint id, float4x4 value)";
|
||||
/* GPUMaterial doesn't support int, so it is passed as a float. */
|
||||
const std::string store_menu_function_header = "void store_menu(const uint id, float value)";
|
||||
const std::string store_quaternion_function_header =
|
||||
"void store_quaternion(const uint id, vec4 value)";
|
||||
|
||||
/* Each of the store functions is essentially a single switch case on the given ID, so start by
|
||||
* opening the function with a curly bracket followed by opening a switch statement in each of
|
||||
|
|
@ -813,6 +832,7 @@ std::string ShaderOperation::generate_code_for_outputs(ShaderCreateInfo &shader_
|
|||
std::stringstream store_bool_function;
|
||||
std::stringstream store_float4x4_function;
|
||||
std::stringstream store_menu_function;
|
||||
std::stringstream store_quaternion_function;
|
||||
const std::string store_function_start = "\n{\n switch (id) {\n";
|
||||
store_float_function << store_float_function_header << store_function_start;
|
||||
store_float2_function << store_float2_function_header << store_function_start;
|
||||
|
|
@ -826,6 +846,7 @@ std::string ShaderOperation::generate_code_for_outputs(ShaderCreateInfo &shader_
|
|||
store_bool_function << store_bool_function_header << store_function_start;
|
||||
store_float4x4_function << store_float4x4_function_header << store_function_start;
|
||||
store_menu_function << store_menu_function_header << store_function_start;
|
||||
store_quaternion_function << store_quaternion_function_header << store_function_start;
|
||||
|
||||
shader_create_info.builtins(BuiltinBits::GLOBAL_INVOCATION_ID);
|
||||
|
||||
|
|
@ -899,6 +920,9 @@ std::string ShaderOperation::generate_code_for_outputs(ShaderCreateInfo &shader_
|
|||
case ResultType::Menu:
|
||||
store_menu_function << common_case_code.str();
|
||||
break;
|
||||
case ResultType::Quaternion:
|
||||
store_quaternion_function << common_case_code.str();
|
||||
break;
|
||||
case ResultType::String:
|
||||
case ResultType::Object:
|
||||
case ResultType::Image:
|
||||
|
|
@ -927,11 +951,13 @@ std::string ShaderOperation::generate_code_for_outputs(ShaderCreateInfo &shader_
|
|||
store_bool_function << store_function_end;
|
||||
store_float4x4_function << store_function_end;
|
||||
store_menu_function << store_function_end;
|
||||
store_quaternion_function << store_function_end;
|
||||
|
||||
return store_float_function.str() + store_float2_function.str() + store_float3_function.str() +
|
||||
store_float4_function.str() + store_color_function.str() + store_int_function.str() +
|
||||
store_int2_function.str() + store_int3_function.str() + store_int4_function.str() +
|
||||
store_bool_function.str() + store_float4x4_function.str() + store_menu_function.str();
|
||||
store_bool_function.str() + store_float4x4_function.str() + store_menu_function.str() +
|
||||
store_quaternion_function.str();
|
||||
}
|
||||
|
||||
static const char *glsl_type_from_result_type(ResultType type)
|
||||
|
|
@ -967,6 +993,8 @@ static const char *glsl_type_from_result_type(ResultType type)
|
|||
case ResultType::Menu:
|
||||
/* GPUMaterial doesn't support int, so it is passed as a float. */
|
||||
return "float";
|
||||
case ResultType::Quaternion:
|
||||
return "vec4";
|
||||
case ResultType::String:
|
||||
case ResultType::Object:
|
||||
case ResultType::Image:
|
||||
|
|
@ -1013,6 +1041,8 @@ static const char *glsl_swizzle_from_result_type(ResultType type)
|
|||
return "xyzw";
|
||||
case ResultType::Menu:
|
||||
return "x";
|
||||
case ResultType::Quaternion:
|
||||
return "xyzw";
|
||||
case ResultType::String:
|
||||
case ResultType::Object:
|
||||
case ResultType::Image:
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <string>
|
||||
|
||||
#include "BLI_assert.h"
|
||||
#include "BLI_math_euler.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
#include "DNA_node_types.h"
|
||||
|
|
@ -110,6 +111,14 @@ void SingleValueNodeInputOperation::execute()
|
|||
result.set_single_value(value);
|
||||
break;
|
||||
}
|
||||
case SOCK_ROTATION: {
|
||||
const bNodeSocketValueRotation *rotation =
|
||||
input_socket_.default_value_typed<bNodeSocketValueRotation>();
|
||||
const math::EulerXYZ euler(float3(rotation->value_euler));
|
||||
const math::Quaternion value = math::to_quaternion(euler);
|
||||
result.set_single_value(value);
|
||||
break;
|
||||
}
|
||||
case SOCK_OBJECT: {
|
||||
Object *value = input_socket_.default_value_typed<bNodeSocketValueObject>()->value;
|
||||
result.set_single_value(value);
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ ResultType socket_data_type_to_result_type(const eNodeSocketDatatype data_type,
|
|||
return ResultType::Menu;
|
||||
case SOCK_STRING:
|
||||
return ResultType::String;
|
||||
case SOCK_ROTATION:
|
||||
return ResultType::Quaternion;
|
||||
case SOCK_OBJECT:
|
||||
return ResultType::Object;
|
||||
case SOCK_IMAGE:
|
||||
|
|
|
|||
|
|
@ -85,6 +85,15 @@ void convert_float_to_bool()
|
|||
imageStore(image_out, texel, int4(float_to_bool(value.x)));
|
||||
}
|
||||
|
||||
void convert_float_to_quaternion()
|
||||
{
|
||||
auto &sampler_in = sampler_get(compositor_convert_float_to_quaternion, input_tx);
|
||||
auto &image_out = image_get(compositor_convert_float_to_quaternion, output_img);
|
||||
int2 texel = int2(gl_GlobalInvocationID.xy);
|
||||
float4 value = texture_load(sampler_in, texel);
|
||||
imageStore(image_out, texel, float_to_quaternion(value.x));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float2 to other.
|
||||
*/
|
||||
|
|
@ -161,6 +170,15 @@ void convert_float2_to_bool()
|
|||
imageStore(image_out, texel, int4(float2_to_bool(value.xy)));
|
||||
}
|
||||
|
||||
void convert_float2_to_quaternion()
|
||||
{
|
||||
auto &sampler_in = sampler_get(compositor_convert_float2_to_quaternion, input_tx);
|
||||
auto &image_out = image_get(compositor_convert_float2_to_quaternion, output_img);
|
||||
int2 texel = int2(gl_GlobalInvocationID.xy);
|
||||
float4 value = texture_load(sampler_in, texel);
|
||||
imageStore(image_out, texel, float2_to_quaternion(value.xy));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float3 to other.
|
||||
*/
|
||||
|
|
@ -237,6 +255,15 @@ void convert_float3_to_bool()
|
|||
imageStore(image_out, texel, int4(float3_to_bool(value.xyz)));
|
||||
}
|
||||
|
||||
void convert_float3_to_quaternion()
|
||||
{
|
||||
auto &sampler_in = sampler_get(compositor_convert_float3_to_quaternion, input_tx);
|
||||
auto &image_out = image_get(compositor_convert_float3_to_quaternion, output_img);
|
||||
int2 texel = int2(gl_GlobalInvocationID.xy);
|
||||
float4 value = texture_load(sampler_in, texel);
|
||||
imageStore(image_out, texel, float3_to_quaternion(value.xyz));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float4 to other.
|
||||
*/
|
||||
|
|
@ -313,6 +340,15 @@ void convert_float4_to_bool()
|
|||
imageStore(image_out, texel, int4(float4_to_bool(value)));
|
||||
}
|
||||
|
||||
void convert_float4_to_quaternion()
|
||||
{
|
||||
auto &sampler_in = sampler_get(compositor_convert_float4_to_quaternion, input_tx);
|
||||
auto &image_out = image_get(compositor_convert_float4_to_quaternion, output_img);
|
||||
int2 texel = int2(gl_GlobalInvocationID.xy);
|
||||
float4 value = texture_load(sampler_in, texel);
|
||||
imageStore(image_out, texel, float4_to_quaternion(value));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Color to other.
|
||||
*/
|
||||
|
|
@ -705,3 +741,60 @@ void convert_bool_to_float4()
|
|||
int4 value = texture_load(sampler_in, texel);
|
||||
imageStore(image_out, texel, float4(bool_to_float4(bool(value.x))));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float4x4 to other.
|
||||
*/
|
||||
|
||||
void convert_float4x4_to_quaternion()
|
||||
{
|
||||
auto &sampler_in = sampler_get(compositor_convert_float4x4_to_quaternion, input_tx);
|
||||
auto &image_out = image_get(compositor_convert_float4x4_to_quaternion, output_img);
|
||||
int2 texel = int2(gl_GlobalInvocationID.xy);
|
||||
float4x4 mat = texture_load_float4x4(sampler_in, texel);
|
||||
imageStore(image_out, texel, float4x4_to_quaternion(mat));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Quaternion to other.
|
||||
*/
|
||||
|
||||
void convert_quaternion_to_float2()
|
||||
{
|
||||
auto &sampler_in = sampler_get(compositor_convert_quaternion_to_float2, input_tx);
|
||||
auto &image_out = image_get(compositor_convert_quaternion_to_float2, output_img);
|
||||
int2 texel = int2(gl_GlobalInvocationID.xy);
|
||||
float4 value = texture_load(sampler_in, texel);
|
||||
imageStore(image_out, texel, float4(quaternion_to_float2(value), 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
void convert_quaternion_to_float3()
|
||||
{
|
||||
auto &sampler_in = sampler_get(compositor_convert_quaternion_to_float3, input_tx);
|
||||
auto &image_out = image_get(compositor_convert_quaternion_to_float3, output_img);
|
||||
int2 texel = int2(gl_GlobalInvocationID.xy);
|
||||
float4 value = texture_load(sampler_in, texel);
|
||||
imageStore(image_out, texel, float4(quaternion_to_float3(value), 0.0f));
|
||||
}
|
||||
|
||||
void convert_quaternion_to_float4()
|
||||
{
|
||||
auto &sampler_in = sampler_get(compositor_convert_quaternion_to_float4, input_tx);
|
||||
auto &image_out = image_get(compositor_convert_quaternion_to_float4, output_img);
|
||||
int2 texel = int2(gl_GlobalInvocationID.xy);
|
||||
float4 value = texture_load(sampler_in, texel);
|
||||
imageStore(image_out, texel, float4(quaternion_to_float4(value)));
|
||||
}
|
||||
|
||||
void convert_quaternion_to_float4x4()
|
||||
{
|
||||
auto &sampler_in = sampler_get(compositor_convert_quaternion_to_float4x4, input_tx);
|
||||
auto &image_out = image_get(compositor_convert_quaternion_to_float4x4, output_img);
|
||||
int2 texel = int2(gl_GlobalInvocationID.xy);
|
||||
float4 value = texture_load(sampler_in, texel);
|
||||
float4x4 mat = quaternion_to_float4x4(value);
|
||||
imageStore(image_out, int3(texel, 0), mat[0]);
|
||||
imageStore(image_out, int3(texel, 1), mat[1]);
|
||||
imageStore(image_out, int3(texel, 2), mat[2]);
|
||||
imageStore(image_out, int3(texel, 3), mat[3]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,12 @@ COMPUTE_SOURCE("compositor_convert.glsl")
|
|||
SAMPLER(0, isampler2D, input_tx)
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_float4x4_shared)
|
||||
LOCAL_GROUP_SIZE(16, 16)
|
||||
COMPUTE_SOURCE("compositor_convert.glsl")
|
||||
SAMPLER(0, sampler2DArray, input_tx)
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float to other.
|
||||
*/
|
||||
|
|
@ -81,6 +87,13 @@ COMPUTE_FUNCTION("convert_float_to_bool")
|
|||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_float_to_quaternion)
|
||||
ADDITIONAL_INFO(compositor_convert_float_shared)
|
||||
IMAGE(0, SFLOAT_16_16_16_16, write, image2D, output_img)
|
||||
COMPUTE_FUNCTION("convert_float_to_quaternion")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Int to other.
|
||||
*/
|
||||
|
|
@ -321,6 +334,13 @@ COMPUTE_FUNCTION("convert_float2_to_bool")
|
|||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_float2_to_quaternion)
|
||||
ADDITIONAL_INFO(compositor_convert_float_shared)
|
||||
IMAGE(0, SFLOAT_16_16_16_16, write, image2D, output_img)
|
||||
COMPUTE_FUNCTION("convert_float2_to_quaternion")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float3 to other.
|
||||
*/
|
||||
|
|
@ -381,6 +401,13 @@ COMPUTE_FUNCTION("convert_float3_to_bool")
|
|||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_float3_to_quaternion)
|
||||
ADDITIONAL_INFO(compositor_convert_float_shared)
|
||||
IMAGE(0, SFLOAT_16_16_16_16, write, image2D, output_img)
|
||||
COMPUTE_FUNCTION("convert_float3_to_quaternion")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Color to other.
|
||||
*/
|
||||
|
|
@ -504,6 +531,13 @@ COMPUTE_FUNCTION("convert_float4_to_bool")
|
|||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_float4_to_quaternion)
|
||||
ADDITIONAL_INFO(compositor_convert_float_shared)
|
||||
IMAGE(0, SFLOAT_16_16_16_16, write, image2D, output_img)
|
||||
COMPUTE_FUNCTION("convert_float4_to_quaternion")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Bool to other.
|
||||
*/
|
||||
|
|
@ -574,3 +608,46 @@ IMAGE(0, SFLOAT_16, write, image2D, output_img)
|
|||
COMPUTE_FUNCTION("convert_color_to_alpha")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float4x4 to other.
|
||||
*/
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_float4x4_to_quaternion)
|
||||
ADDITIONAL_INFO(compositor_convert_float4x4_shared)
|
||||
IMAGE(0, SFLOAT_16_16_16_16, write, image2D, output_img)
|
||||
COMPUTE_FUNCTION("convert_float4x4_to_quaternion")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Quaternion to other.
|
||||
*/
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_quaternion_to_float2)
|
||||
ADDITIONAL_INFO(compositor_convert_float_shared)
|
||||
IMAGE(0, SFLOAT_16_16_16_16, write, image2D, output_img)
|
||||
COMPUTE_FUNCTION("convert_quaternion_to_float2")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_quaternion_to_float3)
|
||||
ADDITIONAL_INFO(compositor_convert_float_shared)
|
||||
IMAGE(0, SFLOAT_16_16_16_16, write, image2D, output_img)
|
||||
COMPUTE_FUNCTION("convert_quaternion_to_float3")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_quaternion_to_float4)
|
||||
ADDITIONAL_INFO(compositor_convert_float_shared)
|
||||
IMAGE(0, SFLOAT_16_16_16_16, write, image2D, output_img)
|
||||
COMPUTE_FUNCTION("convert_quaternion_to_float4")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_convert_quaternion_to_float4x4)
|
||||
ADDITIONAL_INFO(compositor_convert_float_shared)
|
||||
IMAGE(0, SFLOAT_16_16_16_16, write, image2DArray, output_img)
|
||||
COMPUTE_FUNCTION("convert_quaternion_to_float4x4")
|
||||
DO_STATIC_COMPILATION()
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
|
|
|||
|
|
@ -64,6 +64,12 @@ void float_to_bool(float value, float &output_value)
|
|||
output_value = float(float_to_bool(value));
|
||||
}
|
||||
|
||||
[[node]]
|
||||
void float_to_quaternion(float value, float4 &output_value)
|
||||
{
|
||||
output_value = float_to_quaternion(value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Int to other.
|
||||
*/
|
||||
|
|
@ -168,6 +174,12 @@ void float2_to_bool(float2 value, float &output_value)
|
|||
output_value = float(float2_to_bool(value));
|
||||
}
|
||||
|
||||
[[node]]
|
||||
void float2_to_quaternion(float2 value, float4 &output_value)
|
||||
{
|
||||
output_value = float2_to_quaternion(value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float3 to other.
|
||||
*/
|
||||
|
|
@ -220,6 +232,12 @@ void float3_to_bool(float3 value, float &output_value)
|
|||
output_value = float(float3_to_bool(value));
|
||||
}
|
||||
|
||||
[[node]]
|
||||
void float3_to_quaternion(float3 value, float4 &output_value)
|
||||
{
|
||||
output_value = float3_to_quaternion(value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Color to other.
|
||||
*/
|
||||
|
|
@ -324,6 +342,12 @@ void float4_to_bool(float4 value, float &output_value)
|
|||
output_value = float(float4_to_bool(value));
|
||||
}
|
||||
|
||||
[[node]]
|
||||
void float4_to_quaternion(float4 value, float4 &output_value)
|
||||
{
|
||||
output_value = float4_to_quaternion(value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Int2 to other.
|
||||
*/
|
||||
|
|
@ -480,6 +504,44 @@ void bool_to_int3(float value, float3 &output_value)
|
|||
output_value = float3(bool_to_int3(bool(value)));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float4x4 to other.
|
||||
*/
|
||||
|
||||
[[node]]
|
||||
void float4x4_to_quaternion(float4x4 mat, float4 &output_value)
|
||||
{
|
||||
output_value = float4x4_to_quaternion(mat);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Quaternion to other.
|
||||
*/
|
||||
|
||||
[[node]]
|
||||
void quaternion_to_float2(float4 value, float2 &output_value)
|
||||
{
|
||||
output_value = quaternion_to_float2(value);
|
||||
}
|
||||
|
||||
[[node]]
|
||||
void quaternion_to_float3(float4 value, float3 &output_value)
|
||||
{
|
||||
output_value = quaternion_to_float3(value);
|
||||
}
|
||||
|
||||
[[node]]
|
||||
void quaternion_to_float4(float4 value, float4 &output_value)
|
||||
{
|
||||
output_value = quaternion_to_float4(value);
|
||||
}
|
||||
|
||||
[[node]]
|
||||
void quaternion_to_float4x4(float4 value, float4x4 &output_value)
|
||||
{
|
||||
output_value = quaternion_to_float4x4(value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Internal Code Generation Functions.
|
||||
*/
|
||||
|
|
@ -543,3 +605,13 @@ float4 float4_from_float(float value)
|
|||
{
|
||||
return float_to_color(value);
|
||||
}
|
||||
|
||||
float4 float4_from_float4x4(float4x4 mat)
|
||||
{
|
||||
return float4x4_to_quaternion(mat);
|
||||
}
|
||||
|
||||
float4x4 float4x4_from_float4(float4 value)
|
||||
{
|
||||
return quaternion_to_float4x4(value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@ void set_float4(float4 input_value, float4 &output_value)
|
|||
output_value = input_value;
|
||||
}
|
||||
|
||||
[[node]]
|
||||
void set_quaternion(float4 input_value, float4 &output_value)
|
||||
{
|
||||
output_value = input_value;
|
||||
}
|
||||
|
||||
[[node]]
|
||||
void set_color(float4 input_value, float4 &output_value)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -102,3 +102,10 @@ void node_compositor_store_output_menu(const float id, float value, float &out_v
|
|||
store_menu(floatBitsToUint(id), value);
|
||||
out_value = value;
|
||||
}
|
||||
|
||||
[[node]]
|
||||
void node_compositor_store_output_quaternion(const float id, float4 value, float4 &out_value)
|
||||
{
|
||||
store_quaternion(floatBitsToUint(id), value);
|
||||
out_value = value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_math_matrix_construct_lib.glsl"
|
||||
#include "gpu_shader_math_rotation_conversion_lib.glsl"
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float to other.
|
||||
*/
|
||||
|
|
@ -46,6 +49,11 @@ bool float_to_bool(float value)
|
|||
return value > 0.0f;
|
||||
}
|
||||
|
||||
float4 float_to_quaternion(float value)
|
||||
{
|
||||
return to_quaternion(EulerXYZ::from_float3(float3(value))).as_float4();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Int to other.
|
||||
*/
|
||||
|
|
@ -134,6 +142,11 @@ bool float2_to_bool(float2 value)
|
|||
return !all(equal(value, float2(0.0f)));
|
||||
}
|
||||
|
||||
float4 float2_to_quaternion(float2 value)
|
||||
{
|
||||
return to_quaternion(EulerXYZ::from_float3(float3(value, 0.0f))).as_float4();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float3 to other.
|
||||
*/
|
||||
|
|
@ -178,6 +191,11 @@ bool float3_to_bool(float3 value)
|
|||
return !all(equal(value, float3(0.0f)));
|
||||
}
|
||||
|
||||
float4 float3_to_quaternion(float3 value)
|
||||
{
|
||||
return to_quaternion(EulerXYZ::from_float3(value)).as_float4();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Color to other.
|
||||
*/
|
||||
|
|
@ -266,6 +284,11 @@ bool float4_to_bool(float4 value)
|
|||
return !all(equal(value, float4(0.0f)));
|
||||
}
|
||||
|
||||
float4 float4_to_quaternion(float4 value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Int2 to other.
|
||||
*/
|
||||
|
|
@ -397,3 +420,44 @@ int3 bool_to_int3(bool value)
|
|||
{
|
||||
return int3(value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Float4x4 to other.
|
||||
*/
|
||||
|
||||
float4 float4x4_to_quaternion(float4x4 mat)
|
||||
{
|
||||
float3x3 mat_3x3 = normalize(to_float3x3(mat));
|
||||
return to_quaternion(to_euler(mat_3x3)).as_float4();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Quaternion to other.
|
||||
*/
|
||||
|
||||
float2 quaternion_to_float2(float4 value)
|
||||
{
|
||||
Quaternion quat = Quaternion{UNPACK4(value)};
|
||||
return to_euler(from_rotation(quat)).as_float3().xy();
|
||||
}
|
||||
|
||||
float3 quaternion_to_float3(float4 value)
|
||||
{
|
||||
Quaternion quat = Quaternion{UNPACK4(value)};
|
||||
return to_euler(from_rotation(quat)).as_float3();
|
||||
}
|
||||
|
||||
float4 quaternion_to_float4(float4 value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
float4x4 quaternion_to_float4x4(float4 value)
|
||||
{
|
||||
Quaternion quat = Quaternion{UNPACK4(value)};
|
||||
float3x3 mat_3x3 = from_rotation(quat);
|
||||
return float4x4(float4(mat_3x3[0], 0.0f),
|
||||
float4(mat_3x3[1], 0.0f),
|
||||
float4(mat_3x3[2], 0.0f),
|
||||
float4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -630,8 +630,11 @@ set(GLSL_SRC
|
|||
shaders/common/gpu_shader_utildefines_lib.glsl
|
||||
|
||||
shaders/material/gpu_shader_material_add_shader.glsl
|
||||
shaders/material/gpu_shader_material_align_rotation_to_vector.glsl
|
||||
shaders/material/gpu_shader_material_axes_to_rotation.glsl
|
||||
shaders/material/gpu_shader_material_ambient_occlusion.glsl
|
||||
shaders/material/gpu_shader_material_attribute.glsl
|
||||
shaders/material/gpu_shader_material_axis_angle_to_rotation.glsl
|
||||
shaders/material/gpu_shader_material_background.glsl
|
||||
shaders/material/gpu_shader_material_bevel.glsl
|
||||
shaders/material/gpu_shader_material_wavelength.glsl
|
||||
|
|
@ -646,6 +649,7 @@ set(GLSL_SRC
|
|||
shaders/material/gpu_shader_material_displacement.glsl
|
||||
shaders/material/gpu_shader_material_eevee_specular.glsl
|
||||
shaders/material/gpu_shader_material_emission.glsl
|
||||
shaders/material/gpu_shader_material_euler_to_rotation.glsl
|
||||
shaders/material/gpu_shader_material_fractal_noise.glsl
|
||||
shaders/material/gpu_shader_material_fractal_voronoi.glsl
|
||||
shaders/material/gpu_shader_material_fresnel.glsl
|
||||
|
|
@ -659,6 +663,7 @@ set(GLSL_SRC
|
|||
shaders/material/gpu_shader_material_hue_sat_val.glsl
|
||||
shaders/material/gpu_shader_material_implicit_defaults.glsl
|
||||
shaders/material/gpu_shader_material_invert.glsl
|
||||
shaders/material/gpu_shader_material_invert_rotation.glsl
|
||||
shaders/material/gpu_shader_material_layer_weight.glsl
|
||||
shaders/material/gpu_shader_material_light_falloff.glsl
|
||||
shaders/material/gpu_shader_material_light_path.glsl
|
||||
|
|
@ -677,6 +682,7 @@ set(GLSL_SRC
|
|||
shaders/material/gpu_shader_material_particle_info.glsl
|
||||
shaders/material/gpu_shader_material_point_info.glsl
|
||||
shaders/material/gpu_shader_material_principled.glsl
|
||||
shaders/material/gpu_shader_material_quaternion_to_rotation.glsl
|
||||
shaders/material/gpu_shader_material_raycast.glsl
|
||||
shaders/material/gpu_shader_material_ray_portal.glsl
|
||||
shaders/material/gpu_shader_material_refraction.glsl
|
||||
|
|
@ -684,6 +690,11 @@ set(GLSL_SRC
|
|||
shaders/material/gpu_shader_material_rgb_to_bw.glsl
|
||||
shaders/material/gpu_shader_material_radial_tiling.glsl
|
||||
shaders/material/gpu_shader_material_radial_tiling_shared.glsl
|
||||
shaders/material/gpu_shader_material_rotate_rotation.glsl
|
||||
shaders/material/gpu_shader_material_rotate_vector.glsl
|
||||
shaders/material/gpu_shader_material_rotation_to_axis_angle.glsl
|
||||
shaders/material/gpu_shader_material_rotation_to_euler.glsl
|
||||
shaders/material/gpu_shader_material_rotation_to_quaternion.glsl
|
||||
shaders/material/gpu_shader_material_separate_color.glsl
|
||||
shaders/material/gpu_shader_material_separate_xyz.glsl
|
||||
shaders/material/gpu_shader_material_set.glsl
|
||||
|
|
|
|||
|
|
@ -19,3 +19,32 @@ struct Quaternion {
|
|||
return float4(this->x, this->y, this->z, this->w);
|
||||
}
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Quaternion Math
|
||||
* \{ */
|
||||
|
||||
Quaternion math_quaternion_multiply(Quaternion a, Quaternion b)
|
||||
{
|
||||
Quaternion result;
|
||||
result.x = a.x * b.x - a.y * b.y - a.z * b.z - a.w * b.w;
|
||||
result.y = a.x * b.y + a.y * b.x + a.z * b.w - a.w * b.z;
|
||||
result.z = a.x * b.z - a.y * b.w + a.z * b.x + a.w * b.y;
|
||||
result.w = a.x * b.w + a.y * b.z - a.z * b.y + a.w * b.x;
|
||||
return result;
|
||||
}
|
||||
|
||||
Quaternion quaternion_conjugate(Quaternion q)
|
||||
{
|
||||
return {q.x, -q.y, -q.z, -q.w};
|
||||
}
|
||||
|
||||
float3 transform_point_by_quaternion(Quaternion q, float3 v)
|
||||
{
|
||||
const Quaternion v_quat = {0.0f, v.x, v.y, v.z};
|
||||
const Quaternion result = math_quaternion_multiply(math_quaternion_multiply(q, v_quat),
|
||||
quaternion_conjugate(q));
|
||||
return float3(result.y, result.z, result.w);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
|||
|
|
@ -197,6 +197,38 @@ Quaternion to_quaternion(float4x4 mat, const bool normalized)
|
|||
return to_quaternion(to_float3x3(mat), normalized);
|
||||
}
|
||||
|
||||
Quaternion to_quaternion(AxisAngle axis_angle)
|
||||
{
|
||||
float angle_cos = cos(axis_angle.angle);
|
||||
/** Using half angle identities: sin(angle / 2) = sqrt((1 - angle_cos) / 2) */
|
||||
float sine = sqrt(0.5f - angle_cos * 0.5f);
|
||||
float cosine = sqrt(0.5f + angle_cos * 0.5f);
|
||||
|
||||
/* TODO(fclem): Optimize. */
|
||||
float angle_sin = sin(axis_angle.angle);
|
||||
if (angle_sin < 0.0f) {
|
||||
sine = -sine;
|
||||
}
|
||||
|
||||
Quaternion quat;
|
||||
quat.x = cosine;
|
||||
quat.y = axis_angle.axis.x * sine;
|
||||
quat.z = axis_angle.axis.y * sine;
|
||||
quat.w = axis_angle.axis.z * sine;
|
||||
return quat;
|
||||
}
|
||||
|
||||
Quaternion to_quaternion(float3 axis, float angle)
|
||||
{
|
||||
if (is_zero(axis)) {
|
||||
return Quaternion::identity();
|
||||
}
|
||||
AxisAngle aa;
|
||||
aa.axis = normalize(axis);
|
||||
aa.angle = angle;
|
||||
return to_quaternion(aa);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
@ -248,27 +280,6 @@ EulerXYZ to_euler(float4x4 mat)
|
|||
/** \name Axis Angle Functions
|
||||
* \{ */
|
||||
|
||||
Quaternion to_axis_angle(AxisAngle axis_angle)
|
||||
{
|
||||
float angle_cos = cos(axis_angle.angle);
|
||||
/** Using half angle identities: sin(angle / 2) = sqrt((1 - angle_cos) / 2) */
|
||||
float sine = sqrt(0.5f - angle_cos * 0.5f);
|
||||
float cosine = sqrt(0.5f + angle_cos * 0.5f);
|
||||
|
||||
/* TODO(fclem): Optimize. */
|
||||
float angle_sin = sin(axis_angle.angle);
|
||||
if (angle_sin < 0.0f) {
|
||||
sine = -sine;
|
||||
}
|
||||
|
||||
Quaternion quat;
|
||||
quat.x = cosine;
|
||||
quat.y = axis_angle.axis.x * sine;
|
||||
quat.z = axis_angle.axis.y * sine;
|
||||
quat.w = axis_angle.axis.z * sine;
|
||||
return quat;
|
||||
}
|
||||
|
||||
AxisAngle to_axis_angle(Quaternion quat)
|
||||
{
|
||||
/* Calculate angle/2, and sin(angle/2). */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,114 @@
|
|||
/* SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_math_constants_lib.glsl"
|
||||
#include "gpu_shader_math_rotation_conversion_lib.glsl"
|
||||
#include "gpu_shader_math_rotation_lib.glsl"
|
||||
#include "gpu_shader_math_vector_compare_lib.glsl"
|
||||
|
||||
float angle_normalized_v3v3(float3 v1, float3 v2)
|
||||
{
|
||||
v1 = normalize(v1);
|
||||
v2 = normalize(v2);
|
||||
if (dot(v1, v2) >= 0.0f) {
|
||||
return 2.0f * asin(clamp(length(v2 - v1) / 2.0f, -1.0f, 1.0f));
|
||||
}
|
||||
const float3 v2_n = -v2;
|
||||
return M_PI - 2.0f * asin(clamp(length(v2_n - v1) / 2.0f, -1.0f, 1.0f));
|
||||
}
|
||||
|
||||
float3 project_plane_normalized_v3_v3v3(float3 p, float3 v_plane)
|
||||
{
|
||||
const float3 v_plane_n = normalize(v_plane);
|
||||
const float mul = dot(p, v_plane_n);
|
||||
return p - v_plane_n * mul;
|
||||
}
|
||||
|
||||
float angle_signed_on_axis_v3v3_v3(float3 v1, float3 v2, float3 axis)
|
||||
{
|
||||
const float3 axis_n = normalize(axis);
|
||||
const float3 v1_proj = project_plane_normalized_v3_v3v3(v1, axis_n);
|
||||
const float3 v2_proj = project_plane_normalized_v3_v3v3(v2, axis_n);
|
||||
|
||||
float angle = angle_normalized_v3v3(v1_proj, v2_proj);
|
||||
|
||||
const float3 tproj = cross(v2_proj, v1_proj);
|
||||
if (dot(tproj, axis) < 0.0f) {
|
||||
angle = M_PI * 2.0f - angle;
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
|
||||
[[node]]
|
||||
void align_rotation_to_vector_auto_pivot(float4 rotation_in,
|
||||
float factor,
|
||||
float3 input_vector,
|
||||
float3 local_main_axis,
|
||||
out float4 rotation)
|
||||
{
|
||||
if (is_zero(input_vector)) {
|
||||
rotation = rotation_in;
|
||||
return;
|
||||
}
|
||||
|
||||
const Quaternion quat_in = Quaternion{UNPACK4(rotation_in)};
|
||||
const float3 old_axis = transform_point_by_quaternion(quat_in, local_main_axis);
|
||||
const float3 new_axis = normalize(input_vector);
|
||||
|
||||
float3 rotation_axis = cross(old_axis, new_axis);
|
||||
if (is_zero(rotation_axis)) {
|
||||
/* The vectors are linearly dependent, so we fall back to another axis. */
|
||||
rotation_axis = cross(old_axis, float3(1.0f, 0.0f, 0.0f));
|
||||
if (is_zero(rotation_axis)) {
|
||||
/* This is now guaranteed to not be zero. */
|
||||
rotation_axis = cross(old_axis, float3(0.0f, 1.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
const float full_angle = angle_normalized_v3v3(old_axis, new_axis);
|
||||
const float angle = factor * full_angle;
|
||||
|
||||
AxisAngle aa;
|
||||
aa.axis = normalize(rotation_axis);
|
||||
aa.angle = angle;
|
||||
|
||||
rotation = math_quaternion_multiply(to_quaternion(aa), quat_in).as_float4();
|
||||
}
|
||||
|
||||
[[node]]
|
||||
void align_rotation_to_vector_fixed_pivot(float4 rotation_in,
|
||||
float factor,
|
||||
float3 input_vector,
|
||||
float3 local_main_axis,
|
||||
float3 local_pivot_axis,
|
||||
out float4 rotation)
|
||||
{
|
||||
if (all(equal(local_main_axis, local_pivot_axis))) {
|
||||
/* Can't compute any meaningful rotation angle in this case. */
|
||||
rotation = rotation_in;
|
||||
return;
|
||||
}
|
||||
if (is_zero(input_vector)) {
|
||||
rotation = rotation_in;
|
||||
return;
|
||||
}
|
||||
|
||||
const Quaternion quat_in = Quaternion{UNPACK4(rotation_in)};
|
||||
const float3 old_axis = transform_point_by_quaternion(quat_in, local_main_axis);
|
||||
const float3 pivot_axis = transform_point_by_quaternion(quat_in, local_pivot_axis);
|
||||
|
||||
float full_angle = angle_signed_on_axis_v3v3_v3(input_vector, old_axis, pivot_axis);
|
||||
if (full_angle > M_PI) {
|
||||
/* Make sure the point is rotated as little as possible. */
|
||||
full_angle -= 2.0f * M_PI;
|
||||
}
|
||||
|
||||
const float angle = factor * full_angle;
|
||||
|
||||
AxisAngle aa;
|
||||
aa.axis = normalize(pivot_axis);
|
||||
aa.angle = angle;
|
||||
|
||||
rotation = math_quaternion_multiply(to_quaternion(aa), quat_in).as_float4();
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/* SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_math_rotation_conversion_lib.glsl"
|
||||
#include "gpu_shader_math_vector_compare_lib.glsl"
|
||||
#include "gpu_shader_math_vector_lib.glsl"
|
||||
|
||||
[[node]]
|
||||
void axes_to_rotation(float3 primary_in,
|
||||
float3 secondary_in,
|
||||
float primary_idx_f,
|
||||
float secondary_idx_f,
|
||||
float tertiary_idx_f,
|
||||
float tertiary_factor,
|
||||
out float4 rotation)
|
||||
{
|
||||
float3 primary = normalize(primary_in);
|
||||
float3 secondary = secondary_in;
|
||||
float3 tertiary;
|
||||
|
||||
const bool primary_is_non_zero = !is_zero(primary);
|
||||
const bool secondary_is_non_zero = !is_zero(secondary);
|
||||
|
||||
if (primary_is_non_zero && secondary_is_non_zero) {
|
||||
tertiary = cross(primary, secondary);
|
||||
if (is_zero(tertiary)) {
|
||||
tertiary = orthogonal<float3>(primary);
|
||||
}
|
||||
tertiary = normalize(tertiary);
|
||||
secondary = cross(tertiary, primary);
|
||||
}
|
||||
else if (primary_is_non_zero) {
|
||||
secondary = orthogonal<float3>(primary);
|
||||
secondary = normalize(secondary);
|
||||
tertiary = cross(primary, secondary);
|
||||
}
|
||||
else if (secondary_is_non_zero) {
|
||||
secondary = normalize(secondary);
|
||||
primary = orthogonal<float3>(secondary);
|
||||
primary = normalize(primary);
|
||||
tertiary = cross(primary, secondary);
|
||||
}
|
||||
else {
|
||||
rotation = float4(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
const int primary_axis = int(primary_idx_f);
|
||||
const int secondary_axis = int(secondary_idx_f);
|
||||
const int tertiary_axis = int(tertiary_idx_f);
|
||||
|
||||
float3x3 mat;
|
||||
mat[primary_axis] = primary;
|
||||
mat[secondary_axis] = secondary;
|
||||
mat[tertiary_axis] = tertiary_factor * tertiary;
|
||||
|
||||
rotation = to_quaternion(mat).as_float4();
|
||||
}
|
||||
|
||||
[[node]]
|
||||
void axes_to_rotation_identity(float3 primary_in, float3 secondary_in, out float4 rotation)
|
||||
{
|
||||
rotation = float4(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
/* SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_math_rotation_conversion_lib.glsl"
|
||||
|
||||
[[node]]
|
||||
void axis_angle_to_rotation(float3 axis, float angle, out float4 rotation)
|
||||
{
|
||||
rotation = to_quaternion(axis, angle).as_float4();
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
/* SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_math_euler_lib.glsl"
|
||||
#include "gpu_shader_math_rotation_conversion_lib.glsl"
|
||||
|
||||
[[node]]
|
||||
void euler_to_rotation(float3 euler, out float4 rotation)
|
||||
{
|
||||
rotation = to_quaternion(EulerXYZ::from_float3(euler)).as_float4();
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
/* SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_math_quaternion_lib.glsl"
|
||||
|
||||
[[node]]
|
||||
void invert_rotation(float4 rotation, out float4 result)
|
||||
{
|
||||
result = quaternion_conjugate(Quaternion{UNPACK4(rotation)}).as_float4();
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_common_color_utils.glsl"
|
||||
#include "gpu_shader_math_rotation_lib.glsl"
|
||||
|
||||
[[node]]
|
||||
void node_mix_blend(float fac,
|
||||
|
|
@ -13,9 +14,12 @@ void node_mix_blend(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
outcol = mix(col1, col2, fac);
|
||||
}
|
||||
|
|
@ -29,9 +33,12 @@ void node_mix_add(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
outcol = mix(col1, col1 + col2, fac);
|
||||
|
|
@ -47,9 +54,12 @@ void node_mix_mult(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
outcol = mix(col1, col1 * col2, fac);
|
||||
|
|
@ -65,9 +75,12 @@ void node_mix_screen(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
float facm = 1.0f - fac;
|
||||
|
|
@ -85,9 +98,12 @@ void node_mix_overlay(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
float facm = 1.0f - fac;
|
||||
|
|
@ -125,9 +141,12 @@ void node_mix_sub(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
outcol = mix(col1, col1 - col2, fac);
|
||||
|
|
@ -144,9 +163,12 @@ void node_mix_div_fallback(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
float facm = 1.0f - fac;
|
||||
|
|
@ -173,9 +195,12 @@ void node_mix_diff(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
outcol = mix(col1, abs(col1 - col2), fac);
|
||||
|
|
@ -191,9 +216,12 @@ void node_mix_exclusion(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
outcol = max(mix(col1, col1 + col2 - 2.0f * col1 * col2, fac), 0.0f);
|
||||
|
|
@ -209,9 +237,12 @@ void node_mix_dark(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
outcol.rgb = mix(col1.rgb, min(col1.rgb, col2.rgb), fac);
|
||||
|
|
@ -227,9 +258,12 @@ void node_mix_light(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
outcol.rgb = mix(col1.rgb, max(col1.rgb, col2.rgb), fac);
|
||||
outcol.a = col1.a;
|
||||
|
|
@ -244,9 +278,12 @@ void node_mix_dodge(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
outcol = col1;
|
||||
|
||||
|
|
@ -297,9 +334,12 @@ void node_mix_burn(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
float tmp, facm = 1.0f - fac;
|
||||
|
|
@ -358,9 +398,12 @@ void node_mix_hue(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
float facm = 1.0f - fac;
|
||||
|
|
@ -389,9 +432,12 @@ void node_mix_sat(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
float facm = 1.0f - fac;
|
||||
|
|
@ -418,9 +464,12 @@ void node_mix_val(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
float facm = 1.0f - fac;
|
||||
|
|
@ -442,9 +491,12 @@ void node_mix_color(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
float facm = 1.0f - fac;
|
||||
|
|
@ -474,9 +526,12 @@ void node_mix_soft(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
float facm = 1.0f - fac;
|
||||
|
|
@ -496,9 +551,12 @@ void node_mix_linear(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
|
||||
outcol = col1 + fac * (2.0f * (col2 - float4(0.5f)));
|
||||
|
|
@ -514,9 +572,12 @@ void node_mix_float(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
/* Avoid using mix() due to float precision issues caused by different implementations. */
|
||||
outfloat = f1 * (1.0f - fac) + f2 * fac;
|
||||
|
|
@ -531,9 +592,12 @@ void node_mix_vector(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
/* Avoid using mix() due to float precision issues caused by different implementations. */
|
||||
outvec = v1 * (1.0f - fac) + v2 * fac;
|
||||
|
|
@ -548,9 +612,12 @@ void node_mix_vector_non_uniform(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
/* Avoid using mix() due to float precision issues caused by different implementations. */
|
||||
outvec = v1 * (float3(1.0f) - facvec) + v2 * facvec;
|
||||
|
|
@ -565,9 +632,12 @@ void node_mix_rgba(float fac,
|
|||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol)
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
outcol = mix(col1, col2, fac);
|
||||
}
|
||||
|
|
@ -589,3 +659,22 @@ void node_mix_clamp_value(float value, float min, float max, float &outfloat)
|
|||
{
|
||||
outfloat = clamp(value, min, max);
|
||||
}
|
||||
|
||||
[[node]]
|
||||
void node_mix_rotation(float fac,
|
||||
float3 facvec,
|
||||
float f1,
|
||||
float f2,
|
||||
float3 v1,
|
||||
float3 v2,
|
||||
float4 col1,
|
||||
float4 col2,
|
||||
float4 rot1,
|
||||
float4 rot2,
|
||||
float &outfloat,
|
||||
float3 &outvec,
|
||||
float4 &outcol,
|
||||
float4 &outrot)
|
||||
{
|
||||
outrot = interpolate(Quaternion{UNPACK4(rot1)}, Quaternion{UNPACK4(rot2)}, fac).as_float4();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
/* SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_math_vector_compare_lib.glsl"
|
||||
|
||||
[[node]]
|
||||
void quaternion_to_rotation(float w, float x, float y, float z, out float4 rotation)
|
||||
{
|
||||
const float4 quat = float4(w, x, y, z);
|
||||
if (!is_zero(quat)) {
|
||||
rotation = normalize(quat);
|
||||
}
|
||||
else {
|
||||
rotation = float4(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/* SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_math_quaternion_lib.glsl"
|
||||
|
||||
[[node]]
|
||||
void rotate_rotation_global(float4 rotation, float4 rotate_by, out float4 result)
|
||||
{
|
||||
result = math_quaternion_multiply(Quaternion{UNPACK4(rotate_by)}, Quaternion{UNPACK4(rotation)})
|
||||
.as_float4();
|
||||
}
|
||||
|
||||
[[node]]
|
||||
void rotate_rotation_local(float4 rotation, float4 rotate_by, out float4 result)
|
||||
{
|
||||
result = math_quaternion_multiply(Quaternion{UNPACK4(rotation)}, Quaternion{UNPACK4(rotate_by)})
|
||||
.as_float4();
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
/* SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_math_quaternion_lib.glsl"
|
||||
|
||||
[[node]]
|
||||
void rotate_vector(float3 vector, float4 rotation, out float3 result)
|
||||
{
|
||||
result = transform_point_by_quaternion(Quaternion{UNPACK4(rotation)}, vector);
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
/* SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_math_rotation_conversion_lib.glsl"
|
||||
|
||||
[[node]]
|
||||
void rotation_to_axis_angle(float4 rotation, out float3 axis, out float angle)
|
||||
{
|
||||
const AxisAngle aa = to_axis_angle(Quaternion{UNPACK4(rotation)});
|
||||
axis = aa.axis;
|
||||
angle = aa.angle;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
/* SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_math_matrix_construct_lib.glsl"
|
||||
#include "gpu_shader_math_rotation_conversion_lib.glsl"
|
||||
|
||||
[[node]]
|
||||
void rotation_to_euler(float4 rotation, out float3 euler)
|
||||
{
|
||||
Quaternion quat = Quaternion{UNPACK4(rotation)};
|
||||
euler = to_euler(from_rotation(quat)).as_float3();
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
/* SPDX-FileCopyrightText: 2026 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
[[node]]
|
||||
void rotation_to_quaternion(float4 rotation, out float w, out float x, out float y, out float z)
|
||||
{
|
||||
w = rotation.x;
|
||||
x = rotation.y;
|
||||
y = rotation.z;
|
||||
z = rotation.w;
|
||||
}
|
||||
|
|
@ -3275,7 +3275,7 @@ static const EnumPropertyItem *rna_ShaderNodeMix_data_type_itemf(bContext * /*C*
|
|||
const eNodeSocketDatatype data_type = eNodeSocketDatatype(item->value);
|
||||
if (data_type == SOCK_ROTATION) {
|
||||
const bNodeTree *tree = reinterpret_cast<const bNodeTree *>(ptr->owner_id);
|
||||
if (tree->type == NTREE_GEOMETRY) {
|
||||
if (ELEM(tree->type, NTREE_GEOMETRY, NTREE_COMPOSIT)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ static bool composite_node_tree_socket_type_valid(bke::bNodeTreeType * /*ntreety
|
|||
SOCK_RGBA,
|
||||
SOCK_MATRIX,
|
||||
SOCK_MENU,
|
||||
SOCK_ROTATION,
|
||||
SOCK_STRING,
|
||||
SOCK_OBJECT,
|
||||
SOCK_FONT);
|
||||
|
|
@ -141,6 +142,21 @@ static bool composite_validate_link(eNodeSocketDatatype from_type, eNodeSocketDa
|
|||
return true;
|
||||
}
|
||||
|
||||
if (ELEM(from_type, SOCK_FLOAT, SOCK_VECTOR) && to_type == SOCK_ROTATION) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (from_type == SOCK_MATRIX && to_type == SOCK_ROTATION) {
|
||||
return true;
|
||||
}
|
||||
if (from_type == SOCK_ROTATION && to_type == SOCK_MATRIX) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (from_type == SOCK_ROTATION && to_type == SOCK_VECTOR) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return from_type == to_type;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -642,6 +642,7 @@ class FileOutputOperation : public NodeOperation {
|
|||
case ResultType::Bool:
|
||||
case ResultType::Float4x4:
|
||||
case ResultType::Menu:
|
||||
case ResultType::Quaternion:
|
||||
case ResultType::String:
|
||||
case ResultType::Object:
|
||||
case ResultType::Image:
|
||||
|
|
@ -683,6 +684,7 @@ class FileOutputOperation : public NodeOperation {
|
|||
case ResultType::Bool:
|
||||
case ResultType::Float4x4:
|
||||
case ResultType::Menu:
|
||||
case ResultType::Quaternion:
|
||||
case ResultType::String:
|
||||
case ResultType::Object:
|
||||
case ResultType::Image:
|
||||
|
|
@ -745,6 +747,7 @@ class FileOutputOperation : public NodeOperation {
|
|||
case ResultType::Bool:
|
||||
case ResultType::Float4x4:
|
||||
case ResultType::Menu:
|
||||
case ResultType::Quaternion:
|
||||
case ResultType::String:
|
||||
case ResultType::Object:
|
||||
case ResultType::Image:
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "NOD_rna_define.hh"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
#include "node_shader_util.hh"
|
||||
|
||||
namespace blender::nodes::node_fn_align_rotation_to_vector_cc {
|
||||
|
||||
|
|
@ -191,6 +192,35 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
|
|||
math::Axis::from_int(node.custom1), NodeAlignEulerToVectorPivotAxis(node.custom2));
|
||||
}
|
||||
|
||||
static int node_gpu_material(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
const math::Axis main_axis_mode = math::Axis::from_int(node->custom1);
|
||||
const NodeAlignEulerToVectorPivotAxis pivot_axis_mode = NodeAlignEulerToVectorPivotAxis(
|
||||
node->custom2);
|
||||
|
||||
float3 local_main_axis = {0.0f, 0.0f, 0.0f};
|
||||
local_main_axis[main_axis_mode.as_int()] = 1.0f;
|
||||
|
||||
if (pivot_axis_mode == FN_NODE_ALIGN_EULER_TO_VECTOR_PIVOT_AXIS_AUTO) {
|
||||
return GPU_stack_link(
|
||||
mat, node, "align_rotation_to_vector_auto_pivot", in, out, GPU_constant(local_main_axis));
|
||||
}
|
||||
|
||||
float3 local_pivot_axis = {0.0f, 0.0f, 0.0f};
|
||||
local_pivot_axis[pivot_axis_mode - 1] = 1.0f;
|
||||
return GPU_stack_link(mat,
|
||||
node,
|
||||
"align_rotation_to_vector_fixed_pivot",
|
||||
in,
|
||||
out,
|
||||
GPU_constant(local_main_axis),
|
||||
GPU_constant(local_pivot_axis));
|
||||
}
|
||||
|
||||
static void node_rna(StructRNA *srna)
|
||||
{
|
||||
static const EnumPropertyItem axis_items[] = {
|
||||
|
|
@ -243,7 +273,7 @@ static void node_register()
|
|||
{
|
||||
static bke::bNodeType ntype;
|
||||
|
||||
fn_node_type_base(
|
||||
fn_cmp_node_type_base(
|
||||
&ntype, "FunctionNodeAlignRotationToVector"_ustr, FN_NODE_ALIGN_ROTATION_TO_VECTOR);
|
||||
ntype.ui_name = "Align Rotation to Vector";
|
||||
ntype.ui_description = "Orient a rotation along the given direction";
|
||||
|
|
@ -253,6 +283,7 @@ static void node_register()
|
|||
ntype.initfunc = node_init;
|
||||
ntype.draw_buttons = node_layout;
|
||||
ntype.build_multi_function = node_build_multi_function;
|
||||
ntype.gpu_fn = node_gpu_material;
|
||||
bke::node_register_type(ntype);
|
||||
|
||||
node_rna(ntype.rna_ext.srna);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "NOD_rna_define.hh"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
#include "node_shader_util.hh"
|
||||
|
||||
namespace blender::nodes::node_fn_axes_to_rotation_cc {
|
||||
|
||||
|
|
@ -150,6 +151,38 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
|
|||
math::Axis::from_int(node.custom1), math::Axis::from_int(node.custom2));
|
||||
}
|
||||
|
||||
static int node_gpu_material(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
if (node->custom1 == node->custom2) {
|
||||
return GPU_stack_link(mat, node, "axes_to_rotation_identity", in, out);
|
||||
}
|
||||
|
||||
const float primary = float(node->custom1);
|
||||
const float secondary = float(node->custom2);
|
||||
/* Through cancellation this will set the last axis to be the one that's neither the primary
|
||||
* nor secondary axis. */
|
||||
const int tertiary_axis = (0 + 1 + 2) - node->custom1 - node->custom2;
|
||||
const float tertiary = float(tertiary_axis);
|
||||
|
||||
/* Might have to invert the axis to make sure that the created matrix has determinant 1. */
|
||||
const bool invert_tertiary = (node->custom2 + 1) % 3 == node->custom1;
|
||||
const float tertiary_factor = invert_tertiary ? -1.0f : 1.0f;
|
||||
|
||||
return GPU_stack_link(mat,
|
||||
node,
|
||||
"axes_to_rotation",
|
||||
in,
|
||||
out,
|
||||
GPU_constant(&primary),
|
||||
GPU_constant(&secondary),
|
||||
GPU_constant(&tertiary),
|
||||
GPU_constant(&tertiary_factor));
|
||||
}
|
||||
|
||||
static void node_extra_info(NodeExtraInfoParams ¶ms)
|
||||
{
|
||||
if (params.node.custom1 == params.node.custom2) {
|
||||
|
|
@ -188,7 +221,7 @@ static void node_rna(StructRNA *srna)
|
|||
static void node_register()
|
||||
{
|
||||
static bke::bNodeType ntype;
|
||||
fn_node_type_base(&ntype, "FunctionNodeAxesToRotation"_ustr, FN_NODE_AXES_TO_ROTATION);
|
||||
fn_cmp_node_type_base(&ntype, "FunctionNodeAxesToRotation"_ustr, FN_NODE_AXES_TO_ROTATION);
|
||||
ntype.ui_name = "Axes to Rotation";
|
||||
ntype.ui_description =
|
||||
"Create a rotation from a primary and (ideally orthogonal) secondary axis";
|
||||
|
|
@ -199,6 +232,7 @@ static void node_register()
|
|||
ntype.build_multi_function = node_build_multi_function;
|
||||
ntype.draw_buttons = node_layout;
|
||||
ntype.get_extra_info = node_extra_info;
|
||||
ntype.gpu_fn = node_gpu_material;
|
||||
node_rna(ntype.rna_ext.srna);
|
||||
bke::node_register_type(ntype);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "NOD_value_elem_eval.hh"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
#include "node_shader_util.hh"
|
||||
|
||||
namespace blender::nodes::node_fn_axis_angle_to_rotation_cc {
|
||||
|
||||
|
|
@ -33,6 +34,15 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
|
|||
builder.set_matching_fn(fn);
|
||||
}
|
||||
|
||||
static int node_gpu_material(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
return GPU_stack_link(mat, node, "axis_angle_to_rotation", in, out);
|
||||
}
|
||||
|
||||
static void node_eval_elem(value_elem::ElemEvalParams ¶ms)
|
||||
{
|
||||
using namespace value_elem;
|
||||
|
|
@ -67,13 +77,14 @@ static void node_eval_inverse(inverse_eval::InverseEvalParams ¶ms)
|
|||
static void node_register()
|
||||
{
|
||||
static bke::bNodeType ntype;
|
||||
fn_node_type_base(
|
||||
fn_cmp_node_type_base(
|
||||
&ntype, "FunctionNodeAxisAngleToRotation"_ustr, FN_NODE_AXIS_ANGLE_TO_ROTATION);
|
||||
ntype.ui_name = "Axis Angle to Rotation";
|
||||
ntype.ui_description = "Build a rotation from an axis and a rotation around that axis";
|
||||
ntype.enum_name_legacy = "AXIS_ANGLE_TO_ROTATION";
|
||||
ntype.nclass = NODE_CLASS_CONVERTER;
|
||||
ntype.declare = node_declare;
|
||||
ntype.gpu_fn = node_gpu_material;
|
||||
ntype.build_multi_function = node_build_multi_function;
|
||||
ntype.eval_elem = node_eval_elem;
|
||||
ntype.eval_inverse_elem = node_eval_inverse_elem;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "NOD_value_elem_eval.hh"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
#include "node_shader_util.hh"
|
||||
|
||||
namespace blender::nodes::node_fn_euler_to_rotation_cc {
|
||||
|
||||
|
|
@ -18,6 +19,15 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||
b.add_output<decl::Rotation>("Rotation"_ustr);
|
||||
};
|
||||
|
||||
static int node_gpu_material(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
return GPU_stack_link(mat, node, "euler_to_rotation", in, out);
|
||||
}
|
||||
|
||||
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
|
||||
{
|
||||
static auto fn = mf::build::SI1_SO<float3, math::Quaternion>(
|
||||
|
|
@ -55,12 +65,13 @@ static void node_eval_inverse(inverse_eval::InverseEvalParams ¶ms)
|
|||
static void node_register()
|
||||
{
|
||||
static bke::bNodeType ntype;
|
||||
fn_node_type_base(&ntype, "FunctionNodeEulerToRotation"_ustr, FN_NODE_EULER_TO_ROTATION);
|
||||
fn_cmp_node_type_base(&ntype, "FunctionNodeEulerToRotation"_ustr, FN_NODE_EULER_TO_ROTATION);
|
||||
ntype.ui_name = "Euler to Rotation";
|
||||
ntype.ui_description = "Build a rotation from separate angles around each axis";
|
||||
ntype.enum_name_legacy = "EULER_TO_ROTATION";
|
||||
ntype.nclass = NODE_CLASS_CONVERTER;
|
||||
ntype.declare = node_declare;
|
||||
ntype.gpu_fn = node_gpu_material;
|
||||
ntype.build_multi_function = node_build_multi_function;
|
||||
ntype.eval_elem = node_eval_elem;
|
||||
ntype.eval_inverse_elem = node_eval_inverse_elem;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ static void node_register()
|
|||
{
|
||||
static bke::bNodeType ntype;
|
||||
|
||||
fn_node_type_base(&ntype, "FunctionNodeInputRotation"_ustr, FN_NODE_INPUT_ROTATION);
|
||||
fn_cmp_node_type_base(&ntype, "FunctionNodeInputRotation"_ustr, FN_NODE_INPUT_ROTATION);
|
||||
ntype.ui_name = "Rotation";
|
||||
ntype.ui_description =
|
||||
"Provide a rotation value that can be connected to other nodes in the tree";
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "BLI_math_quaternion.hh"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
#include "node_shader_util.hh"
|
||||
|
||||
namespace blender::nodes::node_fn_invert_rotation_cc {
|
||||
|
||||
|
|
@ -17,6 +18,15 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||
b.add_output<decl::Rotation>("Rotation"_ustr).align_with_previous();
|
||||
};
|
||||
|
||||
static int node_gpu_material(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
return GPU_stack_link(mat, node, "invert_rotation", in, out);
|
||||
}
|
||||
|
||||
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
|
||||
{
|
||||
static auto fn = mf::build::SI1_SO<math::Quaternion, math::Quaternion>(
|
||||
|
|
@ -27,12 +37,13 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
|
|||
static void node_register()
|
||||
{
|
||||
static bke::bNodeType ntype;
|
||||
fn_node_type_base(&ntype, "FunctionNodeInvertRotation"_ustr, FN_NODE_INVERT_ROTATION);
|
||||
fn_cmp_node_type_base(&ntype, "FunctionNodeInvertRotation"_ustr, FN_NODE_INVERT_ROTATION);
|
||||
ntype.ui_name = "Invert Rotation";
|
||||
ntype.ui_description = "Compute the inverse of the given rotation";
|
||||
ntype.enum_name_legacy = "INVERT_ROTATION";
|
||||
ntype.nclass = NODE_CLASS_CONVERTER;
|
||||
ntype.declare = node_declare;
|
||||
ntype.gpu_fn = node_gpu_material;
|
||||
ntype.build_multi_function = node_build_multi_function;
|
||||
bke::node_register_type(ntype);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "BLI_math_quaternion.hh"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
#include "node_shader_util.hh"
|
||||
|
||||
namespace blender::nodes::node_fn_quaternion_to_rotation_cc {
|
||||
|
||||
|
|
@ -28,16 +29,26 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
|
|||
builder.set_matching_fn(fn);
|
||||
}
|
||||
|
||||
static int node_gpu_material(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
return GPU_stack_link(mat, node, "quaternion_to_rotation", in, out);
|
||||
}
|
||||
|
||||
static void node_register()
|
||||
{
|
||||
static bke::bNodeType ntype;
|
||||
fn_node_type_base(
|
||||
fn_cmp_node_type_base(
|
||||
&ntype, "FunctionNodeQuaternionToRotation"_ustr, FN_NODE_QUATERNION_TO_ROTATION);
|
||||
ntype.ui_name = "Quaternion to Rotation";
|
||||
ntype.ui_description = "Build a rotation from quaternion components";
|
||||
ntype.enum_name_legacy = "QUATERNION_TO_ROTATION";
|
||||
ntype.nclass = NODE_CLASS_CONVERTER;
|
||||
ntype.declare = node_declare;
|
||||
ntype.gpu_fn = node_gpu_material;
|
||||
ntype.build_multi_function = node_build_multi_function;
|
||||
bke::node_register_type(ntype);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "NOD_rna_define.hh"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
#include "node_shader_util.hh"
|
||||
|
||||
namespace blender::nodes::node_fn_rotate_rotation_cc {
|
||||
|
||||
|
|
@ -32,6 +33,28 @@ static void node_layout(ui::Layout &layout, bContext * /*C*/, PointerRNA *ptr)
|
|||
layout.prop(ptr, "rotation_space", ui::ITEM_R_EXPAND, std::nullopt, ICON_NONE);
|
||||
}
|
||||
|
||||
static int node_gpu_material(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
const char *name = nullptr;
|
||||
switch (RotationSpace(node->custom1)) {
|
||||
case RotationSpace::Global:
|
||||
name = "rotate_rotation_global";
|
||||
break;
|
||||
case RotationSpace::Local:
|
||||
name = "rotate_rotation_local";
|
||||
break;
|
||||
}
|
||||
|
||||
if (name != nullptr) {
|
||||
return GPU_stack_link(mat, node, name, in, out);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
|
||||
{
|
||||
switch (RotationSpace(builder.node().custom1)) {
|
||||
|
|
@ -77,13 +100,14 @@ static void node_rna(StructRNA *srna)
|
|||
static void node_register()
|
||||
{
|
||||
static bke::bNodeType ntype;
|
||||
fn_node_type_base(&ntype, "FunctionNodeRotateRotation"_ustr, FN_NODE_ROTATE_ROTATION);
|
||||
fn_cmp_node_type_base(&ntype, "FunctionNodeRotateRotation"_ustr, FN_NODE_ROTATE_ROTATION);
|
||||
ntype.ui_name = "Rotate Rotation";
|
||||
ntype.ui_description = "Apply a secondary rotation to a given rotation value";
|
||||
ntype.enum_name_legacy = "ROTATE_ROTATION";
|
||||
ntype.nclass = NODE_CLASS_CONVERTER;
|
||||
ntype.declare = node_declare;
|
||||
ntype.draw_buttons = node_layout;
|
||||
ntype.gpu_fn = node_gpu_material;
|
||||
ntype.build_multi_function = node_build_multi_function;
|
||||
bke::node_register_type(ntype);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "BLI_math_quaternion.hh"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
#include "node_shader_util.hh"
|
||||
|
||||
namespace blender::nodes::node_fn_rotate_vector_cc {
|
||||
|
||||
|
|
@ -18,6 +19,15 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||
b.add_input<decl::Rotation>("Rotation"_ustr);
|
||||
};
|
||||
|
||||
static int node_gpu_material(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
return GPU_stack_link(mat, node, "rotate_vector", in, out);
|
||||
}
|
||||
|
||||
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
|
||||
{
|
||||
static auto fn = mf::build::SI2_SO<float3, math::Quaternion, float3>(
|
||||
|
|
@ -29,12 +39,13 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
|
|||
static void node_register()
|
||||
{
|
||||
static bke::bNodeType ntype;
|
||||
fn_node_type_base(&ntype, "FunctionNodeRotateVector"_ustr, FN_NODE_ROTATE_VECTOR);
|
||||
fn_cmp_node_type_base(&ntype, "FunctionNodeRotateVector"_ustr, FN_NODE_ROTATE_VECTOR);
|
||||
ntype.ui_name = "Rotate Vector";
|
||||
ntype.ui_description = "Apply a rotation to a given vector";
|
||||
ntype.enum_name_legacy = "ROTATE_VECTOR";
|
||||
ntype.nclass = NODE_CLASS_CONVERTER;
|
||||
ntype.declare = node_declare;
|
||||
ntype.gpu_fn = node_gpu_material;
|
||||
ntype.build_multi_function = node_build_multi_function;
|
||||
bke::node_register_type(ntype);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "NOD_value_elem_eval.hh"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
#include "node_shader_util.hh"
|
||||
|
||||
namespace blender::nodes::node_fn_rotation_to_axis_angle_cc {
|
||||
|
||||
|
|
@ -46,6 +47,15 @@ class QuaterniontoAxisAngleFunction : public mf::MultiFunction {
|
|||
}
|
||||
};
|
||||
|
||||
static int node_gpu_material(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
return GPU_stack_link(mat, node, "rotation_to_axis_angle", in, out);
|
||||
}
|
||||
|
||||
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
|
||||
{
|
||||
static QuaterniontoAxisAngleFunction fn;
|
||||
|
|
@ -89,13 +99,14 @@ static void node_eval_inverse(inverse_eval::InverseEvalParams ¶ms)
|
|||
static void node_register()
|
||||
{
|
||||
static bke::bNodeType ntype;
|
||||
fn_node_type_base(
|
||||
fn_cmp_node_type_base(
|
||||
&ntype, "FunctionNodeRotationToAxisAngle"_ustr, FN_NODE_ROTATION_TO_AXIS_ANGLE);
|
||||
ntype.ui_name = "Rotation to Axis Angle";
|
||||
ntype.ui_description = "Convert a rotation to axis angle components";
|
||||
ntype.enum_name_legacy = "ROTATION_TO_AXIS_ANGLE";
|
||||
ntype.nclass = NODE_CLASS_CONVERTER;
|
||||
ntype.declare = node_declare;
|
||||
ntype.gpu_fn = node_gpu_material;
|
||||
ntype.build_multi_function = node_build_multi_function;
|
||||
ntype.eval_elem = node_eval_elem;
|
||||
ntype.eval_inverse_elem = node_eval_inverse_elem;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "NOD_value_elem_eval.hh"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
#include "node_shader_util.hh"
|
||||
|
||||
namespace blender::nodes::node_fn_rotation_to_euler_cc {
|
||||
|
||||
|
|
@ -18,6 +19,15 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||
b.add_output<decl::Vector>("Euler"_ustr).subtype(PROP_EULER);
|
||||
};
|
||||
|
||||
static int node_gpu_material(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
return GPU_stack_link(mat, node, "rotation_to_euler", in, out);
|
||||
}
|
||||
|
||||
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
|
||||
{
|
||||
static auto fn = mf::build::SI1_SO<math::Quaternion, float3>(
|
||||
|
|
@ -54,12 +64,13 @@ static void node_eval_inverse(inverse_eval::InverseEvalParams ¶ms)
|
|||
static void node_register()
|
||||
{
|
||||
static bke::bNodeType ntype;
|
||||
fn_node_type_base(&ntype, "FunctionNodeRotationToEuler"_ustr, FN_NODE_ROTATION_TO_EULER);
|
||||
fn_cmp_node_type_base(&ntype, "FunctionNodeRotationToEuler"_ustr, FN_NODE_ROTATION_TO_EULER);
|
||||
ntype.ui_name = "Rotation to Euler";
|
||||
ntype.ui_description = "Convert a standard rotation value to an Euler rotation";
|
||||
ntype.enum_name_legacy = "ROTATION_TO_EULER";
|
||||
ntype.nclass = NODE_CLASS_CONVERTER;
|
||||
ntype.declare = node_declare;
|
||||
ntype.gpu_fn = node_gpu_material;
|
||||
ntype.build_multi_function = node_build_multi_function;
|
||||
ntype.eval_elem = node_eval_elem;
|
||||
ntype.eval_inverse_elem = node_eval_inverse_elem;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "BLI_math_quaternion_types.hh"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
#include "node_shader_util.hh"
|
||||
|
||||
namespace blender::nodes::node_fn_rotation_to_quaternion_cc {
|
||||
|
||||
|
|
@ -56,16 +57,26 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
|
|||
builder.set_matching_fn(fn);
|
||||
}
|
||||
|
||||
static int node_gpu_material(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
return GPU_stack_link(mat, node, "rotation_to_quaternion", in, out);
|
||||
}
|
||||
|
||||
static void node_register()
|
||||
{
|
||||
static bke::bNodeType ntype;
|
||||
fn_node_type_base(
|
||||
fn_cmp_node_type_base(
|
||||
&ntype, "FunctionNodeRotationToQuaternion"_ustr, FN_NODE_ROTATION_TO_QUATERNION);
|
||||
ntype.ui_name = "Rotation to Quaternion";
|
||||
ntype.ui_description = "Retrieve the quaternion components representing a rotation";
|
||||
ntype.enum_name_legacy = "ROTATION_TO_QUATERNION";
|
||||
ntype.nclass = NODE_CLASS_CONVERTER;
|
||||
ntype.declare = node_declare;
|
||||
ntype.gpu_fn = node_gpu_material;
|
||||
ntype.build_multi_function = node_build_multi_function;
|
||||
bke::node_register_type(ntype);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,14 @@ namespace blender {
|
|||
static int node_exec_socket_use_stack(bNodeSocket *sock)
|
||||
{
|
||||
/* NOTE: INT and BOOL supported as FLOAT. Only for EEVEE. */
|
||||
return ELEM(sock->type, SOCK_INT, SOCK_BOOLEAN, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_SHADER);
|
||||
return ELEM(sock->type,
|
||||
SOCK_INT,
|
||||
SOCK_BOOLEAN,
|
||||
SOCK_FLOAT,
|
||||
SOCK_VECTOR,
|
||||
SOCK_RGBA,
|
||||
SOCK_SHADER,
|
||||
SOCK_ROTATION);
|
||||
}
|
||||
|
||||
bNodeStack *node_get_socket_stack(bNodeStack *stack, bNodeSocket *sock)
|
||||
|
|
@ -140,6 +147,9 @@ static bNodeStack *setup_stack(bNodeStack *stack, bNodeTree *ntree, bNode *node,
|
|||
case SOCK_RGBA:
|
||||
node_socket_get_color(ntree, node, sock, ns->vec);
|
||||
break;
|
||||
case SOCK_ROTATION:
|
||||
node_socket_get_rotation(ntree, node, sock, ns->vec);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "DNA_node_types.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_rotation.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utf8.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
|
@ -296,6 +297,25 @@ void node_socket_set_vector(bNodeTree *ntree,
|
|||
RNA_float_set_array(&ptr, "default_value", value);
|
||||
}
|
||||
|
||||
void node_socket_get_rotation(bNodeTree *ntree, bNode * /*node*/, bNodeSocket *sock, float *value)
|
||||
{
|
||||
PointerRNA ptr = RNA_pointer_create_discrete(id_cast<ID *>(ntree), RNA_NodeSocket, sock);
|
||||
float euler[3];
|
||||
RNA_float_get_array(&ptr, "default_value", euler);
|
||||
eul_to_quat(value, euler);
|
||||
}
|
||||
|
||||
void node_socket_set_rotation(bNodeTree *ntree,
|
||||
bNode * /*node*/,
|
||||
bNodeSocket *sock,
|
||||
const float *value)
|
||||
{
|
||||
PointerRNA ptr = RNA_pointer_create_discrete(id_cast<ID *>(ntree), RNA_NodeSocket, sock);
|
||||
float euler[3];
|
||||
quat_to_eul(euler, value);
|
||||
RNA_float_set_array(&ptr, "default_value", euler);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender
|
||||
|
|
|
|||
|
|
@ -66,5 +66,10 @@ void node_socket_get_color(bNodeTree *ntree, bNode *node, bNodeSocket *sock, flo
|
|||
void node_socket_set_color(bNodeTree *ntree, bNode *node, bNodeSocket *sock, const float *value);
|
||||
void node_socket_get_vector(bNodeTree *ntree, bNode *node, bNodeSocket *sock, float *value);
|
||||
void node_socket_set_vector(bNodeTree *ntree, bNode *node, bNodeSocket *sock, const float *value);
|
||||
void node_socket_get_rotation(bNodeTree *ntree, bNode *node, bNodeSocket *sock, float *value);
|
||||
void node_socket_set_rotation(bNodeTree *ntree,
|
||||
bNode *node,
|
||||
bNodeSocket *sock,
|
||||
const float *value);
|
||||
|
||||
} // namespace blender
|
||||
|
|
|
|||
|
|
@ -154,6 +154,9 @@ static void nodestack_get_vec(float *in, short type_in, bNodeStack *ns)
|
|||
copy_v3_v3(in, from);
|
||||
}
|
||||
}
|
||||
else if (type_in == SOCK_ROTATION) {
|
||||
copy_v4_v4(in, from);
|
||||
}
|
||||
else { /* type_in==SOCK_RGBA */
|
||||
if (ns->sockettype == SOCK_RGBA) {
|
||||
copy_v4_v4(in, from);
|
||||
|
|
@ -218,6 +221,9 @@ void node_gpu_stack_from_data(GPUNodeStack *gs, bNodeSocket *socket, bNodeStack
|
|||
else if (socket->type == SOCK_SHADER) {
|
||||
gs->type = GPU_CLOSURE;
|
||||
}
|
||||
else if (socket->type == SOCK_ROTATION) {
|
||||
gs->type = GPU_VEC4;
|
||||
}
|
||||
else {
|
||||
gs->type = GPU_NONE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ static const char *gpu_shader_get_name(eNodeSocketDatatype data_type,
|
|||
return nullptr;
|
||||
}
|
||||
case SOCK_ROTATION:
|
||||
return nullptr;
|
||||
return "node_mix_rotation";
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
return nullptr;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:06c8fe74e220b8ee06a03b1ca387030acc6f1f9ef447d7105914db74258cd003
|
||||
size 81502
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d19d7ee16337cde23143173a4e5ee2ce75a7184bcb605779ec769ed9c89d47b7
|
||||
size 83079
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6764f5e87261734ec4551728ea6f47a2efe2d65ae8c76645f7bee5a164079772
|
||||
size 42936
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d546a9d14cdb4d3c9dedf5307ebfa7053ca67a99e66e04e6aa80ad707f8e9941
|
||||
size 79010
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1b8cd10c9cae0d874dd6803467e87e1eee93bb7fcd1a744344820d51af166dc2
|
||||
size 82691
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2b5776bdb0bb6c7b0f8f6250654b3814c076eb9734f596f01ac4a319b3682592
|
||||
size 82811
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b60d5951d046d9c640dc592e6b8b805059622b2bd1a8aad13f69920e7eb535f7
|
||||
size 85178
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:858979c4232a26d4de9bd12e41e35409f0c9332c886ae90c9c6c326a2cad862a
|
||||
size 62042
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:706aa244e58d4a8be8d1361ef381c559ef190d533e35ee9f2d940cadc7a5e8b6
|
||||
size 83079
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:da86e840127b2114051b87add5a0bb01b41974cf1aae96499b5f2fd63696cb4d
|
||||
size 81906
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e2235cb71ff03d9b5772255bb581c3ce1983a04bac46afebc8f890a4fe6ab222
|
||||
size 76079
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b30b434c11fc5884a1c0c2a3c3695a78bcd611084c2ec373b5d39442ecb8e6ed
|
||||
size 54782
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:39ef7231add469fb1bcb6f1cb78168bf1cde3d53f965ad0580529945e43ff889
|
||||
size 75825
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4e1d1323bcc170dd566ce5535546d0ffe128803f1df82736cb2595d195eecef5
|
||||
size 82959
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9a6fe963dabf6aa433ee1a6127f6ad23c65dca2ff7d82a474b5a42d37308f8a9
|
||||
size 16017
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ac26285272be12fda5456b440c77a7fe1811a9ba6aefad0316f03c33868716df
|
||||
size 79541
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:db44c0cf191f4bcc2edb086884fcf7d51292ef8e15d14d3005fbe840943bf68e
|
||||
size 82966
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:985f1f18f429eab009c5343e1c10a374e7a070a7e1a7d26f09ac0567baa93c45
|
||||
size 85901
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d4d19405bfbfbc78f3eab5dae5fa7159b000ddc0317b51a8311fd4f61b95838a
|
||||
size 59511
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f47665147f8ea0ef0fb6fa5bb605886430af9901be269fbe8aa2ee0f2effa855
|
||||
size 109608
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:58eab1611f8de57c36399db8ccacbf02d46b61de47aa132ec44746b5304beed9
|
||||
size 109926
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:75d55c9f292bf38444b6eac7605d25313d4453bfcc0777846b6e0723eb1c0607
|
||||
size 355339
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c065a41ba1f3b08336cd9abdddfda23249324a370267194e9772f830b9c1cd3b
|
||||
size 113512
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:23f92292f29ca88a0febe5fcc9fb7db645f627f638763cf06fae0a58f21791ff
|
||||
size 109493
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:aa9d6519dfb7a29ebe787518e18bc231da819b30b6fe129ef912fad2759a454f
|
||||
size 112481
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a73e1b9503c3fba4a6e9c83f3ef81d63b0a9fd1f1a3d25683cc7a65956dc406d
|
||||
size 113693
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:150c5ba6d218ddb85029cb2defdb0bfcf27ce137a6a5a25530e21faa96cf2d89
|
||||
size 112172
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5b0b007ab7d1fd69734b80b88d4a55009f2136b3b9341e1660cb11272f7e87df
|
||||
size 113097
|
||||
3
tests/files/compositor/rotation/group_rotation.blend
Normal file
3
tests/files/compositor/rotation/group_rotation.blend
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8a931ad8a043825304dfdffc374081aa498e65c138a590f761c1765911e0ec31
|
||||
size 111750
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5c90ea24dd5c2d2d272fe9fed346dd5cb13513ecabca237db5280e9000100c5d
|
||||
size 111374
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:25b958c525b3afe2ece32387e1b14172b8aa3f9d69be067e49ef39ba2f3a6de3
|
||||
size 108009
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ad44c9bbb2cea0c29469d3cb1852a91ced1f85a46142abc180f6243bbd0c51df
|
||||
size 109388
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fb1419b44c6904feee6ed5848e9fd574d4b8ec0cd7be0d1f47499d54b6303d0c
|
||||
size 108167
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:688504c12b53e3556f9b055c233a1fef2f6d7953a5498f9a7e2abe0b7a91fc5d
|
||||
size 104310
|
||||
3
tests/files/compositor/rotation/node_mix_rotation.blend
Normal file
3
tests/files/compositor/rotation/node_mix_rotation.blend
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:293efd232f64a367234b5760df32a6961d1304d8244a7aaf13230d20fcb6c5c7
|
||||
size 110528
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:419a71de463b7ee664fd74d07441c6f1ee2bff2c4d63537d49b2fbc07ab5af79
|
||||
size 110551
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:09692efd427248e1ec5e73e971f8189cb8aded58361a47efcde361da03fd2a6d
|
||||
size 111628
|
||||
3
tests/files/compositor/rotation/node_rotate_vector.blend
Normal file
3
tests/files/compositor/rotation/node_rotate_vector.blend
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8d957eeed636984d95b255c8c60686549539fc84d602f33aa1facadf45245477
|
||||
size 108264
|
||||
|
|
@ -1099,6 +1099,7 @@ if(TEST_SRC_DIR_EXISTS)
|
|||
texture
|
||||
utilities
|
||||
vector
|
||||
rotation
|
||||
group
|
||||
|
||||
pixel_nodes
|
||||
|
|
@ -1137,6 +1138,7 @@ if(WITH_GPU_COMPOSITOR_TESTS AND TEST_SRC_DIR_EXISTS)
|
|||
texture
|
||||
utilities
|
||||
vector
|
||||
rotation
|
||||
group
|
||||
|
||||
pixel_nodes
|
||||
|
|
|
|||
|
|
@ -496,7 +496,7 @@ class CompositorNodeGroupInterfaceTest(AbstractNodeGroupInterfaceTest, NodeGroup
|
|||
self.do_test_socket_type("NodeSocketInt", subtype='PERCENTAGE')
|
||||
self.do_test_invalid_socket_type("NodeSocketMaterial")
|
||||
self.do_test_socket_type("NodeSocketObject")
|
||||
self.do_test_invalid_socket_type("NodeSocketRotation")
|
||||
self.do_test_socket_type("NodeSocketRotation")
|
||||
self.do_test_invalid_socket_type("NodeSocketShader")
|
||||
self.do_test_socket_type("NodeSocketString")
|
||||
self.do_test_invalid_socket_type("NodeSocketTexture")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue