diff --git a/assets.h b/assets.h index f04830c..2212201 100644 --- a/assets.h +++ b/assets.h @@ -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_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_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_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_CUBOID_HOLLOW,7,4,8,0,0), @@ -6223,9 +6224,6 @@ uint16_t LCR_getNextImagePixel(void) return r; } - - - #define LCR_CAR_VERTEX_COUNT 124 #define LCR_CAR_TRIANGLE_COUNT 228 @@ -6330,26 +6328,26 @@ static const uint16_t LCR_carTriangles[] = static const uint16_t LCR_carUvs[] = { - 107, 233, 64, 134, 123, 192, 66, 251, 63, 292, - 125, 323, 63, 323, 125, 353, 63, 353, 4, 353, - 4, 323, 4, 292, 4, 260, 63, 260, 125, 260, - 125, 477, 63, 509, 63, 477, 4, 477, 4, 446, - 63, 446, 125, 446, 4, 415, 63, 415, 125, 415, - 125, 384, 63, 384, 4, 384, 105, 151, 24, 235, - 6, 194, 23, 152, 24, 235, 64, 134, 66, 251, - 6, 194, 23, 152, 107, 233, 124, 191, 106, 150, - 125, 292, 125, 509, 4, 509, 254, 315, 249, 398, - 374, 397, 252, 501, 366, 501, 505, 270, 402, 274, - 505, 166, 108, 119, 62, 17, 62, 114, 449, 436, - 205, 117, 108, 11, 9, 112, 9, 19, 186, 415, - 307, 124, 205, 14, 437, 14, 398, 17, 437, 116, - 502, 113, 502, 17, 234, 317, 131, 340, 411, 312, - 374, 318, 239, 272, 263, 303, 490, 429, 505, 355, - 135, 403, 307, 7, 398, 114, 239, 164, 131, 271, - 131, 165, 402, 162, 381, 297, 255, 315, 374, 319, - 373, 399, 249, 399, 366, 502, 449, 436, 252, 502, - 186, 416, 234, 317, 130, 340, 412, 313, 263, 134, - 490, 429, 505, 355, 134, 403, 381, 139 + 107, 278, 64, 377, 123, 319, 66, 260, 63, 219, + 125, 188, 63, 188, 125, 158, 63, 158, 4, 158, + 4, 188, 4, 219, 4, 251, 63, 251, 125, 251, + 125, 34, 63, 2, 63, 34, 4, 34, 4, 65, + 63, 65, 125, 65, 4, 96, 63, 96, 125, 96, + 125, 127, 63, 127, 4, 127, 105, 360, 24, 276, + 6, 317, 23, 359, 24, 276, 64, 377, 66, 260, + 6, 317, 23, 359, 107, 278, 124, 320, 106, 361, + 125, 219, 125, 2, 4, 2, 254, 196, 249, 113, + 374, 114, 252, 10, 366, 10, 505, 241, 402, 237, + 505, 345, 108, 392, 62, 494, 62, 397, 449, 75, + 205, 394, 108, 500, 9, 399, 9, 492, 186, 96, + 307, 387, 205, 497, 437, 497, 398, 494, 437, 395, + 502, 398, 502, 494, 234, 194, 131, 171, 411, 199, + 374, 193, 239, 239, 263, 208, 490, 82, 505, 156, + 135, 108, 307, 504, 398, 397, 239, 347, 131, 240, + 131, 346, 402, 349, 381, 214, 255, 196, 374, 192, + 373, 112, 249, 112, 366, 9, 449, 75, 252, 9, + 186, 95, 234, 194, 130, 171, 412, 198, 263, 377, + 490, 82, 505, 156, 134, 108, 381, 372 }; static const uint16_t LCR_carTriangleUvs[] = @@ -6411,16 +6409,13 @@ static const uint16_t LCR_carTriangleUvs[] = 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, 3, 3, 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, - 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 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, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 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 }; - - - #endif diff --git a/assets/encodeCarModel.c b/assets/encodeCarModel.c index 347dd04..f67a089 100644 --- a/assets/encodeCarModel.c +++ b/assets/encodeCarModel.c @@ -69,17 +69,20 @@ int main(void) n,n + 1,n + 2,n + 3,n + 4,n + 5) != 6) error(0); - triangles[triangleCount * 3] = n[0] - 1; - triangles[triangleCount * 3 + 1] = n[2] - 1; - triangles[triangleCount * 3 + 2] = n[4] - 1; + for (int i = 0; i < 6; ++i) + n[i]--; // obj indices are 1-based - triangleUvs[triangleCount * 3] = n[1] - 1; - triangleUvs[triangleCount * 3 + 1] = n[3] - 1; - triangleUvs[triangleCount * 3 + 2] = n[5] - 1; + triangles[triangleCount * 3] = n[0]; + triangles[triangleCount * 3 + 1] = n[4]; + triangles[triangleCount * 3 + 2] = n[2]; - vertexTypes[n[0] - 1] = vertexType; - vertexTypes[n[1] - 1] = vertexType; - vertexTypes[n[2] - 1] = vertexType; + triangleUvs[triangleCount * 3] = n[1]; + triangleUvs[triangleCount * 3 + 1] = n[5]; + triangleUvs[triangleCount * 3 + 2] = n[3]; + + vertexTypes[n[0]] = vertexType; + vertexTypes[n[2]] = vertexType; + vertexTypes[n[4]] = vertexType; triangleCount++; @@ -110,7 +113,7 @@ int main(void) error(4); uvs[2 * uvCount] = a * UNIT; - uvs[2 * uvCount + 1] = b * UNIT; + uvs[2 * uvCount + 1] = (1 - b) * UNIT; uvCount++; diff --git a/renderer.h b/renderer.h index 0fe0935..098c610 100644 --- a/renderer.h +++ b/renderer.h @@ -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 diff --git a/settings.h b/settings.h index 2d78637..be19e93 100644 --- a/settings.h +++ b/settings.h @@ -92,4 +92,8 @@ #define LCR_SETTING_FLOOR_PARTICLE_SIZE 32 #endif +#ifndef LCR_SETTING_ANIMATE_CAR + #define LCR_SETTING_ANIMATE_CAR 1 +#endif + #endif // guard