-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathqnorm.py
101 lines (96 loc) · 4.6 KB
/
qnorm.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# vim:ts=4:et
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
from mathutils import Vector
# Covert normals to quake's normal palette. Implementation taken from ajmdl
#
# AJA: I use the following shortcuts to speed up normal lookup:
#
# Firstly, a preliminary match only uses the first quadrant
# (where all coords are >= 0). Then we use the appropriate
# normal index for the actual quadrant. We can do this because
# the 162 MDL/MD2 normals are not arbitrary but are mirrored in
# every quadrant. The eight numbers in the lists above are the
# indices for each quadrant (+++ ++- +-+ +-- -++ -+- --+ ---).
#
# Secondly we use the axis with the greatest magnitude (of the
# incoming normal) to search an axis-specific group, which means
# we only need to check about 1/3rd of the normals.
# Actually, about 1/14th (taniwha)
x_group = (
(Vector((1.0000, 0.0000, 0.0000)), (52, 52, 52, 52, 143, 143, 143, 143)),
(Vector((0.9554, 0.2952, 0.0000)), (51, 51, 55, 55, 141, 141, 145, 145)),
(Vector((0.9511, 0.1625, 0.2629)), (53, 63, 57, 70, 142, 148, 146, 151)),
(Vector((0.8642, 0.4429, 0.2389)), (46, 61, 56, 69, 19, 147, 123, 150)),
(Vector((0.8507, 0.5257, 0.0000)), (41, 41, 54, 54, 18, 18, 116, 116)),
(Vector((0.8507, 0.0000, 0.5257)), (60, 67, 60, 67, 144, 155, 144, 155)),
(Vector((0.8090, 0.3090, 0.5000)), (48, 62, 58, 68, 16, 149, 124, 152)),
(Vector((0.7166, 0.6817, 0.1476)), (42, 43, 111, 100, 20, 25, 118, 117)),
(Vector((0.6882, 0.5878, 0.4253)), (47, 76, 140, 101, 21, 156, 125, 161)),
(Vector((0.6817, 0.1476, 0.7166)), (49, 65, 59, 66, 15, 153, 126, 154)),
(Vector((0.5878, 0.4253, 0.6882)), (50, 75, 139, 102, 17, 157, 128, 160))
)
y_group = (
(Vector((0.0000, 1.0000, 0.0000)), (32, 32, 104, 104, 32, 32, 104, 104)),
(Vector((0.0000, 0.9554, 0.2952)), (33, 30, 107, 103, 33, 30, 107, 103)),
(Vector((0.2629, 0.9511, 0.1625)), (36, 39, 109, 105, 34, 31, 122, 115)),
(Vector((0.2389, 0.8642, 0.4429)), (35, 38, 108, 97, 23, 29, 121, 113)),
(Vector((0.5257, 0.8507, 0.0000)), (44, 44, 112, 112, 27, 27, 119, 119)),
(Vector((0.0000, 0.8507, 0.5257)), (6, 28, 106, 90, 6, 28, 106, 90)),
(Vector((0.5000, 0.8090, 0.3090)), (37, 40, 110, 98, 22, 26, 120, 114)),
(Vector((0.1476, 0.7166, 0.6817)), (8, 71, 136, 92, 7, 77, 130, 91)),
(Vector((0.4253, 0.6882, 0.5878)), (45, 73, 138, 99, 24, 158, 131, 159)),
(Vector((0.7166, 0.6817, 0.1476)), (42, 43, 111, 100, 20, 25, 118, 117)),
(Vector((0.6882, 0.5878, 0.4253)), (47, 76, 140, 101, 21, 156, 125, 161))
)
z_group = (
(Vector((0.0000, 0.0000, 1.0000)), (5, 84, 5, 84, 5, 84, 5, 84)),
(Vector((0.2952, 0.0000, 0.9554)), (12, 85, 12, 85, 2, 82, 2, 82)),
(Vector((0.1625, 0.2629, 0.9511)), (14, 86, 134, 96, 4, 83, 132, 89)),
(Vector((0.4429, 0.2389, 0.8642)), (13, 74, 133, 95, 1, 81, 127, 87)),
(Vector((0.5257, 0.0000, 0.8507)), (11, 64, 11, 64, 0, 80, 0, 80)),
(Vector((0.0000, 0.5257, 0.8507)), (9, 79, 137, 93, 9, 79, 137, 93)),
(Vector((0.3090, 0.5000, 0.8090)), (10, 72, 135, 94, 3, 78, 129, 88)),
(Vector((0.6817, 0.1476, 0.7166)), (49, 65, 59, 66, 15, 153, 126, 154)),
(Vector((0.5878, 0.4253, 0.6882)), (50, 75, 139, 102, 17, 157, 128, 160)),
(Vector((0.1476, 0.7166, 0.6817)), (8, 71, 136, 92, 7, 77, 130, 91)),
(Vector((0.4253, 0.6882, 0.5878)), (45, 73, 138, 99, 24, 158, 131, 159))
)
def map_normal(n):
fn = Vector((abs(n.x), abs(n.y), abs(n.z)))
group = x_group
if fn.y > fn.x and fn.y > fn.z:
group = y_group
if fn.z > fn.x and fn.z > fn.y:
group = z_group
best = 0
best_dot = -1
for i in range(len(group)):
dot = group[i][0].dot(fn)
if dot > best_dot:
best = i
best_dot = dot
quadrant = 0
if n.x < 0:
quadrant += 4
if n.y < 0:
quadrant += 2
if n.z < 0:
quadrant += 1
return group[best][1][quadrant]