Start pruning tris
This commit is contained in:
parent
5567863745
commit
2d99091cf1
4 changed files with 147 additions and 9 deletions
4
TODO.txt
4
TODO.txt
|
@ -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
|
- sky images could be just composed of 4x4 normal images? then we only need
|
||||||
one type of image
|
one type of image
|
||||||
- map actually in ASCII format? how will humans edit it?
|
- map actually in ASCII format? how will humans edit it?
|
||||||
|
|
10
assets.h
10
assets.h
|
@ -15,7 +15,15 @@ static const uint8_t map1[] =
|
||||||
0,
|
0,
|
||||||
LCR_MAP_BLOCK(LCR_BLOCK_FULL,32,32,32,LCR_BLOCK_MATERIAL_CONCRETE,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_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
|
LCR_MAP_TERMINATOR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
14
map.h
14
map.h
|
@ -45,8 +45,6 @@
|
||||||
coordinate number.
|
coordinate number.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LCR_BLOCK_TRANSFORM_ROT_MASK 0x60
|
|
||||||
|
|
||||||
#define LCR_BLOCK_TRANSFORM_FLIP_H 0x10
|
#define LCR_BLOCK_TRANSFORM_FLIP_H 0x10
|
||||||
#define LCR_BLOCK_TRANSFORM_ROT_90 0x20
|
#define LCR_BLOCK_TRANSFORM_ROT_90 0x20
|
||||||
#define LCR_BLOCK_TRANSFORM_ROT_180 0x40
|
#define LCR_BLOCK_TRANSFORM_ROT_180 0x40
|
||||||
|
@ -59,10 +57,9 @@
|
||||||
#define LCR_MAP_MAGIC_NUMBER2 'M'
|
#define LCR_MAP_MAGIC_NUMBER2 'M'
|
||||||
#define LCR_MAP_MAGIC_NUMBER LCR_MAP_MAGIC_NUMBER1, LCR_MAP_MAGIC_NUMBER2
|
#define LCR_MAP_MAGIC_NUMBER LCR_MAP_MAGIC_NUMBER1, LCR_MAP_MAGIC_NUMBER2
|
||||||
#define LCR_MAP_TERMINATOR 0xff
|
#define LCR_MAP_TERMINATOR 0xff
|
||||||
#define LCR_MAP_BLOCK(t,x,y,z,m,r) t,(unsigned char) (x | (y << 6)), \
|
#define LCR_MAP_BLOCK(t,x,y,z,m,r) t,(uint8_t) (x | (y << 6)), \
|
||||||
(unsigned char) ((y >> 2) | (z << 4)), \
|
(uint8_t) ((y >> 2) | (z << 4)), \
|
||||||
(unsigned char) ((z >> 4) | (m << 2) | \
|
(uint8_t) ((z >> 4) | (m << 2) | (r))
|
||||||
(r << 4))
|
|
||||||
|
|
||||||
#define LCR_BLOCK_SIZE 4 ///< size of map block, in bytes
|
#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);
|
*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])
|
uint32_t LCR_mapBlockGetCoordNumber(const uint8_t block[LCR_BLOCK_SIZE])
|
||||||
{
|
{
|
||||||
return block[1] | (((uint32_t) block[2]) << 8) |
|
return block[1] | (((uint32_t) block[2]) << 8) |
|
||||||
|
|
128
renderer.h
128
renderer.h
|
@ -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,
|
Builds an internal 3D model of the currently loaded map. Returns 1 on success,
|
||||||
otherwise 0 (e.g. not enough space).
|
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)
|
for (int j = 0; j < LCR_currentMap.blockCount; ++j)
|
||||||
{
|
{
|
||||||
uint8_t bx, by, bz;
|
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);
|
blockShapeBytes,&blockShapeByteCount);
|
||||||
|
|
||||||
uint8_t vx, vy, vz, vi = 0;
|
uint8_t vx, vy, vz, vi = 0;
|
||||||
|
@ -124,6 +246,8 @@ uint8_t _LCR_rendererBuildMapModel(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_LCR_rendererPruneHiddenMapTriangles();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue