mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-01-16 22:08:28 +01:00
Migrate Rects to (pos, size) representation
This commit is contained in:
parent
2cc5d9bbbb
commit
c2bb777212
@ -121,44 +121,44 @@ void RasterizeEllipseRows(Vec2<float> radiusSquared, F f)
|
||||
}
|
||||
|
||||
// Call f for every point on the boundary of the indicated rectangle (so that
|
||||
// TopLeft and BottomRight are both corners).
|
||||
// pos and BottomRight are both corners).
|
||||
template<typename F>
|
||||
void RasterizeRect(Rect<int> rect, F f)
|
||||
{
|
||||
for (int x = rect.TopLeft.X; x <= rect.BottomRight.X; x++)
|
||||
f(Vec2(x, rect.TopLeft.Y));
|
||||
for (int x = rect.pos.X; x < rect.pos.X + rect.size.X; x++)
|
||||
f(Vec2(x, rect.pos.Y));
|
||||
|
||||
if (rect.TopLeft.Y != rect.BottomRight.Y)
|
||||
for (int x = rect.TopLeft.X; x <= rect.BottomRight.X; x++)
|
||||
f(Vec2(x, rect.BottomRight.Y));
|
||||
if (rect.pos.Y != rect.pos.Y + rect.size.Y - 1)
|
||||
for (int x = rect.pos.X; x < rect.pos.X + rect.size.X; x++)
|
||||
f(Vec2(x, rect.pos.Y + rect.size.Y - 1));
|
||||
|
||||
// corners already drawn
|
||||
for (int y = rect.TopLeft.Y + 1; y <= rect.BottomRight.Y - 1; y++)
|
||||
f(Vec2(rect.TopLeft.X, y));
|
||||
for (int y = rect.pos.Y + 1; y < rect.pos.Y + rect.size.Y - 1; y++)
|
||||
f(Vec2(rect.pos.X, y));
|
||||
|
||||
if (rect.TopLeft.X != rect.BottomRight.X)
|
||||
for (int y = rect.TopLeft.Y + 1; y <= rect.BottomRight.Y - 1; y++)
|
||||
f(Vec2(rect.BottomRight.X, y));
|
||||
if (rect.pos.X != rect.pos.X + rect.size.X - 1)
|
||||
for (int y = rect.pos.Y + 1; y < rect.pos.Y + rect.size.Y - 1; y++)
|
||||
f(Vec2(rect.pos.X + rect.size.X - 1, y));
|
||||
}
|
||||
|
||||
// Call f for every point on the dotted boundary of the indicated rectangle.
|
||||
template<typename F>
|
||||
void RasterizeDottedRect(Rect<int> rect, F f)
|
||||
{
|
||||
for (int x = rect.TopLeft.X; x <= rect.BottomRight.X; x += 2)
|
||||
f(Vec2(x, rect.TopLeft.Y));
|
||||
for (int x = rect.pos.X; x < rect.pos.X + rect.size.X; x += 2)
|
||||
f(Vec2(x, rect.pos.Y));
|
||||
|
||||
int bottomOff = (rect.BottomRight.Y - rect.TopLeft.Y) % 2;
|
||||
if (rect.TopLeft.Y != rect.BottomRight.Y)
|
||||
for (int x = rect.TopLeft.X + bottomOff; x <= rect.BottomRight.X; x += 2)
|
||||
f(Vec2(x, rect.BottomRight.Y));
|
||||
int bottomOff = (rect.pos.Y + rect.size.Y - 1 - rect.pos.Y) % 2;
|
||||
if (rect.pos.Y != rect.pos.Y + rect.size.Y - 1)
|
||||
for (int x = rect.pos.X + bottomOff; x < rect.pos.X + rect.size.X; x += 2)
|
||||
f(Vec2(x, rect.pos.Y + rect.size.Y - 1));
|
||||
|
||||
// corners already drawn
|
||||
for (int y = rect.TopLeft.Y + 1 + 1; y <= rect.BottomRight.Y - 1; y += 2)
|
||||
f(Vec2(rect.TopLeft.X, y));
|
||||
for (int y = rect.pos.Y + 1 + 1; y < rect.pos.Y + rect.size.Y - 1; y += 2)
|
||||
f(Vec2(rect.pos.X, y));
|
||||
|
||||
int leftOff = (rect.BottomRight.X - rect.TopLeft.X + 1) % 2;
|
||||
if (rect.TopLeft.X != rect.BottomRight.X)
|
||||
for (int y = rect.TopLeft.Y + 1 + leftOff; y <= rect.BottomRight.Y - 1; y += 2)
|
||||
f(Vec2(rect.BottomRight.X, y));
|
||||
int leftOff = (rect.pos.X + rect.size.X - 1 - rect.pos.X + 1) % 2;
|
||||
if (rect.pos.X != rect.pos.X + rect.size.X - 1)
|
||||
for (int y = rect.pos.Y + 1 + leftOff; y < rect.pos.Y + rect.size.Y - 1; y += 2)
|
||||
f(Vec2(rect.pos.X + rect.size.X - 1, y));
|
||||
}
|
||||
|
@ -107,8 +107,8 @@ struct Vec2
|
||||
Vec2<T> Clamp(Rect<T> rect) const
|
||||
{
|
||||
return Vec2<T>(
|
||||
std::clamp(X, rect.TopLeft.X, rect.BottomRight.X),
|
||||
std::clamp(Y, rect.TopLeft.Y, rect.BottomRight.Y)
|
||||
std::clamp(X, rect.pos.X, rect.pos.X + rect.size.X - T(1)),
|
||||
std::clamp(Y, rect.pos.Y, rect.pos.Y + rect.size.Y - T(1))
|
||||
);
|
||||
}
|
||||
|
||||
@ -185,8 +185,8 @@ Mat2<T> const Mat2<T, V>::MirrorY = Mat2<T>(1, 0, 0, -1);
|
||||
template<typename T, typename V>
|
||||
Mat2<T> const Mat2<T, V>::CCW = Mat2<T>(0, 1, -1, 0); // reminder: the Y axis points down
|
||||
|
||||
template<typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>>
|
||||
constexpr static inline Rect<T> RectBetween(Vec2<T>, Vec2<T>);
|
||||
template<typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
|
||||
constexpr static inline Rect<T> RectSized(Vec2<T>, Vec2<T>);
|
||||
|
||||
enum IterationDirection
|
||||
{
|
||||
@ -200,16 +200,15 @@ template<typename T, typename>
|
||||
struct Rect
|
||||
{
|
||||
// Inclusive
|
||||
Vec2<T> TopLeft, BottomRight;
|
||||
Vec2<T> pos, size;
|
||||
|
||||
private:
|
||||
constexpr Rect(Vec2<T> topLeft, Vec2<T> bottomRight):
|
||||
TopLeft(topLeft),
|
||||
BottomRight(bottomRight)
|
||||
constexpr Rect(Vec2<T> newPos, Vec2<T> newSize):
|
||||
pos(newPos),
|
||||
size(newSize)
|
||||
{
|
||||
}
|
||||
friend constexpr Rect<T> RectBetween<T>(Vec2<T>, Vec2<T>);
|
||||
|
||||
private:
|
||||
struct end_sentinel
|
||||
{};
|
||||
|
||||
@ -350,48 +349,25 @@ private:
|
||||
public:
|
||||
constexpr bool operator==(Rect other) const
|
||||
{
|
||||
return TopLeft == other.TopLeft && BottomRight == other.BottomRight;
|
||||
return pos == other.pos && size == other.size;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(Rect other) const
|
||||
{
|
||||
return TopLeft != other.TopLeft || BottomRight != other.BottomRight;
|
||||
return pos != other.pos || size != other.size;
|
||||
}
|
||||
|
||||
constexpr explicit operator bool() const
|
||||
{
|
||||
return BottomRight.X >= TopLeft.X && BottomRight.Y >= TopLeft.Y;
|
||||
}
|
||||
|
||||
// Return the smallest rectangle that contains both input rectangles,
|
||||
// **assuming neither are empty**
|
||||
Rect<T> operator|(Rect<T> other) const
|
||||
{
|
||||
return Rect<T>(
|
||||
Vec2<T>(std::min(TopLeft.X, other.TopLeft.X), std::min(TopLeft.Y, other.TopLeft.Y)),
|
||||
Vec2<T>(std::max(BottomRight.X, other.BottomRight.X), std::max(BottomRight.Y, other.BottomRight.Y))
|
||||
);
|
||||
return size.X > 0 && size.Y > 0;
|
||||
}
|
||||
|
||||
// Return the intersection of two rectangles (possibly empty)
|
||||
Rect<T> operator&(Rect<T> other) const
|
||||
{
|
||||
auto rect = Rect<T>(
|
||||
Vec2<T>(std::max(TopLeft.X, other.TopLeft.X), std::max(TopLeft.Y, other.TopLeft.Y)),
|
||||
Vec2<T>(std::min(BottomRight.X, other.BottomRight.X), std::min(BottomRight.Y, other.BottomRight.Y))
|
||||
);
|
||||
return Rect<T>(
|
||||
rect.TopLeft,
|
||||
Vec2<T>(
|
||||
std::max(rect.TopLeft.X - 1, rect.BottomRight.X),
|
||||
std::max(rect.TopLeft.Y - 1, rect.BottomRight.Y)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
inline Rect<T> &operator|=(Rect<T> other)
|
||||
{
|
||||
return *this = *this | other;
|
||||
auto tl = Vec2<T>(std::max(pos.X , other.pos.X ), std::max(pos.Y , other.pos.Y ));
|
||||
auto br1 = Vec2<T>(std::min(pos.X + size.X, other.pos.X + other.size.X), std::min(pos.Y + size.Y, other.pos.Y + other.size.Y));
|
||||
return Rect<T>(tl, br1 - tl);
|
||||
}
|
||||
|
||||
inline Rect<T> &operator&=(Rect<T> other)
|
||||
@ -401,19 +377,13 @@ public:
|
||||
|
||||
constexpr bool Contains(Vec2<T> point) const
|
||||
{
|
||||
return point.X >= TopLeft.X && point.X <= BottomRight.X && point.Y >= TopLeft.Y && point.Y <= BottomRight.Y;
|
||||
}
|
||||
|
||||
template<typename S = T, typename = std::enable_if_t<std::is_integral_v<S>>>
|
||||
inline Vec2<T> Size() const
|
||||
{
|
||||
return BottomRight - TopLeft + Vec2<T>(1, 1);
|
||||
return point.X >= pos.X && point.X < pos.X + size.X && point.Y >= pos.Y && point.Y < pos.Y + size.Y;
|
||||
}
|
||||
|
||||
template<typename S>
|
||||
Rect<decltype(std::declval<T>() + std::declval<S>())> Inset(S delta) const
|
||||
{
|
||||
return Rect<decltype(std::declval<T>() + std::declval<S>())>(TopLeft + Vec2(delta, delta), BottomRight - Vec2(delta, delta));
|
||||
return Rect<decltype(std::declval<T>() + std::declval<S>())>(pos + Vec2(delta, delta), size - Vec2(delta, delta) * S(2));
|
||||
}
|
||||
|
||||
template<IterationDirection D1, IterationDirection D2, typename S = T, typename = std::enable_if_t<std::is_integral_v<T>>>
|
||||
@ -426,10 +396,10 @@ public:
|
||||
);
|
||||
if constexpr (D1 == TOP_TO_BOTTOM || D1 == BOTTOM_TO_TOP)
|
||||
{
|
||||
return range_row_major<D1, D2>{TopLeft.X, TopLeft.Y, BottomRight.X, BottomRight.Y};
|
||||
return range_row_major<D1, D2>{pos.X, pos.Y, pos.X + size.X - T(1), pos.Y + size.Y - T(1)};
|
||||
}
|
||||
else
|
||||
return range_column_major<D1, D2>{TopLeft.X, TopLeft.Y, BottomRight.X, BottomRight.Y};
|
||||
return range_column_major<D1, D2>{pos.X, pos.Y, pos.X + size.X - T(1), pos.Y + size.Y - T(1)};
|
||||
}
|
||||
|
||||
// Use when the order isn't important
|
||||
@ -445,19 +415,19 @@ public:
|
||||
};
|
||||
|
||||
template<typename T, typename>
|
||||
constexpr inline Rect<T> RectSized(Vec2<T> pos, Vec2<T> size)
|
||||
{
|
||||
return Rect<T>(pos, size);
|
||||
}
|
||||
|
||||
template<typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>>
|
||||
constexpr inline Rect<T> RectBetween(Vec2<T> topLeft, Vec2<T> bottomRight)
|
||||
{
|
||||
return Rect<T>(topLeft, bottomRight);
|
||||
return RectSized(topLeft, bottomRight - topLeft + Vec2<T>(1, 1));
|
||||
}
|
||||
|
||||
template<typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>>
|
||||
constexpr inline Rect<T> RectAt(Vec2<T> pos)
|
||||
{
|
||||
return RectBetween<T>(pos, pos);
|
||||
}
|
||||
|
||||
template<typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
|
||||
constexpr inline Rect<T> RectSized(Vec2<T> topLeft, Vec2<T> dimen)
|
||||
{
|
||||
return RectBetween<T>(topLeft, topLeft + dimen - Vec2<T>(1, 1));
|
||||
return RectSized(pos, Vec2<T>(1, 1));
|
||||
}
|
||||
|
@ -36,10 +36,10 @@ void VideoBuffer::Crop(Rect<int> rect)
|
||||
if (rect == Size().OriginRect())
|
||||
return;
|
||||
|
||||
PlaneAdapter<std::vector<pixel> &> newVideo(rect.Size(), std::in_place, video.Base);
|
||||
PlaneAdapter<std::vector<pixel> &> newVideo(rect.size, std::in_place, video.Base);
|
||||
for (auto y = 0; y < newVideo.Size().Y; y++)
|
||||
std::copy_n(
|
||||
video.RowIterator(rect.TopLeft + Vec2(0, y)),
|
||||
video.RowIterator(rect.pos + Vec2(0, y)),
|
||||
newVideo.Size().X,
|
||||
newVideo.RowIterator(Vec2(0, y))
|
||||
);
|
||||
|
@ -135,8 +135,8 @@ void RasterDrawMethods<Derived>::DrawFilledRect(Rect<int> rect, RGB<uint8_t> col
|
||||
pixel packed = colour.Pack();
|
||||
auto &video = static_cast<Derived &>(*this).video;
|
||||
if (rect)
|
||||
for (int y = rect.TopLeft.Y; y <= rect.BottomRight.Y; y++)
|
||||
std::fill_n(video.RowIterator(Vec2(rect.TopLeft.X, y)), rect.Size().X, packed);
|
||||
for (int y = rect.pos.Y; y < rect.pos.Y + rect.size.Y; y++)
|
||||
std::fill_n(video.RowIterator(Vec2(rect.pos.X, y)), rect.size.X, packed);
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
@ -166,22 +166,22 @@ void RasterDrawMethods<Derived>::BlendFilledEllipse(Vec2<int> center, Vec2<int>
|
||||
template<typename Derived>
|
||||
void RasterDrawMethods<Derived>::BlendImage(pixel const *data, uint8_t alpha, Rect<int> rect)
|
||||
{
|
||||
BlendImage(data, alpha, rect, rect.Size().X);
|
||||
BlendImage(data, alpha, rect, rect.size.X);
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
void RasterDrawMethods<Derived>::BlendImage(pixel const *data, uint8_t alpha, Rect<int> rect, size_t rowStride)
|
||||
{
|
||||
auto origin = rect.TopLeft;
|
||||
auto origin = rect.pos;
|
||||
rect &= clipRect();
|
||||
if (alpha == 0xFF)
|
||||
{
|
||||
auto &video = static_cast<Derived &>(*this).video;
|
||||
for (int y = rect.TopLeft.Y; y <= rect.BottomRight.Y; y++)
|
||||
for (int y = rect.pos.Y; y < rect.pos.Y + rect.size.Y; y++)
|
||||
std::copy_n(
|
||||
data + (rect.TopLeft.X - origin.X) + (y - origin.Y) * rowStride,
|
||||
rect.Size().X,
|
||||
video.RowIterator(Vec2(rect.TopLeft.X, y))
|
||||
data + (rect.pos.X - origin.X) + (y - origin.Y) * rowStride,
|
||||
rect.size.X,
|
||||
video.RowIterator(Vec2(rect.pos.X, y))
|
||||
);
|
||||
}
|
||||
else
|
||||
@ -197,13 +197,13 @@ void RasterDrawMethods<Derived>::BlendImage(pixel const *data, uint8_t alpha, Re
|
||||
template<typename Derived>
|
||||
void RasterDrawMethods<Derived>::XorImage(unsigned char const *data, Rect<int> rect)
|
||||
{
|
||||
XorImage(data, rect, rect.Size().X);
|
||||
XorImage(data, rect, rect.size.X);
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
void RasterDrawMethods<Derived>::XorImage(unsigned char const *data, Rect<int> rect, size_t rowStride)
|
||||
{
|
||||
auto origin = rect.TopLeft;
|
||||
auto origin = rect.pos;
|
||||
rect &= clipRect();
|
||||
for (auto pos : rect)
|
||||
if (data[(pos.X - origin.X) + (pos.Y - origin.Y) * rowStride])
|
||||
@ -213,13 +213,13 @@ void RasterDrawMethods<Derived>::XorImage(unsigned char const *data, Rect<int> r
|
||||
template<typename Derived>
|
||||
void RasterDrawMethods<Derived>::BlendRGBAImage(pixel_rgba const *data, Rect<int> rect)
|
||||
{
|
||||
BlendRGBAImage(data, rect, rect.Size().X);
|
||||
BlendRGBAImage(data, rect, rect.size.X);
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
void RasterDrawMethods<Derived>::BlendRGBAImage(pixel_rgba const *data, Rect<int> rect, size_t rowStride)
|
||||
{
|
||||
auto origin = rect.TopLeft;
|
||||
auto origin = rect.pos;
|
||||
rect &= clipRect();
|
||||
for (auto pos : rect)
|
||||
{
|
||||
|
@ -50,7 +50,7 @@ void ToolButton::Draw(const ui::Point& screenPos)
|
||||
{
|
||||
Graphics * g = GetGraphics();
|
||||
auto rect = ClipRect;
|
||||
if (ClipRect.Size().X && ClipRect.Size().Y)
|
||||
if (ClipRect.size.X && ClipRect.size.Y)
|
||||
g->SwapClipRect(rect); // old cliprect is now in rect
|
||||
|
||||
int totalColour = Appearance.BackgroundInactive.Blue + (3*Appearance.BackgroundInactive.Green) + (2*Appearance.BackgroundInactive.Red);
|
||||
@ -87,7 +87,7 @@ void ToolButton::Draw(const ui::Point& screenPos)
|
||||
g->BlendText(screenPos + textPosition, buttonDisplayText, 0x000000_rgb .WithAlpha(255));
|
||||
}
|
||||
|
||||
if (ClipRect.Size().X && ClipRect.Size().Y)
|
||||
if (ClipRect.size.X && ClipRect.size.Y)
|
||||
g->SwapClipRect(rect); // apply old clip rect
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ void Panel::Draw(const Point& screenPos)
|
||||
//check if the component is in the screen, draw if it is
|
||||
if (rect & Size.OriginRect())
|
||||
{
|
||||
child->Draw(screenPos + rect.TopLeft);
|
||||
child->Draw(screenPos + rect.pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ void ProgressBar::Draw(const Point &screenPos)
|
||||
g->DrawRect(RectSized(screenPos, Size), 0xFFFFFF_rgb);
|
||||
auto inner = RectSized(screenPos + Vec2{ 2, 2 }, Size - Vec2{ 4, 4 });
|
||||
auto drawContent = [this, screenPos, g, inner](int beginX, int endX, ui::Colour bgColour, ui::Colour textColour) {
|
||||
auto clip = RectSized(inner.TopLeft + Vec2{ beginX, 0 }, Vec2{ endX - beginX, inner.Size().Y }) & g->GetClipRect();
|
||||
auto clip = RectSized(inner.pos + Vec2{ beginX, 0 }, Vec2{ endX - beginX, inner.size.Y }) & g->GetClipRect();
|
||||
g->SwapClipRect(clip);
|
||||
if (bgColour.Alpha)
|
||||
{
|
||||
@ -58,18 +58,18 @@ void ProgressBar::Draw(const Point &screenPos)
|
||||
}, progressStatus, textColour);
|
||||
g->SwapClipRect(clip);
|
||||
};
|
||||
drawContent(0, inner.Size().X, 0x000000_rgb .WithAlpha(0), 0xFFFFFF_rgb .WithAlpha(255));
|
||||
drawContent(0, inner.size.X, 0x000000_rgb .WithAlpha(0), 0xFFFFFF_rgb .WithAlpha(255));
|
||||
if (progress == -1)
|
||||
{
|
||||
constexpr auto size = 40;
|
||||
auto pos = int(inner.Size().X * intermediatePos / 100);
|
||||
auto pos = int(inner.size.X * intermediatePos / 100);
|
||||
drawContent(pos, pos + size, style::Colour::WarningTitle, 0x000000_rgb .WithAlpha(255));
|
||||
pos -= inner.Size().X;
|
||||
pos -= inner.size.X;
|
||||
drawContent(pos, pos + size, style::Colour::WarningTitle, 0x000000_rgb .WithAlpha(255));
|
||||
}
|
||||
else
|
||||
{
|
||||
drawContent(0, inner.Size().X * progress / 100, style::Colour::WarningTitle, 0x000000_rgb .WithAlpha(255));
|
||||
drawContent(0, inner.size.X * progress / 100, style::Colour::WarningTitle, 0x000000_rgb .WithAlpha(255));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ void Window::DoDraw()
|
||||
{
|
||||
auto rect = RectSized(Position + child->Position, child->Size);
|
||||
if (AllowExclusiveDrawing || bool(rect & GetGraphics()->Size().OriginRect()))
|
||||
child->Draw(rect.TopLeft);
|
||||
child->Draw(rect.pos);
|
||||
}
|
||||
};
|
||||
for (auto child : Components)
|
||||
|
@ -261,10 +261,10 @@ static int setClipRect(lua_State *L)
|
||||
int h = luaL_optinteger(L, 4, WINDOWH);
|
||||
auto rect = RectSized(Vec2(x, y), Vec2(w, h));
|
||||
lsi->g->SwapClipRect(rect);
|
||||
lua_pushinteger(L, rect.TopLeft.X);
|
||||
lua_pushinteger(L, rect.TopLeft.Y);
|
||||
lua_pushinteger(L, rect.Size().X);
|
||||
lua_pushinteger(L, rect.Size().Y);
|
||||
lua_pushinteger(L, rect.pos.X);
|
||||
lua_pushinteger(L, rect.pos.Y);
|
||||
lua_pushinteger(L, rect.size.X);
|
||||
lua_pushinteger(L, rect.size.Y);
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
@ -85,10 +85,10 @@ void Simulation::Restore(const Snapshot &snap)
|
||||
void Simulation::clear_area(int area_x, int area_y, int area_w, int area_h)
|
||||
{
|
||||
auto intersection = RES.OriginRect() & RectSized(Vec2{ area_x, area_y }, Vec2{ area_w, area_h });
|
||||
area_x = intersection.TopLeft.X;
|
||||
area_y = intersection.TopLeft.Y;
|
||||
area_w = intersection.Size().X;
|
||||
area_h = intersection.Size().Y;
|
||||
area_x = intersection.pos.X;
|
||||
area_y = intersection.pos.Y;
|
||||
area_w = intersection.size.X;
|
||||
area_h = intersection.size.Y;
|
||||
float fx = area_x-.5f, fy = area_y-.5f;
|
||||
for (int i = 0; i <= parts_lastActiveIndex; i++)
|
||||
{
|
||||
|
@ -53,20 +53,20 @@ void Simulation::Load(const GameSave *save, bool includePressure, Vec2<int> bloc
|
||||
std::sort(existingParticles.begin(), existingParticles.end(), [](const auto &lhs, const auto &rhs) {
|
||||
return std::tie(lhs.pos.Y, lhs.pos.X) < std::tie(rhs.pos.Y, rhs.pos.X);
|
||||
});
|
||||
PlaneAdapter<std::vector<size_t>> existingParticleIndices(pasteArea.Size(), existingParticles.size());
|
||||
PlaneAdapter<std::vector<size_t>> existingParticleIndices(pasteArea.size, existingParticles.size());
|
||||
{
|
||||
auto lastPos = Vec2<int>{ -1, -1 }; // not a valid pos in existingParticles
|
||||
for (auto it = existingParticles.begin(); it != existingParticles.end(); ++it)
|
||||
{
|
||||
if (lastPos != it->pos)
|
||||
{
|
||||
existingParticleIndices[it->pos - pasteArea.TopLeft] = it - existingParticles.begin();
|
||||
existingParticleIndices[it->pos - pasteArea.pos] = it - existingParticles.begin();
|
||||
lastPos = it->pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
auto removeExistingParticles = [this, pasteArea, &existingParticles, &existingParticleIndices](Vec2<int> p) {
|
||||
auto rp = p - pasteArea.TopLeft;
|
||||
auto rp = p - pasteArea.pos;
|
||||
if (existingParticleIndices.Size().OriginRect().Contains(rp))
|
||||
{
|
||||
auto index = existingParticleIndices[rp];
|
||||
@ -312,10 +312,10 @@ void Simulation::Load(const GameSave *save, bool includePressure, Vec2<int> bloc
|
||||
|
||||
std::unique_ptr<GameSave> Simulation::Save(bool includePressure, Rect<int> partR) // particle coordinates
|
||||
{
|
||||
auto blockR = RectBetween(partR.TopLeft / CELL, partR.BottomRight / CELL);
|
||||
auto blockP = blockR.TopLeft;
|
||||
auto blockR = RectSized(partR.pos / CELL, partR.size / CELL);
|
||||
auto blockP = blockR.pos;
|
||||
|
||||
auto newSave = std::make_unique<GameSave>(blockR.Size());
|
||||
auto newSave = std::make_unique<GameSave>(blockR.size);
|
||||
newSave->frameCount = frameCount;
|
||||
newSave->rngState = rng.state();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user