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

@ -1,3 +1,7 @@
- based viewing distance idea: limit number of rendered map triangles to N, keep
sorting the triangle array by distance continually! e.g. in each frame handle
one of the N visible triangles like this -- in the non-visible triangles
find one that is closer than this and switch them (if found).
- sky images could be just composed of 4x4 normal images? then we only need
one type of image
- map actually in ASCII format? how will humans edit it?

View file

@ -15,7 +15,15 @@ static const uint8_t map1[] =
0,
LCR_MAP_BLOCK(LCR_BLOCK_FULL,32,32,32,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,32,32,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_WALL,34,32,32,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_WALL,34,32,32,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_90),
LCR_MAP_BLOCK(LCR_BLOCK_FULL,32,33,32,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,33,32,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_FULL,32,33,33,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,33,33,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_FULL,32,32,33,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,32,33,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_TERMINATOR
};

14
map.h
View file

@ -45,8 +45,6 @@
coordinate number.
*/
#define LCR_BLOCK_TRANSFORM_ROT_MASK 0x60
#define LCR_BLOCK_TRANSFORM_FLIP_H 0x10
#define LCR_BLOCK_TRANSFORM_ROT_90 0x20
#define LCR_BLOCK_TRANSFORM_ROT_180 0x40
@ -59,10 +57,9 @@
#define LCR_MAP_MAGIC_NUMBER2 'M'
#define LCR_MAP_MAGIC_NUMBER LCR_MAP_MAGIC_NUMBER1, LCR_MAP_MAGIC_NUMBER2
#define LCR_MAP_TERMINATOR 0xff
#define LCR_MAP_BLOCK(t,x,y,z,m,r) t,(unsigned char) (x | (y << 6)), \
(unsigned char) ((y >> 2) | (z << 4)), \
(unsigned char) ((z >> 4) | (m << 2) | \
(r << 4))
#define LCR_MAP_BLOCK(t,x,y,z,m,r) t,(uint8_t) (x | (y << 6)), \
(uint8_t) ((y >> 2) | (z << 4)), \
(uint8_t) ((z >> 4) | (m << 2) | (r))
#define LCR_BLOCK_SIZE 4 ///< size of map block, in bytes
@ -136,6 +133,11 @@ void LCR_mapBlockGetCoords(const uint8_t block[LCR_BLOCK_SIZE],
*z = (block[2] >> 4) | ((block[3] & 0x03) << 4);
}
uint8_t LCR_mapBlockGetTransform(const uint8_t block[LCR_BLOCK_SIZE])
{
return block[3] & 0xf0;
}
uint32_t LCR_mapBlockGetCoordNumber(const uint8_t block[LCR_BLOCK_SIZE])
{
return block[1] | (((uint32_t) block[2]) << 8) |

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;
}