Commit: 45fb14567831020bf85f32c8d1c44043e6cde5d0
Author: Antony Riakiotakis
Date:   Mon Jul 27 16:27:21 2015 +0200
Branches: temp-tangent-refactor
https://developer.blender.org/rB45fb14567831020bf85f32c8d1c44043e6cde5d0

Tangents are now taken into account when generating tangents for
rendering - Normal maps work again.

Added special code that only creates a tessface layer for tangents, also
added code that creates tangent mface data from loop data during mesh
conversion.

===================================================================

M       source/blender/blenkernel/BKE_DerivedMesh.h
M       source/blender/blenkernel/BKE_mesh.h
M       source/blender/blenkernel/intern/DerivedMesh.c
M       source/blender/blenkernel/intern/cdderivedmesh.c
M       source/blender/blenkernel/intern/customdata.c
M       source/blender/blenkernel/intern/mesh_evaluate.c
M       source/blender/render/intern/source/convertblender.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h 
b/source/blender/blenkernel/BKE_DerivedMesh.h
index 32baa45..a39dc2e 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -614,6 +614,7 @@ void DM_ensure_looptri_data(DerivedMesh *dm);
 void DM_ensure_looptri(DerivedMesh *dm);
 
 void DM_update_tessface_data(DerivedMesh *dm);
+void DM_generate_tangent_tessface_data(DerivedMesh *dm, bool generate);
 
 void DM_update_materials(DerivedMesh *dm, struct Object *ob);
 struct MLoopUV *DM_paint_uvlayer_active_get(DerivedMesh *dm, int mat_nr);
diff --git a/source/blender/blenkernel/BKE_mesh.h 
b/source/blender/blenkernel/BKE_mesh.h
index b20bca7..1233069 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -287,6 +287,8 @@ void BKE_mesh_loops_to_mface_corners(
 void BKE_mesh_loops_to_tessdata(
         struct CustomData *fdata, struct CustomData *ldata, struct CustomData 
*pdata, struct MFace *mface,
         int *polyindices, unsigned int (*loopindices)[4], const int num_faces);
+void BKE_mesh_tangent_loops_to_tessdata(struct CustomData *fdata, struct 
CustomData *ldata, struct MFace *mface,
+                                        int *polyindices, unsigned int 
(*loopindices)[4], const int num_faces);
 int BKE_mesh_recalc_tessellation(
         struct CustomData *fdata, struct CustomData *ldata, struct CustomData 
*pdata,
         struct MVert *mvert,
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c 
b/source/blender/blenkernel/intern/DerivedMesh.c
index 935fc11..d654efd 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -521,7 +521,8 @@ void DM_update_tessface_data(DerivedMesh *dm)
            CustomData_has_layer(fdata, CD_MCOL) ||
            CustomData_has_layer(fdata, CD_PREVIEW_MCOL) ||
            CustomData_has_layer(fdata, CD_ORIGSPACE) ||
-           CustomData_has_layer(fdata, CD_TESSLOOPNORMAL))
+           CustomData_has_layer(fdata, CD_TESSLOOPNORMAL) ||
+           CustomData_has_layer(fdata, CD_TANGENT))
        {
                loopindex = MEM_mallocN(sizeof(*loopindex) * totface, __func__);
 
@@ -557,6 +558,69 @@ void DM_update_tessface_data(DerivedMesh *dm)
        dm->dirty &= ~DM_DIRTY_TESS_CDLAYERS;
 }
 
+void DM_generate_tangent_tessface_data(DerivedMesh *dm, bool generate)
+{
+       int i;
+       MFace *mf, *mface = dm->getTessFaceArray(dm);
+       MPoly *mp = dm->getPolyArray(dm);
+       MLoop *ml = dm->getLoopArray(dm);
+
+       CustomData *fdata = dm->getTessFaceDataLayout(dm);
+       CustomData *pdata = dm->getPolyDataLayout(dm);
+       CustomData *ldata = dm->getLoopDataLayout(dm);
+
+       const int totface = dm->getNumTessFaces(dm);
+       int mf_idx;
+
+       int *polyindex = CustomData_get_layer(fdata, CD_ORIGINDEX);
+       unsigned int (*loopindex)[4];
+
+       /* Should never occure, but better abort than segfault! */
+       if (!polyindex)
+               return;
+
+       CustomData_from_bmeshpoly(fdata, pdata, ldata, totface);
+
+       if (generate) {
+               for (i = 0; i < ldata->totlayer; i++) {
+                       if (ldata->layers[i].type == CD_TANGENT)
+                               CustomData_add_layer_named(fdata, CD_TANGENT, 
CD_CALLOC, NULL, totface, ldata->layers[i].name);
+               }
+               CustomData_bmesh_update_active_layers(fdata, pdata, ldata);
+       }
+
+       loopindex = MEM_mallocN(sizeof(*loopindex) * totface, __func__);
+
+       for (mf_idx = 0, mf = mface; mf_idx < totface; mf_idx++, mf++) {
+               const int mf_len = mf->v4 ? 4 : 3;
+               unsigned int *ml_idx = loopindex[mf_idx];
+               int i, not_done;
+
+               /* Find out loop indices. */
+               /* NOTE: This assumes tessface are valid and in sync with 
loop/poly... Else, most likely, segfault! */
+               for (i = mp[polyindex[mf_idx]].loopstart, not_done = mf_len; 
not_done; i++) {
+                       const int tf_v = BKE_MESH_TESSFACE_VINDEX_ORDER(mf, 
ml[i].v);
+                       if (tf_v != -1) {
+                               ml_idx[tf_v] = i;
+                               not_done--;
+                       }
+               }
+       }
+
+       /* NOTE: quad detection issue - forth vertidx vs forth loopidx:
+        * Here, our tfaces' forth vertex index is never 0 for a quad. However, 
we know our forth loop index may be
+        * 0 for quads (because our quads may have been rotated compared to 
their org poly, see tessellation code).
+        * So we pass the MFace's, and BKE_mesh_loops_to_tessdata will use 
MFace->v4 index as quad test.
+        */
+       BKE_mesh_tangent_loops_to_tessdata(fdata, ldata, mface, polyindex, 
loopindex, totface);
+
+       MEM_freeN(loopindex);
+
+       if (G.debug & G_DEBUG)
+               printf("%s: Updated tessellated tangents of dm %p\n", __func__, 
dm);
+}
+
+
 void DM_update_materials(DerivedMesh *dm, Object *ob)
 {
        int i, totmat = ob->totcol + 1; /* materials start from 1, default 
material is 0 */
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c 
b/source/blender/blenkernel/intern/cdderivedmesh.c
index 30adc76..8c50d52 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1058,7 +1058,7 @@ static void cdDM_drawMappedFacesGLSL(
                                        }
                                        if (matconv[i].attribs.tottang && 
matconv[i].attribs.tang.array) {
                                                if 
(matconv[i].attribs.tface[b].array) {
-                                                       const float 
(*looptang)[4] = matconv[i].attribs.tang.array;
+                                                       const float 
(*looptang)[4] = (const float (*)[4])matconv[i].attribs.tang.array;
                                                        for (j = 0; j < 
mpoly->totloop; j++)
                                                                
copy_v4_v4((float *)&varray[offset + j * max_element_size], 
looptang[mpoly->loopstart + j]);
                                                        offset += sizeof(float) 
* 4;
diff --git a/source/blender/blenkernel/intern/customdata.c 
b/source/blender/blenkernel/intern/customdata.c
index dbc79d3..688a1dd 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -2489,6 +2489,9 @@ void CustomData_from_bmeshpoly(CustomData *fdata, 
CustomData *pdata, CustomData
                else if (ldata->layers[i].type == CD_NORMAL) {
                        CustomData_add_layer_named(fdata, CD_TESSLOOPNORMAL, 
CD_CALLOC, NULL, total, ldata->layers[i].name);
                }
+               else if (ldata->layers[i].type == CD_TANGENT) {
+                       CustomData_add_layer_named(fdata, CD_TANGENT, 
CD_CALLOC, NULL, total, ldata->layers[i].name);
+               }
        }
 
        CustomData_bmesh_update_active_layers(fdata, pdata, ldata);
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c 
b/source/blender/blenkernel/intern/mesh_evaluate.c
index 74c5fb8..a334951 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -2243,6 +2243,7 @@ void BKE_mesh_loops_to_tessdata(CustomData *fdata, 
CustomData *ldata, CustomData
        const bool hasPCol = CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL);
        const bool hasOrigSpace = CustomData_has_layer(ldata, 
CD_ORIGSPACE_MLOOP);
        const bool hasLoopNormal = CustomData_has_layer(ldata, CD_NORMAL);
+       const bool hasLoopTangent = CustomData_has_layer(ldata, CD_TANGENT);
        int findex, i, j;
        const int *pidx;
        unsigned int (*lidx)[4];
@@ -2307,6 +2308,51 @@ void BKE_mesh_loops_to_tessdata(CustomData *fdata, 
CustomData *ldata, CustomData
                        }
                }
        }
+
+       if (hasLoopTangent) {
+               /* need to do for all uv maps at some point */
+               float (*ftangents)[4] = CustomData_get_layer(fdata, CD_TANGENT);
+               float (*ltangents)[4] = CustomData_get_layer(ldata, CD_TANGENT);
+
+               for (findex = 0, pidx = polyindices, lidx = loopindices;
+                    findex < num_faces;
+                    pidx++, lidx++, findex++)
+               {
+                       int nverts = (mface ? mface[findex].v4 : (*lidx)[3]) ? 
4 : 3;
+                       for (j = nverts; j--;) {
+                               copy_v4_v4(ftangents[findex * 4 + j], 
ltangents[(*lidx)[j]]);
+                       }
+               }
+       }
+}
+
+void BKE_mesh_tangent_loops_to_tessdata(CustomData *fdata, CustomData *ldata, 
MFace *mface,
+                                        int *polyindices, unsigned int 
(*loopindices)[4], const int num_faces)
+{
+       /* Note: performances are sub-optimal when we get a NULL mface, we 
could be ~25% quicker with dedicated code...
+        *       Issue is, unless having two different functions with nearly 
the same code, there's not much ways to solve
+        *       this. Better imho to live with it for now. :/ --mont29
+        */
+       const bool hasLoopTangent = CustomData_has_layer(ldata, CD_TANGENT);
+       int findex, j;
+       const int *pidx;
+       unsigned int (*lidx)[4];
+
+       if (hasLoopTangent) {
+               /* need to do for all uv maps at some point */
+               float (*ftangents)[4] = CustomData_get_layer(fdata, CD_TANGENT);
+               float (*ltangents)[4] = CustomData_get_layer(ldata, CD_TANGENT);
+
+               for (findex = 0, pidx = polyindices, lidx = loopindices;
+                    findex < num_faces;
+                    pidx++, lidx++, findex++)
+               {
+                       int nverts = (mface ? mface[findex].v4 : (*lidx)[3]) ? 
4 : 3;
+                       for (j = nverts; j--;) {
+                               copy_v4_v4(ftangents[findex * 4 + j], 
ltangents[(*lidx)[j]]);
+                       }
+               }
+       }
 }
 
 /**
diff --git a/source/blender/render/intern/source/convertblender.c 
b/source/blender/render/intern/source/convertblender.c
index 20387bc..49f7658 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -3272,8 +3272,14 @@ static void init_render_mesh(Render *re, ObjectRen *obr, 
int timeoffset)
                        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);
+                       if (need_nmap_tangent!=0 && 
CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1) {
+                               bool generate_data = false;
+                               if (CustomData_get_layer_index(&dm->loopData, 
CD_TANGENT) == -1) {
+                                       DM_add_tangent_layer(dm);
+                                       generate_data = true;
+                               }
+                               DM_generate_tangent_tessface_data(dm, 
generate_data);
+                       }
                        
                        /* still to do for keys: the correct local texture 
coordinate */

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to