gl01/internal/render/view.go

81 lines
2.2 KiB
Go
Raw Permalink Normal View History

2022-01-20 21:58:50 +08:00
package render
import (
"edgaru089.ink/go/gl01/internal/util/itype"
2022-01-20 21:58:50 +08:00
"github.com/go-gl/mathgl/mgl32"
)
// View represents a viewport in the 3-d world.
// It is essentialy a projection and a view matrix.
type View struct {
EyePos itype.Vec3f // position of the eye
rotY, rotZ, fovY itype.Angle
aspect float32
near, far float32
clipSet bool
}
// View returns the View matrix from parameters set with LookAt().
func (r *View) View() mgl32.Mat4 {
delta := mgl32.Rotate3DY(r.rotY.Radians()).Mul3(mgl32.Rotate3DZ(r.rotZ.Radians())).Mul3x1(mgl32.Vec3{1, 0, 0})
return mgl32.LookAt(
r.EyePos[0], r.EyePos[1], r.EyePos[2],
r.EyePos[0]+delta[0],
r.EyePos[1]+delta[1],
r.EyePos[2]+delta[2],
0, 1, 0,
)
}
// Perspective returns the Perspective matrix with parameters set with Aspect(), FovY() and Clip().
func (r *View) Perspective() mgl32.Mat4 {
if r.clipSet {
return mgl32.Perspective(r.fovY.Radians(), r.aspect, r.near, r.far)
} else {
return mgl32.Perspective(r.fovY.Radians(), r.aspect, 0.1, 200)
}
}
// LookAt resets the View matrix with a camera looking from Eye.
// The camera points to +RotY from X+ axis rotating around Y axis (right-handed);
// +/-RotZ form X+ axis rotating up/down around Z axis.
// ( RotZ should be in the (-90,90) degrees range )
//
// It also returns itself so that operations can be chained.
func (r *View) LookAt(eye itype.Vec3f, rotY, rotZ itype.Angle) *View {
r.EyePos = eye
r.rotY = rotY
r.rotZ = rotZ
return r
}
// Aspect sets the aspect (width / height) of the viewport.
//
// It also returns itself so that operations can be chained.
func (r *View) Aspect(aspectRatio float32) *View {
r.aspect = aspectRatio
return r
}
// FovY sets the Field of View (an angle) on the Y axis.
// FovX = FovY * aspect.
//
// With FovX, call SetFovY(FovX / aspect).
//
// It also returns itself so that operations can be chained.
func (r *View) FovY(fovy itype.Angle) *View {
r.fovY = fovy
return r
}
// Clip sets the near/far clipping distance of the Perspective.
// It defaults to 0.1 / 200.
//
// It also returns itself so that operations can be chained.
func (r *View) Clip(near, far float32) *View {
r.near, r.far = near, far
r.clipSet = true
return r
}