bubbles works again

This commit is contained in:
Josh Deprez 2021-09-17 13:02:31 +10:00
parent 45d7f32a2a
commit eb9f582f42
3 changed files with 36 additions and 12 deletions

View file

@ -1,8 +1,10 @@
package engine
import (
"image"
"log"
"drjosh.dev/gurgle/geom"
"github.com/hajimehoshi/ebiten/v2"
)
@ -80,7 +82,7 @@ func (d drawList) Swap(i, j int) {
d.list[i], d.list[j] = d.list[j], d.list[i]
}
// Bad, slow, topological sort
// Slow topological sort
func (d *drawList) topsort() {
// Produce edge lists - O(|V|^2)
// Count indegrees - also O(|V|^2)
@ -90,6 +92,13 @@ func (d *drawList) topsort() {
if u == (tombstone{}) {
continue
}
var ub image.Rectangle
switch x := u.(type) {
case BoundingBoxer:
ub = x.BoundingBox().BoundingRect(geom.IntProjection{X: 0, Y: 1})
default:
ub = image.Rect(0, 0, 320, 240)
}
for j, v := range d.list {
if i == j {
continue
@ -97,6 +106,17 @@ func (d *drawList) topsort() {
if v == (tombstone{}) {
continue
}
var vb image.Rectangle
switch y := v.(type) {
case BoundingBoxer:
vb = y.BoundingBox().BoundingRect(geom.IntProjection{X: 0, Y: 1})
default:
vb = image.Rect(0, 0, 320, 240)
}
if !ub.Overlaps(vb) {
// No overlap, no need to emit an edge
continue
}
if u.DrawBefore(v) || v.DrawAfter(u) {
edges[i] = append(edges[i], j)
indegree[j]++
@ -120,9 +140,7 @@ func (d *drawList) topsort() {
for len(queue) > 0 {
i := queue[0]
queue = queue[1:]
if false {
d.rev[d.list[i]] = len(list)
}
d.rev[d.list[i]] = len(list)
list = append(list, d.list[i])
for _, j := range edges[i] {
indegree[j]--
@ -137,9 +155,11 @@ func (d *drawList) topsort() {
// Replace list
d.list = list
// Update rev
d.rev = make(map[Drawer]int, len(list))
for i, v := range list {
d.rev[v] = i
if false {
// Update rev
d.rev = make(map[Drawer]int, len(list))
for i, v := range list {
d.rev[v] = i
}
}
}

View file

@ -109,7 +109,7 @@ func (aw *Awakeman) realUpdate() error {
bubblePeriod = 6
)
if false {
if true {
// Add a bubble?
aw.bubbleTimer--
if aw.bubbleTimer <= 0 {

View file

@ -71,15 +71,19 @@ func (b Box) Canon() Box {
return b
}
type Projector interface {
Project(Int3) image.Point
}
// BoundingRect returns an image.Rectangle that bounds the box if it were
// projected.
func (b Box) BoundingRect(π IntProjection) image.Rectangle {
func (b Box) BoundingRect(π Projector) image.Rectangle {
return b.Back(π).Union(b.Front(π))
}
// Back returns an image.Rectangle representing the back of the box, using
// the given projection π.
func (b Box) Back(π IntProjection) image.Rectangle {
func (b Box) Back(π Projector) image.Rectangle {
b.Max.Z = b.Min.Z
return image.Rectangle{
Min: π.Project(b.Min),
@ -89,7 +93,7 @@ func (b Box) Back(π IntProjection) image.Rectangle {
// Front returns an image.Rectangle representing the front of the box, using
// the given projection π.
func (b Box) Front(π IntProjection) image.Rectangle {
func (b Box) Front(π Projector) image.Rectangle {
b.Min.Z = b.Max.Z
return image.Rectangle{
Min: π.Project(b.Min),