Quaternion rotations worked
parent
d624077dd1
commit
8fb02993f4
10
main.go
10
main.go
|
@ -94,7 +94,7 @@ func run() {
|
|||
}
|
||||
gl.UseProgram(program)
|
||||
|
||||
projection := mgl32.Perspective(mgl32.DegToRad(45.0), float32(width)/float32(height), 0.1, 10.0)
|
||||
projection := mgl32.Perspective(mgl32.DegToRad(45.0), float32(width)/float32(height), 0.01, 1000.0)
|
||||
projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00"))
|
||||
gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0])
|
||||
|
||||
|
@ -219,7 +219,7 @@ func handleEvents(running bool, window *sdl.Window, camera *gl_objects.Camera) b
|
|||
}
|
||||
if t.Keysym.Sym == sdl.K_w {
|
||||
if t.Type == sdl.KEYDOWN {
|
||||
camera.SetZVelocity(-1)
|
||||
camera.SetZVelocity(1)
|
||||
} else if t.Type == sdl.KEYUP {
|
||||
camera.SetZVelocity(0)
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ func handleEvents(running bool, window *sdl.Window, camera *gl_objects.Camera) b
|
|||
}
|
||||
if t.Keysym.Sym == sdl.K_s {
|
||||
if t.Type == sdl.KEYDOWN {
|
||||
camera.SetZVelocity(1)
|
||||
camera.SetZVelocity(-1)
|
||||
} else if t.Type == sdl.KEYUP {
|
||||
camera.SetZVelocity(0)
|
||||
} }
|
||||
|
@ -260,14 +260,14 @@ func handleEvents(running bool, window *sdl.Window, camera *gl_objects.Camera) b
|
|||
}
|
||||
if t.Keysym.Sym == sdl.K_z {
|
||||
if t.Type == sdl.KEYDOWN {
|
||||
camera.SetRotationVelocity(1)
|
||||
camera.SetRotationVelocity(-1)
|
||||
} else if t.Type == sdl.KEYUP {
|
||||
camera.SetRotationVelocity(0)
|
||||
}
|
||||
}
|
||||
if t.Keysym.Sym == sdl.K_x {
|
||||
if t.Type == sdl.KEYDOWN {
|
||||
camera.SetRotationVelocity(-1)
|
||||
camera.SetRotationVelocity(1)
|
||||
} else if t.Type == sdl.KEYUP {
|
||||
camera.SetRotationVelocity(0)
|
||||
}
|
||||
|
|
|
@ -5,29 +5,37 @@ import (
|
|||
|
||||
gl "github.com/go-gl/gl/v3.1/gles2"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
|
||||
"gitea.wisellama.rocks/carpy-breakout/pkg/math_helpers"
|
||||
)
|
||||
|
||||
var OriginalDirection mgl32.Vec3 = mgl32.Vec3{0, 0, -1}
|
||||
/*
|
||||
Positive X = right
|
||||
Positive Y = up
|
||||
Positive Z = backward (outward, towards you)
|
||||
Negative Z = forwards (inward)
|
||||
*/
|
||||
|
||||
type Camera struct {
|
||||
Position mgl32.Vec3
|
||||
Direction mgl32.Vec3
|
||||
OriginalDirection mgl32.Vec3
|
||||
Up mgl32.Vec3
|
||||
OriginalUp mgl32.Vec3
|
||||
Velocity mgl32.Vec3
|
||||
Movestep float32
|
||||
MoveStep float32
|
||||
RotationVelocity float32
|
||||
Rotation mgl32.Vec3
|
||||
RotateStep float32
|
||||
MouseSensitivity float32
|
||||
}
|
||||
|
||||
func NewCamera() (Camera) {
|
||||
camera := Camera{}
|
||||
camera.Up = mgl32.Vec3{0, 1, 0}
|
||||
camera.Direction = OriginalDirection
|
||||
camera.Movestep = 0.1
|
||||
camera.RotateStep = 0.05
|
||||
camera.OriginalUp = mgl32.Vec3{0, 1, 0}
|
||||
camera.Direction = mgl32.Vec3{0, 0, -1}
|
||||
camera.OriginalDirection = mgl32.Vec3{0, 0, -1}
|
||||
camera.MoveStep = 0.1
|
||||
camera.RotateStep = 0.02
|
||||
camera.MouseSensitivity = 0.01
|
||||
return camera
|
||||
}
|
||||
|
||||
|
@ -43,42 +51,60 @@ func (c *Camera) Draw(program uint32) {
|
|||
|
||||
func (c *Camera) Update() {
|
||||
c.Rotate(0, 0)
|
||||
c.Move(c.Velocity.Mul(c.Movestep))
|
||||
c.Move(c.Velocity)
|
||||
}
|
||||
|
||||
func (c *Camera) Rotate(mouseX, mouseY int32) {
|
||||
// X mouse movement = rotation about the Y axis
|
||||
// Y mouse movement = rotation about the X axis
|
||||
|
||||
angle := mgl32.Vec3{}
|
||||
// X Rotation (pitch) - mouse up/down
|
||||
c.Rotation[0] = c.RotateStep * -1 * float32(mouseY) * .01
|
||||
xRotate := mgl32.HomogRotate3DX(c.Rotation[0])
|
||||
c.Up = mgl32.TransformNormal(c.Up, xRotate).Normalize()
|
||||
c.Direction = mgl32.TransformNormal(c.Direction, xRotate).Normalize()
|
||||
|
||||
angle[0] = -1 * float32(mouseY) * c.MouseSensitivity
|
||||
// Y Rotation (yaw) - mouse left/right
|
||||
c.Rotation[1] = c.RotateStep * -1 * float32(mouseX) * .01
|
||||
yRotate := mgl32.HomogRotate3DY(c.Rotation[1])
|
||||
c.Up = mgl32.TransformNormal(c.Up, yRotate).Normalize()
|
||||
c.Direction = mgl32.TransformNormal(c.Direction, yRotate).Normalize()
|
||||
|
||||
angle[1] = -1 * float32(mouseX) * c.MouseSensitivity
|
||||
// Z Rotation (roll) - keyboard z/x
|
||||
c.Rotation[2] = c.RotateStep * c.RotationVelocity
|
||||
zRotate := mgl32.HomogRotate3DZ(c.Rotation[2])
|
||||
c.Up = mgl32.TransformNormal(c.Up, zRotate).Normalize()
|
||||
c.Direction = mgl32.TransformNormal(c.Direction, zRotate).Normalize()
|
||||
angle[2] = c.RotationVelocity
|
||||
|
||||
if angle.LenSqr() == 0 {
|
||||
return
|
||||
}
|
||||
angle = angle.Mul(c.RotateStep)
|
||||
|
||||
relativeY := c.Up
|
||||
relativeZ := c.Direction
|
||||
relativeX := relativeZ.Cross(relativeY)
|
||||
|
||||
quatX := mgl32.QuatRotate(angle.X(), relativeX)
|
||||
c.Up = quatX.Rotate(c.Up)
|
||||
c.Direction = quatX.Rotate(c.Direction)
|
||||
|
||||
quatY := mgl32.QuatRotate(angle.Y(), relativeY)
|
||||
c.Up = quatY.Rotate(c.Up)
|
||||
c.Direction = quatY.Rotate(c.Direction)
|
||||
|
||||
quatZ := mgl32.QuatRotate(angle.Z(), relativeZ)
|
||||
c.Up = quatZ.Rotate(c.Up)
|
||||
c.Direction = quatZ.Rotate(c.Direction)
|
||||
}
|
||||
|
||||
func (c *Camera) Move(vec mgl32.Vec3) {
|
||||
// Rotate our movement vector to apply in our current direction
|
||||
rotation := math_helpers.RotationMatrix(vec, c.Direction)
|
||||
t := mgl32.TransformCoordinate(vec, rotation)
|
||||
log.Println(vec)
|
||||
log.Println(t)
|
||||
if vec.LenSqr() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Then translate
|
||||
translation := mgl32.Translate3D(t.X(), t.Y(), t.Z())
|
||||
c.Position = mgl32.TransformCoordinate(c.Position, translation)
|
||||
vec = vec.Normalize()
|
||||
vec = vec.Mul(c.MoveStep)
|
||||
|
||||
perp := c.Direction.Cross(c.Up)
|
||||
relativeY := c.Up.Mul(vec.Y())
|
||||
relativeZ := c.Direction.Mul(vec.Z())
|
||||
relativeX := perp.Mul(vec.X())
|
||||
|
||||
relativeMove := mgl32.Vec3{}
|
||||
relativeMove = relativeMove.Add(relativeX)
|
||||
relativeMove = relativeMove.Add(relativeY)
|
||||
relativeMove = relativeMove.Add(relativeZ)
|
||||
log.Printf("relativeMove = %v, vec = %v", relativeMove.Len(), vec.Len())
|
||||
|
||||
c.Position = c.Position.Add(relativeMove)
|
||||
}
|
||||
|
||||
func (c *Camera) SetXVelocity(v float32) {
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
# How to rotate using Quaternions
|
||||
|
||||
https://math.stackexchange.com/a/535223
|
||||
|
||||
To answer the question simply, given:
|
||||
|
||||
```
|
||||
P = [0, p1, p2, p3] <-- point vector
|
||||
R = [w, x, y, z] <-- rotation
|
||||
R' = [w, -x, -y, -z]
|
||||
```
|
||||
|
||||
For the example in the question, these are:
|
||||
|
||||
```
|
||||
P = [0, 1, 0, 0]
|
||||
R = [0.707, 0.0, 0.707, 0.0]
|
||||
R' = [0.707, 0.0, -0.707, 0.0]
|
||||
```
|
||||
|
||||
You can calculate the resulting vector using the Hamilton product H(a, b) by:
|
||||
|
||||
```
|
||||
P' = RPR'
|
||||
P' = H(H(R, P), R')
|
||||
```
|
||||
|
||||
Performing the calculations:
|
||||
|
||||
```
|
||||
H(R, P) = [0.0, 0.707, 0.0, -0.707]
|
||||
P' = H(H(R, P), R') = [0.0, 0.0, 0.0, -1.0 ]
|
||||
```
|
||||
|
||||
Thus, the example above illustrates a rotation of 90 degrees about the
|
||||
y-axis for the point (1, 0, 0). The result is (0, 0, -1). (Note that
|
||||
the first element of P' will always be 0 and can therefore be
|
||||
discarded.)
|
||||
|
||||
For those unfamiliar with quaternions, it's worth noting that the
|
||||
quaternion R may be determined using the formula:
|
||||
|
||||
```
|
||||
a = angle to rotate
|
||||
[x, y, z] = axis to rotate around (unit vector)
|
||||
|
||||
R = [cos(a/2), sin(a/2)*x, sin(a/2)*y, sin(a/2)*z]
|
||||
```
|
||||
|
||||
See here for further reference.
|
||||
http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
|
|
@ -1,15 +0,0 @@
|
|||
package math_helpers
|
||||
|
||||
import (
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
||||
func RotationMatrix(a, b mgl32.Vec3) mgl32.Mat4 {
|
||||
axis := a.Cross(b)
|
||||
angle := a.Dot(b)
|
||||
if angle == 0 || axis.LenSqr() == 0 {
|
||||
return mgl32.Ident4()
|
||||
} else {
|
||||
return mgl32.HomogRotate3D(angle, axis)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue