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
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/editmesh_tangent.cc')
-rw-r--r--source/blender/blenkernel/intern/editmesh_tangent.cc288
1 files changed, 92 insertions, 196 deletions
diff --git a/source/blender/blenkernel/intern/editmesh_tangent.cc b/source/blender/blenkernel/intern/editmesh_tangent.cc
index 5a01f64826d..a65532d083d 100644
--- a/source/blender/blenkernel/intern/editmesh_tangent.cc
+++ b/source/blender/blenkernel/intern/editmesh_tangent.cc
@@ -20,7 +20,7 @@
#include "MEM_guardedalloc.h"
/* interface */
-#include "mikktspace.h"
+#include "mikktspace.hh"
/* -------------------------------------------------------------------- */
/** \name Tangent Space Calculation
@@ -30,233 +30,129 @@
#define USE_LOOPTRI_DETECT_QUADS
struct SGLSLEditMeshToTangent {
- const float (*precomputedFaceNormals)[3];
- const float (*precomputedLoopNormals)[3];
- const BMLoop *(*looptris)[3];
- int cd_loop_uv_offset; /* texture coordinates */
- const float (*orco)[3];
- float (*tangent)[4]; /* destination */
- int numTessFaces;
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
- /* map from 'fake' face index to looptri,
- * quads will point to the first looptri of the quad */
- const int *face_as_quad_map;
- int num_face_as_quad_map;
-#endif
-};
-
-#ifdef USE_LOOPTRI_DETECT_QUADS
-/* seems weak but only used on quads */
-static const BMLoop *bm_loop_at_face_index(const BMFace *f, int vert_index)
-{
- const BMLoop *l = BM_FACE_FIRST_LOOP(f);
- while (vert_index--) {
- l = l->next;
- }
- return l;
-}
-#endif
-
-static int emdm_ts_GetNumFaces(const SMikkTSpaceContext *pContext)
-{
- SGLSLEditMeshToTangent *pMesh = static_cast<SGLSLEditMeshToTangent *>(pContext->m_pUserData);
-
+ uint GetNumFaces()
+ {
#ifdef USE_LOOPTRI_DETECT_QUADS
- return pMesh->num_face_as_quad_map;
+ return (uint)num_face_as_quad_map;
#else
- return pMesh->numTessFaces;
+ return (uint)numTessFaces;
#endif
-}
-
-static int emdm_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
-{
-#ifdef USE_LOOPTRI_DETECT_QUADS
- SGLSLEditMeshToTangent *pMesh = static_cast<SGLSLEditMeshToTangent *>(pContext->m_pUserData);
- if (pMesh->face_as_quad_map) {
- const BMLoop **lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
- if (lt[0]->f->len == 4) {
- return 4;
- }
}
- return 3;
-#else
- UNUSED_VARS(pContext, face_num);
- return 3;
-#endif
-}
-
-static void emdm_ts_GetPosition(const SMikkTSpaceContext *pContext,
- float r_co[3],
- const int face_num,
- const int vert_index)
-{
- // BLI_assert(vert_index >= 0 && vert_index < 4);
- SGLSLEditMeshToTangent *pMesh = static_cast<SGLSLEditMeshToTangent *>(pContext->m_pUserData);
- const BMLoop **lt;
- const BMLoop *l;
+ uint GetNumVerticesOfFace(const uint face_num)
+ {
#ifdef USE_LOOPTRI_DETECT_QUADS
- if (pMesh->face_as_quad_map) {
- lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
- if (lt[0]->f->len == 4) {
- l = bm_loop_at_face_index(lt[0]->f, vert_index);
- goto finally;
+ if (face_as_quad_map) {
+ if (looptris[face_as_quad_map[face_num]][0]->f->len == 4) {
+ return 4;
+ }
}
- /* fall through to regular triangle */
- }
- else {
- lt = pMesh->looptris[face_num];
- }
+ return 3;
#else
- lt = pMesh->looptris[face_num];
+ UNUSED_VARS(pContext, face_num);
+ return 3;
#endif
- l = lt[vert_index];
-
- const float *co;
-
-finally:
- co = l->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)
-{
- // BLI_assert(vert_index >= 0 && vert_index < 4);
- SGLSLEditMeshToTangent *pMesh = static_cast<SGLSLEditMeshToTangent *>(pContext->m_pUserData);
- const BMLoop **lt;
- const BMLoop *l;
+ const BMLoop *GetLoop(const uint face_num, uint vert_index)
+ {
+ // BLI_assert(vert_index >= 0 && vert_index < 4);
+ const BMLoop **lt;
+ const BMLoop *l;
#ifdef USE_LOOPTRI_DETECT_QUADS
- if (pMesh->face_as_quad_map) {
- lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
- if (lt[0]->f->len == 4) {
- l = bm_loop_at_face_index(lt[0]->f, vert_index);
- goto finally;
+ if (face_as_quad_map) {
+ lt = looptris[face_as_quad_map[face_num]];
+ if (lt[0]->f->len == 4) {
+ l = BM_FACE_FIRST_LOOP(lt[0]->f);
+ while (vert_index--) {
+ l = l->next;
+ }
+ return l;
+ }
+ /* fall through to regular triangle */
+ }
+ else {
+ lt = looptris[face_num];
}
- /* fall through to regular triangle */
- }
- else {
- lt = pMesh->looptris[face_num];
- }
#else
- lt = pMesh->looptris[face_num];
+ lt = looptris[face_num];
#endif
- l = lt[vert_index];
-
-finally:
- if (pMesh->cd_loop_uv_offset != -1) {
- const float *uv = BM_ELEM_CD_GET_FLOAT_P(l, pMesh->cd_loop_uv_offset);
- copy_v2_v2(r_uv, uv);
- }
- else {
- const float *orco = pMesh->orco[BM_elem_index_get(l->v)];
- map_to_sphere(&r_uv[0], &r_uv[1], orco[0], orco[1], orco[2]);
+ return lt[vert_index];
}
-}
-static void emdm_ts_GetNormal(const SMikkTSpaceContext *pContext,
- float r_no[3],
- const int face_num,
- const int vert_index)
-{
- // BLI_assert(vert_index >= 0 && vert_index < 4);
- SGLSLEditMeshToTangent *pMesh = static_cast<SGLSLEditMeshToTangent *>(pContext->m_pUserData);
- const BMLoop **lt;
- const BMLoop *l;
+ mikk::float3 GetPosition(const uint face_num, const uint vert_index)
+ {
+ const BMLoop *l = GetLoop(face_num, vert_index);
+ return mikk::float3(l->v->co);
+ }
-#ifdef USE_LOOPTRI_DETECT_QUADS
- if (pMesh->face_as_quad_map) {
- lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
- if (lt[0]->f->len == 4) {
- l = bm_loop_at_face_index(lt[0]->f, vert_index);
- goto finally;
+ mikk::float3 GetTexCoord(const uint face_num, const uint vert_index)
+ {
+ const BMLoop *l = GetLoop(face_num, vert_index);
+ if (cd_loop_uv_offset != -1) {
+ const float *uv = (const float *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ return mikk::float3(uv[0], uv[1], 1.0f);
+ }
+ else {
+ const float *orco_p = orco[BM_elem_index_get(l->v)];
+ float u, v;
+ map_to_sphere(&u, &v, orco_p[0], orco_p[1], orco_p[2]);
+ return mikk::float3(u, v, 1.0f);
}
- /* fall through to regular triangle */
- }
- else {
- lt = pMesh->looptris[face_num];
}
-#else
- lt = pMesh->looptris[face_num];
-#endif
- l = lt[vert_index];
-finally:
- if (pMesh->precomputedLoopNormals) {
- copy_v3_v3(r_no, pMesh->precomputedLoopNormals[BM_elem_index_get(l)]);
- }
- else if (BM_elem_flag_test(l->f, BM_ELEM_SMOOTH) == 0) { /* flat */
- if (pMesh->precomputedFaceNormals) {
- copy_v3_v3(r_no, pMesh->precomputedFaceNormals[BM_elem_index_get(l->f)]);
+ mikk::float3 GetNormal(const uint face_num, const uint vert_index)
+ {
+ const BMLoop *l = GetLoop(face_num, vert_index);
+ if (precomputedLoopNormals) {
+ return mikk::float3(precomputedLoopNormals[BM_elem_index_get(l)]);
+ }
+ else if (BM_elem_flag_test(l->f, BM_ELEM_SMOOTH) == 0) { /* flat */
+ if (precomputedFaceNormals) {
+ return mikk::float3(precomputedFaceNormals[BM_elem_index_get(l->f)]);
+ }
+ else {
+ return mikk::float3(l->f->no);
+ }
}
else {
- copy_v3_v3(r_no, l->f->no);
+ return mikk::float3(l->v->no);
}
}
- else {
- copy_v3_v3(r_no, l->v->no);
+
+ void SetTangentSpace(const uint face_num,
+ const uint vert_index,
+ mikk::float3 T,
+ bool orientation)
+ {
+ const BMLoop *l = GetLoop(face_num, vert_index);
+ float *p_res = tangent[BM_elem_index_get(l)];
+ copy_v4_fl4(p_res, T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
}
-}
-static void emdm_ts_SetTSpace(const SMikkTSpaceContext *pContext,
- const float fvTangent[3],
- const float fSign,
- const int face_num,
- const int vert_index)
-{
- // BLI_assert(vert_index >= 0 && vert_index < 4);
- SGLSLEditMeshToTangent *pMesh = static_cast<SGLSLEditMeshToTangent *>(pContext->m_pUserData);
- const BMLoop **lt;
- const BMLoop *l;
+ const float (*precomputedFaceNormals)[3];
+ const float (*precomputedLoopNormals)[3];
+ const BMLoop *(*looptris)[3];
+ int cd_loop_uv_offset; /* texture coordinates */
+ const float (*orco)[3];
+ float (*tangent)[4]; /* destination */
+ int numTessFaces;
#ifdef USE_LOOPTRI_DETECT_QUADS
- if (pMesh->face_as_quad_map) {
- lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
- if (lt[0]->f->len == 4) {
- l = bm_loop_at_face_index(lt[0]->f, vert_index);
- goto finally;
- }
- /* fall through to regular triangle */
- }
- else {
- lt = pMesh->looptris[face_num];
- }
-#else
- lt = pMesh->looptris[face_num];
+ /* map from 'fake' face index to looptri,
+ * quads will point to the first looptri of the quad */
+ const int *face_as_quad_map;
+ int num_face_as_quad_map;
#endif
- l = lt[vert_index];
-
- float *pRes;
-
-finally:
- pRes = pMesh->tangent[BM_elem_index_get(l)];
- copy_v3_v3(pRes, fvTangent);
- pRes[3] = fSign;
-}
+};
static void emDM_calc_loop_tangents_thread(TaskPool *__restrict UNUSED(pool), void *taskdata)
{
- SGLSLEditMeshToTangent *mesh2tangent = static_cast<SGLSLEditMeshToTangent *>(taskdata);
- /* new computation method */
- {
- SMikkTSpaceContext sContext{};
- SMikkTSpaceInterface sInterface{};
- sContext.m_pUserData = mesh2tangent;
- sContext.m_pInterface = &sInterface;
- sInterface.m_getNumFaces = emdm_ts_GetNumFaces;
- sInterface.m_getNumVerticesOfFace = emdm_ts_GetNumVertsOfFace;
- sInterface.m_getPosition = emdm_ts_GetPosition;
- sInterface.m_getTexCoord = emdm_ts_GetTextureCoordinate;
- sInterface.m_getNormal = emdm_ts_GetNormal;
- sInterface.m_setTSpaceBasic = emdm_ts_SetTSpace;
- sInterface.m_setTSpace = nullptr;
- /* 0 if failed */
- genTangSpaceDefault(&sContext);
- }
+ SGLSLEditMeshToTangent *mesh_data = static_cast<SGLSLEditMeshToTangent *>(taskdata);
+
+ mikk::Mikktspace<SGLSLEditMeshToTangent> mikk(*mesh_data);
+ mikk.genTangSpace();
}
void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
@@ -392,7 +288,7 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
}
BM_mesh_elem_index_ensure(bm, htype_index);
- mesh2tangent->looptris = (const BMLoop *(*)[3])(em->looptris);
+ mesh2tangent->looptris = (const BMLoop *(*)[3])em->looptris;
mesh2tangent->tangent = static_cast<float(*)[4]>(loopdata_out->layers[index].data);
BLI_task_pool_push(