Turn car vertically on start

This commit is contained in:
Miloslav Ciz 2024-12-19 21:10:18 +01:00
parent b79b83e56a
commit 3352d9a234
3 changed files with 55 additions and 41 deletions

4
game.h
View file

@ -414,6 +414,10 @@ LCR_GameUnit physicsInterpolationParam = LCR_GAME_UNIT -
if (sleep) if (sleep)
LCR_sleep(sleep); LCR_sleep(sleep);
else
{
LCR_LOG1("can't sleep, frames take too long!");
}
LCR_LOG2("game step end"); LCR_LOG2("game step end");

2
map.h
View file

@ -508,7 +508,7 @@ uint8_t LCR_mapLoadFromStr(const char *mapStr)
LCR_currentMap.startPos[0] = coords[0]; LCR_currentMap.startPos[0] = coords[0];
LCR_currentMap.startPos[1] = coords[1]; LCR_currentMap.startPos[1] = coords[1];
LCR_currentMap.startPos[2] = coords[2]; LCR_currentMap.startPos[2] = coords[2];
LCR_currentMap.startPos[3] = trans & 0x60; LCR_currentMap.startPos[3] = trans;
break; break;
case LCR_BLOCK_CHECKPOINT_0: case LCR_BLOCK_CHECKPOINT_0:

View file

@ -60,6 +60,7 @@ struct
TPE_Body carBody; TPE_Body carBody;
TPE_Joint carJoints[LCR_CAR_JOINTS]; TPE_Joint carJoints[LCR_CAR_JOINTS];
TPE_Connection carConnections[LCR_CAR_CONNECTIONS]; TPE_Connection carConnections[LCR_CAR_CONNECTIONS];
uint32_t tick; uint32_t tick;
uint8_t wheelCollisions; /**< In individual bits records for each car wheel uint8_t wheelCollisions; /**< In individual bits records for each car wheel
whether it's currently touching the ground. whether it's currently touching the ground.
@ -70,29 +71,28 @@ struct
TPE_Vec3 carRotations[2]; ///< Current and previous rotation in game units. TPE_Vec3 carRotations[2]; ///< Current and previous rotation in game units.
uint8_t carDrifting; ///< Whether or not the car is currently in drift. uint8_t carDrifting; ///< Whether or not the car is currently in drift.
TPE_Vec3 carOKPositions[LCR_CAR_JOINTS];
uint8_t carNotOKCount;
TPE_Unit fanForce; ///< Upwards acceleration caused by a fan. TPE_Unit fanForce; ///< Upwards acceleration caused by a fan.
LCR_GameUnit wheelAngle; ///< Current wheel angle, 0 to LCR_GAME_UNIT.
LCR_GameUnit wheelRotation; LCR_GameUnit wheelSteer; ///< Left/right steer with LCR_CAR_STEER_MAX bounds.
LCR_GameUnit wheelSteer;
LCR_GameUnit carSpeed; /**< Signed speed in game units per tick (negative LCR_GameUnit carSpeed; /**< Signed speed in game units per tick (negative
if backwards) */ if backwards) */
// for fixing physics bugs:
TPE_Vec3 carOKPositions[LCR_CAR_JOINTS];
uint8_t carNotOKCount;
} LCR_racing; } LCR_racing;
TPE_Vec3 _LCR_TPE_vec3DividePlain(TPE_Vec3 v, TPE_Unit d) TPE_Vec3 _LCR_TPE_vec3DividePlain(TPE_Vec3 v, TPE_Unit d)
{ {
v.x /= d; v.y /= d; v.z /= d; v.x /= d; v.y /= d; v.z /= d;
return v; return v;
} }
/**
Helper function for _LCR_racingEnvironmentFunction, returns closest point
on a map block placed at coordinate origin.
*/
TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block) TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block)
{ {
TPE_Vec3 v, vBest; TPE_Vec3 v, vBest;
@ -230,8 +230,8 @@ TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block)
sides[5] *= -1; sides[5] *= -1;
} }
_CHECK_NEXT(TPE_envAATriPrism(point,TPE_vec3(0,0,0),sides,LCR_PHYSICS_UNIT / 2 _CHECK_NEXT(TPE_envAATriPrism(point,TPE_vec3(0,0,0),sides,
,1)); LCR_PHYSICS_UNIT / 2,1));
sides[2] = sides[4]; sides[2] = sides[4];
sides[3] = sides[5]; sides[3] = sides[5];
@ -239,8 +239,8 @@ TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block)
sides[4] = LCR_PHYSICS_UNIT / 2; sides[4] = LCR_PHYSICS_UNIT / 2;
sides[5] = LCR_PHYSICS_UNIT / 2; sides[5] = LCR_PHYSICS_UNIT / 2;
_CHECK_NEXT(TPE_envAATriPrism(point,TPE_vec3(0,0,0),sides,LCR_PHYSICS_UNIT / 2 _CHECK_NEXT(TPE_envAATriPrism(point,TPE_vec3(0,0,0),sides,
,1)); LCR_PHYSICS_UNIT / 2,1));
point = vBest; point = vBest;
@ -334,8 +334,8 @@ TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block)
case LCR_BLOCK_HILL: case LCR_BLOCK_HILL:
{ {
point = point = (point.y > -1 * LCR_PHYSICS_UNIT / 4 && point.z
(point.y > -1 * LCR_PHYSICS_UNIT / 4 && point.z < LCR_PHYSICS_UNIT / 4) ? < LCR_PHYSICS_UNIT / 4) ?
TPE_envCylinder(point, TPE_envCylinder(point,
TPE_vec3(0,-1 * LCR_PHYSICS_UNIT / 2,LCR_PHYSICS_UNIT / 4), TPE_vec3(0,-1 * LCR_PHYSICS_UNIT / 2,LCR_PHYSICS_UNIT / 4),
TPE_vec3(LCR_PHYSICS_UNIT / 2,0,0), TPE_vec3(LCR_PHYSICS_UNIT / 2,0,0),
@ -351,8 +351,7 @@ TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block)
} }
case LCR_BLOCK_BUMP: case LCR_BLOCK_BUMP:
point = TPE_envCone(point, point = TPE_envCone(point,TPE_vec3(0,-1 * LCR_PHYSICS_UNIT / 4 ,0),
TPE_vec3(0,-1 * LCR_PHYSICS_UNIT / 4 ,0),
TPE_vec3(0,LCR_PHYSICS_UNIT / 6,0),(5 * LCR_PHYSICS_UNIT) / 12); TPE_vec3(0,LCR_PHYSICS_UNIT / 6,0),(5 * LCR_PHYSICS_UNIT) / 12);
break; break;
@ -391,6 +390,10 @@ TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block)
return point; return point;
} }
/**
For tinyphysicsengine, function that defines the shape of physics world,
returns closest point to any given point in space.
*/
TPE_Vec3 _LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist) TPE_Vec3 _LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist)
{ {
// start with the map outside walls: // start with the map outside walls:
@ -467,7 +470,7 @@ TPE_Vec3 _LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist)
const uint8_t *block = LCR_currentMap.blocks; const uint8_t *block = LCR_currentMap.blocks;
/* Full check of all map blocks, slow, shouldn't happen often! */ // Full check of all map blocks, slow, shouldn't happen often!
for (int j = 0; j < LCR_currentMap.blockCount; ++j) for (int j = 0; j < LCR_currentMap.blockCount; ++j)
{ {
TPE_ENV_NEXT(_LCR_racingBlockEnvFunc(point,block),point) TPE_ENV_NEXT(_LCR_racingBlockEnvFunc(point,block),point)
@ -563,7 +566,7 @@ void LCR_racingRestart(void)
TPE_bodyActivate(&(LCR_racing.carBody)); TPE_bodyActivate(&(LCR_racing.carBody));
LCR_racing.wheelCollisions = 0; LCR_racing.wheelCollisions = 0;
LCR_racing.wheelRotation = 0; LCR_racing.wheelAngle = 0;
LCR_racing.wheelSteer = 0; LCR_racing.wheelSteer = 0;
LCR_racing.carSpeed = 0; LCR_racing.carSpeed = 0;
LCR_racing.carDrifting = 0; LCR_racing.carDrifting = 0;
@ -591,8 +594,7 @@ void LCR_racingRestart(void)
all map blocks. */ all map blocks. */
LCR_racing.carBody.flags |= TPE_BODY_FLAG_NO_BSPHERE; LCR_racing.carBody.flags |= TPE_BODY_FLAG_NO_BSPHERE;
TPE_bodyMoveTo(&(LCR_racing.carBody), TPE_bodyMoveTo(&(LCR_racing.carBody),TPE_vec3(
TPE_vec3(
(((TPE_Unit) LCR_currentMap.startPos[0]) - LCR_MAP_SIZE_BLOCKS / 2) (((TPE_Unit) LCR_currentMap.startPos[0]) - LCR_MAP_SIZE_BLOCKS / 2)
* LCR_PHYSICS_UNIT + LCR_PHYSICS_UNIT / 2, * LCR_PHYSICS_UNIT + LCR_PHYSICS_UNIT / 2,
(((TPE_Unit) LCR_currentMap.startPos[1]) - LCR_MAP_SIZE_BLOCKS / 2) (((TPE_Unit) LCR_currentMap.startPos[1]) - LCR_MAP_SIZE_BLOCKS / 2)
@ -600,19 +602,29 @@ TPE_bodyMoveTo(&(LCR_racing.carBody),
(((TPE_Unit) LCR_currentMap.startPos[2]) - LCR_MAP_SIZE_BLOCKS / 2) (((TPE_Unit) LCR_currentMap.startPos[2]) - LCR_MAP_SIZE_BLOCKS / 2)
* LCR_PHYSICS_UNIT + LCR_PHYSICS_UNIT / 2)); * LCR_PHYSICS_UNIT + LCR_PHYSICS_UNIT / 2));
// TODO: allow also flipping the car upside down on start? if (LCR_currentMap.startPos[3])
if (LCR_currentMap.startPos[3]) {
TPE_bodyRotateByAxis(&(LCR_racing.carBody), uint8_t trans = LCR_currentMap.startPos[3];
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));
for (int i = 0; i < LCR_CAR_JOINTS; ++i) if (trans & LCR_BLOCK_TRANSFORM_FLIP_V)
TPE_bodyRotateByAxis(&(LCR_racing.carBody),
TPE_vec3(TPE_FRACTIONS_PER_UNIT / 2,0,0));
trans &=
LCR_BLOCK_TRANSFORM_ROT_90 |
LCR_BLOCK_TRANSFORM_ROT_180 |
LCR_BLOCK_TRANSFORM_ROT_270;
TPE_bodyRotateByAxis(&(LCR_racing.carBody),
TPE_vec3(0,(trans == LCR_BLOCK_TRANSFORM_ROT_90) ?
3 * TPE_F / 4 : (trans == LCR_BLOCK_TRANSFORM_ROT_180) ?
TPE_F / 2 : (TPE_F / 4),0));
}
for (int i = 0; i < LCR_CAR_JOINTS; ++i)
LCR_racing.carOKPositions[i] = TPE_vec3(0,0,0); LCR_racing.carOKPositions[i] = TPE_vec3(0,0,0);
LCR_racing.carNotOKCount = 0; LCR_racing.carNotOKCount = 0;
LCR_racing.carPositions[0] = TPE_vec3(0,0,0); LCR_racing.carPositions[0] = TPE_vec3(0,0,0);
LCR_racing.carPositions[1] = LCR_racing.carPositions[0]; LCR_racing.carPositions[1] = LCR_racing.carPositions[0];
@ -623,8 +635,6 @@ LCR_racing.carNotOKCount = 0;
LCR_racing.carPositions[1] = LCR_racing.carPositions[0]; LCR_racing.carPositions[1] = LCR_racing.carPositions[0];
LCR_racing.carRotations[1] = LCR_racing.carRotations[0]; LCR_racing.carRotations[1] = LCR_racing.carRotations[0];
// TODO
} }
/** /**
@ -701,7 +711,7 @@ int LCR_racingCarWheelTouchesGround(int wheel)
LCR_GameUnit LCR_racingGetWheelRotation(void) LCR_GameUnit LCR_racingGetWheelRotation(void)
{ {
return LCR_racing.wheelRotation; return LCR_racing.wheelAngle;
} }
LCR_GameUnit LCR_racingGetWheelSteer(void) LCR_GameUnit LCR_racingGetWheelSteer(void)
@ -877,11 +887,11 @@ uint32_t LCR_racingStep(unsigned int input)
if (!(input & LCR_RACING_INPUT_BACK)) if (!(input & LCR_RACING_INPUT_BACK))
rotateBy *= -1; rotateBy *= -1;
LCR_racing.wheelRotation = LCR_racing.wheelAngle =
(LCR_racing.wheelRotation + rotateBy) % LCR_GAME_UNIT; (LCR_racing.wheelAngle + rotateBy) % LCR_GAME_UNIT;
if (LCR_racing.wheelRotation < 0) if (LCR_racing.wheelAngle < 0)
LCR_racing.wheelRotation += LCR_GAME_UNIT; LCR_racing.wheelAngle += LCR_GAME_UNIT;
} }
if (input & LCR_RACING_INPUT_RIGHT) if (input & LCR_RACING_INPUT_RIGHT)