91 const float fv_tangent[3],
92 const float face_sign,
103 const int UNUSED(numVerts),
105 float (*r_looptangent)[4],
106 const float (*loopnors)[3],
108 const int UNUSED(numLoops),
121 for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
124 reports,
RPT_ERROR,
"Tangent space can only be computed for tris/quads, aborting");
130 mesh_to_tangent.
mpolys = mpolys;
131 mesh_to_tangent.
mloops = mloops;
132 mesh_to_tangent.
mverts = mverts;
133 mesh_to_tangent.
luvs = loopuvs;
134 mesh_to_tangent.
lnors = loopnors;
135 mesh_to_tangent.
tangents = r_looptangent;
155 float (*r_looptangents)[4],
170 "Tangent space computation needs a UV Map, \"%s\" not found, aborting",
178 reports,
RPT_ERROR,
"Tangent space computation needs loop normals, none found, aborting");
201 #define USE_LOOPTRI_DETECT_QUADS
204 const float (*precomputedFaceNormals)[3];
205 const float (*precomputedLoopNormals)[3];
216 #ifdef USE_LOOPTRI_DETECT_QUADS
230 #ifdef USE_LOOPTRI_DETECT_QUADS
239 #ifdef USE_LOOPTRI_DETECT_QUADS
258 const int vert_index)
266 #ifdef USE_LOOPTRI_DETECT_QUADS
277 lt = &pMesh->
looptri[face_num];
280 lt = &pMesh->
looptri[face_num];
282 loop_index = lt->
tri[vert_index];
292 const int vert_index)
299 #ifdef USE_LOOPTRI_DETECT_QUADS
310 lt = &pMesh->
looptri[face_num];
313 lt = &pMesh->
looptri[face_num];
315 loop_index = lt->
tri[vert_index];
319 const float *uv = pMesh->
mloopuv[loop_index].
uv;
323 const float *orco = pMesh->
orco[pMesh->
mloop[loop_index].
v];
324 map_to_sphere(&r_uv[0], &r_uv[1], orco[0], orco[1], orco[2]);
331 const int vert_index)
349 lt = &pMesh->
looptri[face_num];
352 lt = &pMesh->
looptri[face_num];
354 loop_index = lt->
tri[vert_index];
365 #ifdef USE_LOOPTRI_DETECT_QUADS
390 const float fvTangent[3],
393 const int vert_index)
411 lt = &pMesh->
looptri[face_num];
414 lt = &pMesh->
looptri[face_num];
416 loop_index = lt->
tri[vert_index];
421 pRes = pMesh->
tangent[loop_index];
451 const char *layer_name)
460 bool calc_active_tangent,
461 const char (*tangent_names)[
MAX_NAME],
462 int tangent_names_count,
469 short *rtangent_mask)
475 if (*ract_uv_n != -1) {
476 strcpy(ract_uv_name, loopData->
layers[*ract_uv_n + layer_index].
name);
482 if (*rren_uv_n != -1) {
483 strcpy(rren_uv_name, loopData->
layers[*rren_uv_n + layer_index].
name);
489 for (
int i = 0; i < tangent_names_count; i++) {
490 if (tangent_names[i][0] == 0) {
491 calc_active_tangent =
true;
494 if (calc_active_tangent) {
497 for (
int i = 0; i < tangent_names_count; i++) {
498 if (
STREQ(ract_uv_name, tangent_names[i])) {
501 if (
STREQ(rren_uv_name, tangent_names[i])) {
509 for (
int n = 0; n < uv_layer_num; n++) {
512 for (
int i = 0; i < tangent_names_count; i++) {
513 if (tangent_names[i][0] &&
STREQ(tangent_names[i], name)) {
518 if (!
add && ((*rcalc_act && ract_uv_name[0] &&
STREQ(ract_uv_name, name)) ||
519 (*rcalc_ren && rren_uv_name[0] &&
STREQ(rren_uv_name, name)))) {
523 *rtangent_mask |= (short)(1 << n);
527 if (uv_layer_num == 0) {
534 const uint mpoly_len,
537 const uint looptri_len,
540 bool calc_active_tangent,
541 const char (*tangent_names)[
MAX_NAME],
542 int tangent_names_len,
544 const float (*poly_normals)[3],
545 const float (*loop_normals)[3],
546 const float (*vert_orco)[3],
549 const uint loopdata_out_len,
550 short *tangent_mask_curr_p)
554 bool calc_act =
false;
555 bool calc_ren =
false;
558 short tangent_mask = 0;
559 short tangent_mask_curr = *tangent_mask_curr_p;
572 if ((tangent_mask_curr | tangent_mask) != tangent_mask_curr) {
575 for (
int i = 0; i < tangent_names_len; i++) {
576 if (tangent_names[i][0]) {
578 loopdata, loopdata_out, (
int)loopdata_out_len, tangent_names[i]);
586 if (calc_act && act_uv_name[0]) {
588 loopdata, loopdata_out, (
int)loopdata_out_len, act_uv_name);
590 if (calc_ren && ren_uv_name[0]) {
592 loopdata, loopdata_out, (
int)loopdata_out_len, ren_uv_name);
595 #ifdef USE_LOOPTRI_DETECT_QUADS
600 if (looptri_len != mpoly_len) {
606 for (k = 0, j = 0; j < (int)looptri_len; k++, j++) {
621 if (looptri_len != 0) {
624 tangent_mask_curr = 0;
628 for (
int n = 0; n < tangent_layer_num; n++) {
633 #ifdef USE_LOOPTRI_DETECT_QUADS
653 mesh2tangent->
orco = vert_orco;
654 if (!mesh2tangent->
orco) {
666 tangent_mask_curr |= (short)(1 << (uv_ind - uv_start));
673 BLI_assert(tangent_mask_curr == tangent_mask);
678 tangent_mask_curr = tangent_mask;
680 #ifdef USE_LOOPTRI_DETECT_QUADS
684 # undef USE_LOOPTRI_DETECT_QUADS
688 *tangent_mask_curr_p = tangent_mask_curr;
691 int act_uv_index = (act_uv_n != -1) ?
694 if (act_uv_index != -1) {
701 int ren_uv_index = (ren_uv_n != -1) ?
704 if (ren_uv_index != -1) {
713 bool calc_active_tangent,
714 const char (*tangent_names)[
MAX_NAME],
715 int tangent_names_len)
720 short tangent_mask = 0;
typedef float(TangentPoint)[2]
CustomData interface, see also DNA_customdata_types.h.
const char * CustomData_get_layer_name(const struct CustomData *data, int type, int n)
int CustomData_number_of_layers(const struct CustomData *data, int type)
int CustomData_get_named_layer_index(const struct CustomData *data, int type, const char *name)
void CustomData_set_layer_render_index(struct CustomData *data, int type, int n)
int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n)
void * CustomData_add_layer_named(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem, const char *name)
int CustomData_get_active_layer(const struct CustomData *data, int type)
void * CustomData_get_layer_named(const struct CustomData *data, int type, const char *name)
int CustomData_get_layer_index(const struct CustomData *data, int type)
void * CustomData_get_layer(const struct CustomData *data, int type)
void CustomData_set_layer_active_index(struct CustomData *data, int type, int n)
int CustomData_get_render_layer(const struct CustomData *data, int type)
const float(* BKE_mesh_poly_normals_ensure(const struct Mesh *mesh))[3]
const float(* BKE_mesh_vertex_normals_ensure(const struct Mesh *mesh))[3]
const struct MLoopTri * BKE_mesh_runtime_looptri_ensure(const struct Mesh *mesh)
#define DM_TANGENT_MASK_ORCO
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
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])
void map_to_sphere(float *r_u, float *r_v, float x, float y, float z)
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
void BLI_task_pool_work_and_wait(TaskPool *pool)
TaskPool * BLI_task_pool_create(void *userdata, eTaskPriority priority)
void BLI_task_pool_free(TaskPool *pool)
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
Read Guarded memory(de)allocation.
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
void(* MEM_freeN)(void *vmemh)
void *(* MEM_mallocN)(size_t len, const char *str)
static int dm_ts_GetNumFaces(const SMikkTSpaceContext *pContext)
static int get_num_faces(const SMikkTSpaceContext *pContext)
void BKE_mesh_calc_loop_tangent_single_ex(const MVert *mverts, const int UNUSED(numVerts), const MLoop *mloops, float(*r_looptangent)[4], const float(*loopnors)[3], const MLoopUV *loopuvs, const int UNUSED(numLoops), const MPoly *mpolys, const int numPolys, ReportList *reports)
static void dm_ts_GetTextureCoordinate(const SMikkTSpaceContext *pContext, float r_uv[2], const int face_num, const int vert_index)
static void get_position(const SMikkTSpaceContext *pContext, float r_co[3], const int face_idx, const int vert_idx)
#define USE_LOOPTRI_DETECT_QUADS
void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert, const MPoly *mpoly, const uint mpoly_len, const MLoop *mloop, const MLoopTri *looptri, const uint looptri_len, CustomData *loopdata, bool calc_active_tangent, const char(*tangent_names)[MAX_NAME], int tangent_names_len, const float(*vert_normals)[3], const float(*poly_normals)[3], const float(*loop_normals)[3], const float(*vert_orco)[3], CustomData *loopdata_out, const uint loopdata_out_len, short *tangent_mask_curr_p)
static int dm_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
static void dm_ts_SetTSpace(const SMikkTSpaceContext *pContext, const float fvTangent[3], const float fSign, const int face_num, const int vert_index)
static void dm_ts_GetPosition(const SMikkTSpaceContext *pContext, float r_co[3], const int face_num, const int vert_index)
static void set_tspace(const SMikkTSpaceContext *pContext, const float fv_tangent[3], const float face_sign, const int face_idx, const int vert_idx)
void BKE_mesh_add_loop_tangent_named_layer_for_uv(CustomData *uv_data, CustomData *tan_data, int numLoopData, const char *layer_name)
static void get_normal(const SMikkTSpaceContext *pContext, float r_no[3], const int face_idx, const int vert_idx)
void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData, bool calc_active_tangent, const char(*tangent_names)[MAX_NAME], int tangent_names_count, bool *rcalc_act, bool *rcalc_ren, int *ract_uv_n, int *rren_uv_n, char *ract_uv_name, char *rren_uv_name, short *rtangent_mask)
void BKE_mesh_calc_loop_tangents(Mesh *me_eval, bool calc_active_tangent, const char(*tangent_names)[MAX_NAME], int tangent_names_len)
static void DM_calc_loop_tangents_thread(TaskPool *__restrict UNUSED(pool), void *taskdata)
static int get_num_verts_of_face(const SMikkTSpaceContext *pContext, const int face_idx)
static void dm_ts_GetNormal(const SMikkTSpaceContext *pContext, float r_no[3], const int face_num, const int vert_index)
static void get_texture_coordinate(const SMikkTSpaceContext *pContext, float r_uv[2], const int face_idx, const int vert_idx)
void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, const char *uvmap, float(*r_looptangents)[4], ReportList *reports)
tbool genTangSpaceDefault(const SMikkTSpaceContext *pContext)
bool add(void *owner, const AttributeIDRef &attribute_id, eAttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer)
MutableSpan< float3 > tangents
struct MLoopTri_Store looptris
const float(* precomputedLoopNormals)[3]
const int * face_as_quad_map
const float(* vert_normals)[3]
const float(* precomputedFaceNormals)[3]
SMikkTSpaceInterface * m_pInterface
void(* m_getNormal)(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert)
void(* m_getPosition)(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert)
void(* m_getTexCoord)(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert)
void(* m_setTSpaceBasic)(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert)
int(* m_getNumFaces)(const SMikkTSpaceContext *pContext)
int(* m_getNumVerticesOfFace)(const SMikkTSpaceContext *pContext, const int iFace)