[Bf-blender-cvs] [45fb145] temp-tangent-refactor: Tangents are now taken into account when generating tangents for rendering - Normal maps work again.
Antony Riakiotakis
noreply at git.blender.org
Mon Jul 27 16:27:47 CEST 2015
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 */
More information about the Bf-blender-cvs
mailing list