π.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.
|
||||
func (b *Billboard) Transform() (opts ebiten.DrawImageOptions) {
|
||||
opts.GeoM.Translate(geom.CFloat(
|
||||
b.game.Projection.Project(b.Pos),
|
||||
geom.Project(b.game.Projection, b.Pos),
|
||||
))
|
||||
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
|
||||
bnd, ok := c.Child.(BoundingRecter)
|
||||
if !ok {
|
||||
c.Centre = c.game.Projection.Project(centre)
|
||||
c.Centre = geom.Project(c.game.Projection, centre)
|
||||
c.Zoom = zoom
|
||||
return
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ func (c *Camera) PointAt(centre geom.Int3, zoom float64) {
|
|||
// Camera frame currently Rectangle{ centre ± (screen/(2*zoom)) }.
|
||||
sw2, sh2 := geom.CFloat(c.game.ScreenSize.Div(2))
|
||||
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 {
|
||||
cent.X = br.Min.X + swz
|
||||
}
|
||||
|
|
|
@ -212,7 +212,7 @@ func (p *Prism) String() string {
|
|||
// Transform returns a translation by the projected position.
|
||||
func (p *Prism) Transform() (opts ebiten.DrawImageOptions) {
|
||||
opts.GeoM.Translate(geom.CFloat(
|
||||
p.m.game.Projection.Project(p.pos),
|
||||
geom.Project(p.m.game.Projection, p.pos),
|
||||
))
|
||||
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
|
||||
// implement Prepare in this file, but writing this long comment
|
||||
// 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
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ func (b Box) BoundingRect(π Projector) image.Rectangle {
|
|||
// Back returns an image.Rectangle representing the back of the box, using
|
||||
// the given projection π.
|
||||
func (b Box) Back(π Projector) image.Rectangle {
|
||||
p := π.Project(Int3{0, 0, b.Min.Z})
|
||||
p := π.Project(b.Min.Z)
|
||||
return image.Rectangle{
|
||||
Min: b.Min.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
|
||||
// the given projection π.
|
||||
func (b Box) Front(π Projector) image.Rectangle {
|
||||
p := π.Project(Int3{0, 0, b.Max.Z})
|
||||
p := π.Project(b.Max.Z)
|
||||
return image.Rectangle{
|
||||
Min: b.Min.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
|
||||
// positive Z values are projected to.
|
||||
Sign() image.Point
|
||||
// Project projects a 3D point into 2D.
|
||||
Project(Int3) image.Point
|
||||
// Project projects a Z coordinate into 2D offset.
|
||||
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.
|
||||
|
@ -18,26 +23,24 @@ func (π Projection) Sign() (s image.Point) {
|
|||
return image.Pt(int(FSign(π.X)), int(FSign(π.Y)))
|
||||
}
|
||||
|
||||
// Project performs a parallel projection of a 3D coordiante into 2D.
|
||||
// x projects to (x + z*π.X), and y to (y + z*π.Y)
|
||||
func (π Projection) Project(p Int3) image.Point {
|
||||
// Project returns (z*π.X, z*π.Y).
|
||||
func (π Projection) Project(z int) image.Point {
|
||||
return image.Pt(
|
||||
p.X+int(π.X*float64(p.Z)),
|
||||
p.Y+int(π.Y*float64(p.Z)),
|
||||
int(π.X*float64(z)),
|
||||
int(π.Y*float64(z)),
|
||||
)
|
||||
}
|
||||
|
||||
// IntProjection holds an integer projection definition.
|
||||
// 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
|
||||
|
||||
func (π IntProjection) Sign() image.Point { return image.Point(π) }
|
||||
|
||||
// Project performs an integer parallel projection of a 3D coordinate into 2D.
|
||||
// If π.X = 0, the x returned is p.X; similarly for π.Y and y.
|
||||
// Otherwise, x projects to x + z/π.X and y projects to y + z/π.Y.
|
||||
func (π IntProjection) Project(p Int3) image.Point {
|
||||
// Project returns (z/π.X, z/π.Y), unless π.X or π.Y are 0, in which case that
|
||||
// component is zero
|
||||
func (π IntProjection) Project(z int) image.Point {
|
||||
/*
|
||||
Dividing is used because there's little reason for an isometric
|
||||
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
|
||||
are making the next Celeste.
|
||||
*/
|
||||
q := p.XY()
|
||||
var q image.Point
|
||||
if π.X != 0 {
|
||||
q.X += p.Z / π.X
|
||||
q.X = z / π.X
|
||||
}
|
||||
if π.Y != 0 {
|
||||
q.Y += p.Z / π.Y
|
||||
q.Y = z / π.Y
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue