projection.go, delete crap
This commit is contained in:
parent
86d076c89f
commit
1e029903a6
10 changed files with 44 additions and 47 deletions
Binary file not shown.
|
@ -38,21 +38,21 @@ func (b Box) Size() Point3 {
|
|||
|
||||
// Back returns an image.Rectangle representing the back of the box, using
|
||||
// the given projection π.
|
||||
func (b Box) Back(π image.Point) image.Rectangle {
|
||||
func (b Box) Back(π IntProjection) image.Rectangle {
|
||||
b.Max.Z = b.Min.Z
|
||||
return image.Rectangle{
|
||||
Min: b.Min.IsoProject(π),
|
||||
Max: b.Max.IsoProject(π),
|
||||
Min: π.Project(b.Min),
|
||||
Max: π.Project(b.Max),
|
||||
}
|
||||
}
|
||||
|
||||
// Front returns an image.Rectangle representing the front of the box, using
|
||||
// the given projection π.
|
||||
func (b Box) Front(π image.Point) image.Rectangle {
|
||||
func (b Box) Front(π IntProjection) image.Rectangle {
|
||||
b.Min.Z = b.Max.Z
|
||||
return image.Rectangle{
|
||||
Min: b.Min.IsoProject(π),
|
||||
Max: b.Max.IsoProject(π),
|
||||
Min: π.Project(b.Min),
|
||||
Max: π.Project(b.Max),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,10 +25,10 @@ type Camera struct {
|
|||
// Camera controls
|
||||
// These directly manipulate the camera. If you want to restrict the camera
|
||||
// view area to the child's bounding rectangle, use PointAt.
|
||||
Centre image.Point // world coordinates
|
||||
Rotation float64 // radians
|
||||
Zoom float64 // unitless
|
||||
IsoProjection image.Point
|
||||
Centre image.Point // world coordinates
|
||||
Rotation float64 // radians
|
||||
Zoom float64 // unitless
|
||||
Projection IntProjection
|
||||
|
||||
game *Game
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ func (c *Camera) PointAt(centre Point3, zoom float64) {
|
|||
// Special sauce: if Child has a BoundingRect, make some adjustments
|
||||
bnd, ok := c.Child.(Bounder)
|
||||
if !ok {
|
||||
c.Centre = centre.IsoProject(c.IsoProjection)
|
||||
c.Centre = c.Projection.Project(centre)
|
||||
c.Zoom = zoom
|
||||
return
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ func (c *Camera) PointAt(centre Point3, zoom float64) {
|
|||
// Camera frame currently Rectangle{ centre ± (screen/(2*zoom)) }.
|
||||
sw2, sh2 := cfloat(c.game.ScreenSize.Div(2))
|
||||
swz, shz := int(sw2/zoom), int(sh2/zoom)
|
||||
cent := centre.IsoProject(c.IsoProjection)
|
||||
cent := c.Projection.Project(centre)
|
||||
if cent.X-swz < br.Min.X {
|
||||
cent.X = br.Min.X + swz
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ func (c *Camera) Scan() []interface{} { return []interface{}{c.Child} }
|
|||
|
||||
// Transform returns the camera transform.
|
||||
func (c *Camera) Transform(pt Transform) (tf Transform) {
|
||||
tf.IsoProjection = c.IsoProjection
|
||||
tf.Projection = c.Projection
|
||||
tf.Opts.GeoM.Translate(cfloat(c.Centre.Mul(-1)))
|
||||
tf.Opts.GeoM.Scale(c.Zoom, c.Zoom)
|
||||
tf.Opts.GeoM.Rotate(c.Rotation)
|
||||
|
|
|
@ -1,24 +1,29 @@
|
|||
package engine
|
||||
|
||||
var (
|
||||
// Oblique projections
|
||||
CabinetProjection = ParallelProjection{0.5, 0.5}
|
||||
CavalierProjection = ParallelProjection{1, 1}
|
||||
import "image"
|
||||
|
||||
// Axonometric projections
|
||||
ElevationProjection = ParallelProjection{0, 0}
|
||||
DimetricProjection = ParallelProjection{0, 0.5}
|
||||
HexPrismProjection = ParallelProjection{0, 0.577350269189626} // 1 ÷ √3
|
||||
IsometricProjection = ParallelProjection{0, 0.707106781186548} // 1 ÷ √2
|
||||
TrimetricProjection = ParallelProjection{0, 1}
|
||||
)
|
||||
type IntProjection image.Point
|
||||
|
||||
type ParallelProjection struct {
|
||||
ZX, ZY float64
|
||||
}
|
||||
|
||||
func (π ParallelProjection) Project(p Point3) (px, py float64) {
|
||||
px = float64(p.X) + π.ZX*float64(p.Z)
|
||||
py = float64(p.Y) + π.ZY*float64(p.Z)
|
||||
return px, py
|
||||
// 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 Point3) image.Point {
|
||||
/*
|
||||
I'm using the π character because I'm a maths wanker.
|
||||
|
||||
Dividing is used because there's little reason for an isometric
|
||||
projection in a game to exaggerate the Z position.
|
||||
|
||||
Integers are used to preserve that "pixel perfect" calculation in case
|
||||
you are making the next Celeste.
|
||||
*/
|
||||
q := p.XY()
|
||||
if π.X != 0 {
|
||||
q.X += p.Z / π.X
|
||||
}
|
||||
if π.Y != 0 {
|
||||
q.Y += p.Z / π.Y
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ func (s *Sprite) SetAnim(a *Anim) {
|
|||
// Transform returns a translation by the DrawOffset and the iso-projected Pos.
|
||||
func (s *Sprite) Transform(pt Transform) (tf Transform) {
|
||||
tf.Opts.GeoM.Translate(cfloat(
|
||||
s.Actor.Pos.IsoProject(pt.IsoProjection).Add(s.DrawOffset),
|
||||
pt.Projection.Project(s.Actor.Pos).Add(s.DrawOffset),
|
||||
))
|
||||
return tf.Concat(pt)
|
||||
}
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
package engine
|
||||
|
||||
import (
|
||||
"image"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
import "github.com/hajimehoshi/ebiten/v2"
|
||||
|
||||
// Transform is a bucket of things that affect drawing.
|
||||
type Transform struct {
|
||||
// IsoProjection is used by isometric 3D components to project their
|
||||
// Projection is used by isometric 3D components to project their
|
||||
// coordinates into 2D. There's usually only one component in the tree that
|
||||
// sets this field, but it would apply to all descendants.
|
||||
IsoProjection image.Point
|
||||
Projection IntProjection
|
||||
|
||||
// Opts contains the 2D geometry matrix, the colour matrix, filter mode, and
|
||||
// composition mode.
|
||||
|
@ -21,8 +17,8 @@ type Transform struct {
|
|||
// Concat returns the combined transform (a transform equivalent to applying t
|
||||
// and then u).
|
||||
func (t Transform) Concat(u Transform) Transform {
|
||||
if u.IsoProjection != (image.Point{}) {
|
||||
t.IsoProjection = u.IsoProjection
|
||||
if u.Projection != (IntProjection{}) {
|
||||
t.Projection = u.Projection
|
||||
}
|
||||
t.Opts.ColorM.Concat(u.Opts.ColorM)
|
||||
t.Opts.GeoM.Concat(u.Opts.GeoM)
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
6
main.go
6
main.go
|
@ -57,12 +57,8 @@ func main() {
|
|||
&engine.Camera{
|
||||
ID: "game_camera",
|
||||
Child: lev1,
|
||||
// Each step in Z becomes -½ step in X plus ½ step in Y:
|
||||
IsoProjection: image.Pt(-2, 2),
|
||||
// Each step in Z becomes ½ step in Y:
|
||||
//IsoProjection: image.Pt(0, 2),
|
||||
// Each step in Z becomes a step in Y:
|
||||
//IsoProjection: image.Pt(0, 1),
|
||||
Projection: engine.IntProjection{X: 0, Y: 1},
|
||||
},
|
||||
&engine.DebugToast{ID: "toast", Pos: image.Pt(0, 15)},
|
||||
engine.PerfDisplay{},
|
||||
|
|
Loading…
Reference in a new issue