[Bf-blender-cvs] [c27d30f3eaf] blender-v2.82-release: Displist: Add mikktspace tangent space generation for DL_INDEX3

Clément Foucault noreply at git.blender.org
Thu Jan 30 02:46:06 CET 2020


Commit: c27d30f3eaf866fed12adaa84bae48937ad56e53
Author: Clément Foucault
Date:   Thu Jan 30 02:44:56 2020 +0100
Branches: blender-v2.82-release
https://developer.blender.org/rBc27d30f3eaf866fed12adaa84bae48937ad56e53

Displist: Add mikktspace tangent space generation for DL_INDEX3

This now matches the Mesh behavior. Surfaces and metaball implementation
are yet to be implemented.

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

A	source/blender/blenkernel/BKE_displist_tangent.h
M	source/blender/blenkernel/CMakeLists.txt
A	source/blender/blenkernel/intern/displist_tangent.c
M	source/blender/draw/intern/draw_cache_impl_displist.c

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

diff --git a/source/blender/blenkernel/BKE_displist_tangent.h b/source/blender/blenkernel/BKE_displist_tangent.h
new file mode 100644
index 00000000000..3af7c513f67
--- /dev/null
+++ b/source/blender/blenkernel/BKE_displist_tangent.h
@@ -0,0 +1,26 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __BKE_DISPLIST_TANGENT_H__
+#define __BKE_DISPLIST_TANGENT_H__
+
+/** \file
+ * \ingroup bke
+ */
+
+void BKE_displist_tangent_calc(const DispList *dl, float (*fnormals)[3], float (**r_tangent)[4]);
+
+#endif /* __BKE_DISPLIST_TANGENT_H__ */
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 61aeb51a197..0aa4f0fe677 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -105,6 +105,7 @@ set(SRC
   intern/data_transfer.c
   intern/deform.c
   intern/displist.c
+  intern/displist_tangent.c
   intern/dynamicpaint.c
   intern/editlattice.c
   intern/editmesh.c
@@ -271,6 +272,7 @@ set(SRC
   BKE_data_transfer.h
   BKE_deform.h
   BKE_displist.h
+  BKE_displist_tangent.h
   BKE_dynamicpaint.h
   BKE_editlattice.h
   BKE_editmesh.h
diff --git a/source/blender/blenkernel/intern/displist_tangent.c b/source/blender/blenkernel/intern/displist_tangent.c
new file mode 100644
index 00000000000..56041f09767
--- /dev/null
+++ b/source/blender/blenkernel/intern/displist_tangent.c
@@ -0,0 +1,145 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "BLI_math.h"
+#include "BLI_task.h"
+
+#include "BKE_displist.h"
+#include "BKE_displist_tangent.h"
+
+#include "MEM_guardedalloc.h"
+
+/* interface */
+#include "mikktspace.h"
+
+/** \name Tangent Space Calculation
+ * \{ */
+
+/* Necessary complexity to handle looptri's as quads for correct tangents */
+#define USE_LOOPTRI_DETECT_QUADS
+
+typedef struct {
+  const DispList *dl;
+  float (*tangent)[4]; /* destination */
+} SGLSLDisplistToTangent;
+
+static int dl3_ts_GetNumFaces(const SMikkTSpaceContext *pContext)
+{
+  SGLSLDisplistToTangent *dlt = pContext->m_pUserData;
+
+  return dlt->dl->parts;
+}
+
+static int dl3_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
+{
+  UNUSED_VARS(pContext, face_num);
+
+  return 3;
+}
+
+static void dl3_ts_GetPosition(const SMikkTSpaceContext *pContext,
+                               float r_co[3],
+                               const int face_num,
+                               const int vert_index)
+{
+  SGLSLDisplistToTangent *dlt = pContext->m_pUserData;
+  const float(*verts)[3] = (float(*)[3])dlt->dl->verts;
+  const int(*idx)[3] = (int(*)[3])dlt->dl->index;
+
+  copy_v3_v3(r_co, verts[idx[face_num][vert_index]]);
+}
+
+static void dl3_ts_GetTextureCoordinate(const SMikkTSpaceContext *pContext,
+                                        float r_uv[2],
+                                        const int face_num,
+                                        const int vert_index)
+{
+  SGLSLDisplistToTangent *dlt = pContext->m_pUserData;
+  const int(*idx)[3] = (int(*)[3])dlt->dl->index;
+
+  r_uv[0] = idx[face_num][vert_index] / (float)(dlt->dl->nr - 1);
+  r_uv[1] = 0.0f;
+}
+
+static void dl3_ts_GetNormal(const SMikkTSpaceContext *pContext,
+                             float r_no[3],
+                             const int face_num,
+                             const int vert_index)
+{
+  SGLSLDisplistToTangent *dlt = pContext->m_pUserData;
+  UNUSED_VARS(face_num, vert_index);
+
+  copy_v3_v3(r_no, dlt->dl->nors);
+}
+
+static void dl3_ts_SetTSpace(const SMikkTSpaceContext *pContext,
+                             const float fvTangent[3],
+                             const float fSign,
+                             const int face_num,
+                             const int vert_index)
+{
+  SGLSLDisplistToTangent *dlt = pContext->m_pUserData;
+  UNUSED_VARS(face_num, vert_index);
+
+  copy_v3_v3(dlt->tangent[0], fvTangent);
+  dlt->tangent[0][3] = fSign;
+}
+
+void BKE_displist_tangent_calc(const DispList *dl, float (*fnormals)[3], float (**r_tangent)[4])
+{
+  UNUSED_VARS(fnormals);
+
+  if (dl->type == DL_INDEX3) {
+    /* INDEX3 have only one tangent so we don't need actual allocation. */
+    BLI_assert(*r_tangent != NULL);
+
+    SGLSLDisplistToTangent mesh2tangent = {
+        .tangent = *r_tangent,
+        .dl = dl,
+    };
+    SMikkTSpaceContext sContext = {NULL};
+    SMikkTSpaceInterface sInterface = {NULL};
+    sContext.m_pUserData = &mesh2tangent;
+    sContext.m_pInterface = &sInterface;
+    sInterface.m_getNumFaces = dl3_ts_GetNumFaces;
+    sInterface.m_getNumVerticesOfFace = dl3_ts_GetNumVertsOfFace;
+    sInterface.m_getPosition = dl3_ts_GetPosition;
+    sInterface.m_getTexCoord = dl3_ts_GetTextureCoordinate;
+    sInterface.m_getNormal = dl3_ts_GetNormal;
+    sInterface.m_setTSpaceBasic = dl3_ts_SetTSpace;
+    /* 0 if failed */
+    genTangSpaceDefault(&sContext);
+  }
+  else if (dl->type == DL_SURF) {
+    int vert_len = dl->parts * dl->nr;
+    if (*r_tangent == NULL) {
+      //   *r_tangent = MEM_mallocN(sizeof(float[4]) * vert_len, "displist tangents");
+    }
+
+    /* TODO */
+    BLI_assert(0);
+  }
+  else {
+    /* Unsupported. */
+    BLI_assert(0);
+  }
+}
+
+/** \} */
diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c
index ad2495aa0d1..10f4b7ddbb6 100644
--- a/source/blender/draw/intern/draw_cache_impl_displist.c
+++ b/source/blender/draw/intern/draw_cache_impl_displist.c
@@ -33,6 +33,7 @@
 #include "DNA_curve_types.h"
 
 #include "BKE_displist.h"
+#include "BKE_displist_tangent.h"
 
 #include "GPU_batch.h"
 #include "GPU_extensions.h"
@@ -495,11 +496,12 @@ void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv_and_tan(ListBase *lb,
 
         GPUPackedNormal ptan = {0, 0, 0, 1};
         if (tan_step.size != 0) {
-          float tan[3];
-          /* We consider the surface flat so the vector is already ortogonal to the normal. */
-          sub_v3_v3v3(tan, verts[idx[0]], verts[idx[2]]);
-          normalize_v3(tan);
+          float tan[4];
+          float(*tan_ptr)[4] = &tan;
+          BKE_displist_tangent_calc(dl, NULL, &tan_ptr);
+
           ptan = GPU_normal_convert_i10_v3(tan);
+          ptan.w = (tan[3] > 0.0) ? 1 : -2;
         }
 
         const float x_max = (float)(dl->nr - 1);



More information about the Bf-blender-cvs mailing list