diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index b9adaf2c887..2aa6cc10468 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -275,7 +275,7 @@ typedef struct ObjectInstanceRen { Object *ob, *par; int index, psysindex, lay; - float mat[4][4], imat[3][3]; + float mat[4][4], nmat[3][3]; /* nmat is inverse mat tranposed */ short flag; float dupliorco[3], dupliuv[2]; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index d9708a6c50b..ddceb6a52c5 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -4164,7 +4164,8 @@ static void find_dupli_instances(Render *re, ObjectRen *obr) Mat4MulMat4(obi->mat, imat, obimat); Mat3CpyMat4(nmat, obi->mat); - Mat3Inv(obi->imat, nmat); + Mat3Inv(obi->nmat, nmat); + Mat3Transp(obi->nmat); if(!first) { re->totvert += obr->totvert; @@ -4193,7 +4194,8 @@ static void assign_dupligroup_dupli(Render *re, ObjectInstanceRen *obi, ObjectRe Mat4MulMat4(obi->mat, imat, obimat); Mat3CpyMat4(nmat, obi->mat); - Mat3Inv(obi->imat, nmat); + Mat3Inv(obi->nmat, nmat); + Mat3Transp(obi->nmat); re->totvert += obr->totvert; re->totvlak += obr->totvlak; @@ -5511,7 +5513,6 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob) /* renderdata setup and exceptions */ re->r= scene->r; - re->r.mode &= ~R_OSA; re->flag |= R_GLOB_NOPUNOFLIP; re->excludeob= actob; if(type == RE_BAKE_LIGHT) diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index f556f482463..eb106591096 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -245,7 +245,8 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode) Mat4One(obi->mat); Mat3CpyMat4(cmat, obi->mat); - Mat3Inv(obi->imat, cmat); + Mat3Inv(obi->nmat, cmat); + Mat3Transp(obi->nmat); /* indicate the renderer has to use transform matrices */ if(mode==0) diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index 039faf119df..a4d75c032e5 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -324,17 +324,8 @@ static void occ_face(const OccFace *face, float *co, float *normal, float *area) normal[1]= -vlr->n[1]; normal[2]= -vlr->n[2]; - if(obi->flag & R_TRANSFORMED) { - float xn, yn, zn, (*imat)[3]= obi->imat; - - xn= normal[0]; - yn= normal[1]; - zn= normal[2]; - - normal[0]= imat[0][0]*xn + imat[0][1]*yn + imat[0][2]*zn; - normal[1]= imat[1][0]*xn + imat[1][1]*yn + imat[1][2]*zn; - normal[2]= imat[2][0]*xn + imat[2][1]*yn + imat[2][2]*zn; - } + if(obi->flag & R_TRANSFORMED) + Mat3MulVecfl(obi->nmat, normal); } if(area) { diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index cab825888a1..38991ed6d43 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -29,6 +29,7 @@ /* system includes */ #include #include +#include #include /* External modules: */ @@ -1800,6 +1801,8 @@ typedef struct BakeShade { int usemask; char *rect_mask; /* bake pixel mask */ + + float dxco[3], dyco[3]; } BakeShade; /* bake uses a char mask to know what has been baked */ @@ -1899,6 +1902,7 @@ static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInpu shi->xs= x; shi->ys= y; + shade_input_set_uv(shi); shade_input_set_normals(shi); /* no normal flip */ @@ -2081,6 +2085,55 @@ static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *start, flo return hit; } +static void bake_set_vlr_dxyco(BakeShade *bs, float *uv1, float *uv2, float *uv3) +{ + VlakRen *vlr= bs->vlr; + float A, d1, d2, d3, *v1, *v2, *v3; + + if(bs->quad) { + v1= vlr->v1->co; + v2= vlr->v3->co; + v3= vlr->v4->co; + } + else { + v1= vlr->v1->co; + v2= vlr->v2->co; + v3= vlr->v3->co; + } + + /* formula derived from barycentric coordinates: + * (uvArea1*v1 + uvArea2*v2 + uvArea3*v3)/uvArea + * then taking u and v partial derivatives to get dxco and dyco */ + A= (uv2[0] - uv1[0])*(uv3[1] - uv1[1]) - (uv3[0] - uv1[0])*(uv2[1] - uv1[1]); + + if(fabs(A) > FLT_EPSILON) { + A= 0.5f/A; + + d1= uv2[1] - uv3[1]; + d2= uv3[1] - uv1[1]; + d3= uv1[1] - uv2[1]; + bs->dxco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A; + bs->dxco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A; + bs->dxco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A; + + d1= uv3[0] - uv2[0]; + d2= uv1[0] - uv3[0]; + d3= uv2[0] - uv1[0]; + bs->dyco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A; + bs->dyco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A; + bs->dyco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A; + } + else { + bs->dxco[0]= bs->dxco[1]= bs->dxco[2]= 0.0f; + bs->dyco[0]= bs->dyco[1]= bs->dyco[2]= 0.0f; + } + + if(bs->obi->flag & R_TRANSFORMED) { + Mat3MulVecfl(bs->obi->nmat, bs->dxco); + Mat3MulVecfl(bs->obi->nmat, bs->dyco); + } +} + static void do_bake_shade(void *handle, int x, int y, float u, float v) { BakeShade *bs= handle; @@ -2118,6 +2171,9 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) if(obi->flag & R_TRANSFORMED) Mat4MulVecfl(obi->mat, shi->co); + VECCOPY(shi->dxco, bs->dxco); + VECCOPY(shi->dyco, bs->dyco); + quad= bs->quad; bake_set_shade_input(obi, vlr, shi, quad, 0, x, y, u, v); @@ -2302,10 +2358,12 @@ static void shade_tface(BakeShade *bs) /* UV indices have to be corrected for possible quad->tria splits */ i1= 0; i2= 1; i3= 2; vlr_set_uv_indices(vlr, &i1, &i2, &i3); + bake_set_vlr_dxyco(bs, vec[i1], vec[i2], vec[i3]); zspan_scanconvert(bs->zspan, bs, vec[i1], vec[i2], vec[i3], do_bake_shade); if(vlr->v4) { bs->quad= 1; + bake_set_vlr_dxyco(bs, vec[0], vec[2], vec[3]); zspan_scanconvert(bs->zspan, bs, vec[0], vec[2], vec[3], do_bake_shade); } } diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 9d3fa35eebb..eae112c52ca 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -442,18 +442,13 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr) int RE_vlakren_get_normal(Render *re, ObjectInstanceRen *obi, VlakRen *vlr, float *nor) { float xn, yn, zn, v1[3]; - float (*imat)[3]= obi->imat; + float (*nmat)[3]= obi->nmat; int flipped= 0; if(obi->flag & R_TRANSFORMED) { - xn= vlr->n[0]; - yn= vlr->n[1]; - zn= vlr->n[2]; + VECCOPY(nor, vlr->n); - /* transpose! */ - nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn; - nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn; - nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn; + Mat3MulVecfl(nmat, nor); Normalize(nor); } else @@ -1332,7 +1327,8 @@ ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, if(mat) { Mat4CpyMat4(obi->mat, mat); Mat3CpyMat4(mat3, mat); - Mat3Inv(obi->imat, mat3); + Mat3Inv(obi->nmat, mat3); + Mat3Transp(obi->nmat); obi->flag |= R_DUPLI_TRANSFORMED; } diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 49d09ac12aa..85b35804d93 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -217,19 +217,6 @@ void vlr_set_uv_indices(VlakRen *vlr, int *i1, int *i2, int *i3) } } -static void normal_transform(float imat[][3], float *nor) -{ - float xn, yn, zn; - - xn= nor[0]; - yn= nor[1]; - zn= nor[2]; - - nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn; - nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn; - nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn; -} - /* copy data from face to ShadeInput, general case */ /* indices 0 1 2 3 only */ void shade_input_set_triangle_i(ShadeInput *shi, ObjectInstanceRen *obi, VlakRen *vlr, short i1, short i2, short i3) @@ -269,9 +256,9 @@ void shade_input_set_triangle_i(ShadeInput *shi, ObjectInstanceRen *obi, VlakRen VECCOPY(shi->n3, shi->v3->n); if(obi->flag & R_TRANSFORMED) { - normal_transform(obi->imat, shi->n1); - normal_transform(obi->imat, shi->n2); - normal_transform(obi->imat, shi->n3); + Mat3MulVecfl(obi->nmat, shi->n1); + Mat3MulVecfl(obi->nmat, shi->n2); + Mat3MulVecfl(obi->nmat, shi->n3); } if(!(vlr->flag & (R_NOPUNOFLIP|R_TANGENT))) { @@ -858,7 +845,7 @@ void shade_input_set_shade_texco(ShadeInput *shi) shi->tang[2]= (tl*s3[2] - tu*s1[2] - tv*s2[2]); if(obi->flag & R_TRANSFORMED) - normal_transform(obi->imat, shi->tang); + Mat3MulVecfl(obi->nmat, shi->tang); Normalize(shi->tang); VECCOPY(shi->nmaptang, shi->tang); @@ -878,7 +865,7 @@ void shade_input_set_shade_texco(ShadeInput *shi) shi->nmaptang[2]= (tl*s3[2] - tu*s1[2] - tv*s2[2]); if(obi->flag & R_TRANSFORMED) - normal_transform(obi->imat, shi->nmaptang); + Mat3MulVecfl(obi->nmat, shi->nmaptang); Normalize(shi->nmaptang); } @@ -891,7 +878,7 @@ void shade_input_set_shade_texco(ShadeInput *shi) if(surfnor) { VECCOPY(shi->surfnor, surfnor) if(obi->flag & R_TRANSFORMED) - normal_transform(obi->imat, shi->surfnor); + Mat3MulVecfl(obi->nmat, shi->surfnor); } else VECCOPY(shi->surfnor, shi->vn)