Refactor rasterized line/ellipse calculation code
This commit is contained in:
parent
7d9fdfea4e
commit
e937c3d254
95
src/common/RasterGeometry.h
Normal file
95
src/common/RasterGeometry.h
Normal file
@ -0,0 +1,95 @@
|
||||
#include "Geometry.h"
|
||||
|
||||
// Assuming abs(dw) <= dz
|
||||
template<bool Ortho, typename F>
|
||||
void rasterizeLineZW(int dz, int dw, F f)
|
||||
{
|
||||
const int incW = dw >= 0 ? 1 : -1;
|
||||
int z = 0, w = 0, err = 0;
|
||||
// err / (2 * dz) is the fractional error in w
|
||||
while (z <= dz)
|
||||
{
|
||||
f(z, w);
|
||||
|
||||
err += 2 * dw * incW;
|
||||
if (err >= dz)
|
||||
{
|
||||
w += incW;
|
||||
err -= 2 * dz;
|
||||
if (Ortho && z < dz)
|
||||
f(z, w);
|
||||
}
|
||||
|
||||
z++;
|
||||
}
|
||||
}
|
||||
|
||||
// Ortho makes the resulting line orthogonally connected
|
||||
template<bool Ortho, typename F>
|
||||
void RasterizeLine(Vec2<int> p1, Vec2<int> p2, F f)
|
||||
{
|
||||
if(std::abs(p1.X - p2.X) >= std::abs(p1.Y - p2.Y))
|
||||
{
|
||||
auto source = p1.X < p2.X ? p1 : p2;
|
||||
auto delta = p1.X < p2.X ? p2 - p1 : p1 - p2;
|
||||
rasterizeLineZW<Ortho>(delta.X, delta.Y, [source, f](int z, int w) { f(source + Vec2<int>(z, w)); });
|
||||
}
|
||||
else
|
||||
{
|
||||
auto source = p1.Y < p2.Y ? p1 : p2;
|
||||
auto delta = p1.Y < p2.Y ? p2 - p1 : p1 - p2;
|
||||
rasterizeLineZW<Ortho>(delta.Y, delta.X, [source, f](int z, int w) { f(source + Vec2<int>(w, z)); });
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void rasterizeEllipseQuadrant(Vec2<float> radiusSquared, F f)
|
||||
{
|
||||
auto inEllipse = [=](int x, int y)
|
||||
{
|
||||
return y * y * radiusSquared.X + x * x * radiusSquared.Y <= radiusSquared.X * radiusSquared.Y;
|
||||
};
|
||||
int x = int(std::floor(std::sqrt(radiusSquared.X)));
|
||||
int maxY = int(std::floor(std::sqrt(radiusSquared.Y)));
|
||||
for (int y = 0; y <= maxY; y++)
|
||||
{
|
||||
if (inEllipse(x, y + 1))
|
||||
{
|
||||
f(x, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
int xStart = x;
|
||||
do
|
||||
{
|
||||
x--;
|
||||
} while (x >= 0 && !inEllipse(x, y + 1));
|
||||
f(x + 1, xStart, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void RasterizeEllipsePoints(Vec2<float> radiusSquared, F f)
|
||||
{
|
||||
rasterizeEllipseQuadrant(radiusSquared, [f](int x1, int x2, int y)
|
||||
{
|
||||
for (int x = x1; x <= x2; x++)
|
||||
{
|
||||
f(Vec2<int>(x, y));
|
||||
if (x) f(Vec2<int>(-x, y));
|
||||
if (y) f(Vec2<int>(x, -y));
|
||||
if (x && y) f(Vec2<int>(-x, -y));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void RasterizeEllipseRows(Vec2<float> radiusSquared, F f)
|
||||
{
|
||||
rasterizeEllipseQuadrant(radiusSquared, [f](int _, int xLim, int y)
|
||||
{
|
||||
f(xLim, y);
|
||||
if (y) f(xLim, -y);
|
||||
});
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
#include <cmath>
|
||||
#include "FontReader.h"
|
||||
#include "common/RasterGeometry.h"
|
||||
#include <cmath>
|
||||
|
||||
int PIXELMETHODS_CLASS::drawtext_outline(int x, int y, const String &s, int r, int g, int b, int a)
|
||||
{
|
||||
@ -173,48 +174,8 @@ void PIXELMETHODS_CLASS::addpixel(int x, int y, int r, int g, int b, int a)
|
||||
|
||||
void PIXELMETHODS_CLASS::xor_line(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
int cp=abs(y2-y1)>abs(x2-x1), x, y, dx, dy, sy;
|
||||
float e, de;
|
||||
if (cp)
|
||||
{
|
||||
y = x1;
|
||||
x1 = y1;
|
||||
y1 = y;
|
||||
y = x2;
|
||||
x2 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
if (x1 > x2)
|
||||
{
|
||||
y = x1;
|
||||
x1 = x2;
|
||||
x2 = y;
|
||||
y = y1;
|
||||
y1 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
dx = x2 - x1;
|
||||
dy = abs(y2 - y1);
|
||||
e = 0.0f;
|
||||
if (dx)
|
||||
de = dy/(float)dx;
|
||||
else
|
||||
de = 0.0f;
|
||||
y = y1;
|
||||
sy = (y1<y2) ? 1 : -1;
|
||||
for (x=x1; x<=x2; x++)
|
||||
{
|
||||
if (cp)
|
||||
xor_pixel(y, x);
|
||||
else
|
||||
xor_pixel(x, y);
|
||||
e += de;
|
||||
if (e >= 0.5f)
|
||||
{
|
||||
y += sy;
|
||||
e -= 1.0f;
|
||||
}
|
||||
}
|
||||
RasterizeLine<false>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||
[this](Vec2<int> p) { xor_pixel(p.X, p.Y); });
|
||||
}
|
||||
|
||||
void PIXELMETHODS_CLASS::xor_rect(int x, int y, int w, int h)
|
||||
@ -263,48 +224,8 @@ void PIXELMETHODS_CLASS::xor_bitmap(unsigned char * bitmap, int x, int y, int w,
|
||||
|
||||
void PIXELMETHODS_CLASS::draw_line(int x1, int y1, int x2, int y2, int r, int g, int b, int a)
|
||||
{
|
||||
int cp=abs(y2-y1)>abs(x2-x1), x, y, dx, dy, sy;
|
||||
float e, de;
|
||||
if (cp)
|
||||
{
|
||||
y = x1;
|
||||
x1 = y1;
|
||||
y1 = y;
|
||||
y = x2;
|
||||
x2 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
if (x1 > x2)
|
||||
{
|
||||
y = x1;
|
||||
x1 = x2;
|
||||
x2 = y;
|
||||
y = y1;
|
||||
y1 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
dx = x2 - x1;
|
||||
dy = abs(y2 - y1);
|
||||
e = 0.0f;
|
||||
if (dx)
|
||||
de = dy/(float)dx;
|
||||
else
|
||||
de = 0.0f;
|
||||
y = y1;
|
||||
sy = (y1<y2) ? 1 : -1;
|
||||
for (x=x1; x<=x2; x++)
|
||||
{
|
||||
if (cp)
|
||||
blendpixel(y, x, r, g, b, a);
|
||||
else
|
||||
blendpixel(x, y, r, g, b, a);
|
||||
e += de;
|
||||
if (e >= 0.5f)
|
||||
{
|
||||
y += sy;
|
||||
e -= 1.0f;
|
||||
}
|
||||
}
|
||||
RasterizeLine<false>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||
[this, r, g, b, a](Vec2<int> p) { blendpixel(p.X, p.Y, r, g, b, a); });
|
||||
}
|
||||
|
||||
void PIXELMETHODS_CLASS::drawrect(int x, int y, int w, int h, int r, int g, int b, int a)
|
||||
@ -334,55 +255,17 @@ void PIXELMETHODS_CLASS::fillrect(int x, int y, int w, int h, int r, int g, int
|
||||
|
||||
void PIXELMETHODS_CLASS::drawcircle(int x, int y, int rx, int ry, int r, int g, int b, int a)
|
||||
{
|
||||
int yTop = ry, yBottom, i, j;
|
||||
if (!rx)
|
||||
{
|
||||
for (j = -ry; j <= ry; j++)
|
||||
blendpixel(x, y+j, r, g, b, a);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i <= rx; i++) {
|
||||
yBottom = yTop;
|
||||
while (pow(i-rx,2.0)*pow(ry,2.0) + pow(yTop-ry,2.0)*pow(rx,2.0) <= pow(rx,2.0)*pow(ry,2.0))
|
||||
yTop++;
|
||||
if (yBottom != yTop)
|
||||
yTop--;
|
||||
for (int j = yBottom; j <= yTop; j++)
|
||||
{
|
||||
blendpixel(x+i-rx, y+j-ry, r, g, b, a);
|
||||
if (i != rx)
|
||||
blendpixel(x-i+rx, y+j-ry, r, g, b, a);
|
||||
if (j != ry)
|
||||
{
|
||||
blendpixel(x+i-rx, y-j+ry, r, g, b, a);
|
||||
if (i != rx)
|
||||
blendpixel(x-i+rx, y-j+ry, r, g, b, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
RasterizeEllipsePoints(Vec2<float>(rx * rx, ry * ry),
|
||||
[=](Vec2<int> p) { blendpixel(x + p.X, y + p.Y, r, g, b, a); });
|
||||
}
|
||||
|
||||
void PIXELMETHODS_CLASS::fillcircle(int x, int y, int rx, int ry, int r, int g, int b, int a)
|
||||
{
|
||||
int yTop = ry+1, yBottom, i, j;
|
||||
if (!rx)
|
||||
{
|
||||
for (j = -ry; j <= ry; j++)
|
||||
blendpixel(x, y+j, r, g, b, a);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i <= rx; i++)
|
||||
{
|
||||
while (pow(i-rx,2.0)*pow(ry,2.0) + pow(yTop-ry,2.0)*pow(rx,2.0) <= pow(rx,2.0)*pow(ry,2.0))
|
||||
yTop++;
|
||||
yBottom = 2*ry - yTop;
|
||||
for (int j = yBottom+1; j < yTop; j++)
|
||||
RasterizeEllipseRows(Vec2<float>(rx * rx, ry * ry), [=](int xLim, int dy)
|
||||
{
|
||||
blendpixel(x+i-rx, y+j-ry, r, g, b, a);
|
||||
if (i != rx)
|
||||
blendpixel(x-i+rx, y+j-ry, r, g, b, a);
|
||||
}
|
||||
}
|
||||
for (int dx = -xLim; dx <= xLim; dx++)
|
||||
blendpixel(x + dx, y + dy, r, g, b, a);
|
||||
});
|
||||
}
|
||||
|
||||
void PIXELMETHODS_CLASS::gradientrect(int x, int y, int width, int height, int r, int g, int b, int a, int r2, int g2, int b2, int a2)
|
||||
|
@ -27,7 +27,7 @@ BitmapBrush::BitmapBrush(const BitmapBrush &other) : BitmapBrush(other.origSize,
|
||||
|
||||
std::unique_ptr<unsigned char []> BitmapBrush::GenerateBitmap() const
|
||||
{
|
||||
ui::Point size = radius * 2 + 1;
|
||||
ui::Point size = radius * 2 + ui::Point(1, 1);
|
||||
auto bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
|
||||
if (size == origSize)
|
||||
std::copy(&origBitmap[0], &origBitmap[origSize.X * origSize.Y], &bitmap[0]);
|
||||
|
@ -63,7 +63,7 @@ public:
|
||||
|
||||
ui::Point GetSize() const
|
||||
{
|
||||
return radius * 2 + 1;
|
||||
return radius * 2 + ui::Point(1, 1);
|
||||
}
|
||||
|
||||
ui::Point GetRadius() const
|
||||
|
@ -62,22 +62,22 @@ DecorationTool::~DecorationTool()
|
||||
{
|
||||
}
|
||||
|
||||
void DecorationTool::Draw(Simulation * sim, Brush const &brush, ui::Point position)
|
||||
void DecorationTool::Draw(Simulation * sim, Brush const &brush, Pos position)
|
||||
{
|
||||
sim->ApplyDecorationPoint(position.X, position.Y, Red, Green, Blue, Alpha, toolID, brush);
|
||||
}
|
||||
|
||||
void DecorationTool::DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging)
|
||||
void DecorationTool::DrawLine(Simulation * sim, Brush const &brush, Pos position1, Pos position2, bool dragging)
|
||||
{
|
||||
sim->ApplyDecorationLine(position1.X, position1.Y, position2.X, position2.Y, Red, Green, Blue, Alpha, toolID, brush);
|
||||
}
|
||||
|
||||
void DecorationTool::DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2)
|
||||
void DecorationTool::DrawRect(Simulation * sim, Brush const &brush, Pos position1, Pos position2)
|
||||
{
|
||||
sim->ApplyDecorationBox(position1.X, position1.Y, position2.X, position2.Y, Red, Green, Blue, Alpha, toolID);
|
||||
}
|
||||
|
||||
void DecorationTool::DrawFill(Simulation * sim, Brush const &brush, ui::Point position)
|
||||
void DecorationTool::DrawFill(Simulation * sim, Brush const &brush, Pos position)
|
||||
{
|
||||
pixel loc = ren->vid[position.X+position.Y*WINDOWW];
|
||||
if (toolID == DECO_CLEAR)
|
||||
|
@ -16,8 +16,8 @@ public:
|
||||
|
||||
DecorationTool(Renderer *ren_, int decoMode, String name, String description, int r, int g, int b, ByteString identifier);
|
||||
virtual ~DecorationTool();
|
||||
void Draw(Simulation * sim, Brush const &brush, ui::Point position) override;
|
||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging) override;
|
||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override;
|
||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override;
|
||||
void Draw(Simulation *, Brush const &, Pos) override;
|
||||
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging) override;
|
||||
void DrawRect(Simulation *, Brush const &, Pos, Pos) override;
|
||||
void DrawFill(Simulation *, Brush const &, Pos) override;
|
||||
};
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "common/RasterGeometry.h"
|
||||
#include "Brush.h"
|
||||
#include <cmath>
|
||||
|
||||
@ -15,52 +16,21 @@ public:
|
||||
|
||||
std::unique_ptr<unsigned char []> GenerateBitmap() const override
|
||||
{
|
||||
ui::Point size = radius * 2 + 1;
|
||||
ui::Point size = radius * 2 + ui::Point(1, 1);
|
||||
auto bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
|
||||
|
||||
int rx = radius.X;
|
||||
int ry = radius.Y;
|
||||
|
||||
if (!rx)
|
||||
std::fill(&bitmap[0], &bitmap[size.X * size.Y], 0);
|
||||
float rx = radius.X, ry = radius.Y;
|
||||
if (perfectCircle)
|
||||
{
|
||||
for (int j = 0; j <= 2*ry; j++)
|
||||
{
|
||||
bitmap[j*(size.X)+rx] = 255;
|
||||
}
|
||||
rx += 0.5;
|
||||
ry += 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
int yTop = ry+1, yBottom, i;
|
||||
for (i = 0; i <= rx; i++)
|
||||
RasterizeEllipseRows(Vec2<float>(rx * rx, ry * ry), [this, &bitmap, size](int xLim, int y)
|
||||
{
|
||||
if (perfectCircle)
|
||||
{
|
||||
while (pow(i - rx, 2.0) * pow(ry - 0.5, 2.0) + pow(yTop - ry, 2.0) * pow(rx - 0.5, 2.0) <= pow(rx, 2.0) * pow(ry, 2.0))
|
||||
yTop++;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (pow(i - rx, 2.0) * pow(ry, 2.0) + pow(yTop - ry, 2.0) * pow(rx, 2.0) <= pow(rx, 2.0) * pow(ry, 2.0))
|
||||
yTop++;
|
||||
}
|
||||
yBottom = 2*ry - yTop;
|
||||
for (int j = 0; j <= ry*2; j++)
|
||||
{
|
||||
if (j > yBottom && j < yTop)
|
||||
{
|
||||
bitmap[j*(size.X)+i] = 255;
|
||||
bitmap[j*(size.X)+2*rx-i] = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitmap[j*(size.X)+i] = 0;
|
||||
bitmap[j*(size.X)+2*rx-i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
bitmap[size.X/2] = 255;
|
||||
bitmap[size.X*size.Y-size.X/2-1] = 255;
|
||||
}
|
||||
for (int x = -xLim; x <= xLim; x++)
|
||||
bitmap[x + radius.X + (y + radius.Y) * size.X] = 0xFF;
|
||||
});
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "Tool.h"
|
||||
|
||||
#include "common/RasterGeometry.h"
|
||||
#include "prefs/GlobalPrefs.h"
|
||||
#include "Menu.h"
|
||||
#include "Format.h"
|
||||
@ -255,7 +256,7 @@ void PropertyTool::OpenWindow(Simulation *sim)
|
||||
new PropertyWindow(this, sim);
|
||||
}
|
||||
|
||||
void PropertyTool::SetProperty(Simulation *sim, ui::Point position)
|
||||
void PropertyTool::SetProperty(Simulation *sim, Pos position)
|
||||
{
|
||||
if(position.X<0 || position.X>XRES || position.Y<0 || position.Y>YRES || !validProperty)
|
||||
return;
|
||||
@ -288,7 +289,7 @@ void PropertyTool::SetProperty(Simulation *sim, ui::Point position)
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyTool::Draw(Simulation *sim, Brush const &cBrush, ui::Point position)
|
||||
void PropertyTool::Draw(Simulation *sim, Brush const &cBrush, Pos position)
|
||||
{
|
||||
for (ui::Point off : cBrush)
|
||||
{
|
||||
@ -298,61 +299,15 @@ void PropertyTool::Draw(Simulation *sim, Brush const &cBrush, ui::Point position
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyTool::DrawLine(Simulation *sim, Brush const &cBrush, ui::Point position, ui::Point position2, bool dragging)
|
||||
void PropertyTool::DrawLine(Simulation *sim, Brush const &cBrush, Pos position1, Pos position2, bool dragging)
|
||||
{
|
||||
int x1 = position.X, y1 = position.Y, x2 = position2.X, y2 = position2.Y;
|
||||
bool reverseXY = abs(y2-y1) > abs(x2-x1);
|
||||
int x, y, dx, dy, sy, rx = cBrush.GetRadius().X, ry = cBrush.GetRadius().Y;
|
||||
float e = 0.0f, de;
|
||||
if (reverseXY)
|
||||
{
|
||||
y = x1;
|
||||
x1 = y1;
|
||||
y1 = y;
|
||||
y = x2;
|
||||
x2 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
if (x1 > x2)
|
||||
{
|
||||
y = x1;
|
||||
x1 = x2;
|
||||
x2 = y;
|
||||
y = y1;
|
||||
y1 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
dx = x2 - x1;
|
||||
dy = abs(y2 - y1);
|
||||
if (dx)
|
||||
de = dy/(float)dx;
|
||||
if (cBrush.GetRadius() == Pos::Zero)
|
||||
RasterizeLine<true>(position1, position2, [this, sim, &cBrush](Pos p) { Draw(sim, cBrush, p); });
|
||||
else
|
||||
de = 0.0f;
|
||||
y = y1;
|
||||
sy = (y1<y2) ? 1 : -1;
|
||||
for (x=x1; x<=x2; x++)
|
||||
{
|
||||
if (reverseXY)
|
||||
Draw(sim, cBrush, ui::Point(y, x));
|
||||
else
|
||||
Draw(sim, cBrush, ui::Point(x, y));
|
||||
e += de;
|
||||
if (e >= 0.5f)
|
||||
{
|
||||
y += sy;
|
||||
if (!(rx+ry) && ((y1<y2) ? (y<=y2) : (y>=y2)))
|
||||
{
|
||||
if (reverseXY)
|
||||
Draw(sim, cBrush, ui::Point(y, x));
|
||||
else
|
||||
Draw(sim, cBrush, ui::Point(x, y));
|
||||
}
|
||||
e -= 1.0f;
|
||||
}
|
||||
}
|
||||
RasterizeLine<false>(position1, position2, [this, sim, &cBrush](Pos p) { Draw(sim, cBrush, p); });
|
||||
}
|
||||
|
||||
void PropertyTool::DrawRect(Simulation *sim, Brush const &cBrush, ui::Point position, ui::Point position2)
|
||||
void PropertyTool::DrawRect(Simulation *sim, Brush const &cBrush, Pos position, Pos position2)
|
||||
{
|
||||
int x1 = position.X, y1 = position.Y, x2 = position2.X, y2 = position2.Y;
|
||||
int i, j;
|
||||
@ -370,10 +325,10 @@ void PropertyTool::DrawRect(Simulation *sim, Brush const &cBrush, ui::Point posi
|
||||
}
|
||||
for (j=y1; j<=y2; j++)
|
||||
for (i=x1; i<=x2; i++)
|
||||
SetProperty(sim, ui::Point(i, j));
|
||||
SetProperty(sim, Pos(i, j));
|
||||
}
|
||||
|
||||
void PropertyTool::DrawFill(Simulation *sim, Brush const &cBrush, ui::Point position)
|
||||
void PropertyTool::DrawFill(Simulation *sim, Brush const &cBrush, Pos position)
|
||||
{
|
||||
if (validProperty)
|
||||
sim->flood_prop(position.X, position.Y, propOffset, propValue, propType);
|
||||
|
@ -37,17 +37,17 @@ String Tool::GetName() { return toolName; }
|
||||
String Tool::GetDescription() { return toolDescription; }
|
||||
Tool::~Tool() {}
|
||||
|
||||
void Tool::Click(Simulation * sim, Brush const &brush, ui::Point position) { }
|
||||
void Tool::Draw(Simulation * sim, Brush const &brush, ui::Point position) {
|
||||
void Tool::Click(Simulation * sim, Brush const &brush, Pos position) { }
|
||||
void Tool::Draw(Simulation * sim, Brush const &brush, Pos position) {
|
||||
sim->ToolBrush(position.X, position.Y, toolID, brush, strength);
|
||||
}
|
||||
void Tool::DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging) {
|
||||
void Tool::DrawLine(Simulation * sim, Brush const &brush, Pos position1, Pos position2, bool dragging) {
|
||||
sim->ToolLine(position1.X, position1.Y, position2.X, position2.Y, toolID, brush, strength);
|
||||
}
|
||||
void Tool::DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) {
|
||||
void Tool::DrawRect(Simulation * sim, Brush const &brush, Pos position1, Pos position2) {
|
||||
sim->ToolBox(position1.X, position1.Y, position2.X, position2.Y, toolID, strength);
|
||||
}
|
||||
void Tool::DrawFill(Simulation * sim, Brush const &brush, ui::Point position) {}
|
||||
void Tool::DrawFill(Simulation * sim, Brush const &brush, Pos position) {}
|
||||
|
||||
|
||||
ElementTool::ElementTool(int id, String name, String description, int r, int g, int b, ByteString identifier, VideoBuffer * (*textureGen)(int, int, int)):
|
||||
@ -55,16 +55,17 @@ ElementTool::ElementTool(int id, String name, String description, int r, int g,
|
||||
{
|
||||
}
|
||||
ElementTool::~ElementTool() {}
|
||||
void ElementTool::Draw(Simulation * sim, Brush const &brush, ui::Point position){
|
||||
|
||||
void ElementTool::Draw(Simulation * sim, Brush const &brush, Pos position){
|
||||
sim->CreateParts(position.X, position.Y, toolID, brush);
|
||||
}
|
||||
void ElementTool::DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging) {
|
||||
void ElementTool::DrawLine(Simulation * sim, Brush const &brush, Pos position1, Pos position2, bool dragging) {
|
||||
sim->CreateLine(position1.X, position1.Y, position2.X, position2.Y, toolID, brush);
|
||||
}
|
||||
void ElementTool::DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) {
|
||||
void ElementTool::DrawRect(Simulation * sim, Brush const &brush, Pos position1, Pos position2) {
|
||||
sim->CreateBox(position1.X, position1.Y, position2.X, position2.Y, toolID);
|
||||
}
|
||||
void ElementTool::DrawFill(Simulation * sim, Brush const &brush, ui::Point position) {
|
||||
void ElementTool::DrawFill(Simulation * sim, Brush const &brush, Pos position) {
|
||||
sim->FloodParts(position.X, position.Y, toolID, -1);
|
||||
}
|
||||
|
||||
@ -75,10 +76,10 @@ Tool(id, name, description, r, g, b, identifier, textureGen)
|
||||
blocky = true;
|
||||
}
|
||||
WallTool::~WallTool() {}
|
||||
void WallTool::Draw(Simulation * sim, Brush const &brush, ui::Point position) {
|
||||
void WallTool::Draw(Simulation * sim, Brush const &brush, Pos position) {
|
||||
sim->CreateWalls(position.X, position.Y, 1, 1, toolID, &brush);
|
||||
}
|
||||
void WallTool::DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging) {
|
||||
void WallTool::DrawLine(Simulation * sim, Brush const &brush, Pos position1, Pos position2, bool dragging) {
|
||||
int wallX = position1.X/CELL;
|
||||
int wallY = position1.Y/CELL;
|
||||
if(dragging == false && toolID == WL_FAN && sim->bmap[wallY][wallX]==WL_FAN)
|
||||
@ -102,10 +103,10 @@ void WallTool::DrawLine(Simulation * sim, Brush const &brush, ui::Point position
|
||||
sim->CreateWallLine(position1.X, position1.Y, position2.X, position2.Y, 1, 1, toolID, &brush);
|
||||
}
|
||||
}
|
||||
void WallTool::DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) {
|
||||
void WallTool::DrawRect(Simulation * sim, Brush const &brush, Pos position1, Pos position2) {
|
||||
sim->CreateWallBox(position1.X, position1.Y, position2.X, position2.Y, toolID);
|
||||
}
|
||||
void WallTool::DrawFill(Simulation * sim, Brush const &brush, ui::Point position) {
|
||||
void WallTool::DrawFill(Simulation * sim, Brush const &brush, Pos position) {
|
||||
if (toolID != WL_STREAM)
|
||||
sim->FloodWalls(position.X, position.Y, toolID, -1);
|
||||
}
|
||||
@ -115,7 +116,7 @@ WindTool::WindTool(int id, String name, String description, int r, int g, int b,
|
||||
{
|
||||
}
|
||||
|
||||
void WindTool::DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging)
|
||||
void WindTool::DrawLine(Simulation * sim, Brush const &brush, Pos position1, Pos position2, bool dragging)
|
||||
{
|
||||
float strength = dragging?0.01f:0.002f;
|
||||
strength *= this->strength;
|
||||
@ -132,24 +133,24 @@ void WindTool::DrawLine(Simulation * sim, Brush const &brush, ui::Point position
|
||||
}
|
||||
|
||||
|
||||
void Element_LIGH_Tool::DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging)
|
||||
void Element_LIGH_Tool::DrawLine(Simulation * sim, Brush const &brush, Pos position1, Pos position2, bool dragging)
|
||||
{
|
||||
if (dragging)
|
||||
sim->CreateParts(position1.X, position1.Y, brush.GetRadius().X, brush.GetRadius().Y, PT_LIGH);
|
||||
}
|
||||
|
||||
|
||||
void Element_TESC_Tool::DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) {
|
||||
void Element_TESC_Tool::DrawRect(Simulation * sim, Brush const &brush, Pos position1, Pos position2) {
|
||||
int radiusInfo = brush.GetRadius().X*4+brush.GetRadius().Y*4+7;
|
||||
sim->CreateBox(position1.X, position1.Y, position2.X, position2.Y, toolID | PMAPID(radiusInfo));
|
||||
}
|
||||
void Element_TESC_Tool::DrawFill(Simulation * sim, Brush const &brush, ui::Point position) {
|
||||
void Element_TESC_Tool::DrawFill(Simulation * sim, Brush const &brush, Pos position) {
|
||||
int radiusInfo = brush.GetRadius().X*4+brush.GetRadius().Y*4+7;
|
||||
sim->FloodParts(position.X, position.Y, toolID | PMAPID(radiusInfo), -1);
|
||||
}
|
||||
|
||||
|
||||
void PlopTool::Click(Simulation * sim, Brush const &brush, ui::Point position)
|
||||
void PlopTool::Click(Simulation * sim, Brush const &brush, Pos position)
|
||||
{
|
||||
sim->create_part(-2, position.X, position.Y, TYP(toolID), ID(toolID));
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include "common/Geometry.h"
|
||||
#include "common/String.h"
|
||||
#include "gui/interface/Point.h"
|
||||
#include "simulation/StructProperty.h"
|
||||
|
||||
class Simulation;
|
||||
@ -10,6 +10,7 @@ class VideoBuffer;
|
||||
class Tool
|
||||
{
|
||||
protected:
|
||||
using Pos = Vec2<int>;
|
||||
VideoBuffer * (*textureGen)(int, int, int);
|
||||
int toolID;
|
||||
String toolName;
|
||||
@ -31,11 +32,11 @@ public:
|
||||
VideoBuffer * GetTexture(int width, int height);
|
||||
void SetTextureGen(VideoBuffer * (*textureGen)(int, int, int));
|
||||
virtual ~Tool();
|
||||
virtual void Click(Simulation * sim, Brush const &brush, ui::Point position);
|
||||
virtual void Draw(Simulation * sim, Brush const &brush, ui::Point position);
|
||||
virtual void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false);
|
||||
virtual void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2);
|
||||
virtual void DrawFill(Simulation * sim, Brush const &brush, ui::Point position);
|
||||
virtual void Click(Simulation *, Brush const &, Pos);
|
||||
virtual void Draw(Simulation *, Brush const &, Pos);
|
||||
virtual void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false);
|
||||
virtual void DrawRect(Simulation *, Brush const &, Pos, Pos);
|
||||
virtual void DrawFill(Simulation *, Brush const &, Pos);
|
||||
};
|
||||
|
||||
class GameModel;
|
||||
@ -51,11 +52,11 @@ public:
|
||||
}
|
||||
static VideoBuffer * GetIcon(int toolID, int width, int height);
|
||||
virtual ~SignTool() {}
|
||||
void Click(Simulation * sim, Brush const &brush, ui::Point position) override;
|
||||
void Draw(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override { }
|
||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override { }
|
||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
||||
void Click(Simulation *, Brush const &, Pos) override;
|
||||
void Draw(Simulation *, Brush const &, Pos) override { }
|
||||
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override { }
|
||||
void DrawRect(Simulation *, Brush const &, Pos, Pos) override { }
|
||||
void DrawFill(Simulation *, Brush const &, Pos) override { }
|
||||
};
|
||||
|
||||
class SampleTool: public Tool
|
||||
@ -69,11 +70,11 @@ public:
|
||||
}
|
||||
static VideoBuffer * GetIcon(int toolID, int width, int height);
|
||||
virtual ~SampleTool() {}
|
||||
void Click(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
||||
void Draw(Simulation * sim, Brush const &brush, ui::Point position) override;
|
||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override { }
|
||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override { }
|
||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
||||
void Click(Simulation *, Brush const &, Pos) override { }
|
||||
void Draw(Simulation *, Brush const &, Pos) override;
|
||||
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override { }
|
||||
void DrawRect(Simulation *, Brush const &, Pos, Pos) override { }
|
||||
void DrawFill(Simulation *, Brush const &, Pos) override { }
|
||||
};
|
||||
|
||||
class PropertyTool: public Tool
|
||||
@ -91,14 +92,14 @@ public:
|
||||
size_t propOffset;
|
||||
bool validProperty;
|
||||
|
||||
void OpenWindow(Simulation *sim);
|
||||
void OpenWindow(Simulation *);
|
||||
virtual ~PropertyTool() {}
|
||||
virtual void SetProperty(Simulation *sim, ui::Point position);
|
||||
void Click(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
||||
void Draw(Simulation *sim, Brush const &brush, ui::Point position) override;
|
||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override;
|
||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override;
|
||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override;
|
||||
virtual void SetProperty(Simulation *, Pos);
|
||||
void Click(Simulation *, Brush const &, Pos) override { }
|
||||
void Draw(Simulation *, Brush const &brush, Pos) override;
|
||||
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override;
|
||||
void DrawRect(Simulation *, Brush const &, Pos, Pos) override;
|
||||
void DrawFill(Simulation *, Brush const &, Pos) override;
|
||||
};
|
||||
|
||||
class GOLTool: public Tool
|
||||
@ -110,13 +111,13 @@ public:
|
||||
gameModel(gameModel)
|
||||
{
|
||||
}
|
||||
void OpenWindow(Simulation *sim, int toolSelection, int rule = 0, int colour1 = 0, int colour2 = 0);
|
||||
void OpenWindow(Simulation *, int toolSelection, int rule = 0, int colour1 = 0, int colour2 = 0);
|
||||
virtual ~GOLTool() {}
|
||||
void Click(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
||||
void Draw(Simulation *sim, Brush const &brush, ui::Point position) override { };
|
||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override { };
|
||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override { };
|
||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override { };
|
||||
void Click(Simulation *, Brush const &, Pos) override { }
|
||||
void Draw(Simulation *, Brush const &brush, Pos) override { };
|
||||
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override { };
|
||||
void DrawRect(Simulation *, Brush const &, Pos, Pos) override { };
|
||||
void DrawFill(Simulation *, Brush const &, Pos) override { };
|
||||
};
|
||||
|
||||
|
||||
@ -125,10 +126,10 @@ class ElementTool: public Tool
|
||||
public:
|
||||
ElementTool(int id, String name, String description, int r, int g, int b, ByteString identifier, VideoBuffer * (*textureGen)(int, int, int) = NULL);
|
||||
virtual ~ElementTool();
|
||||
void Draw(Simulation * sim, Brush const &brush, ui::Point position) override;
|
||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override;
|
||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override;
|
||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override;
|
||||
void Draw(Simulation *, Brush const &, Pos) override;
|
||||
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override;
|
||||
void DrawRect(Simulation *, Brush const &, Pos, Pos) override;
|
||||
void DrawFill(Simulation *, Brush const &, Pos) override;
|
||||
};
|
||||
|
||||
class Element_LIGH_Tool: public ElementTool
|
||||
@ -138,10 +139,10 @@ public:
|
||||
ElementTool(id, name, description, r, g, b, identifier, textureGen)
|
||||
{ }
|
||||
virtual ~Element_LIGH_Tool() { }
|
||||
void Click(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override;
|
||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override { }
|
||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
||||
void Click(Simulation *, Brush const &, Pos) override { }
|
||||
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override;
|
||||
void DrawRect(Simulation *, Brush const &, Pos, Pos) override { }
|
||||
void DrawFill(Simulation *, Brush const &, Pos) override { }
|
||||
};
|
||||
|
||||
class Element_TESC_Tool: public ElementTool
|
||||
@ -151,8 +152,8 @@ public:
|
||||
ElementTool(id, name, description, r, g, b, identifier, textureGen)
|
||||
{ }
|
||||
virtual ~Element_TESC_Tool() {}
|
||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override;
|
||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override;
|
||||
void DrawRect(Simulation *, Brush const &, Pos, Pos) override;
|
||||
void DrawFill(Simulation *, Brush const &, Pos) override;
|
||||
};
|
||||
|
||||
class PlopTool: public ElementTool
|
||||
@ -162,11 +163,11 @@ public:
|
||||
ElementTool(id, name, description, r, g, b, identifier, textureGen)
|
||||
{ }
|
||||
virtual ~PlopTool() { }
|
||||
void Draw(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
||||
void Click(Simulation * sim, Brush const &brush, ui::Point position) override;
|
||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override { }
|
||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override { }
|
||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
||||
void Draw(Simulation *, Brush const &, Pos) override { }
|
||||
void Click(Simulation *, Brush const &, Pos) override;
|
||||
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override { }
|
||||
void DrawRect(Simulation *, Brush const &, Pos, Pos) override { }
|
||||
void DrawFill(Simulation *, Brush const &, Pos) override { }
|
||||
};
|
||||
|
||||
class WallTool: public Tool
|
||||
@ -174,10 +175,10 @@ class WallTool: public Tool
|
||||
public:
|
||||
WallTool(int id, String name, String description, int r, int g, int b, ByteString identifier, VideoBuffer * (*textureGen)(int, int, int) = NULL);
|
||||
virtual ~WallTool();
|
||||
void Draw(Simulation * sim, Brush const &brush, ui::Point position) override;
|
||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override;
|
||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override;
|
||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override;
|
||||
void Draw(Simulation *, Brush const &, Pos) override;
|
||||
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override;
|
||||
void DrawRect(Simulation *, Brush const &, Pos, Pos) override;
|
||||
void DrawFill(Simulation *, Brush const &, Pos) override;
|
||||
};
|
||||
|
||||
class WindTool: public Tool
|
||||
@ -185,8 +186,8 @@ class WindTool: public Tool
|
||||
public:
|
||||
WindTool(int id, String name, String description, int r, int g, int b, ByteString identifier, VideoBuffer * (*textureGen)(int, int, int) = NULL);
|
||||
virtual ~WindTool() { }
|
||||
void Draw(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override;
|
||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override { }
|
||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
||||
void Draw(Simulation *, Brush const &, Pos) override { }
|
||||
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override;
|
||||
void DrawRect(Simulation *, Brush const &, Pos, Pos) override { }
|
||||
void DrawFill(Simulation *, Brush const &, Pos) override { }
|
||||
};
|
||||
|
@ -9,7 +9,7 @@ public:
|
||||
|
||||
std::unique_ptr<unsigned char []> GenerateBitmap() const override
|
||||
{
|
||||
ui::Point size = radius * 2 + 1;
|
||||
ui::Point size = radius * 2 + ui::Point(1, 1);
|
||||
auto bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
|
||||
|
||||
int rx = radius.X;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "Snapshot.h"
|
||||
#include "Air.h"
|
||||
#include "gravity/Gravity.h"
|
||||
#include "common/RasterGeometry.h"
|
||||
#include "common/tpt-rand.h"
|
||||
#include "common/tpt-compat.h"
|
||||
#include "client/GameSave.h"
|
||||
@ -242,52 +243,8 @@ int Simulation::CreateWalls(int x, int y, int rx, int ry, int wall, Brush const
|
||||
|
||||
void Simulation::CreateWallLine(int x1, int y1, int x2, int y2, int rx, int ry, int wall, Brush const *cBrush)
|
||||
{
|
||||
int x, y, dx, dy, sy;
|
||||
bool reverseXY = abs(y2-y1) > abs(x2-x1);
|
||||
float e = 0.0f, de;
|
||||
if (reverseXY)
|
||||
{
|
||||
y = x1;
|
||||
x1 = y1;
|
||||
y1 = y;
|
||||
y = x2;
|
||||
x2 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
if (x1 > x2)
|
||||
{
|
||||
y = x1;
|
||||
x1 = x2;
|
||||
x2 = y;
|
||||
y = y1;
|
||||
y1 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
dx = x2 - x1;
|
||||
dy = abs(y2 - y1);
|
||||
de = dx ? dy/(float)dx : 0.0f;
|
||||
y = y1;
|
||||
sy = (y1<y2) ? 1 : -1;
|
||||
for (x=x1; x<=x2; x++)
|
||||
{
|
||||
if (reverseXY)
|
||||
CreateWalls(y, x, rx, ry, wall, cBrush);
|
||||
else
|
||||
CreateWalls(x, y, rx, ry, wall, cBrush);
|
||||
e += de;
|
||||
if (e >= 0.5f)
|
||||
{
|
||||
y += sy;
|
||||
if ((y1<y2) ? (y<=y2) : (y>=y2))
|
||||
{
|
||||
if (reverseXY)
|
||||
CreateWalls(y, x, rx, ry, wall, cBrush);
|
||||
else
|
||||
CreateWalls(x, y, rx, ry, wall, cBrush);
|
||||
}
|
||||
e -= 1.0f;
|
||||
}
|
||||
}
|
||||
RasterizeLine<true>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||
[=](Vec2<int> p) { CreateWalls(p.X, p.Y, rx, ry, wall, cBrush); });
|
||||
}
|
||||
|
||||
void Simulation::CreateWallBox(int x1, int y1, int x2, int y2, int wall)
|
||||
@ -621,56 +578,12 @@ void Simulation::ApplyDecorationPoint(int positionX, int positionY, int colR, in
|
||||
|
||||
void Simulation::ApplyDecorationLine(int x1, int y1, int x2, int y2, int colR, int colG, int colB, int colA, int mode, Brush const &cBrush)
|
||||
{
|
||||
bool reverseXY = abs(y2-y1) > abs(x2-x1);
|
||||
int x, y, dx, dy, sy, rx = 0, ry = 0;
|
||||
float e = 0.0f, de;
|
||||
|
||||
rx = cBrush.GetRadius().X;
|
||||
ry = cBrush.GetRadius().Y;
|
||||
|
||||
if (reverseXY)
|
||||
{
|
||||
y = x1;
|
||||
x1 = y1;
|
||||
y1 = y;
|
||||
y = x2;
|
||||
x2 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
if (x1 > x2)
|
||||
{
|
||||
y = x1;
|
||||
x1 = x2;
|
||||
x2 = y;
|
||||
y = y1;
|
||||
y1 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
dx = x2 - x1;
|
||||
dy = abs(y2 - y1);
|
||||
de = dx ? dy/(float)dx : 0.0f;
|
||||
y = y1;
|
||||
sy = (y1<y2) ? 1 : -1;
|
||||
for (x=x1; x<=x2; x++)
|
||||
{
|
||||
if (reverseXY)
|
||||
ApplyDecorationPoint(y, x, colR, colG, colB, colA, mode, cBrush);
|
||||
else
|
||||
ApplyDecorationPoint(x, y, colR, colG, colB, colA, mode, cBrush);
|
||||
e += de;
|
||||
if (e >= 0.5f)
|
||||
{
|
||||
y += sy;
|
||||
if (!(rx+ry))
|
||||
{
|
||||
if (reverseXY)
|
||||
ApplyDecorationPoint(y, x, colR, colG, colB, colA, mode, cBrush);
|
||||
else
|
||||
ApplyDecorationPoint(x, y, colR, colG, colB, colA, mode, cBrush);
|
||||
}
|
||||
e -= 1.0f;
|
||||
}
|
||||
}
|
||||
if (cBrush.GetRadius() == Vec2<int>::Zero)
|
||||
RasterizeLine<true>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||
[this, colR, colG, colB, colA, mode, &cBrush](Vec2<int> p) { ApplyDecorationPoint(p.X, p.Y, colR, colG, colB, colA, mode, cBrush); });
|
||||
else
|
||||
RasterizeLine<false>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||
[this, colR, colG, colB, colA, mode, &cBrush](Vec2<int> p) { ApplyDecorationPoint(p.X, p.Y, colR, colG, colB, colA, mode, cBrush); });
|
||||
}
|
||||
|
||||
void Simulation::ApplyDecorationBox(int x1, int y1, int x2, int y2, int colR, int colG, int colB, int colA, int mode)
|
||||
@ -785,52 +698,12 @@ int Simulation::ToolBrush(int positionX, int positionY, int tool, Brush const &c
|
||||
|
||||
void Simulation::ToolLine(int x1, int y1, int x2, int y2, int tool, Brush const &cBrush, float strength)
|
||||
{
|
||||
bool reverseXY = abs(y2-y1) > abs(x2-x1);
|
||||
int x, y, dx, dy, sy, rx = cBrush.GetRadius().X, ry = cBrush.GetRadius().Y;
|
||||
float e = 0.0f, de;
|
||||
if (reverseXY)
|
||||
{
|
||||
y = x1;
|
||||
x1 = y1;
|
||||
y1 = y;
|
||||
y = x2;
|
||||
x2 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
if (x1 > x2)
|
||||
{
|
||||
y = x1;
|
||||
x1 = x2;
|
||||
x2 = y;
|
||||
y = y1;
|
||||
y1 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
dx = x2 - x1;
|
||||
dy = abs(y2 - y1);
|
||||
de = dx ? dy/(float)dx : 0.0f;
|
||||
y = y1;
|
||||
sy = (y1<y2) ? 1 : -1;
|
||||
for (x=x1; x<=x2; x++)
|
||||
{
|
||||
if (reverseXY)
|
||||
ToolBrush(y, x, tool, cBrush, strength);
|
||||
else
|
||||
ToolBrush(x, y, tool, cBrush, strength);
|
||||
e += de;
|
||||
if (e >= 0.5f)
|
||||
{
|
||||
y += sy;
|
||||
if (!(rx+ry) && ((y1<y2) ? (y<=y2) : (y>=y2)))
|
||||
{
|
||||
if (reverseXY)
|
||||
ToolBrush(y, x, tool, cBrush, strength);
|
||||
else
|
||||
ToolBrush(x, y, tool, cBrush, strength);
|
||||
}
|
||||
e -= 1.0f;
|
||||
}
|
||||
}
|
||||
if (cBrush.GetRadius() == Vec2<int>::Zero)
|
||||
RasterizeLine<true>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||
[this, tool, strength, &cBrush](Vec2<int> p) { ToolBrush(p.X, p.Y, tool, cBrush, strength); });
|
||||
else
|
||||
RasterizeLine<false>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||
[this, tool, strength, &cBrush](Vec2<int> p) { ToolBrush(p.X, p.Y, tool, cBrush, strength); });
|
||||
}
|
||||
|
||||
void Simulation::ToolBox(int x1, int y1, int x2, int y2, int tool, float strength)
|
||||
@ -927,52 +800,12 @@ int Simulation::CreateParts(int x, int y, int rx, int ry, int c, int flags)
|
||||
|
||||
void Simulation::CreateLine(int x1, int y1, int x2, int y2, int c, Brush const &cBrush, int flags)
|
||||
{
|
||||
int x, y, dx, dy, sy, rx = cBrush.GetRadius().X, ry = cBrush.GetRadius().Y;
|
||||
bool reverseXY = abs(y2-y1) > abs(x2-x1);
|
||||
float e = 0.0f, de;
|
||||
if (reverseXY)
|
||||
{
|
||||
y = x1;
|
||||
x1 = y1;
|
||||
y1 = y;
|
||||
y = x2;
|
||||
x2 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
if (x1 > x2)
|
||||
{
|
||||
y = x1;
|
||||
x1 = x2;
|
||||
x2 = y;
|
||||
y = y1;
|
||||
y1 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
dx = x2 - x1;
|
||||
dy = abs(y2 - y1);
|
||||
de = dx ? dy/(float)dx : 0.0f;
|
||||
y = y1;
|
||||
sy = (y1<y2) ? 1 : -1;
|
||||
for (x=x1; x<=x2; x++)
|
||||
{
|
||||
if (reverseXY)
|
||||
CreateParts(y, x, c, cBrush, flags);
|
||||
else
|
||||
CreateParts(x, y, c, cBrush, flags);
|
||||
e += de;
|
||||
if (e >= 0.5f)
|
||||
{
|
||||
y += sy;
|
||||
if (!(rx+ry) && ((y1<y2) ? (y<=y2) : (y>=y2)))
|
||||
{
|
||||
if (reverseXY)
|
||||
CreateParts(y, x, c, cBrush, flags);
|
||||
else
|
||||
CreateParts(x, y, c, cBrush, flags);
|
||||
}
|
||||
e -= 1.0f;
|
||||
}
|
||||
}
|
||||
if (cBrush.GetRadius() == Vec2<int>::Zero)
|
||||
RasterizeLine<true>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||
[this, c, flags, &cBrush](Vec2<int> p) { CreateParts(p.X, p.Y, c, cBrush, flags); });
|
||||
else
|
||||
RasterizeLine<false>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||
[this, c, flags, &cBrush](Vec2<int> p) { CreateParts(p.X, p.Y, c, cBrush, flags); });
|
||||
}
|
||||
|
||||
void Simulation::CreateBox(int x1, int y1, int x2, int y2, int c, int flags)
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "SimulationData.h"
|
||||
#include "GOLString.h"
|
||||
#include "client/GameSave.h"
|
||||
#include "common/RasterGeometry.h"
|
||||
#include "common/tpt-compat.h"
|
||||
#include "common/tpt-rand.h"
|
||||
#include "common/tpt-thread-local.h"
|
||||
@ -837,55 +838,10 @@ void Simulation::SetEdgeMode(int newEdgeMode)
|
||||
// Would make sense to move to Editing.cpp but SPRK needs it.
|
||||
void Simulation::CreateLine(int x1, int y1, int x2, int y2, int c)
|
||||
{
|
||||
bool reverseXY = abs(y2-y1) > abs(x2-x1);
|
||||
int x, y, dx, dy, sy;
|
||||
float e, de;
|
||||
int v = ID(c);
|
||||
c = TYP(c);
|
||||
if (reverseXY)
|
||||
{
|
||||
y = x1;
|
||||
x1 = y1;
|
||||
y1 = y;
|
||||
y = x2;
|
||||
x2 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
if (x1 > x2)
|
||||
{
|
||||
y = x1;
|
||||
x1 = x2;
|
||||
x2 = y;
|
||||
y = y1;
|
||||
y1 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
dx = x2 - x1;
|
||||
dy = abs(y2 - y1);
|
||||
e = 0.0f;
|
||||
de = dx ? dy/(float)dx : 0.0f;
|
||||
y = y1;
|
||||
sy = (y1<y2) ? 1 : -1;
|
||||
for (x=x1; x<=x2; x++)
|
||||
{
|
||||
if (reverseXY)
|
||||
create_part(-1, y, x, c, v);
|
||||
else
|
||||
create_part(-1, x, y, c, v);
|
||||
e += de;
|
||||
if (e >= 0.5f)
|
||||
{
|
||||
y += sy;
|
||||
if ((y1<y2) ? (y<=y2) : (y>=y2))
|
||||
{
|
||||
if (reverseXY)
|
||||
create_part(-1, y, x, c, v);
|
||||
else
|
||||
create_part(-1, x, y, c, v);
|
||||
}
|
||||
e -= 1.0f;
|
||||
}
|
||||
}
|
||||
RasterizeLine<true>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||
[=](Vec2<int> p) { create_part(-1, p.X, p.Y, c, v); });
|
||||
}
|
||||
|
||||
void Simulation::orbitalparts_get(int block1, int block2, int resblock1[], int resblock2[])
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "common/RasterGeometry.h"
|
||||
#include "simulation/ElementCommon.h"
|
||||
#include "simulation/Air.h"
|
||||
|
||||
@ -55,65 +56,13 @@ static const auto isInsulator = [](Simulation* a, int b) -> bool {
|
||||
template<class BinaryPredicate>
|
||||
bool CheckLine(Simulation* sim, int x1, int y1, int x2, int y2, BinaryPredicate func)
|
||||
{
|
||||
bool reverseXY = abs(y2-y1) > abs(x2-x1);
|
||||
int x, y, dx, dy, sy;
|
||||
float e, de;
|
||||
if (reverseXY)
|
||||
{
|
||||
y = x1;
|
||||
x1 = y1;
|
||||
y1 = y;
|
||||
y = x2;
|
||||
x2 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
if (x1 > x2)
|
||||
{
|
||||
y = x1;
|
||||
x1 = x2;
|
||||
x2 = y;
|
||||
y = y1;
|
||||
y1 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
dx = x2 - x1;
|
||||
dy = abs(y2 - y1);
|
||||
e = 0.0f;
|
||||
if (dx)
|
||||
de = dy/(float)dx;
|
||||
else
|
||||
de = 0.0f;
|
||||
y = y1;
|
||||
sy = (y1<y2) ? 1 : -1;
|
||||
for (x=x1; x<=x2; x++)
|
||||
{
|
||||
if (reverseXY)
|
||||
bool found = false;
|
||||
RasterizeLine<true>(Vec2<int>(x1, y1), Vec2<int>(x2, y2), [func, sim, &found](Vec2<int> p)
|
||||
{
|
||||
if (func(sim, sim->pmap[x][y])) return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (func(sim, sim->pmap[y][x])) return true;
|
||||
}
|
||||
e += de;
|
||||
if (e >= 0.5f)
|
||||
{
|
||||
y += sy;
|
||||
if ((y1<y2) ? (y<=y2) : (y>=y2))
|
||||
{
|
||||
if (reverseXY)
|
||||
{
|
||||
if (func(sim, sim->pmap[x][y])) return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (func(sim, sim->pmap[y][x])) return true;
|
||||
}
|
||||
}
|
||||
e -= 1.0f;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
if (!found)
|
||||
found = func(sim, sim->pmap[p.Y][p.X]);
|
||||
});
|
||||
return found;
|
||||
}
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS)
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "common/RasterGeometry.h"
|
||||
#include "simulation/ElementCommon.h"
|
||||
|
||||
static int update(UPDATE_FUNC_ARGS);
|
||||
@ -225,68 +226,23 @@ static bool create_LIGH(Simulation * sim, int x, int y, int c, float temp, int l
|
||||
|
||||
static void create_line_par(Simulation * sim, int x1, int y1, int x2, int y2, int c, float temp, int life, int tmp, int tmp2, int i)
|
||||
{
|
||||
bool reverseXY = abs(y2-y1) > abs(x2-x1), back = false;
|
||||
int x, y, dx, dy, Ystep;
|
||||
float e = 0.0f, de;
|
||||
if (reverseXY)
|
||||
{
|
||||
y = x1;
|
||||
x1 = y1;
|
||||
y1 = y;
|
||||
y = x2;
|
||||
x2 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
if (x1 > x2)
|
||||
back = 1;
|
||||
dx = x2 - x1;
|
||||
dy = abs(y2 - y1);
|
||||
if (dx)
|
||||
de = dy/(float)dx;
|
||||
else
|
||||
de = 0.0f;
|
||||
y = y1;
|
||||
Ystep = (y1<y2) ? 1 : -1;
|
||||
if (!back)
|
||||
{
|
||||
for (x = x1; x <= x2; x++)
|
||||
{
|
||||
bool ret;
|
||||
if (reverseXY)
|
||||
ret = create_LIGH(sim, y, x, c, temp, life, tmp, tmp2,x==x2, i);
|
||||
else
|
||||
ret = create_LIGH(sim, x, y, c, temp, life, tmp, tmp2,x==x2, i);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
e += de;
|
||||
if (e >= 0.5f)
|
||||
// force particles to be created in order from (x1,y1) to (x2,y2)
|
||||
bool back = std::abs(x1 - x2) >= std::abs(y2 - y1) ? x1 >= x2 : y1 >= y2;
|
||||
bool done = false;
|
||||
if (back)
|
||||
RasterizeLine<false>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||
[&done, sim, c, temp, life, tmp, tmp2, x2, y2, i] (Vec2<int> p)
|
||||
{
|
||||
y += Ystep;
|
||||
e -= 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!done)
|
||||
done = create_LIGH(sim, p.X, p.Y, c, temp, life, tmp, tmp2, p == Vec2<int>(x2, y2), i);
|
||||
});
|
||||
else
|
||||
{
|
||||
for (x = x1; x >= x2; x--)
|
||||
{
|
||||
bool ret;
|
||||
if (reverseXY)
|
||||
ret = create_LIGH(sim, y, x, c, temp, life, tmp, tmp2,x==x2, i);
|
||||
else
|
||||
ret = create_LIGH(sim, x, y, c, temp, life, tmp, tmp2,x==x2, i);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
e += de;
|
||||
if (e <= -0.5f)
|
||||
RasterizeLine<false>(-Vec2<int>(x1, y1), -Vec2<int>(x2, y2),
|
||||
[&done, sim, c, temp, life, tmp, tmp2, x2, y2, i] (Vec2<int> p)
|
||||
{
|
||||
y += Ystep;
|
||||
e += 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!done)
|
||||
done = create_LIGH(sim, -p.X, -p.Y, c, temp, life, tmp, tmp2, -p == Vec2<int>(x2, y2), i);
|
||||
});
|
||||
}
|
||||
|
||||
static int graphics(GRAPHICS_FUNC_ARGS)
|
||||
|
Reference in New Issue
Block a user