std::vector<ImageData> SpriteImporter::splitImagesInGrid(const std::vector<ImageData>& images, Vector2i grid) { std::vector<ImageData> result; for (auto& src: images) { auto imgSize = src.img->getSize(); int nX = imgSize.x / grid.x; int nY = imgSize.y / grid.y; for (int y = 0; y < nY; ++y) { for (int x = 0; x < nX; ++x) { auto img = std::make_unique<Image>(Image::Format::RGBA, grid); img->blitFrom(Vector2i(), *src.img, Rect4i(Vector2i(x, y) * grid, grid.x, grid.y)); Rect4i trimRect = img->getTrimRect(); if (trimRect.getWidth() > 0 && trimRect.getHeight() > 0) { result.emplace_back(); auto& dst = result.back(); String suffix = "_" + toString(x) + "_" + toString(y); dst.duration = src.duration; dst.frameNumber = src.frameNumber; dst.filenames.emplace_back(src.filenames.at(0) + suffix); dst.sequenceName = src.sequenceName + suffix; dst.img = std::move(img); dst.clip = Rect4i({}, grid); } } } } return result; }
RectangleSpatialChecker::QueryResults RectangleSpatialChecker::query(Rect4i rect) { QueryResults results; results.n = 0; if (sweep > 0x7FFFFFFF) { resetSweep(); } sweep++; // This will work as a poor man's bloom filter int resultMask = 0; Vector2i p1 = pointToCell(rect.getTopLeft()); Vector2i p2 = pointToCell(rect.getBottomRight()); int x0 = p1.x; int x1 = p2.x; int y0 = p1.y; int y1 = p2.y; for (int y = y0; y <= y1; y++) { for (int x = x0; x <= x1; x++) { // Go through each rect in each grid element auto& vec = getGridCell(x, y); const size_t n = vec.size(); for (size_t i = 0; i < n; i++) { Entry& e = vec[i]; // Check if they intersect if (e.rect.overlaps(rect)) { // Check if it's already in the buffer if ((resultMask & e.hashMask) != 0) { for (size_t j = 0; j < results.n; j++) { if (resultsBuffer[j] == e.data) { goto endOfCheckLoop; // Oh yeah, baby. I went there. } } } // Hash it in the mask resultMask |= e.hashMask; // Insert into the buffer if (results.n < resultsBuffer.size()) { resultsBuffer[results.n] = e.data; } else { resultsBuffer.push_back(e.data); } results.n++; endOfCheckLoop:; } } } } results.results = resultsBuffer.data(); return results; }
void DX11Painter::setClip(Rect4i clip, bool enable) { if (enable) { scissorRaster->bind(video); D3D11_RECT rect; rect.top = clip.getTop(); rect.bottom = clip.getBottom(); rect.left = clip.getLeft(); rect.right = clip.getRight(); video.getDeviceContext().RSSetScissorRects(1, &rect); } else { normalRaster->bind(video); } }
void roundMaskRect(Rect4i & r, const Rect4i & maxRect, int unit) { //Increase width as necessary int remainder = unit - (r.width() % unit); if (remainder != 0) { int dist1 = r.x1 - maxRect.x1; int dist2 = maxRect.x2 - r.x2; //do we have enough room to expand? if (remainder <= (dist1 + dist2)) { dist1 = MIN(dist1, remainder); r.x1 -= dist1; remainder -= dist1; dist2 = MIN(dist2, remainder); r.x2 += dist2; } } //Increase height as necessary remainder = unit - (r.height() % unit); if (remainder != 0) { int dist1 = r.y1 - maxRect.y1; int dist2 = maxRect.y2 - r.y2; //do we have enough room to expand? if (remainder <= (dist1 + dist2)) { dist1 = MIN(dist1, remainder); r.y1 -= dist1; remainder -= dist1; dist2 = MIN(dist2, remainder); r.y2 += dist2; } } }
bool RectangleSpatialChecker::updateData(Entry& entry, Rect4i prev, Rect4i next) { if (prev == next) { return false; // Nothing to do here } int x0, x1, y0, y1; x0 = y0 = std::numeric_limits<int>::max(); x1 = y1 = std::numeric_limits<int>::lowest(); Rect4i addRect; Rect4i delRect; bool hasAdd = false; bool hasDel = false; if (prev.getWidth() > 0 && prev.getHeight() > 0) { Vector2i p1 = pointToCell(prev.getTopLeft()); Vector2i p2 = pointToCell(prev.getBottomRight()); delRect = Rect4i(p1, p2); hasDel = true; x0 = p1.x; x1 = p2.x; y0 = p1.y; y1 = p2.y; } if (next.getWidth() > 0 && next.getHeight() > 0) { Vector2i p1 = pointToCell(next.getTopLeft()); Vector2i p2 = pointToCell(next.getBottomRight()); addRect = Rect4i(p1, p2); hasAdd = true; x0 = std::min(x0, p1.x); x1 = std::max(x1, p2.x); y0 = std::min(y0, p1.y); y1 = std::max(y1, p2.y); } for (int y = y0; y <= y1; y++) { for (int x = x0; x <= x1; x++) { Vector2i p(x, y); bool removeHere = hasDel && delRect.isInside(p); bool addHere = hasAdd && addRect.isInside(p); auto& contents = getGridCell(x, y); if (addHere && removeHere) { // Find existing, then update it with new rect for (size_t i = 0; i < contents.size(); i++) { if (contents[i].data == entry.data) { contents[i].rect = next; break; } } } else if (removeHere) { // Remove //int removed = 0; for (size_t i = 0; i < contents.size(); i++) { if (contents[i].data == entry.data) { if (i != contents.size() - 1) { std::swap(contents[i], contents[contents.size() - 1]); } contents.pop_back(); break; // Safe to break because there should only ever be one copy of each object in each cell } } } else if (addHere) { // Insert, making sure to update rect to new value, since "entry" is still outdated contents.push_back(entry); contents.back().rect = next; } } } // Update the main entry itself entry.rect = next; return true; }
Vector2i SystemSDL::getCenteredWindow(Vector2i size, int screen) const { Rect4i rect = getDisplayRect(screen); return rect.getTopLeft() + (rect.getSize() - size) / 2; }