diff --git a/assets/encodeCarModel.c b/assets/encodeCarModel.c index f67a089..98c762a 100644 --- a/assets/encodeCarModel.c +++ b/assets/encodeCarModel.c @@ -6,7 +6,7 @@ normals or other such things. The following materials must be set for model triangles: "a" for body, "b" - for rear wheels, "c" and "d" for front wheels. + for front wheels, "c" and "d" for back wheels. */ #include diff --git a/racing.h b/racing.h index 87fe6fc..fc6ee74 100644 --- a/racing.h +++ b/racing.h @@ -58,7 +58,6 @@ TPE_Vec3 _LCR_TPE_vec3DividePlain(TPE_Vec3 v, TPE_Unit d) TPE_Vec3 _LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist) { - return TPE_envAABoxInside(point,TPE_vec3(0,0,0),TPE_vec3( LCR_PHYSICS_UNIT * LCR_MAP_SIZE_BLOCKS, (LCR_PHYSICS_UNIT * LCR_MAP_SIZE_BLOCKS) / 2, diff --git a/renderer.h b/renderer.h index 9b6e876..092deaa 100644 --- a/renderer.h +++ b/renderer.h @@ -1163,6 +1163,30 @@ 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 angleDiff = angleNew - angleOld; + + if (angleDiff == 0) + return angleNew; + + S3L_Unit angleDiffAbs = S3L_abs(angleDiff); + + if (angleDiffAbs > S3L_F / 2) // consider e.g. 350 degrees minus 1 degree + { + angleDiffAbs -= S3L_F / 2; + angleDiff += (angleDiff > 0) ? -1 * (S3L_F / 2) : (S3L_F / 2); + } + + if (angleDiffAbs > S3L_F / 4) // angle too big, rotate immediately + return angleNew; + + return angleOld + angleDiff / 4; // smoothly interpolate +} + /** Loads the map models with 8 chunks that are nearest to a certain point towards which camera is looking. @@ -1337,36 +1361,45 @@ void LCR_rendererCameraFollow(void) (LCR_SETTING_CAMERA_HEIGHT + LCR_SETTING_CAMERA_HEIGHT_BAND) * LCR_RENDERER_UNIT / 8); - LCR_renderer.scene.camera.transform.translation.x = - S3L_clamp( - LCR_renderer.scene.camera.transform.translation.x, - LCR_renderer.carModel->transform.translation.x - - LCR_SETTING_CAMERA_MAX_DISTANCE * LCR_RENDERER_UNIT / 4, - LCR_renderer.carModel->transform.translation.x + - LCR_SETTING_CAMERA_MAX_DISTANCE * LCR_RENDERER_UNIT / 4); + S3L_Vec4 toCam = + LCR_renderer.scene.camera.transform.translation; - LCR_renderer.scene.camera.transform.translation.z = - S3L_clamp( - LCR_renderer.scene.camera.transform.translation.z, - LCR_renderer.carModel->transform.translation.z - - LCR_SETTING_CAMERA_MAX_DISTANCE * LCR_RENDERER_UNIT / 4, - LCR_renderer.carModel->transform.translation.z + - LCR_SETTING_CAMERA_MAX_DISTANCE * LCR_RENDERER_UNIT / 4); + S3L_vec3Sub(&toCam, + LCR_renderer.carModel->transform.translation); - /* Hotfix for a Gimbal lock kinda issue, don't do lookAt when completely - above the car, rather shift the camera a bit (needs some tuning). */ - if (S3L_abs(LCR_renderer.scene.camera.transform.translation.x - - LCR_renderer.carModel->transform.translation.x) > 8 && - S3L_abs(LCR_renderer.scene.camera.transform.translation.z - - LCR_renderer.carModel->transform.translation.z) > 8) - S3L_lookAt(LCR_renderer.carModel->transform.translation, - &(LCR_renderer.scene.camera.transform)); - else + S3L_Unit horizontalDist = + S3L_sqrt(toCam.x * toCam.x + toCam.z * toCam.z); + + if (horizontalDist == 0) { - LCR_renderer.scene.camera.transform.translation.x += 4; - LCR_renderer.scene.camera.transform.translation.z -= 8; + toCam.z = 1; + horizontalDist = 1; } + S3L_Unit horizontalDistNew = + S3L_clamp(horizontalDist, + (LCR_SETTING_CAMERA_DISTANCE - LCR_SETTING_CAMERA_DISTANCE_BAND) + * (LCR_RENDERER_UNIT / 4), + (LCR_SETTING_CAMERA_DISTANCE + LCR_SETTING_CAMERA_DISTANCE_BAND) + * (LCR_RENDERER_UNIT / 4)); + + if (horizontalDistNew != horizontalDist) + { + toCam.x = (toCam.x * horizontalDistNew) / horizontalDist; + toCam.z = (toCam.z * horizontalDistNew) / horizontalDist; + + LCR_renderer.scene.camera.transform.translation.x = + LCR_renderer.carModel->transform.translation.x + + (toCam.x * horizontalDistNew) / horizontalDist; + + LCR_renderer.scene.camera.transform.translation.z = + LCR_renderer.carModel->transform.translation.z + + (toCam.z * horizontalDistNew) / horizontalDist; + } + + S3L_lookAt(LCR_renderer.carModel->transform.translation, + &(LCR_renderer.scene.camera.transform)); + #if LCR_SETTING_SMOOTH_ANIMATIONS // now average with previous transform to smooth the animation out: S3L_vec3Add(&(LCR_renderer.scene.camera.transform.translation), @@ -1376,13 +1409,11 @@ void LCR_rendererCameraFollow(void) LCR_renderer.scene.camera.transform.translation.y /= 2; LCR_renderer.scene.camera.transform.translation.z /= 2; - transPrev.rotation.x -= LCR_renderer.scene.camera.transform.rotation.x; - transPrev.rotation.y -= LCR_renderer.scene.camera.transform.rotation.y; + LCR_renderer.scene.camera.transform.rotation.x = _LCR_smoothRotation( + transPrev.rotation.x,LCR_renderer.scene.camera.transform.rotation.x); - if (S3L_abs(transPrev.rotation.y) < S3L_F / 5) - LCR_renderer.scene.camera.transform.rotation.y += transPrev.rotation.y / 2; - - LCR_renderer.scene.camera.transform.rotation.x += transPrev.rotation.x / 2; + LCR_renderer.scene.camera.transform.rotation.y = _LCR_smoothRotation( + transPrev.rotation.y,LCR_renderer.scene.camera.transform.rotation.y); #endif } diff --git a/settings.h b/settings.h index d6c2ac2..53aa28a 100644 --- a/settings.h +++ b/settings.h @@ -102,7 +102,7 @@ #ifndef LCR_SETTING_CAMERA_HEIGHT /** Base height of the car follow camera, in 4ths of map block height. */ - #define LCR_SETTING_CAMERA_HEIGHT 7 + #define LCR_SETTING_CAMERA_HEIGHT 5 #endif #ifndef LCR_SETTING_CAMERA_HEIGHT_BAND @@ -110,10 +110,15 @@ #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 +#ifndef LCR_SETTING_CAMERA_DISTANCE + /** Base horizontal distance of the car follow camera, in 4ths of map block width. */ - #define LCR_SETTING_CAMERA_MAX_DISTANCE 5 + #define LCR_SETTING_CAMERA_DISTANCE 4 +#endif + +#ifndef LCR_SETTING_CAMERA_DISTANCE_BAND + /** Band for distance of the car follow camera, in same units as base dist. */ + #define LCR_SETTING_CAMERA_DISTANCE_BAND 3 #endif #ifndef LCR_SETTING_GHOST_COLOR