diff --git a/Minecraft.Client/GameRenderer.cpp b/Minecraft.Client/GameRenderer.cpp index 73b39529c..30ef91662 100644 --- a/Minecraft.Client/GameRenderer.cpp +++ b/Minecraft.Client/GameRenderer.cpp @@ -409,6 +409,28 @@ float GameRenderer::getFov(float a, bool applyEffects) } +float GameRenderer::getViewmodelFov(float a) +{ + // The first-person hand/item should not scale with the user's world FOV (Java-like viewmodel feel). + if (cameraFlip > 0) return 90; + + shared_ptr player = dynamic_pointer_cast(mc->cameraTargetPlayer); + if (!player) return 70.0f; + + float fov = 70.0f; + + if (player->getHealth() <= 0) + { + float duration = player->deathTime + a; + fov /= ((1 - 500 / (duration + 500)) * 2.0f + 1); + } + + int t = Camera::getBlockAt(mc->level, player, a); + if (t != 0 && Tile::tiles[t]->material == Material::water) fov = fov * 60 / 70; + + return fov + fovOffsetO + (fovOffset - fovOffsetO) * a; +} + void GameRenderer::bobHurt(float a) { shared_ptr player = mc->cameraTargetPlayer; @@ -591,6 +613,24 @@ void GameRenderer::unZoomRegion() zoom = 1; } +void GameRenderer::applyViewportFovAndAspectAdjustments(float& fov, float& aspect) const +{ + if (!mc || !mc->player) return; + + if ((mc->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_SPLIT_TOP) || + (mc->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM)) + { + aspect *= 2.0f; + fov *= 0.7f; // Reduce FOV to make things less fish-eye, at the expense of reducing vertical FOV from single player mode + } + else if ((mc->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_SPLIT_LEFT) || + (mc->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT)) + { + // Ideally I'd like to make the fov bigger here, but if I do then you can see that the arm isn't very long... + aspect *= 0.5f; + } +} + // 4J added as we have more complex adjustments to make for fov & aspect on account of viewports void GameRenderer::getFovAndAspect(float& fov, float& aspect, float a, bool applyEffects) { @@ -600,18 +640,18 @@ void GameRenderer::getFovAndAspect(float& fov, float& aspect, float a, bool appl aspect = g_rScreenWidth / static_cast(g_rScreenHeight); fov = getFov(a, applyEffects); - if( ( mc->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_SPLIT_TOP ) || - ( mc->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM ) ) - { - aspect *= 2.0f; - fov *= 0.7f; // Reduce FOV to make things less fish-eye, at the expense of reducing vertical FOV from single player mode - } - else if( ( mc->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_SPLIT_LEFT ) || - ( mc->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT) ) - { - // Ideally I'd like to make the fov bigger here, but if I do then you an see that the arm isn't very long... - aspect *= 0.5f; - } + applyViewportFovAndAspectAdjustments(fov, aspect); +} + +void GameRenderer::getViewmodelFovAndAspect(float& fov, float& aspect, float a) +{ + // Use the real window dimensions so the perspective updates on resize. + extern int g_rScreenWidth; + extern int g_rScreenHeight; + aspect = g_rScreenWidth / static_cast(g_rScreenHeight); + fov = getViewmodelFov(a); + + applyViewportFovAndAspectAdjustments(fov, aspect); } void GameRenderer::setupCamera(float a, int eye) @@ -716,7 +756,7 @@ void GameRenderer::renderItemInHand(float a, int eye) // 4J - have split out fov & aspect calculation so we can take into account viewports float fov, aspect; - getFovAndAspect(fov, aspect, a, false); + getViewmodelFovAndAspect(fov, aspect, a); if (zoom != 1) { diff --git a/Minecraft.Client/GameRenderer.h b/Minecraft.Client/GameRenderer.h index c379106e0..da41d1452 100644 --- a/Minecraft.Client/GameRenderer.h +++ b/Minecraft.Client/GameRenderer.h @@ -102,6 +102,7 @@ public: private: void tickFov(); float getFov(float a, bool applyEffects); + float getViewmodelFov(float a); void bobHurt(float a); void bobView(float a); void moveCameraToPlayer(float a); @@ -112,7 +113,9 @@ public: void zoomRegion(double zoom, double xa, double ya); void unZoomRegion(); private: + void applyViewportFovAndAspectAdjustments(float& fov, float& aspect) const; void getFovAndAspect(float& fov, float& aspect, float a, bool applyEffects); // 4J added + void getViewmodelFovAndAspect(float& fov, float& aspect, float a); // 4J added public: void setupCamera(float a, int eye); private: