Commit: 29109403e002b0a07f7637c2b65351c3d5ec0783 Author: Antony Riakiotakis Date: Fri Jul 17 18:22:11 2015 +0200 Branches: temp-tangent-refactor https://developer.blender.org/rB29109403e002b0a07f7637c2b65351c3d5ec0783
Convert tangent layer and baking to use looptris. This is WIP code to make sure all blender uses tangents generated from loops. =================================================================== M source/blender/blenkernel/BKE_multires.h M source/blender/blenkernel/intern/DerivedMesh.c M source/blender/blenkernel/intern/multires.c M source/blender/render/intern/source/bake_api.c M source/blender/render/intern/source/multires_bake.c M source/gameengine/Converter/BL_BlenderDataConversion.cpp =================================================================== diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index a8242a5..178751d 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -42,6 +42,11 @@ struct MultiresModifierData; struct Object; struct Scene; +struct MLoop; +struct MVert; +struct MPoly; +struct MLoopTri; + /* Delete mesh mdisps and grid paint masks */ void multires_customdata_delete(struct Mesh *me); @@ -114,6 +119,6 @@ void multires_topology_changed(struct Mesh *me); /**** interpolation stuff ****/ void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, float v); -int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y); +int mdisp_rot_face_to_crn(struct MVert *mvert, struct MPoly *mpoly, struct MLoop *mloops, const struct MLoopTri *lt, const int face_side, const float u, const float v, float *x, float *y); #endif /* __BKE_MULTIRES_H__ */ diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 05ec83e..32d0375 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2995,7 +2995,7 @@ void DM_add_tangent_layer(DerivedMesh *dm) float (*fnors)[3]; short (*tlnors)[4][3]; - if (CustomData_get_layer_index(&dm->faceData, CD_TANGENT) != -1) + if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) != -1) return; fnors = dm->getTessFaceDataArray(dm, CD_NORMAL); @@ -3019,8 +3019,8 @@ void DM_add_tangent_layer(DerivedMesh *dm) } /* create tangent layer */ - DM_add_tessface_layer(dm, CD_TANGENT, CD_CALLOC, NULL); - tangent = DM_get_tessface_data_layer(dm, CD_TANGENT); + DM_add_loop_layer(dm, CD_TANGENT, CD_CALLOC, NULL); + tangent = DM_get_loop_data_layer(dm, CD_TANGENT); /* new computation method */ { @@ -3202,7 +3202,7 @@ void DM_calc_auto_bump_scale(DerivedMesh *dm) void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, DMVertexAttribs *attribs) { - CustomData *vdata, *fdata, *tfdata = NULL; + CustomData *vdata; int a, b, layer; /* From the layers requested by the GLSL shader, figure out which ones are @@ -3211,7 +3211,6 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, memset(attribs, 0, sizeof(DMVertexAttribs)); vdata = &dm->vertData; - fdata = tfdata = dm->getTessFaceDataLayout(dm); /* calc auto bump scale if necessary */ if (dm->auto_bump_scale <= 0.0f) @@ -3219,10 +3218,11 @@ 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(fdata, CD_TANGENT) == -1) + if (gattribs->layer[b].type == CD_TANGENT) { + CustomData *ldata = dm->getLoopDataLayout(dm); + if (CustomData_get_layer_index(ldata, CD_TANGENT) == -1) DM_add_tangent_layer(dm); - + } for (b = 0; b < gattribs->totlayer; b++) { if (gattribs->layer[b].type == CD_MTFACE) { /* uv coordinates */ @@ -3328,13 +3328,14 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, } else if (gattribs->layer[b].type == CD_TANGENT) { /* tangents */ - layer = CustomData_get_layer_index(fdata, CD_TANGENT); + CustomData *ldata = dm->getLoopDataLayout(dm); + layer = CustomData_get_layer_index(ldata, CD_TANGENT); attribs->tottang = 1; if (layer != -1) { - attribs->tang.array = fdata->layers[layer].data; - attribs->tang.em_offset = fdata->layers[layer].offset; + attribs->tang.array = ldata->layers[layer].data; + attribs->tang.em_offset = ldata->layers[layer].offset; } else { attribs->tang.array = NULL; diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 0c984c3..9ef5b69 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -2338,12 +2338,12 @@ void multires_topology_changed(Mesh *me) /***************** Multires interpolation stuff *****************/ /* Find per-corner coordinate with given per-face UV coord */ -int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y) +int mdisp_rot_face_to_crn(struct MVert *UNUSED(mvert), struct MPoly *mpoly, struct MLoop *UNUSED(mloop), const struct MLoopTri *UNUSED(lt), const int face_side, const float u, const float v, float *x, float *y) { const float offset = face_side * 0.5f - 0.5f; int S = 0; - if (corners == 4) { + if (mpoly->totloop == 4) { if (u <= offset && v <= offset) S = 0; else if (u > offset && v <= offset) S = 1; else if (u > offset && v > offset) S = 2; @@ -2366,7 +2366,7 @@ int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u, *y = v - offset; } } - else { + else if (mpoly->totloop == 3) { int grid_size = offset; float w = (face_side - 1) - u - v; float W1, W2; @@ -2381,6 +2381,30 @@ int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u, *x = (1 - (2 * W1) / (1 - W2)) * grid_size; *y = (1 - (2 * W2) / (1 - W1)) * grid_size; } + else { + /* the complicated ngon case: find the actual coordinate from + * the barycentric coordinates and finally find the closest vertex + * should work reliably for convex cases only but better than nothing */ + +#if 0 + int minS, i; + float mindist = FLT_MAX; + + for (i = 0; i < mpoly->totloop; i++) { + float len = len_v3v3(NULL, mvert[mloop[mpoly->loopstart + i].v].co); + if (len < mindist) { + mindist = len; + minS = i; + } + } + S = minS; +#endif + /* temp not implemented yet and also not working properly in current master. + * (was worked around by subdividing once) */ + S = 0; + *x = 0; + *y = 0; + } return S; } diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c index bc5db5b..508ea8c 100644 --- a/source/blender/render/intern/source/bake_api.c +++ b/source/blender/render/intern/source/bake_api.c @@ -73,6 +73,7 @@ #include "BKE_cdderivedmesh.h" #include "BKE_image.h" #include "BKE_node.h" +#include "BKE_mesh.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -357,88 +358,60 @@ static void mesh_calc_tri_tessface( TriTessFace *triangles, Mesh *me, bool tangent, DerivedMesh *dm) { int i; - int p_id; - MFace *mface; MVert *mvert; TSpace *tspace; float *precomputed_normals = NULL; bool calculate_normal; + const int tottri = poly_to_tri_count(me->totpoly, me->totloop); + MLoopTri *looptri; - mface = CustomData_get_layer(&me->fdata, CD_MFACE); mvert = CustomData_get_layer(&me->vdata, CD_MVERT); + looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__); if (tangent) { DM_ensure_normals(dm); DM_add_tangent_layer(dm); - precomputed_normals = dm->getTessFaceDataArray(dm, CD_NORMAL); + precomputed_normals = dm->getPolyDataArray(dm, CD_NORMAL); calculate_normal = precomputed_normals ? false : true; - //mface = dm->getTessFaceArray(dm); - //mvert = dm->getVertArray(dm); - - tspace = dm->getTessFaceDataArray(dm, CD_TANGENT); + tspace = dm->getLoopDataArray(dm, CD_TANGENT); BLI_assert(tspace); } - p_id = -1; - for (i = 0; i < me->totface; i++) { - MFace *mf = &mface[i]; - TSpace *ts = tangent ? &tspace[i * 4] : NULL; + BKE_mesh_recalc_looptri( + me->mloop, me->mpoly, + me->mvert, + me->totloop, me->totpoly, + looptri); - p_id++; + for (i = 0; i < tottri; i++) { + MLoopTri *lt = &looptri[i]; + MPoly *mp = &me->mpoly[lt->poly]; - triangles[p_id].mverts[0] = &mvert[mf->v1]; - triangles[p_id].mverts[1] = &mvert[mf->v2]; - triangles[p_id].mverts[2] = &mvert[mf->v3]; - triangles[p_id].is_smooth = (mf->flag & ME_SMOOTH) != 0; + triangles[i].mverts[0] = &mvert[lt->tri[0]]; + triangles[i].mverts[1] = &mvert[lt->tri[1]]; + triangles[i].mverts[2] = &mvert[lt->tri[2]]; + triangles[i].is_smooth = (mp->flag & ME_SMOOTH) != 0; if (tangent) { - triangles[p_id].tspace[0] = &ts[0]; - triangles[p_id].tspace[1] = &ts[1]; - triangles[p_id].tspace[2] = &ts[2]; + triangles[i].tspace[0] = &tspace[lt->tri[0]]; + triangles[i].tspace[1] = &tspace[lt->tri[1]]; + triangles[i].tspace[2] = &tspace[lt->tri[2]]; if (calculate_normal) { - if (mf->v4 != 0) { - normal_quad_v3(triangles[p_id].normal, - mvert[mf->v1].co, - mvert[mf->v2].co, - mvert[mf->v3].co, - mvert[mf->v4].co); - } - else { - normal_tri_v3(triangles[p_id].normal, - triangles[p_id].mverts[0]->co, - triangles[p_id].mverts[1]->co, - triangles[p_id].mverts[2]->co); - } + normal_tri_v3(triangles[i].normal, + triangles[i].mverts[0]->co, + triangles[i].mverts[1]->co, + triangles[i].mverts[2]->co); } else { - copy_v3_v3(triangles[p_id].normal, &precomputed_normals[3 * i]); - } - } - - /* 4 vertices in the face */ - if (mf->v4 != 0) { - p_id++; - - triangles[p_id].mverts[0] = &mvert[mf->v1]; - triangles[p_id].mverts[1] = &mvert[mf->v3]; - triangles[p_id].mverts[2] = &mvert[mf->v4]; - triangles[p_id].is_smooth = (mf->flag & ME_SMOOTH) != 0; - - if (tangent) { - triangles[p_id].tspace[0] = &ts[0]; - triangles[p_id].tspace[1] = &ts[2]; - triangles[p_id].tspace[2] = &ts[3]; - - /* same normal as the other "triangle" */ - copy_v3_v3(triangles[p_id].normal, triangles[p_id - 1].normal); + copy_v3_v3(triangles[i].normal, &precomputed_normals[lt->poly]); } } } - BLI_assert(p_id < me->totface * 2); + MEM_freeN(looptri); } bool RE_bake_pixels_populate_from_objects( diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c index de57d4e..d46e241 100644 --- a/source/blender/render/intern/source/multires_bake.c +++ b/source/blender/render/inte @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs