38 # define M_PI 3.1415926535897932384626433832795
41 #define INTERNAL_RND_SORT_SEED 39871946
44 # define MIKK_INLINE static __forceinline
46 # define MIKK_INLINE static inline __attribute__((always_inline)) __attribute__((unused))
56 return (
v1.x ==
v2.x) && (
v1.y ==
v2.y) && (
v1.z ==
v2.z);
94 return v.x *
v.x +
v.y *
v.y +
v.z *
v.z;
128 return fabsf(fX) > FLT_MIN;
145 const unsigned int mask = CHAR_BIT *
sizeof(value) - 1;
163 #define MARK_DEGENERATE 1
164 #define QUAD_ONE_DEGEN_TRI 2
165 #define GROUP_WITH_ANY 4
166 #define ORIENT_PRESERVING 8
169 int FaceNeighbors[3];
179 unsigned char vert_num[4];
194 const int iNrTrianglesIn);
197 const int iNrTrianglesIn);
199 const int piTriListIn[],
201 const int iNrTrianglesIn);
204 int piGroupTrianglesBuffer[],
205 const int piTriListIn[],
206 const int iNrTrianglesIn);
210 const int iNrActiveGroups,
211 const int piTriListIn[],
212 const float fThresCos,
217 assert(iVert >= 0 && iVert < 4 && iFace >= 0);
218 return (iFace << 2) | (iVert & 0x3);
223 piVert[0] = iIndexIn & 0x3;
224 piFace[0] = iIndexIn >> 2;
260 const int iNrTrianglesIn,
266 const int iNrTrianglesIn,
277 int *piTriListIn =
NULL, *piGroupTrianglesBuffer =
NULL;
281 int iNrTrianglesIn = 0, f = 0,
t = 0, i = 0;
282 int iNrTSPaces = 0, iTotTris = 0, iDegenTriangles = 0, iNrMaxGroups = 0;
283 int iNrActiveGroups = 0, index = 0;
286 const float fThresCos =
cosf((fAngularThreshold * (
float)
M_PI) / 180.0f);
296 for (f = 0; f < iNrFaces; f++) {
303 if (iNrTrianglesIn <= 0)
307 piTriListIn = (
int *)malloc(
sizeof(
int[3]) * iNrTrianglesIn);
309 if (piTriListIn ==
NULL || pTriInfos ==
NULL) {
310 if (piTriListIn !=
NULL)
312 if (pTriInfos !=
NULL)
326 iTotTris = iNrTrianglesIn;
328 for (
t = 0;
t < iTotTris;
t++) {
329 const int i0 = piTriListIn[
t * 3 + 0];
330 const int i1 = piTriListIn[
t * 3 + 1];
331 const int i2 = piTriListIn[
t * 3 + 2];
335 if (
veq(p0, p1) ||
veq(p0, p2) ||
veq(p1, p2))
341 iNrTrianglesIn = iTotTris - iDegenTriangles;
348 DegenPrologue(pTriInfos, piTriListIn, iNrTrianglesIn, iTotTris);
352 InitTriInfo(pTriInfos, piTriListIn, pContext, iNrTrianglesIn);
356 iNrMaxGroups = iNrTrianglesIn * 3;
357 pGroups = (
SGroup *)malloc(
sizeof(
SGroup) * iNrMaxGroups);
358 piGroupTrianglesBuffer = (
int *)malloc(
sizeof(
int[3]) * iNrTrianglesIn);
359 if (pGroups ==
NULL || piGroupTrianglesBuffer ==
NULL) {
362 if (piGroupTrianglesBuffer !=
NULL)
363 free(piGroupTrianglesBuffer);
370 pTriInfos, pGroups, piGroupTrianglesBuffer, piTriListIn, iNrTrianglesIn);
376 if (psTspace ==
NULL) {
380 free(piGroupTrianglesBuffer);
383 memset(psTspace, 0,
sizeof(
STSpace) * iNrTSPaces);
384 for (
t = 0;
t < iNrTSPaces;
t++) {
385 psTspace[
t].
vOs.
x = 1.0f;
386 psTspace[
t].
vOs.
y = 0.0f;
387 psTspace[
t].
vOs.
z = 0.0f;
389 psTspace[
t].
vOt.
x = 0.0f;
390 psTspace[
t].
vOt.
y = 1.0f;
391 psTspace[
t].
vOt.
z = 0.0f;
400 psTspace, pTriInfos, pGroups, iNrActiveGroups, piTriListIn, fThresCos, pContext);
405 free(piGroupTrianglesBuffer);
420 DegenEpilogue(psTspace, pTriInfos, piTriListIn, pContext, iNrTrianglesIn, iTotTris);
426 for (f = 0; f < iNrFaces; f++) {
453 for (i = 0; i <
verts; i++) {
454 const STSpace *pTSpace = &psTspace[index];
455 float tang[] = {pTSpace->
vOs.
x, pTSpace->
vOs.
y, pTSpace->
vOs.
z};
456 float bitang[] = {pTSpace->
vOt.
x, pTSpace->
vOt.
y, pTSpace->
vOt.
z};
462 pContext, tang, pTSpace->
bOrient ==
TTRUE ? 1.0f : (-1.0f), f, i);
477 const int iNrTrianglesIn);
483 return *((
uint *)(&
v));
486 #define HASH(x, y, z) (((x)*73856093) ^ ((y)*19349663) ^ ((z)*83492791))
487 #define HASH_F(x, y, z) HASH(float_as_uint(x), float_as_uint(y), float_as_uint(z))
494 for (
int pass = 0; pass < 4; pass++, shift += 8) {
497 for (
int i = 0; i < n; i++) {
498 bins[((comp[i] >> shift) & 0xff) + 1]++;
501 for (
int i = 2; i < 256; i++) {
502 bins[i] += bins[i - 1];
505 for (
int i = 0; i < n; i++) {
506 int pos = bins[(comp[i] >> shift) & 0xff]++;
507 comp2[
pos] = comp[i];
515 uint *tmpcomp = comp;
529 const int iNrTrianglesIn)
536 int *temp_indices = (
int *)malloc(
sizeof(
int) *
numVertices);
549 const int index = piTriList_in_and_out[i];
560 hashes[i] =
HASH(hashP, hashN, hashT);
576 int blockend = blockstart + 1;
578 if (hashes[blockend] !=
hash)
582 for (
int i = blockstart; i < blockend; i++) {
583 int index1 = piTriList_in_and_out[
indices[i]];
587 for (
int i2 = i + 1; i2 < blockend; i2++) {
588 int index2 = piTriList_in_and_out[
indices[i2]];
589 if (index1 == index2)
594 piTriList_in_and_out[
indices[i2]] = index1;
604 blockstart = blockend;
613 const int iNrTrianglesIn)
615 int iNumUniqueVerts = 0,
t = 0, i = 0;
616 for (
t = 0;
t < iNrTrianglesIn;
t++) {
617 for (i = 0; i < 3; i++) {
618 const int offs =
t * 3 + i;
619 const int index = piTriList_in_and_out[offs];
626 int t2 = 0, index2rec = -1;
627 while (!bFound && t2 <=
t) {
629 while (!bFound && j < 3) {
630 const int index2 = piTriList_in_and_out[t2 * 3 + j];
635 if (
veq(vP, vP2) &&
veq(vN, vN2) &&
veq(vT, vT2))
646 if (index2rec == index) {
650 piTriList_in_and_out[offs] = index2rec;
658 const int iNrTrianglesIn)
660 int iTSpacesOffs = 0, f = 0,
t = 0;
661 int iDstTriIndex = 0;
671 unsigned char *pVerts = pTriInfos[iDstTriIndex].
vert_num;
675 piTriList_out[iDstTriIndex * 3 + 0] =
MakeIndex(f, 0);
676 piTriList_out[iDstTriIndex * 3 + 1] =
MakeIndex(f, 1);
677 piTriList_out[iDstTriIndex * 3 + 2] =
MakeIndex(f, 2);
683 pTriInfos[iDstTriIndex + 1].
iTSpacesOffs = iTSpacesOffs;
700 tbool bQuadDiagIs_02;
701 if (distSQ_02 < distSQ_13)
702 bQuadDiagIs_02 =
TTRUE;
703 else if (distSQ_13 < distSQ_02)
713 bQuadDiagIs_02 = distSQ_13 < distSQ_02 ?
TFALSE :
TTRUE;
716 if (bQuadDiagIs_02) {
718 unsigned char *pVerts_A = pTriInfos[iDstTriIndex].
vert_num;
723 piTriList_out[iDstTriIndex * 3 + 0] = i0;
724 piTriList_out[iDstTriIndex * 3 + 1] =
i1;
725 piTriList_out[iDstTriIndex * 3 + 2] = i2;
728 unsigned char *pVerts_B = pTriInfos[iDstTriIndex].
vert_num;
733 piTriList_out[iDstTriIndex * 3 + 0] = i0;
734 piTriList_out[iDstTriIndex * 3 + 1] = i2;
735 piTriList_out[iDstTriIndex * 3 + 2] = i3;
740 unsigned char *pVerts_A = pTriInfos[iDstTriIndex].
vert_num;
745 piTriList_out[iDstTriIndex * 3 + 0] = i0;
746 piTriList_out[iDstTriIndex * 3 + 1] =
i1;
747 piTriList_out[iDstTriIndex * 3 + 2] = i3;
750 unsigned char *pVerts_B = pTriInfos[iDstTriIndex].
vert_num;
755 piTriList_out[iDstTriIndex * 3 + 0] =
i1;
756 piTriList_out[iDstTriIndex * 3 + 1] = i2;
757 piTriList_out[iDstTriIndex * 3 + 2] = i3;
763 iTSpacesOffs +=
verts;
764 assert(iDstTriIndex <= iNrTrianglesIn);
767 for (
t = 0;
t < iNrTrianglesIn;
t++)
768 pTriInfos[
t].iFlag = 0;
825 const int piTriListIn[],
826 const int iNrTrianglesIn);
828 const int piTriListIn[],
829 const int iNrTrianglesIn);
838 const float t21x = t2.
x - t1.
x;
839 const float t21y = t2.
y - t1.
y;
840 const float t31x = t3.
x - t1.
x;
841 const float t31y = t3.
y - t1.
y;
843 const float fSignedAreaSTx2 = t21x * t31y - t21y * t31x;
845 return fSignedAreaSTx2 < 0 ? (-fSignedAreaSTx2) : fSignedAreaSTx2;
849 const int piTriListIn[],
851 const int iNrTrianglesIn)
853 int f = 0, i = 0,
t = 0;
858 for (f = 0; f < iNrTrianglesIn; f++)
859 for (i = 0; i < 3; i++) {
863 pTriInfos[f].
vOs.
x = 0.0f;
864 pTriInfos[f].
vOs.
y = 0.0f;
865 pTriInfos[f].
vOs.
z = 0.0f;
866 pTriInfos[f].
vOt.
x = 0.0f;
867 pTriInfos[f].
vOt.
y = 0.0f;
868 pTriInfos[f].
vOt.
z = 0.0f;
869 pTriInfos[f].
fMagS = 0;
870 pTriInfos[f].
fMagT = 0;
877 for (f = 0; f < iNrTrianglesIn; f++) {
886 const float t21x = t2.
x - t1.
x;
887 const float t21y = t2.
y - t1.
y;
888 const float t31x = t3.
x - t1.
x;
889 const float t31y = t3.
y - t1.
y;
893 const float fSignedAreaSTx2 = t21x * t31y - t21y * t31x;
900 if (
NotZero(fSignedAreaSTx2)) {
901 const float fAbsArea =
fabsf(fSignedAreaSTx2);
902 const float fLenOs =
Length(vOs);
903 const float fLenOt =
Length(vOt);
906 pTriInfos[f].vOs =
vscale(fS / fLenOs, vOs);
908 pTriInfos[f].vOt =
vscale(fS / fLenOt, vOt);
911 pTriInfos[f].
fMagS = fLenOs / fAbsArea;
912 pTriInfos[f].
fMagT = fLenOt / fAbsArea;
921 while (
t < (iNrTrianglesIn - 1)) {
931 if ((bIsDeg_a || bIsDeg_b) ==
TFALSE) {
935 if (bOrientA != bOrientB) {
939 bChooseOrientFirstTri =
TTRUE;
940 else if (
CalcTexArea(pContext, &piTriListIn[
t * 3 + 0]) >=
942 bChooseOrientFirstTri =
TTRUE;
946 const int t0 = bChooseOrientFirstTri ?
t : (
t + 1);
947 const int t1 = bChooseOrientFirstTri ? (
t + 1) :
t;
977 const int iMyTriIndex,
983 int piGroupTrianglesBuffer[],
984 const int piTriListIn[],
985 const int iNrTrianglesIn)
987 const int iNrMaxGroups = iNrTrianglesIn * 3;
988 int iNrActiveGroups = 0;
989 int iOffset = 0, f = 0, i = 0;
991 for (f = 0; f < iNrTrianglesIn; f++) {
992 for (i = 0; i < 3; i++) {
996 int neigh_indexL, neigh_indexR;
997 const int vert_index = piTriListIn[f * 3 + i];
998 assert(iNrActiveGroups < iNrMaxGroups);
1010 neigh_indexR = pTriInfos[f].
FaceNeighbors[i > 0 ? (i - 1) : 2];
1011 if (neigh_indexL >= 0)
1014 piTriListIn, pTriInfos, neigh_indexL, pTriInfos[f].AssignedGroup[i]);
1019 assert(bAnswer || bDiff);
1020 (void)bAnswer, (
void)bDiff;
1022 if (neigh_indexR >= 0)
1025 piTriListIn, pTriInfos, neigh_indexR, pTriInfos[f].AssignedGroup[i]);
1030 assert(bAnswer || bDiff);
1031 (void)bAnswer, (
void)bDiff;
1039 assert(iOffset <= iNrMaxGroups);
1044 return iNrActiveGroups;
1055 const int iMyTriIndex,
1058 STriInfo *pMyTriInfo = &psTriInfos[iMyTriIndex];
1062 const int *pVerts = &piTriListIn[3 * iMyTriIndex + 0];
1064 if (pVerts[0] == iVertRep)
1066 else if (pVerts[1] == iVertRep)
1068 else if (pVerts[2] == iVertRep)
1070 assert(i >= 0 && i < 3);
1098 const int neigh_indexR = pMyTriInfo->
FaceNeighbors[i > 0 ? (i - 1) : 2];
1099 if (neigh_indexL >= 0)
1100 AssignRecur(piTriListIn, psTriInfos, neigh_indexL, pGroup);
1101 if (neigh_indexR >= 0)
1102 AssignRecur(piTriListIn, psTriInfos, neigh_indexR, pGroup);
1112 static void QuickSort(
int *pSortBuffer,
int iLeft,
int iRight,
unsigned int uSeed);
1115 const int piTriListIn[],
1118 const int iVertexRepresentitive);
1123 const int iNrActiveGroups,
1124 const int piTriListIn[],
1125 const float fThresCos,
1130 int *pTmpMembers =
NULL;
1131 int iMaxNrFaces = 0, iUniqueTspaces = 0, g = 0, i = 0;
1132 for (g = 0; g < iNrActiveGroups; g++)
1133 if (iMaxNrFaces < pGroups[g].iNrFaces)
1136 if (iMaxNrFaces == 0)
1140 pSubGroupTspace = (
STSpace *)malloc(
sizeof(
STSpace) * iMaxNrFaces);
1142 pTmpMembers = (
int *)malloc(
sizeof(
int) * iMaxNrFaces);
1143 if (pSubGroupTspace ==
NULL || pUniSubGroups ==
NULL || pTmpMembers ==
NULL) {
1144 if (pSubGroupTspace !=
NULL)
1145 free(pSubGroupTspace);
1146 if (pUniSubGroups !=
NULL)
1147 free(pUniSubGroups);
1148 if (pTmpMembers !=
NULL)
1154 for (g = 0; g < iNrActiveGroups; g++) {
1155 const SGroup *pGroup = &pGroups[g];
1156 int iUniqueSubGroups = 0, s = 0;
1158 for (i = 0; i < pGroup->
iNrFaces; i++)
1161 int index = -1, iVertIndex = -1, iOF_1 = -1, iMembers = 0, j = 0,
l = 0;
1165 if (pTriInfos[f].AssignedGroup[0] == pGroup)
1167 else if (pTriInfos[f].AssignedGroup[1] == pGroup)
1169 else if (pTriInfos[f].AssignedGroup[2] == pGroup)
1171 assert(index >= 0 && index < 3);
1173 iVertIndex = piTriListIn[f * 3 + index];
1187 for (j = 0; j < pGroup->
iNrFaces; j++) {
1202 const float fCosS =
vdot(vOs, vOs2);
1203 const float fCosT =
vdot(vOt, vOt2);
1205 assert(f !=
t || bSameOrgFace);
1206 if (bAny || bSameOrgFace || (fCosS > fThresCos && fCosT > fThresCos))
1207 pTmpMembers[iMembers++] =
t;
1216 QuickSort(pTmpMembers, 0, iMembers - 1, uSeed);
1222 while (
l < iUniqueSubGroups && !bFound) {
1229 assert(bFound ||
l == iUniqueSubGroups);
1235 int *pIndices = (
int *)malloc(
sizeof(
int) * iMembers);
1236 if (pIndices ==
NULL) {
1239 for (s = 0; s < iUniqueSubGroups; s++)
1240 free(pUniSubGroups[s].pTriMembers);
1241 free(pUniSubGroups);
1243 free(pSubGroupTspace);
1246 pUniSubGroups[iUniqueSubGroups].
iNrFaces = iMembers;
1247 pUniSubGroups[iUniqueSubGroups].
pTriMembers = pIndices;
1248 memcpy(pIndices, tmp_group.
pTriMembers,
sizeof(
int) * iMembers);
1261 const int iVert = pTriInfos[f].
vert_num[index];
1262 STSpace *pTS_out = &psTspace[iOffs + iVert];
1266 *pTS_out =
AvgTSpace(pTS_out, &pSubGroupTspace[
l]);
1272 *pTS_out = pSubGroupTspace[
l];
1280 for (s = 0; s < iUniqueSubGroups; s++)
1281 free(pUniSubGroups[s].pTriMembers);
1282 iUniqueTspaces += iUniqueSubGroups;
1286 free(pUniSubGroups);
1288 free(pSubGroupTspace);
1295 const int piTriListIn[],
1298 const int iVertexRepresentitive)
1301 float fAngleSum = 0;
1312 for (face = 0; face < iFaces; face++) {
1313 const int f = face_indices[face];
1318 float fCos,
fAngle, fMagS, fMagT;
1319 int i = -1, index = -1, i0 = -1,
i1 = -1, i2 = -1;
1320 if (piTriListIn[3 * f + 0] == iVertexRepresentitive)
1322 else if (piTriListIn[3 * f + 1] == iVertexRepresentitive)
1324 else if (piTriListIn[3 * f + 2] == iVertexRepresentitive)
1326 assert(i >= 0 && i < 3);
1329 index = piTriListIn[3 * f + i];
1334 i2 = piTriListIn[3 * f + (i < 2 ? (i + 1) : 0)];
1335 i1 = piTriListIn[3 * f + i];
1336 i0 = piTriListIn[3 * f + (i > 0 ? (i - 1) : 2)];
1351 fCos = fCos > 1 ? 1 : (fCos < (-1) ? (-1) : fCos);
1353 fMagS = pTriInfos[f].
fMagS;
1354 fMagT = pTriInfos[f].
fMagT;
1367 if (fAngleSum > 0) {
1368 res.
fMagS /= fAngleSum;
1369 res.
fMagT /= fAngleSum;
1381 while (i < pg1->iNrFaces && bStillSame) {
1389 static void QuickSort(
int *pSortBuffer,
int iLeft,
int iRight,
unsigned int uSeed)
1391 int iL, iR, n, index, iMid, iTmp;
1394 unsigned int t = uSeed & 31;
1396 uSeed = uSeed +
t + 3;
1403 index = (int)(uSeed % (
unsigned int)n);
1405 iMid = pSortBuffer[index + iL];
1408 while (pSortBuffer[iL] < iMid)
1410 while (pSortBuffer[iR] > iMid)
1414 iTmp = pSortBuffer[iL];
1415 pSortBuffer[iL] = pSortBuffer[iR];
1416 pSortBuffer[iR] = iTmp;
1423 QuickSort(pSortBuffer, iLeft, iR, uSeed);
1425 QuickSort(pSortBuffer, iL, iRight, uSeed);
1432 SEdge *pSortBuffer,
int iLeft,
int iRight,
const int channel,
unsigned int uSeed);
1433 static void GetEdge(
int *i0_out,
1442 const int piTriListIn[],
1443 const int iNrTrianglesIn)
1447 int iEntries = 0, iCurStartIndex = -1, f = 0, i = 0;
1448 for (f = 0; f < iNrTrianglesIn; f++)
1449 for (i = 0; i < 3; i++) {
1450 const int i0 = piTriListIn[f * 3 + i];
1451 const int i1 = piTriListIn[f * 3 + (i < 2 ? (i + 1) : 0)];
1452 pEdges[f * 3 + i].
i0 = i0 <
i1 ? i0 :
i1;
1453 pEdges[f * 3 + i].
i1 = !(i0 <
i1) ? i0 :
i1;
1454 pEdges[f * 3 + i].
f = f;
1463 iEntries = iNrTrianglesIn * 3;
1465 for (i = 1; i < iEntries; i++) {
1466 if (pEdges[iCurStartIndex].i0 != pEdges[i].i0) {
1467 const int iL = iCurStartIndex;
1468 const int iR = i - 1;
1479 for (i = 1; i < iEntries; i++) {
1480 if (pEdges[iCurStartIndex].i0 != pEdges[i].i0 || pEdges[iCurStartIndex].
i1 != pEdges[i].
i1) {
1481 const int iL = iCurStartIndex;
1482 const int iR = i - 1;
1490 for (i = 0; i < iEntries; i++) {
1491 const int i0 = pEdges[i].
i0;
1492 const int i1 = pEdges[i].
i1;
1493 const int f = pEdges[i].
f;
1494 tbool bUnassigned_A;
1497 int edgenum_A, edgenum_B = 0;
1501 &piTriListIn[f * 3],
1506 if (bUnassigned_A) {
1510 while (j < iEntries && i0 == pEdges[j].i0 &&
i1 == pEdges[j].
i1 && bNotFound) {
1511 tbool bUnassigned_B;
1518 &piTriListIn[
t * 3],
1523 if (i0_A == i0_B && i1_A == i1_B && bUnassigned_B)
1530 int t = pEdges[j].
f;
1540 const int piTriListIn[],
1541 const int iNrTrianglesIn)
1544 for (f = 0; f < iNrTrianglesIn; f++) {
1545 for (i = 0; i < 3; i++) {
1547 if (pTriInfos[f].FaceNeighbors[i] == -1) {
1548 const int i0_A = piTriListIn[f * 3 + i];
1549 const int i1_A = piTriListIn[f * 3 + (i < 2 ? (i + 1) : 0)];
1554 while (!bFound &&
t < iNrTrianglesIn) {
1557 while (!bFound && j < 3) {
1559 const int i1_B = piTriListIn[
t * 3 + j];
1560 const int i0_B = piTriListIn[
t * 3 + (j < 2 ? (j + 1) : 0)];
1562 if (i0_A == i0_B && i1_A == i1_B)
1585 SEdge *pSortBuffer,
int iLeft,
int iRight,
const int channel,
unsigned int uSeed)
1588 int iL, iR, n, index, iMid;
1592 const int iElems = iRight - iLeft + 1;
1595 else if (iElems == 2) {
1596 if (pSortBuffer[iLeft].
array[channel] > pSortBuffer[iRight].
array[channel]) {
1597 sTmp = pSortBuffer[iLeft];
1598 pSortBuffer[iLeft] = pSortBuffer[iRight];
1599 pSortBuffer[iRight] = sTmp;
1603 else if (iElems < 16) {
1605 for (i = 0; i < iElems - 1; i++) {
1606 for (j = 0; j < iElems - i - 1; j++) {
1607 int index = iLeft + j;
1608 if (pSortBuffer[index].
array[channel] > pSortBuffer[index + 1].
array[channel]) {
1609 sTmp = pSortBuffer[index];
1610 pSortBuffer[index] = pSortBuffer[index + 1];
1611 pSortBuffer[index + 1] = sTmp;
1621 uSeed = uSeed +
t + 3;
1628 index = (int)(uSeed % (
unsigned int)n);
1630 iMid = pSortBuffer[index + iL].
array[channel];
1633 while (pSortBuffer[iL].
array[channel] < iMid)
1635 while (pSortBuffer[iR].
array[channel] > iMid)
1639 sTmp = pSortBuffer[iL];
1640 pSortBuffer[iL] = pSortBuffer[iR];
1641 pSortBuffer[iR] = sTmp;
1689 int piTriList_out[],
1690 const int iNrTrianglesIn,
1693 int iNextGoodTriangleSearchIndex = -1;
1694 tbool bStillFindingGoodOnes;
1698 while (
t < (iTotTris - 1)) {
1705 if ((bIsDeg_a ^ bIsDeg_b) != 0) {
1717 iNextGoodTriangleSearchIndex = 1;
1719 bStillFindingGoodOnes =
TTRUE;
1720 while (
t < iNrTrianglesIn && bStillFindingGoodOnes) {
1723 if (iNextGoodTriangleSearchIndex < (
t + 2))
1724 iNextGoodTriangleSearchIndex =
t + 2;
1730 while (bJustADegenerate && iNextGoodTriangleSearchIndex < iTotTris) {
1736 bJustADegenerate =
TFALSE;
1738 ++iNextGoodTriangleSearchIndex;
1742 t1 = iNextGoodTriangleSearchIndex;
1743 ++iNextGoodTriangleSearchIndex;
1744 assert(iNextGoodTriangleSearchIndex > (
t + 1));
1747 if (!bJustADegenerate) {
1749 for (i = 0; i < 3; i++) {
1750 const int index = piTriList_out[t0 * 3 + i];
1751 piTriList_out[t0 * 3 + i] = piTriList_out[t1 * 3 + i];
1752 piTriList_out[t1 * 3 + i] = index;
1755 const STriInfo tri_info = pTriInfos[t0];
1756 pTriInfos[t0] = pTriInfos[t1];
1757 pTriInfos[t1] = tri_info;
1761 bStillFindingGoodOnes =
TFALSE;
1764 if (bStillFindingGoodOnes)
1768 assert(bStillFindingGoodOnes);
1769 assert(iNrTrianglesIn ==
t);
1779 const int iNrTrianglesIn,
1785 for (
t = 0;
t < 3 * iNrTrianglesIn;
t++) {
1786 int iVertIndex = piTriListIn[
t];
1805 for (
t = 0;
t < 3 * iNrTrianglesIn;
t++) {
1806 int iVertIndex = piTriListIn[
t];
1807 if (pLookupCtx->
pLookup[iVertIndex] != -1) {
1810 pLookupCtx->
pLookup[iVertIndex] =
t;
1816 const int iNrTrianglesIn,
1817 const int iVertexIndex)
1832 return pLookupCtx->
pLookup[iVertexIndex];
1849 const int iNrTrianglesIn,
1856 for (
t = iNrTrianglesIn;
t < iTotTris;
t++) {
1864 for (i = 0; i < 3; i++) {
1865 const int index1 = piTriListIn[
t * 3 + i];
1872 const int iTri = j / 3;
1873 const int iVert = j % 3;
1874 const int iSrcVert = pTriInfos[iTri].
vert_num[iVert];
1876 const int iDstVert = pTriInfos[
t].
vert_num[i];
1879 psTspace[iDstOffs + iDstVert] = psTspace[iSrcOffs + iSrcVert];
1885 for (
t = 0;
t < iNrTrianglesIn;
t++) {
1890 int iOrgF = -1, i = 0;
1892 unsigned char *pV = pTriInfos[
t].
vert_num;
1893 int iFlag = (1 << pV[0]) | (1 << pV[1]) | (1 << pV[2]);
1894 int iMissingIndex = 0;
1895 if ((iFlag & 2) == 0)
1897 else if ((iFlag & 4) == 0)
1899 else if ((iFlag & 8) == 0)
1906 while (bNotFound && i < 3) {
1907 const int iVert = pV[i];
1911 psTspace[iOffs + iMissingIndex] = psTspace[iOffs + iVert];
typedef float(TangentPoint)[2]
void BLI_kdtree_nd_() free(KDTree *tree)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint i1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Normalize
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
static const float data2[18 *GP_PRIM_DATABUF_SIZE]
static tbool AssignRecur(const int piTriListIn[], STriInfo psTriInfos[], const int iMyTriIndex, SGroup *pGroup)
static void radixsort_pair(uint *comp, int *data, uint *comp2, int *data2, int n)
struct VertReverseLookupContext VertReverseLookupContext
static int Build4RuleGroups(STriInfo pTriInfos[], SGroup pGroups[], int piGroupTrianglesBuffer[], const int piTriListIn[], const int iNrTrianglesIn)
MIKK_INLINE tbool veq(const SVec3 v1, const SVec3 v2)
MIKK_INLINE tbool NotZero(const float fX)
MIKK_INLINE float LengthSquared(const SVec3 v)
static void GenerateSharedVerticesIndexListSlow(int piTriList_in_and_out[], const SMikkTSpaceContext *pContext, const int iNrTrianglesIn)
static void GetEdge(int *i0_out, int *i1_out, int *edgenum_out, const int indices[], const int i0_in, const int i1_in)
MIKK_INLINE float Length(const SVec3 v)
static void QuickSort(int *pSortBuffer, int iLeft, int iRight, unsigned int uSeed)
#define ORIENT_PRESERVING
MIKK_INLINE SVec3 GetTexCoord(const SMikkTSpaceContext *pContext, const int index)
#define QUAD_ONE_DEGEN_TRI
MIKK_INLINE SVec3 vsub(const SVec3 v1, const SVec3 v2)
MIKK_INLINE unsigned int rotl(unsigned int value, unsigned int count)
tbool genTangSpace(const SMikkTSpaceContext *pContext, const float fAngularThreshold)
static int LookupVertexIndexFromGoodTriangle(VertReverseLookupContext *pLookupCtx, int piTriListIn[], const int iNrTrianglesIn, const int iVertexIndex)
MIKK_INLINE SVec3 GetPosition(const SMikkTSpaceContext *pContext, const int index)
MIKK_INLINE SVec3 GetNormal(const SMikkTSpaceContext *pContext, const int index)
static uint float_as_uint(const float v)
MIKK_INLINE SVec3 vadd(const SVec3 v1, const SVec3 v2)
static void DegenPrologue(STriInfo pTriInfos[], int piTriList_out[], const int iNrTrianglesIn, const int iTotTris)
tbool genTangSpaceDefault(const SMikkTSpaceContext *pContext)
static void InitTriInfo(STriInfo pTriInfos[], const int piTriListIn[], const SMikkTSpaceContext *pContext, const int iNrTrianglesIn)
#define INTERNAL_RND_SORT_SEED
static int GenerateInitialVerticesIndexList(STriInfo pTriInfos[], int piTriList_out[], const SMikkTSpaceContext *pContext, const int iNrTrianglesIn)
static void GenerateReverseLookup(const int piTriListIn[], const int iNrTrianglesIn, VertReverseLookupContext *pLookupCtx)
MIKK_INLINE SVec3 NormalizeSafe(const SVec3 v)
static float CalcTexArea(const SMikkTSpaceContext *pContext, const int indices[])
MIKK_INLINE SVec3 vscale(const float fS, const SVec3 v)
MIKK_INLINE int MakeIndex(const int iFace, const int iVert)
static void FreeReverseLookup(VertReverseLookupContext *pLookupCtx)
static void DegenEpilogue(STSpace psTspace[], STriInfo pTriInfos[], int piTriListIn[], const SMikkTSpaceContext *pContext, const int iNrTrianglesIn, const int iTotTris)
static void GenerateSharedVerticesIndexList(int piTriList_in_and_out[], const SMikkTSpaceContext *pContext, const int iNrTrianglesIn)
MIKK_INLINE float vdot(const SVec3 v1, const SVec3 v2)
static tbool GenerateTSpaces(STSpace psTspace[], const STriInfo pTriInfos[], const SGroup pGroups[], const int iNrActiveGroups, const int piTriListIn[], const float fThresCos, const SMikkTSpaceContext *pContext)
static void BuildNeighborsFast(STriInfo pTriInfos[], SEdge *pEdges, const int piTriListIn[], const int iNrTrianglesIn)
static STSpace EvalTspace(int face_indices[], const int iFaces, const int piTriListIn[], const STriInfo pTriInfos[], const SMikkTSpaceContext *pContext, const int iVertexRepresentitive)
static tbool CompareSubGroups(const SSubGroup *pg1, const SSubGroup *pg2)
static void QuickSortEdges(SEdge *pSortBuffer, int iLeft, int iRight, const int channel, unsigned int uSeed)
static STSpace AvgTSpace(const STSpace *pTS0, const STSpace *pTS1)
MIKK_INLINE void IndexToData(int *piFace, int *piVert, const int iIndexIn)
static void BuildNeighborsSlow(STriInfo pTriInfos[], const int piTriListIn[], const int iNrTrianglesIn)
MIKK_INLINE void AddTriToGroup(SGroup *pGroup, const int iTriIndex)
INLINE Rall1d< T, V, S > acos(const Rall1d< T, V, S > &x)
tbool bOrientPreservering
int iVertexRepresentitive
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_setTSpace)(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT, const tbool bIsOrientationPreserving, 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)
SGroup * AssignedGroup[3]
unsigned char vert_num[4]
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)