themes and styles

This commit is contained in:
IliaDenisov
2026-03-08 15:31:17 +02:00
parent e37a67bc99
commit 1c2fc30127
39 changed files with 2693 additions and 199 deletions
+17 -16
View File
@@ -1,7 +1,7 @@
package world
// drawCirclesFromPlan executes a circles-only draw from an already built render plan.
func drawCirclesFromPlan(drawer PrimitiveDrawer, plan RenderPlan, worldW, worldH int, allowWrap bool) {
func drawCirclesFromPlan(drawer PrimitiveDrawer, plan RenderPlan, worldW, worldH int, allowWrap bool, circleRadiusScaleFp int) {
for _, td := range plan.Tiles {
if td.ClipW <= 0 || td.ClipH <= 0 {
continue
@@ -30,13 +30,14 @@ func drawCirclesFromPlan(drawer PrimitiveDrawer, plan RenderPlan, worldW, worldH
for _, c := range circles {
var shifts []wrapShift
effRadius := circleRadiusEffFp(c.Radius, circleRadiusScaleFp)
if allowWrap {
shifts = circleWrapShifts(c, worldW, worldH)
shifts = circleWrapShifts(c.X, c.Y, effRadius, worldW, worldH)
} else {
shifts = []wrapShift{{dx: 0, dy: 0}}
}
for _, s := range shifts {
if circleCopyIntersectsTile(c, s.dx, s.dy, td.Tile, worldW, worldH) {
if circleCopyIntersectsTile(c.X, c.Y, effRadius, s.dx, s.dy, td.Tile, worldW, worldH) {
copiesToDraw = append(copiesToDraw, circleCopy{c: c, dx: s.dx, dy: s.dy})
}
}
@@ -75,27 +76,27 @@ type wrapShift struct {
// circleWrapShifts returns 1..4 wrap shifts (multiples of worldW/worldH) required to render
// all torus copies of the circle inside the canonical world domain.
// The (0,0) shift is always present.
func circleWrapShifts(c Circle, worldW, worldH int) []wrapShift {
func circleWrapShifts(cx, cy, radiusFp, worldW, worldH int) []wrapShift {
// If radius covers the whole axis, additional copies are not useful.
// (One copy already covers everything under any reasonable clip.)
if c.Radius >= worldW || c.Radius >= worldH {
if radiusFp >= worldW || radiusFp >= worldH {
return []wrapShift{{dx: 0, dy: 0}}
}
xShifts := []int{0}
yShifts := []int{0}
if c.X+c.Radius >= worldW {
if cx+radiusFp >= worldW {
xShifts = append(xShifts, -worldW)
}
if c.X-c.Radius < 0 {
if cx-radiusFp < 0 {
xShifts = append(xShifts, worldW)
}
if c.Y+c.Radius >= worldH {
if cy+radiusFp >= worldH {
yShifts = append(yShifts, -worldH)
}
if c.Y-c.Radius < 0 {
if cy-radiusFp < 0 {
yShifts = append(yShifts, worldH)
}
@@ -110,7 +111,7 @@ func circleWrapShifts(c Circle, worldW, worldH int) []wrapShift {
// circleCopyIntersectsTile checks whether the circle copy (shifted by dx/dy) intersects the tile segment.
// We use the tile's unwrapped segment bounds: [offset+rect.min, offset+rect.max) per axis.
func circleCopyIntersectsTile(c Circle, dx, dy int, tile WorldTile, worldW, worldH int) bool {
func circleCopyIntersectsTile(cx, cy, radiusFp, dx, dy int, tile WorldTile, worldW, worldH int) bool {
// Unwrapped tile segment bounds.
segMinX := tile.OffsetX + tile.Rect.minX
segMaxX := tile.OffsetX + tile.Rect.maxX
@@ -118,13 +119,13 @@ func circleCopyIntersectsTile(c Circle, dx, dy int, tile WorldTile, worldW, worl
segMaxY := tile.OffsetY + tile.Rect.maxY
// Circle bbox in the same unwrapped space (apply shift + tile offset).
cx := c.X + tile.OffsetX + dx
cy := c.Y + tile.OffsetY + dy
cx = cx + tile.OffsetX + dx
cy = cy + tile.OffsetY + dy
minX := cx - c.Radius
maxX := cx + c.Radius
minY := cy - c.Radius
maxY := cy + c.Radius
minX := cx - radiusFp
maxX := cx + radiusFp
minY := cy - radiusFp
maxY := cy + radiusFp
// Treat bbox as half-open for intersection checks.
if maxX <= segMinX || minX >= segMaxX || maxY <= segMinY || minY >= segMaxY {