more small tidyups

This commit is contained in:
Josh Deprez 2021-09-20 15:03:33 +10:00
parent a9d6c8827f
commit 951b38271f
2 changed files with 14 additions and 16 deletions

View file

@ -11,8 +11,8 @@ import (
// DrawDAG is a DrawLayer that organises DrawBoxer descendants in a directed // DrawDAG is a DrawLayer that organises DrawBoxer descendants in a directed
// acyclic graph (DAG), in order to draw them according to ordering constraints. // acyclic graph (DAG), in order to draw them according to ordering constraints.
// It combines a DAG with a spatial index used when adding new vertices // It combines a DAG with a spatial index used when updating vertices to reduce
// in order to reduce the number of tests between components. // the number of tests between components.
type DrawDAG struct { type DrawDAG struct {
ChunkSize int ChunkSize int
Components []interface{} Components []interface{}
@ -22,8 +22,7 @@ type DrawDAG struct {
boxCache map[DrawBoxer]geom.Box boxCache map[DrawBoxer]geom.Box
chunks map[image.Point]drawerSet // chunk coord -> drawers with bounding rects intersecting chunk chunks map[image.Point]drawerSet // chunk coord -> drawers with bounding rects intersecting chunk
chunksRev map[DrawBoxer]image.Rectangle // comopnent -> rectangle of chunk coords chunksRev map[DrawBoxer]image.Rectangle // comopnent -> rectangle of chunk coords
parent func(x interface{}) interface{} game *Game
proj geom.Projector
} }
// Draw draws everything in the DAG in topological order. // Draw draws everything in the DAG in topological order.
@ -55,7 +54,7 @@ func (d *DrawDAG) DrawAll(screen *ebiten.Image, opts *ebiten.DrawImageOptions) {
// Walk up game tree to find the nearest state in cache. // Walk up game tree to find the nearest state in cache.
var st state var st state
stack := []interface{}{x} stack := []interface{}{x}
for p := d.parent(x); ; p = d.parent(p) { for p := d.game.Parent(x); ; p = d.game.Parent(p) {
if s, found := cache[p]; found { if s, found := cache[p]; found {
st = s st = s
break break
@ -94,12 +93,11 @@ func (d *DrawDAG) Prepare(game *Game) error {
d.boxCache = make(map[DrawBoxer]geom.Box) d.boxCache = make(map[DrawBoxer]geom.Box)
d.chunks = make(map[image.Point]drawerSet) d.chunks = make(map[image.Point]drawerSet)
d.chunksRev = make(map[DrawBoxer]image.Rectangle) d.chunksRev = make(map[DrawBoxer]image.Rectangle)
d.parent = game.Parent d.game = game
d.proj = game.Projection
// Descendants might not be prepared yet, so fill the cache with zero boxes // Descendants might not be prepared yet, so fill the cache with zero boxes
// and fill remaining data structures during update // and fill remaining data structures during update
// TODO: work out a system for dependent prepares........ sync.Once? // TODO: work out a how to prepare the descendants first
return PreorderWalk(d, func(c, _ interface{}) error { return PreorderWalk(d, func(c, _ interface{}) error {
if db, ok := c.(DrawBoxer); ok { if db, ok := c.(DrawBoxer); ok {
d.boxCache[db] = geom.Box{} d.boxCache[db] = geom.Box{}
@ -113,6 +111,7 @@ func (d *DrawDAG) Scan() []interface{} { return d.Components }
func (d *DrawDAG) Update() error { func (d *DrawDAG) Update() error {
// Re-evaluate bounding boxes for all descendants. If a box has changed, // Re-evaluate bounding boxes for all descendants. If a box has changed,
// fix up the edges by removing and re-adding the vertex. // fix up the edges by removing and re-adding the vertex.
// TODO: ensure this happens after updates for the descendants.
var readd []DrawBoxer var readd []DrawBoxer
for db, bb := range d.boxCache { for db, bb := range d.boxCache {
nbb := db.BoundingBox() nbb := db.BoundingBox()
@ -129,8 +128,6 @@ func (d *DrawDAG) Update() error {
// Add adds a Drawer and any needed edges to the DAG and chunk map. // Add adds a Drawer and any needed edges to the DAG and chunk map.
func (d *DrawDAG) Add(x DrawBoxer) { func (d *DrawDAG) Add(x DrawBoxer) {
πsign := d.proj.Sign()
// Ensure vertex is present // Ensure vertex is present
d.dag.addVertex(x) d.dag.addVertex(x)
@ -139,7 +136,7 @@ func (d *DrawDAG) Add(x DrawBoxer) {
d.boxCache[x] = xb d.boxCache[x] = xb
// Update the reverse chunk map // Update the reverse chunk map
xbr := xb.BoundingRect(d.proj) xbr := xb.BoundingRect(d.game.Projection)
revr := image.Rectangle{ revr := image.Rectangle{
Min: xbr.Min.Div(d.ChunkSize), Min: xbr.Min.Div(d.ChunkSize),
Max: xbr.Max.Sub(image.Pt(1, 1)).Div(d.ChunkSize), Max: xbr.Max.Sub(image.Pt(1, 1)).Div(d.ChunkSize),
@ -166,11 +163,12 @@ func (d *DrawDAG) Add(x DrawBoxer) {
} }
} }
// Add edges between x and elements of cand // Add edges between x and elements of cand
πsign := d.game.Projection.Sign()
for c := range cand { for c := range cand {
y := c.(DrawBoxer) y := c.(DrawBoxer)
// Bounding rectangle overlap test // Bounding rectangle overlap test
// No overlap, no edge. // No overlap, no edge.
if ybr := y.BoundingBox().BoundingRect(d.proj); !xbr.Overlaps(ybr) { if ybr := y.BoundingBox().BoundingRect(d.game.Projection); !xbr.Overlaps(ybr) {
continue continue
} }
switch { switch {

View file

@ -117,17 +117,17 @@ func (a RatMatrix3) Adjugate() RatMatrix3 {
return RatMatrix3{ return RatMatrix3{
0: [3]Rat{ 0: [3]Rat{
0: a[1][1].Mul(a[2][2]).Sub(a[1][2].Mul(a[2][1])), 0: a[1][1].Mul(a[2][2]).Sub(a[1][2].Mul(a[2][1])),
1: a[0][1].Mul(a[2][2]).Sub(a[0][2].Mul(a[2][1])).Neg(), 1: a[0][2].Mul(a[2][1]).Sub(a[0][1].Mul(a[2][2])),
2: a[0][1].Mul(a[1][2]).Sub(a[0][2].Mul(a[1][1])), 2: a[0][1].Mul(a[1][2]).Sub(a[0][2].Mul(a[1][1])),
}, },
1: [3]Rat{ 1: [3]Rat{
0: a[1][0].Mul(a[2][2]).Sub(a[1][2].Mul(a[2][0])).Neg(), 0: a[1][2].Mul(a[2][0]).Sub(a[1][0].Mul(a[2][2])),
1: a[0][0].Mul(a[2][2]).Sub(a[0][2].Mul(a[2][0])), 1: a[0][0].Mul(a[2][2]).Sub(a[0][2].Mul(a[2][0])),
2: a[0][0].Mul(a[1][2]).Sub(a[0][2].Mul(a[1][0])).Neg(), 2: a[0][2].Mul(a[1][0]).Sub(a[0][0].Mul(a[1][2])),
}, },
2: [3]Rat{ 2: [3]Rat{
0: a[1][0].Mul(a[2][1]).Sub(a[1][1].Mul(a[2][0])), 0: a[1][0].Mul(a[2][1]).Sub(a[1][1].Mul(a[2][0])),
1: a[0][0].Mul(a[2][1]).Sub(a[0][1].Mul(a[2][0])).Neg(), 1: a[0][1].Mul(a[2][0]).Sub(a[0][0].Mul(a[2][1])),
2: a[0][0].Mul(a[1][1]).Sub(a[0][1].Mul(a[1][0])), 2: a[0][0].Mul(a[1][1]).Sub(a[0][1].Mul(a[1][0])),
}, },
} }