-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.
This commit is contained in:
2004-01-05 08:44:49 +00:00
parent 57a7dfe5a5
commit 22bfc207f3
9 changed files with 273 additions and 22 deletions

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
/* ------------------------------------------------------------------------- */

View File

@@ -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;
@@ -1311,6 +1325,9 @@ 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,6 +1527,8 @@ 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) {
@@ -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;
}

View File

@@ -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");

View File

@@ -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, 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|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, 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");

View File

@@ -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;