diff options
author | Alexander Romanov <a.romanov@blend4web.com> | 2016-01-23 15:27:36 +0300 |
---|---|---|
committer | Alexander Romanov <a.romanov@blend4web.com> | 2016-01-23 15:39:31 +0300 |
commit | a6aaaad9795e80af05e8281030107c32c6a1366b (patch) | |
tree | 187e682a49789f2ccfa459d905e4cee741b884d4 /source/blender/nodes | |
parent | e9452f909cdba368f54637cd0b15ff14d1c60cf3 (diff) |
Vector Transform node support for GLSL mode and the internal renderer
The Vector Transform node is a useful node which is present in the Cycles renderer.
{F144283}
This patch implements the Vector Transform node for GLSL mode and the internal renderer.
Example: {F273060}
Alexander (Blend4Web Team)
Reviewers: brecht, campbellbarton, sergey
Reviewed By: campbellbarton, sergey
Subscribers: psy-fi, duarteframos, RobM, lightbwk, sergey, AlexKowel, valentin_b4w, Evgeny_Rodygin, yurikovelenov
Projects: #bf_blender:_next
Differential Revision: https://developer.blender.org/D909
Diffstat (limited to 'source/blender/nodes')
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_vectTransform.c | 133 |
1 files changed, 132 insertions, 1 deletions
diff --git a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c index 4cab9d3ca97..5b6d213703a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c +++ b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c @@ -52,15 +52,146 @@ static void node_shader_init_vect_transform(bNodeTree *UNUSED(ntree), bNode *nod node->storage = vect; } +static const float (* const get_matrix_from_to(ShaderCallData *scd, short from, short to))[4] +{ + switch (from) { + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + switch (to) { + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + return NULL; + case SHD_VECT_TRANSFORM_SPACE_WORLD: + return RE_object_instance_get_matrix(scd->shi->obi, RE_OBJECT_INSTANCE_MATRIX_OB); + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + return RE_object_instance_get_matrix(scd->shi->obi, RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEW); + } + break; + case SHD_VECT_TRANSFORM_SPACE_WORLD: + switch (to) { + case SHD_VECT_TRANSFORM_SPACE_WORLD: + return NULL; + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + return RE_render_current_get_matrix(RE_VIEW_MATRIX); + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + return RE_object_instance_get_matrix(scd->shi->obi, RE_OBJECT_INSTANCE_MATRIX_OBINV); + } + break; + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + switch (to) { + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + return NULL; + case SHD_VECT_TRANSFORM_SPACE_WORLD: + return RE_render_current_get_matrix(RE_VIEWINV_MATRIX); + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + return RE_object_instance_get_matrix(scd->shi->obi, RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEWINV); + } + break; + } + return NULL; +} + +static void node_shader_exec_vect_transform(void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) +{ + float vec[4]; + const float (*mat)[4]; + + if (data) { + NodeShaderVectTransform *nodeprop = (NodeShaderVectTransform *)node->storage; + + nodestack_get_vec(vec, SOCK_VECTOR, in[0]); + + if (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_POINT) + vec[3] = 1.0f; + else + vec[3] = 0.0f; + + mat = get_matrix_from_to((ShaderCallData *)data, nodeprop->convert_from, nodeprop->convert_to); + if (mat) { + mul_m4_v4((float(*)[4])mat, vec); + } + + if (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_NORMAL) + normalize_v3(vec); + + copy_v4_v4(out[0]->vec, vec); + } +} + +static GPUNodeLink *get_gpulink_matrix_from_to(short from, short to) +{ + switch (from) { + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + switch (to) { + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + return NULL; + case SHD_VECT_TRANSFORM_SPACE_WORLD: + return GPU_builtin(GPU_OBJECT_MATRIX); + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + return GPU_builtin(GPU_LOC_TO_VIEW_MATRIX); + } + case SHD_VECT_TRANSFORM_SPACE_WORLD: + switch (to) { + case SHD_VECT_TRANSFORM_SPACE_WORLD: + return NULL; + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + return GPU_builtin(GPU_VIEW_MATRIX); + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + return GPU_builtin(GPU_INVERSE_OBJECT_MATRIX); + } + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + switch (to) { + case SHD_VECT_TRANSFORM_SPACE_CAMERA: + return NULL; + case SHD_VECT_TRANSFORM_SPACE_WORLD: + return GPU_builtin(GPU_INVERSE_VIEW_MATRIX); + case SHD_VECT_TRANSFORM_SPACE_OBJECT: + return GPU_builtin(GPU_INVERSE_LOC_TO_VIEW_MATRIX); + } + } + return 0; +} +static int gpu_shader_vect_transform(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) +{ + struct GPUNodeLink *inputlink; + struct GPUNodeLink *fromto; + + int ret = 0; + + const char *vtransform = "direction_transform_m4v3"; + const char *ptransform = "point_transform_m4v3"; + const char *func_name = 0; + + NodeShaderVectTransform *nodeprop = (NodeShaderVectTransform *)node->storage; + + if (in[0].hasinput) + inputlink = in[0].link; + else + inputlink = GPU_uniform(in[0].vec); + + fromto = get_gpulink_matrix_from_to(nodeprop->convert_from, nodeprop->convert_to); + + func_name = (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_POINT) ? ptransform : vtransform; + if (fromto) + ret = GPU_link(mat, func_name, inputlink, fromto, &out[0].link); + else + ret = GPU_link(mat, "set_rgb", inputlink, &out[0].link); + + if (nodeprop->type == SHD_VECT_TRANSFORM_TYPE_NORMAL) + return GPU_link(mat, "vect_normalize", out[0].link, &out[0].link); + + return ret; +} + void register_node_type_sh_vect_transform(void) { static bNodeType ntype; sh_node_type_base(&ntype, SH_NODE_VECT_TRANSFORM, "Vector Transform", NODE_CLASS_CONVERTOR, 0); - node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING); node_type_init(&ntype, node_shader_init_vect_transform); node_type_socket_templates(&ntype, sh_node_vect_transform_in, sh_node_vect_transform_out); node_type_storage(&ntype, "NodeShaderVectTransform", node_free_standard_storage, node_copy_standard_storage); + node_type_exec(&ntype, NULL, NULL, node_shader_exec_vect_transform); + node_type_gpu(&ntype, gpu_shader_vect_transform); nodeRegisterType(&ntype); } |