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 package engine
import ( import (
"image"
"log" "log"
"drjosh.dev/gurgle/geom"
"github.com/hajimehoshi/ebiten/v2" "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] d.list[i], d.list[j] = d.list[j], d.list[i]
} }
// Bad, slow, topological sort // Slow topological sort
func (d *drawList) topsort() { func (d *drawList) topsort() {
// Produce edge lists - O(|V|^2) // Produce edge lists - O(|V|^2)
// Count indegrees - also O(|V|^2) // Count indegrees - also O(|V|^2)
@ -90,6 +92,13 @@ func (d *drawList) topsort() {
if u == (tombstone{}) { if u == (tombstone{}) {
continue 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 { for j, v := range d.list {
if i == j { if i == j {
continue continue
@ -97,6 +106,17 @@ func (d *drawList) topsort() {
if v == (tombstone{}) { if v == (tombstone{}) {
continue 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) { if u.DrawBefore(v) || v.DrawAfter(u) {
edges[i] = append(edges[i], j) edges[i] = append(edges[i], j)
indegree[j]++ indegree[j]++
@ -120,9 +140,7 @@ func (d *drawList) topsort() {
for len(queue) > 0 { for len(queue) > 0 {
i := queue[0] i := queue[0]
queue = queue[1:] 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]) list = append(list, d.list[i])
for _, j := range edges[i] { for _, j := range edges[i] {
indegree[j]-- indegree[j]--
@ -137,9 +155,11 @@ func (d *drawList) topsort() {
// Replace list // Replace list
d.list = list d.list = list
if false {
// Update rev // Update rev
d.rev = make(map[Drawer]int, len(list)) d.rev = make(map[Drawer]int, len(list))
for i, v := range list { for i, v := range list {
d.rev[v] = i d.rev[v] = i
} }
}
} }

View file

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

View file

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