diff --git a/racing.h b/racing.h index b6967b3..45bbcba 100644 --- a/racing.h +++ b/racing.h @@ -54,6 +54,7 @@ struct TPE_Vec3 carPositions[2]; ///* Current and previous position. + TPE_Vec3 carRotations[2]; ///* Current and previous rotation. LCR_GameUnit wheelRotation; LCR_GameUnit wheelSteer; @@ -95,6 +96,21 @@ uint8_t _LCR_racingCollisionHandler(uint16_t b1, uint16_t j1, uint16_t b2, return 1; } +LCR_GameUnit _LCR_racingSmoothRot(LCR_GameUnit angleNew, LCR_GameUnit angleOld) +{ + /* We'll smooth small rotations by averaging the last two angles; bigger + rotations won't be smoothed -- firstly this removes lag for fast rotations + and also deals with the issue of averaging e.g. 1 and 359 degrees. */ + + LCR_GameUnit diff = angleNew - angleOld; + + if (diff > LCR_GAME_UNIT / 8 || + diff < -1 * LCR_GAME_UNIT / 8) + return angleNew; + + return angleOld + diff / 2; +} + /** Initializes new run. */ @@ -108,6 +124,11 @@ void LCR_racingRestart(void) LCR_racing.wheelRotation = 0; LCR_racing.wheelSteer = 0; + LCR_racing.carPositions[0] = TPE_vec3(0,0,0); + LCR_racing.carPositions[1] = LCR_racing.carPositions[0]; + + LCR_racing.carRotations[0] = TPE_vec3(0,0,0); + LCR_racing.carRotations[1] = LCR_racing.carRotations[0]; // TODO } @@ -146,6 +167,11 @@ void LCR_racingInit(void) LCR_racingRestart(); } +/** + Gets current car transformation intended for rendering, i.e. potentially with + smoothing and interpolation applied to the underlying internal state in the + physics engine. +*/ void LCR_racingGetCarTransform(LCR_GameUnit position[3], LCR_GameUnit rotation[3], LCR_GameUnit interpolationParam) { @@ -163,17 +189,24 @@ void LCR_racingGetCarTransform(LCR_GameUnit position[3], position[0] = v.x; position[1] = v.y; position[2] = v.z; + + rotation[0] = _LCR_racingSmoothRot(LCR_racing.carRotations[0].x, + LCR_racing.carRotations[1].x); + + rotation[1] = _LCR_racingSmoothRot(LCR_racing.carRotations[0].y, + LCR_racing.carRotations[1].y); + + rotation[2] = _LCR_racingSmoothRot(LCR_racing.carRotations[0].z, + LCR_racing.carRotations[1].z); #else position[0] = LCR_racing.carPositions[0].x; position[1] = LCR_racing.carPositions[0].y; position[2] = LCR_racing.carPositions[0].z; + + rotation[0] = LCR_racing.carRotations[0].x; + rotation[1] = LCR_racing.carRotations[0].y; + rotation[2] = LCR_racing.carRotations[0].z; #endif - - v = TPE_bodyGetRotation(&(LCR_racing.carBody),0,2,1); - - rotation[0] = (v.x * LCR_GAME_UNIT) / TPE_F; - rotation[1] = (v.y * LCR_GAME_UNIT) / TPE_F; - rotation[2] = (v.z * LCR_GAME_UNIT) / TPE_F; } void _LCR_drawPhysicsDebugPixel(uint16_t x, uint16_t y, uint8_t color) @@ -347,7 +380,6 @@ void LCR_racingStep(unsigned int input) TPE_Vec3 tmpVec = LCR_racing.carPositions[0]; - LCR_racing.carPositions[0] = _LCR_TPE_vec3DividePlain( TPE_vec3TimesPlain( @@ -374,6 +406,13 @@ LCR_racing.carPositions[0] = LCR_racing.carPositions[1] = tmpVec; + tmpVec = _LCR_TPE_vec3DividePlain(TPE_vec3TimesPlain( + TPE_bodyGetRotation(&(LCR_racing.carBody),0,2,1), + LCR_GAME_UNIT),TPE_F); + + LCR_racing.carRotations[1] = LCR_racing.carRotations[0]; + LCR_racing.carRotations[0] = tmpVec; + LCR_racing.tick++; } diff --git a/renderer.h b/renderer.h index 5638271..4058084 100644 --- a/renderer.h +++ b/renderer.h @@ -98,34 +98,12 @@ void LCR_rendererSetCarTransform(LCR_GameUnit position[3], LCR_renderer.carModel->transform.translation.z = (position[2] * LCR_RENDERER_UNIT) / LCR_GAME_UNIT; -// TODO: make a separate function that does the smoothing (updateCarTransform) -LCR_renderer.carModel->transform.rotation.x = -_LCR_smoothRotation(LCR_renderer.carModel->transform.rotation.x, - S3L_wrap((rotation[0] * S3L_F) / LCR_GAME_UNIT,S3L_F),3); - - -/* -LCR_renderer.carModel->transform.rotation.y = S3L_wrap((rotation[1] * - S3L_F) / LCR_GAME_UNIT,S3L_F); // don't smooth for faster reaction? -*/ - -LCR_renderer.carModel->transform.rotation.y = -_LCR_smoothRotation(LCR_renderer.carModel->transform.rotation.y, - S3L_wrap((rotation[1] * S3L_F) / LCR_GAME_UNIT,S3L_F),1); - - -LCR_renderer.carModel->transform.rotation.z = -_LCR_smoothRotation(LCR_renderer.carModel->transform.rotation.z, - S3L_wrap((rotation[2] * S3L_F) / LCR_GAME_UNIT,S3L_F),3); - -/* LCR_renderer.carModel->transform.rotation.x = S3L_wrap((rotation[0] * S3L_F) / LCR_GAME_UNIT,S3L_F); LCR_renderer.carModel->transform.rotation.y = S3L_wrap((rotation[1] * S3L_F) / LCR_GAME_UNIT,S3L_F); LCR_renderer.carModel->transform.rotation.z = S3L_wrap((rotation[2] * S3L_F) / LCR_GAME_UNIT,S3L_F); -*/ } void _LCR_pixelFunc3D(S3L_PixelInfo *pixel) @@ -1184,7 +1162,7 @@ void _LCR_rendererLoadMapChunk(uint8_t chunk, int8_t x, int8_t y, int8_t z) /** Serves for smoothing out angle change, e.g. that of camera rotation. */ -S3L_Unit _LCR_smoothRotation(S3L_Unit angleOld, S3L_Unit angleNew, +S3L_Unit _LCR_rendererSmoothRot(S3L_Unit angleOld, S3L_Unit angleNew, unsigned int amount) { /* We have to do the following angle correction -- even if keep angles in @@ -1428,10 +1406,10 @@ void LCR_rendererCameraFollow(void) LCR_renderer.scene.camera.transform.translation.y /= 2; LCR_renderer.scene.camera.transform.translation.z /= 2; - LCR_renderer.scene.camera.transform.rotation.x = _LCR_smoothRotation( + LCR_renderer.scene.camera.transform.rotation.x = _LCR_rendererSmoothRot( transPrev.rotation.x,LCR_renderer.scene.camera.transform.rotation.x,8); - LCR_renderer.scene.camera.transform.rotation.y = _LCR_smoothRotation( + LCR_renderer.scene.camera.transform.rotation.y = _LCR_rendererSmoothRot( transPrev.rotation.y,LCR_renderer.scene.camera.transform.rotation.y,6); #endif }