1 #include "xr_vector3.h"
2 #include "xr_math.h"
3 
4 namespace xray_re {
5 
6 static float uv_adjustment[0x2000];
7 static bool initialized = false;
8 
initialize()9 void initialize()
10 {
11 //	for (int i = 0; i != xr_dim(uv_adjustment); ++i) {
12 	for (int i = xr_dim(uv_adjustment); --i >= 0;) {
13 		int u = i >> 7;
14 		int v = i & 0x7f;
15 		if (u + v >= 127) {
16 			u = 127 - u;
17 			v = 127 - v;
18 		}
19 		uv_adjustment[i] = 1.f/std::sqrt(u*u + v*v + (126.f-u-v)*(126.f-u-v));
20 	}
21 	initialized = true;
22 }
23 
decompress(uint16_t s)24 template<> _vector3<float>& _vector3<float>::decompress(uint16_t s)
25 {
26 	if (!initialized)
27 		initialize();
28 
29 	int u = (s >> 7) & 0x3f;
30 	int v = s & 0x7f;
31 	if (u + v >= 127) {
32 		u = 127 - u;
33 		v = 127 - v;
34 	}
35 	float adj = uv_adjustment[s & 0x1fff];
36 	x = adj * u;
37 	y = adj * v;
38 	z = adj * (126 - u - v);
39 	if (s & 0x8000)
40 		x = -x;
41 	if (s & 0x4000)
42 		y = -y;
43 	if (s & 0x2000)
44 		z = -z;
45 	return *this;
46 }
47 
compress() const48 template<> uint16_t _vector3<float>::compress() const
49 {
50 	if (!initialized)
51 		initialize();
52 
53 	uint16_t s = 0;
54 	float _x, _y, _z;
55 	if ((_x = x) < 0) {
56 		_x = -_x;
57 		s |= 0x8000;
58 	}
59 	if ((_y = y) < 0) {
60 		_y = -_y;
61 		s |= 0x4000;
62 	}
63 	if ((_z = z) < 0) {
64 		_z = -_z;
65 		s |= 0x2000;
66 	}
67 	float adj = 126.f/(_x + _y + _z);
68 	int u = int(std::floor(_x * adj));
69 	int v = int(std::floor(_y * adj));
70 	if (u > 63) {
71 		u = 127 - u;
72 		v = 127 - v;
73 	}
74 	return (u << 7) | v | s;
75 }
76 
77 }
78