diff --git a/assets.h b/assets.h index 1ead39e..29828f7 100644 --- a/assets.h +++ b/assets.h @@ -26,9 +26,19 @@ static const uint8_t map1[] = 10, 0, - LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,32,2,32,LCR_BLOCK_MATERIAL_CONCRETE,0), - LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,1,40,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,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), @@ -40,6 +50,7 @@ static const uint8_t map1[] = LCR_MAP_BLOCK(LCR_BLOCK_FULL,2,25,50,LCR_BLOCK_MATERIAL_GRASS,0), LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,3,3,3,0,0), +*/ /* LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,0,0,LCR_BLOCK_MATERIAL_GRASS,0), diff --git a/game.h b/game.h index 8dd47ca..c3c6511 100644 --- a/game.h +++ b/game.h @@ -195,8 +195,6 @@ uint8_t LCR_gameStep(uint32_t time) if (time >= LCR_game.nextRenderFrameTime) { - - LCR_GameUnit physicsInterpolationParam = LCR_GAME_UNIT - ((LCR_game.nextRacingTickTime - time) * LCR_GAME_UNIT) / LCR_RACING_TICK_MS; diff --git a/racing.h b/racing.h index 90ea00c..87fe6fc 100644 --- a/racing.h +++ b/racing.h @@ -26,7 +26,9 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit #define LCR_CAR_FORWARD_FRICTION TPE_F / 14 #define LCR_CAR_TURN_FRICTION (3 * TPE_F / 4) #define LCR_CAR_ELASTICITY (TPE_F / 100) -#define LCR_CAR_ACCELERATION (LCR_PHYSICS_UNIT / 8) +#define LCR_CAR_ACCELERATION (LCR_PHYSICS_UNIT / 20) +#define LCR_CAR_TURN_SPEED (LCR_GAME_UNIT / 3) +#define LCR_CAR_TURN_MAX (LCR_GAME_UNIT / 4) struct { @@ -203,10 +205,12 @@ void _LCR_racingWheelAccelerate(unsigned int wheel, TPE_Vec3 dir) (dir.z * LCR_CAR_ACCELERATION) / TPE_F; } +/** + Updates the racing physics world, call every LCR_RACING_TICK_MS milliseconds. +*/ void LCR_racingStep(unsigned int input) { TPE_Vec3 carForw, carRight, carUp; -// TPE_Vec3 vel = TPE_vec3(0,0,0); carForw = TPE_vec3Normalized(TPE_vec3Plus( TPE_vec3Minus(LCR_racing.carBody.joints[0].position, @@ -224,26 +228,40 @@ void LCR_racingStep(unsigned int input) if (input) { + unsigned char steering = 0; + // TODO: magic constants - if (input & LCR_RACING_INPUT_FORW) - LCR_racing.wheelRotation = - (LCR_racing.wheelRotation + 5) % LCR_GAME_UNIT; - if (input & LCR_RACING_INPUT_BACK) - LCR_racing.wheelRotation -= 4; + if (input & (LCR_RACING_INPUT_FORW | LCR_RACING_INPUT_BACK)) + { + // TODO: in air always rotate wheels - while (LCR_racing.wheelRotation < 0) + LCR_racing.wheelRotation = LCR_racing.wheelRotation + + (LCR_racingGetCarSpeed() / 32) + % LCR_GAME_UNIT; + + if (LCR_racing.wheelRotation < 0) LCR_racing.wheelRotation += LCR_GAME_UNIT; + } + if (input & LCR_RACING_INPUT_RIGHT) + { + steering = 2; LCR_racing.wheelSteer = TPE_min( - LCR_racing.wheelSteer + 64,LCR_GAME_UNIT / 2); + LCR_racing.wheelSteer + LCR_CAR_TURN_SPEED, + LCR_CAR_TURN_MAX); + } - if (input & LCR_RACING_INPUT_LEFT) + else if (input & LCR_RACING_INPUT_LEFT) + { + steering = 1; LCR_racing.wheelSteer = TPE_max( - LCR_racing.wheelSteer - 64,-1 * LCR_GAME_UNIT / 2); + LCR_racing.wheelSteer - LCR_CAR_TURN_SPEED, + -1 * LCR_CAR_TURN_MAX); + } - if ((LCR_racing.wheelCollisions & 0x03) == 0x03) // back wheels on gr.? + if ((LCR_racing.wheelCollisions & 0x0c)) // back wheel on ground? { if (input & LCR_RACING_INPUT_FORW) { @@ -256,13 +274,45 @@ void LCR_racingStep(unsigned int input) _LCR_racingWheelAccelerate(1,TPE_vec3TimesPlain(carForw,-1)); } } + + for (int i = 0; i < 4; ++i) + if (LCR_racing.wheelCollisions & (0x01 << i)) // wheel on ground? + { + TPE_Vec3 jv = TPE_vec3( // joint velocity + LCR_racing.carBody.joints[i].velocity[0], + LCR_racing.carBody.joints[i].velocity[1], + LCR_racing.carBody.joints[i].velocity[2]); + + TPE_Vec3 ja = carRight; // wheel axis of rotation + + if (i >= 2 && steering) + { + // for front wheels with turning we tilt the wheel axis 45 degrees + + TPE_Unit steer = + (LCR_racing.wheelSteer * TPE_F) / LCR_GAME_UNIT; + + ja = TPE_vec3Normalized( + TPE_vec3Plus(TPE_vec3Times(carForw,steer),carRight)); + } + + /* 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); + + jv = TPE_vec3Minus(jv,fric); // subtract the friction + + LCR_racing.carBody.joints[i].velocity[0] = jv.x; + LCR_racing.carBody.joints[i].velocity[1] = jv.y; + LCR_racing.carBody.joints[i].velocity[2] = jv.z; + } } if ((!(input & LCR_RACING_INPUT_LEFT)) && (!(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); diff --git a/renderer.h b/renderer.h index fca8474..9b6e876 100644 --- a/renderer.h +++ b/renderer.h @@ -75,7 +75,7 @@ struct #if LCR_ANIMATE_CAR S3L_Unit wheelRotation; S3L_Unit wheelSteer; - S3L_Unit wheelRotationCenters[4]; + S3L_Unit wheelRotationCenters[4]; /**< back and front wheel XY centers */ S3L_Unit animatedCarVerts[LCR_CAR_VERTEX_COUNT * 3]; #endif diff --git a/settings.h b/settings.h index 8d8fbe0..d6c2ac2 100644 --- a/settings.h +++ b/settings.h @@ -102,18 +102,18 @@ #ifndef LCR_SETTING_CAMERA_HEIGHT /** Base height of the car follow camera, in 4ths of map block height. */ - #define LCR_SETTING_CAMERA_HEIGHT 4 + #define LCR_SETTING_CAMERA_HEIGHT 7 #endif #ifndef LCR_SETTING_CAMERA_HEIGHT_BAND /** Size of height band of the follow camera, in same units as base height. */ - #define LCR_SETTING_CAMERA_HEIGHT_BAND 2 + #define LCR_SETTING_CAMERA_HEIGHT_BAND 1 #endif #ifndef LCR_SETTING_CAMERA_MAX_DISTANCE /** Maximum horizontal distance of the car follow camera, in 4ths of map block width. */ - #define LCR_SETTING_CAMERA_MAX_DISTANCE 6 + #define LCR_SETTING_CAMERA_MAX_DISTANCE 5 #endif #ifndef LCR_SETTING_GHOST_COLOR