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
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
70
intern/cycles/kernel/shaders/node_vector_rotate.osl
Normal file
70
intern/cycles/kernel/shaders/node_vector_rotate.osl
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
87
intern/cycles/kernel/svm/svm_vector_rotate.h
Normal file
87
intern/cycles/kernel/svm/svm_vector_rotate.h
Normal file
@@ -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, ¢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 (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
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -264,6 +264,7 @@ shader_node_categories = [
|
||||
NodeItem("ShaderNodeNormalMap"),
|
||||
NodeItem("ShaderNodeNormal"),
|
||||
NodeItem("ShaderNodeVectorCurve"),
|
||||
NodeItem("ShaderNodeVectorRotate"),
|
||||
NodeItem("ShaderNodeVectorTransform"),
|
||||
]),
|
||||
ShaderNodeCategory("SH_NEW_CONVERTOR", "Converter", items=[
|
||||
|
||||
@@ -994,6 +994,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree,
|
||||
#define SH_NODE_VOLUME_INFO 705
|
||||
#define SH_NODE_VERTEX_COLOR 706
|
||||
#define SH_NODE_OUTPUT_AOV 707
|
||||
#define SH_NODE_VECTOR_ROTATE 708
|
||||
|
||||
/* custom defines options for Material node */
|
||||
// #define SH_NODE_MAT_DIFF 1
|
||||
|
||||
@@ -3975,6 +3975,7 @@ static void registerShaderNodes(void)
|
||||
register_node_type_sh_clamp();
|
||||
register_node_type_sh_math();
|
||||
register_node_type_sh_vect_math();
|
||||
register_node_type_sh_vector_rotate();
|
||||
register_node_type_sh_vect_transform();
|
||||
register_node_type_sh_squeeze();
|
||||
register_node_type_sh_invert();
|
||||
|
||||
@@ -745,6 +745,11 @@ static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), Poin
|
||||
uiItemR(layout, ptr, "vector_type", 0, NULL, ICON_NONE);
|
||||
}
|
||||
|
||||
static void node_shader_buts_vector_rotate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||
{
|
||||
uiItemR(layout, ptr, "rotation_type", 0, NULL, ICON_NONE);
|
||||
}
|
||||
|
||||
static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||
{
|
||||
uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
|
||||
@@ -1207,6 +1212,9 @@ static void node_shader_set_butfunc(bNodeType *ntype)
|
||||
case SH_NODE_VECTOR_MATH:
|
||||
ntype->draw_buttons = node_shader_buts_vect_math;
|
||||
break;
|
||||
case SH_NODE_VECTOR_ROTATE:
|
||||
ntype->draw_buttons = node_shader_buts_vector_rotate;
|
||||
break;
|
||||
case SH_NODE_VECT_TRANSFORM:
|
||||
ntype->draw_buttons = node_shader_buts_vect_transform;
|
||||
break;
|
||||
|
||||
@@ -303,6 +303,7 @@ data_to_c_simple(shaders/material/gpu_shader_material_uv_map.glsl SRC)
|
||||
data_to_c_simple(shaders/material/gpu_shader_material_vector_curves.glsl SRC)
|
||||
data_to_c_simple(shaders/material/gpu_shader_material_vector_displacement.glsl SRC)
|
||||
data_to_c_simple(shaders/material/gpu_shader_material_vector_math.glsl SRC)
|
||||
data_to_c_simple(shaders/material/gpu_shader_material_vector_rotate.glsl SRC)
|
||||
data_to_c_simple(shaders/material/gpu_shader_material_velvet.glsl SRC)
|
||||
data_to_c_simple(shaders/material/gpu_shader_material_vertex_color.glsl SRC)
|
||||
data_to_c_simple(shaders/material/gpu_shader_material_volume_absorption.glsl SRC)
|
||||
|
||||
@@ -119,6 +119,7 @@ extern char datatoc_gpu_shader_material_uv_map_glsl[];
|
||||
extern char datatoc_gpu_shader_material_vector_curves_glsl[];
|
||||
extern char datatoc_gpu_shader_material_vector_displacement_glsl[];
|
||||
extern char datatoc_gpu_shader_material_vector_math_glsl[];
|
||||
extern char datatoc_gpu_shader_material_vector_rotate_glsl[];
|
||||
extern char datatoc_gpu_shader_material_velvet_glsl[];
|
||||
extern char datatoc_gpu_shader_material_vertex_color_glsl[];
|
||||
extern char datatoc_gpu_shader_material_volume_absorption_glsl[];
|
||||
@@ -527,6 +528,11 @@ static GPUMaterialLibrary gpu_shader_material_vector_math_library = {
|
||||
.dependencies = {&gpu_shader_material_math_util_library, NULL},
|
||||
};
|
||||
|
||||
static GPUMaterialLibrary gpu_shader_material_vector_rotate_library = {
|
||||
.code = datatoc_gpu_shader_material_vector_rotate_glsl,
|
||||
.dependencies = {&gpu_shader_material_math_util_library, NULL},
|
||||
};
|
||||
|
||||
static GPUMaterialLibrary gpu_shader_material_velvet_library = {
|
||||
.code = datatoc_gpu_shader_material_velvet_glsl,
|
||||
.dependencies = {&gpu_shader_material_diffuse_library, NULL},
|
||||
@@ -647,6 +653,7 @@ static GPUMaterialLibrary *gpu_material_libraries[] = {
|
||||
&gpu_shader_material_vector_curves_library,
|
||||
&gpu_shader_material_vector_displacement_library,
|
||||
&gpu_shader_material_vector_math_library,
|
||||
&gpu_shader_material_vector_rotate_library,
|
||||
&gpu_shader_material_velvet_library,
|
||||
&gpu_shader_material_vertex_color_library,
|
||||
&gpu_shader_material_volume_absorption_library,
|
||||
@@ -879,4 +886,3 @@ char *gpu_material_library_generate_code(GSet *used_libraries, const char *frag_
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
vec3 rotate_around_axis(vec3 p, vec3 axis, float angle)
|
||||
{
|
||||
float costheta = cos(angle);
|
||||
float sintheta = sin(angle);
|
||||
vec3 r;
|
||||
|
||||
r.x = ((costheta + (1.0 - costheta) * axis.x * axis.x) * p.x) +
|
||||
(((1.0 - costheta) * axis.x * axis.y - axis.z * sintheta) * p.y) +
|
||||
(((1.0 - costheta) * axis.x * axis.z + axis.y * sintheta) * p.z);
|
||||
|
||||
r.y = (((1.0 - costheta) * axis.x * axis.y + axis.z * sintheta) * p.x) +
|
||||
((costheta + (1.0 - costheta) * axis.y * axis.y) * p.y) +
|
||||
(((1.0 - costheta) * axis.y * axis.z - axis.x * sintheta) * p.z);
|
||||
|
||||
r.z = (((1.0 - costheta) * axis.x * axis.z - axis.y * sintheta) * p.x) +
|
||||
(((1.0 - costheta) * axis.y * axis.z + axis.x * sintheta) * p.y) +
|
||||
((costheta + (1.0 - costheta) * axis.z * axis.z) * p.z);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void node_vector_rotate_axis_angle(
|
||||
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
|
||||
{
|
||||
vec = (length(axis) != 0.0) ?
|
||||
rotate_around_axis(vector_in - center, normalize(axis), angle) + center :
|
||||
vector_in;
|
||||
}
|
||||
|
||||
void node_vector_rotate_axis_x(
|
||||
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
|
||||
{
|
||||
vec = rotate_around_axis(vector_in - center, vec3(1.0, 0.0, 0.0), angle) + center;
|
||||
}
|
||||
|
||||
void node_vector_rotate_axis_y(
|
||||
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
|
||||
{
|
||||
vec = rotate_around_axis(vector_in - center, vec3(0.0, 1.0, 0.0), angle) + center;
|
||||
}
|
||||
|
||||
void node_vector_rotate_axis_z(
|
||||
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
|
||||
{
|
||||
vec = rotate_around_axis(vector_in - center, vec3(0.0, 0.0, 1.0), angle) + center;
|
||||
}
|
||||
|
||||
void node_vector_rotate_euler_xyz(
|
||||
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
|
||||
{
|
||||
vec = euler_to_mat3(rotation) * (vector_in - center) + center;
|
||||
}
|
||||
|
||||
void node_vector_rotate_euler_xzy(
|
||||
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
|
||||
{
|
||||
vec = euler_to_mat3(-rotation.xzy) * (vector_in - center) + center;
|
||||
}
|
||||
|
||||
void node_vector_rotate_euler_yxz(
|
||||
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
|
||||
{
|
||||
vec = euler_to_mat3(-rotation.yxz) * (vector_in - center) + center;
|
||||
}
|
||||
|
||||
void node_vector_rotate_euler_yzx(
|
||||
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
|
||||
{
|
||||
vec = euler_to_mat3(rotation.yzx) * (vector_in - center) + center;
|
||||
}
|
||||
|
||||
void node_vector_rotate_euler_zxy(
|
||||
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
|
||||
{
|
||||
vec = euler_to_mat3(rotation.zxy) * (vector_in - center) + center;
|
||||
}
|
||||
|
||||
void node_vector_rotate_euler_zyx(
|
||||
vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
|
||||
{
|
||||
vec = euler_to_mat3(-rotation.zyx) * (vector_in - center) + center;
|
||||
}
|
||||
@@ -1212,6 +1212,20 @@ enum {
|
||||
NODE_MAPPING_TYPE_NORMAL = 3,
|
||||
};
|
||||
|
||||
/* Rotation node vector types */
|
||||
enum {
|
||||
NODE_VECTOR_ROTATE_TYPE_AXIS = 0,
|
||||
NODE_VECTOR_ROTATE_TYPE_AXIS_X = 1,
|
||||
NODE_VECTOR_ROTATE_TYPE_AXIS_Y = 2,
|
||||
NODE_VECTOR_ROTATE_TYPE_AXIS_Z = 3,
|
||||
NODE_VECTOR_ROTATE_TYPE_EULER_XYZ = 4,
|
||||
NODE_VECTOR_ROTATE_TYPE_EULER_XZY = 5,
|
||||
NODE_VECTOR_ROTATE_TYPE_EULER_YXZ = 6,
|
||||
NODE_VECTOR_ROTATE_TYPE_EULER_YZX = 7,
|
||||
NODE_VECTOR_ROTATE_TYPE_EULER_ZXY = 8,
|
||||
NODE_VECTOR_ROTATE_TYPE_EULER_ZYX = 9,
|
||||
};
|
||||
|
||||
/* math node clamp */
|
||||
#define SHD_MATH_CLAMP 1
|
||||
|
||||
|
||||
@@ -122,6 +122,49 @@ const EnumPropertyItem rna_enum_mapping_type_items[] = {
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
const EnumPropertyItem rna_enum_vector_rotate_type_items[] = {
|
||||
{NODE_VECTOR_ROTATE_TYPE_AXIS,
|
||||
"AXIS_ANGLE",
|
||||
0,
|
||||
"Axis Angle",
|
||||
"Rotate a point using axis angle"},
|
||||
{NODE_VECTOR_ROTATE_TYPE_AXIS_X, "X_AXIS", 0, "X Axis", "Rotate a point using X axis"},
|
||||
{NODE_VECTOR_ROTATE_TYPE_AXIS_Y, "Y_AXIS", 0, "Y Axis", "Rotate a point using Y axis"},
|
||||
{NODE_VECTOR_ROTATE_TYPE_AXIS_Z, "Z_AXIS", 0, "Z Axis", "Rotate a point using Z axis"},
|
||||
{NODE_VECTOR_ROTATE_TYPE_EULER_XYZ,
|
||||
"EULER_XYZ",
|
||||
0,
|
||||
"XYZ Euler",
|
||||
"Rotate a point using XYZ order"},
|
||||
|
||||
{NODE_VECTOR_ROTATE_TYPE_EULER_XZY,
|
||||
"EULER_XZY",
|
||||
0,
|
||||
"XZY Euler",
|
||||
"Rotate a point using XZY order"},
|
||||
{NODE_VECTOR_ROTATE_TYPE_EULER_YXZ,
|
||||
"EULER_YXZ",
|
||||
0,
|
||||
"YXZ Euler",
|
||||
"Rotate a point using YXZ order"},
|
||||
{NODE_VECTOR_ROTATE_TYPE_EULER_YZX,
|
||||
"EULER_YZX",
|
||||
0,
|
||||
"YZX Euler",
|
||||
"Rotate a point using YZX order"},
|
||||
{NODE_VECTOR_ROTATE_TYPE_EULER_ZXY,
|
||||
"EULER_ZXY",
|
||||
0,
|
||||
"ZXY Euler",
|
||||
"Rotate a point using ZXY order"},
|
||||
{NODE_VECTOR_ROTATE_TYPE_EULER_ZYX,
|
||||
"EULER_ZYX",
|
||||
0,
|
||||
"XZY Euler",
|
||||
"Rotate a point using ZYX order"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
const EnumPropertyItem rna_enum_node_math_items[] = {
|
||||
{0, "", 0, N_("Functions"), ""},
|
||||
{NODE_MATH_ADD, "ADD", 0, "Add", "A + B"},
|
||||
@@ -4141,6 +4184,17 @@ static void def_sh_mapping(StructRNA *srna)
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update");
|
||||
}
|
||||
|
||||
static void def_sh_vector_rotate(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
prop = RNA_def_property(srna, "rotation_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "custom1");
|
||||
RNA_def_property_enum_items(prop, rna_enum_vector_rotate_type_items);
|
||||
RNA_def_property_ui_text(prop, "Type", "Type of rotation");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update");
|
||||
}
|
||||
|
||||
static void def_sh_attribute(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
@@ -206,6 +206,7 @@ set(SRC
|
||||
shader/nodes/node_shader_uvmap.c
|
||||
shader/nodes/node_shader_valToRgb.c
|
||||
shader/nodes/node_shader_value.c
|
||||
shader/nodes/node_shader_vector_rotate.c
|
||||
shader/nodes/node_shader_vectTransform.c
|
||||
shader/nodes/node_shader_vector_displacement.c
|
||||
shader/nodes/node_shader_vector_math.c
|
||||
|
||||
@@ -85,6 +85,7 @@ void register_node_type_sh_volume_info(void);
|
||||
void register_node_type_sh_script(void);
|
||||
void register_node_type_sh_normal_map(void);
|
||||
void register_node_type_sh_tangent(void);
|
||||
void register_node_type_sh_vector_rotate(void);
|
||||
void register_node_type_sh_vect_transform(void);
|
||||
void register_node_type_sh_vertex_color(void);
|
||||
|
||||
|
||||
@@ -117,6 +117,7 @@ DefNode(ShaderNode, SH_NODE_TEX_CHECKER, def_sh_tex_checker, "TEX
|
||||
DefNode(ShaderNode, SH_NODE_TEX_BRICK, def_sh_tex_brick, "TEX_BRICK", TexBrick, "Brick Texture", "" )
|
||||
DefNode(ShaderNode, SH_NODE_TEX_POINTDENSITY, def_sh_tex_pointdensity,"TEX_POINTDENSITY", TexPointDensity, "Point Density", "" )
|
||||
DefNode(ShaderNode, SH_NODE_TEX_COORD, def_sh_tex_coord, "TEX_COORD", TexCoord, "Texture Coordinate","" )
|
||||
DefNode(ShaderNode, SH_NODE_VECTOR_ROTATE, def_sh_vector_rotate, "VECTOR_ROTATE", VectorRotate, "Vector Rotate", "" )
|
||||
DefNode(ShaderNode, SH_NODE_VECT_TRANSFORM, def_sh_vect_transform, "VECT_TRANSFORM", VectorTransform, "Vector Transform", "" )
|
||||
DefNode(ShaderNode, SH_NODE_SEPHSV, 0, "SEPHSV", SeparateHSV, "Separate HSV", "" )
|
||||
DefNode(ShaderNode, SH_NODE_COMBHSV, 0, "COMBHSV", CombineHSV, "Combine HSV", "" )
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup shdnodes
|
||||
*/
|
||||
|
||||
#include "../node_shader_util.h"
|
||||
|
||||
/* **************** Vector Rotate ******************** */
|
||||
static bNodeSocketTemplate sh_node_vector_rotate_in[] = {
|
||||
{SOCK_VECTOR, 1, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
|
||||
{SOCK_VECTOR, 1, N_("Center"), 0.0f, 0.0f, 0.0f, 1.0f, -FLT_MAX, FLT_MAX, PROP_NONE},
|
||||
{SOCK_VECTOR, 1, N_("Axis"), 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f, PROP_NONE, PROP_NONE},
|
||||
{SOCK_FLOAT, 1, N_("Angle"), 0.0f, 0.0f, 0.0f, 1.0f, -FLT_MAX, FLT_MAX, PROP_ANGLE, PROP_NONE},
|
||||
{SOCK_VECTOR, 1, N_("Rotation"), 0.0f, 0.0f, 0.0f, 1.0f, -FLT_MAX, FLT_MAX, PROP_EULER},
|
||||
{-1, 0, ""}};
|
||||
|
||||
static bNodeSocketTemplate sh_node_vector_rotate_out[] = {{SOCK_VECTOR, 0, N_("Vector")},
|
||||
{-1, 0, ""}};
|
||||
|
||||
static int gpu_shader_vector_rotate(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData *UNUSED(execdata),
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
|
||||
static const char *names[] = {
|
||||
[NODE_VECTOR_ROTATE_TYPE_AXIS] = "node_vector_rotate_axis_angle",
|
||||
[NODE_VECTOR_ROTATE_TYPE_AXIS_X] = "node_vector_rotate_axis_x",
|
||||
[NODE_VECTOR_ROTATE_TYPE_AXIS_Y] = "node_vector_rotate_axis_y",
|
||||
[NODE_VECTOR_ROTATE_TYPE_AXIS_Z] = "node_vector_rotate_axis_z",
|
||||
[NODE_VECTOR_ROTATE_TYPE_EULER_XYZ] = "node_vector_rotate_euler_xyz",
|
||||
[NODE_VECTOR_ROTATE_TYPE_EULER_XZY] = "node_vector_rotate_euler_xzy",
|
||||
[NODE_VECTOR_ROTATE_TYPE_EULER_YXZ] = "node_vector_rotate_euler_yxz",
|
||||
[NODE_VECTOR_ROTATE_TYPE_EULER_YZX] = "node_vector_rotate_euler_yzx",
|
||||
[NODE_VECTOR_ROTATE_TYPE_EULER_ZXY] = "node_vector_rotate_euler_zxy",
|
||||
[NODE_VECTOR_ROTATE_TYPE_EULER_ZYX] = "node_vector_rotate_euler_zyx",
|
||||
};
|
||||
|
||||
if (node->custom1 < ARRAY_SIZE(names) && names[node->custom1]) {
|
||||
return GPU_stack_link(mat, node, names[node->custom1], in, out);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void node_shader_update_vector_rotate(bNodeTree *UNUSED(ntree), bNode *node)
|
||||
{
|
||||
bNodeSocket *sock_rotation = nodeFindSocket(node, SOCK_IN, "Rotation");
|
||||
nodeSetSocketAvailability(sock_rotation,
|
||||
!ELEM(node->custom1,
|
||||
NODE_VECTOR_ROTATE_TYPE_AXIS,
|
||||
NODE_VECTOR_ROTATE_TYPE_AXIS_X,
|
||||
NODE_VECTOR_ROTATE_TYPE_AXIS_Y,
|
||||
NODE_VECTOR_ROTATE_TYPE_AXIS_Z));
|
||||
bNodeSocket *sock_axis = nodeFindSocket(node, SOCK_IN, "Axis");
|
||||
nodeSetSocketAvailability(sock_axis, ELEM(node->custom1, NODE_VECTOR_ROTATE_TYPE_AXIS));
|
||||
bNodeSocket *sock_angle = nodeFindSocket(node, SOCK_IN, "Angle");
|
||||
nodeSetSocketAvailability(sock_angle,
|
||||
ELEM(node->custom1,
|
||||
NODE_VECTOR_ROTATE_TYPE_AXIS,
|
||||
NODE_VECTOR_ROTATE_TYPE_AXIS_X,
|
||||
NODE_VECTOR_ROTATE_TYPE_AXIS_Y,
|
||||
NODE_VECTOR_ROTATE_TYPE_AXIS_Z));
|
||||
}
|
||||
|
||||
void register_node_type_sh_vector_rotate(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
sh_node_type_base(&ntype, SH_NODE_VECTOR_ROTATE, "Vector Rotate", NODE_CLASS_OP_VECTOR, 0);
|
||||
node_type_socket_templates(&ntype, sh_node_vector_rotate_in, sh_node_vector_rotate_out);
|
||||
node_type_gpu(&ntype, gpu_shader_vector_rotate);
|
||||
node_type_update(&ntype, node_shader_update_vector_rotate);
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
Reference in New Issue
Block a user