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

@ -44,6 +44,8 @@ struct
*/
S3L_Model3D models[LCR_RENDERER_MODEL_COUNT];
uint32_t frame;
uint8_t loadedChunks[8]; ///< numbers of loaded map chunks
S3L_Unit mapVerts[LCR_SETTING_MAX_MAP_VERTICES * 3];
@ -68,6 +70,14 @@ struct
int previousTriID;
int triUVs[6];
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;
void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
@ -77,6 +87,10 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
{
LCR_renderer.previousTriID = pixel->triangleID;
#if LCR_SETTING_TEXTURE_SUBSAMPLE != 0
LCR_renderer.texSubsampleCount = 0;
#endif
if (pixel->modelIndex == 8)
{
// car model
@ -87,11 +101,8 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
{
LCR_renderer.triUVs[i] =
(LCR_carUvs[2 * LCR_carTriangleUvs[
3 * pixel->triangleIndex + i / 2] + i % 2] * LCR_IMAGE_SIZE) / 512;
if (i % 2)
LCR_renderer.triUVs[i] = 64 -
LCR_renderer.triUVs[i];
3 * pixel->triangleIndex + i / 2] + i % 2] * (LCR_IMAGE_SIZE + 1))
/ 512;
}
}
else
@ -102,10 +113,6 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
3 * pixel->triangleIndex;
S3L_Unit *v[3];
#if LCR_SETTING_TEXTURE_SUBSAMPLE != 0
LCR_renderer.texSubsampleCount = 0;
#endif
for (int i = 0; i < 3; ++i)
v[i] = LCR_renderer.mapVerts + 3 * t[i];
@ -170,6 +177,7 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
uint16_t color;
#if LCR_SETTING_TEXTURE_SUBSAMPLE != 0
if (LCR_renderer.texSubsampleCount == 0)
{
@ -716,6 +724,8 @@ uint8_t LCR_rendererInit(void)
{
LCR_log("initializing renderer");
LCR_renderer.frame = 0;
if (!_LCR_buildMapModel())
return 0;
@ -725,10 +735,47 @@ uint8_t LCR_rendererInit(void)
LCR_renderer.carModel = LCR_renderer.models + 8;
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_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.scale.x = LCR_RENDERER_UNIT / 3;
@ -1162,6 +1209,51 @@ void LCR_drawLevelFloor(void)
#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)
{
LCR_renderer.previousTriID = -1;
@ -1172,27 +1264,17 @@ void LCR_rendererDraw(void)
LCR_rendererDrawSky(2,
LCR_renderer.scene.camera.transform.rotation.y,
-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_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);
LCR_renderer.frame++;
}
#endif // guard