107 const float fv_tangent[3],
108 const float face_sign,
115 p_res[3] = face_sign;
125 const int UNUSED(numVerts),
127 float (*r_looptangent)[4],
128 float (*loopnors)[3],
130 const int UNUSED(numLoops),
143 for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
146 reports,
RPT_ERROR,
"Tangent space can only be computed for tris/quads, aborting");
152 mesh_to_tangent.
mpolys = mpolys;
153 mesh_to_tangent.
mloops = mloops;
154 mesh_to_tangent.
mverts = mverts;
155 mesh_to_tangent.
luvs = loopuvs;
156 mesh_to_tangent.
lnors = loopnors;
157 mesh_to_tangent.
tangents = r_looptangent;
183 float (*r_looptangents)[4],
199 "Tangent space computation needs an UVMap, \"%s\" not found, aborting",
207 reports,
RPT_ERROR,
"Tangent space computation needs loop normals, none found, aborting");
230 #define USE_LOOPTRI_DETECT_QUADS
233 const float (*precomputedFaceNormals)[3];
234 const float (*precomputedLoopNormals)[3];
244 #ifdef USE_LOOPTRI_DETECT_QUADS
258 #ifdef USE_LOOPTRI_DETECT_QUADS
267 #ifdef USE_LOOPTRI_DETECT_QUADS
286 const int vert_index)
294 #ifdef USE_LOOPTRI_DETECT_QUADS
305 lt = &pMesh->
looptri[face_num];
308 lt = &pMesh->
looptri[face_num];
310 loop_index = lt->
tri[vert_index];
320 const int vert_index)
327 #ifdef USE_LOOPTRI_DETECT_QUADS
338 lt = &pMesh->
looptri[face_num];
341 lt = &pMesh->
looptri[face_num];
343 loop_index = lt->
tri[vert_index];
347 const float *uv = pMesh->
mloopuv[loop_index].
uv;
351 const float *orco = pMesh->
orco[pMesh->
mloop[loop_index].
v];
352 map_to_sphere(&r_uv[0], &r_uv[1], orco[0], orco[1], orco[2]);
359 const int vert_index)
377 lt = &pMesh->
looptri[face_num];
380 lt = &pMesh->
looptri[face_num];
382 loop_index = lt->
tri[vert_index];
393 #ifdef USE_LOOPTRI_DETECT_QUADS
413 const short *no = pMesh->
mvert[pMesh->
mloop[loop_index].
v].
no;
419 const float fvTangent[3],
422 const int vert_index)
440 lt = &pMesh->
looptri[face_num];
443 lt = &pMesh->
looptri[face_num];
445 loop_index = lt->
tri[vert_index];
450 pRes = pMesh->
tangent[loop_index];
480 const char *layer_name)
495 bool calc_active_tangent,
496 const char (*tangent_names)[
MAX_NAME],
497 int tangent_names_count,
504 short *rtangent_mask)
510 if (*ract_uv_n != -1) {
511 strcpy(ract_uv_name, loopData->
layers[*ract_uv_n + layer_index].
name);
517 if (*rren_uv_n != -1) {
518 strcpy(rren_uv_name, loopData->
layers[*rren_uv_n + layer_index].
name);
524 for (
int i = 0; i < tangent_names_count; i++) {
525 if (tangent_names[i][0] == 0) {
526 calc_active_tangent =
true;
529 if (calc_active_tangent) {
532 for (
int i = 0; i < tangent_names_count; i++) {
533 if (
STREQ(ract_uv_name, tangent_names[i])) {
536 if (
STREQ(rren_uv_name, tangent_names[i])) {
544 for (
int n = 0; n < uv_layer_num; n++) {
547 for (
int i = 0; i < tangent_names_count; i++) {
548 if (tangent_names[i][0] &&
STREQ(tangent_names[i], name)) {
553 if (!
add && ((*rcalc_act && ract_uv_name[0] &&
STREQ(ract_uv_name, name)) ||
554 (*rcalc_ren && rren_uv_name[0] &&
STREQ(rren_uv_name, name)))) {
558 *rtangent_mask |= (short)(1 << n);
562 if (uv_layer_num == 0) {
572 const uint mpoly_len,
575 const uint looptri_len,
578 bool calc_active_tangent,
579 const char (*tangent_names)[
MAX_NAME],
580 int tangent_names_len,
581 const float (*poly_normals)[3],
582 const float (*loop_normals)[3],
583 const float (*vert_orco)[3],
586 const uint loopdata_out_len,
587 short *tangent_mask_curr_p)
591 bool calc_act =
false;
592 bool calc_ren =
false;
595 short tangent_mask = 0;
596 short tangent_mask_curr = *tangent_mask_curr_p;
609 if ((tangent_mask_curr | tangent_mask) != tangent_mask_curr) {
612 for (
int i = 0; i < tangent_names_len; i++) {
613 if (tangent_names[i][0]) {
615 loopdata, loopdata_out, (
int)loopdata_out_len, tangent_names[i]);
623 if (calc_act && act_uv_name[0]) {
625 loopdata, loopdata_out, (
int)loopdata_out_len, act_uv_name);
627 if (calc_ren && ren_uv_name[0]) {
629 loopdata, loopdata_out, (
int)loopdata_out_len, ren_uv_name);
632 #ifdef USE_LOOPTRI_DETECT_QUADS
637 if (looptri_len != mpoly_len) {
643 for (k = 0, j = 0; j < (int)looptri_len; k++, j++) {
658 if (looptri_len != 0) {
661 tangent_mask_curr = 0;
665 for (
int n = 0; n < tangent_layer_num; n++) {
670 #ifdef USE_LOOPTRI_DETECT_QUADS
689 mesh2tangent->
orco = vert_orco;
690 if (!mesh2tangent->
orco) {
702 tangent_mask_curr |= (short)(1 << (uv_ind - uv_start));
709 BLI_assert(tangent_mask_curr == tangent_mask);
714 tangent_mask_curr = tangent_mask;
716 #ifdef USE_LOOPTRI_DETECT_QUADS
720 # undef USE_LOOPTRI_DETECT_QUADS
724 *tangent_mask_curr_p = tangent_mask_curr;
727 int act_uv_index = (act_uv_n != -1) ?
730 if (act_uv_index != -1) {
737 int ren_uv_index = (ren_uv_n != -1) ?
740 if (ren_uv_index != -1) {
749 bool calc_active_tangent,
750 const char (*tangent_names)[
MAX_NAME],
751 int tangent_names_len)
756 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 struct MLoopTri * BKE_mesh_runtime_looptri_ensure(struct Mesh *mesh)
#define DM_TANGENT_MASK_ORCO
void BKE_report(ReportList *reports, ReportType type, const char *message)
void BKE_reportf(ReportList *reports, ReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const float z)
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])
MINLINE void normal_short_to_float_v3(float r[3], const short n[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, TaskPriority 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)
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)
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(*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)
#define USE_LOOPTRI_DETECT_QUADS
void BKE_mesh_calc_loop_tangent_single_ex(const MVert *mverts, const int UNUSED(numVerts), const MLoop *mloops, float(*r_looptangent)[4], float(*loopnors)[3], const MLoopUV *loopuvs, const int UNUSED(numLoops), const MPoly *mpolys, const int numPolys, ReportList *reports)
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)
static void add(GHash *messages, MemArena *memarena, const Message *msg)
struct MLoopTri_Store looptris
struct CustomData pdata ldata
const float(* precomputedLoopNormals)[3]
const int * face_as_quad_map
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)