diff options
-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; |