diff options
author | Robert Wenzlaff <rwenzlaff@soylent-green.com> | 2004-01-05 11:44:49 +0300 |
---|---|---|
committer | Robert Wenzlaff <rwenzlaff@soylent-green.com> | 2004-01-05 11:44:49 +0300 |
commit | 22bfc207f37b9f87fc576a985b59a2652ef4ff25 (patch) | |
tree | 194654f92b73a58c4d1ce250709dfccf361fd0d2 | |
parent | 57a7dfe5a5e8bbbc1f682c342ad40c65b9517aff (diff) |
-First port of Displacement mapping from tuhopuu. Image textures not working
yet (R.vn and R.vlr no longer exist, and were needed to get the image mapped
right). Works esp. well with Subsurfs. Sensitive to vertex normal issues
in Simple and Mesh modes.
-Also porting Simple Subdivide. Subdivides mesh at rendertime w/o changing
shape, for smooth displace and Radiosity.
-Removed an unused var from KnifeSubdivide.
-rw-r--r-- | source/blender/blenkernel/intern/subsurf.c | 106 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_material_types.h | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_mesh_types.h | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_texture_types.h | 1 | ||||
-rw-r--r-- | source/blender/render/extern/include/render_types.h | 1 | ||||
-rw-r--r-- | source/blender/renderconverter/intern/convertBlenderScene.c | 155 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 3 | ||||
-rw-r--r-- | source/blender/src/buttons_shading.c | 25 | ||||
-rw-r--r-- | source/blender/src/editmesh.c | 2 |
9 files changed, 273 insertions, 22 deletions
diff --git a/source/blender/blenkernel/intern/subsurf.c b/source/blender/blenkernel/intern/subsurf.c index 4df97851fd9..a7913c68a50 100644 --- a/source/blender/blenkernel/intern/subsurf.c +++ b/source/blender/blenkernel/intern/subsurf.c @@ -610,6 +610,107 @@ static void hypermesh_subdivide(HyperMesh *me, HyperMesh *nme) { } } +/* Simple subdivition surface for radio and displacement */ +static void hypermesh_simple_subdivide(HyperMesh *me, HyperMesh *nme) { + HyperVert *v; + HyperEdge *e; + HyperFace *f; + LinkNode *link; + float co[3]; + int j, k, count; + + for (f= me->faces; f; f= f->next) { /* Adds vert at center of each existing face */ + Vec3CpyI(co, 0.0, 0.0, 0.0); + for (j=0; j<f->nverts; j++) Vec3Add(co, f->verts[j]->co); + Vec3MulN(co, (float)(1.0/f->nverts)); + + f->mid= hypermesh_add_vert(nme, co, NULL); + } + + for (e= me->edges; e; e= e->next) { /* Add vert in middle of each edge */ + Vec3AvgT(co, e->v[0]->co, e->v[1]->co); + e->ep= hypermesh_add_vert(nme, co, NULL); + } + + for (v= me->verts; v; v= v->next) { + v->nmv= hypermesh_add_vert(nme, v->co, v->orig); + } + + for (e= me->edges; e; e= e->next) { /* Add originam edges */ + hypermesh_add_edge(nme, e->v[0]->nmv, e->ep, e->flag); + hypermesh_add_edge(nme, e->v[1]->nmv, e->ep, e->flag); + } + + for (f= me->faces; f; f= f->next) { + int last= f->nverts-1; + unsigned char vcol_mid[4]; + unsigned char vcol_edge[4][4]; + float uvco_mid[2]; + float uvco_edge[4][4]; + + if (me->hasvcol) { + int t[4]= {0, 0, 0, 0}; + for (j=0; j<f->nverts; j++) { + t[0]+= f->vcol[j][0]; + t[1]+= f->vcol[j][1]; + t[2]+= f->vcol[j][2]; + t[3]+= f->vcol[j][3]; + } + vcol_mid[0]= t[0]/f->nverts; + vcol_mid[1]= t[1]/f->nverts; + vcol_mid[2]= t[2]/f->nverts; + vcol_mid[3]= t[3]/f->nverts; + + for (j=0; j<f->nverts; last= j, j++) + VColAvgT(vcol_edge[j], f->vcol[last], f->vcol[j]); + last= f->nverts-1; + } + if (me->hasuvco) { + Vec2CpyI(uvco_mid, 0.0, 0.0); + for (j=0; j<f->nverts; j++) + Vec2Add(uvco_mid, f->uvco[j]); + Vec2MulN(uvco_mid, (float)(1.0/f->nverts)); + + for (j=0; j<f->nverts; last= j, j++) + Vec2AvgT(uvco_edge[j], f->uvco[last], f->uvco[j]); + last= f->nverts-1; + } + + for (j=0; j<f->nverts; last=j, j++) { + HyperVert *nv[4]; + HyperFace *nf; + + nv[0]= f->verts[last]->nmv; + nv[1]= f->edges[j]->ep; + nv[2]= f->mid; + nv[3]= f->edges[last]->ep; + + nf= hypermesh_add_face(nme, nv, 4, 0); + nf->orig= f->orig; + + if (me->hasvcol) { + nf->vcol= BLI_memarena_alloc(nme->arena, sizeof(*nf->vcol)*4); + + for (k=0; k<4; k++) { + nf->vcol[0][k]= f->vcol[last][k]; + nf->vcol[1][k]= vcol_edge[j][k]; + nf->vcol[2][k]= vcol_mid[k]; + nf->vcol[3][k]= vcol_edge[last][k]; + } + } + if (me->hasuvco) { + nf->uvco= BLI_memarena_alloc(nme->arena, sizeof(*nf->uvco)*4); + + Vec2Cpy(nf->uvco[0], f->uvco[last]); + Vec2Cpy(nf->uvco[1], uvco_edge[j]); + Vec2Cpy(nf->uvco[2], uvco_mid); + Vec2Cpy(nf->uvco[3], uvco_edge[last]); + } + } + } +} + + static void hypermesh_free(HyperMesh *me) { BLI_memarena_free(me->arena); @@ -914,9 +1015,10 @@ static DispList *subsurf_subdivide_to_displist(HyperMesh *hme, short subdiv, sho tmp->hasuvco= hme->hasuvco; tmp->orig_me= hme->orig_me; - hypermesh_subdivide(hme, tmp); - hypermesh_free(hme); + if (flag & ME_SIMPLE_DIV) hypermesh_simple_subdivide(hme, tmp); + else hypermesh_subdivide(hme, tmp); /* default to CC subdiv. */ + hypermesh_free(hme); hme= tmp; } diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index f81f79f2b25..92642c63437 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -172,6 +172,7 @@ typedef struct Material { #define MAP_HAR 256 #define MAP_RAYMIRR 512 #define MAP_TRANSLU 1024 +#define MAP_DISPLACE 4096 /* pr_type */ #define MA_FLAT 0 diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 3b69656464e..71c65d450bf 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -165,6 +165,7 @@ typedef struct Mesh { #define ME_SMESH 64 #define ME_SUBSURF 128 #define ME_OPT_EDGES 256 +#define ME_SIMPLE_DIV 512 /* puno = vertexnormal (mface) */ #define ME_FLIPV1 1 diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 7872e384079..ba95e2ecbed 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -228,6 +228,7 @@ typedef struct Tex { #define MAP_ALPHA 128 #define MAP_HAR 256 #define MAP_XTRA 512 +#define MAP_DISPLACE 4096 /* pr_type */ #define MA_FLAT 0 diff --git a/source/blender/render/extern/include/render_types.h b/source/blender/render/extern/include/render_types.h index 90eb7c4f058..536ce83a9ae 100644 --- a/source/blender/render/extern/include/render_types.h +++ b/source/blender/render/extern/include/render_types.h @@ -159,6 +159,7 @@ typedef struct VertRen void *svert; /* smooth vert, only used during initrender */ short clip, texofs; /* texofs= flag */ float accum; /* accum for radio weighting */ + short flag; } VertRen; /* ------------------------------------------------------------------------- */ diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c index 9bccd128a5c..266194c5e01 100644 --- a/source/blender/renderconverter/intern/convertBlenderScene.c +++ b/source/blender/renderconverter/intern/convertBlenderScene.c @@ -144,6 +144,12 @@ static int test_flipnorm(float *v1, float *v2, float *v3, VlakRen *vlr, float im static void init_render_object(Object *ob); static HaloRen *initstar(float *vec, float hasize); +/* Displacement Texture */ +void displace_render_face(VlakRen *vlr, int tex, float scale); +void do_displacement(Object *ob, int startface, int numface, int startvert, int numvert); +short test_for_displace(Object *ob); +void displace_render_vert(VertRen *vr, MTex *mtex, short mask, float scale); + /* more prototypes for autosmoothing below */ @@ -1099,8 +1105,9 @@ static void init_render_displist_mesh(Object *ob) float xn, yn, zn; float mat[4][4], imat[3][3], *data, *nors, *orco=0, n1[3], flen; int a, b, flipnorm= -1, need_orco=0, startvert, p1, p2, p3, p4; - int old_totvert= R.totvert; - int old_totvlak= R.totvlak; + int old_totvert= R.totvert, numvert=0; + int old_totvlak= R.totvlak, numface=0; + short displace_chanels=0; me= ob->data; @@ -1123,6 +1130,9 @@ static void init_render_displist_mesh(Object *ob) } } + /* Test to see if there are displacement chanels */ + displace_chanels=test_for_displace(ob); + dl= me->disp.first; /* Force a displist rebuild if this is a subsurf and we have a different subdiv level */ @@ -1147,7 +1157,7 @@ static void init_render_displist_mesh(Object *ob) while(dl) { if(dl->type==DL_SURF) { startvert= R.totvert; - a= dl->nr*dl->parts; + numvert = a = dl->nr*dl->parts; data= dl->verts; nors= dl->nors; @@ -1195,6 +1205,7 @@ static void init_render_displist_mesh(Object *ob) flen= CalcNormFloat4(v1->co, v3->co, v4->co, v2->co, n1); if(flen!=0.0) { + numface++; vlr= RE_findOrAddVlak(R.totvlak++); vlr->ob= ob; vlr->v1= v1; @@ -1233,6 +1244,8 @@ static void init_render_displist_mesh(Object *ob) int i; startvert= R.totvert; + numvert=dlm->totvert; + for (i=0; i<dlm->totvert; i++) { MVert *mv= &dlm->mvert[i]; @@ -1274,6 +1287,7 @@ static void init_render_displist_mesh(Object *ob) } if(flen!=0.0) { + numface++; vlr= RE_findOrAddVlak(R.totvlak++); vlr->ob= ob; vlr->v1= v1; @@ -1310,8 +1324,11 @@ static void init_render_displist_mesh(Object *ob) dl= dl->next; } - - + + if (displace_chanels) { + do_displacement(ob, old_totvlak, numface, old_totvert, numvert ); + } + normalenrender(old_totvert, old_totvlak); } @@ -1510,7 +1527,9 @@ static void init_render_mesh(Object *ob) float *extverts=0, *orco; int a, a1, ok, do_puno, need_orco=0, totvlako, totverto, vertofs; int start, end, flipnorm, do_autosmooth=0; - + short displace_chanels=0; + int startface, numface=0; + me= ob->data; if (rendermesh_uses_displist(me) && me->subdivr>0) { init_render_displist_mesh(ob); @@ -1554,6 +1573,9 @@ static void init_render_mesh(Object *ob) } } + /* Test to see if there are displacement chanels */ + displace_chanels=test_for_displace(ob); + if(me->orco==0) { need_orco= 0; for(a=1; a<=ob->totcol; a++) { @@ -1767,6 +1789,11 @@ static void init_render_mesh(Object *ob) } } + if (displace_chanels) { + do_displacement(ob, totvlako, end, totverto, me->totvert ); + do_puno=1; + } + if(do_autosmooth || (me->flag & ME_AUTOSMOOTH)) { autosmooth(totverto, totvlako, me->smoothresh); do_puno= 1; @@ -3090,3 +3117,119 @@ void RE_rotateBlenderScene(void) set_normalflags(); } + +/* **************************************************************** */ +/* Displacement mapping */ +/* **************************************************************** */ +extern float Tin, Tr, Tg, Tb; + +short test_for_displace(Object *ob){ +/* Produce bitfield indicating which textures are displacement textures. */ + Material *ma; + short result = 0; + int i, j; + + for (i=1; i<=ob->totcol; i++) { + ma=give_render_material(ob, i); + if (ma) for(j=0; j<8; j++){ + if (ma->mtex[j] && (ma->mtex[j]->mapto & MAP_DISPLACE)){ + result |= 1<<j; + } + } + } + return result; +} + + +void do_displacement(Object *ob, int startface, int numface, int startvert, int numvert ){ + + int i, j; + Material *ma; + MTex *mtex; + float co[3]={0,0,0}, min[3]={1e9, 1e9, 1e9}, max[3]={-1e9, -1e9, -1e9}; + float scale=1.0f; + VertRen *vr; + VlakRen *vlr; + Mesh *me; + + minmax_object(ob, min, max); + VecSubf(min, max, min); + scale=MAX3(min[0], min[1], min[2]); /*Overall scale of obj */ + + /* calculate vertex normals */ + //normalenrender(startvert, startface); + + for(i=startvert; i<startvert+numvert; i++){ /* Clear vert flags */ + vr=RE_findOrAddVert(i); + vr->flag=0; + } + + for(i=startface; i<startface+numface; i++){ + vlr=RE_findOrAddVlak(i); + + for(j=0; j<8; j++){ + mtex = vlr->mat->mtex[j]; + if ((mtex)&&( vlr->mat->mtex[j]->mapto & MAP_DISPLACE ) ) displace_render_face(vlr, j, scale); + } + + /* Recaluclate the face normal */ + if(vlr->v4) vlr->len= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, + vlr->v1->co, vlr->n); + else vlr->len= CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, + vlr->n); + + } +} + +void displace_render_face(VlakRen *vlr, int tex, float scale){ + + MTex *mtex; + int mask; + float dp; + + VlakRen vlr2; + VertRen vr; + + mask = 1<<tex; /* Displace vert once per displace texture channel */ + mtex=vlr->mat->mtex[tex]; + + //VECCOPY(R.vn, vlr->n); /* extertex() needs face/puno */ + //R.vlr=vlr; + + /* Displace the verts */ + + if (! (vlr->v1->flag & mask)) displace_render_vert(vlr->v1, mtex, mask, scale); + + if (! (vlr->v2->flag & mask) ) displace_render_vert(vlr->v2, mtex, mask, scale); + + if (! (vlr->v3->flag & mask)) displace_render_vert(vlr->v3, mtex, mask, scale); + + if (vlr->v4) { + if (!(vlr->v4->flag & mask)) displace_render_vert(vlr->v4, mtex, mask, scale); + } +} + +void displace_render_vert(VertRen *vr, MTex *mtex, short mask, float scale){ + + float co[3]={0,0,0}, dp, sample[3]; + + if ((mtex->texco & TEXCO_ORCO) && (vr->orco)) { + VECCOPY(co, vr->orco); + } + else if ((mtex->texco & TEXCO_STICKY) && (vr->sticky)) { + VECCOPY(co, vr->sticky); + } + else if (mtex->texco & TEXCO_GLOB) { + /* VECCOPY(co, vr->co); Interesting, but not right. */ + + } + + externtex(mtex, co); + + vr->co[0]+=0.25*(Tin-0.5) * vr->n[0] * mtex->varfac *scale ; + vr->co[1]+=0.25*(Tin-0.5) * vr->n[1] * mtex->varfac *scale ; + vr->co[2]+=0.25*(Tin-0.5) * vr->n[2] * mtex->varfac *scale ; + + vr->flag |= mask; + +} diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 4197a80d1f8..ee7679a478b 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -379,7 +379,8 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me) uiBlockBeginAlign(block); uiBlockSetCol(block, TH_BUT_SETTING1); - uiDefButS(block, TOG|BIT|7, B_MAKEDISP, "SubSurf", 10,124,154,19, &me->flag, 0, 0, 0, 0, "Treats the active object as a Catmull-Clark Subdivision Surface"); + uiDefButS(block, TOG|BIT|7, B_MAKEDISP, "SubSurf", 10,124,90,19, &me->flag, 0, 0, 0, 0, "Treats the active object as a Catmull-Clark Subdivision Surface"); + uiDefButS(block, TOG|BIT|9, B_MAKEDISP, "Simple", 100,124,64,19, &me->flag, 0, 0, 0, 0, "Treats the active object as a Simple Subdivision Surface for Radio/Displacement"); uiBlockSetCol(block, TH_AUTO); uiDefButS(block, NUM, B_MAKEDISP, "Subdiv:", 10,104,110,19, &me->subdiv, 0, 6, 0, 0, "Defines the level of subdivision to display in real time interactively"); uiDefButS(block, NUM, B_MAKEDISP, "", 120, 104, 44, 19, &me->subdivr, 0, 6, 0, 0, "Defines the level of subdivision to apply during rendering"); diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index 87a85d1bf19..a10dea000b8 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -2118,18 +2118,19 @@ static void material_panel_map_to(Material *ma) /* MAP TO */ uiBlockBeginAlign(block); - uiDefButS(block, TOG|BIT|0, B_MATPRV, "Col", 900,180,73,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect basic colour of the material"); - uiDefButS(block, TOG3|BIT|1, B_MATPRV, "Nor", 973,180,73,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the rendered normal"); - uiDefButS(block, TOG|BIT|2, B_MATPRV, "Csp", 1046,180,73,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the specularity colour"); - uiDefButS(block, TOG|BIT|3, B_MATPRV, "Cmir", 1119,180,73,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affext the mirror colour"); - uiDefButS(block, TOG3|BIT|4, B_MATPRV, "Ref", 1192,180,74,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the value of the materials reflectivity"); - - uiDefButS(block, TOG3|BIT|5, B_MATPRV, "Spec", 900,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the value of specularity"); - uiDefButS(block, TOG3|BIT|8, B_MATPRV, "Hard", 960,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the hardness value"); - uiDefButS(block, TOG3|BIT|9, B_MATPRV, "RayMir",1020,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the ray-mirror value"); - uiDefButS(block, TOG3|BIT|7, B_MATPRV, "Alpha", 1080,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the alpha value"); - uiDefButS(block, TOG3|BIT|6, B_MATPRV, "Emit", 1140,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the emit value"); - uiDefButS(block, TOG3|BIT|10, B_MATPRV, "Translu",1200,160,63,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the translucency value"); + uiDefButS(block, TOG|BIT|0, B_MATPRV, "Col", 900,180,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect basic colour of the material"); + uiDefButS(block, TOG3|BIT|1, B_MATPRV, "Nor", 960,180,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the rendered normal"); + uiDefButS(block, TOG|BIT|2, B_MATPRV, "Csp", 1020,180,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the specularity colour"); + uiDefButS(block, TOG|BIT|3, B_MATPRV, "Cmir", 1080,180,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affext the mirror colour"); + uiDefButS(block, TOG3|BIT|4, B_MATPRV, "Ref", 1140,180,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the value of the materials reflectivity"); + uiDefButS(block, TOG3|BIT|5, B_MATPRV, "Spec", 1200,180,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the value of specularity"); + + uiDefButS(block, TOG3|BIT|8, B_MATPRV, "Hard", 900,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the hardness value"); + uiDefButS(block, TOG3|BIT|9, B_MATPRV, "RayMir",960,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the ray-mirror value"); + uiDefButS(block, TOG3|BIT|7, B_MATPRV, "Alpha", 1020,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the alpha value"); + uiDefButS(block, TOG3|BIT|6, B_MATPRV, "Emit", 1080,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the emit value"); + uiDefButS(block, TOG3|BIT|10, B_MATPRV, "Translu",1140,160,65,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the translucency value"); + uiDefButS(block, TOG|BIT|12, B_MATPRV, "Disp", 1205,160,55,19, &(mtex->mapto), 0, 0, 0, 0, "Let the texture displace the surface"); uiBlockBeginAlign(block); uiDefButS(block, ROW, B_MATPRV, "Mix", 1087,120,48,18, &(mtex->blendtype), 9.0, (float)MTEX_BLEND, 0, 0, "Sets texture to blend the values or colour"); diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 68d23189863..0d0cecfa717 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -7410,7 +7410,7 @@ CutCurve *get_mouse_trail(int *len, char mode){ void KnifeSubdivide(char mode){ int oldcursor, len=0; - short isect=0, aligned=0; + short isect=0; CutCurve *curve; EditEdge *eed; Window *win; |