Start pruning tris

This commit is contained in:
Miloslav Ciz 2024-07-24 23:16:13 +02:00
parent 5567863745
commit 2d99091cf1
4 changed files with 147 additions and 9 deletions

View file

@ -79,6 +79,126 @@ void _LCR_addMapTriangle(S3L_Index a, S3L_Index b, S3L_Index c)
}
}
void _LCR_rendererSwapTriangles(S3L_Index *t1, S3L_Index *t2)
{
S3L_Index tmp;
for (int i = 0; i < 3; ++i)
{
tmp = t1[i];
t1[i] = t2[i];
t2[i] = tmp;
}
}
/**
Checks whether two triangles (and potenrially their neighbors) cover each
other, in return values lowest bit means whether t1 is covered and the second
lowest bit means whether t2 is covered.
*/
uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
const S3L_Index *t2)
{
if ((t1[0] == t2[0] || t1[0] == t2[1] || t1[0] == t2[2]) &&
(t1[1] == t2[0] || t1[1] == t2[1] || t1[1] == t2[2]) &&
(t1[2] == t2[0] || t1[2] == t2[1] || t1[2] == t2[2]))
return 0x03; // same indices => both are covered
return 0;
}
/**
Removes map triangles that are covered by other triangles (and also vertices
that by this become unused). This makes the map model smaller, faster and
prevents bleeding through due to z-bugger imprecisions.
*/
void _LCR_rendererPruneHiddenMapTriangles(void)
{
int n = 0; // number of removed elements
int i = 0;
S3L_Index *t1 = LCR_mapTriangles, *t2;
/*
We'll be moving the covered triangles to the end of the array, then at the
end we'll just shorten the array.
*/
while (i < LCR_mapModel->triangleCount - n)
{
t2 = t1 + 3;
int t1Covered = 0;
for (int j = i + 1; j < LCR_mapModel->triangleCount; ++j)
{
uint8_t cover = _LCR_rendererCheckMapTriangleCover(t1,t2);
t1Covered |= cover & 0x01;
if (cover & 0x02)
{
if (j < LCR_mapModel->triangleCount - n)
{
_LCR_rendererSwapTriangles(t2,
LCR_mapTriangles + (LCR_mapModel->triangleCount - 1 - n) * 3);
n++;
}
}
t2 += 3;
}
if (t1Covered)
{
_LCR_rendererSwapTriangles(t1,
LCR_mapTriangles + (LCR_mapModel->triangleCount - 1 - n) * 3);
n++;
}
else
{
t1 += 3;
i++;
}
}
LCR_mapModel->triangleCount -= n;
// remove unused vertices:
i = 0;
printf("ASASA %d\n",LCR_mapModel->vertexCount);
while (i < LCR_mapModel->vertexCount)
{
int used = 0;
for (int j = 0; j < LCR_mapModel->triangleCount * 3; ++j)
if (LCR_mapTriangles[j] == i)
{
used = 1;
break;
}
if (used)
i++;
else
{
for (int j = 0; j < 3; ++j)
LCR_mapVertices[3 * i + j] =
LCR_mapVertices[(LCR_mapModel->vertexCount - 1) * 3 + j];
for (int j = 0; j < LCR_mapModel->triangleCount * 3; ++j)
if (LCR_mapTriangles[j] == LCR_mapModel->vertexCount - 1)
LCR_mapTriangles[j] = i;
LCR_mapModel->vertexCount--;
}
}
printf("ASASA %d\n",LCR_mapModel->vertexCount);
}
/**
Builds an internal 3D model of the currently loaded map. Returns 1 on success,
otherwise 0 (e.g. not enough space).
@ -93,9 +213,11 @@ uint8_t _LCR_rendererBuildMapModel(void)
for (int j = 0; j < LCR_currentMap.blockCount; ++j)
{
uint8_t bx, by, bz;
LCR_mapBlockGetCoords(LCR_currentMap.blocks + j * LCR_BLOCK_SIZE,&bx,&by,&bz);
LCR_mapBlockGetCoords(LCR_currentMap.blocks + j * LCR_BLOCK_SIZE,
&bx,&by,&bz);
LCR_mapGetBlockShape(LCR_currentMap.blocks[j * LCR_BLOCK_SIZE],0,
LCR_mapGetBlockShape(LCR_currentMap.blocks[j * LCR_BLOCK_SIZE],
LCR_mapBlockGetTransform(LCR_currentMap.blocks + j * LCR_BLOCK_SIZE),
blockShapeBytes,&blockShapeByteCount);
uint8_t vx, vy, vz, vi = 0;
@ -124,6 +246,8 @@ uint8_t _LCR_rendererBuildMapModel(void)
}
}
_LCR_rendererPruneHiddenMapTriangles();
return 1;
}