[Bf-blender-cvs] [30067b4] master: Fix editmesh GLSL tangent drawing

Campbell Barton noreply at git.blender.org
Mon Aug 24 07:25:30 CEST 2015


Commit: 30067b499ac15d709af416fa691d801fc628d6d9
Author: Campbell Barton
Date:   Mon Aug 24 15:14:34 2015 +1000
Branches: master
https://developer.blender.org/rB30067b499ac15d709af416fa691d801fc628d6d9

Fix editmesh GLSL tangent drawing

The generic tangent calculation relied on CDDM arrays which aren't available in edit-mode.

Add a tangent calculation callback, which has its own implementation for editmesh data.

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

M	source/blender/blenkernel/BKE_DerivedMesh.h
M	source/blender/blenkernel/intern/DerivedMesh.c
M	source/blender/blenkernel/intern/cdderivedmesh.c
M	source/blender/blenkernel/intern/editderivedmesh.c
M	source/blender/blenkernel/intern/subsurf_ccg.c
M	source/blender/render/intern/source/bake_api.c
M	source/blender/render/intern/source/convertblender.c
M	source/blender/render/intern/source/multires_bake.c
M	source/gameengine/Converter/BL_BlenderDataConversion.cpp

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

diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 2eac1a0..e6d5b89 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -209,6 +209,8 @@ struct DerivedMesh {
 	void (*calcLoopNormalsSpaceArray)(DerivedMesh *dm, const bool use_split_normals, const float split_angle,
 	                                  struct MLoopNorSpaceArray *r_lnors_spacearr);
 
+	void (*calcLoopTangents)(DerivedMesh *dm);
+
 	/** Recalculates mesh tessellation */
 	void (*recalcTessellation)(DerivedMesh *dm);
 
@@ -771,7 +773,7 @@ void DM_vertex_attributes_from_gpu(
 
 void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert, int loop);
 
-void DM_add_tangent_layer(DerivedMesh *dm);
+void DM_calc_loop_tangents(DerivedMesh *dm);
 void DM_calc_auto_bump_scale(DerivedMesh *dm);
 
 /** Set object's bounding box based on DerivedMesh min/max data */
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 6c13c79..c470b48 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -3070,7 +3070,7 @@ static void SetTSpace(const SMikkTSpaceContext *pContext, const float fvTangent[
 	pRes[3] = fSign;
 }
 
-void DM_add_tangent_layer(DerivedMesh *dm)
+void DM_calc_loop_tangents(DerivedMesh *dm)
 {
 	/* mesh vars */
 	const MLoopTri *looptri;
@@ -3296,6 +3296,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
 {
 	CustomData *vdata, *ldata;
 	int a, b, layer;
+	const bool is_editmesh = (dm->type == DM_TYPE_EDITBMESH);
 
 	/* From the layers requested by the GLSL shader, figure out which ones are
 	 * actually available for this derivedmesh, and retrieve the pointers */
@@ -3312,115 +3313,64 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
 	/* add a tangent layer if necessary */
 	for (b = 0; b < gattribs->totlayer; b++) {
 		if (gattribs->layer[b].type == CD_TANGENT) {
-			if (CustomData_get_layer_index(ldata, CD_TANGENT) == -1) {
-				DM_add_tangent_layer(dm);
-				break;
+			if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) == -1) {
+				dm->calcLoopTangents(dm);
 			}
+			break;
 		}
 	}
 
 	for (b = 0; b < gattribs->totlayer; b++) {
 		if (gattribs->layer[b].type == CD_MTFACE) {
 			/* uv coordinates */
-			if (dm->type == DM_TYPE_EDITBMESH) {
-				/* exception .. */
-				CustomData *ldata = dm->getLoopDataLayout(dm);
-
-				if (gattribs->layer[b].name[0])
-					layer = CustomData_get_named_layer_index(ldata, CD_MLOOPUV,
-					                                         gattribs->layer[b].name);
-				else
-					layer = CustomData_get_active_layer_index(ldata, CD_MLOOPUV);
-
-				a = attribs->tottface++;
+			if (gattribs->layer[b].name[0])
+				layer = CustomData_get_named_layer_index(ldata, CD_MLOOPUV, gattribs->layer[b].name);
+			else
+				layer = CustomData_get_active_layer_index(ldata, CD_MLOOPUV);
 
-				if (layer != -1) {
-					attribs->tface[a].array = NULL;
-					attribs->tface[a].em_offset = ldata->layers[layer].offset;
-				}
-				else {
-					attribs->tface[a].array = NULL;
-					attribs->tface[a].em_offset = -1;
-				}
+			a = attribs->tottface++;
 
-				attribs->tface[a].gl_index = gattribs->layer[b].glindex;
-				attribs->tface[a].gl_texco = gattribs->layer[b].gltexco;
+			if (layer != -1) {
+				attribs->tface[a].array = is_editmesh ? NULL: ldata->layers[layer].data;
+				attribs->tface[a].em_offset = ldata->layers[layer].offset;
 			}
 			else {
-				if (gattribs->layer[b].name[0])
-					layer = CustomData_get_named_layer_index(ldata, CD_MLOOPUV,
-					                                         gattribs->layer[b].name);
-				else
-					layer = CustomData_get_active_layer_index(ldata, CD_MLOOPUV);
-
-				a = attribs->tottface++;
-
-				if (layer != -1) {
-					attribs->tface[a].array = ldata->layers[layer].data;
-					attribs->tface[a].em_offset = ldata->layers[layer].offset;
-				}
-				else {
-					attribs->tface[a].array = NULL;
-					attribs->tface[a].em_offset = -1;
-				}
-
-				attribs->tface[a].gl_index = gattribs->layer[b].glindex;
-				attribs->tface[a].gl_texco = gattribs->layer[b].gltexco;
+				attribs->tface[a].array = NULL;
+				attribs->tface[a].em_offset = -1;
 			}
+
+			attribs->tface[a].gl_index = gattribs->layer[b].glindex;
+			attribs->tface[a].gl_texco = gattribs->layer[b].gltexco;
 		}
 		else if (gattribs->layer[b].type == CD_MCOL) {
-			if (dm->type == DM_TYPE_EDITBMESH) {
-				if (gattribs->layer[b].name[0])
-					layer = CustomData_get_named_layer_index(ldata, CD_MLOOPCOL,
-					                                         gattribs->layer[b].name);
-				else
-					layer = CustomData_get_active_layer_index(ldata, CD_MLOOPCOL);
-
-				a = attribs->totmcol++;
+			if (gattribs->layer[b].name[0])
+				layer = CustomData_get_named_layer_index(ldata, CD_MLOOPCOL, gattribs->layer[b].name);
+			else
+				layer = CustomData_get_active_layer_index(ldata, CD_MLOOPCOL);
 
-				if (layer != -1) {
-					attribs->mcol[a].array = NULL;
-					/* odd, store the offset for a different layer type here, but editmode draw code expects it */
-					attribs->mcol[a].em_offset = ldata->layers[layer].offset;
-				}
-				else {
-					attribs->mcol[a].array = NULL;
-					attribs->mcol[a].em_offset = -1;
-				}
+			a = attribs->totmcol++;
 
-				attribs->mcol[a].gl_index = gattribs->layer[b].glindex;
+			if (layer != -1) {
+				attribs->mcol[a].array = is_editmesh ? NULL: ldata->layers[layer].data;
+				/* odd, store the offset for a different layer type here, but editmode draw code expects it */
+				attribs->mcol[a].em_offset = ldata->layers[layer].offset;
 			}
 			else {
-				/* vertex colors */
-				if (gattribs->layer[b].name[0])
-					layer = CustomData_get_named_layer_index(ldata, CD_MLOOPCOL,
-					                                         gattribs->layer[b].name);
-				else
-					layer = CustomData_get_active_layer_index(ldata, CD_MLOOPCOL);
-
-				a = attribs->totmcol++;
-
-				if (layer != -1) {
-					attribs->mcol[a].array = ldata->layers[layer].data;
-					/* odd, store the offset for a different layer type here, but editmode draw code expects it */
-					attribs->mcol[a].em_offset = ldata->layers[layer].offset;
-				}
-				else {
-					attribs->mcol[a].array = NULL;
-					attribs->mcol[a].em_offset = -1;
-				}
-
-				attribs->mcol[a].gl_index = gattribs->layer[b].glindex;
+				attribs->mcol[a].array = NULL;
+				attribs->mcol[a].em_offset = -1;
 			}
+
+			attribs->mcol[a].gl_index = gattribs->layer[b].glindex;
 		}
 		else if (gattribs->layer[b].type == CD_TANGENT) {
-			layer = CustomData_get_layer_index(ldata, CD_TANGENT);
+			/* note, even with 'is_editmesh' this uses the derived-meshes loop data */
+			layer = CustomData_get_layer_index(&dm->loopData, CD_TANGENT);
 
 			attribs->tottang = 1;
 
 			if (layer != -1) {
-				attribs->tang.array = ldata->layers[layer].data;
-				attribs->tang.em_offset = ldata->layers[layer].offset;
+				attribs->tang.array = dm->loopData.layers[layer].data;
+				attribs->tang.em_offset = dm->loopData.layers[layer].offset;
 			}
 			else {
 				attribs->tang.array = NULL;
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 19c4e66..c3168c0 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1957,6 +1957,7 @@ static CDDerivedMesh *cdDM_create(const char *desc)
 	dm->calcNormals = CDDM_calc_normals;
 	dm->calcLoopNormals = CDDM_calc_loop_normals;
 	dm->calcLoopNormalsSpaceArray = CDDM_calc_loop_normals_spacearr;
+	dm->calcLoopTangents = DM_calc_loop_tangents;
 	dm->recalcTessellation = CDDM_recalc_tessellation;
 	dm->recalcLoopTri = CDDM_recalc_looptri;
 
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 8158411..f463cab 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -237,6 +237,184 @@ static void emDM_calcLoopNormalsSpaceArray(
 #endif
 }
 
+
+typedef struct {
+	const float (*precomputedFaceNormals)[3];
+	const float (*precomputedLoopNormals)[3];
+	BMLoop *(*looptris)[3];
+	int cd_loop_uv_offset;   /* texture coordinates */
+	const float (*orco)[3];
+	float (*tangent)[4];    /* destination */
+	int numTessFaces;
+
+} SGLSLEditMeshToTangent;
+
+/* interface */
+#include "mikktspace.h"
+
+static int emdm_ts_GetNumFaces(const SMikkTSpaceContext *pContext)
+{
+	SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
+	return pMesh->numTessFaces;
+}
+
+static int emdm_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
+{
+	//SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
+	UNUSED_VARS(pContext, face_num);
+	return 3;
+}
+
+static void emdm_ts_GetPosition(
+        const SMikkTSpaceContext *pContext, float r_co[3],
+        const int face_num, const int vert_index)
+{
+	//assert(vert_index >= 0 && vert_index < 4);
+	SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
+	BMLoop **lt = pMesh->looptris[face_num];
+	const float *co = lt[vert_index]->v->co;
+	copy_v3_v3(r_co, co);
+}
+
+static void emdm_ts_GetTextureCoordinate(
+        const SMikkTSpaceContext *pContext, float r_uv[2],
+        const int face_num, const int vert_index)
+{
+	//assert(vert_index >= 0 && vert_index < 4);
+	SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
+	BMLoop **lt = pMesh->looptris[face_num];
+
+	if (pMesh->cd_loop_uv_offset != -1) {
+		const float *uv = BM_ELEM_CD_GET_VOID_P(lt[vert_index], pMesh->cd_loop_uv_offset);
+		copy_v2_v2(r_uv, uv);
+	}
+	else {
+		const float *orco = pMesh->orco[BM_elem_index_get(lt[vert_index]->v)];
+		map_to_sphere(&r_uv[0], &r_uv[1], orco[0], orco[1], orco[2]);
+	}
+}
+
+static void emdm_ts_GetNormal(
+        const SMikkTSpaceContext *pContext, float r_no[3],
+        const int face_num, const int vert_index)
+{
+	//assert(vert_index >= 0 && vert_index < 4);
+	SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
+	BMLoop **lt = pMesh->looptris[face_num];
+	const bool smoothnormal =

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list