@@ -371,6 +371,8 @@ static Bool distCalcProc_BoundaryAndBoundary_2D(const Coord3D *posA, const Objec
371371static Bool distCalcProc_CenterAndCenter_3D (const Coord3D *posA, const Object *objA, const Coord3D *posB, const Object *objB, Real& abDistSqr, Coord3D& abVec, Real maxDistSqr);
372372static Bool distCalcProc_BoundaryAndBoundary_3D (const Coord3D *posA, const Object *objA, const Coord3D *posB, const Object *objB, Real& abDistSqr, Coord3D& abVec, Real maxDistSqr);
373373
374+ static Bool doesCircleOverlapCell (Real centerX, Real centerY, Real radius, Real cellX, Real cellY, Real cellSize);
375+
374376// -----------------------------------------------------------------------------
375377inline void projectCoord3D (Coord3D *coord, const Coord3D *unitDir, Real dist)
376378{
@@ -1878,6 +1880,43 @@ void PartitionData::doCircleFill(
18781880 }
18791881}
18801882
1883+ static Bool doesCircleOverlapCell (Real centerX, Real centerY, Real radius, Real cellX, Real cellY, Real cellSize)
1884+ {
1885+ Real closestX = std::max (cellX, std::min (centerX, cellX + cellSize));
1886+ Real closestY = std::max (cellY, std::min (centerY, cellY + cellSize));
1887+ Real distX = centerX - closestX;
1888+ Real distY = centerY - closestY;
1889+
1890+ return (sqr (distX) + sqr (distY)) < sqr (radius);
1891+ }
1892+
1893+ void PartitionData::doCircleFillPrecise (Real centerX, Real centerY, Real radius)
1894+ {
1895+ Int minCellX, minCellY, maxCellX, maxCellY;
1896+ ThePartitionManager->worldToCell (centerX - radius, centerY - radius, &minCellX, &minCellY);
1897+ ThePartitionManager->worldToCell (centerX + radius, centerY + radius, &maxCellX, &maxCellY);
1898+
1899+ Real cellSize = ThePartitionManager->getCellSize ();
1900+
1901+ for (Int x = minCellX; x <= maxCellX; ++x)
1902+ {
1903+ for (Int y = minCellY; y <= maxCellY; ++y)
1904+ {
1905+ Real cellWorldX = x * cellSize;
1906+ Real cellWorldY = y * cellSize;
1907+
1908+ if (doesCircleOverlapCell (centerX, centerY, radius, cellWorldX, cellWorldY, cellSize))
1909+ {
1910+ PartitionCell* cell = ThePartitionManager->getCellAt (x, y);
1911+ if (cell)
1912+ {
1913+ addSubPixToCoverage (cell);
1914+ }
1915+ }
1916+ }
1917+ }
1918+ }
1919+
18811920// -----------------------------------------------------------------------------
18821921void PartitionData::doSmallFill (
18831922 Real centerX,
@@ -2079,7 +2118,13 @@ void PartitionData::updateCellsTouched()
20792118 case GEOMETRY_SPHERE :
20802119 case GEOMETRY_CYLINDER :
20812120 {
2121+ #if RETAIL_COMPATIBLE_CRC || RETAIL_COMPATIBLE_CIRCLE_FILL_ALGORITHM
20822122 doCircleFill (pos.x , pos.y , majorRadius);
2123+ #else
2124+ // TheSuperHackers @bugfix Stubbjax 29/01/2026 Use precise circle fill to improve
2125+ // collision accuracy, most notably for objects with geometry radii >= 20 and < 40.
2126+ doCircleFillPrecise (pos.x , pos.y , majorRadius);
2127+ #endif
20832128 break ;
20842129 }
20852130
0 commit comments