Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorCharlie Jolly <charlie>2020-02-17 18:15:46 +0300
committerCharlie Jolly <mistajolly@gmail.com>2020-02-17 18:43:18 +0300
commit20a4cdfd700d3722fdcaa3b3952ccea1b0e6ee47 (patch)
tree16eee69e8e1d3bdfb902e05df15b055f7141fd4d /intern
parentab3a6e050c856345d10f8e36155913288559e4dc (diff)
Cycles: Vector Rotate Node using Axis and Angle method
This node provides the ability to rotate a vector around a `center` point using either `Axis Angle` , `Single Axis` or `Euler` methods. Reviewed By: #cycles, brecht Differential Revision: https://developer.blender.org/D3789
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/blender_shader.cpp6
-rw-r--r--intern/cycles/kernel/CMakeLists.txt1
-rw-r--r--intern/cycles/kernel/shaders/CMakeLists.txt1
-rw-r--r--intern/cycles/kernel/shaders/node_math.h21
-rw-r--r--intern/cycles/kernel/shaders/node_vector_rotate.osl70
-rw-r--r--intern/cycles/kernel/svm/svm.h4
-rw-r--r--intern/cycles/kernel/svm/svm_types.h14
-rw-r--r--intern/cycles/kernel/svm/svm_vector_rotate.h87
-rw-r--r--intern/cycles/render/nodes.cpp58
-rw-r--r--intern/cycles/render/nodes.h16
10 files changed, 278 insertions, 0 deletions
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 12009d6160c..5a70126e012 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -323,6 +323,12 @@ static ShaderNode *add_node(Scene *scene,
vector_math_node->type = (NodeVectorMathType)b_vector_math_node.operation();
node = vector_math_node;
}
+ else if (b_node.is_a(&RNA_ShaderNodeVectorRotate)) {
+ 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();
+ node = vector_rotate_node;
+ }
else if (b_node.is_a(&RNA_ShaderNodeVectorTransform)) {
BL::ShaderNodeVectorTransform b_vector_transform_node(b_node);
VectorTransformNode *vtransform = new VectorTransformNode();
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 99172f30b8b..566b6e3d191 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -228,6 +228,7 @@ set(SRC_SVM_HEADERS
svm/svm_fractal_noise.h
svm/svm_types.h
svm/svm_value.h
+ svm/svm_vector_rotate.h
svm/svm_vector_transform.h
svm/svm_voronoi.h
svm/svm_voxel.h
diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt
index 1c9445107ad..958ebe2f04e 100644
--- a/intern/cycles/kernel/shaders/CMakeLists.txt
+++ b/intern/cycles/kernel/shaders/CMakeLists.txt
@@ -78,6 +78,7 @@ set(SRC_OSL
node_value.osl
node_vector_curves.osl
node_vector_math.osl
+ node_vector_rotate.osl
node_vector_transform.osl
node_velvet_bsdf.osl
node_vertex_color.osl
diff --git a/intern/cycles/kernel/shaders/node_math.h b/intern/cycles/kernel/shaders/node_math.h
index 7d8478672af..4b1a6c5bc16 100644
--- a/intern/cycles/kernel/shaders/node_math.h
+++ b/intern/cycles/kernel/shaders/node_math.h
@@ -87,3 +87,24 @@ point wrap(point value, point max, point min)
wrap(value[1], max[1], min[1]),
wrap(value[2], max[2], min[2]));
}
+
+matrix euler_to_mat(point euler)
+{
+ float cx = cos(euler[0]);
+ float cy = cos(euler[1]);
+ float cz = cos(euler[2]);
+ float sx = sin(euler[0]);
+ float sy = sin(euler[1]);
+ float sz = sin(euler[2]);
+ matrix mat = matrix(1.0);
+ mat[0][0] = cy * cz;
+ mat[0][1] = cy * sz;
+ mat[0][2] = -sy;
+ mat[1][0] = sy * sx * cz - cx * sz;
+ mat[1][1] = sy * sx * sz + cx * cz;
+ mat[1][2] = cy * sx;
+ +mat[2][0] = sy * cx * cz + sx * sz;
+ mat[2][1] = sy * cx * sz - sx * cz;
+ mat[2][2] = cy * cx;
+ return mat;
+}
diff --git a/intern/cycles/kernel/shaders/node_vector_rotate.osl b/intern/cycles/kernel/shaders/node_vector_rotate.osl
new file mode 100644
index 00000000000..a049ee92dbc
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_vector_rotate.osl
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2011-2020 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "stdcycles.h"
+#include "node_math.h"
+
+shader node_vector_rotate(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),
+ vector Axis = vector(0.0, 0.0, 1.0),
+ float Angle = 0.0,
+ output vector VectorOut = vector(0.0, 0.0, 0.0))
+{
+ if (type == "euler_xyz") {
+ VectorOut = transform(euler_to_mat(Rotation), VectorIn - Center) + Center;
+ }
+ else if (type == "euler_xzy") {
+ VectorOut = transform(euler_to_mat(point(-Rotation[0], -Rotation[2], -Rotation[1])),
+ VectorIn - Center) +
+ Center;
+ }
+ else if (type == "euler_yxz") {
+ VectorOut = transform(euler_to_mat(point(-Rotation[1], -Rotation[0], -Rotation[2])),
+ VectorIn - Center) +
+ Center;
+ }
+ else if (type == "euler_yzx") {
+ VectorOut = transform(euler_to_mat(point(Rotation[1], Rotation[2], Rotation[0])),
+ VectorIn - Center) +
+ Center;
+ }
+ else if (type == "euler_zxy") {
+ VectorOut = transform(euler_to_mat(point(Rotation[2], Rotation[0], Rotation[1])),
+ VectorIn - Center) +
+ Center;
+ }
+ else if (type == "euler_zyx") {
+ VectorOut = transform(euler_to_mat(point(-Rotation[2], -Rotation[1], -Rotation[0])),
+ 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;
+ }
+}
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index fd2833ee687..88c9dbf5838 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -200,6 +200,7 @@ CCL_NAMESPACE_END
#include "kernel/svm/svm_voronoi.h"
#include "kernel/svm/svm_checker.h"
#include "kernel/svm/svm_brick.h"
+#include "kernel/svm/svm_vector_rotate.h"
#include "kernel/svm/svm_vector_transform.h"
#include "kernel/svm/svm_voxel.h"
#include "kernel/svm/svm_bump.h"
@@ -513,6 +514,9 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg,
case NODE_COMBINE_HSV:
svm_node_combine_hsv(kg, sd, stack, node.y, node.z, node.w, &offset);
break;
+ case NODE_VECTOR_ROTATE:
+ svm_node_vector_rotate(sd, stack, node.y, node.z, node.w);
+ break;
case NODE_VECTOR_TRANSFORM:
svm_node_vector_transform(kg, sd, stack, node);
break;
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 45c299e0acb..cff2b964c51 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -153,6 +153,7 @@ typedef enum ShaderNodeType {
NODE_AOV_START,
NODE_AOV_VALUE,
NODE_AOV_COLOR,
+ NODE_VECTOR_ROTATE,
} ShaderNodeType;
typedef enum NodeAttributeType {
@@ -351,6 +352,19 @@ typedef enum NodeMappingType {
NODE_MAPPING_TYPE_NORMAL
} NodeMappingType;
+typedef enum NodeVectorRotateType {
+ NODE_VECTOR_ROTATE_TYPE_AXIS,
+ NODE_VECTOR_ROTATE_TYPE_AXIS_X,
+ NODE_VECTOR_ROTATE_TYPE_AXIS_Y,
+ NODE_VECTOR_ROTATE_TYPE_AXIS_Z,
+ NODE_VECTOR_ROTATE_TYPE_EULER_XYZ,
+ NODE_VECTOR_ROTATE_TYPE_EULER_XZY,
+ NODE_VECTOR_ROTATE_TYPE_EULER_YXZ,
+ NODE_VECTOR_ROTATE_TYPE_EULER_YZX,
+ NODE_VECTOR_ROTATE_TYPE_EULER_ZXY,
+ NODE_VECTOR_ROTATE_TYPE_EULER_ZYX,
+} NodeVectorRotateType;
+
typedef enum NodeVectorTransformType {
NODE_VECTOR_TRANSFORM_TYPE_VECTOR,
NODE_VECTOR_TRANSFORM_TYPE_POINT,
diff --git a/intern/cycles/kernel/svm/svm_vector_rotate.h b/intern/cycles/kernel/svm/svm_vector_rotate.h
new file mode 100644
index 00000000000..c7923e10c53
--- /dev/null
+++ b/intern/cycles/kernel/svm/svm_vector_rotate.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2011-2020 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+/* Vector Rotate */
+
+ccl_device void svm_node_vector_rotate(ShaderData *sd,
+ float *stack,
+ uint input_stack_offsets,
+ uint axis_stack_offsets,
+ uint result_stack_offset)
+{
+ uint type, vector_stack_offset, rotation_stack_offset, center_stack_offset, axis_stack_offset,
+ angle_stack_offset;
+
+ svm_unpack_node_uchar3(input_stack_offsets, &type, &vector_stack_offset, &rotation_stack_offset);
+ svm_unpack_node_uchar3(
+ axis_stack_offsets, &center_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 (type != NODE_VECTOR_ROTATE_TYPE_AXIS && type != NODE_VECTOR_ROTATE_TYPE_AXIS_X &&
+ type != NODE_VECTOR_ROTATE_TYPE_AXIS_Y && type != NODE_VECTOR_ROTATE_TYPE_AXIS_Z) {
+ float3 rotation = stack_load_float3(stack, rotation_stack_offset); // Default XYZ.
+ switch (type) {
+ case NODE_VECTOR_ROTATE_TYPE_EULER_XZY:
+ rotation = make_float3(-rotation.x, -rotation.z, -rotation.y);
+ break;
+ case NODE_VECTOR_ROTATE_TYPE_EULER_YXZ:
+ rotation = make_float3(-rotation.y, -rotation.x, -rotation.z);
+ break;
+ case NODE_VECTOR_ROTATE_TYPE_EULER_YZX:
+ rotation = make_float3(rotation.y, rotation.z, rotation.x);
+ break;
+ case NODE_VECTOR_ROTATE_TYPE_EULER_ZXY:
+ rotation = make_float3(rotation.z, rotation.x, rotation.y);
+ break;
+ case NODE_VECTOR_ROTATE_TYPE_EULER_ZYX:
+ rotation = make_float3(-rotation.z, -rotation.y, -rotation.x);
+ break;
+ }
+ 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;
+ }
+ float angle = stack_load_float(stack, angle_stack_offset);
+ result = is_zero(axis) ? vector : rotate_around_axis(vector - center, axis, angle) + center;
+ }
+
+ /* Output */
+ if (stack_valid(result_stack_offset)) {
+ stack_store_float3(stack, result_stack_offset, result);
+ }
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 83b973011a1..41b4b05ba19 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -6131,6 +6131,64 @@ void VectorMathNode::compile(OSLCompiler &compiler)
compiler.add(this, "node_vector_math");
}
+/* Vector Rotate */
+
+NODE_DEFINE(VectorRotateNode)
+{
+ NodeType *type = NodeType::add("vector_rotate", create, NodeType::SHADER);
+
+ static NodeEnum type_enum;
+ type_enum.insert("axis", NODE_VECTOR_ROTATE_TYPE_AXIS);
+ type_enum.insert("x_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_X);
+ type_enum.insert("y_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_Y);
+ type_enum.insert("z_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_Z);
+ type_enum.insert("euler_xyz", NODE_VECTOR_ROTATE_TYPE_EULER_XYZ);
+ type_enum.insert("euler_xzy", NODE_VECTOR_ROTATE_TYPE_EULER_XZY);
+ type_enum.insert("euler_yxz", NODE_VECTOR_ROTATE_TYPE_EULER_YXZ);
+ type_enum.insert("euler_yzx", NODE_VECTOR_ROTATE_TYPE_EULER_YZX);
+ type_enum.insert("euler_zxy", NODE_VECTOR_ROTATE_TYPE_EULER_ZXY);
+ type_enum.insert("euler_zyx", NODE_VECTOR_ROTATE_TYPE_EULER_ZYX);
+ SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_ROTATE_TYPE_AXIS);
+
+ 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));
+ SOCKET_IN_VECTOR(axis, "Axis", make_float3(0.0f, 0.0f, 1.0f));
+ SOCKET_IN_FLOAT(angle, "Angle", 0.0f);
+ SOCKET_OUT_VECTOR(vector, "Vector");
+
+ return type;
+}
+
+VectorRotateNode::VectorRotateNode() : ShaderNode(node_type)
+{
+}
+
+void VectorRotateNode::compile(SVMCompiler &compiler)
+{
+ ShaderInput *vector_in = input("Vector");
+ ShaderInput *rotation_in = input("Rotation");
+ ShaderInput *center_in = input("Center");
+ ShaderInput *axis_in = input("Axis");
+ 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));
+}
+
+void VectorRotateNode::compile(OSLCompiler &compiler)
+{
+ compiler.parameter(this, "type");
+ compiler.add(this, "node_vector_rotate");
+}
+
/* VectorTransform */
NODE_DEFINE(VectorTransformNode)
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 8346ac77ae6..3cf1c56feb0 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -1384,6 +1384,22 @@ class VectorMathNode : public ShaderNode {
NodeVectorMathType type;
};
+class VectorRotateNode : public ShaderNode {
+ public:
+ SHADER_NODE_CLASS(VectorRotateNode)
+
+ virtual int get_group()
+ {
+ return NODE_GROUP_LEVEL_3;
+ }
+ NodeVectorRotateType type;
+ float3 vector;
+ float3 center;
+ float3 axis;
+ float angle;
+ float3 rotation;
+};
+
class VectorTransformNode : public ShaderNode {
public:
SHADER_NODE_CLASS(VectorTransformNode)