Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiika Hamalainen <blender@miikah.org>2011-10-22 20:16:14 +0400
committerMiika Hamalainen <blender@miikah.org>2011-10-22 20:16:14 +0400
commit30cba27987362054d16b10e73ddf2601af93be68 (patch)
treed971f10db56b5d024cf5f7d6f3d48d1e3c20d698 /source/blender/render
parent8be3249537e7930e0fa5adb59bc343455da309e9 (diff)
Dynamic Paint:
* Some changes and cleanup pointed on the codereview.
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/extern/include/RE_render_ext.h7
-rw-r--r--source/blender/render/intern/include/texture.h2
-rw-r--r--source/blender/render/intern/source/render_texture.c258
-rw-r--r--source/blender/render/intern/source/shadeinput.c28
-rw-r--r--source/blender/render/intern/source/shadeoutput.c16
5 files changed, 289 insertions, 22 deletions
diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h
index e98f481b162..deae2ed9b66 100644
--- a/source/blender/render/extern/include/RE_render_ext.h
+++ b/source/blender/render/extern/include/RE_render_ext.h
@@ -50,6 +50,7 @@ struct RNode;
struct Render;
struct MTex;
struct ImBuf;
+struct DerivedMesh;
// RADIO REMOVED, Maybe this will be useful later
//void RE_zbufferall_radio(struct RadView *vw, struct RNode **rg_elem, int rg_totelem, struct Render *re);
@@ -65,5 +66,11 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen
void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result);
void antialias_tagbuf(int xsize, int ysize, char *rectmove);
+/* dynamicpaint.c */
+struct Material *RE_init_sample_material(struct Material *orig_mat, struct Scene *scene);
+void RE_free_sample_material(struct Material *mat);
+void RE_sample_material_color(struct Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3],
+ int face_index, short hit_quad, struct DerivedMesh *orcoDm, struct Object *ob);
+
#endif /* RE_RENDER_EXT_H */
diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h
index 294c7b53766..9815cfdff7d 100644
--- a/source/blender/render/intern/include/texture.h
+++ b/source/blender/render/intern/include/texture.h
@@ -68,7 +68,7 @@ void do_halo_tex(struct HaloRen *har, float xn, float yn, float col_r[4]);
void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float hor[3], float zen[3], float *blend, int skyflag, short thread);
void do_material_tex(struct ShadeInput *shi);
void do_lamp_tex(LampRen *la, const float lavec[3], struct ShadeInput *shi, float col_r[3], int effect);
-void do_volume_tex(struct ShadeInput *shi, const float *xyz, int mapto_flag, float *col, float *val, struct Render *re);
+void do_volume_tex(struct ShadeInput *shi, const float xyz[3], int mapto_flag, float col[3], float *val, struct Render *re);
void init_render_textures(Render *re);
void end_render_textures(Render *re);
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index 2d9ce24b46c..a050fd8622b 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -40,6 +40,7 @@
#include "BLI_rand.h"
#include "BLI_utildefines.h"
+#include "DNA_anim_types.h"
#include "DNA_texture_types.h"
#include "DNA_object_types.h"
#include "DNA_lamp_types.h"
@@ -57,10 +58,12 @@
#include "BKE_node.h"
#include "BKE_plugin_types.h"
-
+#include "BKE_animsys.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_material.h"
+#include "BKE_scene.h"
#include "BKE_library.h"
#include "BKE_image.h"
@@ -3474,4 +3477,257 @@ void render_realtime_texture(ShadeInput *shi, Image *ima)
shi->vcol[3]*= texr.ta;
}
+/* A modified part of shadeinput.c -> shade_input_set_uv()
+* Used for sampling UV mapped texture color */
+static void textured_face_generate_uv(float *uv, float *normal, float *hit, float *v1, float *v2, float *v3)
+{
+
+ float detsh, t00, t10, t01, t11, xn, yn, zn;
+ int axis1, axis2;
+
+ /* find most stable axis to project */
+ xn= fabs(normal[0]);
+ yn= fabs(normal[1]);
+ zn= fabs(normal[2]);
+
+ if(zn>=xn && zn>=yn) { axis1= 0; axis2= 1; }
+ else if(yn>=xn && yn>=zn) { axis1= 0; axis2= 2; }
+ else { axis1= 1; axis2= 2; }
+
+ /* compute u,v and derivatives */
+ t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2];
+ t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2];
+
+ detsh= 1.0f/(t00*t11-t10*t01);
+ t00*= detsh; t01*=detsh;
+ t10*=detsh; t11*=detsh;
+
+ uv[0] = (hit[axis1]-v3[axis1])*t11-(hit[axis2]-v3[axis2])*t10;
+ uv[1] = (hit[axis2]-v3[axis2])*t00-(hit[axis1]-v3[axis1])*t01;
+
+ /* u and v are in range -1 to 0, we allow a little bit extra but not too much, screws up speedvectors */
+ CLAMP(uv[0], -2.0f, 1.0f);
+ CLAMP(uv[1], -2.0f, 1.0f);
+}
+
+/* Generate an updated copy of material to use for color sampling. */
+Material *RE_init_sample_material(Material *orig_mat, Scene *scene)
+{
+ Tex *tex = NULL;
+ Material *mat;
+ int tex_nr;
+
+ if (!orig_mat) return NULL;
+
+ /* copy material */
+ mat = localize_material(orig_mat);
+
+ /* update material anims */
+ BKE_animsys_evaluate_animdata(scene, &mat->id, mat->adt, BKE_curframe(scene), ADT_RECALC_ANIM);
+
+ /* strip material copy from unsupported flags */
+ for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
+ if(mat->septex & (1<<tex_nr)) continue;
+
+ if(mat->mtex[tex_nr]) {
+ MTex *mtex = mat->mtex[tex_nr];
+
+ /* only keep compatible texflags */
+ mtex->texflag = mtex->texflag & (MTEX_RGBTOINT | MTEX_STENCIL | MTEX_NEGATIVE | MTEX_ALPHAMIX);
+
+ /* depending of material type, strip non-compatible mapping modes */
+ if (mat->material_type == MA_TYPE_SURFACE) {
+ if (!ELEM4(mtex->texco, TEXCO_ORCO, TEXCO_OBJECT, TEXCO_GLOB, TEXCO_UV)) {
+ /* ignore this texture */
+ mtex->texco = 0;
+ continue;
+ }
+ /* strip all mapto flags except color and alpha */
+ mtex->mapto = (mtex->mapto & MAP_COL) | (mtex->mapto & MAP_ALPHA);
+ }
+ else if (mat->material_type == MA_TYPE_VOLUME) {
+ if (!ELEM3(mtex->texco, TEXCO_OBJECT, TEXCO_ORCO, TEXCO_GLOB)) {
+ /* ignore */
+ mtex->texco = 0;
+ continue;
+ }
+ /* strip all mapto flags except color and alpha */
+ mtex->mapto = mtex->mapto & (MAP_TRANSMISSION_COL | MAP_REFLECTION_COL | MAP_DENSITY);
+ }
+
+ /* if mapped to an object, calculate inverse matrices */
+ if(mtex->texco==TEXCO_OBJECT) {
+ Object *ob= mtex->object;
+ if(ob) {
+ invert_m4_m4(ob->imat, ob->obmat);
+ copy_m4_m4(ob->imat_ren, ob->imat);
+ }
+ }
+
+ /* copy texture */
+ tex= mtex->tex = localize_texture(mtex->tex);
+
+ /* update texture anims */
+ BKE_animsys_evaluate_animdata(scene, &tex->id, tex->adt, BKE_curframe(scene), ADT_RECALC_ANIM);
+
+ /* update texture cache if required */
+ if(tex->type==TEX_VOXELDATA) {
+ cache_voxeldata(tex, (int)scene->r.cfra);
+ }
+ if(tex->type==TEX_POINTDENSITY) {
+ /* set dummy values for render and do cache */
+ Render dummy_re = {0};
+ dummy_re.scene = scene;
+ unit_m4(dummy_re.viewinv);
+ unit_m4(dummy_re.viewmat);
+ unit_m4(dummy_re.winmat);
+ dummy_re.winx = dummy_re.winy = 128;
+ cache_pointdensity(&dummy_re, tex);
+ }
+
+ /* update image sequences and movies */
+ if(tex->ima && ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
+ if(tex->iuser.flag & IMA_ANIM_ALWAYS)
+ BKE_image_user_calc_frame(&tex->iuser, (int)scene->r.cfra, 0);
+ }
+ }
+ }
+ return mat;
+}
+
+/* free all duplicate data allocated by RE_init_sample_material() */
+void RE_free_sample_material(Material *mat)
+{
+ int tex_nr;
+
+ /* free textures */
+ for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
+ if(mat->septex & (1<<tex_nr)) continue;
+ if(mat->mtex[tex_nr]) {
+ MTex *mtex= mat->mtex[tex_nr];
+ free_texture(mtex->tex);
+ }
+ }
+
+ free_material(mat);
+}
+
+
+
+/*
+* Get material diffuse color and alpha (including linked textures) in given coordinates
+*
+* color,alpha : input/output color values
+* volume_co : sample coordinate in global space. used by volumetric materials
+* surface_co : sample surface coordinate in global space. used by "surface" materials
+* face_index : surface face index
+* hit_quad : whether point is on second "half" of a quad
+* orcoDm : orco state derived mesh
+*/
+void RE_sample_material_color(Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3], int face_index, short hit_quad, DerivedMesh *orcoDm, Object *ob)
+{
+ MFace *mface;
+ int v1, v2, v3;
+ MVert *mvert;
+ float uv[3], normal[3];
+ ShadeInput shi = {0};
+
+ /* Get face data */
+ mvert = orcoDm->getVertArray(orcoDm);
+ mface = orcoDm->getFaceArray(orcoDm);
+
+ if (!mvert || !mface || !mat) return;
+ v1=mface[face_index].v1, v2=mface[face_index].v2, v3=mface[face_index].v3;
+ if (hit_quad) {v2=mface[face_index].v3; v3=mface[face_index].v4;}
+ normal_tri_v3( normal, mvert[v1].co, mvert[v2].co, mvert[v3].co);
+
+ /* generate shadeinput with data required */
+ shi.mat = mat;
+
+ /* fill shadeinput data depending on material type */
+ if (mat->material_type == MA_TYPE_SURFACE) {
+ /* global coordinates */
+ VECCOPY(shi.gl, surface_co);
+ /* object space coordinates */
+ VECCOPY(shi.co, surface_co);
+ mul_m4_v3(ob->imat, shi.co);
+ /* orco coordinates */
+ {
+ float l;
+ /* Get generated UV */
+ textured_face_generate_uv(uv, normal, shi.co, mvert[v1].co, mvert[v2].co, mvert[v3].co);
+ l= 1.0f+uv[0]+uv[1];
+
+ /* calculate generated coordinate */
+ shi.lo[0]= l*mvert[v3].co[0]-uv[0]*mvert[v1].co[0]-uv[1]*mvert[v2].co[0];
+ shi.lo[1]= l*mvert[v3].co[1]-uv[0]*mvert[v1].co[1]-uv[1]*mvert[v2].co[1];
+ shi.lo[2]= l*mvert[v3].co[2]-uv[0]*mvert[v1].co[2]-uv[1]*mvert[v2].co[2];
+ }
+ /* uv coordinates */
+ {
+ int i, layers = CustomData_number_of_layers(&orcoDm->faceData, CD_MTFACE);
+ int layer_index = CustomData_get_layer_index(&orcoDm->faceData, CD_MTFACE);
+
+ /* for every uv layer set coords and name */
+ for (i=0; i<layers; i++) {
+ if(layer_index >= 0) {
+ float *uv1, *uv2, *uv3;
+ float l;
+ CustomData *data = &orcoDm->faceData;
+ MTFace *tface = (MTFace*) data->layers[layer_index+i].data;
+ float uv[3];
+ /* point layer name from actual layer data */
+ shi.uv[i].name = data->layers[i].name;
+ /* Get generated coordinates to calculate UV from */
+ textured_face_generate_uv(uv, normal, shi.co, mvert[v1].co, mvert[v2].co, mvert[v3].co);
+ /* Get UV mapping coordinate */
+ l= 1.0f+uv[0]+uv[1];
+
+ uv1= tface[face_index].uv[0];
+ uv2= (hit_quad) ? tface[face_index].uv[2] : tface[face_index].uv[1];
+ uv3= (hit_quad) ? tface[face_index].uv[3] : tface[face_index].uv[2];
+
+ shi.uv[i].uv[0]= -1.0f + 2.0f*(l*uv3[0]-uv[0]*uv1[0]-uv[1]*uv2[0]);
+ shi.uv[i].uv[1]= -1.0f + 2.0f*(l*uv3[1]-uv[0]*uv1[1]-uv[1]*uv2[1]);
+ shi.uv[i].uv[2]= 0.0f; /* texture.c assumes there are 3 coords */
+ }
+ }
+ /* active uv layer */
+ shi.actuv = CustomData_get_active_layer_index(&orcoDm->faceData,CD_MTFACE) - layer_index;
+ shi.totuv = layers;
+ }
+
+ /* apply initial values from material */
+ shi.r = mat->r;
+ shi.g = mat->g;
+ shi.b = mat->b;
+ shi.alpha = mat->alpha;
+
+ /* do texture */
+ do_material_tex(&shi);
+
+ /* apply result */
+ color[0] = shi.r;
+ color[1] = shi.g;
+ color[2] = shi.b;
+ *alpha = shi.alpha;
+ }
+ else if (mat->material_type == MA_TYPE_VOLUME) {
+ ObjectInstanceRen obi = {0};
+ Render re = {0};
+ obi.ob = ob;
+ shi.obi = &obi;
+ unit_m4(re.viewinv);
+
+ color[0] = mat->vol.reflection_col[0];
+ color[1] = mat->vol.reflection_col[1];
+ color[2] = mat->vol.reflection_col[2];
+ *alpha = mat->vol.density;
+
+ /* do texture */
+ do_volume_tex(&shi, volume_co, (MAP_TRANSMISSION_COL | MAP_REFLECTION_COL | MAP_DENSITY),
+ color, alpha, &re);
+ }
+}
+
/* eof */
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index f3e5fc63bda..e20c6ee174c 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -1103,6 +1103,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
for (i=0; (mcol=RE_vlakren_get_mcol(obr, vlr, i, &name, 0)); i++) {
ShadeInputCol *scol= &shi->col[i];
char *cp1, *cp2, *cp3;
+ float a[3];
shi->totcol++;
scol->name= name;
@@ -1111,18 +1112,21 @@ void shade_input_set_shade_texco(ShadeInput *shi)
cp2= (char *)(mcol+j2);
cp3= (char *)(mcol+j3);
- /* alpha value */
- scol->col[3]= (l*((float)cp3[0]) - u*((float)cp1[0]) - v*((float)cp2[0]))/255.0f;
-
- /* try to prevent invalid color sampling of zero alpha points */
- if (!cp1[0]) cp1 = cp2; if (!cp1[0]) cp1 = cp3;
- if (!cp2[0]) cp2 = cp1; if (!cp2[0]) cp2 = cp3;
- if (!cp3[0]) cp3 = cp1; if (!cp3[0]) cp3 = cp2;
-
- /* sample color value */
- scol->col[0]= (l*((float)cp3[3]) - u*((float)cp1[3]) - v*((float)cp2[3]))/255.0f;
- scol->col[1]= (l*((float)cp3[2]) - u*((float)cp1[2]) - v*((float)cp2[2]))/255.0f;
- scol->col[2]= (l*((float)cp3[1]) - u*((float)cp1[1]) - v*((float)cp2[1]))/255.0f;
+ /* alpha values */
+ a[0] = ((float)cp1[0])/255.f;
+ a[1] = ((float)cp2[0])/255.f;
+ a[2] = ((float)cp3[0])/255.f;
+ scol->col[3]= l*a[2] - u*a[0] - v*a[1];
+
+ /* sample premultiplied color value */
+ scol->col[0]= (l*((float)cp3[3])*a[2] - u*((float)cp1[3])*a[0] - v*((float)cp2[3])*a[1])/255.f;
+ scol->col[1]= (l*((float)cp3[2])*a[2] - u*((float)cp1[2])*a[0] - v*((float)cp2[2])*a[1])/255.f;
+ scol->col[2]= (l*((float)cp3[1])*a[2] - u*((float)cp1[1])*a[0] - v*((float)cp2[1])*a[1])/255.f;
+
+ /* if not zero alpha, restore non-multiplied color */
+ if (scol->col[3]) {
+ mul_v3_fl(scol->col, 1.0f/scol->col[3]);
+ }
}
if(shi->totcol) {
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index 0056b073c81..eece830f5b9 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -874,10 +874,10 @@ void shade_color(ShadeInput *shi, ShadeResult *shr)
shi->alpha= shi->vcol[3];
}
else if(ma->mode & (MA_VERTEXCOLP)) {
- float inv_alpha = 1.0f - shi->vcol[3];
- shi->r= shi->r*inv_alpha + shi->vcol[0]*shi->vcol[3];
- shi->g= shi->g*inv_alpha + shi->vcol[1]*shi->vcol[3];
- shi->b= shi->b*inv_alpha + shi->vcol[2]*shi->vcol[3];
+ float neg_alpha = 1.0f - shi->vcol[3];
+ shi->r= shi->r*neg_alpha + shi->vcol[0]*shi->vcol[3];
+ shi->g= shi->g*neg_alpha + shi->vcol[1]*shi->vcol[3];
+ shi->b= shi->b*neg_alpha + shi->vcol[2]*shi->vcol[3];
}
if(ma->texco)
@@ -1671,10 +1671,10 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
shi->alpha= shi->vcol[3];
}
else if(ma->mode & (MA_VERTEXCOLP)) {
- float inv_alpha = 1.0f - shi->vcol[3];
- shi->r= shi->r*inv_alpha + shi->vcol[0]*shi->vcol[3];
- shi->g= shi->g*inv_alpha + shi->vcol[1]*shi->vcol[3];
- shi->b= shi->b*inv_alpha + shi->vcol[2]*shi->vcol[3];
+ float neg_alpha = 1.0f - shi->vcol[3];
+ shi->r= shi->r*neg_alpha + shi->vcol[0]*shi->vcol[3];
+ shi->g= shi->g*neg_alpha + shi->vcol[1]*shi->vcol[3];
+ shi->b= shi->b*neg_alpha + shi->vcol[2]*shi->vcol[3];
}
if(ma->texco){
do_material_tex(shi);