1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-07-03 06:24:32 +00:00

Improve camera zooming behavior + camera related cleanups

- Now, the camera will now no longer be pulled towards the upper left
  or lower rigtht corner.
- cameraPos was never used as an interpolating vector, cleaned up related code.
- Core::invGlobalScale is now updated whenever Core::globalScale is changed
  (Not a nice solution but it does work)
- Increase cull radius by 10%, should prevent tiles from disappearing when
  zoomed in a lot.
This commit is contained in:
fgenesis 2014-03-07 17:59:36 +01:00
parent b501ba67e3
commit 2cec85fd05
11 changed files with 50 additions and 119 deletions

View file

@ -593,6 +593,7 @@ void AnimationEditor::zoomOut()
if (dsq->isNested()) return;
core->globalScale -= Vector(ANIM_EDIT_ZOOM, ANIM_EDIT_ZOOM);
core->globalScaleChanged();
}
void AnimationEditor::zoomIn()
@ -600,6 +601,7 @@ void AnimationEditor::zoomIn()
if (dsq->isNested()) return;
core->globalScale += Vector(ANIM_EDIT_ZOOM, ANIM_EDIT_ZOOM);
core->globalScaleChanged();
}
void AnimationEditor::reorderKeys()

View file

@ -2508,6 +2508,7 @@ void Avatar::formAbility(int ability)
dsq->shakeCamera(25, 2);
core->globalScale = Vector(0.4, 0.4);
core->globalScaleChanged();
myZoom = Vector(0.4, 0.4);
/*
@ -4214,20 +4215,6 @@ void Avatar::destroy()
avatar = 0;
}
void Avatar::toggleZoom()
{
if (core->globalScale.isInterpolating()) return;
if (core->globalScale.x == 1)
core->globalScale.interpolateTo(Vector(0.75,0.75),0.2);
else if (core->globalScale.x == 0.75)
core->globalScale.interpolateTo(Vector(0.5,0.5),0.2);
else if (core->globalScale.x == 0.5)
core->globalScale.interpolateTo(Vector(0.25,0.25),0.2);
else if (core->globalScale.x == 0.25)
core->globalScale.interpolateTo(Vector(1,1),0.2);
}
void Avatar::startBackFlip()
{
if (boneLock.on) return;
@ -6887,6 +6874,7 @@ void Avatar::onUpdate(float dt)
core->globalScale.x = myZoom.x;
core->globalScale.y = myZoom.y;
}
core->globalScaleChanged();
}

View file

@ -442,7 +442,6 @@ protected:
int getBeamWidth();
Vector getWallNormal(TileVector t);
bool checkWarpAreas();
void toggleZoom();
float splashDelay;
//Hair *hair;

View file

@ -357,28 +357,6 @@ ElementEffect DSQ::getElementEffectByIndex(int e)
return empty;
}
/*
Element *DSQ::getSolidElementNear(Vector pos, int rad)
{
Element *closestE = 0;
int closestDist = -1;
for (int i = 0; i < elements.size(); i++)
{
Element *e = elements[i];
int dist = (e->position - pos).getSquaredLength2D();
if (e->isElementActive() && e->elementFlag == EF_SOLID && dist < sqr(rad) && (dist < closestDist || closestDist==-1))
{
closestDist = dist;
closestE = e;
}
}
return closestE;
}
*/
Vector DSQ::getCameraCenter()
{
return cameraPos; //+ Vector(400*(1.0f/core->globalScale.x),300*(1.0f/core->globalScale.x));
}
void DSQ::centerMessage(const std::string &text, float y, int type)
{
@ -703,7 +681,7 @@ void DSQ::debugMenu()
Entity *e = dsq->getEntityByNameNoCase(entityName);
if (e)
{
dsq->cameraPos = e->position;
dsq->cameraPos = game->getCameraPositionFor(e->position);
}
}
else if (c == 'C')

View file

@ -1360,7 +1360,6 @@ public:
std::string getEntityFlagName(Entity *e);
std::string getUserInputString(std::string label, std::string t="", bool allowNonLowerCase=false);
Vector getUserInputDirection(std::string label);
Vector getCameraCenter();
bool onPickedSaveSlot(AquariaSaveSlot *slot);
void doSaveSlotMenu(SaveSlotMode ssm, const Vector &position = Vector(0,0,0));
void doModSelect();
@ -1377,7 +1376,6 @@ public:
std::string getDialogueFilename(const std::string &f);
bool isShakingCamera();
//Element *getSolidElementNear(Vector pos, int rad);
std::string languagePack;

View file

@ -6670,13 +6670,13 @@ void Game::applyState()
core->cacheRender();
core->cameraPos.stop();
cameraInterp.stop();
core->globalScale = dsq->continuity.zoom;
//core->globalScaleChanged();
avatar->myZoom = dsq->continuity.zoom;
cameraInterp = getCameraPositionFor(avatar->position);
cameraInterp = avatar->position;
core->cameraPos = getCameraPositionFor(avatar->position);
core->sort();
@ -7450,7 +7450,9 @@ void Game::overrideZoom(float sz, float t)
else
{
dsq->game->toggleOverrideZoom(true);
dsq->globalScale.stop();
dsq->globalScale.interpolateTo(Vector(sz, sz), t);
dsq->globalScaleChanged();
}
}
@ -8535,13 +8537,7 @@ void Game::toggleGridRender()
Vector Game::getCameraPositionFor(const Vector &pos)
{
Vector dest = pos;
Vector v;
dest += v + Vector(-400/core->globalScale.x,-300/core->globalScale.y);
dest.z = 0;
return dest;
return Vector(pos.x - 400 * core->invGlobalScale, pos.y - 300 * core->invGlobalScale, 0);
}
void Game::setParallaxTextureCoordinates(Quad *q, float speed)
@ -10296,10 +10292,10 @@ void Game::update(float dt)
{
if (!isPaused())
waterLevel.update(dt);
cameraInterp.update(dt);
if (cameraFollow)
{
Vector dest = getCameraPositionFor(*cameraFollow);
Vector dest = *cameraFollow;
if (avatar)
{
@ -10313,43 +10309,21 @@ void Game::update(float dt)
}
}
/*
if (avatar)
{
if (!dsq->game->isPaused() && core->mouse.buttons.middle && !dsq->game->avatar->isSinging() && dsq->game->avatar->isInputEnabled())
{
Vector diff = avatar->getAim();//dsq->getGameCursorPosition() - avatar->position;
diff.capLength2D(600);
avatar->looking = 1;
dest += diff;
}
else
{
avatar->looking = 0;
}
}
*/
if (cameraLerpDelay==0)
{
//cameraLerpDelay = 0.15;
cameraLerpDelay = vars->defaultCameraLerpDelay;
}
Vector oldCamPos = dsq->cameraPos;
cameraInterp.stop();
cameraInterp.interpolateTo(dest, cameraLerpDelay);
dsq->cameraPos.x = cameraInterp.x;
dsq->cameraPos.y = cameraInterp.y;
// constrainCamera
dsq->cameraPos = getCameraPositionFor(cameraInterp);
constrainCamera();
/*
if (cam_region)
ConstrainToRegion(&ek->cameraPos, cam_region, core->getVirtualWidth()*(core->globalScale.x), core->getVirtualHeight()*(core->globalScale.y));
*/
float dd = (dsq->cameraPos - oldCamPos).getLength2D();
}
cameraInterp.update(dt);
}
}
@ -10484,20 +10458,14 @@ void Game::warpCameraTo(RenderObject *r)
void Game::warpCameraTo(Vector position)
{
cameraInterp.stop();
cameraInterp = getCameraPositionFor(position);
dsq->cameraPos.x = cameraInterp.x;
dsq->cameraPos.y = cameraInterp.y;
cameraInterp = position;
dsq->cameraPos = getCameraPositionFor(position);
}
void Game::snapCam()
{
if (cameraFollow)
{
Vector p = getCameraPositionFor(*cameraFollow);
cameraInterp.interpolateTo(p,0);
cameraInterp = p;
core->cameraPos = p;
}
warpCameraTo(*cameraFollow);
}
ElementTemplate Game::getElementTemplateForLetter(int i)
@ -10758,6 +10726,7 @@ void Game::removeState()
dsq->game->avatar->myZoom = Vector(1,1);
dsq->globalScale = Vector(1,1);
core->globalScaleChanged();
for (int i = 0; i < getNumPaths(); i++)
{

View file

@ -2960,6 +2960,7 @@ void SceneEditor::toggle(bool on)
core->cameraPos.x += cameraOffset * core->getVirtualWidth()/2;
core->cameraPos.y += cameraOffset * core->getVirtualHeight()/2;
core->globalScale = zoom;
core->globalScaleChanged();
}
else
{
@ -3230,6 +3231,7 @@ void SceneEditor::update(float dt)
if (zoom.x < 0.04f)
zoom.x = zoom.y = 0.04f;
core->globalScale = zoom;
core->globalScaleChanged();
if (zoom.x != oldZoom.x)
{
const float mouseX = core->mouse.position.x;

View file

@ -4025,12 +4025,12 @@ luaFunc(cam_setPosition)
bool pingPong = getBool(L, 5);
bool ease = getBool(L, 6);
Vector p = dsq->game->getCameraPositionFor(Vector(x,y));
Vector p(x,y);
dsq->game->cameraInterp.stop();
dsq->game->cameraInterp.interpolateTo(p, time, loopType, pingPong, ease);
dsq->cameraPos = p;
dsq->cameraPos = dsq->game->getCameraPositionFor(dsq->game->cameraInterp);
luaReturnNil();
}

View file

@ -249,7 +249,7 @@ void GameOver::applyState()
//core->sound->fadeOut(transTime);
StateObject::applyState();
core->globalScale = Vector(1,1);
core->cameraPos.stop();
core->globalScaleChanged();
core->cameraPos = Vector(0,0,0);
core->sound->playSfx("Death");

View file

@ -1319,12 +1319,12 @@ bool Core::initSoundLibrary(const std::string &defaultDevice)
Vector Core::getGameCursorPosition()
{
return core->cameraPos + mouse.position * Vector(1/core->globalScale.x, 1/core->globalScale.y, 1);
return getGamePosition(mouse.position);
}
Vector Core::getGamePosition(const Vector &v)
{
return core->cameraPos + (v * Vector(1/core->globalScale.x, 1/core->globalScale.y, 1));
return cameraPos + (v * invGlobalScale);
}
bool Core::getMouseButtonState(int m)
@ -1795,8 +1795,8 @@ void Core::onUpdate(float dt)
//script.update(dt);
cameraPos.update(dt);
globalScale.update(dt);
core->globalScaleChanged();
if (afterEffectManager)
{
@ -1817,6 +1817,12 @@ void Core::onUpdate(float dt)
}
}
void Core::globalScaleChanged()
{
invGlobalScale = 1.0f/globalScale.x;
invGlobalScaleSqr = invGlobalScale * invGlobalScale;
}
Vector Core::getClearColor()
{
return clearColor;
@ -2412,7 +2418,7 @@ void Core::setPixelScale(int pixelScaleX, int pixelScaleY)
virtualWidth = pixelScaleX;
//MAX(virtualWidth, 800);
virtualHeight = pixelScaleY;//int((pixelScale*aspectY)/aspectX); //assumes 4:3 aspect ratio
this->baseCullRadius = sqrtf(sqr(getVirtualWidth()/2) + sqr(getVirtualHeight()/2));
this->baseCullRadius = 1.1f * sqrtf(sqr(getVirtualWidth()/2) + sqr(getVirtualHeight()/2));
std::ostringstream os;
os << "virtual(" << virtualWidth << ", " << virtualHeight << ")";
@ -3290,7 +3296,7 @@ void Core::setMouseConstraint(bool on)
mouseConstraint = on;
}
void Core::setMouseConstraintCircle(int circle)
void Core::setMouseConstraintCircle(float circle)
{
mouseConstraint = true;
mouseCircle = circle;
@ -4051,20 +4057,9 @@ void Core::cacheRender()
void Core::updateCullData()
{
// update cull data
//this->cullRadius = int((getVirtualWidth())*invGlobalScale);
this->cullRadius = baseCullRadius * invGlobalScale;
this->cullRadiusSqr = (float)this->cullRadius * (float)this->cullRadius;
this->cullCenter = cameraPos + Vector(400.0f*invGlobalScale,300.0f*invGlobalScale);
screenCullX1 = cameraPos.x;
screenCullX2 = cameraPos.x + 800*invGlobalScale;
screenCullY1 = cameraPos.y;
screenCullY2 = cameraPos.y + 600*invGlobalScale;
int cx = core->cameraPos.x + 400*invGlobalScale;
int cy = core->cameraPos.y + 300*invGlobalScale;
screenCenter = Vector(cx, cy);
cullRadius = baseCullRadius * invGlobalScale;
cullRadiusSqr = cullRadius * cullRadius;
screenCenter = cullCenter = cameraPos + Vector(400.0f*invGlobalScale,300.0f*invGlobalScale);
}
void Core::render(int startLayer, int endLayer, bool useFrameBufferIfAvail)
@ -4079,12 +4074,11 @@ void Core::render(int startLayer, int endLayer, bool useFrameBufferIfAvail)
endLayer = overrideEndLayer;
}
globalScaleChanged();
if (core->minimized) return;
onRender();
invGlobalScale = 1.0f/globalScale.x;
invGlobalScaleSqr = invGlobalScale * invGlobalScale;
RenderObject::lastTextureApplied = 0;
updateCullData();

View file

@ -1037,7 +1037,7 @@ public:
void removeRenderObject(RenderObject *r, RemoveRenderObjectFlag flag = DESTROY_RENDER_OBJECT);
void setMouseConstraint(bool on);
void setMouseConstraintCircle(int mouseCircle);
void setMouseConstraintCircle(float mouseCircle);
void setReentryInputGrab(int on);
@ -1130,7 +1130,7 @@ public:
virtual void onPlayedVoice(const std::string &name){}
InterpolatedVector cameraPos;
Vector cameraPos;
int fps;
bool loopDone;
@ -1174,13 +1174,14 @@ public:
bool minimized;
std::string getEnqueuedJumpState();
int cullRadius;
float cullRadius;
float cullRadiusSqr;
Vector cullCenter;
int screenCullX1, screenCullY1, screenCullX2, screenCullY2;
unsigned int renderObjectCount, processedRenderObjectCount, totalRenderObjectCount;
float invGlobalScale, invGlobalScaleSqr;
void globalScaleChanged();
void screenshot();
void clearRenderObjects();
@ -1348,13 +1349,13 @@ protected:
std::string appName;
bool mouseConstraint;
int mouseCircle;
float mouseCircle;
bool doMouseConstraint();
virtual void onMouseInput(){}
bool doScreenshot;
int baseCullRadius;
float baseCullRadius;
bool initSoundLibrary(const std::string &defaultDevice);
bool initInputLibrary();
bool initJoystickLibrary(int numSticks=1);