Files
aego/render/culling/culling.go
T
sanspie 17cb5e4291 Stage 2-5: assets, scene/ECS, editor, 3D, and Aego Script
Stage 2: render pipeline and UI toolkit over gpu/platform.
Stage 3: schema registry, asset pipeline + runtime loader, scene graph and ECS.
Stage 4: editor — docking, inspector, scene/game views, play mode, asset browser, console, profiler; 4.5 adds the 3D foundation (mixed 2D/3D spaces, meshes, depth).
Stage 5: Aego Script — compiler (lexer/parser/types/resolver/checker/asm/compiler), bytecode with verifier and register VM, instance runtime, stdlib, native bindings, and editor/CLI integration (aego run/edit/check/test/dump).
2026-10-08 13:17:28 +03:00

51 lines
1.3 KiB
Go

package culling
import (
"aego/core/mathx"
"aego/render/sprite"
)
func Bounds(d *sprite.Draw, pixelsPerUnit float32) mathx.AABB2 {
size := d.WorldSize(pixelsPerUnit)
origin := d.Origin
minX := -origin.X * size.X
minY := -origin.Y * size.Y
maxX := minX + size.X
maxY := minY + size.Y
if d.Rotation == 0 {
return mathx.AABB2{
Min: mathx.Vec2{X: d.Position.X + minX, Y: d.Position.Y + minY},
Max: mathx.Vec2{X: d.Position.X + maxX, Y: d.Position.Y + maxY},
}
}
s, c := mathx.Sin(d.Rotation), mathx.Cos(d.Rotation)
corners := [4]mathx.Vec2{
{X: minX, Y: minY},
{X: maxX, Y: minY},
{X: maxX, Y: maxY},
{X: minX, Y: maxY},
}
lo := mathx.Vec2{X: mathx.Pi * 1e9, Y: mathx.Pi * 1e9}
hi := lo.Neg()
for _, p := range corners {
r := mathx.Vec2{X: p.X*c - p.Y*s + d.Position.X, Y: p.X*s + p.Y*c + d.Position.Y}
lo.X, lo.Y = min(lo.X, r.X), min(lo.Y, r.Y)
hi.X, hi.Y = max(hi.X, r.X), max(hi.Y, r.Y)
}
return mathx.AABB2{Min: lo, Max: hi}
}
func Visible(bounds mathx.AABB2, d *sprite.Draw, pixelsPerUnit float32) bool {
return bounds.Intersects(Bounds(d, pixelsPerUnit))
}
func Cull(visible mathx.AABB2, draws []sprite.Draw, pixelsPerUnit float32, out []uint32) []uint32 {
out = out[:0]
for i := range draws {
if Visible(visible, &draws[i], pixelsPerUnit) {
out = append(out, uint32(i))
}
}
return out
}