Vector Transform node support for GLSL mode and the internal renderer
authorAlexander Romanov <a.romanov@blend4web.com>
Sat, 23 Jan 2016 12:27:36 +0000 (15:27 +0300)
committerAlexander Romanov <a.romanov@blend4web.com>
Sat, 23 Jan 2016 12:39:31 +0000 (15:39 +0300)
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

17 files changed:
release/scripts/startup/nodeitems_builtins.py
source/blender/editors/render/render_internal.c
source/blender/gpu/GPU_material.h
source/blender/gpu/intern/gpu_codegen.c
source/blender/gpu/intern/gpu_draw.c
source/blender/gpu/intern/gpu_material.c
source/blender/gpu/shaders/gpu_shader_material.glsl
source/blender/nodes/shader/nodes/node_shader_vectTransform.c
source/blender/python/intern/gpu.c
source/blender/render/extern/include/RE_pipeline.h
source/blender/render/extern/include/RE_shader_ext.h
source/blender/render/intern/include/render_types.h
source/blender/render/intern/include/renderdatabase.h
source/blender/render/intern/source/renderdatabase.c
source/blender/render/intern/source/shadeoutput.c
source/blenderplayer/bad_level_call_stubs/stubs.c
source/gameengine/Ketsji/BL_BlenderShader.cpp

index c3def14787dbbd0bafebb9415366c83650e8f90c..7af10aab6482f1f81c48a997e0d30868f29182b5 100644 (file)
@@ -159,6 +159,7 @@ shader_node_categories = [
         NodeItem("ShaderNodeNormal"),
         NodeItem("ShaderNodeMapping"),
         NodeItem("ShaderNodeVectorCurve"),
+        NodeItem("ShaderNodeVectorTransform"),
         ]),
     ShaderOldNodeCategory("SH_CONVERTOR", "Converter", items=[
         NodeItem("ShaderNodeValToRGB"),
index 143003cc4e613fddc33947f53685d99f0cb99cf2..eb8ea01f7505283e03488b350fd377cbf4009398 100644 (file)
@@ -1188,6 +1188,7 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
        char name[32];
        int update_flag;
        bool use_border;
+       int ob_inst_update_flag = 0;
 
        update_flag = rp->engine->job_update_flag;
        rp->engine->job_update_flag = 0;
@@ -1299,6 +1300,13 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
        /* OK, can we enter render code? */
        if (rstats->convertdone) {
                bool first_time = true;
+
+               if (update_flag & PR_UPDATE_VIEW) {
+                       ob_inst_update_flag |= RE_OBJECT_INSTANCES_UPDATE_VIEW;
+               }
+
+               RE_updateRenderInstances(re, ob_inst_update_flag);
+
                for (;;) {
                        if (first_time == false) {
                                if (restore)
index 25788c26fea9ba3b42b51efbfa984118f4724752..65cdf834533f57348586d04387626dfcdc6a7328 100644 (file)
@@ -95,6 +95,8 @@ typedef enum GPUBuiltin {
        GPU_PARTICLE_LOCATION =     (1 << 10),
        GPU_PARTICLE_VELOCITY =     (1 << 11),
        GPU_PARTICLE_ANG_VELOCITY = (1 << 12),
+       GPU_LOC_TO_VIEW_MATRIX =    (1 << 13),
+       GPU_INVERSE_LOC_TO_VIEW_MATRIX = (1 << 14),
 } GPUBuiltin;
 
 typedef enum GPUOpenGLBuiltin {
@@ -148,6 +150,8 @@ typedef enum GPUDynamicType {
        GPU_DYNAMIC_OBJECT_IMAT          = 4  | GPU_DYNAMIC_GROUP_OBJECT,
        GPU_DYNAMIC_OBJECT_COLOR         = 5  | GPU_DYNAMIC_GROUP_OBJECT,
        GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE = 6  | GPU_DYNAMIC_GROUP_OBJECT,
+       GPU_DYNAMIC_OBJECT_LOCTOVIEWMAT  = 7  | GPU_DYNAMIC_GROUP_OBJECT,
+       GPU_DYNAMIC_OBJECT_LOCTOVIEWIMAT = 8  | GPU_DYNAMIC_GROUP_OBJECT,
 
        GPU_DYNAMIC_LAMP_DYNVEC          = 1  | GPU_DYNAMIC_GROUP_LAMP,
        GPU_DYNAMIC_LAMP_DYNCO           = 2  | GPU_DYNAMIC_GROUP_LAMP,
@@ -218,7 +222,7 @@ void GPU_material_bind(
         GPUMaterial *material, int oblay, int viewlay, double time, int mipmap,
         float viewmat[4][4], float viewinv[4][4], float cameraborder[4], bool scenelock);
 void GPU_material_bind_uniforms(
-        GPUMaterial *material, float obmat[4][4], float obcol[4],
+        GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float obcol[4],
         float autobumpscale, GPUParticleInfo *pi);
 void GPU_material_unbind(GPUMaterial *material);
 bool GPU_material_bound(GPUMaterial *material);
index 857b339c3a3a5f79b97f60ee76e0f9d1ecfdc09f..fb46b167f0f693e3449b860f5da701850af3709f 100644 (file)
@@ -381,6 +381,10 @@ const char *GPU_builtin_name(GPUBuiltin builtin)
                return "unfinvviewmat";
        else if (builtin == GPU_INVERSE_OBJECT_MATRIX)
                return "unfinvobmat";
+       else if (builtin == GPU_LOC_TO_VIEW_MATRIX)
+               return "unflocaltoviewmat";
+       else if (builtin == GPU_INVERSE_LOC_TO_VIEW_MATRIX)
+               return "unfinvlocaltoviewmat";
        else if (builtin == GPU_VIEW_POSITION)
                return "varposition";
        else if (builtin == GPU_VIEW_NORMAL)
index 95c019be4096da28934e8fd71df6a590bd704f98..a7f802a4502df4baf635e6bbb6f6c860a38cf2c4 100644 (file)
@@ -1763,7 +1763,7 @@ int GPU_object_material_bind(int nr, void *attribs)
                                GMS.gviewmat, GMS.gviewinv, GMS.gviewcamtexcofac, GMS.gscenelock);
 
                        auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f;
-                       GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gob->col, auto_bump_scale, &partile_info);
+                       GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gob->col, auto_bump_scale, &partile_info);
                        GMS.gboundmat = mat;
 
                        /* for glsl use alpha blend mode, unless it's set to solid and
index 29e49ca89d33a2f4e16647aa1cd70fb2a2a2311c..7cb2fc0622dd29ba39a0833473ef2a99bae48774 100644 (file)
@@ -112,6 +112,7 @@ struct GPUMaterial {
        /* for passing uniforms */
        int viewmatloc, invviewmatloc;
        int obmatloc, invobmatloc;
+       int localtoviewmatloc, invlocaltoviewmatloc;
        int obcolloc, obautobumpscaleloc;
        int cameratexcofacloc;
 
@@ -242,6 +243,10 @@ static int GPU_material_construct_end(GPUMaterial *material, const char *passnam
                        material->obmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_MATRIX));
                if (material->builtins & GPU_INVERSE_OBJECT_MATRIX)
                        material->invobmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_OBJECT_MATRIX));
+               if (material->builtins & GPU_LOC_TO_VIEW_MATRIX)
+                       material->localtoviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_LOC_TO_VIEW_MATRIX));
+               if (material->builtins & GPU_INVERSE_LOC_TO_VIEW_MATRIX)
+                       material->invlocaltoviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_LOC_TO_VIEW_MATRIX));
                if (material->builtins & GPU_OBCOLOR)
                        material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR));
                if (material->builtins & GPU_AUTO_BUMPSCALE)
@@ -384,12 +389,14 @@ void GPU_material_bind(
 }
 
 void GPU_material_bind_uniforms(
-        GPUMaterial *material, float obmat[4][4], float obcol[4],
+        GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float obcol[4],
         float autobumpscale, GPUParticleInfo *pi)
 {
        if (material->pass) {
                GPUShader *shader = GPU_pass_shader(material->pass);
                float invmat[4][4], col[4];
+               float localtoviewmat[4][4];
+               float invlocaltoviewmat[4][4];
 
                /* handle per object builtins */
                if (material->builtins & GPU_OBJECT_MATRIX) {
@@ -399,6 +406,19 @@ void GPU_material_bind_uniforms(
                        invert_m4_m4(invmat, obmat);
                        GPU_shader_uniform_vector(shader, material->invobmatloc, 16, 1, (float *)invmat);
                }
+               if (material->builtins & GPU_LOC_TO_VIEW_MATRIX) {
+                       if (viewmat) {
+                               mul_m4_m4m4(localtoviewmat, viewmat, obmat);
+                               GPU_shader_uniform_vector(shader, material->localtoviewmatloc, 16, 1, (float *)localtoviewmat);
+                       }
+               }
+               if (material->builtins & GPU_INVERSE_LOC_TO_VIEW_MATRIX) {
+                       if (viewmat) {
+                               mul_m4_m4m4(localtoviewmat, viewmat, obmat);
+                               invert_m4_m4(invlocaltoviewmat, localtoviewmat);
+                               GPU_shader_uniform_vector(shader, material->invlocaltoviewmatloc, 16, 1, (float*)invlocaltoviewmat);
+                       }
+               }
                if (material->builtins & GPU_OBCOLOR) {
                        copy_v4_v4(col, obcol);
                        CLAMP(col[3], 0.0f, 1.0f);
@@ -2352,6 +2372,8 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
                { GPU_INVERSE_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWIMAT, GPU_DATA_16F },
                { GPU_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_MAT, GPU_DATA_16F },
                { GPU_INVERSE_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_IMAT, GPU_DATA_16F },
+               { GPU_LOC_TO_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_LOCTOVIEWMAT, GPU_DATA_16F },
+               { GPU_INVERSE_LOC_TO_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_LOCTOVIEWIMAT, GPU_DATA_16F },
                { GPU_OBCOLOR, GPU_DYNAMIC_OBJECT_COLOR, GPU_DATA_4F },
                { GPU_AUTO_BUMPSCALE, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE, GPU_DATA_1F },
                { 0 }
index dfb1af0e86350681c944b61da120d09222372431..e7072016cc01a29df3acd4c33a3d349a9c03a354 100644 (file)
@@ -166,6 +166,21 @@ void particle_info(vec4 sprops, vec3 loc, vec3 vel, vec3 avel, out float index,
     angular_velocity = avel;
 }
 
+void vect_normalize(vec3 vin, out vec3 vout)
+{
+       vout = normalize(vin);
+}
+
+void direction_transform_m4v3(vec3 vin, mat4 mat, out vec3 vout)
+{
+       vout = (mat*vec4(vin, 0.0)).xyz;
+}
+
+void point_transform_m4v3(vec3 vin, mat4 mat, out vec3 vout)
+{
+       vout = (mat*vec4(vin, 1.0)).xyz;
+}
+
 void mapping(vec3 vec, mat4 mat, vec3 minvec, vec3 maxvec, float domin, float domax, out vec3 outvec)
 {
        outvec = (mat * vec4(vec, 1.0)).xyz;
index 4cab9d3ca97870b8060f8a9739e9257de96daa37..5b6d213703a775c58907a17cc28e3a8a222b0c5c 100644 (file)
@@ -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);
 }
index aada3f6fc8073b943dd9b49a6d3d44724b9829a3..c6e47de8c9040567d4ff463cb75879993d57232a 100644 (file)
@@ -97,6 +97,8 @@ static PyObject *PyInit_gpu(void)
        PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_MAT);
        PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_VIEWIMAT);
        PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_IMAT);
+       PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_LOCTOVIEWMAT);
+       PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_LOCTOVIEWIMAT);
        PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_COLOR);
        PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE);
        /* GPU_DYNAMIC_GROUP_LAMP */
index 96ac8aa8c5a98d56c0459d64af5fbaccc1dbc5e0..ce0691b7632ad35b5715777c4f2d6d9c52dff594 100644 (file)
@@ -363,6 +363,13 @@ bool RE_is_rendering_allowed(struct Scene *scene, struct Object *camera_override
 
 bool RE_allow_render_generic_object(struct Object *ob);
 
+/* RE_updateRenderInstances flag */
+enum {
+       RE_OBJECT_INSTANCES_UPDATE_VIEW  = (1 << 0),
+       RE_OBJECT_INSTANCES_UPDATE_OBMAT = (1 << 1),
+};
+void RE_updateRenderInstances(Render *re, int flag);
+
 /******* defined in render_result.c *********/
 
 bool RE_HasFakeLayer(RenderResult *res);
index f78c0aa8cb2116eef1f4d69f0e9f294afc720499..2b07ace26dbb92add97390eab9061e5b4e89a4ba 100644 (file)
@@ -220,6 +220,22 @@ float RE_bake_make_derivative(struct ImBuf *ibuf, float *heights_buffer, const c
                               const float height_min, const float height_max,
                               const float fmult);
 
+enum {
+       RE_OBJECT_INSTANCE_MATRIX_OB,
+       RE_OBJECT_INSTANCE_MATRIX_OBINV,
+       RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEW,
+       RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEWINV,
+};
+
+const float (*RE_object_instance_get_matrix(struct ObjectInstanceRen *obi, int matrix_id))[4];
+
+enum {
+       RE_VIEW_MATRIX,
+       RE_VIEWINV_MATRIX,
+};
+
+const float (*RE_render_current_get_matrix(int matrix_id))[4];
+
 #define BAKE_RESULT_OK                 0
 #define BAKE_RESULT_NO_OBJECTS         1
 #define BAKE_RESULT_FEEDBACK_LOOP      2
index 3569cb2c1683b2d54071b9923ceb8ec669aed4e6..3b69c12475376ad638aafa178a15ac7af86f35c1 100644 (file)
@@ -353,6 +353,10 @@ typedef struct ObjectInstanceRen {
 
        float mat[4][4], imat[4][4];
        float nmat[3][3]; /* nmat is inverse mat tranposed */
+
+       float obmat[4][4], obinvmat[4][4];
+       float localtoviewmat[4][4], localtoviewinvmat[4][4];
+
        short flag;
 
        float dupliorco[3], dupliuv[2];
index 224974454e82d352e28d5396171da51845326de4..167ebc580305aa904e46fb5234ee183f0412569d 100644 (file)
@@ -119,6 +119,7 @@ struct ObjectInstanceRen *RE_addRenderInstance(
         struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par,
         int index, int psysindex, float mat[4][4], int lay, const struct DupliObject *dob);
 void RE_makeRenderInstances(struct Render *re);
+void RE_updateRenderInstance(Render *re, ObjectInstanceRen *obi, int flag);
 
 void RE_instance_rotate_ray_start(struct ObjectInstanceRen *obi, struct Isect *is);
 void RE_instance_rotate_ray_dir(struct ObjectInstanceRen *obi, struct Isect *is);
index ac42c0d1dcc96b4c29a1cab39d8e31b4c08f96c0..560627b1be1bdbac2711b4776b98629bbe8329db 100644 (file)
@@ -1363,6 +1363,26 @@ void project_renderdata(Render *re,
 
 /* ------------------------------------------------------------------------- */
 
+void RE_updateRenderInstance(Render *re, ObjectInstanceRen *obi, int flag)
+{
+       /* flag specifies what things have changed. */
+       if (flag & RE_OBJECT_INSTANCES_UPDATE_OBMAT) {
+               copy_m4_m4(obi->obmat, obi->ob->obmat);
+               invert_m4_m4(obi->obinvmat, obi->obmat);
+       }
+       if (flag & RE_OBJECT_INSTANCES_UPDATE_VIEW) {
+               mul_m4_m4m4(obi->localtoviewmat, re->viewmat, obi->obmat);
+               mul_m4_m4m4(obi->localtoviewinvmat, obi->obinvmat, re->viewinv);
+       }
+}
+
+void RE_updateRenderInstances(Render *re, int flag)
+{
+       int i = 0;
+       for (i = 0; i < re->totinstance; i++)
+               RE_updateRenderInstance(re, &re->objectinstance[i], flag);
+}
+
 ObjectInstanceRen *RE_addRenderInstance(
         Render *re, ObjectRen *obr, Object *ob, Object *par,
         int index, int psysindex, float mat[4][4], int lay, const DupliObject *dob)
@@ -1407,6 +1427,8 @@ ObjectInstanceRen *RE_addRenderInstance(
                }
        }
 
+       RE_updateRenderInstance(re, obi, RE_OBJECT_INSTANCES_UPDATE_OBMAT | RE_OBJECT_INSTANCES_UPDATE_VIEW);
+
        if (mat) {
                copy_m4_m4(obi->mat, mat);
                copy_m3_m4(mat3, mat);
index 27c0f5d81ec6f9d1d8fafb914d30ef7a595e2c99..71b409dbba757851b833f72348e2bee811e054d9 100644 (file)
@@ -2112,3 +2112,31 @@ float RE_lamp_get_data(ShadeInput *shi, Object *lamp_obj, float col[4], float lv
 
        return 0.0f;
 }
+
+const float (*RE_object_instance_get_matrix(struct ObjectInstanceRen *obi, int matrix_id))[4]
+{
+       if (obi) {
+               switch (matrix_id) {
+                       case RE_OBJECT_INSTANCE_MATRIX_OB:
+                               return (const float(*)[4])obi->obmat;
+                       case RE_OBJECT_INSTANCE_MATRIX_OBINV:
+                               return (const float(*)[4])obi->obinvmat;
+                       case RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEW:
+                               return (const float(*)[4])obi->localtoviewmat;
+                       case RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEWINV:
+                               return (const float(*)[4])obi->localtoviewinvmat;
+               }
+       }
+       return NULL;
+}
+
+const float (*RE_render_current_get_matrix(int matrix_id))[4]
+{
+       switch(matrix_id) {
+               case RE_VIEW_MATRIX:
+                       return (const float(*)[4])R.viewmat;
+               case RE_VIEWINV_MATRIX:
+                       return (const float(*)[4])R.viewinv;
+       }
+       return NULL;
+}
index 4d0840ece74729c7ca814701b770b913a935b820..c0ff81b3b20f166bfa78e3e6b802ed910b02c4fb 100644 (file)
@@ -263,6 +263,8 @@ void RE_sample_material_color(
 struct Render *RE_GetRender(const char *name) RET_NULL
 struct Object *RE_GetCamera(struct Render *re) RET_NULL
 float RE_lamp_get_data(struct ShadeInput *shi, struct Object *lamp_obj, float col[4], float lv[3], float *dist, float shadow[4]) RET_ZERO
+const float (*RE_object_instance_get_matrix(struct ObjectInstanceRen *obi, int matrix_id))[4] RET_NULL
+const float (*RE_render_current_get_matrix(int matrix_id))[4] RET_NULL
 
 /* blenkernel */
 bool BKE_paint_proj_mesh_data_check(struct Scene *scene, struct Object *ob, bool *uvs, bool *mat, bool *tex, bool *stencil) RET_ZERO
index 0f71f8d3bac3238b16487d7a7d16337be6974265..95679b5d3a613ad442d93eff7d82dc0c0a5ce008 100644 (file)
@@ -74,8 +74,8 @@ void BL_BlenderShader::SetProg(bool enable, double time, RAS_IRasterizer* rasty)
                        float viewmat[4][4], viewinvmat[4][4];
                        const MT_Matrix4x4& view = rasty->GetViewMatrix();
                        const MT_Matrix4x4& viewinv = rasty->GetViewInvMatrix();
-                       view.getValue((float*)viewmat);
-                       viewinv.getValue((float*)viewinvmat);
+                       view.getValue(&viewmat[0][0]);
+                       viewinv.getValue(&viewinvmat[0][0]);
 
                        GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time, 1, viewmat, viewinvmat, NULL, false);
                }
@@ -148,7 +148,7 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
 
 void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
 {
-       float obmat[4][4], obcol[4];
+       float obmat[4][4], viewmat[4][4], obcol[4];
        GPUMaterial *gpumat;
 
        gpumat = mGPUMat;
@@ -160,15 +160,16 @@ void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
        model.setValue(ms.m_OpenGLMatrix);
 
        // note: getValue gives back column major as needed by OpenGL
-       model.getValue((float*)obmat);
+       model.getValue(&obmat[0][0]);
 
        if (ms.m_bObjectColor)
-               ms.m_RGBAcolor.getValue((float *)obcol);
+               ms.m_RGBAcolor.getValue(&obcol[0]);
        else
                obcol[0] = obcol[1] = obcol[2] = obcol[3] = 1.0f;
 
+       rasty->GetViewMatrix().getValue(&viewmat[0][0]);
        float auto_bump_scale = ms.m_pDerivedMesh!=0 ? ms.m_pDerivedMesh->auto_bump_scale : 1.0f;
-       GPU_material_bind_uniforms(gpumat, obmat, obcol, auto_bump_scale, NULL);
+       GPU_material_bind_uniforms(gpumat, obmat, viewmat, obcol, auto_bump_scale, NULL);
 
        mAlphaBlend = GPU_material_alpha_blend(gpumat, obcol);
 }