more small tidyups
This commit is contained in:
parent
a9d6c8827f
commit
951b38271f
2 changed files with 14 additions and 16 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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])),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue