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 "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)
|
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)
|
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;
|
RasterizeLine<false>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||||
float e, de;
|
[this](Vec2<int> p) { xor_pixel(p.X, p.Y); });
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::xor_rect(int x, int y, int w, int h)
|
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)
|
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;
|
RasterizeLine<false>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||||
float e, de;
|
[this, r, g, b, a](Vec2<int> p) { blendpixel(p.X, p.Y, r, g, b, a); });
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::drawrect(int x, int y, int w, int h, int r, int g, int b, int 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)
|
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;
|
RasterizeEllipsePoints(Vec2<float>(rx * rx, ry * ry),
|
||||||
if (!rx)
|
[=](Vec2<int> p) { blendpixel(x + p.X, y + p.Y, r, g, b, a); });
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::fillcircle(int x, int y, int rx, int ry, int r, int g, int b, int 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;
|
RasterizeEllipseRows(Vec2<float>(rx * rx, ry * ry), [=](int xLim, int dy)
|
||||||
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++)
|
|
||||||
{
|
{
|
||||||
blendpixel(x+i-rx, y+j-ry, r, g, b, a);
|
for (int dx = -xLim; dx <= xLim; dx++)
|
||||||
if (i != rx)
|
blendpixel(x + dx, y + dy, r, g, b, a);
|
||||||
blendpixel(x-i+rx, y+j-ry, 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)
|
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
|
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);
|
auto bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
|
||||||
if (size == origSize)
|
if (size == origSize)
|
||||||
std::copy(&origBitmap[0], &origBitmap[origSize.X * origSize.Y], &bitmap[0]);
|
std::copy(&origBitmap[0], &origBitmap[origSize.X * origSize.Y], &bitmap[0]);
|
||||||
|
@ -63,7 +63,7 @@ public:
|
|||||||
|
|
||||||
ui::Point GetSize() const
|
ui::Point GetSize() const
|
||||||
{
|
{
|
||||||
return radius * 2 + 1;
|
return radius * 2 + ui::Point(1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui::Point GetRadius() const
|
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);
|
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);
|
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);
|
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];
|
pixel loc = ren->vid[position.X+position.Y*WINDOWW];
|
||||||
if (toolID == DECO_CLEAR)
|
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);
|
DecorationTool(Renderer *ren_, int decoMode, String name, String description, int r, int g, int b, ByteString identifier);
|
||||||
virtual ~DecorationTool();
|
virtual ~DecorationTool();
|
||||||
void Draw(Simulation * sim, Brush const &brush, ui::Point position) override;
|
void Draw(Simulation *, Brush const &, Pos) override;
|
||||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging) override;
|
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging) override;
|
||||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override;
|
void DrawRect(Simulation *, Brush const &, Pos, Pos) override;
|
||||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override;
|
void DrawFill(Simulation *, Brush const &, Pos) override;
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "common/RasterGeometry.h"
|
||||||
#include "Brush.h"
|
#include "Brush.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
@ -15,52 +16,21 @@ public:
|
|||||||
|
|
||||||
std::unique_ptr<unsigned char []> GenerateBitmap() const override
|
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);
|
auto bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
|
||||||
|
|
||||||
int rx = radius.X;
|
std::fill(&bitmap[0], &bitmap[size.X * size.Y], 0);
|
||||||
int ry = radius.Y;
|
float rx = radius.X, ry = radius.Y;
|
||||||
|
if (perfectCircle)
|
||||||
if (!rx)
|
|
||||||
{
|
{
|
||||||
for (int j = 0; j <= 2*ry; j++)
|
rx += 0.5;
|
||||||
{
|
ry += 0.5;
|
||||||
bitmap[j*(size.X)+rx] = 255;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
RasterizeEllipseRows(Vec2<float>(rx * rx, ry * ry), [this, &bitmap, size](int xLim, int y)
|
||||||
{
|
|
||||||
int yTop = ry+1, yBottom, i;
|
|
||||||
for (i = 0; i <= rx; i++)
|
|
||||||
{
|
{
|
||||||
if (perfectCircle)
|
for (int x = -xLim; x <= xLim; x++)
|
||||||
{
|
bitmap[x + radius.X + (y + radius.Y) * size.X] = 0xFF;
|
||||||
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;
|
|
||||||
}
|
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "Tool.h"
|
#include "Tool.h"
|
||||||
|
|
||||||
|
#include "common/RasterGeometry.h"
|
||||||
#include "prefs/GlobalPrefs.h"
|
#include "prefs/GlobalPrefs.h"
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "Format.h"
|
#include "Format.h"
|
||||||
@ -255,7 +256,7 @@ void PropertyTool::OpenWindow(Simulation *sim)
|
|||||||
new PropertyWindow(this, 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)
|
if(position.X<0 || position.X>XRES || position.Y<0 || position.Y>YRES || !validProperty)
|
||||||
return;
|
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)
|
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;
|
if (cBrush.GetRadius() == Pos::Zero)
|
||||||
bool reverseXY = abs(y2-y1) > abs(x2-x1);
|
RasterizeLine<true>(position1, position2, [this, sim, &cBrush](Pos p) { Draw(sim, cBrush, p); });
|
||||||
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;
|
|
||||||
else
|
else
|
||||||
de = 0.0f;
|
RasterizeLine<false>(position1, position2, [this, sim, &cBrush](Pos p) { Draw(sim, cBrush, p); });
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 x1 = position.X, y1 = position.Y, x2 = position2.X, y2 = position2.Y;
|
||||||
int i, j;
|
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 (j=y1; j<=y2; j++)
|
||||||
for (i=x1; i<=x2; i++)
|
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)
|
if (validProperty)
|
||||||
sim->flood_prop(position.X, position.Y, propOffset, propValue, propType);
|
sim->flood_prop(position.X, position.Y, propOffset, propValue, propType);
|
||||||
|
@ -37,17 +37,17 @@ String Tool::GetName() { return toolName; }
|
|||||||
String Tool::GetDescription() { return toolDescription; }
|
String Tool::GetDescription() { return toolDescription; }
|
||||||
Tool::~Tool() {}
|
Tool::~Tool() {}
|
||||||
|
|
||||||
void Tool::Click(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, ui::Point position) {
|
void Tool::Draw(Simulation * sim, Brush const &brush, Pos position) {
|
||||||
sim->ToolBrush(position.X, position.Y, toolID, brush, strength);
|
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);
|
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);
|
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)):
|
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() {}
|
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);
|
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);
|
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);
|
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);
|
sim->FloodParts(position.X, position.Y, toolID, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,10 +76,10 @@ Tool(id, name, description, r, g, b, identifier, textureGen)
|
|||||||
blocky = true;
|
blocky = true;
|
||||||
}
|
}
|
||||||
WallTool::~WallTool() {}
|
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);
|
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 wallX = position1.X/CELL;
|
||||||
int wallY = position1.Y/CELL;
|
int wallY = position1.Y/CELL;
|
||||||
if(dragging == false && toolID == WL_FAN && sim->bmap[wallY][wallX]==WL_FAN)
|
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);
|
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);
|
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)
|
if (toolID != WL_STREAM)
|
||||||
sim->FloodWalls(position.X, position.Y, toolID, -1);
|
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;
|
float strength = dragging?0.01f:0.002f;
|
||||||
strength *= this->strength;
|
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)
|
if (dragging)
|
||||||
sim->CreateParts(position1.X, position1.Y, brush.GetRadius().X, brush.GetRadius().Y, PT_LIGH);
|
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;
|
int radiusInfo = brush.GetRadius().X*4+brush.GetRadius().Y*4+7;
|
||||||
sim->CreateBox(position1.X, position1.Y, position2.X, position2.Y, toolID | PMAPID(radiusInfo));
|
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;
|
int radiusInfo = brush.GetRadius().X*4+brush.GetRadius().Y*4+7;
|
||||||
sim->FloodParts(position.X, position.Y, toolID | PMAPID(radiusInfo), -1);
|
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));
|
sim->create_part(-2, position.X, position.Y, TYP(toolID), ID(toolID));
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "common/Geometry.h"
|
||||||
#include "common/String.h"
|
#include "common/String.h"
|
||||||
#include "gui/interface/Point.h"
|
|
||||||
#include "simulation/StructProperty.h"
|
#include "simulation/StructProperty.h"
|
||||||
|
|
||||||
class Simulation;
|
class Simulation;
|
||||||
@ -10,6 +10,7 @@ class VideoBuffer;
|
|||||||
class Tool
|
class Tool
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
using Pos = Vec2<int>;
|
||||||
VideoBuffer * (*textureGen)(int, int, int);
|
VideoBuffer * (*textureGen)(int, int, int);
|
||||||
int toolID;
|
int toolID;
|
||||||
String toolName;
|
String toolName;
|
||||||
@ -31,11 +32,11 @@ public:
|
|||||||
VideoBuffer * GetTexture(int width, int height);
|
VideoBuffer * GetTexture(int width, int height);
|
||||||
void SetTextureGen(VideoBuffer * (*textureGen)(int, int, int));
|
void SetTextureGen(VideoBuffer * (*textureGen)(int, int, int));
|
||||||
virtual ~Tool();
|
virtual ~Tool();
|
||||||
virtual void Click(Simulation * sim, Brush const &brush, ui::Point position);
|
virtual void Click(Simulation *, Brush const &, Pos);
|
||||||
virtual void Draw(Simulation * sim, Brush const &brush, ui::Point position);
|
virtual void Draw(Simulation *, Brush const &, Pos);
|
||||||
virtual void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false);
|
virtual void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false);
|
||||||
virtual void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2);
|
virtual void DrawRect(Simulation *, Brush const &, Pos, Pos);
|
||||||
virtual void DrawFill(Simulation * sim, Brush const &brush, ui::Point position);
|
virtual void DrawFill(Simulation *, Brush const &, Pos);
|
||||||
};
|
};
|
||||||
|
|
||||||
class GameModel;
|
class GameModel;
|
||||||
@ -51,11 +52,11 @@ public:
|
|||||||
}
|
}
|
||||||
static VideoBuffer * GetIcon(int toolID, int width, int height);
|
static VideoBuffer * GetIcon(int toolID, int width, int height);
|
||||||
virtual ~SignTool() {}
|
virtual ~SignTool() {}
|
||||||
void Click(Simulation * sim, Brush const &brush, ui::Point position) override;
|
void Click(Simulation *, Brush const &, Pos) override;
|
||||||
void Draw(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
void Draw(Simulation *, Brush const &, Pos) override { }
|
||||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override { }
|
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override { }
|
||||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override { }
|
void DrawRect(Simulation *, Brush const &, Pos, Pos) override { }
|
||||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
void DrawFill(Simulation *, Brush const &, Pos) override { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class SampleTool: public Tool
|
class SampleTool: public Tool
|
||||||
@ -69,11 +70,11 @@ public:
|
|||||||
}
|
}
|
||||||
static VideoBuffer * GetIcon(int toolID, int width, int height);
|
static VideoBuffer * GetIcon(int toolID, int width, int height);
|
||||||
virtual ~SampleTool() {}
|
virtual ~SampleTool() {}
|
||||||
void Click(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
void Click(Simulation *, Brush const &, Pos) override { }
|
||||||
void Draw(Simulation * sim, Brush const &brush, ui::Point position) override;
|
void Draw(Simulation *, Brush const &, Pos) override;
|
||||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override { }
|
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override { }
|
||||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override { }
|
void DrawRect(Simulation *, Brush const &, Pos, Pos) override { }
|
||||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
void DrawFill(Simulation *, Brush const &, Pos) override { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class PropertyTool: public Tool
|
class PropertyTool: public Tool
|
||||||
@ -91,14 +92,14 @@ public:
|
|||||||
size_t propOffset;
|
size_t propOffset;
|
||||||
bool validProperty;
|
bool validProperty;
|
||||||
|
|
||||||
void OpenWindow(Simulation *sim);
|
void OpenWindow(Simulation *);
|
||||||
virtual ~PropertyTool() {}
|
virtual ~PropertyTool() {}
|
||||||
virtual void SetProperty(Simulation *sim, ui::Point position);
|
virtual void SetProperty(Simulation *, Pos);
|
||||||
void Click(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
void Click(Simulation *, Brush const &, Pos) override { }
|
||||||
void Draw(Simulation *sim, Brush const &brush, ui::Point position) override;
|
void Draw(Simulation *, Brush const &brush, Pos) override;
|
||||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override;
|
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override;
|
||||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override;
|
void DrawRect(Simulation *, Brush const &, Pos, Pos) override;
|
||||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override;
|
void DrawFill(Simulation *, Brush const &, Pos) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GOLTool: public Tool
|
class GOLTool: public Tool
|
||||||
@ -110,13 +111,13 @@ public:
|
|||||||
gameModel(gameModel)
|
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() {}
|
virtual ~GOLTool() {}
|
||||||
void Click(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
void Click(Simulation *, Brush const &, Pos) override { }
|
||||||
void Draw(Simulation *sim, Brush const &brush, ui::Point position) override { };
|
void Draw(Simulation *, Brush const &brush, Pos) override { };
|
||||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override { };
|
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override { };
|
||||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override { };
|
void DrawRect(Simulation *, Brush const &, Pos, Pos) override { };
|
||||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override { };
|
void DrawFill(Simulation *, Brush const &, Pos) override { };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -125,10 +126,10 @@ class ElementTool: public Tool
|
|||||||
public:
|
public:
|
||||||
ElementTool(int id, String name, String description, int r, int g, int b, ByteString identifier, VideoBuffer * (*textureGen)(int, int, int) = NULL);
|
ElementTool(int id, String name, String description, int r, int g, int b, ByteString identifier, VideoBuffer * (*textureGen)(int, int, int) = NULL);
|
||||||
virtual ~ElementTool();
|
virtual ~ElementTool();
|
||||||
void Draw(Simulation * sim, Brush const &brush, ui::Point position) override;
|
void Draw(Simulation *, Brush const &, Pos) override;
|
||||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override;
|
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override;
|
||||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override;
|
void DrawRect(Simulation *, Brush const &, Pos, Pos) override;
|
||||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override;
|
void DrawFill(Simulation *, Brush const &, Pos) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Element_LIGH_Tool: public ElementTool
|
class Element_LIGH_Tool: public ElementTool
|
||||||
@ -138,10 +139,10 @@ public:
|
|||||||
ElementTool(id, name, description, r, g, b, identifier, textureGen)
|
ElementTool(id, name, description, r, g, b, identifier, textureGen)
|
||||||
{ }
|
{ }
|
||||||
virtual ~Element_LIGH_Tool() { }
|
virtual ~Element_LIGH_Tool() { }
|
||||||
void Click(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
void Click(Simulation *, Brush const &, Pos) override { }
|
||||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override;
|
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override;
|
||||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override { }
|
void DrawRect(Simulation *, Brush const &, Pos, Pos) override { }
|
||||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
void DrawFill(Simulation *, Brush const &, Pos) override { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Element_TESC_Tool: public ElementTool
|
class Element_TESC_Tool: public ElementTool
|
||||||
@ -151,8 +152,8 @@ public:
|
|||||||
ElementTool(id, name, description, r, g, b, identifier, textureGen)
|
ElementTool(id, name, description, r, g, b, identifier, textureGen)
|
||||||
{ }
|
{ }
|
||||||
virtual ~Element_TESC_Tool() {}
|
virtual ~Element_TESC_Tool() {}
|
||||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override;
|
void DrawRect(Simulation *, Brush const &, Pos, Pos) override;
|
||||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override;
|
void DrawFill(Simulation *, Brush const &, Pos) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlopTool: public ElementTool
|
class PlopTool: public ElementTool
|
||||||
@ -162,11 +163,11 @@ public:
|
|||||||
ElementTool(id, name, description, r, g, b, identifier, textureGen)
|
ElementTool(id, name, description, r, g, b, identifier, textureGen)
|
||||||
{ }
|
{ }
|
||||||
virtual ~PlopTool() { }
|
virtual ~PlopTool() { }
|
||||||
void Draw(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
void Draw(Simulation *, Brush const &, Pos) override { }
|
||||||
void Click(Simulation * sim, Brush const &brush, ui::Point position) override;
|
void Click(Simulation *, Brush const &, Pos) override;
|
||||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override { }
|
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override { }
|
||||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override { }
|
void DrawRect(Simulation *, Brush const &, Pos, Pos) override { }
|
||||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
void DrawFill(Simulation *, Brush const &, Pos) override { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class WallTool: public Tool
|
class WallTool: public Tool
|
||||||
@ -174,10 +175,10 @@ class WallTool: public Tool
|
|||||||
public:
|
public:
|
||||||
WallTool(int id, String name, String description, int r, int g, int b, ByteString identifier, VideoBuffer * (*textureGen)(int, int, int) = NULL);
|
WallTool(int id, String name, String description, int r, int g, int b, ByteString identifier, VideoBuffer * (*textureGen)(int, int, int) = NULL);
|
||||||
virtual ~WallTool();
|
virtual ~WallTool();
|
||||||
void Draw(Simulation * sim, Brush const &brush, ui::Point position) override;
|
void Draw(Simulation *, Brush const &, Pos) override;
|
||||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override;
|
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override;
|
||||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override;
|
void DrawRect(Simulation *, Brush const &, Pos, Pos) override;
|
||||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override;
|
void DrawFill(Simulation *, Brush const &, Pos) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WindTool: public Tool
|
class WindTool: public Tool
|
||||||
@ -185,8 +186,8 @@ class WindTool: public Tool
|
|||||||
public:
|
public:
|
||||||
WindTool(int id, String name, String description, int r, int g, int b, ByteString identifier, VideoBuffer * (*textureGen)(int, int, int) = NULL);
|
WindTool(int id, String name, String description, int r, int g, int b, ByteString identifier, VideoBuffer * (*textureGen)(int, int, int) = NULL);
|
||||||
virtual ~WindTool() { }
|
virtual ~WindTool() { }
|
||||||
void Draw(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
void Draw(Simulation *, Brush const &, Pos) override { }
|
||||||
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override;
|
void DrawLine(Simulation *, Brush const &, Pos, Pos, bool dragging = false) override;
|
||||||
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override { }
|
void DrawRect(Simulation *, Brush const &, Pos, Pos) override { }
|
||||||
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override { }
|
void DrawFill(Simulation *, Brush const &, Pos) override { }
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,7 @@ public:
|
|||||||
|
|
||||||
std::unique_ptr<unsigned char []> GenerateBitmap() const override
|
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);
|
auto bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
|
||||||
|
|
||||||
int rx = radius.X;
|
int rx = radius.X;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "Snapshot.h"
|
#include "Snapshot.h"
|
||||||
#include "Air.h"
|
#include "Air.h"
|
||||||
#include "gravity/Gravity.h"
|
#include "gravity/Gravity.h"
|
||||||
|
#include "common/RasterGeometry.h"
|
||||||
#include "common/tpt-rand.h"
|
#include "common/tpt-rand.h"
|
||||||
#include "common/tpt-compat.h"
|
#include "common/tpt-compat.h"
|
||||||
#include "client/GameSave.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)
|
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;
|
RasterizeLine<true>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||||
bool reverseXY = abs(y2-y1) > abs(x2-x1);
|
[=](Vec2<int> p) { CreateWalls(p.X, p.Y, rx, ry, wall, cBrush); });
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Simulation::CreateWallBox(int x1, int y1, int x2, int y2, int wall)
|
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)
|
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);
|
if (cBrush.GetRadius() == Vec2<int>::Zero)
|
||||||
int x, y, dx, dy, sy, rx = 0, ry = 0;
|
RasterizeLine<true>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||||
float e = 0.0f, de;
|
[this, colR, colG, colB, colA, mode, &cBrush](Vec2<int> p) { ApplyDecorationPoint(p.X, p.Y, colR, colG, colB, colA, mode, cBrush); });
|
||||||
|
else
|
||||||
rx = cBrush.GetRadius().X;
|
RasterizeLine<false>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||||
ry = cBrush.GetRadius().Y;
|
[this, colR, colG, colB, colA, mode, &cBrush](Vec2<int> p) { ApplyDecorationPoint(p.X, p.Y, colR, colG, colB, colA, mode, cBrush); });
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Simulation::ApplyDecorationBox(int x1, int y1, int x2, int y2, int colR, int colG, int colB, int colA, int mode)
|
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)
|
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);
|
if (cBrush.GetRadius() == Vec2<int>::Zero)
|
||||||
int x, y, dx, dy, sy, rx = cBrush.GetRadius().X, ry = cBrush.GetRadius().Y;
|
RasterizeLine<true>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||||
float e = 0.0f, de;
|
[this, tool, strength, &cBrush](Vec2<int> p) { ToolBrush(p.X, p.Y, tool, cBrush, strength); });
|
||||||
if (reverseXY)
|
else
|
||||||
{
|
RasterizeLine<false>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||||
y = x1;
|
[this, tool, strength, &cBrush](Vec2<int> p) { ToolBrush(p.X, p.Y, tool, cBrush, strength); });
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Simulation::ToolBox(int x1, int y1, int x2, int y2, int tool, float 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)
|
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;
|
if (cBrush.GetRadius() == Vec2<int>::Zero)
|
||||||
bool reverseXY = abs(y2-y1) > abs(x2-x1);
|
RasterizeLine<true>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||||
float e = 0.0f, de;
|
[this, c, flags, &cBrush](Vec2<int> p) { CreateParts(p.X, p.Y, c, cBrush, flags); });
|
||||||
if (reverseXY)
|
else
|
||||||
{
|
RasterizeLine<false>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||||
y = x1;
|
[this, c, flags, &cBrush](Vec2<int> p) { CreateParts(p.X, p.Y, c, cBrush, flags); });
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Simulation::CreateBox(int x1, int y1, int x2, int y2, int c, int flags)
|
void Simulation::CreateBox(int x1, int y1, int x2, int y2, int c, int flags)
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "SimulationData.h"
|
#include "SimulationData.h"
|
||||||
#include "GOLString.h"
|
#include "GOLString.h"
|
||||||
#include "client/GameSave.h"
|
#include "client/GameSave.h"
|
||||||
|
#include "common/RasterGeometry.h"
|
||||||
#include "common/tpt-compat.h"
|
#include "common/tpt-compat.h"
|
||||||
#include "common/tpt-rand.h"
|
#include "common/tpt-rand.h"
|
||||||
#include "common/tpt-thread-local.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.
|
// 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)
|
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);
|
int v = ID(c);
|
||||||
c = TYP(c);
|
c = TYP(c);
|
||||||
if (reverseXY)
|
RasterizeLine<true>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||||
{
|
[=](Vec2<int> p) { create_part(-1, p.X, p.Y, c, v); });
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Simulation::orbitalparts_get(int block1, int block2, int resblock1[], int resblock2[])
|
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/ElementCommon.h"
|
||||||
#include "simulation/Air.h"
|
#include "simulation/Air.h"
|
||||||
|
|
||||||
@ -55,65 +56,13 @@ static const auto isInsulator = [](Simulation* a, int b) -> bool {
|
|||||||
template<class BinaryPredicate>
|
template<class BinaryPredicate>
|
||||||
bool CheckLine(Simulation* sim, int x1, int y1, int x2, int y2, BinaryPredicate func)
|
bool CheckLine(Simulation* sim, int x1, int y1, int x2, int y2, BinaryPredicate func)
|
||||||
{
|
{
|
||||||
bool reverseXY = abs(y2-y1) > abs(x2-x1);
|
bool found = false;
|
||||||
int x, y, dx, dy, sy;
|
RasterizeLine<true>(Vec2<int>(x1, y1), Vec2<int>(x2, y2), [func, sim, &found](Vec2<int> p)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
if (func(sim, sim->pmap[x][y])) return true;
|
if (!found)
|
||||||
}
|
found = func(sim, sim->pmap[p.Y][p.X]);
|
||||||
else
|
});
|
||||||
{
|
return found;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int update(UPDATE_FUNC_ARGS)
|
static int update(UPDATE_FUNC_ARGS)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "common/RasterGeometry.h"
|
||||||
#include "simulation/ElementCommon.h"
|
#include "simulation/ElementCommon.h"
|
||||||
|
|
||||||
static int update(UPDATE_FUNC_ARGS);
|
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)
|
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;
|
// force particles to be created in order from (x1,y1) to (x2,y2)
|
||||||
int x, y, dx, dy, Ystep;
|
bool back = std::abs(x1 - x2) >= std::abs(y2 - y1) ? x1 >= x2 : y1 >= y2;
|
||||||
float e = 0.0f, de;
|
bool done = false;
|
||||||
if (reverseXY)
|
if (back)
|
||||||
{
|
RasterizeLine<false>(Vec2<int>(x1, y1), Vec2<int>(x2, y2),
|
||||||
y = x1;
|
[&done, sim, c, temp, life, tmp, tmp2, x2, y2, i] (Vec2<int> p)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
y += Ystep;
|
if (!done)
|
||||||
e -= 1.0f;
|
done = create_LIGH(sim, p.X, p.Y, c, temp, life, tmp, tmp2, p == Vec2<int>(x2, y2), i);
|
||||||
}
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
RasterizeLine<false>(-Vec2<int>(x1, y1), -Vec2<int>(x2, y2),
|
||||||
for (x = x1; x >= x2; x--)
|
[&done, sim, c, temp, life, tmp, tmp2, x2, y2, i] (Vec2<int> p)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
y += Ystep;
|
if (!done)
|
||||||
e += 1.0f;
|
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)
|
static int graphics(GRAPHICS_FUNC_ARGS)
|
||||||
|
Reference in New Issue
Block a user