Skip to content

Commit

Permalink
Merge pull request #33 from krux02/master
Browse files Browse the repository at this point in the history
fixed #30
  • Loading branch information
krux02 authored Oct 23, 2017
2 parents 6f7c3ea + b1c5c3e commit bbbb44e
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 9 deletions.
1 change: 0 additions & 1 deletion glm/mat.nim
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,6 @@ proc mat2*[T](s: T): Mat2[T] =
for i in 0 .. 1:
result.arr[i].arr[i] = s


proc mat4*[T]() : Mat4[T] =
for i in 0 .. 3:
result.arr[i].arr[i] = T(1)
Expand Down
4 changes: 2 additions & 2 deletions glm/mat_transform.nim
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ proc rotate*[T](m:Mat4x4[T]; angle:T, axis:Vec3[T]): Mat4x4[T] {.inline.} =
c = cos(a)
s = sin(a)
var
naxis = normalize(axis)
temp = T(1 - c) * naxis
axis = normalize(axis)
temp = T(1 - c) * axis
Rotate = mat4[T](0)

Rotate[0,0] = c + temp[0] * axis[0]
Expand Down
9 changes: 5 additions & 4 deletions glm/quat.nim
Original file line number Diff line number Diff line change
Expand Up @@ -272,15 +272,16 @@ proc conjugate[T](q: Quat[T]): Quat[T] =
result.arr[2] = -q[2]
result.arr[3] = q[3]


proc inverse*[T](q: Quat[T]) : Quat[T] =
return conjugate(q) / dot(q, q);

#proc rotate[T](q: Quat[T]):
proc rotate*[T](q: Quat[T]; angle: T; v: Vec3[T]) : Quat[T] =
## rotates q around the axis v by the given angle in radians
result.xyz = normalize(v) * sin(angle * 0.5)
result.w = cos(angle * 0.5)
## normalizes ``v`` for you.
result.arr = vec4(
normalize(v) * sin(angle * 0.5),
cos(angle * 0.5)
).arr
result = q * result

proc mat3*[T](q : Quat[T]) : Mat3[T] =
Expand Down
63 changes: 61 additions & 2 deletions tests/quaternion.nim
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
import ../glm


proc epsilonEqual(a,b,epsilon: float32): bool =
return abs(a - b) < epsilon

proc epsilonEqual(a,b: Quatf; epsilon: float32): Vec4b =
for i, x in a - b:
result[i] = abs(x) < epsilon

proc epsilonEqual(a,b: Vec3f; epsilon: float32): Vec3b =
proc epsilonEqual[N,T](a,b: Vec[N,T]; epsilon: T): Vec[N,bool] =
for i, x in (a - b).arr:
result[i] = abs(x) < epsilon

proc epsilonEqual(a,b: Mat4f; epsilon: float32): Mat4[bool] =
for i in 0..<4:
result[i] = epsilonEqual(a.arr[i], b.arr[i], epsilon)

proc angleAxis(angle: float32, axis: Vec3f): Quatf =
quatf(axis, angle)

proc all[N,M](arg: Mat[N,M,bool]): bool =
for x in arg.arr:
if not all(x):
return false
return true

proc test_quat_angle(): int =
var Error: int = 0;

Expand Down Expand Up @@ -277,4 +288,52 @@ Error += test_quat_slerp()
Error += test_size()
Error += test_quat_mat_convert()

quit(Error)
if Error != 0:
quit(Error)

block test_quat_rotate:
let HalfPi = float32(PI * 0.5)

let data = [
(HalfPi, vec3f(1,0,0)),
(HalfPi, vec3f(0,1,0)),
(HalfPi, vec3f(0,0,1)),
(HalfPi, vec3f(-1,0,0)),
(HalfPi, vec3f(0,-1,0)),
(HalfPi, vec3f(0,0,-1)),
(0.123f, vec3f(4,-2,-8))
]

for angle, axis in data.items:
let m1 =
quatf()
.rotate(angle, axis)
.mat4f

let m2 =
mat4f(1)
.rotate(angle, axis)

doAssert all(epsilonEqual(m1,m2, 0.001f))


let m1 =
quatf()
.rotate(HalfPi, vec3f(1,0,0))
.rotate(HalfPi, vec3f(0,1,0))
.mat4f

let m2 =
mat4f(1)
.rotate(HalfPi, vec3f(1,0,0))
.rotate(HalfPi, vec3f(0,1,0))

doAssert all(epsilonEqual(m1,m2, 0.001f))

proc rotate*[T](q: Quat[T]; angle: T; v: Vec3[T]) : Quat[T] =
## rotates q around the axis v by the given angle in radians
result.arr = vec4(
normalize(v) * sin(angle * 0.5),
cos(angle * 0.5)
).arr
result = q * result

0 comments on commit bbbb44e

Please sign in to comment.