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
This commit is contained in:
Alexander Romanov 2016-01-23 15:27:36 +03:00
parent e9452f909c
commit a6aaaad979
17 changed files with 278 additions and 10 deletions

@ -159,6 +159,7 @@ shader_node_categories = [
NodeItem("ShaderNodeNormal"), NodeItem("ShaderNodeNormal"),
NodeItem("ShaderNodeMapping"), NodeItem("ShaderNodeMapping"),
NodeItem("ShaderNodeVectorCurve"), NodeItem("ShaderNodeVectorCurve"),
NodeItem("ShaderNodeVectorTransform"),
]), ]),
ShaderOldNodeCategory("SH_CONVERTOR", "Converter", items=[ ShaderOldNodeCategory("SH_CONVERTOR", "Converter", items=[
NodeItem("ShaderNodeValToRGB"), NodeItem("ShaderNodeValToRGB"),

@ -1188,6 +1188,7 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
char name[32]; char name[32];
int update_flag; int update_flag;
bool use_border; bool use_border;
int ob_inst_update_flag = 0;
update_flag = rp->engine->job_update_flag; update_flag = rp->engine->job_update_flag;
rp->engine->job_update_flag = 0; 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? */ /* OK, can we enter render code? */
if (rstats->convertdone) { if (rstats->convertdone) {
bool first_time = true; 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 (;;) { for (;;) {
if (first_time == false) { if (first_time == false) {
if (restore) if (restore)

@ -95,6 +95,8 @@ typedef enum GPUBuiltin {
GPU_PARTICLE_LOCATION = (1 << 10), GPU_PARTICLE_LOCATION = (1 << 10),
GPU_PARTICLE_VELOCITY = (1 << 11), GPU_PARTICLE_VELOCITY = (1 << 11),
GPU_PARTICLE_ANG_VELOCITY = (1 << 12), GPU_PARTICLE_ANG_VELOCITY = (1 << 12),
GPU_LOC_TO_VIEW_MATRIX = (1 << 13),
GPU_INVERSE_LOC_TO_VIEW_MATRIX = (1 << 14),
} GPUBuiltin; } GPUBuiltin;
typedef enum GPUOpenGLBuiltin { typedef enum GPUOpenGLBuiltin {
@ -148,6 +150,8 @@ typedef enum GPUDynamicType {
GPU_DYNAMIC_OBJECT_IMAT = 4 | GPU_DYNAMIC_GROUP_OBJECT, GPU_DYNAMIC_OBJECT_IMAT = 4 | GPU_DYNAMIC_GROUP_OBJECT,
GPU_DYNAMIC_OBJECT_COLOR = 5 | 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_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_DYNVEC = 1 | GPU_DYNAMIC_GROUP_LAMP,
GPU_DYNAMIC_LAMP_DYNCO = 2 | 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, GPUMaterial *material, int oblay, int viewlay, double time, int mipmap,
float viewmat[4][4], float viewinv[4][4], float cameraborder[4], bool scenelock); float viewmat[4][4], float viewinv[4][4], float cameraborder[4], bool scenelock);
void GPU_material_bind_uniforms( 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); float autobumpscale, GPUParticleInfo *pi);
void GPU_material_unbind(GPUMaterial *material); void GPU_material_unbind(GPUMaterial *material);
bool GPU_material_bound(GPUMaterial *material); bool GPU_material_bound(GPUMaterial *material);

@ -381,6 +381,10 @@ const char *GPU_builtin_name(GPUBuiltin builtin)
return "unfinvviewmat"; return "unfinvviewmat";
else if (builtin == GPU_INVERSE_OBJECT_MATRIX) else if (builtin == GPU_INVERSE_OBJECT_MATRIX)
return "unfinvobmat"; 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) else if (builtin == GPU_VIEW_POSITION)
return "varposition"; return "varposition";
else if (builtin == GPU_VIEW_NORMAL) else if (builtin == GPU_VIEW_NORMAL)

@ -1763,7 +1763,7 @@ int GPU_object_material_bind(int nr, void *attribs)
GMS.gviewmat, GMS.gviewinv, GMS.gviewcamtexcofac, GMS.gscenelock); GMS.gviewmat, GMS.gviewinv, GMS.gviewcamtexcofac, GMS.gscenelock);
auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f; 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; GMS.gboundmat = mat;
/* for glsl use alpha blend mode, unless it's set to solid and /* for glsl use alpha blend mode, unless it's set to solid and

@ -112,6 +112,7 @@ struct GPUMaterial {
/* for passing uniforms */ /* for passing uniforms */
int viewmatloc, invviewmatloc; int viewmatloc, invviewmatloc;
int obmatloc, invobmatloc; int obmatloc, invobmatloc;
int localtoviewmatloc, invlocaltoviewmatloc;
int obcolloc, obautobumpscaleloc; int obcolloc, obautobumpscaleloc;
int cameratexcofacloc; 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)); material->obmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_MATRIX));
if (material->builtins & GPU_INVERSE_OBJECT_MATRIX) if (material->builtins & GPU_INVERSE_OBJECT_MATRIX)
material->invobmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(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) if (material->builtins & GPU_OBCOLOR)
material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR)); material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR));
if (material->builtins & GPU_AUTO_BUMPSCALE) if (material->builtins & GPU_AUTO_BUMPSCALE)
@ -384,12 +389,14 @@ void GPU_material_bind(
} }
void GPU_material_bind_uniforms( 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) float autobumpscale, GPUParticleInfo *pi)
{ {
if (material->pass) { if (material->pass) {
GPUShader *shader = GPU_pass_shader(material->pass); GPUShader *shader = GPU_pass_shader(material->pass);
float invmat[4][4], col[4]; float invmat[4][4], col[4];
float localtoviewmat[4][4];
float invlocaltoviewmat[4][4];
/* handle per object builtins */ /* handle per object builtins */
if (material->builtins & GPU_OBJECT_MATRIX) { if (material->builtins & GPU_OBJECT_MATRIX) {
@ -399,6 +406,19 @@ void GPU_material_bind_uniforms(
invert_m4_m4(invmat, obmat); invert_m4_m4(invmat, obmat);
GPU_shader_uniform_vector(shader, material->invobmatloc, 16, 1, (float *)invmat); 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) { if (material->builtins & GPU_OBCOLOR) {
copy_v4_v4(col, obcol); copy_v4_v4(col, obcol);
CLAMP(col[3], 0.0f, 1.0f); 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_INVERSE_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWIMAT, GPU_DATA_16F },
{ GPU_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_MAT, 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_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_OBCOLOR, GPU_DYNAMIC_OBJECT_COLOR, GPU_DATA_4F },
{ GPU_AUTO_BUMPSCALE, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE, GPU_DATA_1F }, { GPU_AUTO_BUMPSCALE, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE, GPU_DATA_1F },
{ 0 } { 0 }

@ -166,6 +166,21 @@ void particle_info(vec4 sprops, vec3 loc, vec3 vel, vec3 avel, out float index,
angular_velocity = avel; 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) void mapping(vec3 vec, mat4 mat, vec3 minvec, vec3 maxvec, float domin, float domax, out vec3 outvec)
{ {
outvec = (mat * vec4(vec, 1.0)).xyz; outvec = (mat * vec4(vec, 1.0)).xyz;

@ -52,15 +52,146 @@ static void node_shader_init_vect_transform(bNodeTree *UNUSED(ntree), bNode *nod
node->storage = vect; 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) void register_node_type_sh_vect_transform(void)
{ {
static bNodeType ntype; static bNodeType ntype;
sh_node_type_base(&ntype, SH_NODE_VECT_TRANSFORM, "Vector Transform", NODE_CLASS_CONVERTOR, 0); 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_init(&ntype, node_shader_init_vect_transform);
node_type_socket_templates(&ntype, sh_node_vect_transform_in, sh_node_vect_transform_out); 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_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); nodeRegisterType(&ntype);
} }

@ -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_MAT);
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_VIEWIMAT); 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_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_COLOR);
PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE);
/* GPU_DYNAMIC_GROUP_LAMP */ /* GPU_DYNAMIC_GROUP_LAMP */

@ -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); 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 *********/ /******* defined in render_result.c *********/
bool RE_HasFakeLayer(RenderResult *res); bool RE_HasFakeLayer(RenderResult *res);

@ -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 height_min, const float height_max,
const float fmult); 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_OK 0
#define BAKE_RESULT_NO_OBJECTS 1 #define BAKE_RESULT_NO_OBJECTS 1
#define BAKE_RESULT_FEEDBACK_LOOP 2 #define BAKE_RESULT_FEEDBACK_LOOP 2

@ -353,6 +353,10 @@ typedef struct ObjectInstanceRen {
float mat[4][4], imat[4][4]; float mat[4][4], imat[4][4];
float nmat[3][3]; /* nmat is inverse mat tranposed */ 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; short flag;
float dupliorco[3], dupliuv[2]; float dupliorco[3], dupliuv[2];

@ -119,6 +119,7 @@ struct ObjectInstanceRen *RE_addRenderInstance(
struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, 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); int index, int psysindex, float mat[4][4], int lay, const struct DupliObject *dob);
void RE_makeRenderInstances(struct Render *re); 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_start(struct ObjectInstanceRen *obi, struct Isect *is);
void RE_instance_rotate_ray_dir(struct ObjectInstanceRen *obi, struct Isect *is); void RE_instance_rotate_ray_dir(struct ObjectInstanceRen *obi, struct Isect *is);

@ -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( ObjectInstanceRen *RE_addRenderInstance(
Render *re, ObjectRen *obr, Object *ob, Object *par, Render *re, ObjectRen *obr, Object *ob, Object *par,
int index, int psysindex, float mat[4][4], int lay, const DupliObject *dob) 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) { if (mat) {
copy_m4_m4(obi->mat, mat); copy_m4_m4(obi->mat, mat);
copy_m3_m4(mat3, mat); copy_m3_m4(mat3, mat);

@ -2112,3 +2112,31 @@ float RE_lamp_get_data(ShadeInput *shi, Object *lamp_obj, float col[4], float lv
return 0.0f; 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;
}

@ -263,6 +263,8 @@ void RE_sample_material_color(
struct Render *RE_GetRender(const char *name) RET_NULL struct Render *RE_GetRender(const char *name) RET_NULL
struct Object *RE_GetCamera(struct Render *re) 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 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 */ /* blenkernel */
bool BKE_paint_proj_mesh_data_check(struct Scene *scene, struct Object *ob, bool *uvs, bool *mat, bool *tex, bool *stencil) RET_ZERO bool BKE_paint_proj_mesh_data_check(struct Scene *scene, struct Object *ob, bool *uvs, bool *mat, bool *tex, bool *stencil) RET_ZERO

@ -74,8 +74,8 @@ void BL_BlenderShader::SetProg(bool enable, double time, RAS_IRasterizer* rasty)
float viewmat[4][4], viewinvmat[4][4]; float viewmat[4][4], viewinvmat[4][4];
const MT_Matrix4x4& view = rasty->GetViewMatrix(); const MT_Matrix4x4& view = rasty->GetViewMatrix();
const MT_Matrix4x4& viewinv = rasty->GetViewInvMatrix(); const MT_Matrix4x4& viewinv = rasty->GetViewInvMatrix();
view.getValue((float*)viewmat); view.getValue(&viewmat[0][0]);
viewinv.getValue((float*)viewinvmat); viewinv.getValue(&viewinvmat[0][0]);
GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time, 1, viewmat, viewinvmat, NULL, false); 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 ) 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; GPUMaterial *gpumat;
gpumat = mGPUMat; gpumat = mGPUMat;
@ -160,15 +160,16 @@ void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
model.setValue(ms.m_OpenGLMatrix); model.setValue(ms.m_OpenGLMatrix);
// note: getValue gives back column major as needed by OpenGL // note: getValue gives back column major as needed by OpenGL
model.getValue((float*)obmat); model.getValue(&obmat[0][0]);
if (ms.m_bObjectColor) if (ms.m_bObjectColor)
ms.m_RGBAcolor.getValue((float *)obcol); ms.m_RGBAcolor.getValue(&obcol[0]);
else else
obcol[0] = obcol[1] = obcol[2] = obcol[3] = 1.0f; 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; 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); mAlphaBlend = GPU_material_alpha_blend(gpumat, obcol);
} }