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
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2011-03-20 16:35:35 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2011-03-20 16:35:35 +0300
commit549b5e1222fcda5ca9b7d1892ca4d05e2c62c066 (patch)
treef69a4a833a3eb092530bb0d7959e43cf05ca0362 /source
parenta50cdf713a800c07629495f0d5e7124cddbbc2c9 (diff)
Fix/change in normal computation, now the viewport uses the same angle
weighted normals as the render engine, and the render engine will copy normals from the mesh rather than always recalculating them. Subsurf/multires still use regular vertex normals, but they are expected to be sufficiently high resolution to not need this. This means that normal maps displayed in the viewport actually match the render engine exactly and don't have artifacts due to this discrepancy. It of course also avoids unexpected surprises where your render normals look different than your viewport normals. Subversion bumped to 4 for version patch to recalculate normals. Patch by Morten Mikkelsen, with some small changes.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h2
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c38
-rw-r--r--source/blender/blenkernel/intern/mesh.c45
-rw-r--r--source/blender/blenlib/BLI_math_geom.h6
-rw-r--r--source/blender/blenlib/intern/math_geom.c43
-rw-r--r--source/blender/blenloader/intern/readfile.c7
-rw-r--r--source/blender/editors/mesh/editmesh_lib.c25
-rw-r--r--source/blender/render/intern/source/convertblender.c113
9 files changed, 186 insertions, 95 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 857c88a6004..55ade5fe5d9 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -206,7 +206,7 @@ struct DerivedMesh {
/* Fill the array (of length .getNumVerts()) with all vertex locations */
void (*getVertCos)(DerivedMesh *dm, float (*cos_r)[3]);
- /* Get vertex normal, undefined if index is not valid */
+ /* Get smooth vertex normal, undefined if index is not valid */
void (*getVertNo)(DerivedMesh *dm, int index, float no_r[3]);
/* Get a map of vertices to faces
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 6cbc49e19c8..2bba079d605 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -44,7 +44,7 @@ extern "C" {
* and keep comment above the defines.
* Use STRINGIFY() rather then defining with quotes */
#define BLENDER_VERSION 256
-#define BLENDER_SUBVERSION 3
+#define BLENDER_SUBVERSION 4
#define BLENDER_MINVERSION 250
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 407d2ded085..b7034a7db8a 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1798,7 +1798,7 @@ void CDDM_calc_normals(DerivedMesh *dm)
int i;
int numVerts = dm->numVertData;
int numFaces = dm->numFaceData;
- MFace *mf;
+ MFace *mfaces;
MVert *mv;
if(numVerts == 0) return;
@@ -1817,27 +1817,43 @@ void CDDM_calc_normals(DerivedMesh *dm)
NULL, dm->numFaceData);
/* calculate face normals and add to vertex normals */
- mf = CDDM_get_faces(dm);
- for(i = 0; i < numFaces; i++, mf++) {
+ mfaces = CDDM_get_faces(dm);
+ for(i = 0; i < numFaces; i++) {
+ MFace * mf = &mfaces[i];
float *f_no = face_nors[i];
if(mf->v4)
- normal_quad_v3( f_no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
+ normal_quad_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
else
- normal_tri_v3( f_no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
+ normal_tri_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
- add_v3_v3(temp_nors[mf->v1], f_no);
- add_v3_v3(temp_nors[mf->v2], f_no);
- add_v3_v3(temp_nors[mf->v3], f_no);
- if(mf->v4)
- add_v3_v3(temp_nors[mf->v4], f_no);
+ if((mf->flag&ME_SMOOTH)!=0) {
+ float *n4 = (mf->v4)? temp_nors[mf->v4]: NULL;
+ float *c4 = (mf->v4)? mv[mf->v4].co: NULL;
+
+ accumulate_vertex_normals(temp_nors[mf->v1], temp_nors[mf->v2], temp_nors[mf->v3], n4,
+ f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, c4);
+ }
+ }
+
+ for(i = 0; i < numFaces; i++) {
+ MFace * mf = &mfaces[i];
+
+ if((mf->flag&ME_SMOOTH)==0) {
+ float *f_no = face_nors[i];
+
+ if(is_zero_v3(temp_nors[mf->v1])) copy_v3_v3(temp_nors[mf->v1], f_no);
+ if(is_zero_v3(temp_nors[mf->v2])) copy_v3_v3(temp_nors[mf->v2], f_no);
+ if(is_zero_v3(temp_nors[mf->v3])) copy_v3_v3(temp_nors[mf->v3], f_no);
+ if(mf->v4 && is_zero_v3(temp_nors[mf->v4])) copy_v3_v3(temp_nors[mf->v4], f_no);
+ }
}
/* normalize vertex normals and assign */
for(i = 0; i < numVerts; i++, mv++) {
float *no = temp_nors[i];
- if (normalize_v3(no) == 0.0)
+ if(normalize_v3(no) == 0.0f)
normalize_v3_v3(no, mv->co);
normal_float_to_short_v3(mv->no, no);
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 247e48a5576..1e29f5c9d3f 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1278,26 +1278,42 @@ void mesh_calc_normals(MVert *mverts, int numVerts, MFace *mfaces, int numFaces,
float *fnors= MEM_callocN(sizeof(*fnors)*3*numFaces, "meshnormals");
int i;
- for (i=0; i<numFaces; i++) {
+ for(i=0; i<numFaces; i++) {
MFace *mf= &mfaces[i];
float *f_no= &fnors[i*3];
- if (mf->v4)
- normal_quad_v3( f_no,mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co, mverts[mf->v4].co);
+ if(mf->v4)
+ normal_quad_v3(f_no, mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co, mverts[mf->v4].co);
else
- normal_tri_v3( f_no,mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co);
-
- add_v3_v3(tnorms[mf->v1], f_no);
- add_v3_v3(tnorms[mf->v2], f_no);
- add_v3_v3(tnorms[mf->v3], f_no);
- if (mf->v4)
- add_v3_v3(tnorms[mf->v4], f_no);
+ normal_tri_v3(f_no, mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co);
+
+ if((mf->flag&ME_SMOOTH)!=0) {
+ float *n4 = (mf->v4)? tnorms[mf->v4]: NULL;
+ float *c4 = (mf->v4)? mverts[mf->v4].co: NULL;
+
+ accumulate_vertex_normals(tnorms[mf->v1], tnorms[mf->v2], tnorms[mf->v3], n4,
+ f_no, mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co, c4);
+ }
+ }
+
+ for(i=0; i<numFaces; i++) {
+ MFace *mf= &mfaces[i];
+
+ if((mf->flag&ME_SMOOTH)==0) {
+ float *f_no= &fnors[i*3];
+ if(is_zero_v3(tnorms[mf->v1])) copy_v3_v3(tnorms[mf->v1], f_no);
+ if(is_zero_v3(tnorms[mf->v2])) copy_v3_v3(tnorms[mf->v2], f_no);
+ if(is_zero_v3(tnorms[mf->v3])) copy_v3_v3(tnorms[mf->v3], f_no);
+ if(mf->v4 && is_zero_v3(tnorms[mf->v4])) copy_v3_v3(tnorms[mf->v4], f_no);
+ }
}
- for (i=0; i<numVerts; i++) {
+
+ /* following Mesh convention; we use vertex coordinate itself for normal in this case */
+ for(i=0; i<numVerts; i++) {
MVert *mv= &mverts[i];
float *no= tnorms[i];
- if (normalize_v3(no)==0.0)
+ if(normalize_v3(no) == 0.0f)
normalize_v3_v3(no, mv->co);
normal_float_to_short_v3(mv->no, no);
@@ -1305,11 +1321,10 @@ void mesh_calc_normals(MVert *mverts, int numVerts, MFace *mfaces, int numFaces,
MEM_freeN(tnorms);
- if (faceNors_r) {
+ if(faceNors_r)
*faceNors_r = fnors;
- } else {
+ else
MEM_freeN(fnors);
- }
}
float (*mesh_getVertexCos(Mesh *me, int *numVerts_r))[3]
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index 8d2f9ffa38b..3174c65beac 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -169,6 +169,12 @@ void box_minmax_bounds_m4(float min[3], float max[3],
void map_to_tube(float *u, float *v, float x, float y, float z);
void map_to_sphere(float *u, float *v, float x, float y, float z);
+/********************************** Normals **********************************/
+
+void accumulate_vertex_normals(float n1[3], float n2[3], float n3[3],
+ float n4[3], const float f_no[3], const float co1[3], const float co2[3],
+ const float co3[3], const float co4[3]);
+
/********************************* Tangents **********************************/
typedef struct VertexTangent {
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 6a3abc697e9..b0709c30494 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -1980,6 +1980,49 @@ void map_to_sphere(float *u, float *v,float x, float y, float z)
}
}
+/********************************* Normals **********************************/
+
+void accumulate_vertex_normals(float n1[3], float n2[3], float n3[3],
+ float n4[3], const float f_no[3], const float co1[3], const float co2[3],
+ const float co3[3], const float co4[3])
+{
+ float vdiffs[4][3];
+ const int nverts= (n4!=NULL && co4!=NULL)? 4: 3;
+
+ /* compute normalized edge vectors */
+ sub_v3_v3v3(vdiffs[0], co2, co1);
+ sub_v3_v3v3(vdiffs[1], co3, co2);
+
+ if(nverts==3) {
+ sub_v3_v3v3(vdiffs[2], co1, co3);
+ }
+ else {
+ sub_v3_v3v3(vdiffs[2], co4, co3);
+ sub_v3_v3v3(vdiffs[3], co1, co4);
+ normalize_v3(vdiffs[3]);
+ }
+
+ normalize_v3(vdiffs[0]);
+ normalize_v3(vdiffs[1]);
+ normalize_v3(vdiffs[2]);
+
+ /* accumulate angle weighted face normal */
+ {
+ float *vn[]= {n1, n2, n3, n4};
+ const float *prev_edge = vdiffs[nverts-1];
+ int i;
+
+ for(i=0; i<nverts; i++) {
+ const float *cur_edge= vdiffs[i];
+ const float fac= saacos(-dot_v3v3(cur_edge, prev_edge));
+
+ // accumulate
+ madd_v3_v3fl(vn[i], f_no, fac);
+ prev_edge = cur_edge;
+ }
+ }
+}
+
/********************************* Tangents **********************************/
/* For normal map tangents we need to detect uv boundaries, and only average
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 35aeb756274..9fe5fbb2a60 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -11551,6 +11551,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
+ if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile <4)){
+ Mesh *me;
+
+ for(me= main->mesh.first; me; me= me->id.next)
+ mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
+ }
+
/* put compatibility code here until next subversion bump */
{
diff --git a/source/blender/editors/mesh/editmesh_lib.c b/source/blender/editors/mesh/editmesh_lib.c
index 18706c0372e..384b311437b 100644
--- a/source/blender/editors/mesh/editmesh_lib.c
+++ b/source/blender/editors/mesh/editmesh_lib.c
@@ -2010,21 +2010,34 @@ void recalc_editnormals(EditMesh *em)
if(efa->v4) {
normal_quad_v3( efa->n,efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
cent_quad_v3(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
- add_v3_v3(efa->v4->no, efa->n);
}
else {
normal_tri_v3( efa->n,efa->v1->co, efa->v2->co, efa->v3->co);
cent_tri_v3(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co);
}
- add_v3_v3(efa->v1->no, efa->n);
- add_v3_v3(efa->v2->no, efa->n);
- add_v3_v3(efa->v3->no, efa->n);
+
+ if((efa->flag&ME_SMOOTH)!=0) {
+ float *n4= (efa->v4)? efa->v4->no: NULL;
+ float *c4= (efa->v4)? efa->v4->co: NULL;
+
+ accumulate_vertex_normals(efa->v1->no, efa->v2->no, efa->v3->no, n4,
+ efa->n, efa->v1->co, efa->v2->co, efa->v3->co, c4);
+ }
+ }
+
+ for(efa= em->faces.first; efa; efa=efa->next) {
+ if((efa->flag&ME_SMOOTH)==0) {
+ if(is_zero_v3(efa->v1->no)) copy_v3_v3(efa->v1->no, efa->n);
+ if(is_zero_v3(efa->v2->no)) copy_v3_v3(efa->v2->no, efa->n);
+ if(is_zero_v3(efa->v3->no)) copy_v3_v3(efa->v3->no, efa->n);
+ if(efa->v4 && is_zero_v3(efa->v4->no)) copy_v3_v3(efa->v4->no, efa->n);
+ }
}
/* following Mesh convention; we use vertex coordinate itself for normal in this case */
for(eve= em->verts.first; eve; eve=eve->next) {
- if (normalize_v3(eve->no)==0.0) {
- VECCOPY(eve->no, eve->co);
+ if(normalize_v3(eve->no) == 0.0f) {
+ copy_v3_v3(eve->no, eve->co);
normalize_v3(eve->no);
}
}
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index d7eb22b5fc7..f51ed550813 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -499,6 +499,11 @@ static void calc_tangent_vector(ObjectRen *obr, VertexTangent **vtangents, MemAr
}
+
+/****************************************************************
+************ tangent space generation interface *****************
+****************************************************************/
+
typedef struct
{
ObjectRen *obr;
@@ -594,53 +599,11 @@ static void calc_vertexnormals(Render *re, ObjectRen *obr, int do_tangent, int d
for(a=0; a<obr->totvlak; a++) {
VlakRen *vlr= RE_findOrAddVlak(obr, a);
if(vlr->flag & ME_SMOOTH) {
- VertRen *v1= vlr->v1;
- VertRen *v2= vlr->v2;
- VertRen *v3= vlr->v3;
- VertRen *v4= vlr->v4;
- float n1[3], n2[3], n3[3], n4[3];
- float fac1, fac2, fac3, fac4=0.0f;
-
- sub_v3_v3v3(n1, v2->co, v1->co);
- normalize_v3(n1);
- sub_v3_v3v3(n2, v3->co, v2->co);
- normalize_v3(n2);
- if(v4==NULL) {
- sub_v3_v3v3(n3, v1->co, v3->co);
- normalize_v3(n3);
-
- fac1= saacos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]);
- fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
- fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
- }
- else {
- sub_v3_v3v3(n3, v4->co, v3->co);
- normalize_v3(n3);
- sub_v3_v3v3(n4, v1->co, v4->co);
- normalize_v3(n4);
-
- fac1= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
- fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
- fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
- fac4= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]);
-
- v4->n[0] +=fac4*vlr->n[0];
- v4->n[1] +=fac4*vlr->n[1];
- v4->n[2] +=fac4*vlr->n[2];
- }
-
- v1->n[0] +=fac1*vlr->n[0];
- v1->n[1] +=fac1*vlr->n[1];
- v1->n[2] +=fac1*vlr->n[2];
-
- v2->n[0] +=fac2*vlr->n[0];
- v2->n[1] +=fac2*vlr->n[1];
- v2->n[2] +=fac2*vlr->n[2];
+ float *n4= (vlr->v4)? vlr->v4->n: NULL;
+ float *c4= (vlr->v4)? vlr->v4->co: NULL;
- v3->n[0] +=fac3*vlr->n[0];
- v3->n[1] +=fac3*vlr->n[1];
- v3->n[2] +=fac3*vlr->n[2];
-
+ accumulate_vertex_normals(vlr->v1->n, vlr->v2->n, vlr->v3->n, n4,
+ vlr->n, vlr->v1->co, vlr->v2->co, vlr->v3->co, c4);
}
if(do_nmap_tangent || do_tangent) {
/* tangents still need to be calculated for flat faces too */
@@ -652,17 +615,12 @@ static void calc_vertexnormals(Render *re, ObjectRen *obr, int do_tangent, int d
/* do solid faces */
for(a=0; a<obr->totvlak; a++) {
VlakRen *vlr= RE_findOrAddVlak(obr, a);
+
if((vlr->flag & ME_SMOOTH)==0) {
- float *f1= vlr->v1->n;
- if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
- f1= vlr->v2->n;
- if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
- f1= vlr->v3->n;
- if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
- if(vlr->v4) {
- f1= vlr->v4->n;
- if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
- }
+ if(is_zero_v3(vlr->v1->n)) VECCOPY(vlr->v1->n, vlr->n);
+ if(is_zero_v3(vlr->v2->n)) VECCOPY(vlr->v2->n, vlr->n);
+ if(is_zero_v3(vlr->v3->n)) VECCOPY(vlr->v3->n, vlr->n);
+ if(vlr->v4 && is_zero_v3(vlr->v4->n)) VECCOPY(vlr->v4->n, vlr->n);
}
if(do_nmap_tangent) {
@@ -3236,6 +3194,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
int a, a1, ok, vertofs;
int end, do_autosmooth=0, totvert = 0;
int use_original_normals= 0;
+ int recalc_normals = 0; // false by default
me= ob->data;
@@ -3313,6 +3272,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
ma= give_render_material(re, ob, 1);
+
if(ma->material_type == MA_TYPE_HALO) {
make_render_halos(re, obr, me, totvert, mvert, ma, orco);
}
@@ -3321,8 +3281,15 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
for(a=0; a<totvert; a++, mvert++) {
ver= RE_findOrAddVert(obr, obr->totvert++);
VECCOPY(ver->co, mvert->co);
- if(do_autosmooth==0) /* autosmooth on original unrotated data to prevent differences between frames */
+ if(do_autosmooth==0) { /* autosmooth on original unrotated data to prevent differences between frames */
+ ver->n[0]=mvert->no[0];
+ ver->n[1]=mvert->no[1];
+ ver->n[2]=mvert->no[2];
mul_m4_v3(mat, ver->co);
+ mul_transposed_m3_v3(imat, ver->n);
+ normalize_v3(ver->n);
+ negate_v3(ver->n);
+ }
if(orco) {
ver->orco= orco;
@@ -3339,6 +3306,10 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if(!timeoffset) {
/* store customdata names, because DerivedMesh is freed */
RE_set_customdata_names(obr, &dm->faceData);
+
+ /* add tangent layer if we need one */
+ if(need_nmap_tangent!=0 && CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1)
+ DM_add_tangent_layer(dm);
/* still to do for keys: the correct local texture coordinate */
@@ -3369,7 +3340,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if(ok) {
end= dm->getNumFaces(dm);
mface= dm->getFaceArray(dm);
-
+
for(a=0; a<end; a++, mface++) {
int v1, v2, v3, v4, flag;
@@ -3415,7 +3386,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
CustomDataLayer *layer;
MTFace *mtface, *mtf;
MCol *mcol, *mc;
- int index, mtfn= 0, mcn= 0;
+ int index, mtfn= 0, mcn= 0, mtng=0;
char *name;
for(index=0; index<dm->faceData.totlayer; index++) {
@@ -3432,6 +3403,22 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
mcol= (MCol*)layer->data;
memcpy(mc, &mcol[a*4], sizeof(MCol)*4);
}
+ else if(layer->type == CD_TANGENT && mtng < 1)
+ {
+ if(need_nmap_tangent!=0)
+ {
+ const float * tangent = (const float *) layer->data;
+ int t;
+ int nr_verts = v4!=0 ? 4 : 3;
+ float * ftang = RE_vlakren_get_nmap_tangent(obr, vlr, 1);
+ for(t=0; t<nr_verts; t++)
+ {
+ QUATCOPY(ftang+t*4, tangent+a*16+t*4);
+ mul_mat3_m4_v3(mat, ftang+t*4);
+ normalize_v3(ftang+t*4);
+ }
+ }
+ }
}
}
}
@@ -3447,6 +3434,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
MEdge *medge;
struct edgesort *edgetable;
int totedge= 0;
+ recalc_normals= 1;
medge= dm->getEdgeArray(dm);
@@ -3489,6 +3477,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if(!timeoffset) {
if (test_for_displace(re, ob ) ) {
+ recalc_normals= 1;
calc_vertexnormals(re, obr, 0, 0);
if(do_autosmooth)
do_displacement(re, obr, mat, imat);
@@ -3497,11 +3486,13 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
}
if(do_autosmooth) {
+ recalc_normals= 1;
autosmooth(re, obr, mat, me->smoothresh);
}
- calc_vertexnormals(re, obr, need_tangent, need_nmap_tangent);
-
+ if(recalc_normals!=0 || need_tangent!=0)
+ calc_vertexnormals(re, obr, need_tangent, need_nmap_tangent);
+
if(need_stress)
calc_edge_stress(re, obr, me);
}