From 011cd891c1d2c9d3a7063dd94002b505e6644c12 Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Tue, 24 Sep 2024 14:48:45 +0200 Subject: [PATCH 01/10] Continue block collisions --- assets.h | 12 +++++--- map.h | 1 - racing.h | 74 ++++++++++++++++++++++++++++++++++++++++++++- renderer.h | 10 ++++++ tinyphysicsengine.h | 14 +++++---- 5 files changed, 99 insertions(+), 12 deletions(-) diff --git a/assets.h b/assets.h index 4d69bb9..8e9e46b 100644 --- a/assets.h +++ b/assets.h @@ -26,11 +26,15 @@ static const uint8_t map1[] = 10, 0, - LCR_MAP_BLOCK(LCR_BLOCK_RAMP,36,0,32,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_RAMP_34,20,0,32,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_RAMP_12,32,0,37,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_RAMP_14,32,0,20,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP,35,0,32,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP,34,0,32,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP,33,0,32,LCR_BLOCK_MATERIAL_CONCRETE,0), + +LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,0,33,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,0,34,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,0,35,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,0,36,LCR_BLOCK_MATERIAL_CONCRETE,0), /* LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,0,0,0,LCR_BLOCK_MATERIAL_CONCRETE,0), diff --git a/map.h b/map.h index 57e8436..accab5c 100644 --- a/map.h +++ b/map.h @@ -84,7 +84,6 @@ #define LCR_BLOCK_RAMP_CURVED_SHORT 0x0a #define LCR_BLOCK_RAMP_CURVED_WALL 0x0b - #define LCR_BLOCK_FULL_ACCEL 0x20 #define LCR_BLOCK_FULL_FAN 0x30 diff --git a/racing.h b/racing.h index 721238f..95bd32d 100644 --- a/racing.h +++ b/racing.h @@ -70,8 +70,80 @@ TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block) (((int) bz) - LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT + LCR_PHYSICS_UNIT / 2); + point = TPE_vec3Minus(point,center); // shift to origin + +// TODO: transform + + switch (block[0]) + { + case LCR_BLOCK_FULL: + case LCR_BLOCK_BOTTOM: + case LCR_BLOCK_LEFT: + case LCR_BLOCK_BOTTOM_LEFT: + case LCR_BLOCK_BOTTOM_LEFT_FRONT: + case LCR_BLOCK_FULL_ACCEL: + case LCR_BLOCK_FULL_FAN: + { + TPE_Vec3 + offset = TPE_vec3(0,0,0), + size = TPE_vec3(LCR_PHYSICS_UNIT / 2,LCR_PHYSICS_UNIT / 4, + LCR_PHYSICS_UNIT / 2); + + if (block[0] == LCR_BLOCK_BOTTOM || + block[0] == LCR_BLOCK_BOTTOM_LEFT || + block[0] == LCR_BLOCK_BOTTOM_LEFT_FRONT) + { + offset.y -= LCR_PHYSICS_UNIT / 8; + size.y = LCR_PHYSICS_UNIT / 8; + } + + if (block[0] == LCR_BLOCK_LEFT || + block[0] == LCR_BLOCK_BOTTOM_LEFT || + block[0] == LCR_BLOCK_BOTTOM_LEFT_FRONT) + { + offset.x -= LCR_PHYSICS_UNIT / 4; + size.x = LCR_PHYSICS_UNIT / 4; + } + + if (block[0] == LCR_BLOCK_BOTTOM_LEFT_FRONT) + { + offset.z -= LCR_PHYSICS_UNIT / 4; + size.z = LCR_PHYSICS_UNIT / 4; + } + + point = TPE_envAABox(point,offset,size); + break; + } + + case LCR_BLOCK_RAMP: + case LCR_BLOCK_RAMP_34: + case LCR_BLOCK_RAMP_12: + case LCR_BLOCK_RAMP_14: + { + TPE_Unit sides[6]; + sides[0] = -1 * LCR_PHYSICS_UNIT / 2; sides[1] = -1 * LCR_PHYSICS_UNIT / 2; + sides[2] = LCR_PHYSICS_UNIT / 2; sides[3] = -1 * LCR_PHYSICS_UNIT / 2; + sides[4] = LCR_PHYSICS_UNIT / 2; sides[5] = LCR_PHYSICS_UNIT / 2; + + point = TPE_envAATriPrism(point,TPE_vec3(0,0,0),sides,LCR_PHYSICS_UNIT,2); + break; + } + + default: + point = TPE_vec3(0,0,LCR_MAP_SIZE_BLOCKS * LCR_PHYSICS_UNIT); + break; + } + +// TODO: untransform + + point = TPE_vec3Plus(point,center); // shift back + + return point; + +/* return TPE_envAABox(point,center,TPE_vec3(LCR_PHYSICS_UNIT / 2, LCR_PHYSICS_UNIT / 4,LCR_PHYSICS_UNIT / 2)); +*/ } TPE_Vec3 _LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist) @@ -504,7 +576,7 @@ void LCR_physicsDebugDraw(LCR_GameUnit camPos[3], LCR_GameUnit camRot[2], cView.z = (camFov * TPE_F) / LCR_GAME_UNIT; TPE_worldDebugDraw(&(LCR_racing.physicsWorld),_LCR_drawPhysicsDebugPixel, - cPos,cRot,cView,16,LCR_PHYSICS_UNIT / 4); + cPos,cRot,cView,16,LCR_PHYSICS_UNIT / 4,LCR_racing.tick * 4); } #endif // guard diff --git a/renderer.h b/renderer.h index 61eeeca..d984a90 100644 --- a/renderer.h +++ b/renderer.h @@ -615,6 +615,16 @@ uint8_t _LCR_buildMapModel(void) S3L_model3DInit(LCR_renderer.mapVerts,0,LCR_renderer.mapTris,0, &LCR_renderer.mapModel); +// TEMPORARY FIX: this scales the map so that it better aligns with the +// physics world -- dunno why it's not aligned by default, investigate (if it's +// numerical errors then at least make this a const) +LCR_renderer.mapModel.transform.scale.x = + (S3L_F * 1009) / 1000; +LCR_renderer.mapModel.transform.scale.y = + LCR_renderer.mapModel.transform.scale.x; +LCR_renderer.mapModel.transform.scale.z = + LCR_renderer.mapModel.transform.scale.x; + for (int j = 0; j < LCR_currentMap.blockCount; ++j) { if ((j + 1) % LCR_SETTING_TRIANGLE_CULLING_PERIOD == 0) diff --git a/tinyphysicsengine.h b/tinyphysicsengine.h index bbd77d3..2fc14a7 100644 --- a/tinyphysicsengine.h +++ b/tinyphysicsengine.h @@ -539,7 +539,7 @@ TPE_Vec3 TPE_bodyGetCenterOfMass(const TPE_Body *body); e.g. 16). */ void TPE_worldDebugDraw(TPE_World *world, TPE_DebugDrawFunction drawFunc, TPE_Vec3 camPos, TPE_Vec3 camRot, TPE_Vec3 camView, uint16_t envGridRes, - TPE_Unit envGridSize); + TPE_Unit envGridSize, TPE_Unit offset); #define TPE_DEBUG_COLOR_CONNECTION 0 #define TPE_DEBUG_COLOR_JOINT 1 @@ -592,7 +592,7 @@ TPE_Vec3 TPE_envLineSegment(TPE_Vec3 point, TPE_Vec3 a, TPE_Vec3 b); TPE_Vec3 TPE_envHeightmap(TPE_Vec3 point, TPE_Vec3 center, TPE_Unit gridSize, TPE_Unit (*heightFunction)(int32_t x, int32_t y), TPE_Unit maxDist); -/** Environment function for triagnular prism, e.g. for ramps. The sides array +/** Environment function for triangular prism, e.g. for ramps. The sides array contains three 2D coordinates of points of the triangle in given plane with respect to the center. WARNING: the points must be specified in counter clowckwise direction! The direction var specified axis direction (0, 1 or @@ -2079,7 +2079,7 @@ void _TPE_drawDebugPixel( void TPE_worldDebugDraw(TPE_World *world, TPE_DebugDrawFunction drawFunc, TPE_Vec3 camPos, TPE_Vec3 camRot, TPE_Vec3 camView, uint16_t envGridRes, - TPE_Unit envGridSize) + TPE_Unit envGridSize, TPE_Unit offset) { #define Z_LIMIT 250 if (world->environmentFunction != 0) @@ -2092,6 +2092,8 @@ void TPE_worldDebugDraw(TPE_World *world, TPE_DebugDrawFunction drawFunc, TPE_Vec3 center; + offset %= envGridSize; + if (envGridRes != 0) { center = TPE_vec3(0,TPE_sin(camRot.x),TPE_cos(camRot.x)); @@ -2101,9 +2103,9 @@ void TPE_worldDebugDraw(TPE_World *world, TPE_DebugDrawFunction drawFunc, center = TPE_vec3Times(center,gridHalfSize); center = TPE_vec3Plus(camPos,center); - center.x = (center.x / envGridSize) * envGridSize; - center.y = (center.y / envGridSize) * envGridSize; - center.z = (center.z / envGridSize) * envGridSize; + center.x = (center.x / envGridSize) * envGridSize + offset; + center.y = (center.y / envGridSize) * envGridSize + offset; + center.z = (center.z / envGridSize) * envGridSize + offset; } testPoint.y = center.y - gridHalfSize; From fa6632483337a0df11b9ab2edbfa9847faab73b9 Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Thu, 26 Sep 2024 14:56:39 +0200 Subject: [PATCH 02/10] Continue block collisions --- assets.h | 8 ++++++++ map.h | 50 ++++++++++++++++++++++++++++++++++++++++++++------ racing.h | 53 ++++++++++++++++++++++++++++++++++------------------- renderer.h | 25 ++++++++++++++----------- 4 files changed, 100 insertions(+), 36 deletions(-) diff --git a/assets.h b/assets.h index 8e9e46b..9161d24 100644 --- a/assets.h +++ b/assets.h @@ -35,6 +35,14 @@ LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,0,33,LCR_BLOCK_MATERIAL_CONCRETE,0), LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,0,34,LCR_BLOCK_MATERIAL_CONCRETE,0), LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,0,35,LCR_BLOCK_MATERIAL_CONCRETE,0), LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,0,36,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,1,36,LCR_BLOCK_MATERIAL_CONCRETE,0), + +LCR_MAP_BLOCK(LCR_BLOCK_FULL,34,0,33,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_FULL,34,0,34,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_FULL,34,0,35,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_FULL,34,0,36,LCR_BLOCK_MATERIAL_CONCRETE,0), + +LCR_MAP_BLOCK(LCR_BLOCK_RAMP,32,32,32,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_180), /* LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,0,0,0,LCR_BLOCK_MATERIAL_CONCRETE,0), diff --git a/map.h b/map.h index accab5c..c6dec9e 100644 --- a/map.h +++ b/map.h @@ -148,6 +148,20 @@ void LCR_mapBlockGetCoords(const uint8_t block[LCR_BLOCK_SIZE], *z = (block[2] >> 4) | ((block[3] & 0x03) << 4); } +uint8_t LCR_mapBlockOppositeTransform(uint8_t transform) +{ + if (!(transform & LCR_BLOCK_TRANSFORM_FLIP_H)) + { + if ((transform & 0x60) == LCR_BLOCK_TRANSFORM_ROT_90) + return ((transform & (~0x60)) | LCR_BLOCK_TRANSFORM_ROT_270); + + if ((transform & 0x60) == LCR_BLOCK_TRANSFORM_ROT_270) + return ((transform & (~0x60)) | LCR_BLOCK_TRANSFORM_ROT_90); + } + + return transform; +} + uint8_t LCR_mapBlockGetTransform(const uint8_t block[LCR_BLOCK_SIZE]) { return block[3] & 0xf0; @@ -171,6 +185,15 @@ uint32_t LCR_mapBlockCoordsToCoordNumber(uint8_t x, uint8_t y, uint8_t z) return LCR_mapBlockGetCoordNumber(b); } +int LCR_rampHeight4ths(uint8_t rampType) +{ + return + (rampType == LCR_BLOCK_RAMP_14) + + (rampType == LCR_BLOCK_RAMP) * 4 + + (rampType == LCR_BLOCK_RAMP_12 || rampType == LCR_BLOCK_RAMP_34) * 2 + + (rampType == LCR_BLOCK_RAMP_34); +} + uint8_t *LCR_getMapBlockAtCoordNumber(uint32_t coord) { // binary search the block: @@ -424,6 +447,21 @@ void _LCR_addBlockShapeByte(uint8_t *bytes, uint8_t *byteCount, *byteCount += 1; } + + +#define LCR_TRANSFORM_COORDS(trans,cx,cy,cz,maxXZ,maxY)\ + if (trans & LCR_BLOCK_TRANSFORM_FLIP_H) cx = maxXZ - cx;\ + if (trans & 0x20) { /* for both 90 and 270 */ \ + cx ^= cz; cz ^= cx; cx ^= cz; /* swap */ \ + cx = maxXZ - cx; } \ + if (trans & 0x40) { /* for both 180 and 270 */ \ + cx = maxXZ - cx; \ + cz = maxXZ - cz; } \ + if (trans & LCR_BLOCK_TRANSFORM_FLIP_V) \ + cy = maxY - cy; + + + /** Gets a shape of given map block type as a 3D model composed of triangles. The model is returned as an array of byte triplets (triangles), with each byte @@ -521,11 +559,7 @@ void LCR_mapGetBlockShape(uint8_t blockType, uint8_t transform, case LCR_BLOCK_RAMP_14: case LCR_BLOCK_RAMP_34: { - uint8_t top = - (blockType == LCR_BLOCK_RAMP_14) + - (blockType == LCR_BLOCK_RAMP) * 4 + - (blockType == LCR_BLOCK_RAMP_12 || blockType == LCR_BLOCK_RAMP_34) * 2 + - (blockType == LCR_BLOCK_RAMP_34); + uint8_t top = LCR_rampHeight4ths(blockType); ADD(0,0,0) ADD(0,top,6) ADD(0,0,6) // side ADD(6,0,0) ADD(6,0,6) ADD(6,top,6) // side @@ -549,7 +583,10 @@ void LCR_mapGetBlockShape(uint8_t blockType, uint8_t transform, uint8_t x, y, z, tmp; _LCR_decodeMapBlockCoords(bytes[i],&x,&y,&z); - + +LCR_TRANSFORM_COORDS(transform,x,y,z,6,4) + +/* if (transform & LCR_BLOCK_TRANSFORM_FLIP_H) x = 6 - x; @@ -568,6 +605,7 @@ void LCR_mapGetBlockShape(uint8_t blockType, uint8_t transform, if (transform & LCR_BLOCK_TRANSFORM_FLIP_V) y = 4 - y; +*/ bytes[i] = _LCR_encodeMapBlockCoords(x,y,z); } diff --git a/racing.h b/racing.h index 95bd32d..81b225d 100644 --- a/racing.h +++ b/racing.h @@ -61,18 +61,22 @@ TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block) { uint8_t bx, by, bz; LCR_mapBlockGetCoords(block,&bx,&by,&bz); + + TPE_Vec3 blockOffset = TPE_vec3( + (((int) bx) - LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT, + (((int) by) - LCR_MAP_SIZE_BLOCKS / 2) * (LCR_PHYSICS_UNIT / 2), + (((int) bz) - LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT); - TPE_Vec3 center = TPE_vec3( - (((int) bx) - LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT - + LCR_PHYSICS_UNIT / 2, - (((int) by) - LCR_MAP_SIZE_BLOCKS / 2) * (LCR_PHYSICS_UNIT / 2) - + LCR_PHYSICS_UNIT / 4, - (((int) bz) - LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT - + LCR_PHYSICS_UNIT / 2); + point = TPE_vec3Minus(point,blockOffset); // shift to origin - point = TPE_vec3Minus(point,center); // shift to origin + uint8_t transform = + LCR_mapBlockOppositeTransform(LCR_mapBlockGetTransform(block)); -// TODO: transform + LCR_TRANSFORM_COORDS(transform,point.x,point.y,point.z,(LCR_PHYSICS_UNIT / 2), + (LCR_PHYSICS_UNIT / 4)) + + point = TPE_vec3Minus(point,TPE_vec3( + LCR_PHYSICS_UNIT / 2,LCR_PHYSICS_UNIT / 4,LCR_PHYSICS_UNIT / 2)); switch (block[0]) { @@ -121,9 +125,15 @@ TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block) case LCR_BLOCK_RAMP_14: { TPE_Unit sides[6]; - sides[0] = -1 * LCR_PHYSICS_UNIT / 2; sides[1] = -1 * LCR_PHYSICS_UNIT / 2; - sides[2] = LCR_PHYSICS_UNIT / 2; sides[3] = -1 * LCR_PHYSICS_UNIT / 2; - sides[4] = LCR_PHYSICS_UNIT / 2; sides[5] = LCR_PHYSICS_UNIT / 2; + sides[0] = -1 * LCR_PHYSICS_UNIT / 2; + sides[1] = -1 * LCR_PHYSICS_UNIT / 4; + + sides[2] = LCR_PHYSICS_UNIT / 2; + sides[3] = -1 * LCR_PHYSICS_UNIT / 4; + + sides[4] = LCR_PHYSICS_UNIT / 2; + sides[5] = -1 * LCR_PHYSICS_UNIT / 4 + + LCR_rampHeight4ths(block[0]) * (LCR_PHYSICS_UNIT / 8); point = TPE_envAATriPrism(point,TPE_vec3(0,0,0),sides,LCR_PHYSICS_UNIT,2); break; @@ -134,16 +144,17 @@ TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block) break; } -// TODO: untransform + point = TPE_vec3Plus(point, + TPE_vec3(LCR_PHYSICS_UNIT / 2,LCR_PHYSICS_UNIT / 4,LCR_PHYSICS_UNIT / 2)); - point = TPE_vec3Plus(point,center); // shift back + transform = LCR_mapBlockOppositeTransform(transform); + + LCR_TRANSFORM_COORDS(transform,point.x,point.y,point.z,LCR_PHYSICS_UNIT, + (LCR_PHYSICS_UNIT / 2)) + + point = TPE_vec3Plus(point,blockOffset); // shift back return point; - -/* - return TPE_envAABox(point,center,TPE_vec3(LCR_PHYSICS_UNIT / 2, - LCR_PHYSICS_UNIT / 4,LCR_PHYSICS_UNIT / 2)); -*/ } TPE_Vec3 _LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist) @@ -154,6 +165,10 @@ TPE_Vec3 _LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist) (LCR_PHYSICS_UNIT * LCR_MAP_SIZE_BLOCKS) / 2, LCR_PHYSICS_UNIT * LCR_MAP_SIZE_BLOCKS)),point) + // without this check we might try to get block outside the map + if (_pBest.x == point.x && _pBest.y == point.y && _pBest.z == point.z) + return _pBest; + if (maxDist <= LCR_PHYSICS_UNIT / 4) // considering half of square height { /* Here we only check the 8 closest blocks => relatively fast. */ diff --git a/renderer.h b/renderer.h index d984a90..a1bd69c 100644 --- a/renderer.h +++ b/renderer.h @@ -16,7 +16,8 @@ /// Renderer specific unit, length of one map square. #define LCR_RENDERER_UNIT (S3L_F / 2) - // ^ just S3L_F leaves some tris bugging + // NOTE: ^ S3L_F sometimes makes some triangles bug, S3L_F/2 seems to fix it + // but it's more jerky, maybe try to apply anti-overflow in S3L? #define LCR_RENDERER_CHUNK_RESOLUTION 4 // do not change #define LCR_RENDERER_LOD_BLOCKS 64 // do not change @@ -30,6 +31,10 @@ #define LCR_RENDERER_MODEL_COUNT 10 #define LCR_RENDERER_CAR_SCALE (LCR_RENDERER_UNIT / 4) +/** For some reason the map model is a bit misaligned with physics world, this + kinda hotfixes it -- later try to discover source of this bug. TODO */ +#define _LCR_MAP_MODEL_SCALE 1034 + struct { S3L_Scene scene; @@ -615,15 +620,12 @@ uint8_t _LCR_buildMapModel(void) S3L_model3DInit(LCR_renderer.mapVerts,0,LCR_renderer.mapTris,0, &LCR_renderer.mapModel); -// TEMPORARY FIX: this scales the map so that it better aligns with the -// physics world -- dunno why it's not aligned by default, investigate (if it's -// numerical errors then at least make this a const) -LCR_renderer.mapModel.transform.scale.x = - (S3L_F * 1009) / 1000; -LCR_renderer.mapModel.transform.scale.y = - LCR_renderer.mapModel.transform.scale.x; -LCR_renderer.mapModel.transform.scale.z = - LCR_renderer.mapModel.transform.scale.x; + LCR_renderer.mapModel.transform.scale.x = + (_LCR_MAP_MODEL_SCALE * S3L_F) / 1024; + LCR_renderer.mapModel.transform.scale.y + = LCR_renderer.mapModel.transform.scale.x; + LCR_renderer.mapModel.transform.scale.z + = LCR_renderer.mapModel.transform.scale.x; for (int j = 0; j < LCR_currentMap.blockCount; ++j) { @@ -724,7 +726,8 @@ LCR_renderer.mapModel.transform.scale.z = } } - _LCR_rendererAddMapTri(triIndices[0],triIndices[1],triIndices[2],triData); + _LCR_rendererAddMapTri(triIndices[0],triIndices[1],triIndices[2], + triData); } vi = 0; From 28a1256a888f4ef24cd4c2ce75683b4699bb4606 Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Thu, 26 Sep 2024 21:29:36 +0200 Subject: [PATCH 03/10] Fix collision bug --- assets.h | 21 ++++++++------------- racing.h | 27 ++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/assets.h b/assets.h index 9161d24..aed4680 100644 --- a/assets.h +++ b/assets.h @@ -27,22 +27,17 @@ static const uint8_t map1[] = 0, LCR_MAP_BLOCK(LCR_BLOCK_RAMP,36,0,32,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_RAMP,35,0,32,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_RAMP,34,0,32,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_RAMP,33,0,32,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,1,1,0,0), -LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,0,33,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,0,34,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,0,35,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,0,36,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,1,36,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP,46,0,33,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_90), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,1,1,10,0,0), -LCR_MAP_BLOCK(LCR_BLOCK_FULL,34,0,33,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_FULL,34,0,34,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_FULL,34,0,35,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_FULL,34,0,36,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_FULL,36,0,33,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,1,10,0,0), + +LCR_MAP_BLOCK(LCR_BLOCK_FULL,36,0,43,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,4,1,0,0), -LCR_MAP_BLOCK(LCR_BLOCK_RAMP,32,32,32,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_180), /* LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,0,0,0,LCR_BLOCK_MATERIAL_CONCRETE,0), diff --git a/racing.h b/racing.h index 81b225d..06be891 100644 --- a/racing.h +++ b/racing.h @@ -20,6 +20,9 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit #include "tinyphysicsengine.h" // TODO: move some of this to constants? + +#if 0 + #define LCR_GRAVITY (LCR_PHYSICS_UNIT / 100) #define LCR_CAR_FORWARD_FRICTION (TPE_F / 11) #define LCR_CAR_TURN_FRICTION (4 * TPE_F / 4) @@ -28,6 +31,20 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit #define LCR_CAR_TURN_SPEED (LCR_GAME_UNIT / 20) #define LCR_CAR_TURN_MAX (LCR_GAME_UNIT / 4) +#else + +#define LCR_GRAVITY (LCR_PHYSICS_UNIT / 140) +#define LCR_CAR_FORWARD_FRICTION (TPE_F / 9) +#define LCR_CAR_TURN_FRICTION (4 * TPE_F / 4) +#define LCR_CAR_ELASTICITY (TPE_F / 110) +#define LCR_CAR_ACCELERATION (LCR_PHYSICS_UNIT / 16) +#define LCR_CAR_TURN_SPEED (LCR_GAME_UNIT / 20) +#define LCR_CAR_TURN_MAX (LCR_GAME_UNIT / 4) + +#endif + + + #define LCR_CAR_JOINTS 5 #define LCR_CAR_CONNECTIONS 10 @@ -61,7 +78,7 @@ TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block) { uint8_t bx, by, bz; LCR_mapBlockGetCoords(block,&bx,&by,&bz); - + TPE_Vec3 blockOffset = TPE_vec3( (((int) bx) - LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT, (((int) by) - LCR_MAP_SIZE_BLOCKS / 2) * (LCR_PHYSICS_UNIT / 2), @@ -72,11 +89,11 @@ TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block) uint8_t transform = LCR_mapBlockOppositeTransform(LCR_mapBlockGetTransform(block)); - LCR_TRANSFORM_COORDS(transform,point.x,point.y,point.z,(LCR_PHYSICS_UNIT / 2), - (LCR_PHYSICS_UNIT / 4)) + LCR_TRANSFORM_COORDS(transform,point.x,point.y,point.z,LCR_PHYSICS_UNIT, + (LCR_PHYSICS_UNIT / 2)) - point = TPE_vec3Minus(point,TPE_vec3( - LCR_PHYSICS_UNIT / 2,LCR_PHYSICS_UNIT / 4,LCR_PHYSICS_UNIT / 2)); + point = TPE_vec3Minus(point, + TPE_vec3(LCR_PHYSICS_UNIT / 2,LCR_PHYSICS_UNIT / 4,LCR_PHYSICS_UNIT / 2)); switch (block[0]) { From e9f919052c9a00b5cfcd1f943c10066d2edf5a4e Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Fri, 27 Sep 2024 00:08:52 +0200 Subject: [PATCH 04/10] Add logs and checks --- frontend_sdl.c | 20 ++++++++++++++++++++ game.h | 29 ++++++++++++++++++++++++++++- racing.h | 18 ++++++++++++++++-- renderer.h | 40 +++++++++++++++++++++++++++++++++------- settings.h | 7 +++++++ 5 files changed, 104 insertions(+), 10 deletions(-) diff --git a/frontend_sdl.c b/frontend_sdl.c index cdbaa3d..99346f2 100644 --- a/frontend_sdl.c +++ b/frontend_sdl.c @@ -1,6 +1,8 @@ #include #include +#define LCR_SETTING_LOG_LEVEL 5 + #include "game.h" #include "debug.h" @@ -67,12 +69,30 @@ int main(int argc, char *argv[]) SDL_WINDOWPOS_UNDEFINED, LCR_SETTING_RESOLUTION_X, LCR_SETTING_RESOLUTION_Y, SDL_WINDOW_SHOWN); + if (!window) + { + fputs("ERROR: couldn't create window",stderr); + return 1; + } + renderer = SDL_CreateRenderer(window,-1,0); + if (!renderer) + { + fputs("ERROR: couldn't create renderer",stderr); + return 1; + } + texture = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGB565,SDL_TEXTUREACCESS_STATIC, LCR_SETTING_RESOLUTION_X,LCR_SETTING_RESOLUTION_Y); + if (!texture) + { + fputs("ERROR: couldn't create texture",stderr); + return 1; + } + screenSurface = SDL_GetWindowSurface(window); SDL_ShowCursor(0); diff --git a/game.h b/game.h index 3ad4f74..107a6d2 100644 --- a/game.h +++ b/game.h @@ -94,6 +94,25 @@ uint8_t LCR_gameStep(uint32_t timeMs); //------------------------------------------------------------------------------ +#define LCR_LOG0(s) ; +#define LCR_LOG1(s) ; +#define LCR_LOG2(s) ; + +#if LCR_SETTING_LOG_LEVEL > 0 + #undef LCR_LOG0 + #define LCR_LOG0(s) LCR_log(s); + + #if LCR_SETTING_LOG_LEVEL > 1 + #undef LCR_LOG1 + #define LCR_LOG1(s) LCR_log(s); + + #if LCR_SETTING_LOG_LEVEL > 2 + #undef LCR_LOG2 + #define LCR_LOG2(s) LCR_log(s); + #endif + #endif +#endif + #define LCR_CONTROL_MODE_FREECAM 0x00 #define LCR_CONTROL_MODE_DRIVE 0x01 @@ -144,7 +163,7 @@ static inline void LCR_drawPixelXYSafe(unsigned int x, unsigned int y, void LCR_gameInit(void) { - LCR_log("initializing"); + LCR_LOG0("initializing"); for (int i = 0; i < LCR_KEYS_TOTAL; ++i) LCR_keyStates[i] = 0; @@ -162,10 +181,13 @@ void LCR_gameInit(void) void LCR_gameEnd(void) { + LCR_LOG0("ending"); } uint8_t LCR_gameStep(uint32_t time) { + LCR_LOG2("game step start"); + for (int i = 0; i < LCR_KEYS_TOTAL; ++i) LCR_keyStates[i] = LCR_keyPressed(i) ? (LCR_keyStates[i] < 255 ? LCR_keyStates[i] + 1 : 255) : 0; @@ -188,6 +210,7 @@ if ((LCR_racing.tick % 32) == 0) while (time >= LCR_game.nextRacingTickTime) { + LCR_LOG2("gonna step racing engine"); unsigned int input = 0; if (LCR_game.controlMode != LCR_CONTROL_MODE_FREECAM) @@ -205,6 +228,8 @@ if ((LCR_racing.tick % 32) == 0) if (time >= LCR_game.nextRenderFrameTime) { + LCR_LOG2("gonna render next frame"); + LCR_GameUnit physicsInterpolationParam = LCR_GAME_UNIT - ((LCR_game.nextRacingTickTime - time) * LCR_GAME_UNIT) / LCR_RACING_TICK_MS; @@ -278,6 +303,8 @@ LCR_GameUnit physicsInterpolationParam = LCR_GAME_UNIT - if (sleep) LCR_sleep(sleep); + LCR_LOG2("game step end"); + return 1; } diff --git a/racing.h b/racing.h index 06be891..a204abb 100644 --- a/racing.h +++ b/racing.h @@ -246,7 +246,8 @@ TPE_Vec3 _LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist) } else { -printf("oof\n"); + LCR_LOG1("collision checking all blocks (shouldn't happen often!)"); + const uint8_t *block = LCR_currentMap.blocks; /* Full check of all map blocks, slow, shouldn't happen often! */ @@ -299,6 +300,8 @@ LCR_GameUnit _LCR_racingSmoothRot(LCR_GameUnit angleNew, LCR_GameUnit angleOld) */ void LCR_racingRestart(void) { + LCR_LOG0("restarting race"); + LCR_racing.tick = 0; TPE_bodyActivate(&(LCR_racing.carBody)); @@ -320,7 +323,7 @@ void LCR_racingRestart(void) */ void LCR_racingInit(void) { - LCR_log("initializing racing engine"); + LCR_LOG0("initializing racing engine"); // make the car body: TPE_makeCenterRectFull(LCR_racing.carJoints, @@ -361,6 +364,8 @@ void LCR_racingInit(void) void LCR_racingGetCarTransform(LCR_GameUnit position[3], LCR_GameUnit rotation[3], LCR_GameUnit interpolationParam) { + LCR_LOG2("getting car transform"); + TPE_Vec3 v; #if LCR_SETTING_SMOOTH_ANIMATIONS @@ -435,6 +440,8 @@ void _LCR_racingWheelAccelerate(unsigned int wheel, TPE_Vec3 dir) */ void LCR_racingStep(unsigned int input) { + LCR_LOG2("racing step start"); + TPE_Vec3 carForw, carRight, carUp; carForw = TPE_vec3Normalized(TPE_vec3Plus( @@ -546,7 +553,10 @@ void LCR_racingStep(unsigned int input) TPE_bodyApplyGravity(&(LCR_racing.carBody),LCR_GRAVITY); LCR_racing.wheelCollisions <<= 4; + + LCR_LOG2("gonna step physics engine"); TPE_worldStep(&(LCR_racing.physicsWorld)); + LCR_LOG2("stepping physics engine done"); if (TPE_vec3Dot(carUp,TPE_vec3Minus(LCR_racing.carBody.joints[4].position, LCR_racing.carBody.joints[0].position)) < 0) @@ -588,11 +598,15 @@ void LCR_racingStep(unsigned int input) LCR_racing.carRotations[0] = tmpVec; LCR_racing.tick++; + + LCR_LOG2("racing step end"); } void LCR_physicsDebugDraw(LCR_GameUnit camPos[3], LCR_GameUnit camRot[2], LCR_GameUnit camFov) { + LCR_LOG2("drawing physics debug overlay"); + TPE_Vec3 cPos, cRot, cView; cPos.x = (camPos[0] * LCR_PHYSICS_UNIT) / LCR_GAME_UNIT; diff --git a/renderer.h b/renderer.h index a1bd69c..1f19e8b 100644 --- a/renderer.h +++ b/renderer.h @@ -91,6 +91,8 @@ struct void LCR_rendererSetCarTransform(LCR_GameUnit position[3], LCR_GameUnit rotation[3]) { + LCR_LOG2("setting car transform"); + LCR_renderer.carModel->transform.translation.x = (position[0] * LCR_RENDERER_UNIT) / LCR_GAME_UNIT; LCR_renderer.carModel->transform.translation.y = @@ -271,7 +273,7 @@ S3L_Index _LCR_rendererAddMapVert(S3L_Unit x, S3L_Unit y, S3L_Unit z) return LCR_renderer.mapModel.vertexCount - 1; } - LCR_log("couldn't add map vertex!"); + LCR_LOG0("couldn't add map vertex!"); return 0; } @@ -479,7 +481,7 @@ uint8_t _LCR_rendererCheckMapTriCover(const S3L_Index *t1, */ void _LCR_cullHiddenMapTris(void) { - LCR_log("culling invisible triangles"); + LCR_LOG1("culling invisible triangles"); int n = 0; // number of removed elements int i = 0; @@ -567,7 +569,7 @@ void _LCR_cullHiddenMapTris(void) void _LCR_makeMapChunks(void) { - LCR_log("making map chunks"); + LCR_LOG1("making map chunks"); S3L_Index start = 0; @@ -612,7 +614,7 @@ void _LCR_makeMapChunks(void) */ uint8_t _LCR_buildMapModel(void) { - LCR_log("building map model"); + LCR_LOG1("building map model"); uint8_t blockShapeBytes[LCR_MAP_BLOCK_SHAPE_MAX_BYTES]; uint8_t blockShapeByteCount; @@ -739,14 +741,14 @@ uint8_t _LCR_buildMapModel(void) _LCR_cullHiddenMapTris(); - LCR_log("map model built"); + LCR_LOG1("map model built"); return 1; } void _LCR_rendererComputeLOD(void) { - LCR_log("computing LOD"); + LCR_LOG1("computing LOD"); for (int i = 0; i < LCR_RENDERER_LOD_BLOCKS; ++i) LCR_renderer.gridOfLODs[i] = 0; @@ -767,7 +769,7 @@ void _LCR_rendererComputeLOD(void) uint8_t LCR_rendererInit(void) { - LCR_log("initializing renderer"); + LCR_LOG0("initializing renderer"); LCR_renderer.frame = 0; @@ -834,6 +836,8 @@ LCR_renderer.ghostModel->transform.translation.x -= LCR_GAME_UNIT / 4; LCR_renderer.wheelSteer = 0; #endif + LCR_LOG2("initializing 3D scene"); + S3L_sceneInit( LCR_renderer.models,LCR_RENDERER_MODEL_COUNT,&LCR_renderer.scene); @@ -864,6 +868,8 @@ void LCR_rendererGetCameraTransform(LCR_GameUnit position[3], void LCR_rendererMoveCamera(LCR_GameUnit forwRightUpOffset[3], LCR_GameUnit yawPitchOffset[2]) { + LCR_LOG2("moving camera"); + S3L_Vec4 f, r, u; S3L_rotationToDirections(LCR_renderer.scene.camera.transform.rotation, @@ -963,6 +969,8 @@ void LCR_rendererDrawRect(int x, int y, unsigned int w, unsigned int h, void _LCR_rendererDrawLODBlock(int blockX, int blockY, int blockZ, unsigned int size, uint16_t color, uint8_t variability) { + LCR_LOG2("drawing LOD block"); + S3L_Vec4 p, r; p.x = (blockX - LCR_MAP_SIZE_BLOCKS / 2) * LCR_RENDERER_UNIT @@ -1007,6 +1015,8 @@ void _LCR_rendererDrawLODBlock(int blockX, int blockY, int blockZ, unsigned int */ void LCR_rendererDrawSky(int sky, S3L_Unit offsetH, S3L_Unit offsetV) { + LCR_LOG2("drawing sky"); + int anchorPoint[2], y; unsigned long pixelIndex; unsigned int topColor, bottomColor; @@ -1196,6 +1206,8 @@ S3L_Unit _LCR_rendererSmoothRot(S3L_Unit angleOld, S3L_Unit angleNew, */ void _LCR_rendererLoadMapChunks(void) { + LCR_LOG2("loading map chunks"); + int8_t camChunk[3], chunkOffsets[3]; S3L_Vec4 cp = LCR_renderer.scene.camera.transform.translation; S3L_Vec4 cf; @@ -1236,6 +1248,8 @@ void _LCR_rendererLoadMapChunks(void) */ void LCR_rendererDrawLOD(void) { + LCR_LOG2("drawing LOD"); + #if LCR_SETTING_LOD_DISTANCE < 64 int variability = 0; @@ -1267,6 +1281,8 @@ void LCR_rendererDrawLOD(void) void LCR_drawLevelFloor(void) { + LCR_LOG2("drawing floor"); + #if LCR_SETTING_FLOOR_PARTICLE_SIZE != 0 #define _STEP ((LCR_MAP_SIZE_BLOCKS * LCR_RENDERER_UNIT) / LCR_SETTING_FLOOR_PARTICLE_RESOLUTION) @@ -1302,6 +1318,8 @@ void LCR_drawLevelFloor(void) #if LCR_ANIMATE_CAR void _LCR_rendererAnimateCar(void) { + LCR_LOG2("animating car"); + for (int i = LCR_renderer.frame % LCR_SETTING_CAR_ANIMATION_SUBDIVIDE; i < LCR_CAR_VERTEX_COUNT; i += LCR_SETTING_CAR_ANIMATION_SUBDIVIDE) { @@ -1351,6 +1369,8 @@ void _LCR_rendererAnimateCar(void) void LCR_rendererCameraFollow(void) { + LCR_LOG2("following camera"); + S3L_Transform3D transPrev = LCR_renderer.scene.camera.transform; LCR_renderer.scene.camera.transform.translation.y = @@ -1427,6 +1447,8 @@ void LCR_rendererSetWheelState(LCR_GameUnit rotation, LCR_GameUnit steer) void LCR_rendererDraw(void) { + LCR_LOG2("rendering frame (start)"); + // first make sure rotations are in correct range: LCR_renderer.scene.camera.transform.rotation.y = S3L_wrap( LCR_renderer.scene.camera.transform.rotation.y, S3L_F); @@ -1450,9 +1472,13 @@ void LCR_rendererDraw(void) LCR_drawLevelFloor(); LCR_rendererDrawLOD(); + LCR_LOG2("gonna render 3D scene"); S3L_drawScene(LCR_renderer.scene); + LCR_LOG2("rendering 3D scene done"); LCR_renderer.frame++; + + LCR_LOG2("rendering frame (end)"); } #endif // guard diff --git a/settings.h b/settings.h index 029cbec..6afad11 100644 --- a/settings.h +++ b/settings.h @@ -131,4 +131,11 @@ #define LCR_SETTING_SMOOTH_ANIMATIONS 1 #endif +#ifndef LCR_SETTING_LOG_LEVEL + /** How detailed the console logs should be. 0 turns off logging, 1 means + normal, 2 more detailed etc. Setting high log level may result in spam and + slower game, but is useful for debugging. */ + #define LCR_SETTING_LOG_LEVEL 1 +#endif + #endif // guard From 53096517c9e11966691ffcb008f4da0b15926b2e Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Fri, 27 Sep 2024 00:55:30 +0200 Subject: [PATCH 05/10] Fix segfault --- frontend_sdl.c | 2 +- renderer.h | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/frontend_sdl.c b/frontend_sdl.c index 99346f2..5764f1b 100644 --- a/frontend_sdl.c +++ b/frontend_sdl.c @@ -1,7 +1,7 @@ #include #include -#define LCR_SETTING_LOG_LEVEL 5 +#define LCR_SETTING_LOG_LEVEL 0 #include "game.h" #include "debug.h" diff --git a/renderer.h b/renderer.h index 1f19e8b..8194ae8 100644 --- a/renderer.h +++ b/renderer.h @@ -917,7 +917,7 @@ void LCR_rendererDrawRect(int x, int y, unsigned int w, unsigned int h, if (x < 0) { - if (-1 * x > ((int) w)) + if (-1 * x >= ((int) w)) return; w += x; @@ -936,12 +936,13 @@ void LCR_rendererDrawRect(int x, int y, unsigned int w, unsigned int h, y = 0; } - if (y + h > LCR_EFFECTIVE_RESOLUTION_X) + if (y + h > LCR_EFFECTIVE_RESOLUTION_Y) h = LCR_EFFECTIVE_RESOLUTION_Y - y; unsigned long index = y * LCR_EFFECTIVE_RESOLUTION_X + x; - if (dither) +if (0) +// if (dither) { uint8_t parity = (x % 2) == (y % 2); From 34293981b0fb6f4a32eba09a876763a13f6f710b Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Sat, 28 Sep 2024 01:47:05 +0200 Subject: [PATCH 06/10] Try to handle car turtle --- frontend_sdl.c | 2 +- racing.h | 163 +++++++++++++++++++++++++++++++++++++++++++------ renderer.h | 3 +- 3 files changed, 145 insertions(+), 23 deletions(-) diff --git a/frontend_sdl.c b/frontend_sdl.c index 5764f1b..5d769e3 100644 --- a/frontend_sdl.c +++ b/frontend_sdl.c @@ -1,7 +1,7 @@ #include #include -#define LCR_SETTING_LOG_LEVEL 0 +#define LCR_SETTING_LOG_LEVEL 2 #include "game.h" #include "debug.h" diff --git a/racing.h b/racing.h index a204abb..f29dcda 100644 --- a/racing.h +++ b/racing.h @@ -15,6 +15,10 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit #define LCR_RACING_INPUT_LEFT 0x08 #define LCR_PHYSICS_UNIT 2048 ///< length of map square for physics engine + + +#define TPE_RESHAPE_TENSION_LIMIT 10 +#define TPE_RESHAPE_ITERATIONS 5 #include "map.h" #include "tinyphysicsengine.h" @@ -35,16 +39,14 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit #define LCR_GRAVITY (LCR_PHYSICS_UNIT / 140) #define LCR_CAR_FORWARD_FRICTION (TPE_F / 9) -#define LCR_CAR_TURN_FRICTION (4 * TPE_F / 4) +#define LCR_CAR_TURN_FRICTION (TPE_F) #define LCR_CAR_ELASTICITY (TPE_F / 110) #define LCR_CAR_ACCELERATION (LCR_PHYSICS_UNIT / 16) -#define LCR_CAR_TURN_SPEED (LCR_GAME_UNIT / 20) -#define LCR_CAR_TURN_MAX (LCR_GAME_UNIT / 4) +#define LCR_CAR_TURN_SPEED (LCR_GAME_UNIT / 18) +#define LCR_CAR_TURN_MAX ((7 * LCR_GAME_UNIT) / 24) #endif - - #define LCR_CAR_JOINTS 5 #define LCR_CAR_CONNECTIONS 10 @@ -64,6 +66,11 @@ struct TPE_Vec3 carPositions[2]; ///* Current and previous position. TPE_Vec3 carRotations[2]; ///* Current and previous rotation. + +TPE_Vec3 carOKPositions[LCR_CAR_JOINTS]; +uint8_t carNotOKCount; + + LCR_GameUnit wheelRotation; LCR_GameUnit wheelSteer; } LCR_racing; @@ -315,9 +322,22 @@ void LCR_racingRestart(void) LCR_racing.carRotations[0] = TPE_vec3(0,0,0); LCR_racing.carRotations[1] = LCR_racing.carRotations[0]; + + +for (int i = 0; i < LCR_CAR_JOINTS; ++i) + LCR_racing.carOKPositions[i] = TPE_vec3(0,0,0); + +LCR_racing.carNotOKCount = 0; + + + // TODO } + + + + /** Initializes the racing module, only call once. */ @@ -353,6 +373,9 @@ void LCR_racingInit(void) all map blocks. */ LCR_racing.carBody.flags |= TPE_BODY_FLAG_NO_BSPHERE; +TPE_bodyRotateByAxis(&LCR_racing.carBody, + TPE_vec3(TPE_F / 3,0,0)); + LCR_racingRestart(); } @@ -558,29 +581,24 @@ void LCR_racingStep(unsigned int input) TPE_worldStep(&(LCR_racing.physicsWorld)); LCR_LOG2("stepping physics engine done"); - if (TPE_vec3Dot(carUp,TPE_vec3Minus(LCR_racing.carBody.joints[4].position, - LCR_racing.carBody.joints[0].position)) < 0) - { - /* if the car falls on its roof the center joint may flip to the other - side, here we fix it */ - - LCR_racing.carBody.joints[4].position = TPE_vec3Plus(TPE_vec3Times(carUp, - LCR_GAME_UNIT / 4),LCR_racing.carBody.joints[4].position); - } TPE_Vec3 tmpVec = LCR_racing.carPositions[0]; - LCR_racing.carPositions[0] = // average position of 4 wheels to get car pos - _LCR_TPE_vec3DividePlain( - TPE_vec3TimesPlain( - TPE_vec3Plus( +TPE_Vec3 wheelAverage = + _LCR_TPE_vec3DividePlain( + TPE_vec3Plus( TPE_vec3Plus( LCR_racing.carBody.joints[0].position, LCR_racing.carBody.joints[1].position), TPE_vec3Plus( LCR_racing.carBody.joints[2].position, - LCR_racing.carBody.joints[3].position) - ),LCR_GAME_UNIT),4 * LCR_PHYSICS_UNIT); + LCR_racing.carBody.joints[3].position)),4); + +LCR_racing.carPositions[0] = + _LCR_TPE_vec3DividePlain( + TPE_vec3TimesPlain( + wheelAverage,LCR_GAME_UNIT), + LCR_PHYSICS_UNIT); LCR_racing.carPositions[0] = // smooth the position TPE_vec3KeepWithinBox(LCR_racing.carPositions[1],LCR_racing.carPositions[0], @@ -597,6 +615,111 @@ void LCR_racingStep(unsigned int input) LCR_racing.carRotations[1] = LCR_racing.carRotations[0]; LCR_racing.carRotations[0] = tmpVec; + +int carOK = 1; // TODO: for checking if car shape is fine, if we're inside a wall etc. + + + TPE_Unit roofAngle = + TPE_vec3Dot(carUp,TPE_vec3Normalized(TPE_vec3Minus(LCR_racing.carBody.joints[4].position, + LCR_racing.carBody.joints[0].position))); + + if (roofAngle < TPE_F / 4) // TODO: magic constant + { + LCR_LOG2("car roof low, applying anti force") + + tmpVec = TPE_vec3Times(carUp,LCR_PHYSICS_UNIT / 16); // TODO: 16 magic con. + + if (roofAngle <= 0) + { + LCR_LOG1("car roof flipped over, fixing") + LCR_racing.carBody.joints[4].position = wheelAverage; + roofAngle = 0; + } + + roofAngle = TPE_F - 4 * roofAngle; // 4 comes from above TPE_F / 4 + + tmpVec = TPE_vec3Times(tmpVec,roofAngle); + + // accelerate roof and wheels away from each other + for (int i = 0; i < LCR_CAR_JOINTS; ++i) + { + LCR_racing.carBody.joints[i].velocity[0] += (i == 4 ? 1 : -1) * tmpVec.x; + LCR_racing.carBody.joints[i].velocity[1] += (i == 4 ? 1 : -1) * tmpVec.y; + LCR_racing.carBody.joints[i].velocity[2] += (i == 4 ? 1 : -1) * tmpVec.z; + } + } + + + + +if (1 /*carOK*/) +{ + for (int i = 0; i < LCR_CAR_JOINTS; ++i) + LCR_racing.carOKPositions[i] = LCR_racing.carBody.joints[i].position; +} +else +{ + LCR_racing.carNotOKCount++; + +// if (LCR_racing.carNotOKCount > 4) + { + LCR_LOG1("car not OK, fixing"); + + for (int i = 0; i < LCR_CAR_JOINTS; ++i) +{ + LCR_racing.carBody.joints[i].position = LCR_racing.carOKPositions[i]; +//LCR_racing.carBody.joints[i].velocity[0] = 0; +//LCR_racing.carBody.joints[i].velocity[1] = 0; +//LCR_racing.carBody.joints[i].velocity[2] = 0; +} + TPE_bodyReshape(&(LCR_racing.carBody), + LCR_racing.physicsWorld.environmentFunction); + + // TODO + + LCR_racing.carNotOKCount = 0; + } +} + + + + +#if 0 + if (TPE_vec3Dot(carUp,TPE_vec3Minus(LCR_racing.carBody.joints[4].position, + LCR_racing.carBody.joints[0].position)) < 0) + { + /* if the car falls on its roof the center joint may flip to the other + side, here we fix it */ + LCR_LOG1("car roof flipped over, fixing") + + // LCR_racing.carBody.joints[4].position = TPE_vec3Plus(TPE_vec3Times(carUp, + // LCR_PHYSICS_UNIT / 8),LCR_racing.carBody.joints[4].position); + +//tmpVec = TPE_vec3Times(carUp,LCR_PHYSICS_UNIT / 8); + +/* +for (int j = 0; j < 4; ++j) + LCR_racing.carBody.joints[j].position = TPE_vec3Minus( + LCR_racing.carBody.joints[j].position,tmpVec); +*/ + +/* +LCR_racing.carBody.joints[4].position = TPE_vec3Plus(TPE_vec3Times(carUp, + LCR_GAME_UNIT / 4),LCR_racing.carBody.joints[4].position); + + +LCR_racing.carBody.joints[4].position = + TPE_vec3Plus(LCR_racing.carBody.joints[4],tmpVec); +*/ + +// TPE_bodyReshape(&(LCR_racing.carBody), +//LCR_racing.physicsWorld.environmentFunction); + + + } +#endif + + LCR_racing.tick++; LCR_LOG2("racing step end"); diff --git a/renderer.h b/renderer.h index 8194ae8..9779d00 100644 --- a/renderer.h +++ b/renderer.h @@ -941,8 +941,7 @@ void LCR_rendererDrawRect(int x, int y, unsigned int w, unsigned int h, unsigned long index = y * LCR_EFFECTIVE_RESOLUTION_X + x; -if (0) -// if (dither) + if (dither) { uint8_t parity = (x % 2) == (y % 2); From beda272f18a547e8e9246eae759ff469e52a61b1 Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Sun, 29 Sep 2024 20:52:52 +0200 Subject: [PATCH 07/10] Handle start position --- assets.h | 67 +---------------- map.h | 61 +++++++--------- racing.h | 172 ++++++++++++++++++++++++++++---------------- tinyphysicsengine.h | 8 +++ 4 files changed, 146 insertions(+), 162 deletions(-) diff --git a/assets.h b/assets.h index aed4680..f8b9c2e 100644 --- a/assets.h +++ b/assets.h @@ -32,77 +32,16 @@ LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,1,1,0,0), LCR_MAP_BLOCK(LCR_BLOCK_RAMP,46,0,33,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_90), LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,1,1,10,0,0), -LCR_MAP_BLOCK(LCR_BLOCK_FULL,36,0,33,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_LEFT,36,0,33,LCR_BLOCK_MATERIAL_CONCRETE,0), LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,1,10,0,0), LCR_MAP_BLOCK(LCR_BLOCK_FULL,36,0,43,LCR_BLOCK_MATERIAL_CONCRETE,0), LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,4,1,0,0), +LCR_MAP_BLOCK(LCR_BLOCK_FULL,32,0,32,0,0), +LCR_MAP_BLOCK(LCR_BLOCK_START,32,1,32,0,LCR_BLOCK_TRANSFORM_ROT_180), -/* - LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,0,0,0,LCR_BLOCK_MATERIAL_CONCRETE,0), - LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,63,1,1,0,0), - LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,0,0,63,LCR_BLOCK_MATERIAL_CONCRETE,0), - LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,63,1,1,0,0), - - LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,0,0,0,LCR_BLOCK_MATERIAL_CONCRETE,0), - LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,1,1,63,0,0), - - LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,63,0,0,LCR_BLOCK_MATERIAL_CONCRETE,0), - LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,1,1,63,0,0), -*/ - -/* - LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,32,32,32,LCR_BLOCK_MATERIAL_CONCRETE,0), - LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,4,4,4,0,0), - - LCR_MAP_BLOCK(LCR_BLOCK_FULL,50,20,20,LCR_BLOCK_MATERIAL_GRASS,0), - LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,5,5,5,0,0), - - LCR_MAP_BLOCK(LCR_BLOCK_FULL,10,10,10,LCR_BLOCK_MATERIAL_GRASS,0), - LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,3,3,3,0,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_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_FULL,63,63,0,LCR_BLOCK_MATERIAL_GRASS,0), - LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,1,1,40,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), -*/ -/* - 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,32,32,32,LCR_BLOCK_MATERIAL_CONCRETE,0), - LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,32,32,LCR_BLOCK_MATERIAL_GRASS,0), - LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_WALL,34,32,32,LCR_BLOCK_MATERIAL_GRASS,0), - LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_WALL,35,32,32,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_90), - - LCR_MAP_BLOCK(LCR_BLOCK_FULL,63,35,32,LCR_BLOCK_MATERIAL_CONCRETE,0), - LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,35,32,LCR_BLOCK_MATERIAL_ICE,0), - LCR_MAP_BLOCK(LCR_BLOCK_FULL,40,35,32,LCR_BLOCK_MATERIAL_DIRT,0), - LCR_MAP_BLOCK(LCR_BLOCK_FULL,41,35,32,LCR_BLOCK_MATERIAL_CONCRETE,0), - LCR_MAP_BLOCK(LCR_BLOCK_FULL,42,35,32,LCR_BLOCK_MATERIAL_CONCRETE,0), - LCR_MAP_BLOCK(LCR_BLOCK_FULL,43,35,32,LCR_BLOCK_MATERIAL_CONCRETE,0), - LCR_MAP_BLOCK(LCR_BLOCK_FULL,44,35,32,LCR_BLOCK_MATERIAL_CONCRETE,0), - - LCR_MAP_BLOCK(LCR_BLOCK_BOTTOM_LEFT,34,32,33,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 }; diff --git a/map.h b/map.h index c6dec9e..f1292ab 100644 --- a/map.h +++ b/map.h @@ -104,7 +104,7 @@ struct { uint16_t blockCount; uint8_t blocks[LCR_SETTING_MAP_MAX_BLOCKS * LCR_BLOCK_SIZE]; - uint32_t startPos; + uint8_t startPos[4]; ///< Initial position and rotation. uint8_t environment; @@ -227,6 +227,8 @@ uint8_t *LCR_getMapBlockAtCoordNumber(uint32_t coord) */ uint8_t _LCR_mapAddBlock(const uint8_t block[LCR_BLOCK_SIZE]) { + LCR_LOG2("adding map block"); + if (LCR_currentMap.blockCount >= LCR_SETTING_MAP_MAX_BLOCKS) return 0; @@ -283,7 +285,11 @@ uint8_t _LCR_mapAddBlock(const uint8_t block[LCR_BLOCK_SIZE]) */ uint8_t LCR_mapLoad(const uint8_t *map) { - LCR_currentMap.startPos = 0; + LCR_LOG0("loading map") + + for (int i = 0; i < 4; ++i) + LCR_currentMap.startPos[i] = 0; + LCR_currentMap.blockCount = 0; if (map[0] != LCR_MAP_MAGIC_NUMBER1 || map[1] != LCR_MAP_MAGIC_NUMBER2) @@ -348,6 +354,15 @@ uint8_t LCR_mapLoad(const uint8_t *map) break; } + case LCR_BLOCK_START: + LCR_mapBlockGetCoords(map, + LCR_currentMap.startPos, + LCR_currentMap.startPos + 1, + LCR_currentMap.startPos + 2); + + LCR_currentMap.startPos[3] = LCR_mapBlockGetTransform(map) & 0x60; + break; + default: if (!_LCR_mapAddBlock(map)) // normal block return 0; @@ -355,16 +370,10 @@ uint8_t LCR_mapLoad(const uint8_t *map) break; } - map += 4; + map += LCR_BLOCK_SIZE; } - - // process and remove special blocks: - - // TODO - - // sort the blocks (for fast searching): - - // TODO + + LCR_LOG2("map loaded") return 1; } @@ -447,8 +456,9 @@ void _LCR_addBlockShapeByte(uint8_t *bytes, uint8_t *byteCount, *byteCount += 1; } - - +/** + Macro that transforms coordinates according to block transformation. +*/ #define LCR_TRANSFORM_COORDS(trans,cx,cy,cz,maxXZ,maxY)\ if (trans & LCR_BLOCK_TRANSFORM_FLIP_H) cx = maxXZ - cx;\ if (trans & 0x20) { /* for both 90 and 270 */ \ @@ -460,8 +470,6 @@ void _LCR_addBlockShapeByte(uint8_t *bytes, uint8_t *byteCount, if (trans & LCR_BLOCK_TRANSFORM_FLIP_V) \ cy = maxY - cy; - - /** Gets a shape of given map block type as a 3D model composed of triangles. The model is returned as an array of byte triplets (triangles), with each byte @@ -584,28 +592,7 @@ void LCR_mapGetBlockShape(uint8_t blockType, uint8_t transform, _LCR_decodeMapBlockCoords(bytes[i],&x,&y,&z); -LCR_TRANSFORM_COORDS(transform,x,y,z,6,4) - -/* - if (transform & LCR_BLOCK_TRANSFORM_FLIP_H) - x = 6 - x; - - if (transform & 0x20) // for both 90 and 270 - { - tmp = z; - z = x; - x = 6 - tmp; - } - - if (transform & 0x40) // for both 180 and 270 - { - x = 6 - x; - z = 6 - z; - } - - if (transform & LCR_BLOCK_TRANSFORM_FLIP_V) - y = 4 - y; -*/ + LCR_TRANSFORM_COORDS(transform,x,y,z,6,4) bytes[i] = _LCR_encodeMapBlockCoords(x,y,z); } diff --git a/racing.h b/racing.h index f29dcda..63d5bb9 100644 --- a/racing.h +++ b/racing.h @@ -62,9 +62,8 @@ struct Lower bits record current collisions, higher bits the previous state (for averaging). */ - - TPE_Vec3 carPositions[2]; ///* Current and previous position. - TPE_Vec3 carRotations[2]; ///* Current and previous rotation. + TPE_Vec3 carPositions[2]; ///* Current and previous position in game units. + TPE_Vec3 carRotations[2]; ///* Current and previous rotation in game units. TPE_Vec3 carOKPositions[LCR_CAR_JOINTS]; @@ -322,6 +321,61 @@ void LCR_racingRestart(void) LCR_racing.carRotations[0] = TPE_vec3(0,0,0); LCR_racing.carRotations[1] = LCR_racing.carRotations[0]; + +TPE_bodyMoveTo(&(LCR_racing.carBody), + TPE_vec3( + (((TPE_Unit) LCR_currentMap.startPos[0]) - LCR_MAP_SIZE_BLOCKS / 2) + * LCR_PHYSICS_UNIT + LCR_PHYSICS_UNIT / 2, + (((TPE_Unit) LCR_currentMap.startPos[1]) - LCR_MAP_SIZE_BLOCKS / 2) + * LCR_PHYSICS_UNIT / 2 + LCR_PHYSICS_UNIT / 4, + (((TPE_Unit) LCR_currentMap.startPos[2]) - LCR_MAP_SIZE_BLOCKS / 2) + * LCR_PHYSICS_UNIT + LCR_PHYSICS_UNIT / 2)); + +// TODO: allow also flipping the car upside down on start? +if (LCR_currentMap.startPos[3]) + TPE_bodyRotateByAxis(&(LCR_racing.carBody), + TPE_vec3(0, + LCR_currentMap.startPos[3] == LCR_BLOCK_TRANSFORM_ROT_90 ? 3 * TPE_F / 4 : + (LCR_currentMap.startPos[3] == LCR_BLOCK_TRANSFORM_ROT_180 ? TPE_F / 2 : + (TPE_F / 4)),0)); + + +/* +const uint8_t *b = LCR_currentMap.blocks; + +for (int i = 0; i < LCR_currentMap.blockCount; ++i) +{ + if (*b == LCR_BLOCK_START) + { + uint8_t x, y, z; + + LCR_LOG1("placing car to start position"); + + LCR_mapBlockGetCoords(b,&x,&y,&z); + + TPE_bodyMoveTo(&(LCR_racing.carBody), + TPE_vec3( + (((TPE_Unit) x) - LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT + + LCR_PHYSICS_UNIT / 2, + (((TPE_Unit) y) - LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT / 2 + + LCR_PHYSICS_UNIT / 4, + (((TPE_Unit) z) - LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT + + LCR_PHYSICS_UNIT / 2 + )); + + // resuse x: + x = LCR_mapBlockGetTransform(b) & 0x60; + + if (x) + TPE_bodyRotateByAxis(&(LCR_racing.carBody), + TPE_vec3(0,x == LCR_BLOCK_TRANSFORM_ROT_90 ? TPE_F / 4 : + (x == LCR_BLOCK_TRANSFORM_ROT_180 ? TPE_F / 2 : (3 * TPE_F / 4)),0)); + } + + b += LCR_BLOCK_SIZE; +} +*/ + for (int i = 0; i < LCR_CAR_JOINTS; ++i) @@ -373,9 +427,6 @@ void LCR_racingInit(void) all map blocks. */ LCR_racing.carBody.flags |= TPE_BODY_FLAG_NO_BSPHERE; -TPE_bodyRotateByAxis(&LCR_racing.carBody, - TPE_vec3(TPE_F / 3,0,0)); - LCR_racingRestart(); } @@ -616,29 +667,29 @@ LCR_racing.carPositions[0] = LCR_racing.carRotations[0] = tmpVec; -int carOK = 1; // TODO: for checking if car shape is fine, if we're inside a wall etc. - TPE_Unit roofAngle = - TPE_vec3Dot(carUp,TPE_vec3Normalized(TPE_vec3Minus(LCR_racing.carBody.joints[4].position, - LCR_racing.carBody.joints[0].position))); + TPE_Unit angle = + TPE_vec3Dot(carUp,TPE_vec3Normalized(TPE_vec3Minus( + LCR_racing.carBody.joints[4].position, + LCR_racing.carBody.joints[0].position))); - if (roofAngle < TPE_F / 4) // TODO: magic constant + if (angle < TPE_F / 4) // TODO: magic constant { LCR_LOG2("car roof low, applying anti force") tmpVec = TPE_vec3Times(carUp,LCR_PHYSICS_UNIT / 16); // TODO: 16 magic con. - if (roofAngle <= 0) + if (angle <= 0) { LCR_LOG1("car roof flipped over, fixing") LCR_racing.carBody.joints[4].position = wheelAverage; - roofAngle = 0; + angle = 0; } - roofAngle = TPE_F - 4 * roofAngle; // 4 comes from above TPE_F / 4 + angle = TPE_F - 4 * angle; // 4 comes from above TPE_F / 4 - tmpVec = TPE_vec3Times(tmpVec,roofAngle); + tmpVec = TPE_vec3Times(tmpVec,angle); // accelerate roof and wheels away from each other for (int i = 0; i < LCR_CAR_JOINTS; ++i) @@ -650,76 +701,75 @@ int carOK = 1; // TODO: for checking if car shape is fine, if we're inside a wal } +angle = + (TPE_vec3Dot( + TPE_vec3Minus( + LCR_racing.carBody.joints[1].position, + LCR_racing.carBody.joints[0].position), + TPE_vec3Minus( + LCR_racing.carBody.joints[2].position, + LCR_racing.carBody.joints[0].position)) + + TPE_vec3Dot( + TPE_vec3Minus( + LCR_racing.carBody.joints[0].position, + LCR_racing.carBody.joints[3].position), + TPE_vec3Minus( + LCR_racing.carBody.joints[2].position, + LCR_racing.carBody.joints[3].position))); + +int carOK = 1; // TODO: for checking if car shape is fine, if we're inside a wall etc. + +if (angle < 1900 || angle > 2350 || + (LCR_racing.carBody.flags & TPE_BODY_FLAG_UNRESOLVED)) + carOK = 0; -if (1 /*carOK*/) +if (carOK) { + LCR_racing.carNotOKCount -= LCR_racing.carNotOKCount ? 1 : 0; + for (int i = 0; i < LCR_CAR_JOINTS; ++i) LCR_racing.carOKPositions[i] = LCR_racing.carBody.joints[i].position; } else { - LCR_racing.carNotOKCount++; -// if (LCR_racing.carNotOKCount > 4) + if (LCR_racing.carNotOKCount > 5) { LCR_LOG1("car not OK, fixing"); for (int i = 0; i < LCR_CAR_JOINTS; ++i) -{ - LCR_racing.carBody.joints[i].position = LCR_racing.carOKPositions[i]; + { + LCR_racing.carBody.joints[i].position = + TPE_vec3Plus( + LCR_racing.carBody.joints[i].position, + LCR_racing.carOKPositions[i]); + + LCR_racing.carBody.joints[i].position.x /= 2; + LCR_racing.carBody.joints[i].position.y /= 2; + LCR_racing.carBody.joints[i].position.z /= 2; + + + + //LCR_racing.carBody.joints[i].velocity[0] = 0; //LCR_racing.carBody.joints[i].velocity[1] = 0; //LCR_racing.carBody.joints[i].velocity[2] = 0; -} - TPE_bodyReshape(&(LCR_racing.carBody), - LCR_racing.physicsWorld.environmentFunction); + } + +// TPE_bodyReshape(&(LCR_racing.carBody), +// LCR_racing.physicsWorld.environmentFunction); // TODO - LCR_racing.carNotOKCount = 0; + // LCR_racing.carNotOKCount = 0; } + else + LCR_racing.carNotOKCount++; } - -#if 0 - if (TPE_vec3Dot(carUp,TPE_vec3Minus(LCR_racing.carBody.joints[4].position, - LCR_racing.carBody.joints[0].position)) < 0) - { - /* if the car falls on its roof the center joint may flip to the other - side, here we fix it */ - LCR_LOG1("car roof flipped over, fixing") - - // LCR_racing.carBody.joints[4].position = TPE_vec3Plus(TPE_vec3Times(carUp, - // LCR_PHYSICS_UNIT / 8),LCR_racing.carBody.joints[4].position); - -//tmpVec = TPE_vec3Times(carUp,LCR_PHYSICS_UNIT / 8); - -/* -for (int j = 0; j < 4; ++j) - LCR_racing.carBody.joints[j].position = TPE_vec3Minus( - LCR_racing.carBody.joints[j].position,tmpVec); -*/ - -/* -LCR_racing.carBody.joints[4].position = TPE_vec3Plus(TPE_vec3Times(carUp, - LCR_GAME_UNIT / 4),LCR_racing.carBody.joints[4].position); - - -LCR_racing.carBody.joints[4].position = - TPE_vec3Plus(LCR_racing.carBody.joints[4],tmpVec); -*/ - -// TPE_bodyReshape(&(LCR_racing.carBody), -//LCR_racing.physicsWorld.environmentFunction); - - - } -#endif - - LCR_racing.tick++; LCR_LOG2("racing step end"); diff --git a/tinyphysicsengine.h b/tinyphysicsengine.h index 2fc14a7..ed3e6a2 100644 --- a/tinyphysicsengine.h +++ b/tinyphysicsengine.h @@ -252,6 +252,9 @@ typedef struct energy. */ #define TPE_BODY_FLAG_NO_BSPHERE 64 /**< Stops quick bounding sphere checks against environment. */ +#define TPE_BODY_FLAG_UNRESOLVED 128 /**< Set automatically for bodies whose + collision with environment failed + to be resolved. */ /** Function used for defining static environment, working similarly to an SDF (signed distance function). The parameters are: 3D point P, max distance D. @@ -1913,6 +1916,8 @@ uint8_t TPE_bodyEnvironmentResolveCollision(TPE_Body *body, TPE_Vec3 c; TPE_Unit d; + body->flags &= ~TPE_BODY_FLAG_UNRESOLVED; + if (!(body->flags & TPE_BODY_FLAG_NO_BSPHERE)) { TPE_bodyGetFastBSphere(body,&c,&d); @@ -1938,6 +1943,9 @@ uint8_t TPE_bodyEnvironmentResolveCollision(TPE_Body *body, { collision = 1; + if (r == 2) + body->flags |= TPE_BODY_FLAG_UNRESOLVED; + if (body->flags & TPE_BODY_FLAG_NONROTATING) _TPE_bodyNonrotatingJointCollided(body,i,previousPos,r == 1); } From 3310008a0de310f1652f1e028f9b6e33cd44b6d9 Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Sun, 29 Sep 2024 21:41:06 +0200 Subject: [PATCH 08/10] Clean a bit --- assets.h | 37 +++++++-------- racing.h | 138 +++++++++++++++---------------------------------------- 2 files changed, 57 insertions(+), 118 deletions(-) diff --git a/assets.h b/assets.h index f8b9c2e..e8eecaf 100644 --- a/assets.h +++ b/assets.h @@ -16,8 +16,6 @@ #include #include "map.h" -// TODO: images should be 64x64 indexed, sky will be composed of 2x2 normal images - static const uint8_t map1[] = { LCR_MAP_MAGIC_NUMBER, @@ -48,10 +46,13 @@ LCR_MAP_BLOCK(LCR_BLOCK_START,32,1,32,0,LCR_BLOCK_TRANSFORM_ROT_180), #define LCR_IMAGE_SIZE 64 ///< one-dimension resolution of bitmap image #define LCR_IMAGE_STORE_SIZE (LCR_IMAGE_SIZE * LCR_IMAGE_SIZE + 256 * 2) -// TODO: put this into struct -uint16_t _LCR_currentImagePalette[256]; -const uint8_t *_LCR_currentImagePixel; -const uint8_t *_LCR_currentImage; + +struct +{ + uint16_t palette[256]; + const uint8_t *pixel; + const uint8_t *image; +} LCR_currentImage; #define LCR_IMAGE_WALL_CONCRETE 0 #define LCR_IMAGE_WALL_WOOD 1 @@ -6138,17 +6139,17 @@ static const uint8_t LCR_images[] = void LCR_loadImage(unsigned int index) { - _LCR_currentImage = LCR_images + index * LCR_IMAGE_STORE_SIZE; + LCR_currentImage.image = LCR_images + index * LCR_IMAGE_STORE_SIZE; for (int i = 0; i < 256; ++i) { - _LCR_currentImagePalette[i] = *_LCR_currentImage; - _LCR_currentImage++; - _LCR_currentImagePalette[i] |= ((uint16_t) (*_LCR_currentImage)) << 8; - _LCR_currentImage++; + LCR_currentImage.palette[i] = *LCR_currentImage.image; + LCR_currentImage.image++; + LCR_currentImage.palette[i] |= ((uint16_t) (*LCR_currentImage.image)) << 8; + LCR_currentImage.image++; } - _LCR_currentImagePixel = _LCR_currentImage; + LCR_currentImage.pixel = LCR_currentImage.image; } /** @@ -6159,11 +6160,11 @@ void LCR_imageChangeBrightness(int up) { if (up) for (int i = 0; i < 256; ++i) - _LCR_currentImagePalette[i] |= 0x18e3; + LCR_currentImage.palette[i] |= 0x18e3; else for (int i = 0; i < 256; ++i) - _LCR_currentImagePalette[i] = - ((_LCR_currentImagePalette[i] >> 1) & 0x7bef); + LCR_currentImage.palette[i] = + ((LCR_currentImage.palette[i] >> 1) & 0x7bef); } /** @@ -6175,7 +6176,7 @@ uint16_t LCR_sampleImage(int x, int y) // TODO: bottleneck, later on optimize here x = (y % LCR_IMAGE_SIZE) * LCR_IMAGE_SIZE + (x % LCR_IMAGE_SIZE); x += (x < 0) * (LCR_IMAGE_SIZE * LCR_IMAGE_SIZE); - return _LCR_currentImagePalette[_LCR_currentImage[x]]; + return LCR_currentImage.palette[LCR_currentImage.image[x]]; } /** @@ -6184,8 +6185,8 @@ uint16_t LCR_sampleImage(int x, int y) */ uint16_t LCR_getNextImagePixel(void) { - uint16_t r = _LCR_currentImagePalette[*_LCR_currentImagePixel]; - _LCR_currentImagePixel++; + uint16_t r = LCR_currentImage.palette[*LCR_currentImage.pixel]; + LCR_currentImage.pixel++; return r; } diff --git a/racing.h b/racing.h index 63d5bb9..3859619 100644 --- a/racing.h +++ b/racing.h @@ -16,27 +16,14 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit #define LCR_PHYSICS_UNIT 2048 ///< length of map square for physics engine - #define TPE_RESHAPE_TENSION_LIMIT 10 -#define TPE_RESHAPE_ITERATIONS 5 +#define TPE_RESHAPE_ITERATIONS 5 #include "map.h" #include "tinyphysicsengine.h" // TODO: move some of this to constants? -#if 0 - -#define LCR_GRAVITY (LCR_PHYSICS_UNIT / 100) -#define LCR_CAR_FORWARD_FRICTION (TPE_F / 11) -#define LCR_CAR_TURN_FRICTION (4 * TPE_F / 4) -#define LCR_CAR_ELASTICITY (TPE_F / 100) -#define LCR_CAR_ACCELERATION (LCR_PHYSICS_UNIT / 15) -#define LCR_CAR_TURN_SPEED (LCR_GAME_UNIT / 20) -#define LCR_CAR_TURN_MAX (LCR_GAME_UNIT / 4) - -#else - #define LCR_GRAVITY (LCR_PHYSICS_UNIT / 140) #define LCR_CAR_FORWARD_FRICTION (TPE_F / 9) #define LCR_CAR_TURN_FRICTION (TPE_F) @@ -45,8 +32,6 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit #define LCR_CAR_TURN_SPEED (LCR_GAME_UNIT / 18) #define LCR_CAR_TURN_MAX ((7 * LCR_GAME_UNIT) / 24) -#endif - #define LCR_CAR_JOINTS 5 #define LCR_CAR_CONNECTIONS 10 @@ -339,52 +324,12 @@ if (LCR_currentMap.startPos[3]) (LCR_currentMap.startPos[3] == LCR_BLOCK_TRANSFORM_ROT_180 ? TPE_F / 2 : (TPE_F / 4)),0)); - -/* -const uint8_t *b = LCR_currentMap.blocks; - -for (int i = 0; i < LCR_currentMap.blockCount; ++i) -{ - if (*b == LCR_BLOCK_START) - { - uint8_t x, y, z; - - LCR_LOG1("placing car to start position"); - - LCR_mapBlockGetCoords(b,&x,&y,&z); - - TPE_bodyMoveTo(&(LCR_racing.carBody), - TPE_vec3( - (((TPE_Unit) x) - LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT + - LCR_PHYSICS_UNIT / 2, - (((TPE_Unit) y) - LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT / 2 + - LCR_PHYSICS_UNIT / 4, - (((TPE_Unit) z) - LCR_MAP_SIZE_BLOCKS / 2) * LCR_PHYSICS_UNIT + - LCR_PHYSICS_UNIT / 2 - )); - - // resuse x: - x = LCR_mapBlockGetTransform(b) & 0x60; - - if (x) - TPE_bodyRotateByAxis(&(LCR_racing.carBody), - TPE_vec3(0,x == LCR_BLOCK_TRANSFORM_ROT_90 ? TPE_F / 4 : - (x == LCR_BLOCK_TRANSFORM_ROT_180 ? TPE_F / 2 : (3 * TPE_F / 4)),0)); - } - - b += LCR_BLOCK_SIZE; -} -*/ - - - for (int i = 0; i < LCR_CAR_JOINTS; ++i) LCR_racing.carOKPositions[i] = TPE_vec3(0,0,0); LCR_racing.carNotOKCount = 0; - // TODO } @@ -676,13 +621,13 @@ LCR_racing.carPositions[0] = if (angle < TPE_F / 4) // TODO: magic constant { - LCR_LOG2("car roof low, applying anti force") + LCR_LOG2("roof squeezed, applying anti force") tmpVec = TPE_vec3Times(carUp,LCR_PHYSICS_UNIT / 16); // TODO: 16 magic con. if (angle <= 0) { - LCR_LOG1("car roof flipped over, fixing") + LCR_LOG1("roof flipped over, fixing") LCR_racing.carBody.joints[4].position = wheelAverage; angle = 0; } @@ -700,75 +645,68 @@ LCR_racing.carPositions[0] = } } +// now try to decide if car shape is OK +TPE_Unit v1, v2; -angle = - (TPE_vec3Dot( - TPE_vec3Minus( +v1 = TPE_vec3Dot( + TPE_vec3Minus( LCR_racing.carBody.joints[1].position, LCR_racing.carBody.joints[0].position), TPE_vec3Minus( - LCR_racing.carBody.joints[2].position, - LCR_racing.carBody.joints[0].position)) + - TPE_vec3Dot( + LCR_racing.carBody.joints[3].position, + LCR_racing.carBody.joints[0].position)); + +v2 = TPE_vec3Dot( + TPE_vec3Minus( + LCR_racing.carBody.joints[1].position, + LCR_racing.carBody.joints[2].position), TPE_vec3Minus( - LCR_racing.carBody.joints[0].position, - LCR_racing.carBody.joints[3].position), - TPE_vec3Minus( - LCR_racing.carBody.joints[2].position, - LCR_racing.carBody.joints[3].position))); + LCR_racing.carBody.joints[3].position, + LCR_racing.carBody.joints[2].position)); -int carOK = 1; // TODO: for checking if car shape is fine, if we're inside a wall etc. +v1 = v1 > v2 ? ((v1 * LCR_GAME_UNIT) / TPE_nonZero(v2)) : + ((v2 * LCR_GAME_UNIT) / TPE_nonZero(v1)); -if (angle < 1900 || angle > 2350 || - (LCR_racing.carBody.flags & TPE_BODY_FLAG_UNRESOLVED)) - carOK = 0; +#define _TOLERANCE (LCR_GAME_UNIT / 8) - -if (carOK) +if ((LCR_racing.carBody.flags & TPE_BODY_FLAG_UNRESOLVED) || + v1 < (LCR_GAME_UNIT - _TOLERANCE) || + v1 > (LCR_GAME_UNIT + _TOLERANCE)) { - LCR_racing.carNotOKCount -= LCR_racing.carNotOKCount ? 1 : 0; + // car not OK - for (int i = 0; i < LCR_CAR_JOINTS; ++i) - LCR_racing.carOKPositions[i] = LCR_racing.carBody.joints[i].position; -} -else -{ - - if (LCR_racing.carNotOKCount > 5) + if (LCR_racing.carNotOKCount > 8) // TODO: constant { - LCR_LOG1("car not OK, fixing"); + LCR_LOG1("car not OK for some time, fixing"); for (int i = 0; i < LCR_CAR_JOINTS; ++i) { + // iterate towards previous OK position + LCR_racing.carBody.joints[i].position = - TPE_vec3Plus( - LCR_racing.carBody.joints[i].position, + TPE_vec3Plus(LCR_racing.carBody.joints[i].position, LCR_racing.carOKPositions[i]); LCR_racing.carBody.joints[i].position.x /= 2; LCR_racing.carBody.joints[i].position.y /= 2; LCR_racing.carBody.joints[i].position.z /= 2; - - - -//LCR_racing.carBody.joints[i].velocity[0] = 0; -//LCR_racing.carBody.joints[i].velocity[1] = 0; -//LCR_racing.carBody.joints[i].velocity[2] = 0; + for (int j = 0; j < 3; ++j) // lower speed a bit + LCR_racing.carBody.joints[i].velocity[j] = + (7 * ((int) LCR_racing.carBody.joints[i].velocity[j])) / 8; } - -// TPE_bodyReshape(&(LCR_racing.carBody), -// LCR_racing.physicsWorld.environmentFunction); - - // TODO - - // LCR_racing.carNotOKCount = 0; } else LCR_racing.carNotOKCount++; } +else +{ + // car OK + LCR_racing.carNotOKCount -= LCR_racing.carNotOKCount ? 1 : 0; - + for (int i = 0; i < LCR_CAR_JOINTS; ++i) + LCR_racing.carOKPositions[i] = LCR_racing.carBody.joints[i].position; +} LCR_racing.tick++; From 10366c2a09e3cf31dc7478c08e83451a2b2f77ac Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Mon, 30 Sep 2024 01:58:21 +0200 Subject: [PATCH 09/10] Start antiglitch --- TODO.txt | 52 ++++++++++++++++++++++----------------------- assets.h | 39 +++++++++++++++++++++++++--------- racing.h | 42 ++++++++++++++---------------------- tinyphysicsengine.h | 3 +-- 4 files changed, 71 insertions(+), 65 deletions(-) diff --git a/TODO.txt b/TODO.txt index 40affe4..a2ed219 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,10 +1,5 @@ +- allow car to be flipped upside down on start? with start block transform - maybe change sticker to fan? could me more fun: TEST and see -- 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 - one type of image - map actually in ASCII format? how will humans edit it? - make a simple rendering setting: - will exclude images and only draw solid colors, let's say only 16, so that @@ -16,19 +11,7 @@ - then iterate over the strip that should have the sky texture and only draw to pixels where depth buffer was not overwritten (this step can be left out in case we have depth buffer or sky turned off) -TOTAL SIZE OF TEXTURES: - - 64 x 64 x 2 = 8192, 6 x floor + 2 x wall + 1 x car = 8 * 8192 = 73728 - - (128 x 128 x 1) x 3 background = 49152 - - total = 122880 -- OK so materials (final?): - - concrete: normal \ - - accelerator: accelerates (adds some constant to speed?) > same wall texture? - - maybe jumppad (big "fan")? / - - dirt: a bit slippery (maybe also a bit slows down?) \ - - magnet: pulls car downwards (allows riding on ceiling etc.) > same wall texture? - - ice: extremely slippery (can barely turn) / - camera behavior? what if car is riding upside down (on magnet) etc? -- track size: 64x64x64 - EFFICINT MAP DRAWING: - map will be subdivided into subblocks (probably 16x16x16 or 8x8x8), only nearest subblocks (and possibly only those in viewing direction will be @@ -41,14 +24,6 @@ TOTAL SIZE OF TEXTURES: subblocks we want to draw. - THIS??? Draw further blocks in a simplified way, e.g. just splatting literal squares with constant color? See how it looks :) -- Architecture (modules): - - map: loads map n stuff - - racing engine (depends on map): handles physics of car with given inputs - - rendering engine (depends on map): hanles rendering of the map - - game (depends on all): joins it all together - - settings, constants etc. - - individual frontends - - ...? - Textures: size? format? They will likely take a lot of mem, weak computers will have to do without them. - possibility of simple procedural textures to save space! <-- SOUNDS NICE @@ -140,4 +115,27 @@ TOTAL SIZE OF TEXTURES: BUGS: -DONE: +HANDLED: + +- track size: 64x64x64 +- sky images could be just composed of 4x4 normal images? then we only need + one type of image +TOTAL SIZE OF TEXTURES: + - 64 x 64 x 2 = 8192, 6 x floor + 2 x wall + 1 x car = 8 * 8192 = 73728 + - (128 x 128 x 1) x 3 background = 49152 + - total = 122880 +- OK so materials (final?): + - concrete: normal \ + - accelerator: accelerates (adds some constant to speed?) > same wall texture? + - maybe jumppad (big "fan")? / + - dirt: a bit slippery (maybe also a bit slows down?) \ + - magnet: pulls car downwards (allows riding on ceiling etc.) > same wall texture? + - ice: extremely slippery (can barely turn) / +- Architecture (modules): + - map: loads map n stuff + - racing engine (depends on map): handles physics of car with given inputs + - rendering engine (depends on map): hanles rendering of the map + - game (depends on all): joins it all together + - settings, constants etc. + - individual frontends + - ...? diff --git a/assets.h b/assets.h index e8eecaf..0ca3918 100644 --- a/assets.h +++ b/assets.h @@ -24,20 +24,39 @@ static const uint8_t map1[] = 10, 0, -LCR_MAP_BLOCK(LCR_BLOCK_RAMP,36,0,32,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,1,1,0,0), +LCR_MAP_BLOCK(LCR_BLOCK_START,1,1,1,0,0), -LCR_MAP_BLOCK(LCR_BLOCK_RAMP,46,0,33,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_90), -LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,1,1,10,0,0), +LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,0,0,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,15,1,20,0,0), + +LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,0,20,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,15,1,0,0), + +LCR_MAP_BLOCK(LCR_BLOCK_RAMP,0,1,19,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,8,1,1,0,0), + +LCR_MAP_BLOCK(LCR_BLOCK_RAMP,8,1,5,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_270), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,1,1,8,0,0), + +LCR_MAP_BLOCK(LCR_BLOCK_LEFT,5,1,5,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_90), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,2,1,0,0), + + +LCR_MAP_BLOCK(LCR_BLOCK_LEFT,9,0,20,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,8,1,8,0,0), + + +LCR_MAP_BLOCK(LCR_BLOCK_FULL,15,0,0,LCR_BLOCK_MATERIAL_GRASS,0), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,1,15,0,0), + +LCR_MAP_BLOCK(LCR_BLOCK_FULL,25,0,0,LCR_BLOCK_MATERIAL_ICE,0), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,1,15,0,0), + +LCR_MAP_BLOCK(LCR_BLOCK_FULL,35,0,0,LCR_BLOCK_MATERIAL_DIRT,0), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,1,15,0,0), -LCR_MAP_BLOCK(LCR_BLOCK_LEFT,36,0,33,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,1,10,0,0), -LCR_MAP_BLOCK(LCR_BLOCK_FULL,36,0,43,LCR_BLOCK_MATERIAL_CONCRETE,0), -LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,4,1,0,0), -LCR_MAP_BLOCK(LCR_BLOCK_FULL,32,0,32,0,0), -LCR_MAP_BLOCK(LCR_BLOCK_START,32,1,32,0,LCR_BLOCK_TRANSFORM_ROT_180), LCR_MAP_TERMINATOR diff --git a/racing.h b/racing.h index 3859619..65d6e07 100644 --- a/racing.h +++ b/racing.h @@ -454,6 +454,21 @@ void _LCR_racingWheelAccelerate(unsigned int wheel, TPE_Vec3 dir) (dir.z * LCR_CAR_ACCELERATION) / TPE_F; } +int _LCR_racingCarShapeOK(void) +{ + int r = 1; + + for (int i = 0; i < LCR_racing.carBody.jointCount; ++i) + r &= TPE_connectionTension(TPE_dist( + LCR_racing.carBody.joints[ + LCR_racing.carBody.connections[i].joint1].position, + LCR_racing.carBody.joints[ + LCR_racing.carBody.connections[i].joint2].position), + LCR_racing.carBody.connections[i].length) < TPE_F / 16; // TODO: const + + return r; +} + /** Updates the racing physics world, call every LCR_RACING_TICK_MS milliseconds. */ @@ -645,33 +660,8 @@ LCR_racing.carPositions[0] = } } -// now try to decide if car shape is OK -TPE_Unit v1, v2; - -v1 = TPE_vec3Dot( - TPE_vec3Minus( - LCR_racing.carBody.joints[1].position, - LCR_racing.carBody.joints[0].position), - TPE_vec3Minus( - LCR_racing.carBody.joints[3].position, - LCR_racing.carBody.joints[0].position)); - -v2 = TPE_vec3Dot( - TPE_vec3Minus( - LCR_racing.carBody.joints[1].position, - LCR_racing.carBody.joints[2].position), - TPE_vec3Minus( - LCR_racing.carBody.joints[3].position, - LCR_racing.carBody.joints[2].position)); - -v1 = v1 > v2 ? ((v1 * LCR_GAME_UNIT) / TPE_nonZero(v2)) : - ((v2 * LCR_GAME_UNIT) / TPE_nonZero(v1)); - -#define _TOLERANCE (LCR_GAME_UNIT / 8) - if ((LCR_racing.carBody.flags & TPE_BODY_FLAG_UNRESOLVED) || - v1 < (LCR_GAME_UNIT - _TOLERANCE) || - v1 > (LCR_GAME_UNIT + _TOLERANCE)) + !_LCR_racingCarShapeOK()) { // car not OK diff --git a/tinyphysicsengine.h b/tinyphysicsengine.h index ed3e6a2..e48ec74 100644 --- a/tinyphysicsengine.h +++ b/tinyphysicsengine.h @@ -640,8 +640,7 @@ static inline TPE_Unit TPE_nonZero(TPE_Unit x) static inline TPE_Unit TPE_connectionTension(TPE_Unit length, TPE_Unit desiredLength) { - return (length * TPE_F) / desiredLength - - TPE_F; + return (length * TPE_F) / desiredLength - TPE_F; } TPE_Joint TPE_joint(TPE_Vec3 position, TPE_Unit size) From 4a3c9b2873b95a58ac9d447ca39f321d695f7ee1 Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Mon, 30 Sep 2024 02:28:27 +0200 Subject: [PATCH 10/10] Continue antiglitch --- racing.h | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/racing.h b/racing.h index 65d6e07..dce1623 100644 --- a/racing.h +++ b/racing.h @@ -583,6 +583,8 @@ void LCR_racingStep(unsigned int input) (!(input & LCR_RACING_INPUT_RIGHT))) LCR_racing.wheelSteer /= 2; + + if ((LCR_racing.wheelCollisions & 0x0f) != 0x0f) // EXPERIMENTAL: don't apply gravity with all wheels on ground TPE_bodyApplyGravity(&(LCR_racing.carBody),LCR_GRAVITY); @@ -671,28 +673,33 @@ if ((LCR_racing.carBody.flags & TPE_BODY_FLAG_UNRESOLVED) || for (int i = 0; i < LCR_CAR_JOINTS; ++i) { - // iterate towards previous OK position + if (LCR_racing.carNotOKCount < 30) // TODO: const + { + // for a while try to smoothly iterate towards previous OK position + LCR_racing.carBody.joints[i].position = + TPE_vec3Plus(LCR_racing.carBody.joints[i].position, + LCR_racing.carOKPositions[i]); - LCR_racing.carBody.joints[i].position = - TPE_vec3Plus(LCR_racing.carBody.joints[i].position, - LCR_racing.carOKPositions[i]); - - LCR_racing.carBody.joints[i].position.x /= 2; - LCR_racing.carBody.joints[i].position.y /= 2; - LCR_racing.carBody.joints[i].position.z /= 2; + LCR_racing.carBody.joints[i].position.x /= 2; + LCR_racing.carBody.joints[i].position.y /= 2; + LCR_racing.carBody.joints[i].position.z /= 2; + } + else // hard set the pos (iteration may be infinite due to sim.) + LCR_racing.carBody.joints[i].position = LCR_racing.carOKPositions[i]; for (int j = 0; j < 3; ++j) // lower speed a bit LCR_racing.carBody.joints[i].velocity[j] = (7 * ((int) LCR_racing.carBody.joints[i].velocity[j])) / 8; } } - else - LCR_racing.carNotOKCount++; + + LCR_racing.carNotOKCount += LCR_racing.carNotOKCount < 32 ? 1 : 0; } else { // car OK - LCR_racing.carNotOKCount -= LCR_racing.carNotOKCount ? 1 : 0; +// LCR_racing.carNotOKCount -= LCR_racing.carNotOKCount ? 1 : 0; + LCR_racing.carNotOKCount = 0; for (int i = 0; i < LCR_CAR_JOINTS; ++i) LCR_racing.carOKPositions[i] = LCR_racing.carBody.joints[i].position;