Blender V5.0
node_shader_vector_transform.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2013 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "node_shader_util.hh"
10#include "node_util.hh"
11
13#include "UI_resources.hh"
14
16
18{
19 b.add_input<decl::Vector>("Vector")
20 .default_value({0.5f, 0.5f, 0.5f})
21 .min(-10000.0f)
22 .max(10000.0f)
23 .description("Vector, point, or normal which will be used for conversion between spaces");
24 b.add_output<decl::Vector>("Vector");
25}
26
28{
29 layout->prop(
30 ptr, "vector_type", UI_ITEM_R_SPLIT_EMPTY_NAME | UI_ITEM_R_EXPAND, std::nullopt, ICON_NONE);
31 layout->prop(ptr, "convert_from", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
32 layout->prop(ptr, "convert_to", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
33}
34
35static void node_shader_init_vect_transform(bNodeTree * /*ntree*/, bNode *node)
36{
37 NodeShaderVectTransform *vect = MEM_callocN<NodeShaderVectTransform>("NodeShaderVectTransform");
38
39 /* Convert World into Object Space per default */
40 vect->convert_to = 1;
41
42 node->storage = vect;
43}
44
45static const char *get_gpufn_name_from_to(short from, short to, bool is_direction)
46{
47 switch (from) {
49 switch (to) {
51 return nullptr;
53 return is_direction ? "direction_transform_object_to_world" :
54 "point_transform_object_to_world";
56 return is_direction ? "direction_transform_object_to_view" :
57 "point_transform_object_to_view";
58 }
59 break;
61 switch (to) {
63 return nullptr;
65 return is_direction ? "direction_transform_world_to_view" :
66 "point_transform_world_to_view";
68 return is_direction ? "direction_transform_world_to_object" :
69 "point_transform_world_to_object";
70 }
71 break;
73 switch (to) {
75 return nullptr;
77 return is_direction ? "direction_transform_view_to_world" :
78 "point_transform_view_to_world";
80 return is_direction ? "direction_transform_view_to_object" :
81 "point_transform_view_to_object";
82 }
83 break;
84 }
85 return nullptr;
86}
87
89 bNode *node,
90 bNodeExecData * /*execdata*/,
93{
94 GPUNodeLink *inputlink;
95
97
98 if (in[0].hasinput) {
99 inputlink = in[0].link;
100 }
101 else {
102 inputlink = GPU_uniform(in[0].vec);
103 }
104
105 const bool is_direction = (nodeprop->type != SHD_VECT_TRANSFORM_TYPE_POINT);
106 const char *func_name = get_gpufn_name_from_to(
107 nodeprop->convert_from, nodeprop->convert_to, is_direction);
108
109 if (func_name) {
110 /* For cycles we have inverted Z */
111 /* TODO: pass here the correct matrices */
114 {
115 GPU_link(mat, "invert_z", inputlink, &inputlink);
116 }
117
118 GPU_link(mat, func_name, inputlink, &out[0].link);
119
122 {
123 GPU_link(mat, "invert_z", out[0].link, &out[0].link);
124 }
125 }
126 else {
127 GPU_link(mat, "set_rgb", inputlink, &out[0].link);
128 }
129
130 if (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_NORMAL) {
131 GPU_link(mat, "vector_normalize", out[0].link, &out[0].link);
132 }
133
134 return true;
135}
136
138#ifdef WITH_MATERIALX
139{
140 NodeItem res = empty();
141 NodeShaderVectTransform *nodeprop = (NodeShaderVectTransform *)node_->storage;
142 std::string fromspace;
143 std::string tospace;
144 std::string category;
145 NodeItem vector = get_input_value("Vector", NodeItem::Type::Vector3);
146
147 switch (nodeprop->convert_from) {
149 fromspace = "world";
150 break;
152 fromspace = "object";
153 break;
154 default:
155 /* NOTE: SHD_VECT_TRANSFORM_SPACE_CAMERA don't have an implementation in MaterialX. */
157 return vector;
158 }
159
160 switch (nodeprop->convert_to) {
162 tospace = "world";
163 break;
165 tospace = "object";
166 break;
167 default:
168 /* NOTE: SHD_VECT_TRANSFORM_SPACE_CAMERA don't have an implementation in MaterialX. */
170 return vector;
171 }
172
173 if (fromspace == tospace) {
174 return vector;
175 }
176
177 switch (nodeprop->type) {
179 category = "transformpoint";
180 break;
182 category = "transformnormal";
183 break;
185 category = "transformvector";
186 break;
187 default:
189 return vector;
190 }
191
192 return create_node(category,
193 NodeItem::Type::Vector3,
194 {{"in", vector}, {"fromspace", val(fromspace)}, {"tospace", val(tospace)}});
195}
196#endif
198
199} // namespace blender::nodes::node_shader_vector_transform_cc
200
202{
204
205 static blender::bke::bNodeType ntype;
206
207 sh_node_type_base(&ntype, "ShaderNodeVectorTransform", SH_NODE_VECT_TRANSFORM);
208 ntype.ui_name = "Vector Transform";
209 ntype.ui_description =
210 "Convert a vector, point, or normal between world, camera, and object coordinate space";
211 ntype.enum_name_legacy = "VECT_TRANSFORM";
213 ntype.declare = file_ns::node_declare;
214 ntype.draw_buttons = file_ns::node_shader_buts_vect_transform;
215 ntype.initfunc = file_ns::node_shader_init_vect_transform;
217 ntype, "NodeShaderVectTransform", node_free_standard_storage, node_copy_standard_storage);
218 ntype.gpu_fn = file_ns::gpu_shader_vect_transform;
219 ntype.materialx_fn = file_ns::node_shader_materialx;
220
222}
#define NODE_CLASS_OP_VECTOR
Definition BKE_node.hh:450
#define SH_NODE_VECT_TRANSFORM
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
@ SHD_VECT_TRANSFORM_TYPE_VECTOR
@ SHD_VECT_TRANSFORM_TYPE_NORMAL
@ SHD_VECT_TRANSFORM_TYPE_POINT
@ SHD_VECT_TRANSFORM_SPACE_WORLD
@ SHD_VECT_TRANSFORM_SPACE_OBJECT
@ SHD_VECT_TRANSFORM_SPACE_CAMERA
bool GPU_link(GPUMaterial *mat, const char *name,...)
GPUNodeLink * GPU_uniform(const float *num)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
@ UI_ITEM_R_EXPAND
#define in
#define out
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
void node_type_storage(bNodeType &ntype, std::optional< StringRefNull > storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
Definition node.cc:5414
static int gpu_shader_vect_transform(GPUMaterial *mat, bNode *node, bNodeExecData *, GPUNodeStack *in, GPUNodeStack *out)
static void node_shader_buts_vect_transform(uiLayout *layout, bContext *, PointerRNA *ptr)
static const char * get_gpufn_name_from_to(short from, short to, bool is_direction)
static void node_shader_init_vect_transform(bNodeTree *, bNode *node)
std::vector< ElementType, Eigen::aligned_allocator< ElementType > > vector
#define NODE_SHADER_MATERIALX_BEGIN
#define NODE_SHADER_MATERIALX_END
void sh_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
void register_node_type_sh_vect_transform()
void node_free_standard_storage(bNode *node)
Definition node_util.cc:42
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
Definition node_util.cc:54
#define min(a, b)
Definition sort.cc:36
void * storage
Defines a node type.
Definition BKE_node.hh:238
NodeMaterialXFunction materialx_fn
Definition BKE_node.hh:344
std::string ui_description
Definition BKE_node.hh:244
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:289
NodeGPUExecFunction gpu_fn
Definition BKE_node.hh:342
const char * enum_name_legacy
Definition BKE_node.hh:247
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:259
NodeDeclareFunction declare
Definition BKE_node.hh:362
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
PointerRNA * ptr
Definition wm_files.cc:4238