Optimize even more

This commit is contained in:
Miloslav Ciz 2024-08-02 01:01:02 +02:00
parent 880ae3c805
commit 5508d80944

View file

@ -21,12 +21,12 @@
struct struct
{ {
S3L_Scene scene3D; S3L_Scene scene;
S3L_Model3D models3D[3]; // TODO S3L_Model3D models[3]; // TODO
S3L_Model3D *mapModel; S3L_Model3D *mapModel;
S3L_Unit mapVertices[LCR_SETTING_MAX_MAP_VERTICES * 3]; S3L_Unit mapVerts[LCR_SETTING_MAX_MAP_VERTICES * 3];
S3L_Index mapTriangles[LCR_SETTING_MAX_MAP_TRIANGLES * 3]; S3L_Index mapTris[LCR_SETTING_MAX_MAP_TRIANGLES * 3];
/** /**
Additional data for triangles. 4 higher bits hold direction (for lighting): Additional data for triangles. 4 higher bits hold direction (for lighting):
@ -36,21 +36,20 @@ struct
uint8_t mapTriangleData[LCR_SETTING_MAX_MAP_TRIANGLES]; uint8_t mapTriangleData[LCR_SETTING_MAX_MAP_TRIANGLES];
// pixel function precomputed values: // pixel function precomputed values:
int previousTriangleID; int previousTriID;
int triangleUVs[6]; int triUVs[6];
} LCR_renderer; } LCR_renderer;
void LCR_pixelFunc3D(S3L_PixelInfo *pixel) void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
{ {
// once we get a new triangle, we precompute things for it: // once we get a new triangle, we precompute things for it:
if (pixel->triangleIndex != LCR_renderer.previousTriangleID) if (pixel->triangleIndex != LCR_renderer.previousTriID)
{ {
S3L_Index *t = LCR_renderer.mapTriangles + 3 * pixel->triangleIndex; S3L_Index *t = LCR_renderer.mapTris + 3 * pixel->triangleIndex;
S3L_Unit *v[3]; S3L_Unit *v[3];
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
v[i] = LCR_renderer.mapVertices + 3 * t[i]; v[i] = LCR_renderer.mapVerts + 3 * t[i];
uint8_t type = LCR_renderer.mapTriangleData[pixel->triangleID] >> 4; uint8_t type = LCR_renderer.mapTriangleData[pixel->triangleID] >> 4;
@ -62,7 +61,7 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
LCR_imageChangeBrightness(1); LCR_imageChangeBrightness(1);
for (int i = 0; i < 6; ++i) for (int i = 0; i < 6; ++i)
LCR_renderer.triangleUVs[i] = (( LCR_renderer.triUVs[i] = ((
(v[i / 2][(i % 2) * 2]) * (v[i / 2][(i % 2) * 2]) *
LCR_IMAGE_SIZE) / LCR_RENDERER_UNIT); LCR_IMAGE_SIZE) / LCR_RENDERER_UNIT);
} }
@ -73,38 +72,38 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
for (int i = 0; i < 6; ++i) for (int i = 0; i < 6; ++i)
{ {
LCR_renderer.triangleUVs[i] = (( LCR_renderer.triUVs[i] = ((
(v[i / 2][i % 2 ? 1 : (type == 1 ? 2 : 0)]) * (v[i / 2][i % 2 ? 1 : (type == 1 ? 2 : 0)]) *
LCR_IMAGE_SIZE) / LCR_RENDERER_UNIT); LCR_IMAGE_SIZE) / LCR_RENDERER_UNIT);
if (i % 2) if (i % 2)
LCR_renderer.triangleUVs[i] = LCR_IMAGE_SIZE - LCR_renderer.triUVs[i] = LCR_IMAGE_SIZE -
LCR_renderer.triangleUVs[i]; LCR_renderer.triUVs[i];
} }
} }
// shift the UVs to the origin (prevent high values of UV coords) // shift the UVs to the origin (prevent high values of UV coords)
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
{ {
uint8_t minCoord = LCR_renderer.triangleUVs[i] < uint8_t minCoord = LCR_renderer.triUVs[i] <
LCR_renderer.triangleUVs[2 + i] ? (0 + i) : (2 + i); LCR_renderer.triUVs[2 + i] ? (0 + i) : (2 + i);
if (LCR_renderer.triangleUVs[4 + i] < LCR_renderer.triangleUVs[minCoord]) if (LCR_renderer.triUVs[4 + i] < LCR_renderer.triUVs[minCoord])
minCoord = 4 + i; minCoord = 4 + i;
S3L_Unit shiftBy = LCR_renderer.triangleUVs[minCoord] % LCR_IMAGE_SIZE; S3L_Unit shiftBy = LCR_renderer.triUVs[minCoord] % LCR_IMAGE_SIZE;
if (shiftBy < 0) if (shiftBy < 0)
shiftBy += LCR_IMAGE_SIZE; shiftBy += LCR_IMAGE_SIZE;
shiftBy -= LCR_renderer.triangleUVs[minCoord]; shiftBy -= LCR_renderer.triUVs[minCoord];
LCR_renderer.triangleUVs[i] += shiftBy; LCR_renderer.triUVs[i] += shiftBy;
LCR_renderer.triangleUVs[2 + i] += shiftBy; LCR_renderer.triUVs[2 + i] += shiftBy;
LCR_renderer.triangleUVs[4 + i] += shiftBy; LCR_renderer.triUVs[4 + i] += shiftBy;
} }
LCR_renderer.previousTriangleID = pixel->triangleIndex; LCR_renderer.previousTriID = pixel->triangleIndex;
} }
int barycentric[3]; int barycentric[3];
@ -114,39 +113,38 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
barycentric[2] = pixel->barycentric[2] / 8; barycentric[2] = pixel->barycentric[2] / 8;
uint16_t color = LCR_sampleImage( uint16_t color = LCR_sampleImage(
(barycentric[0] * LCR_renderer.triangleUVs[0] + (barycentric[0] * LCR_renderer.triUVs[0] +
barycentric[1] * LCR_renderer.triangleUVs[2] + barycentric[1] * LCR_renderer.triUVs[2] +
barycentric[2] * LCR_renderer.triangleUVs[4]) barycentric[2] * LCR_renderer.triUVs[4])
/ (S3L_FRACTIONS_PER_UNIT / 8), / (S3L_FRACTIONS_PER_UNIT / 8),
(barycentric[0] * LCR_renderer.triangleUVs[1] + (barycentric[0] * LCR_renderer.triUVs[1] +
barycentric[1] * LCR_renderer.triangleUVs[3] + barycentric[1] * LCR_renderer.triUVs[3] +
barycentric[2] * LCR_renderer.triangleUVs[5]) barycentric[2] * LCR_renderer.triUVs[5])
/ (S3L_FRACTIONS_PER_UNIT / 8) / (S3L_FRACTIONS_PER_UNIT / 8));
);
LCR_drawPixelXYUnsafe(pixel->x,pixel->y,color); LCR_drawPixelXYUnsafe(pixel->x,pixel->y,color);
} }
S3L_Index _LCR_addMapVertex(S3L_Unit x, S3L_Unit y, S3L_Unit z) S3L_Index _LCR_addMapVert(S3L_Unit x, S3L_Unit y, S3L_Unit z)
{ {
S3L_Index index = 0; S3L_Index index = 0;
S3L_Unit *vertices = LCR_renderer.mapVertices; S3L_Unit *verts = LCR_renderer.mapVerts;
while (index < LCR_renderer.mapModel->vertexCount) // if exists, return vertex index while (index < LCR_renderer.mapModel->vertexCount) // if exists, return index
{ {
if (vertices[0] == x && vertices[1] == y && vertices[2] == z) if (verts[0] == x && verts[1] == y && verts[2] == z)
return index; return index;
vertices += 3; verts += 3;
index++; index++;
} }
// if it doesn't exist, add it // if it doesn't exist, add it
if (LCR_renderer.mapModel->vertexCount < LCR_SETTING_MAX_MAP_VERTICES) if (LCR_renderer.mapModel->vertexCount < LCR_SETTING_MAX_MAP_VERTICES)
{ {
*vertices = x; vertices++; *verts = x; verts++;
*vertices = y; vertices++; *verts = y; verts++;
*vertices = z; *verts = z;
LCR_renderer.mapModel->vertexCount++; LCR_renderer.mapModel->vertexCount++;
return LCR_renderer.mapModel->vertexCount - 1; return LCR_renderer.mapModel->vertexCount - 1;
} }
@ -156,12 +154,12 @@ S3L_Index _LCR_addMapVertex(S3L_Unit x, S3L_Unit y, S3L_Unit z)
return 0; return 0;
} }
void _LCR_addMapTriangle(S3L_Index a, S3L_Index b, S3L_Index c, uint8_t mat) void _LCR_addMapTri(S3L_Index a, S3L_Index b, S3L_Index c, uint8_t mat)
{ {
if (LCR_renderer.mapModel->triangleCount < LCR_SETTING_MAX_MAP_TRIANGLES) if (LCR_renderer.mapModel->triangleCount < LCR_SETTING_MAX_MAP_TRIANGLES)
{ {
S3L_Index *t = S3L_Index *t =
&(LCR_renderer.mapTriangles[LCR_renderer.mapModel->triangleCount * 3]); &(LCR_renderer.mapTris[LCR_renderer.mapModel->triangleCount * 3]);
*t = a; t++; *t = a; t++;
*t = b; t++; *t = b; t++;
@ -174,12 +172,12 @@ void _LCR_addMapTriangle(S3L_Index a, S3L_Index b, S3L_Index c, uint8_t mat)
} }
} }
void _LCR_rendererSwapMapTriangles(unsigned int index1, unsigned int index2) void _LCR_swapMapTris(unsigned int index1, unsigned int index2)
{ {
uint8_t tmpMat; uint8_t tmpMat;
S3L_Index tmpIndex, S3L_Index tmpIndex,
*t1 = LCR_renderer.mapTriangles + index1 * 3, *t1 = LCR_renderer.mapTris + index1 * 3,
*t2 = LCR_renderer.mapTriangles + index2 * 3; *t2 = LCR_renderer.mapTris + index2 * 3;
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
{ {
@ -189,12 +187,11 @@ void _LCR_rendererSwapMapTriangles(unsigned int index1, unsigned int index2)
} }
tmpMat = LCR_renderer.mapTriangleData[index1]; tmpMat = LCR_renderer.mapTriangleData[index1];
LCR_renderer.mapTriangleData[index1] = LCR_renderer.mapTriangleData[index1] = LCR_renderer.mapTriangleData[index2];
LCR_renderer.mapTriangleData[index2];
LCR_renderer.mapTriangleData[index2] = tmpMat; LCR_renderer.mapTriangleData[index2] = tmpMat;
} }
int _LCR_quadCoversTriangle(const S3L_Unit quad[8], const S3L_Unit tri[6]) int _LCR_quadCoversTri(const S3L_Unit quad[8], const S3L_Unit tri[6])
{ {
for (int i = 0; i < 3; ++i) // for each triangle point for (int i = 0; i < 3; ++i) // for each triangle point
{ {
@ -238,7 +235,7 @@ int _LCR_quadCoversTriangle(const S3L_Unit quad[8], const S3L_Unit tri[6])
other, in return values lowest bit means whether t1 is covered and the second other, in return values lowest bit means whether t1 is covered and the second
lowest bit means whether t2 is covered. lowest bit means whether t2 is covered.
*/ */
uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1, uint8_t _LCR_checkMapTriCover(const S3L_Index *t1,
const S3L_Index *t2) const S3L_Index *t2)
{ {
if ((t1[0] == t2[0] || t1[0] == t2[1] || t1[0] == t2[2]) && if ((t1[0] == t2[0] || t1[0] == t2[1] || t1[0] == t2[2]) &&
@ -252,8 +249,8 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
{ {
vertices[i] = LCR_renderer.mapVertices + 3 * t1[i]; vertices[i] = LCR_renderer.mapVerts + 3 * t1[i];
vertices[3 + i] = LCR_renderer.mapVertices + 3 * t2[i]; vertices[3 + i] = LCR_renderer.mapVerts + 3 * t2[i];
} }
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
@ -267,6 +264,12 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
if (plane >= 0) // both triangles in the same plane => then do more checks if (plane >= 0) // both triangles in the same plane => then do more checks
{ {
if (S3L_abs(vertices[0][0] - vertices[3][0]) +
S3L_abs(vertices[0][1] - vertices[3][1]) +
S3L_abs(vertices[0][2] - vertices[3][2]) >
2 * LCR_RENDERER_UNIT)
return 0; // quick manhattan distance bailout condition
for (int j = 0; j < 2; ++j) for (int j = 0; j < 2; ++j)
{ {
S3L_Unit points2D[14]; // tri1, quad (tri2 + 1 extra vert) S3L_Unit points2D[14]; // tri1, quad (tri2 + 1 extra vert)
@ -286,13 +289,13 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
points2D[13] = (4 * points2D[7] + 3 * points2D[9] + points2D[11]) / 8; points2D[13] = (4 * points2D[7] + 3 * points2D[9] + points2D[11]) / 8;
// first: does the triangle alone cover the other one? // first: does the triangle alone cover the other one?
if (_LCR_quadCoversTriangle(points2D + 6,points2D)) if (_LCR_quadCoversTri(points2D + 6,points2D))
result |= 1 << j; result |= 1 << j;
else else
{ {
// now check if this triangle along with a neighbor cover the other one // now check if this triangle along with a neighbor cover the other one
S3L_Index *t3 = LCR_renderer.mapTriangles; S3L_Index *t3 = LCR_renderer.mapTris;
for (int i = 0; i < LCR_renderer.mapModel->triangleCount; ++i) for (int i = 0; i < LCR_renderer.mapModel->triangleCount; ++i)
{ {
@ -304,12 +307,12 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
if ( if (
t3 != t1 && t3 != t2 && t3 != t1 && t3 != t2 &&
(sharedVerts == 3 || sharedVerts == 5 || sharedVerts == 6) && (sharedVerts == 3 || sharedVerts == 5 || sharedVerts == 6) &&
LCR_renderer.mapVertices[3 * t3[0] + plane] == LCR_renderer.mapVerts[3 * t3[0] + plane] ==
LCR_renderer.mapVertices[3 * t3[1] + plane] && LCR_renderer.mapVerts[3 * t3[1] + plane] &&
LCR_renderer.mapVertices[3 * t3[1] + plane] == LCR_renderer.mapVerts[3 * t3[1] + plane] ==
LCR_renderer.mapVertices[3 * t3[2] + plane] && LCR_renderer.mapVerts[3 * t3[2] + plane] &&
LCR_renderer.mapVertices[3 * t3[0] + plane] == LCR_renderer.mapVerts[3 * t3[0] + plane] ==
LCR_renderer.mapVertices[3 * t1[0] + plane] LCR_renderer.mapVerts[3 * t1[0] + plane]
) )
{ {
// here shares exactly two vertices and is in the same plane // here shares exactly two vertices and is in the same plane
@ -317,10 +320,10 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
uint8_t freeVert = uint8_t freeVert =
sharedVerts == 3 ? 2 : (sharedVerts == 5 ? 1 : 0); sharedVerts == 3 ? 2 : (sharedVerts == 5 ? 1 : 0);
points2D[12] = LCR_renderer.mapVertices[3 * t3[freeVert] + coordX]; points2D[12] = LCR_renderer.mapVerts[3 * t3[freeVert] + coordX];
points2D[13] = LCR_renderer.mapVertices[3 * t3[freeVert] + coordY]; points2D[13] = LCR_renderer.mapVerts[3 * t3[freeVert] + coordY];
if (_LCR_quadCoversTriangle(points2D + 6,points2D)) if (_LCR_quadCoversTri(points2D + 6,points2D))
{ {
result |= 1 << j; result |= 1 << j;
break; break;
@ -354,14 +357,14 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
that by this become unused). This makes the map model smaller, faster and that by this become unused). This makes the map model smaller, faster and
prevents bleeding through due to z-bugger imprecisions. prevents bleeding through due to z-bugger imprecisions.
*/ */
void _LCR_rendererCullHiddenMapTriangles(void) void _LCR_cullHiddenMapTris(void)
{ {
LCR_log("culling invisible triangles"); LCR_log("culling invisible triangles");
int n = 0; // number of removed elements int n = 0; // number of removed elements
int i = 0; int i = 0;
S3L_Index *t1 = LCR_renderer.mapTriangles, *t2; S3L_Index *t1 = LCR_renderer.mapTris, *t2;
/* /*
We'll be moving the covered triangles to the end of the array, then at the We'll be moving the covered triangles to the end of the array, then at the
@ -375,7 +378,7 @@ void _LCR_rendererCullHiddenMapTriangles(void)
for (int j = i + 1; j < LCR_renderer.mapModel->triangleCount; ++j) for (int j = i + 1; j < LCR_renderer.mapModel->triangleCount; ++j)
{ {
uint8_t cover = _LCR_rendererCheckMapTriangleCover(t1,t2); uint8_t cover = _LCR_checkMapTriCover(t1,t2);
t1Covered |= cover & 0x01; t1Covered |= cover & 0x01;
@ -383,8 +386,7 @@ void _LCR_rendererCullHiddenMapTriangles(void)
{ {
if (j < LCR_renderer.mapModel->triangleCount - n) if (j < LCR_renderer.mapModel->triangleCount - n)
{ {
_LCR_swapMapTris(j,
_LCR_rendererSwapMapTriangles(j,
LCR_renderer.mapModel->triangleCount - 1 - n); LCR_renderer.mapModel->triangleCount - 1 - n);
n++; n++;
@ -396,7 +398,7 @@ void _LCR_rendererCullHiddenMapTriangles(void)
if (t1Covered) if (t1Covered)
{ {
_LCR_rendererSwapMapTriangles(i, _LCR_swapMapTris(i,
LCR_renderer.mapModel->triangleCount - 1 - n); LCR_renderer.mapModel->triangleCount - 1 - n);
n++; n++;
@ -420,7 +422,7 @@ void _LCR_rendererCullHiddenMapTriangles(void)
int used = 0; int used = 0;
for (int j = 0; j < LCR_renderer.mapModel->triangleCount * 3; ++j) for (int j = 0; j < LCR_renderer.mapModel->triangleCount * 3; ++j)
if (LCR_renderer.mapTriangles[j] == i) if (LCR_renderer.mapTris[j] == i)
{ {
used = 1; used = 1;
break; break;
@ -431,12 +433,12 @@ void _LCR_rendererCullHiddenMapTriangles(void)
else else
{ {
for (int j = 0; j < 3; ++j) for (int j = 0; j < 3; ++j)
LCR_renderer.mapVertices[3 * i + j] = LCR_renderer.mapVerts[3 * i + j] =
LCR_renderer.mapVertices[(LCR_renderer.mapModel->vertexCount - 1) * 3 + j]; LCR_renderer.mapVerts[(LCR_renderer.mapModel->vertexCount - 1) * 3 + j];
for (int j = 0; j < LCR_renderer.mapModel->triangleCount * 3; ++j) for (int j = 0; j < LCR_renderer.mapModel->triangleCount * 3; ++j)
if (LCR_renderer.mapTriangles[j] == LCR_renderer.mapModel->vertexCount - 1) if (LCR_renderer.mapTris[j] == LCR_renderer.mapModel->vertexCount - 1)
LCR_renderer.mapTriangles[j] = i; LCR_renderer.mapTris[j] = i;
LCR_renderer.mapModel->vertexCount--; LCR_renderer.mapModel->vertexCount--;
} }
@ -447,22 +449,22 @@ void _LCR_rendererCullHiddenMapTriangles(void)
Builds the internal 3D model of the currently loaded map. Returns 1 on Builds the internal 3D model of the currently loaded map. Returns 1 on
success, 0 otherwise (e.g. not enough space). success, 0 otherwise (e.g. not enough space).
*/ */
uint8_t _LCR_rendererBuildMapModel(void) uint8_t _LCR_buildMapModel(void)
{ {
LCR_log("building map model"); LCR_log("building map model");
uint8_t blockShapeBytes[LCR_MAP_BLOCK_SHAPE_MAX_BYTES]; uint8_t blockShapeBytes[LCR_MAP_BLOCK_SHAPE_MAX_BYTES];
uint8_t blockShapeByteCount; uint8_t blockShapeByteCount;
S3L_model3DInit(LCR_renderer.mapVertices,0,LCR_renderer.mapTriangles,0,LCR_renderer.mapModel); S3L_model3DInit(LCR_renderer.mapVerts,0,LCR_renderer.mapTris,0,LCR_renderer.mapModel);
for (int j = 0; j < LCR_currentMap.blockCount; ++j) for (int j = 0; j < LCR_currentMap.blockCount; ++j)
{ {
if ((j + 1) % LCR_SETTING_TRIANGLE_CULLING_PERIOD == 0) if ((j + 1) % LCR_SETTING_TRIANGLE_CULLING_PERIOD == 0)
_LCR_rendererCullHiddenMapTriangles(); _LCR_cullHiddenMapTris();
S3L_Unit originOffset = -1 * LCR_MAP_SIZE_BLOCKS / 2 * LCR_RENDERER_UNIT; S3L_Unit originOffset = -1 * LCR_MAP_SIZE_BLOCKS / 2 * LCR_RENDERER_UNIT;
S3L_Index triangleIndices[3]; S3L_Index triIndices[3];
const uint8_t *block = LCR_currentMap.blocks + j * LCR_BLOCK_SIZE; const uint8_t *block = LCR_currentMap.blocks + j * LCR_BLOCK_SIZE;
uint8_t uint8_t
blockType = block[0], blockType = block[0],
@ -492,7 +494,7 @@ uint8_t _LCR_rendererBuildMapModel(void)
((vx == 0) << 2) | ((vx == LCR_BLOCK_SHAPE_COORD_MAX) << 3) | ((vx == 0) << 2) | ((vx == LCR_BLOCK_SHAPE_COORD_MAX) << 3) |
((vz == 0) << 4) | ((vz == LCR_BLOCK_SHAPE_COORD_MAX) << 5); ((vz == 0) << 4) | ((vz == LCR_BLOCK_SHAPE_COORD_MAX) << 5);
triangleIndices[vi] = _LCR_addMapVertex( triIndices[vi] = _LCR_addMapVert(
originOffset + (((S3L_Unit) bx) * LCR_RENDERER_UNIT) + originOffset + (((S3L_Unit) bx) * LCR_RENDERER_UNIT) +
(LCR_RENDERER_UNIT * ((S3L_Unit) vx)) / LCR_BLOCK_SHAPE_COORD_MAX, (LCR_RENDERER_UNIT * ((S3L_Unit) vx)) / LCR_BLOCK_SHAPE_COORD_MAX,
(originOffset + (((S3L_Unit) by) * LCR_RENDERER_UNIT)) / 2 + (originOffset + (((S3L_Unit) by) * LCR_RENDERER_UNIT)) / 2 +
@ -507,18 +509,18 @@ uint8_t _LCR_rendererBuildMapModel(void)
// don't add triangles completely at the floor or ceiling of the map // don't add triangles completely at the floor or ceiling of the map
if (!edgeBits) if (!edgeBits)
{ {
#define VERT(n,c) LCR_renderer.mapVertices[3 * n + c] #define VERT(n,c) LCR_renderer.mapVerts[3 * n + c]
uint8_t blockMat = LCR_mapBlockGetMaterial(block); uint8_t blockMat = LCR_mapBlockGetMaterial(block);
uint8_t triangleData = uint8_t triData =
(((VERT(triangleIndices[0],0) == VERT(triangleIndices[1],0)) && (((VERT(triIndices[0],0) == VERT(triIndices[1],0)) &&
(VERT(triangleIndices[1],0) == VERT(triangleIndices[2],0))) << 4) | (VERT(triIndices[1],0) == VERT(triIndices[2],0))) << 4) |
(((VERT(triangleIndices[0],2) == VERT(triangleIndices[1],2)) && (((VERT(triIndices[0],2) == VERT(triIndices[1],2)) &&
(VERT(triangleIndices[1],2) == VERT(triangleIndices[2],2))) << 5); (VERT(triIndices[1],2) == VERT(triIndices[2],2))) << 5);
#undef VERT #undef VERT
if (triangleData & 0xf0) // wall? if (triData & 0xf0) // wall?
{ {
triangleData |= triData |=
((blockMat == LCR_BLOCK_MATERIAL_CONCRETE) || ((blockMat == LCR_BLOCK_MATERIAL_CONCRETE) ||
(blockMat == LCR_BLOCK_MATERIAL_ICE) || (blockMat == LCR_BLOCK_MATERIAL_ICE) ||
(blockType == LCR_BLOCK_FULL_ACCEL) || (blockType == LCR_BLOCK_FULL_ACCEL) ||
@ -528,26 +530,26 @@ uint8_t _LCR_rendererBuildMapModel(void)
else else
{ // TODO: tidy this mess? { // TODO: tidy this mess?
if (blockType == LCR_BLOCK_FULL_ACCEL) if (blockType == LCR_BLOCK_FULL_ACCEL)
triangleData |= LCR_IMAGE_GROUND_ACCEL; triData |= LCR_IMAGE_GROUND_ACCEL;
else if (blockType == LCR_BLOCK_FULL_STICKER) else if (blockType == LCR_BLOCK_FULL_STICKER)
triangleData |= LCR_IMAGE_GROUND_STICKER; triData |= LCR_IMAGE_GROUND_STICKER;
else else
switch (blockMat) switch (blockMat)
{ {
case LCR_BLOCK_MATERIAL_CONCRETE: case LCR_BLOCK_MATERIAL_CONCRETE:
triangleData |= LCR_IMAGE_GROUND_CONCRETE; triData |= LCR_IMAGE_GROUND_CONCRETE;
break; break;
case LCR_BLOCK_MATERIAL_GRASS: case LCR_BLOCK_MATERIAL_GRASS:
triangleData |= LCR_IMAGE_GROUND_GRASS; triData |= LCR_IMAGE_GROUND_GRASS;
break; break;
case LCR_BLOCK_MATERIAL_DIRT: case LCR_BLOCK_MATERIAL_DIRT:
triangleData |= LCR_IMAGE_GROUND_DIRT; triData |= LCR_IMAGE_GROUND_DIRT;
break; break;
case LCR_BLOCK_MATERIAL_ICE: case LCR_BLOCK_MATERIAL_ICE:
triangleData |= LCR_IMAGE_GROUND_ICE; triData |= LCR_IMAGE_GROUND_ICE;
break; break;
default: default:
@ -555,9 +557,7 @@ uint8_t _LCR_rendererBuildMapModel(void)
} }
} }
_LCR_addMapTriangle( _LCR_addMapTri(triIndices[0],triIndices[1],triIndices[2],triData);
triangleIndices[0],triangleIndices[1],triangleIndices[2],
triangleData);
} }
vi = 0; vi = 0;
@ -567,7 +567,9 @@ uint8_t _LCR_rendererBuildMapModel(void)
// TODO: also cull the triangles in the loop by some N steps // TODO: also cull the triangles in the loop by some N steps
_LCR_rendererCullHiddenMapTriangles(); _LCR_cullHiddenMapTris();
LCR_log("map model built");
return 1; return 1;
} }
@ -576,12 +578,12 @@ uint8_t LCR_rendererInit(void)
{ {
LCR_log("initializing renderer"); LCR_log("initializing renderer");
LCR_renderer.mapModel = LCR_renderer.models3D; LCR_renderer.mapModel = LCR_renderer.models;
if (!_LCR_rendererBuildMapModel()) if (!_LCR_buildMapModel())
return 0; return 0;
S3L_sceneInit(LCR_renderer.models3D,1,&LCR_renderer.scene3D); S3L_sceneInit(LCR_renderer.models,1,&LCR_renderer.scene);
return 1; return 1;
} }
@ -591,32 +593,32 @@ void LCR_rendererMoveCamera(LCR_SpaceUnit forwRightUpOffset[3],
{ {
S3L_Vec4 f, r, u; S3L_Vec4 f, r, u;
S3L_rotationToDirections(LCR_renderer.scene3D.camera.transform.rotation, S3L_rotationToDirections(LCR_renderer.scene.camera.transform.rotation,
S3L_FRACTIONS_PER_UNIT,&f,&r,&u); S3L_FRACTIONS_PER_UNIT,&f,&r,&u);
LCR_renderer.scene3D.camera.transform.translation.x += LCR_renderer.scene.camera.transform.translation.x +=
((f.x * forwRightUpOffset[0] + r.x * forwRightUpOffset[1] + ((f.x * forwRightUpOffset[0] + r.x * forwRightUpOffset[1] +
u.x * forwRightUpOffset[2]) * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN; u.x * forwRightUpOffset[2]) * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN;
LCR_renderer.scene3D.camera.transform.translation.y += LCR_renderer.scene.camera.transform.translation.y +=
((f.y * forwRightUpOffset[0] + r.y * forwRightUpOffset[1] + ((f.y * forwRightUpOffset[0] + r.y * forwRightUpOffset[1] +
u.y * forwRightUpOffset[2]) * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN; u.y * forwRightUpOffset[2]) * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN;
LCR_renderer.scene3D.camera.transform.translation.z += LCR_renderer.scene.camera.transform.translation.z +=
((f.z * forwRightUpOffset[0] + r.z * forwRightUpOffset[1] + ((f.z * forwRightUpOffset[0] + r.z * forwRightUpOffset[1] +
u.z * forwRightUpOffset[2]) * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN; u.z * forwRightUpOffset[2]) * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN;
LCR_renderer.scene3D.camera.transform.rotation.y += LCR_renderer.scene.camera.transform.rotation.y +=
(yawPitchOffset[0] * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN; (yawPitchOffset[0] * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN;
LCR_renderer.scene3D.camera.transform.rotation.x += LCR_renderer.scene.camera.transform.rotation.x +=
(yawPitchOffset[1] * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN; (yawPitchOffset[1] * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN;
if (LCR_renderer.scene3D.camera.transform.rotation.x > S3L_FRACTIONS_PER_UNIT / 4) if (LCR_renderer.scene.camera.transform.rotation.x > S3L_FRACTIONS_PER_UNIT / 4)
LCR_renderer.scene3D.camera.transform.rotation.x = S3L_FRACTIONS_PER_UNIT / 4; LCR_renderer.scene.camera.transform.rotation.x = S3L_FRACTIONS_PER_UNIT / 4;
if (LCR_renderer.scene3D.camera.transform.rotation.x < -1 * S3L_FRACTIONS_PER_UNIT / 4) if (LCR_renderer.scene.camera.transform.rotation.x < -1 * S3L_FRACTIONS_PER_UNIT / 4)
LCR_renderer.scene3D.camera.transform.rotation.x = -1 * S3L_FRACTIONS_PER_UNIT / 4; LCR_renderer.scene.camera.transform.rotation.x = -1 * S3L_FRACTIONS_PER_UNIT / 4;
} }
/** /**
@ -749,14 +751,14 @@ void LCR_rendererDrawSky(int sky, S3L_Unit offsetH, S3L_Unit offsetV)
void LCR_rendererDraw(void) void LCR_rendererDraw(void)
{ {
LCR_renderer.previousTriangleID = -1; LCR_renderer.previousTriID = -1;
S3L_newFrame(); S3L_newFrame();
LCR_rendererDrawSky(2, LCR_rendererDrawSky(2,
LCR_renderer.scene3D.camera.transform.rotation.y, LCR_renderer.scene.camera.transform.rotation.y,
-4 * LCR_renderer.scene3D.camera.transform.rotation.x); -4 * LCR_renderer.scene.camera.transform.rotation.x);
S3L_drawScene(LCR_renderer.scene3D); S3L_drawScene(LCR_renderer.scene);
} }
#endif // guard #endif // guard