45 return uint(this->faces[face_num].
size());
50 const uint loop_idx =
uint(this->faces[face_num].start()) + vert_num;
51 return mikk::float3(this->positions[this->corner_verts[loop_idx]]);
56 const float *uv = this->uv_map[
uint(this->faces[face_num].start()) + vert_num];
62 return mikk::float3(this->corner_normals[
uint(this->faces[face_num].start()) + vert_num]);
67 float *p_res = this->tangents[
uint(this->faces[face_num].start()) + vert_num];
86 mesh_to_tangent.
positions = vert_positions;
90 mesh_to_tangent.
uv_map = uv_map;
99 reports,
RPT_ERROR,
"Tangent space can only be computed for tris/quads, aborting");
114#define USE_TRI_DETECT_QUADS
130#ifdef USE_TRI_DETECT_QUADS
139#ifdef USE_TRI_DETECT_QUADS
140 return uint(this->num_face_as_quad_map);
142 return uint(this->corner_tris.
size());
148#ifdef USE_TRI_DETECT_QUADS
149 if (this->face_as_quad_map) {
150 const int face_index = this->tri_faces[this->face_as_quad_map[face_num]];
151 if (this->faces[face_index].
size() == 4) {
164#ifdef USE_TRI_DETECT_QUADS
168 if (this->faces[face_index].
size() == 4) {
169 return uint(this->faces[face_index][vert_num]);
174 tri = this->corner_tris[face_num];
175 face_index = this->tri_faces[face_num];
178 tri = &this->corner_tris[face_num];
184# pragma GCC diagnostic push
185# pragma GCC diagnostic ignored "-Warray-bounds"
188 return uint(tri[
int(vert_num)]);
191# pragma GCC diagnostic pop
199 uint loop_index = this->
GetLoop(face_num, vert_num, tri, face_index);
200 return mikk::float3(this->positions[this->corner_verts[loop_index]]);
207 uint loop_index = this->
GetLoop(face_num, vert_num, tri, face_index);
209 const float2 &uv = this->uv_map[loop_index];
212 const float *l_orco = this->orco[this->corner_verts[loop_index]];
222 uint loop_index = this->
GetLoop(face_num, vert_num, tri, face_index);
223 if (!this->corner_normals.
is_empty()) {
226 if (!this->sharp_faces.
is_empty() && this->sharp_faces[face_index]) {
227 if (!this->face_normals.
is_empty()) {
230#ifdef USE_TRI_DETECT_QUADS
233 if (face.
size() == 4) {
235 this->positions[this->corner_verts[face[0]]],
236 this->positions[this->corner_verts[face[1]]],
237 this->positions[this->corner_verts[face[2]]],
238 this->positions[this->corner_verts[face[3]]]);
244 this->positions[this->corner_verts[tri[0]]],
245 this->positions[this->corner_verts[tri[1]]],
246 this->positions[this->corner_verts[tri[2]]]);
250 return mikk::float3(this->vert_normals[this->corner_verts[loop_index]]);
257 uint loop_index = this->
GetLoop(face_num, vert_num, tri, face_index);
258 copy_v4_fl4(this->tangents[loop_index],
T.x,
T.y,
T.z, orientation ? 1.0f : -1.0f);
270 int &num_face_as_quad_map,
271 int *&face_as_quad_map)
273#ifdef USE_TRI_DETECT_QUADS
274 if (corner_tris.
size() !=
faces.size()) {
280 for (k = 0, j = 0; j < int(corner_tris.
size()); k++, j++) {
281 face_as_quad_map[k] = j;
283 if (
faces[corner_tri_faces[j]].
size() == 4) {
287 num_face_as_quad_map = k;
290 num_face_as_quad_map = int(corner_tris.
size());
293 num_face_as_quad_map = 0;
294 face_as_quad_map =
nullptr;
313 int num_face_as_quad_map;
314 int *face_as_quad_map =
nullptr;
316 faces, corner_tris, corner_tri_faces, num_face_as_quad_map, face_as_quad_map);
320 for (const int64_t i : range) {
321 SGLSLMeshToTangent mesh2tangent{};
322 mesh2tangent.positions = vert_positions;
323 mesh2tangent.faces = faces;
324 mesh2tangent.corner_verts = corner_verts;
325 mesh2tangent.corner_tris = corner_tris;
326 mesh2tangent.tri_faces = corner_tri_faces;
327 mesh2tangent.sharp_faces = sharp_faces;
328 mesh2tangent.vert_normals = vert_normals;
329 mesh2tangent.face_normals = face_normals;
330 mesh2tangent.corner_normals = corner_normals;
331 mesh2tangent.uv_map = uv_maps[i];
333 mesh2tangent.face_as_quad_map = face_as_quad_map;
334 mesh2tangent.num_face_as_quad_map = num_face_as_quad_map;
336 results[i].reinitialize(corner_verts.size());
337 mesh2tangent.tangents = results[i];
339 mikk::Mikktspace<SGLSLMeshToTangent> mikk(mesh2tangent);
364 int num_face_as_quad_map;
365 int *face_as_quad_map =
nullptr;
367 faces, corner_tris, corner_tri_faces, num_face_as_quad_map, face_as_quad_map);
375 mesh2tangent.
tri_faces = corner_tri_faces;
380 mesh2tangent.
orco = vert_orco;
void BKE_report(ReportList *reports, eReportType type, const char *message)
float normal_quad_v3(float n[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
bool map_to_sphere(float *r_u, float *r_v, float x, float y, float z)
MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w)
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr int64_t size() const
constexpr int64_t size() const
constexpr bool is_empty() const
static void calc_face_as_quad_map(BMEditMesh *&em, BMesh *&bm, int &totface, int &num_face_as_quad_map, int *&face_as_quad_map)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Array< float4 > calc_orco_tangents(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, Span< int3 > corner_tris, Span< int > corner_tri_faces, Span< bool > sharp_faces, Span< float3 > vert_normals, Span< float3 > face_normals, Span< float3 > corner_normals, Span< float3 > vert_orco)
Array< Array< float4 > > calc_uv_tangents(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, Span< int3 > corner_tris, Span< int > corner_tri_faces, Span< bool > sharp_faces, Span< float3 > vert_normals, Span< float3 > face_normals, Span< float3 > corner_normals, Span< Span< float2 > > uv_maps)
static void calc_face_as_quad_map(const OffsetIndices< int > faces, const Span< int3 > corner_tris, const Span< int > corner_tri_faces, int &num_face_as_quad_map, int *&face_as_quad_map)
void calc_uv_tangent_tris_quads(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, Span< float3 > corner_normals, Span< float2 > uv_map, MutableSpan< float4 > results, ReportList *reports)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
VecBase< float, 2 > float2
VecBase< int32_t, 3 > int3
Span< float3 > corner_normals
mikk::float3 GetTexCoord(const uint face_num, const uint vert_num)
mikk::float3 GetPosition(const uint face_num, const uint vert_num)
MutableSpan< float4 > tangents
OffsetIndices< int > faces
uint GetNumVerticesOfFace(const uint face_num)
void SetTangentSpace(const uint face_num, const uint vert_num, mikk::float3 T, bool orientation)
mikk::float3 GetNormal(const uint face_num, const uint vert_num)
uint GetLoop(const uint face_num, const uint vert_num, int3 &tri, int &face_index)
mikk::float3 GetNormal(const uint face_num, const uint vert_num)
Span< float3 > face_normals
Span< float3 > vert_normals
Span< float3 > corner_normals
OffsetIndices< int > faces
const int * face_as_quad_map
uint GetNumVerticesOfFace(const uint face_num)
MutableSpan< float4 > tangents
mikk::float3 GetTexCoord(const uint face_num, const uint vert_num)
mikk::float3 GetPosition(const uint face_num, const uint vert_num)
void SetTangentSpace(const uint face_num, const uint vert_num, mikk::float3 T, bool orientation)