Improvements in minimap drawing

This commit is contained in:
Eduardo Bart 2013-01-31 03:38:06 -02:00
parent abcc95634e
commit 89c012e81f
6 changed files with 55 additions and 37 deletions

View File

@ -129,11 +129,11 @@ function UIMinimap:removeFlag(pos, icon, description)
end end
function UIMinimap:updateFlag(flag) function UIMinimap:updateFlag(flag)
local topLeft, bottomRight = self:getArea() local point = self:getPoint(flag.pos)
if self:isFlagVisible(flag, topLeft, bottomRight) then if self:containsPoint(point) and self:getZoom() > 0 then
flag:setVisible(true) flag:setVisible(true)
flag:setMarginLeft(-5.5 + (self:getWidth() / (bottomRight.x - topLeft.x)) * (flag.pos.x - topLeft.x)) flag:setMarginLeft(point.x - self:getX() - flag:getWidth()/2)
flag:setMarginTop(-5.5 + (self:getHeight() / (bottomRight.y - topLeft.y)) * (flag.pos.y - topLeft.y)) flag:setMarginTop(point.y - self:getY() - flag:getHeight()/2)
else else
flag:setVisible(false) flag:setVisible(false)
end end
@ -317,6 +317,4 @@ function UIMinimap:getArea()
return topLeft, bottomRight return topLeft, bottomRight
end end
function UIMinimap:isFlagVisible(flag, topLeft, bottomRight)
return flag.pos.x >= topLeft.x and flag.pos.x <= bottomRight.x and flag.pos.y >= topLeft.y and flag.pos.y <= bottomRight.y and flag.pos.z == topLeft.z
end

View File

@ -593,6 +593,7 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIMinimap>("setCameraPosition", &UIMinimap::setCameraPosition); g_lua.bindClassMemberFunction<UIMinimap>("setCameraPosition", &UIMinimap::setCameraPosition);
g_lua.bindClassMemberFunction<UIMinimap>("setCross", &UIMinimap::setCross); g_lua.bindClassMemberFunction<UIMinimap>("setCross", &UIMinimap::setCross);
g_lua.bindClassMemberFunction<UIMinimap>("followCreature", &UIMinimap::followCreature); g_lua.bindClassMemberFunction<UIMinimap>("followCreature", &UIMinimap::followCreature);
g_lua.bindClassMemberFunction<UIMinimap>("getPoint", &UIMinimap::getPoint);
g_lua.bindClassMemberFunction<UIMinimap>("getPosition", &UIMinimap::getPosition); g_lua.bindClassMemberFunction<UIMinimap>("getPosition", &UIMinimap::getPosition);
g_lua.bindClassMemberFunction<UIMinimap>("getCameraPosition", &UIMinimap::getCameraPosition); g_lua.bindClassMemberFunction<UIMinimap>("getCameraPosition", &UIMinimap::getCameraPosition);
g_lua.bindClassMemberFunction<UIMinimap>("getFollowingCreature", &UIMinimap::getFollowingCreature); g_lua.bindClassMemberFunction<UIMinimap>("getFollowingCreature", &UIMinimap::getFollowingCreature);

View File

@ -97,18 +97,10 @@ void Minimap::draw(const Rect& screenRect, const Position& mapCenter, float scal
{ {
if(screenRect.isEmpty()) if(screenRect.isEmpty())
return; return;
if(MMBLOCK_SIZE*scale <= 1) if(MMBLOCK_SIZE*scale <= 1)
return; return;
Size mapSize = screenRect.size() / scale; Rect mapRect = calcMapRect(screenRect, mapCenter, scale);
while(mapSize.width() > 8192 || mapSize.height() > 8192) {
scale *= 2;
mapSize = screenRect.size() / scale;
}
Rect mapRect(0, 0, mapSize);
mapRect.moveCenter(Point(mapCenter.x, mapCenter.y));
g_painter->saveState(); g_painter->saveState();
g_painter->setColor(Color::black); g_painter->setColor(Color::black);
g_painter->drawFilledRect(screenRect); g_painter->drawFilledRect(screenRect);
@ -119,14 +111,15 @@ void Minimap::draw(const Rect& screenRect, const Position& mapCenter, float scal
Point p = getBlockOffset(mapRect.topLeft() - Point(1,1)); Point p = getBlockOffset(mapRect.topLeft() - Point(1,1));
g_painter->translate(-(mapRect.topLeft() - p)*scale); g_painter->translate(-(mapRect.topLeft() - p)*scale);
if(scale > 1.0f) Size wantedSize = mapRect.size() * scale;
g_painter->translate(Point(1,1) * scale * 0.5f); Point off = Point(wantedSize.toPoint() - screenRect.size().toPoint())/2;
g_painter->translate(-off);
for(int y = p.y, ys = 0;y<=mapRect.bottom();y += MMBLOCK_SIZE, ys += MMBLOCK_SIZE*scale) { for(int y = p.y, ys = 0;y<=mapRect.bottom()+1;y += MMBLOCK_SIZE, ys += MMBLOCK_SIZE*scale) {
if(y < 0 || y >= 65536 - MMBLOCK_SIZE) if(y < 0 || y >= 65536 - MMBLOCK_SIZE)
continue; continue;
for(int x = p.x, xs = 0;x<=mapRect.right();x += MMBLOCK_SIZE, xs += MMBLOCK_SIZE*scale) { for(int x = p.x, xs = 0;x<=mapRect.right()+1;x += MMBLOCK_SIZE, xs += MMBLOCK_SIZE*scale) {
if(x < 0 || x >= 65536 - MMBLOCK_SIZE) if(x < 0 || x >= 65536 - MMBLOCK_SIZE)
continue; continue;
@ -151,32 +144,50 @@ void Minimap::draw(const Rect& screenRect, const Position& mapCenter, float scal
g_painter->restoreSavedState(); g_painter->restoreSavedState();
} }
Point Minimap::getPoint(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale)
{
if(screenRect.isEmpty())
return Point(-1,-1);
if(MMBLOCK_SIZE*scale <= 1)
return Point(-1,-1);
Rect mapRect = calcMapRect(screenRect, mapCenter, scale);
Point off = Point((mapRect.size() * scale).toPoint() - screenRect.size().toPoint())/2;
Point posoff = (Point(pos.x,pos.y) - mapRect.topLeft())*scale;
return posoff + screenRect.topLeft() - off + (Point(1,1)*scale)/2;
}
Position Minimap::getPosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale) Position Minimap::getPosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale)
{ {
if(screenRect.isEmpty()) if(screenRect.isEmpty())
return Position(); return Position();
if(MMBLOCK_SIZE*scale <= 1) if(MMBLOCK_SIZE*scale <= 1)
return Position(); return Position();
Position pos(mapCenter); Rect mapRect = calcMapRect(screenRect, mapCenter, scale);
Point off = Point((mapRect.size() * scale).toPoint() - screenRect.size().toPoint())/2;
Size mapSize = screenRect.size() / scale; Point pos2d = (point - screenRect.topLeft() + off)/scale + mapRect.topLeft();
while(mapSize.width() > 8192 || mapSize.height() > 8192) { return Position(pos2d.x, pos2d.y, mapCenter.z);
scale *= 2;
mapSize = screenRect.size() / scale;
}
Rect mapRect(0, 0, mapSize);
mapRect.moveCenter(Point(mapCenter.x, mapCenter.y));
Point p = (point - screenRect.topLeft() - Point(1,1) * scale * 0.5f)/scale + mapRect.topLeft();
pos.x = p.x;
pos.y = p.y;
return pos;
} }
Rect Minimap::calcMapRect(const Rect& screenRect, const Position& mapCenter, float scale)
{
int w, h;
do {
w = std::ceil(screenRect.width() / scale);
h = std::ceil(screenRect.height() / scale);
if(w % 2 == 0)
w++;
if(h % 2 == 0)
h++;
scale *= 2;
} while(w > 8192 || h > 8192);
Rect mapRect(0,0,h,w);
mapRect.moveCenter(Point(mapCenter.x, mapCenter.y));
return mapRect;
}
void Minimap::updateTile(const Position& pos, const TilePtr& tile) void Minimap::updateTile(const Position& pos, const TilePtr& tile)
{ {
MinimapTile minimapTile; MinimapTile minimapTile;

View File

@ -82,6 +82,7 @@ public:
void clean(); void clean();
void draw(const Rect& screenRect, const Position& mapCenter, float scale); void draw(const Rect& screenRect, const Position& mapCenter, float scale);
Point getPoint(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale);
Position getPosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale); Position getPosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale);
void updateTile(const Position& pos, const TilePtr& tile); void updateTile(const Position& pos, const TilePtr& tile);
@ -91,6 +92,7 @@ public:
void saveOtmm(const std::string& fileName); void saveOtmm(const std::string& fileName);
private: private:
Rect calcMapRect(const Rect& screenRect, const Position& mapCenter, float scale);
bool hasBlock(const Position& pos) { return m_tileBlocks[pos.z].find(getBlockIndex(pos)) != m_tileBlocks[pos.z].end(); } bool hasBlock(const Position& pos) { return m_tileBlocks[pos.z].find(getBlockIndex(pos)) != m_tileBlocks[pos.z].end(); }
MinimapBlock& getBlock(const Position& pos) { return m_tileBlocks[pos.z][getBlockIndex(pos)]; } MinimapBlock& getBlock(const Position& pos) { return m_tileBlocks[pos.z][getBlockIndex(pos)]; }
Point getBlockOffset(const Point& pos) { return Point(pos.x - pos.x % MMBLOCK_SIZE, Point getBlockOffset(const Point& pos) { return Point(pos.x - pos.x % MMBLOCK_SIZE,

View File

@ -80,6 +80,11 @@ void UIMinimap::setCameraPosition(const Position& pos)
m_cameraPosition = pos; m_cameraPosition = pos;
} }
Point UIMinimap::getPoint(const Position& pos)
{
return g_minimap.getPoint(pos, getPaddingRect(), getCameraPosition(), m_scale);
}
Position UIMinimap::getPosition(const Point& mousePos) Position UIMinimap::getPosition(const Point& mousePos)
{ {
return g_minimap.getPosition(mousePos, getPaddingRect(), getCameraPosition(), m_scale); return g_minimap.getPosition(mousePos, getPaddingRect(), getCameraPosition(), m_scale);

View File

@ -43,6 +43,7 @@ public:
void setCross(bool enable) { m_crossEnabled = enable; } void setCross(bool enable) { m_crossEnabled = enable; }
void followCreature(const CreaturePtr& creature); void followCreature(const CreaturePtr& creature);
Point getPoint(const Position& pos);
Position getPosition(const Point& mousePos); Position getPosition(const Point& mousePos);
Position getCameraPosition(); Position getCameraPosition();
CreaturePtr getFollowingCreature() { return m_followingCreature; } CreaturePtr getFollowingCreature() { return m_followingCreature; }