autoexpand save when particles are translated out of boundaries

This commit is contained in:
krawthekrow 2016-09-12 17:15:09 +08:00 committed by jacob1
parent 1c275e943f
commit ca542b1ef1
3 changed files with 86 additions and 6 deletions

View File

@ -260,12 +260,82 @@ char * GameSave::Serialise(unsigned int & dataSize)
return serialiseOPS(dataSize);
}
void GameSave::Translate(vector2d translate)
{
if(Collapsed())
Expand();
int nx, ny;
vector2d pos;
float minx = 0, miny = 0, maxx = 0, maxy = 0;
for (size_t i = 0; i < signs.size(); i++)
{
pos = v2d_new(signs[i].x, signs[i].y);
pos = v2d_add(pos,translate);
nx = floor(pos.x+0.5f);
ny = floor(pos.y+0.5f);
if (nx < minx)
minx = nx;
if (ny < miny)
miny = ny;
if (nx > maxx)
maxx = nx;
if (ny > maxy)
maxy = ny;
}
for (int i = 0; i < particlesCount; i++)
{
if (!particles[i].type) continue;
pos = v2d_new(particles[i].x, particles[i].y);
pos = v2d_add(pos,translate);
nx = floor(pos.x+0.5f);
ny = floor(pos.y+0.5f);
if (nx < minx)
minx = nx;
if (ny < miny)
miny = ny;
if (nx > maxx)
maxx = nx;
if (ny > maxy)
maxy = ny;
}
vector2d backCorrection = v2d_new(
(minx < 0) ? (-floor(minx / 4)) : 0,
(miny < 0) ? (-floor(miny / 4)) : 0
);
int blockBoundsX = int(maxx / CELL) + 1, blockBoundsY = int(maxy / CELL) + 1;
vector2d frontCorrection = v2d_new(
(blockBoundsX > blockWidth) ? (blockBoundsX - blockWidth) : 0,
(blockBoundsY > blockHeight) ? (blockBoundsY - blockHeight) : 0
);
if (frontCorrection.x < backCorrection.x)
frontCorrection.x = backCorrection.x;
else
backCorrection.x = frontCorrection.x;
if (frontCorrection.y < backCorrection.y)
frontCorrection.y = backCorrection.y;
else
backCorrection.y = frontCorrection.y;
int newWidth = (blockWidth + backCorrection.x + frontCorrection.x) * CELL;
int newHeight = (blockHeight + backCorrection.y + frontCorrection.y) * CELL;
if (newWidth > XRES)
frontCorrection.x = backCorrection.x = 0;
if (newHeight > YRES)
frontCorrection.y = backCorrection.y = 0;
translate = v2d_add(translate, v2d_multiply_float(backCorrection, CELL));
Transform(m2d_identity, translate,
(blockWidth + backCorrection.x + frontCorrection.x) * CELL,
(blockHeight + backCorrection.y + frontCorrection.y) * CELL
);
}
void GameSave::Transform(matrix2d transform, vector2d translate)
{
if(Collapsed())
Expand();
int x, y, nx, ny, width = blockWidth*CELL, height = blockHeight*CELL, newWidth, newHeight, newBlockWidth, newBlockHeight;
vector2d pos, tmp, ctl, cbr, vel;
int width = blockWidth*CELL, height = blockHeight*CELL, newWidth, newHeight;
vector2d tmp, ctl, cbr;
vector2d cornerso[4];
// undo any translation caused by rotation
cornerso[0] = v2d_new(0,0);
@ -286,10 +356,19 @@ void GameSave::Transform(matrix2d transform, vector2d translate)
translate = v2d_sub(translate,tmp);
newWidth = floor(cbr.x+0.5f)-floor(ctl.x+0.5f)+1;
newHeight = floor(cbr.y+0.5f)-floor(ctl.y+0.5f)+1;
Transform(transform, translate, newWidth, newHeight);
}
void GameSave::Transform(matrix2d transform, vector2d translate, int newWidth, int newHeight)
{
if(Collapsed())
Expand();
if (newWidth>XRES) newWidth = XRES;
if (newHeight>YRES) newHeight = YRES;
newBlockWidth = newWidth/CELL;
newBlockHeight = newHeight/CELL;
int x, y, nx, ny, newBlockWidth = newWidth / CELL, newBlockHeight = newHeight / CELL;
vector2d pos, vel;
unsigned char ** blockMapNew;
float **fanVelXNew, **fanVelYNew, **pressureNew, **velocityXNew, **velocityYNew, **ambientHeatNew;

View File

@ -76,7 +76,9 @@ public:
void setSize(int width, int height);
char * Serialise(unsigned int & dataSize);
std::vector<char> Serialise();
void Translate(vector2d translate);
void Transform(matrix2d transform, vector2d translate);
void Transform(matrix2d transform, vector2d translate, int newWidth, int newHeight);
void Expand();
void Collapse();

View File

@ -544,9 +544,8 @@ void GameController::LoadStamp(GameSave *stamp)
void GameController::TranslateSave(ui::Point point)
{
matrix2d transform = m2d_identity;
vector2d translate = v2d_new(point.X, point.Y);
gameModel->GetPlaceSave()->Transform(transform, translate);
gameModel->GetPlaceSave()->Translate(translate);
gameModel->SetPlaceSave(gameModel->GetPlaceSave());
}