Animate car

This commit is contained in:
Miloslav Ciz 2024-09-01 14:06:24 +02:00
parent 4e645b4c0f
commit 920ddc4981
4 changed files with 153 additions and 69 deletions

View file

@ -41,6 +41,7 @@ static const uint8_t map1[] =
LCR_MAP_BLOCK(LCR_BLOCK_FULL,2,25,50,LCR_BLOCK_MATERIAL_GRASS,0), LCR_MAP_BLOCK(LCR_BLOCK_FULL,2,25,50,LCR_BLOCK_MATERIAL_GRASS,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,3,3,3,0,0), LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,3,3,3,0,0),
/*
LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,0,0,LCR_BLOCK_MATERIAL_GRASS,0), LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,0,0,LCR_BLOCK_MATERIAL_GRASS,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,40,1,1,0,0), LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,40,1,1,0,0),
@ -49,7 +50,7 @@ static const uint8_t map1[] =
LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,15,0,LCR_BLOCK_MATERIAL_GRASS,0), LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,15,0,LCR_BLOCK_MATERIAL_GRASS,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,7,4,8,0,0), LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,7,4,8,0,0),
*/
/* /*
LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,15,0,LCR_BLOCK_MATERIAL_GRASS,0), LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,15,0,LCR_BLOCK_MATERIAL_GRASS,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,7,4,8,0,0), LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,7,4,8,0,0),
@ -6223,9 +6224,6 @@ uint16_t LCR_getNextImagePixel(void)
return r; return r;
} }
#define LCR_CAR_VERTEX_COUNT 124 #define LCR_CAR_VERTEX_COUNT 124
#define LCR_CAR_TRIANGLE_COUNT 228 #define LCR_CAR_TRIANGLE_COUNT 228
@ -6330,26 +6328,26 @@ static const uint16_t LCR_carTriangles[] =
static const uint16_t LCR_carUvs[] = static const uint16_t LCR_carUvs[] =
{ {
107, 233, 64, 134, 123, 192, 66, 251, 63, 292, 107, 278, 64, 377, 123, 319, 66, 260, 63, 219,
125, 323, 63, 323, 125, 353, 63, 353, 4, 353, 125, 188, 63, 188, 125, 158, 63, 158, 4, 158,
4, 323, 4, 292, 4, 260, 63, 260, 125, 260, 4, 188, 4, 219, 4, 251, 63, 251, 125, 251,
125, 477, 63, 509, 63, 477, 4, 477, 4, 446, 125, 34, 63, 2, 63, 34, 4, 34, 4, 65,
63, 446, 125, 446, 4, 415, 63, 415, 125, 415, 63, 65, 125, 65, 4, 96, 63, 96, 125, 96,
125, 384, 63, 384, 4, 384, 105, 151, 24, 235, 125, 127, 63, 127, 4, 127, 105, 360, 24, 276,
6, 194, 23, 152, 24, 235, 64, 134, 66, 251, 6, 317, 23, 359, 24, 276, 64, 377, 66, 260,
6, 194, 23, 152, 107, 233, 124, 191, 106, 150, 6, 317, 23, 359, 107, 278, 124, 320, 106, 361,
125, 292, 125, 509, 4, 509, 254, 315, 249, 398, 125, 219, 125, 2, 4, 2, 254, 196, 249, 113,
374, 397, 252, 501, 366, 501, 505, 270, 402, 274, 374, 114, 252, 10, 366, 10, 505, 241, 402, 237,
505, 166, 108, 119, 62, 17, 62, 114, 449, 436, 505, 345, 108, 392, 62, 494, 62, 397, 449, 75,
205, 117, 108, 11, 9, 112, 9, 19, 186, 415, 205, 394, 108, 500, 9, 399, 9, 492, 186, 96,
307, 124, 205, 14, 437, 14, 398, 17, 437, 116, 307, 387, 205, 497, 437, 497, 398, 494, 437, 395,
502, 113, 502, 17, 234, 317, 131, 340, 411, 312, 502, 398, 502, 494, 234, 194, 131, 171, 411, 199,
374, 318, 239, 272, 263, 303, 490, 429, 505, 355, 374, 193, 239, 239, 263, 208, 490, 82, 505, 156,
135, 403, 307, 7, 398, 114, 239, 164, 131, 271, 135, 108, 307, 504, 398, 397, 239, 347, 131, 240,
131, 165, 402, 162, 381, 297, 255, 315, 374, 319, 131, 346, 402, 349, 381, 214, 255, 196, 374, 192,
373, 399, 249, 399, 366, 502, 449, 436, 252, 502, 373, 112, 249, 112, 366, 9, 449, 75, 252, 9,
186, 416, 234, 317, 130, 340, 412, 313, 263, 134, 186, 95, 234, 194, 130, 171, 412, 198, 263, 377,
490, 429, 505, 355, 134, 403, 381, 139 490, 82, 505, 156, 134, 108, 381, 372
}; };
static const uint16_t LCR_carTriangleUvs[] = static const uint16_t LCR_carTriangleUvs[] =
@ -6411,16 +6409,13 @@ static const uint16_t LCR_carTriangleUvs[] =
static const uint8_t LCR_carVertexTypes[] = static const uint8_t LCR_carVertexTypes[] =
{ {
3, 3, 2, 3, 3, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 3, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 1, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1,
0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}; };
#endif #endif

View file

@ -69,17 +69,20 @@ int main(void)
n,n + 1,n + 2,n + 3,n + 4,n + 5) != 6) n,n + 1,n + 2,n + 3,n + 4,n + 5) != 6)
error(0); error(0);
triangles[triangleCount * 3] = n[0] - 1; for (int i = 0; i < 6; ++i)
triangles[triangleCount * 3 + 1] = n[2] - 1; n[i]--; // obj indices are 1-based
triangles[triangleCount * 3 + 2] = n[4] - 1;
triangleUvs[triangleCount * 3] = n[1] - 1; triangles[triangleCount * 3] = n[0];
triangleUvs[triangleCount * 3 + 1] = n[3] - 1; triangles[triangleCount * 3 + 1] = n[4];
triangleUvs[triangleCount * 3 + 2] = n[5] - 1; triangles[triangleCount * 3 + 2] = n[2];
vertexTypes[n[0] - 1] = vertexType; triangleUvs[triangleCount * 3] = n[1];
vertexTypes[n[1] - 1] = vertexType; triangleUvs[triangleCount * 3 + 1] = n[5];
vertexTypes[n[2] - 1] = vertexType; triangleUvs[triangleCount * 3 + 2] = n[3];
vertexTypes[n[0]] = vertexType;
vertexTypes[n[2]] = vertexType;
vertexTypes[n[4]] = vertexType;
triangleCount++; triangleCount++;
@ -110,7 +113,7 @@ int main(void)
error(4); error(4);
uvs[2 * uvCount] = a * UNIT; uvs[2 * uvCount] = a * UNIT;
uvs[2 * uvCount + 1] = b * UNIT; uvs[2 * uvCount + 1] = (1 - b) * UNIT;
uvCount++; uvCount++;

View file

@ -44,6 +44,8 @@ struct
*/ */
S3L_Model3D models[LCR_RENDERER_MODEL_COUNT]; S3L_Model3D models[LCR_RENDERER_MODEL_COUNT];
uint32_t frame;
uint8_t loadedChunks[8]; ///< numbers of loaded map chunks uint8_t loadedChunks[8]; ///< numbers of loaded map chunks
S3L_Unit mapVerts[LCR_SETTING_MAX_MAP_VERTICES * 3]; S3L_Unit mapVerts[LCR_SETTING_MAX_MAP_VERTICES * 3];
@ -68,6 +70,14 @@ struct
int previousTriID; int previousTriID;
int triUVs[6]; int triUVs[6];
uint8_t texSubsampleCount; uint8_t texSubsampleCount;
#if LCR_SETTING_ANIMATE_CAR
S3L_Unit wheelRotation;
S3L_Unit wheelTurn;
S3L_Unit wheelRotationCenters[4];
S3L_Unit animatedCarVerts[LCR_CAR_VERTEX_COUNT * 3];
#endif
} LCR_renderer; } LCR_renderer;
void LCR_pixelFunc3D(S3L_PixelInfo *pixel) void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
@ -77,6 +87,10 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
{ {
LCR_renderer.previousTriID = pixel->triangleID; LCR_renderer.previousTriID = pixel->triangleID;
#if LCR_SETTING_TEXTURE_SUBSAMPLE != 0
LCR_renderer.texSubsampleCount = 0;
#endif
if (pixel->modelIndex == 8) if (pixel->modelIndex == 8)
{ {
// car model // car model
@ -87,11 +101,8 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
{ {
LCR_renderer.triUVs[i] = LCR_renderer.triUVs[i] =
(LCR_carUvs[2 * LCR_carTriangleUvs[ (LCR_carUvs[2 * LCR_carTriangleUvs[
3 * pixel->triangleIndex + i / 2] + i % 2] * LCR_IMAGE_SIZE) / 512; 3 * pixel->triangleIndex + i / 2] + i % 2] * (LCR_IMAGE_SIZE + 1))
/ 512;
if (i % 2)
LCR_renderer.triUVs[i] = 64 -
LCR_renderer.triUVs[i];
} }
} }
else else
@ -102,10 +113,6 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
3 * pixel->triangleIndex; 3 * pixel->triangleIndex;
S3L_Unit *v[3]; S3L_Unit *v[3];
#if LCR_SETTING_TEXTURE_SUBSAMPLE != 0
LCR_renderer.texSubsampleCount = 0;
#endif
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
v[i] = LCR_renderer.mapVerts + 3 * t[i]; v[i] = LCR_renderer.mapVerts + 3 * t[i];
@ -170,6 +177,7 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
uint16_t color; uint16_t color;
#if LCR_SETTING_TEXTURE_SUBSAMPLE != 0 #if LCR_SETTING_TEXTURE_SUBSAMPLE != 0
if (LCR_renderer.texSubsampleCount == 0) if (LCR_renderer.texSubsampleCount == 0)
{ {
@ -716,6 +724,8 @@ uint8_t LCR_rendererInit(void)
{ {
LCR_log("initializing renderer"); LCR_log("initializing renderer");
LCR_renderer.frame = 0;
if (!_LCR_buildMapModel()) if (!_LCR_buildMapModel())
return 0; return 0;
@ -725,10 +735,47 @@ uint8_t LCR_rendererInit(void)
LCR_renderer.carModel = LCR_renderer.models + 8; LCR_renderer.carModel = LCR_renderer.models + 8;
S3L_model3DInit( S3L_model3DInit(
LCR_carVertices,LCR_CAR_VERTEX_COUNT, #if LCR_SETTING_ANIMATE_CAR
LCR_renderer.animatedCarVerts
#else
LCR_carVertices
#endif
,LCR_CAR_VERTEX_COUNT,
LCR_carTriangles,LCR_CAR_TRIANGLE_COUNT, LCR_carTriangles,LCR_CAR_TRIANGLE_COUNT,
LCR_renderer.carModel); LCR_renderer.carModel);
#if LCR_SETTING_ANIMATE_CAR
for (int i = 0; i < LCR_CAR_VERTEX_COUNT * 3; ++i)
LCR_renderer.animatedCarVerts[i] = LCR_carVertices[i];
int count[2];
count[0] = 0;
count[1] = 0;
for (int i = 0; i < 4; ++i)
LCR_renderer.wheelRotationCenters[i] = 0;
for (int i = 0; i < LCR_CAR_VERTEX_COUNT; ++i)
if (LCR_carVertexTypes[i] > 0) // wheel?
{
uint8_t front = LCR_carVertexTypes[i] == 1;
LCR_renderer.wheelRotationCenters[0 + 2 * front] +=
LCR_carVertices[3 * i + 2];
LCR_renderer.wheelRotationCenters[1 + 2 * front] +=
LCR_carVertices[3 * i + 1];
count[front]++;
}
LCR_renderer.wheelRotationCenters[0] /= count[0];
LCR_renderer.wheelRotationCenters[1] /= count[0];
LCR_renderer.wheelRotationCenters[2] /= count[1];
LCR_renderer.wheelRotationCenters[3] /= count[1];
LCR_renderer.wheelRotation = 0;
LCR_renderer.wheelTurn = 0;
#endif
LCR_renderer.carModel->transform.translation.x -= 2 * LCR_RENDERER_UNIT; LCR_renderer.carModel->transform.translation.x -= 2 * LCR_RENDERER_UNIT;
LCR_renderer.carModel->transform.scale.x = LCR_RENDERER_UNIT / 3; LCR_renderer.carModel->transform.scale.x = LCR_RENDERER_UNIT / 3;
@ -1162,6 +1209,51 @@ void LCR_drawLevelFloor(void)
#endif #endif
} }
void _LCR_rendererAnimateCar(void)
{
for (int i = 0; i < LCR_CAR_VERTEX_COUNT; ++i)
if (LCR_carVertexTypes[i] > 0)
{
S3L_Unit s = S3L_sin(-1 * LCR_renderer.wheelRotation),
c = S3L_cos(-1 * LCR_renderer.wheelRotation);
S3L_Unit v[2], tmp;
unsigned int index = 3 * i;
uint8_t offset = (LCR_carVertexTypes[i] == 1) * 2;
v[0] = LCR_carVertices[index + 2] -
LCR_renderer.wheelRotationCenters[offset];
v[1] = LCR_carVertices[index + 1] -
LCR_renderer.wheelRotationCenters[offset + 1];
tmp = v[0];
v[0] = (v[0] * c - v[1] * s) / S3L_FRACTIONS_PER_UNIT;
v[1] = (tmp * s + v[1] * c) / S3L_FRACTIONS_PER_UNIT;
LCR_renderer.animatedCarVerts[index + 2] =
v[0] + LCR_renderer.wheelRotationCenters[offset];
LCR_renderer.animatedCarVerts[index + 1] =
v[1] + LCR_renderer.wheelRotationCenters[offset + 1];
if (LCR_carVertexTypes[i] > 1)
{
/* Turn front wheels; this is not real turning but just a fake by
skewing in Z and X directions. */
LCR_renderer.animatedCarVerts[index] = LCR_carVertices[index];
LCR_renderer.animatedCarVerts[index + 2] -=
(LCR_renderer.animatedCarVerts[index] * LCR_renderer.wheelTurn)
/ (8 * S3L_FRACTIONS_PER_UNIT);
LCR_renderer.animatedCarVerts[index] +=
((LCR_renderer.animatedCarVerts[index + 2] -
LCR_renderer.wheelRotationCenters[0]) * LCR_renderer.wheelTurn)
/ (2 * S3L_FRACTIONS_PER_UNIT);
}
}
}
void LCR_rendererDraw(void) void LCR_rendererDraw(void)
{ {
LCR_renderer.previousTriID = -1; LCR_renderer.previousTriID = -1;
@ -1173,26 +1265,16 @@ void LCR_rendererDraw(void)
LCR_renderer.scene.camera.transform.rotation.y, LCR_renderer.scene.camera.transform.rotation.y,
-4 * LCR_renderer.scene.camera.transform.rotation.x); -4 * LCR_renderer.scene.camera.transform.rotation.x);
LCR_renderer.wheelRotation += 5;
LCR_renderer.wheelTurn = S3L_sin(LCR_renderer.frame * 4);
_LCR_rendererAnimateCar();
LCR_drawLevelFloor(); LCR_drawLevelFloor();
LCR_rendererDrawLOD(); LCR_rendererDrawLOD();
LCR_renderer.carModel->transform.translation =
LCR_renderer.scene.camera.transform.translation;
LCR_renderer.carModel->transform.translation.x +=
LCR_RENDERER_UNIT * 2;
LCR_renderer.carModel->transform.translation.z -=
LCR_RENDERER_UNIT * 1;
LCR_renderer.carModel->transform.translation.y -=
LCR_RENDERER_UNIT * 2;
S3L_drawScene(LCR_renderer.scene); S3L_drawScene(LCR_renderer.scene);
LCR_renderer.frame++;
} }
#endif // guard #endif // guard

View file

@ -92,4 +92,8 @@
#define LCR_SETTING_FLOOR_PARTICLE_SIZE 32 #define LCR_SETTING_FLOOR_PARTICLE_SIZE 32
#endif #endif
#ifndef LCR_SETTING_ANIMATE_CAR
#define LCR_SETTING_ANIMATE_CAR 1
#endif
#endif // guard #endif // guard