From 9b31556979a8731850b3b638d962525fd9e0b405 Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Thu, 23 Jan 2025 11:34:05 +0100 Subject: [PATCH] Add car/ghost render dist --- TODO.txt | 9 +++++++-- game.h | 14 +++++--------- renderer.h | 32 +++++++++++++++++++++++++++++--- settings.h | 5 +++++ 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/TODO.txt b/TODO.txt index cbbd781..e537e5f 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,6 +1,7 @@ =========== GENERAL ============== -- ghost visible distance +- force chunk reload upon map restart so that there's no blinking at start +- make a small txt game menual - test if the replay stretching works - replay validation - ghosts: if the replay for the ghost is too long (too many samples for the @@ -24,16 +25,20 @@ =========== BUGS ================= -- why does the ghost stop in front of the finish? +- starting test replay two twice in a row breaks it - drawing dithered transparent objects fills z-buffer in the transparent parts and then the geometry behind it isn't drawn <- PARTIALLY FIXED NOW =========== HANDLED ============== - allow stopping car rotation in air like in Trackmania +- ghost visible distance -- maybe even car should have this (watching rep with + free camera)? maybe generalize setCar/GhostVisibility to + setCarGhostVisibilityDistance where 0 means make invisible? - add time slow down setting - the horizon on background seems too low? maybe add setting to shift it a bit? - replay format +- why does the ghost stop in front of the finish? - prevent time overflow! stop incrementing level frame once it's at maximum - car shadow? probably would have to be done as screen space effect with z-buffer (shadow as 3D model would require collision detection and would make diff --git a/game.h b/game.h index e764853..71c3bcb 100644 --- a/game.h +++ b/game.h @@ -390,7 +390,7 @@ void LCR_gameGetNthGhostSample(unsigned int n, void LCR_gameGhostGetTransform(uint32_t frame, LCR_GameUnit position[3], LCR_GameUnit rotation[3]) { - unsigned int n = ((frame >> LCR_game.ghost.stretch) / LCR_SETTING_GHOST_STEP); + int n = ((frame >> LCR_game.ghost.stretch) / LCR_SETTING_GHOST_STEP); LCR_gameGetNthGhostSample(n,position,rotation); @@ -423,14 +423,10 @@ void LCR_gameGhostGetTransform(uint32_t frame, } } - /* Small hack: at the beginning the ghost can be seen misaligned with the - real car due to its quantized position, here we gradually snap it to the - nearest 1/8th of a block (which should hit the start position) during the - first 16 frames. */ - if (LCR_racing.tick < 16) - for (int i = 0; i < 3; ++i) - position[i] = position[i] + (LCR_racing.tick * (position[i] - - ((position[i] + LCR_GAME_UNIT / 8) / (LCR_GAME_UNIT / 4)))) / 16; + // offset (correct rounding down): + position[0] += LCR_GAME_UNIT / 16; + position[1] += LCR_GAME_UNIT / 16; + position[2] += LCR_GAME_UNIT / 16; } void _LCR_gamePrepareGhost(void) diff --git a/renderer.h b/renderer.h index 6d5c7bb..79b9cb8 100644 --- a/renderer.h +++ b/renderer.h @@ -79,6 +79,9 @@ struct uint32_t frame; + uint8_t carVisibilityDist; + uint8_t ghostVisibilityDist; + uint8_t loadedChunks[8]; ///< numbers of loaded map chunks S3L_Unit mapVerts[LCR_SETTING_MAX_MAP_VERTICES * 3]; @@ -1930,6 +1933,26 @@ void LCR_rendererDraw3D(void) LCR_rendererDrawLOD(); + uint8_t carGhostVisibility = 0; + S3L_Model3D *m = LCR_renderer.carModel; + + for (uint8_t i = 0; i < 2; ++i) + { + carGhostVisibility <<= 1; + + if (LCR_renderer.carModel->config.visible) + { + carGhostVisibility |= 1; + + m->config.visible = (S3L_distanceManhattan( + m->transform.translation, + LCR_renderer.scene.camera.transform.translation) / LCR_RENDERER_UNIT) + <= LCR_SETTING_CAR_RENDER_DISTANCE; + } + + m = LCR_renderer.ghostModel; + } + LCR_LOG2("3D rendering (start)"); #if LCR_SETTING_POTATO_GRAPHICS @@ -1944,8 +1967,8 @@ void LCR_rendererDraw3D(void) for (int i = 0; i < LCR_renderer.scene.modelCount; ++i) LCR_renderer.scene.models[i].config.visible = 0; - LCR_renderer.carModel->config.visible = 1; - LCR_renderer.ghostModel->config.visible = 1; + LCR_renderer.carModel->config.visible = carGhostVisibility >> 1; + LCR_renderer.ghostModel->config.visible = carGhostVisibility & 0x01; S3L_newFrame(); S3L_drawScene(LCR_renderer.scene); @@ -1954,8 +1977,11 @@ void LCR_rendererDraw3D(void) LCR_renderer.scene.models[i].config.visible = 1; #else S3L_drawScene(LCR_renderer.scene); + + LCR_renderer.carModel->config.visible = carGhostVisibility >> 1; + LCR_renderer.ghostModel->config.visible = carGhostVisibility & 0x01; #endif - + LCR_renderer.frame++; LCR_LOG2("3D rendering (end)"); diff --git a/settings.h b/settings.h index aefb036..9e1bbb5 100644 --- a/settings.h +++ b/settings.h @@ -220,4 +220,9 @@ #define LCR_SETTING_GHOST_MAX_SAMPLES 128 #endif +#ifndef LCR_SETTING_CAR_RENDER_DISTANCE + /** Distance in blocks at which player and ghost car will be seen. */ + #define LCR_SETTING_CAR_RENDER_DISTANCE 25 +#endif + #endif // guard