diff options
author | Charlie Jolly <mistajolly@gmail.com> | 2020-02-25 17:52:01 +0300 |
---|---|---|
committer | Charlie Jolly <mistajolly@gmail.com> | 2020-03-02 15:49:19 +0300 |
commit | 847c091ae838a0e5268fc327dac931c810d88d9b (patch) | |
tree | 0284badd5653d67447fc692bd61230bfc9def8b6 /intern | |
parent | 493c99078a8fbd8807f137401c11d401b85ba0e7 (diff) |
Shading: Add invert option to Vector Rotate Node
Checkbox to invert rotation angle, suggested by @simonthommes
Differential Revision: https://developer.blender.org/D6932
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_vector_rotate.osl | 34 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_vector_rotate.h | 71 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 19 | ||||
-rw-r--r-- | intern/cycles/render/nodes.h | 1 |
5 files changed, 71 insertions, 55 deletions
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 6709e90c3d3..732c4b0da96 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -327,6 +327,7 @@ static ShaderNode *add_node(Scene *scene, BL::ShaderNodeVectorRotate b_vector_rotate_node(b_node); VectorRotateNode *vector_rotate_node = new VectorRotateNode(); vector_rotate_node->type = (NodeVectorRotateType)b_vector_rotate_node.rotation_type(); + vector_rotate_node->invert = b_vector_rotate_node.invert(); node = vector_rotate_node; } else if (b_node.is_a(&RNA_ShaderNodeVectorTransform)) { diff --git a/intern/cycles/kernel/shaders/node_vector_rotate.osl b/intern/cycles/kernel/shaders/node_vector_rotate.osl index 533aa7bbe13..d32733b0966 100644 --- a/intern/cycles/kernel/shaders/node_vector_rotate.osl +++ b/intern/cycles/kernel/shaders/node_vector_rotate.osl @@ -17,7 +17,8 @@ #include "stdcycles.h" #include "node_math.h" -shader node_vector_rotate(string type = "axis", +shader node_vector_rotate(int invert = 0, + string type = "axis", vector VectorIn = vector(0.0, 0.0, 0.0), point Center = point(0.0, 0.0, 0.0), point Rotation = point(0.0, 0.0, 0.0), @@ -26,20 +27,23 @@ shader node_vector_rotate(string type = "axis", output vector VectorOut = vector(0.0, 0.0, 0.0)) { if (type == "euler_xyz") { - VectorOut = transform(euler_to_mat(Rotation), VectorIn - Center) + Center; + matrix rmat = (invert) ? transpose(euler_to_mat(Rotation)) : euler_to_mat(Rotation); + VectorOut = transform(rmat, VectorIn - Center) + Center; } - else if (type == "x_axis") { - VectorOut = rotate(VectorIn - Center, Angle, point(0.0), vector(1.0, 0.0, 0.0)) + Center; - } - else if (type == "y_axis") { - VectorOut = rotate(VectorIn - Center, Angle, point(0.0), vector(0.0, 1.0, 0.0)) + Center; - } - else if (type == "z_axis") { - VectorOut = rotate(VectorIn - Center, Angle, point(0.0), vector(0.0, 0.0, 1.0)) + Center; - } - else { // axis - VectorOut = (length(Axis) != 0.0) ? - rotate(VectorIn - Center, Angle, point(0.0), Axis) + Center : - VectorIn; + else { + float a = (invert) ? -Angle : Angle; + if (type == "x_axis") { + VectorOut = rotate(VectorIn - Center, a, point(0.0), vector(1.0, 0.0, 0.0)) + Center; + } + else if (type == "y_axis") { + VectorOut = rotate(VectorIn - Center, a, point(0.0), vector(0.0, 1.0, 0.0)) + Center; + } + else if (type == "z_axis") { + VectorOut = rotate(VectorIn - Center, a, point(0.0), vector(0.0, 0.0, 1.0)) + Center; + } + else { // axis + VectorOut = (length(Axis) != 0.0) ? rotate(VectorIn - Center, a, point(0.0), Axis) + Center : + VectorIn; + } } } diff --git a/intern/cycles/kernel/svm/svm_vector_rotate.h b/intern/cycles/kernel/svm/svm_vector_rotate.h index 0dc0e223f41..79a4ec2c40e 100644 --- a/intern/cycles/kernel/svm/svm_vector_rotate.h +++ b/intern/cycles/kernel/svm/svm_vector_rotate.h @@ -25,45 +25,52 @@ ccl_device void svm_node_vector_rotate(ShaderData *sd, uint result_stack_offset) { uint type, vector_stack_offset, rotation_stack_offset, center_stack_offset, axis_stack_offset, - angle_stack_offset; + angle_stack_offset, invert; - svm_unpack_node_uchar3(input_stack_offsets, &type, &vector_stack_offset, &rotation_stack_offset); + svm_unpack_node_uchar4( + input_stack_offsets, &type, &vector_stack_offset, &rotation_stack_offset, &invert); svm_unpack_node_uchar3( axis_stack_offsets, ¢er_stack_offset, &axis_stack_offset, &angle_stack_offset); - float3 vector = stack_load_float3(stack, vector_stack_offset); - float3 center = stack_load_float3(stack, center_stack_offset); - float3 result = make_float3(0.0f, 0.0f, 0.0f); + if (stack_valid(result_stack_offset)) { - if (type == NODE_VECTOR_ROTATE_TYPE_EULER_XYZ) { - float3 rotation = stack_load_float3(stack, rotation_stack_offset); // Default XYZ. - Transform rotationTransform = euler_to_transform(rotation); - result = transform_direction(&rotationTransform, vector - center) + center; - } - else { - float3 axis; - switch (type) { - case NODE_VECTOR_ROTATE_TYPE_AXIS_X: - axis = make_float3(1.0f, 0.0f, 0.0f); - break; - case NODE_VECTOR_ROTATE_TYPE_AXIS_Y: - axis = make_float3(0.0f, 1.0f, 0.0f); - break; - case NODE_VECTOR_ROTATE_TYPE_AXIS_Z: - axis = make_float3(0.0f, 0.0f, 1.0f); - break; - default: - axis = normalize(stack_load_float3(stack, axis_stack_offset)); - break; + float3 vector = stack_load_float3(stack, vector_stack_offset); + float3 center = stack_load_float3(stack, center_stack_offset); + float3 result = make_float3(0.0f, 0.0f, 0.0f); + + if (type == NODE_VECTOR_ROTATE_TYPE_EULER_XYZ) { + float3 rotation = stack_load_float3(stack, rotation_stack_offset); // Default XYZ. + Transform rotationTransform = euler_to_transform(rotation); + if (invert) { + result = transform_direction_transposed(&rotationTransform, vector - center) + center; + } + else { + result = transform_direction(&rotationTransform, vector - center) + center; + } + } + else { + float3 axis; + switch (type) { + case NODE_VECTOR_ROTATE_TYPE_AXIS_X: + axis = make_float3(1.0f, 0.0f, 0.0f); + break; + case NODE_VECTOR_ROTATE_TYPE_AXIS_Y: + axis = make_float3(0.0f, 1.0f, 0.0f); + break; + case NODE_VECTOR_ROTATE_TYPE_AXIS_Z: + axis = make_float3(0.0f, 0.0f, 1.0f); + break; + default: + axis = normalize(stack_load_float3(stack, axis_stack_offset)); + break; + } + float angle = stack_load_float(stack, angle_stack_offset); + angle = invert ? -angle : angle; + result = (len_squared(axis) != 0.0f) ? + rotate_around_axis(vector - center, axis, angle) + center : + vector; } - float angle = stack_load_float(stack, angle_stack_offset); - result = (len_squared(axis) != 0.0f) ? - rotate_around_axis(vector - center, axis, angle) + center : - vector; - } - /* Output */ - if (stack_valid(result_stack_offset)) { stack_store_float3(stack, result_stack_offset, result); } } diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 4ff03d28330..a52b7f0ea00 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -6157,6 +6157,8 @@ NODE_DEFINE(VectorRotateNode) type_enum.insert("euler_xyz", NODE_VECTOR_ROTATE_TYPE_EULER_XYZ); SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_ROTATE_TYPE_AXIS); + SOCKET_BOOLEAN(invert, "Invert", false); + SOCKET_IN_VECTOR(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f)); SOCKET_IN_POINT(rotation, "Rotation", make_float3(0.0f, 0.0f, 0.0f)); SOCKET_IN_POINT(center, "Center", make_float3(0.0f, 0.0f, 0.0f)); @@ -6180,19 +6182,20 @@ void VectorRotateNode::compile(SVMCompiler &compiler) ShaderInput *angle_in = input("Angle"); ShaderOutput *vector_out = output("Vector"); - compiler.add_node(NODE_VECTOR_ROTATE, - compiler.encode_uchar4(type, - compiler.stack_assign(vector_in), - compiler.stack_assign(rotation_in)), - compiler.encode_uchar4(compiler.stack_assign(center_in), - compiler.stack_assign(axis_in), - compiler.stack_assign(angle_in)), - compiler.stack_assign(vector_out)); + compiler.add_node( + NODE_VECTOR_ROTATE, + compiler.encode_uchar4( + type, compiler.stack_assign(vector_in), compiler.stack_assign(rotation_in), invert), + compiler.encode_uchar4(compiler.stack_assign(center_in), + compiler.stack_assign(axis_in), + compiler.stack_assign(angle_in)), + compiler.stack_assign(vector_out)); } void VectorRotateNode::compile(OSLCompiler &compiler) { compiler.parameter(this, "type"); + compiler.parameter(this, "invert"); compiler.add(this, "node_vector_rotate"); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 38b6b7554c0..1d76cb5e828 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -1400,6 +1400,7 @@ class VectorRotateNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } NodeVectorRotateType type; + bool invert; float3 vector; float3 center; float3 axis; |