Decimal zoom with lerp

This commit is contained in:
Kae 2023-06-29 07:05:01 +10:00
parent 0b479ae1b9
commit 1e213aac5f
9 changed files with 77 additions and 18 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
build/ build/
dist/ dist/
enc_temp_folder/
.cache/ .cache/
attic/ attic/
tiled/ tiled/

View File

@ -1 +1,44 @@
{ "zoomList" : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 ] } {
"paneLayout": { "panefeature": { "positionLocked": false } },
"zoomList": [
1,
1.125,
1.25,
1.375,
1.5,
1.675,
1.75,
1.875,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32
]
}

View File

@ -866,11 +866,13 @@ void ClientApplication::updateCamera() {
if (!m_universeClient->worldClient()) if (!m_universeClient->worldClient())
return; return;
WorldCamera& camera = m_worldPainter->camera();
camera.update(WorldTimestep);
if (m_mainInterface->fixedCamera()) if (m_mainInterface->fixedCamera())
return; return;
auto assets = m_root->assets(); auto assets = m_root->assets();
auto camera = m_worldPainter->camera();
const float triggerRadius = 100.0f; const float triggerRadius = 100.0f;
const float deadzone = 0.1f; const float deadzone = 0.1f;
@ -934,7 +936,6 @@ void ClientApplication::updateCamera() {
m_worldPainter->setCameraPosition(m_universeClient->worldClient()->geometry(), baseCamera + (smoothDelta + m_cameraSmoothDelta) * 0.5f); m_worldPainter->setCameraPosition(m_universeClient->worldClient()->geometry(), baseCamera + (smoothDelta + m_cameraSmoothDelta) * 0.5f);
m_cameraSmoothDelta = smoothDelta; m_cameraSmoothDelta = smoothDelta;
camera = m_worldPainter->camera();
m_universeClient->worldClient()->setClientWindow(camera.worldTileRect()); m_universeClient->worldClient()->setClientWindow(camera.worldTileRect());
} }

View File

@ -73,7 +73,7 @@ void ChatBubbleManager::setCamera(WorldCamera const& camera) {
actions.append(SayChatAction{bubble.entity, bubble.text, state.idealDestination, bubble.config}); actions.append(SayChatAction{bubble.entity, bubble.text, state.idealDestination, bubble.config});
}); });
m_bubbles.clear(); m_bubbles.clear();
for (auto portraitBubble : m_portraitBubbles) for (auto& portraitBubble : m_portraitBubbles)
actions.append(PortraitChatAction{ actions.append(PortraitChatAction{
portraitBubble.entity, portraitBubble.entity,
portraitBubble.portrait, portraitBubble.portrait,

View File

@ -159,7 +159,7 @@ void GraphicsMenu::syncGui() {
} else { } else {
zoomSlider->setVal(m_zoomList.size() - 1); zoomSlider->setVal(m_zoomList.size() - 1);
} }
fetchChild<LabelWidget>("zoomValueLabel")->setText(strf("{}x", m_localChanges.get("zoomLevel").toInt())); fetchChild<LabelWidget>("zoomValueLabel")->setText(strf("{}x", m_localChanges.get("zoomLevel").toFloat()));
fetchChild<ButtonWidget>("speechBubbleCheckbox")->setChecked(m_localChanges.get("speechBubbles").toBool()); fetchChild<ButtonWidget>("speechBubbleCheckbox")->setChecked(m_localChanges.get("speechBubbles").toBool());

View File

@ -530,6 +530,7 @@ RectF TextPainter::doRenderLine(StringView text, TextPositioning const& position
return true; return true;
}; };
m_fontTextureGroup.switchFont(m_renderSettings.font);
Text::processText(text, textCallback, commandsCallback); Text::processText(text, textCallback, commandsCallback);
return bounds; return bounds;
@ -538,7 +539,7 @@ RectF TextPainter::doRenderLine(StringView text, TextPositioning const& position
RectF TextPainter::doRenderGlyph(String::Char c, TextPositioning const& position, bool reallyRender) { RectF TextPainter::doRenderGlyph(String::Char c, TextPositioning const& position, bool reallyRender) {
if (m_nonRenderedCharacters.find(String(c)) != NPos) if (m_nonRenderedCharacters.find(String(c)) != NPos)
return RectF(); return RectF();
m_fontTextureGroup.switchFont(m_renderSettings.font);
int width = glyphWidth(c); int width = glyphWidth(c);
// Offset left by width if right anchored. // Offset left by width if right anchored.
float hOffset = 0; float hOffset = 0;

View File

@ -3,6 +3,7 @@
#include "StarWorldGeometry.hpp" #include "StarWorldGeometry.hpp"
#include "StarGameTypes.hpp" #include "StarGameTypes.hpp"
#include "StarInterpolation.hpp"
namespace Star { namespace Star {
@ -11,8 +12,9 @@ public:
void setScreenSize(Vec2U screenSize); void setScreenSize(Vec2U screenSize);
Vec2U screenSize() const; Vec2U screenSize() const;
void setPixelRatio(unsigned pixelRatio); void setTargetPixelRatio(float targetPixelRatio);
unsigned pixelRatio() const; void setPixelRatio(float pixelRatio);
float pixelRatio() const;
void setWorldGeometry(WorldGeometry geometry); void setWorldGeometry(WorldGeometry geometry);
WorldGeometry worldGeometry() const; WorldGeometry worldGeometry() const;
@ -42,10 +44,13 @@ public:
// worldTileRect, in screen coordinates. // worldTileRect, in screen coordinates.
Vec2F tileMinScreen() const; Vec2F tileMinScreen() const;
void update(float dt);
private: private:
WorldGeometry m_worldGeometry; WorldGeometry m_worldGeometry;
Vec2U m_screenSize; Vec2U m_screenSize;
unsigned m_pixelRatio = 1; float m_pixelRatio = 1.0f;
float m_targetPixelRatio = 1.0f;
Vec2F m_worldCenter; Vec2F m_worldCenter;
}; };
@ -57,11 +62,15 @@ inline Vec2U WorldCamera::screenSize() const {
return m_screenSize; return m_screenSize;
} }
inline void WorldCamera::setPixelRatio(unsigned pixelRatio) { inline void WorldCamera::setTargetPixelRatio(float targetPixelRatio) {
m_pixelRatio = pixelRatio; m_targetPixelRatio = targetPixelRatio;
} }
inline unsigned WorldCamera::pixelRatio() const { inline void WorldCamera::setPixelRatio(float pixelRatio) {
m_pixelRatio = m_targetPixelRatio = pixelRatio;
}
inline float WorldCamera::pixelRatio() const {
return m_pixelRatio; return m_pixelRatio;
} }
@ -112,6 +121,10 @@ inline Vec2F WorldCamera::tileMinScreen() const {
return (Vec2F(tileRect.min()) - screenRect.min()) * (TilePixels * m_pixelRatio); return (Vec2F(tileRect.min()) - screenRect.min()) * (TilePixels * m_pixelRatio);
} }
inline void WorldCamera::update(float dt) {
m_pixelRatio = lerp(exp(-20.0f * dt), m_targetPixelRatio, m_pixelRatio);
}
} }
#endif #endif

View File

@ -41,13 +41,13 @@ void WorldPainter::setCameraPosition(WorldGeometry const& geometry, Vec2F const&
m_camera.setCenterWorldPosition(position); m_camera.setCenterWorldPosition(position);
} }
WorldCamera const& WorldPainter::camera() const { WorldCamera& WorldPainter::camera() {
return m_camera; return m_camera;
} }
void WorldPainter::render(WorldRenderData& renderData) { void WorldPainter::render(WorldRenderData& renderData) {
m_camera.setScreenSize(m_renderer->screenSize()); m_camera.setScreenSize(m_renderer->screenSize());
m_camera.setPixelRatio(Root::singleton().configuration()->get("zoomLevel").toFloat()); m_camera.setTargetPixelRatio(Root::singleton().configuration()->get("zoomLevel").toFloat());
m_assets = Root::singleton().assets(); m_assets = Root::singleton().assets();
@ -159,10 +159,10 @@ void WorldPainter::renderParticles(WorldRenderData& renderData, Particle::Layer
if (!particleRenderWindow.contains(position)) if (!particleRenderWindow.contains(position))
continue; continue;
Vec2I size = Vec2I::filled(particle.size * m_camera.pixelRatio()); Vec2F size = Vec2F::filled(particle.size * m_camera.pixelRatio());
if (particle.type == Particle::Type::Ember) { if (particle.type == Particle::Type::Ember) {
m_renderer->render(renderFlatRect(RectF(position - Vec2F(size) / 2, position + Vec2F(size) / 2), particle.color.toRgba(), particle.fullbright ? 0.0f : 1.0f)); m_renderer->render(renderFlatRect(RectF(position - size / 2, position + size / 2), particle.color.toRgba(), particle.fullbright ? 0.0f : 1.0f));
} else if (particle.type == Particle::Type::Streak) { } else if (particle.type == Particle::Type::Streak) {
// Draw a rotated quad streaking in the direction the particle is coming from. // Draw a rotated quad streaking in the direction the particle is coming from.
@ -199,7 +199,7 @@ void WorldPainter::renderParticles(WorldRenderData& renderData, Particle::Layer
} else if (particle.type == Particle::Type::Text) { } else if (particle.type == Particle::Type::Text) {
Vec2F position = m_camera.worldToScreen(particle.position); Vec2F position = m_camera.worldToScreen(particle.position);
unsigned size = textParticleFontSize * m_camera.pixelRatio() * particle.size; unsigned size = round((float)textParticleFontSize * m_camera.pixelRatio() * particle.size);
if (size > 0) { if (size > 0) {
m_textPainter->setFontSize(size); m_textPainter->setFontSize(size);
m_textPainter->setFontColor(particle.color.toRgba()); m_textPainter->setFontColor(particle.color.toRgba());

View File

@ -21,7 +21,7 @@ public:
void setCameraPosition(WorldGeometry const& worldGeometry, Vec2F const& position); void setCameraPosition(WorldGeometry const& worldGeometry, Vec2F const& position);
WorldCamera const& camera() const; WorldCamera& camera();
void render(WorldRenderData& renderData); void render(WorldRenderData& renderData);