π.Project -> geom.Project(π,
This commit is contained in:
parent
c533ee63f7
commit
ed78ef3d2e
6 changed files with 26 additions and 22 deletions
|
@ -83,7 +83,7 @@ func (b *Billboard) String() string {
|
||||||
// Transform returns a translation by the projected position.
|
// Transform returns a translation by the projected position.
|
||||||
func (b *Billboard) Transform() (opts ebiten.DrawImageOptions) {
|
func (b *Billboard) Transform() (opts ebiten.DrawImageOptions) {
|
||||||
opts.GeoM.Translate(geom.CFloat(
|
opts.GeoM.Translate(geom.CFloat(
|
||||||
b.game.Projection.Project(b.Pos),
|
geom.Project(b.game.Projection, b.Pos),
|
||||||
))
|
))
|
||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ func (c *Camera) PointAt(centre geom.Int3, zoom float64) {
|
||||||
// Special sauce: if Child has a BoundingRect, make some adjustments
|
// Special sauce: if Child has a BoundingRect, make some adjustments
|
||||||
bnd, ok := c.Child.(BoundingRecter)
|
bnd, ok := c.Child.(BoundingRecter)
|
||||||
if !ok {
|
if !ok {
|
||||||
c.Centre = c.game.Projection.Project(centre)
|
c.Centre = geom.Project(c.game.Projection, centre)
|
||||||
c.Zoom = zoom
|
c.Zoom = zoom
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ func (c *Camera) PointAt(centre geom.Int3, zoom float64) {
|
||||||
// Camera frame currently Rectangle{ centre ± (screen/(2*zoom)) }.
|
// Camera frame currently Rectangle{ centre ± (screen/(2*zoom)) }.
|
||||||
sw2, sh2 := geom.CFloat(c.game.ScreenSize.Div(2))
|
sw2, sh2 := geom.CFloat(c.game.ScreenSize.Div(2))
|
||||||
swz, shz := int(sw2/zoom), int(sh2/zoom)
|
swz, shz := int(sw2/zoom), int(sh2/zoom)
|
||||||
cent := c.game.Projection.Project(centre)
|
cent := geom.Project(c.game.Projection, centre)
|
||||||
if cent.X-swz < br.Min.X {
|
if cent.X-swz < br.Min.X {
|
||||||
cent.X = br.Min.X + swz
|
cent.X = br.Min.X + swz
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,7 @@ func (p *Prism) String() string {
|
||||||
// Transform returns a translation by the projected position.
|
// Transform returns a translation by the projected position.
|
||||||
func (p *Prism) Transform() (opts ebiten.DrawImageOptions) {
|
func (p *Prism) Transform() (opts ebiten.DrawImageOptions) {
|
||||||
opts.GeoM.Translate(geom.CFloat(
|
opts.GeoM.Translate(geom.CFloat(
|
||||||
p.m.game.Projection.Project(p.pos),
|
geom.Project(p.m.game.Projection, p.pos),
|
||||||
))
|
))
|
||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,8 @@ func (s *Sprite) Transform() (opts ebiten.DrawImageOptions) {
|
||||||
// Reaching into Actor for a reference to Game so I don't have to
|
// Reaching into Actor for a reference to Game so I don't have to
|
||||||
// implement Prepare in this file, but writing this long comment
|
// implement Prepare in this file, but writing this long comment
|
||||||
// providing exposition...
|
// providing exposition...
|
||||||
s.Actor.game.Projection.Project(s.Actor.Pos).Add(s.DrawOffset),
|
geom.Project(s.Actor.game.Projection, s.Actor.Pos).
|
||||||
|
Add(s.DrawOffset),
|
||||||
))
|
))
|
||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ func (b Box) BoundingRect(π Projector) image.Rectangle {
|
||||||
// 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(π Projector) image.Rectangle {
|
func (b Box) Back(π Projector) image.Rectangle {
|
||||||
p := π.Project(Int3{0, 0, b.Min.Z})
|
p := π.Project(b.Min.Z)
|
||||||
return image.Rectangle{
|
return image.Rectangle{
|
||||||
Min: b.Min.XY().Add(p),
|
Min: b.Min.XY().Add(p),
|
||||||
Max: b.Max.XY().Add(p),
|
Max: b.Max.XY().Add(p),
|
||||||
|
@ -90,7 +90,7 @@ func (b Box) Back(π Projector) 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(π Projector) image.Rectangle {
|
func (b Box) Front(π Projector) image.Rectangle {
|
||||||
p := π.Project(Int3{0, 0, b.Max.Z})
|
p := π.Project(b.Max.Z)
|
||||||
return image.Rectangle{
|
return image.Rectangle{
|
||||||
Min: b.Min.XY().Add(p),
|
Min: b.Min.XY().Add(p),
|
||||||
Max: b.Max.XY().Add(p),
|
Max: b.Max.XY().Add(p),
|
||||||
|
|
|
@ -7,8 +7,13 @@ type Projector interface {
|
||||||
// Sign returns a {-1, 0, 1}-valued 2D vector pointing in the direction that
|
// Sign returns a {-1, 0, 1}-valued 2D vector pointing in the direction that
|
||||||
// positive Z values are projected to.
|
// positive Z values are projected to.
|
||||||
Sign() image.Point
|
Sign() image.Point
|
||||||
// Project projects a 3D point into 2D.
|
// Project projects a Z coordinate into 2D offset.
|
||||||
Project(Int3) image.Point
|
Project(int) image.Point
|
||||||
|
}
|
||||||
|
|
||||||
|
// Project is shorthand for π.Project(p.Z).Add(p.XY()).
|
||||||
|
func Project(π Projector, p Int3) image.Point {
|
||||||
|
return π.Project(p.Z).Add(p.XY())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Projection uses floats to define a projection.
|
// Projection uses floats to define a projection.
|
||||||
|
@ -18,26 +23,24 @@ func (π Projection) Sign() (s image.Point) {
|
||||||
return image.Pt(int(FSign(π.X)), int(FSign(π.Y)))
|
return image.Pt(int(FSign(π.X)), int(FSign(π.Y)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Project performs a parallel projection of a 3D coordiante into 2D.
|
// Project returns (z*π.X, z*π.Y).
|
||||||
// x projects to (x + z*π.X), and y to (y + z*π.Y)
|
func (π Projection) Project(z int) image.Point {
|
||||||
func (π Projection) Project(p Int3) image.Point {
|
|
||||||
return image.Pt(
|
return image.Pt(
|
||||||
p.X+int(π.X*float64(p.Z)),
|
int(π.X*float64(z)),
|
||||||
p.Y+int(π.Y*float64(p.Z)),
|
int(π.Y*float64(z)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IntProjection holds an integer projection definition.
|
// IntProjection holds an integer projection definition.
|
||||||
// It is designed for projecting Z onto X and Y with integer fractions as would
|
// It is designed for projecting Z onto X and Y with integer fractions as would
|
||||||
// be used in e.g. a diametric projection (IntProjection{X:0, Y:-2}).
|
// be used in e.g. a diametric projection (IntProjection{X:0, Y:2}).
|
||||||
type IntProjection image.Point
|
type IntProjection image.Point
|
||||||
|
|
||||||
func (π IntProjection) Sign() image.Point { return image.Point(π) }
|
func (π IntProjection) Sign() image.Point { return image.Point(π) }
|
||||||
|
|
||||||
// Project performs an integer parallel projection of a 3D coordinate into 2D.
|
// Project returns (z/π.X, z/π.Y), unless π.X or π.Y are 0, in which case that
|
||||||
// If π.X = 0, the x returned is p.X; similarly for π.Y and y.
|
// component is zero
|
||||||
// Otherwise, x projects to x + z/π.X and y projects to y + z/π.Y.
|
func (π IntProjection) Project(z int) image.Point {
|
||||||
func (π IntProjection) Project(p Int3) image.Point {
|
|
||||||
/*
|
/*
|
||||||
Dividing is used because there's little reason for an isometric
|
Dividing is used because there's little reason for an isometric
|
||||||
projection in a game to exaggerate the Z position.
|
projection in a game to exaggerate the Z position.
|
||||||
|
@ -45,12 +48,12 @@ func (π IntProjection) Project(p Int3) image.Point {
|
||||||
Integers are used to preserve "pixel perfect" calculation in case you
|
Integers are used to preserve "pixel perfect" calculation in case you
|
||||||
are making the next Celeste.
|
are making the next Celeste.
|
||||||
*/
|
*/
|
||||||
q := p.XY()
|
var q image.Point
|
||||||
if π.X != 0 {
|
if π.X != 0 {
|
||||||
q.X += p.Z / π.X
|
q.X = z / π.X
|
||||||
}
|
}
|
||||||
if π.Y != 0 {
|
if π.Y != 0 {
|
||||||
q.Y += p.Z / π.Y
|
q.Y = z / π.Y
|
||||||
}
|
}
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue