generated from taichi-dev/voxel-challenge
-
Notifications
You must be signed in to change notification settings - Fork 19
/
math_utils.py
67 lines (53 loc) · 1.83 KB
/
math_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import math
import taichi as ti
import numpy as np
eps = 1e-4
inf = 1e10
@ti.func
def out_dir(n):
u = ti.Vector([1.0, 0.0, 0.0])
if ti.abs(n[1]) < 1 - 1e-3:
u = n.cross(ti.Vector([0.0, 1.0, 0.0])).normalized()
v = n.cross(u)
phi = 2 * math.pi * ti.random(ti.f32)
r = ti.random(ti.f32)
ay = ti.sqrt(r)
ax = ti.sqrt(1 - r)
return ax * (ti.cos(phi) * u + ti.sin(phi) * v) + ay * n
@ti.func
def ray_aabb_intersection(box_min, box_max, o, d):
intersect = 1
near_int = -inf
far_int = inf
for i in ti.static(range(3)):
if d[i] == 0:
if o[i] < box_min[i] or o[i] > box_max[i]:
intersect = 0
else:
i1 = (box_min[i] - o[i]) / d[i]
i2 = (box_max[i] - o[i]) / d[i]
new_far_int = ti.max(i1, i2)
new_near_int = ti.min(i1, i2)
far_int = ti.min(new_far_int, far_int)
near_int = ti.max(new_near_int, near_int)
if near_int > far_int:
intersect = 0
return intersect, near_int, far_int
def np_normalize(v):
# https://stackoverflow.com/a/51512965/12003165
return v / np.sqrt(np.sum(v**2))
def np_rotate_matrix(axis, theta):
"""
Return the rotation matrix associated with counterclockwise rotation about
the given axis by theta radians.
"""
# https://stackoverflow.com/a/6802723/12003165
axis = np_normalize(axis)
a = math.cos(theta / 2.0)
b, c, d = -axis * math.sin(theta / 2.0)
aa, bb, cc, dd = a * a, b * b, c * c, d * d
bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d
return np.array([[aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac), 0],
[2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab), 0],
[2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc, 0],
[0, 0, 0, 1]])