From d0bbd09856dc72103e47342c574141b4b9845f15 Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Sun, 6 Oct 2024 21:53:11 +0200 Subject: [PATCH] Start materials --- assets.h | 31 +++++++++++-- map.h | 2 + racing.h | 132 ++++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 126 insertions(+), 39 deletions(-) diff --git a/assets.h b/assets.h index d64c6d5..de7729d 100644 --- a/assets.h +++ b/assets.h @@ -26,7 +26,7 @@ static const uint8_t map1[] = LCR_MAP_BLOCK(LCR_BLOCK_START,1,1,1,0,0), -LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,0,0,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,0,0,LCR_BLOCK_MATERIAL_GRASS,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), @@ -44,12 +44,35 @@ 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_RAMP_CURVED_WALL,3,4,4,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_WALL,3,1,8,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP_STEEP,3,2,8,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_PLAT,2,1,8,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP_STEEP,2,2,8,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP_STEEP,3,4,8,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_FLIP_V), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_PLAT,3,5,8,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_FLIP_V), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_PLAT,4,5,8,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_FLIP_V), -/* -LCR_MAP_BLOCK(LCR_BLOCK_FULL,15,0,0,LCR_BLOCK_MATERIAL_GRASS,0), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_WALL,4,1,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_180), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP_STEEP,4,2,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_180), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_PLAT,5,1,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_180), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP_STEEP,5,2,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_180), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP_STEEP,4,4,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_FLIP_V | LCR_BLOCK_TRANSFORM_ROT_180), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_PLAT,4,5,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_FLIP_V | LCR_BLOCK_TRANSFORM_ROT_180), +LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_PLAT,3,5,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_FLIP_V | LCR_BLOCK_TRANSFORM_ROT_180), + +LCR_MAP_BLOCK(LCR_BLOCK_FULL,2,1,9,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,2,5,1,0,0), + +LCR_MAP_BLOCK(LCR_BLOCK_FULL,4,1,5,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,2,5,1,0,0), + +LCR_MAP_BLOCK(LCR_BLOCK_FULL,3,6,6,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,2,1,3,0,0), + +LCR_MAP_BLOCK(LCR_BLOCK_FULL,15,0,0,LCR_BLOCK_MATERIAL_CONCRETE,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), diff --git a/map.h b/map.h index 093eacb..0576346 100644 --- a/map.h +++ b/map.h @@ -557,6 +557,8 @@ void LCR_mapGetBlockShape(uint8_t blockType, uint8_t transform, ADD(6,0,6) ADD(6,4,6) ADD(6,4,5) // right ADD(0,4,5) ADD(6,4,5) ADD(0,4,6) // top ADD(0,4,6) ADD(6,4,5) ADD(6,4,6) + // fall through + case LCR_BLOCK_RAMP_CURVED: { uint8_t plusZ = blockType == LCR_BLOCK_RAMP_CURVED; diff --git a/racing.h b/racing.h index 291cdf1..da1a916 100644 --- a/racing.h +++ b/racing.h @@ -32,6 +32,16 @@ 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) +#define LCR_CAR_FORWARD_FRICTION_ICE (TPE_F / 200) +#define LCR_CAR_TURN_FRICTION_ICE (TPE_F / 20) +#define LCR_CAR_ACCELERATION_ICE (LCR_PHYSICS_UNIT / 100) + +#define LCR_CAR_FORWARD_FRICTION_DIRT (TPE_F / 7) +#define LCR_CAR_TURN_FRICTION_DIRT (TPE_F / 2) + +#define LCR_CAR_TURN_FRICTION_GRASS (4 * (TPE_F / 5)) +#define LCR_CAR_ACCELERATION_GRASS (LCR_PHYSICS_UNIT / 20) + #define LCR_CAR_JOINTS 5 #define LCR_CAR_CONNECTIONS 10 @@ -144,11 +154,13 @@ TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block) _CHECK_NEXT(TPE_envAABox(point,TPE_vec3(5 * LCR_PHYSICS_UNIT / 12,0,0), TPE_vec3(LCR_PHYSICS_UNIT / 12,LCR_PHYSICS_UNIT / 4,LCR_PHYSICS_UNIT / 2))); + // fall through case LCR_BLOCK_RAMP_CURVED_PLAT: _CHECK_NEXT(TPE_envAABox(point,TPE_vec3(0,0,5 * LCR_PHYSICS_UNIT / 12), TPE_vec3(LCR_PHYSICS_UNIT / 2,LCR_PHYSICS_UNIT / 4,LCR_PHYSICS_UNIT / 12 ))); + // fall through case LCR_BLOCK_RAMP_CURVED: { @@ -524,14 +536,22 @@ LCR_GameUnit LCR_racingGetWheelSteer(void) return LCR_racing.wheelSteer; } -void _LCR_racingWheelAccelerate(unsigned int wheel, TPE_Vec3 dir) +void _LCR_racingWheelAccelerate(unsigned int wheel, TPE_Vec3 dir, + uint8_t material) { + TPE_Unit acc = + material == LCR_BLOCK_MATERIAL_ICE ? + LCR_CAR_ACCELERATION_ICE : + (material == LCR_BLOCK_MATERIAL_GRASS ? + LCR_CAR_ACCELERATION_GRASS : + LCR_CAR_ACCELERATION); + LCR_racing.carBody.joints[wheel].velocity[0] += - (dir.x * LCR_CAR_ACCELERATION) / TPE_F; + (dir.x * acc) / TPE_F; LCR_racing.carBody.joints[wheel].velocity[1] += - (dir.y * LCR_CAR_ACCELERATION) / TPE_F; + (dir.y * acc) / TPE_F; LCR_racing.carBody.joints[wheel].velocity[2] += - (dir.z * LCR_CAR_ACCELERATION) / TPE_F; + (dir.z * acc) / TPE_F; } int _LCR_racingCarShapeOK(void) @@ -557,6 +577,8 @@ void LCR_racingStep(unsigned int input) LCR_LOG2("racing step start"); TPE_Vec3 carForw, carRight, carUp; + uint8_t groundMat = LCR_BLOCK_MATERIAL_CONCRETE; // material under wheels + int groundBlockIndex = -1; carForw = TPE_vec3Normalized(TPE_vec3Plus( TPE_vec3Minus(LCR_racing.carBody.joints[0].position, @@ -572,6 +594,47 @@ void LCR_racingStep(unsigned int input) carUp = TPE_vec3Cross(carForw,carRight); + if ((LCR_racing.wheelCollisions & 0x0f) != 0x0f) // EXPERIMENTAL: don't apply gravity with all wheels on ground + TPE_bodyApplyGravity(&(LCR_racing.carBody),LCR_GRAVITY); + + if (LCR_racing.wheelCollisions) // at least one wheel on ground? + { + TPE_Unit upDot = TPE_vec3Dot(carUp,TPE_vec3(0,TPE_F,0)); + + if (upDot > TPE_F / 8 || upDot < -1 * TPE_F / 8) // TODO: consts + { + uint8_t + gx = (LCR_racing.carPositions[0].x + (LCR_MAP_SIZE_BLOCKS / 2) * + LCR_GAME_UNIT) / LCR_GAME_UNIT, + gy = (LCR_racing.carPositions[0].y + (LCR_MAP_SIZE_BLOCKS / 2) * + (LCR_GAME_UNIT / 2)) / (LCR_GAME_UNIT / 2), + gz = (LCR_racing.carPositions[0].z + (LCR_MAP_SIZE_BLOCKS / 2) * + LCR_GAME_UNIT) / LCR_GAME_UNIT; + + TPE_Unit yMod = (LCR_racing.carPositions[0].y + LCR_MAP_SIZE_BLOCKS * + LCR_GAME_UNIT / 2) % (LCR_GAME_UNIT / 2); + + if (upDot > 0 && yMod < LCR_GAME_UNIT / 2) // TODO: const + groundBlockIndex = LCR_mapGetBlockAt(gx,gy - 1,gz); + else if (upDot < 0 && yMod > LCR_GAME_UNIT / 2) + groundBlockIndex = LCR_mapGetBlockAt(gx,gy + 1,gz); + + if (groundBlockIndex == -1) + groundBlockIndex = LCR_mapGetBlockAt(gx,gy,gz); + } + + if (groundBlockIndex != -1) + groundMat = LCR_mapBlockGetMaterial( + LCR_currentMap.blocks + groundBlockIndex * LCR_BLOCK_SIZE); + } + + LCR_racing.carBody.friction = + groundMat == LCR_BLOCK_MATERIAL_ICE ? + LCR_CAR_FORWARD_FRICTION_ICE : + (groundMat == LCR_BLOCK_MATERIAL_DIRT ? + LCR_CAR_FORWARD_FRICTION_DIRT : + LCR_CAR_FORWARD_FRICTION); + if (input) { unsigned char steering = 0; @@ -615,13 +678,13 @@ void LCR_racingStep(unsigned int input) { if (input & LCR_RACING_INPUT_FORW) { - _LCR_racingWheelAccelerate(0,carForw); - _LCR_racingWheelAccelerate(1,carForw); + _LCR_racingWheelAccelerate(0,carForw,groundMat); + _LCR_racingWheelAccelerate(1,carForw,groundMat); } else if (input & LCR_RACING_INPUT_BACK) { - _LCR_racingWheelAccelerate(0,TPE_vec3TimesPlain(carForw,-1)); - _LCR_racingWheelAccelerate(1,TPE_vec3TimesPlain(carForw,-1)); + _LCR_racingWheelAccelerate(0,TPE_vec3TimesPlain(carForw,-1),groundMat); + _LCR_racingWheelAccelerate(1,TPE_vec3TimesPlain(carForw,-1),groundMat); } } @@ -649,7 +712,15 @@ void LCR_racingStep(unsigned int input) /* friction is in the direction if the axis and its magnitude is determined by the dot product (angle) of the axis and velocity */ TPE_Vec3 fric = TPE_vec3Times(ja,(TPE_vec3Dot(ja,jv) * - LCR_CAR_TURN_FRICTION) / TPE_F); + (groundMat == LCR_BLOCK_MATERIAL_CONCRETE ? + LCR_CAR_TURN_FRICTION : + (groundMat == LCR_BLOCK_MATERIAL_DIRT ? + LCR_CAR_TURN_FRICTION_DIRT : + ( + groundMat == LCR_BLOCK_MATERIAL_GRASS ? + LCR_CAR_TURN_FRICTION_GRASS : + LCR_CAR_TURN_FRICTION_ICE))) + ) / TPE_F); jv = TPE_vec3Minus(jv,fric); // subtract the friction @@ -663,35 +734,25 @@ 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); - LCR_racing.wheelCollisions <<= 4; LCR_LOG2("gonna step physics engine"); TPE_worldStep(&(LCR_racing.physicsWorld)); LCR_LOG2("stepping physics engine done"); - TPE_Vec3 tmpVec = LCR_racing.carPositions[0]; -TPE_Vec3 wheelAverage = - _LCR_TPE_vec3DividePlain( + 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)),4); + 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)),4); -LCR_racing.carPositions[0] = - _LCR_TPE_vec3DividePlain( - TPE_vec3TimesPlain( - wheelAverage,LCR_GAME_UNIT), - LCR_PHYSICS_UNIT); + 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], @@ -708,13 +769,9 @@ LCR_racing.carPositions[0] = LCR_racing.carRotations[1] = LCR_racing.carRotations[0]; LCR_racing.carRotations[0] = tmpVec; - - - - TPE_Unit angle = - 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 (angle < TPE_F / 4) // TODO: magic constant { @@ -742,6 +799,11 @@ LCR_racing.carPositions[0] = } } + + + + + if ((LCR_racing.carBody.flags & TPE_BODY_FLAG_UNRESOLVED) || !_LCR_racingCarShapeOK()) {