2016-12-01 17:38:49 -06:00
|
|
|
package pixel
|
|
|
|
|
|
|
|
import "github.com/go-gl/mathgl/mgl32"
|
|
|
|
|
|
|
|
// Transform holds space transformation information. Concretely, a transformation is specified by position,
|
|
|
|
// anchor, scale and rotation.
|
|
|
|
//
|
|
|
|
// All points are first rotated around the anchor. Then they are multiplied by the scale. If the
|
|
|
|
// scale factor is 2, the object becomes 2x bigger. Finally, all points are moved, so that the original
|
|
|
|
// anchor is located precisely at the position.
|
|
|
|
//
|
|
|
|
// Create a Transform object with the Position function. This sets the position variable, which is the
|
|
|
|
// most important. Then use methods, like Scale and Rotate to change scale, rotation and achor. The order
|
|
|
|
// in which you apply these methods is irrelevant.
|
|
|
|
//
|
|
|
|
// pixel.Position(pixel.V(100, 100)).Rotate(math.Pi / 3).Scale(1.5)
|
|
|
|
type Transform struct {
|
2016-12-02 10:36:36 -06:00
|
|
|
pos, anc, sca Vec
|
|
|
|
rot float64
|
2016-12-01 17:38:49 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// Position creates a Transformation object with specified position. Anchor is (0, 0), rotation is 0 and scale is 1.
|
|
|
|
func Position(position Vec) Transform {
|
|
|
|
return Transform{
|
|
|
|
pos: position,
|
2016-12-02 10:36:36 -06:00
|
|
|
sca: V(1, 1),
|
2016-12-01 17:38:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Move adds delta to position.
|
|
|
|
func (t Transform) Move(delta Vec) Transform {
|
|
|
|
t.pos += delta
|
|
|
|
return t
|
|
|
|
}
|
|
|
|
|
|
|
|
// Anchor sets anchor. Anchor is the rotation center and will be moved to the position.
|
|
|
|
func (t Transform) Anchor(anchor Vec) Transform {
|
|
|
|
t.anc = anchor
|
|
|
|
return t
|
|
|
|
}
|
|
|
|
|
|
|
|
// MoveAnchor adds delta to anchor.
|
|
|
|
func (t Transform) MoveAnchor(delta Vec) Transform {
|
|
|
|
t.anc += delta
|
|
|
|
return t
|
|
|
|
}
|
|
|
|
|
|
|
|
// Scale scales the transform by the supplied factor.
|
|
|
|
//
|
|
|
|
// Note, that subsequent calls to this method accumulate the final scale factor. Scaling two times by 2 is equivalent
|
|
|
|
// to scaling once by 4.
|
|
|
|
func (t Transform) Scale(scale float64) Transform {
|
2016-12-02 10:36:36 -06:00
|
|
|
t.sca *= V(scale, scale)
|
|
|
|
return t
|
|
|
|
}
|
|
|
|
|
|
|
|
// ScaleXY scales the transform by the supplied X and Y factor. Note, that scale is applied before rotation.
|
|
|
|
//
|
|
|
|
// Note, that subsequent calls to this method accumulate the final scale factor. Scaling two times by 2 is equivalent
|
|
|
|
// to scaling once by 4.
|
|
|
|
func (t Transform) ScaleXY(scale Vec) Transform {
|
2016-12-01 17:38:49 -06:00
|
|
|
t.sca *= scale
|
|
|
|
return t
|
|
|
|
}
|
|
|
|
|
|
|
|
// Rotate rotates the transform by the supplied angle in radians.
|
|
|
|
//
|
|
|
|
// Note, that subsequent calls to this method accumulate the final rotation. Rotating two times by Pi/2 is
|
|
|
|
// equivalent to rotating once by Pi.
|
|
|
|
func (t Transform) Rotate(angle float64) Transform {
|
|
|
|
t.rot += angle
|
|
|
|
return t
|
|
|
|
}
|
|
|
|
|
|
|
|
// Mat3 returns a transformation matrix that satisfies previously set transform properties.
|
|
|
|
func (t Transform) Mat3() mgl32.Mat3 {
|
|
|
|
mat := mgl32.Ident3()
|
|
|
|
mat = mat.Mul3(mgl32.Translate2D(float32(t.pos.X()), float32(t.pos.Y())))
|
|
|
|
mat = mat.Mul3(mgl32.Rotate3DZ(float32(t.rot)))
|
2016-12-02 10:36:36 -06:00
|
|
|
mat = mat.Mul3(mgl32.Scale2D(float32(t.sca.X()), float32(t.sca.Y())))
|
2016-12-01 17:38:49 -06:00
|
|
|
mat = mat.Mul3(mgl32.Translate2D(float32(t.anc.X()), float32(t.anc.Y())))
|
|
|
|
return mat
|
|
|
|
}
|