This repository has been archived by the owner on Jan 25, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sourcemathlib.cpp
231 lines (192 loc) · 5.51 KB
/
sourcemathlib.cpp
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#include "sourcemathlib.h"
//-----------------------------------------------------------------------------
// Macros and constants required by some of the SSE assembly:
//-----------------------------------------------------------------------------
#ifdef _WIN32
#define _PS_EXTERN_CONST(Name, Val) \
const __declspec(align(16)) float _ps_##Name[4] = { Val, Val, Val, Val }
#define _PS_EXTERN_CONST_TYPE(Name, Type, Val) \
const __declspec(align(16)) Type _ps_##Name[4] = { Val, Val, Val, Val }; \
#define _EPI32_CONST(Name, Val) \
static const __declspec(align(16)) __int32 _epi32_##Name[4] = { Val, Val, Val, Val }
#define _PS_CONST(Name, Val) \
static const __declspec(align(16)) float _ps_##Name[4] = { Val, Val, Val, Val }
#elif _LINUX
#define _PS_EXTERN_CONST(Name, Val) \
const __attribute__((aligned(16))) float _ps_##Name[4] = { Val, Val, Val, Val }
#define _PS_EXTERN_CONST_TYPE(Name, Type, Val) \
const __attribute__((aligned(16))) Type _ps_##Name[4] = { Val, Val, Val, Val }; \
#define _EPI32_CONST(Name, Val) \
static const __attribute__((aligned(16))) int32 _epi32_##Name[4] = { Val, Val, Val, Val }
#define _PS_CONST(Name, Val) \
static const __attribute__((aligned(16))) float _ps_##Name[4] = { Val, Val, Val, Val }
#endif
_PS_EXTERN_CONST(am_0, 0.0f);
_PS_EXTERN_CONST(am_1, 1.0f);
_PS_EXTERN_CONST(am_m1, -1.0f);
_PS_EXTERN_CONST(am_0p5, 0.5f);
_PS_EXTERN_CONST(am_1p5, 1.5f);
_PS_EXTERN_CONST(am_pi, (float)M_PI);
_PS_EXTERN_CONST(am_pi_o_2, (float)(M_PI / 2.0));
_PS_EXTERN_CONST(am_2_o_pi, (float)(2.0 / M_PI));
_PS_EXTERN_CONST(am_pi_o_4, (float)(M_PI / 4.0));
_PS_EXTERN_CONST(am_4_o_pi, (float)(4.0 / M_PI));
_PS_EXTERN_CONST_TYPE(am_sign_mask, int32, 0x80000000);
_PS_EXTERN_CONST_TYPE(am_inv_sign_mask, int32, ~0x80000000);
_PS_EXTERN_CONST_TYPE(am_min_norm_pos,int32, 0x00800000);
_PS_EXTERN_CONST_TYPE(am_mant_mask, int32, 0x7f800000);
_PS_EXTERN_CONST_TYPE(am_inv_mant_mask, int32, ~0x7f800000);
_EPI32_CONST(1, 1);
_EPI32_CONST(2, 2);
_PS_CONST(sincos_p0, 0.15707963267948963959e1f);
_PS_CONST(sincos_p1, -0.64596409750621907082e0f);
_PS_CONST(sincos_p2, 0.7969262624561800806e-1f);
_PS_CONST(sincos_p3, -0.468175413106023168e-2f);
static const uint32 _sincos_masks[] = { (uint32)0x0, (uint32)~0x0 };
static const uint32 _sincos_inv_masks[] = { (uint32)~0x0, (uint32)0x0 };
void SinCos(float x, float* s, float* c)
{
float t4, t8, t12;
__asm
{
movss xmm0, x
movss t12, xmm0
movss xmm1, _ps_am_inv_sign_mask
mov eax, t12
mulss xmm0, _ps_am_2_o_pi
andps xmm0, xmm1
and eax, 0x80000000
cvttss2si edx, xmm0
mov ecx, edx
mov t12, esi
mov esi, edx
add edx, 0x1
shl ecx, (31 - 1)
shl edx, (31 - 1)
movss xmm4, _ps_am_1
cvtsi2ss xmm3, esi
mov t8, eax
and esi, 0x1
subss xmm0, xmm3
movss xmm3, _sincos_inv_masks[esi * 4]
minss xmm0, xmm4
subss xmm4, xmm0
movss xmm6, xmm4
andps xmm4, xmm3
and ecx, 0x80000000
movss xmm2, xmm3
andnps xmm3, xmm0
and edx, 0x80000000
movss xmm7, t8
andps xmm0, xmm2
mov t8, ecx
mov t4, edx
orps xmm4, xmm3
mov eax, s //mov eax, [esp + 4 + 16]
mov edx, c //mov edx, [esp + 4 + 16 + 4]
andnps xmm2, xmm6
orps xmm0, xmm2
movss xmm2, t8
movss xmm1, xmm0
movss xmm5, xmm4
xorps xmm7, xmm2
movss xmm3, _ps_sincos_p3
mulss xmm0, xmm0
mulss xmm4, xmm4
movss xmm2, xmm0
movss xmm6, xmm4
orps xmm1, xmm7
movss xmm7, _ps_sincos_p2
mulss xmm0, xmm3
mulss xmm4, xmm3
movss xmm3, _ps_sincos_p1
addss xmm0, xmm7
addss xmm4, xmm7
movss xmm7, _ps_sincos_p0
mulss xmm0, xmm2
mulss xmm4, xmm6
addss xmm0, xmm3
addss xmm4, xmm3
movss xmm3, t4
mulss xmm0, xmm2
mulss xmm4, xmm6
orps xmm5, xmm3
mov esi, t12
addss xmm0, xmm7
addss xmm4, xmm7
mulss xmm0, xmm1
mulss xmm4, xmm5
// use full stores since caller might reload with full loads
movss [eax], xmm0
movss [edx], xmm4
}
}
//-----------------------------------------------------------------------------
// Euler QAngle -> Basis Vectors
//-----------------------------------------------------------------------------
void AngleVectors (const Vector &angles, Vector *forward) //retrieves v_forward
{
//Assert( s_bMathlibInitialized );
//Assert( forward );
float sp, sy, cp, cy;
SinCos( DEG2RAD( angles[YAW] ), &sy, &cy );
SinCos( DEG2RAD( angles[PITCH] ), &sp, &cp );
forward->x = cp*cy;
forward->y = cp*sy;
forward->z = -sp;
#ifdef DEBUG
printf("v_forward: %f %f %f\n", forward->x, forward->y, forward->z);
#endif
}
void AngleVectors (const Vector &angles, Vector *forward, Vector *right, Vector *up)
{
//Assert( s_bMathlibInitialized );
float sr, sp, sy, cr, cp, cy;
SinCos( DEG2RAD( angles[YAW] ), &sy, &cy );
SinCos( DEG2RAD( angles[PITCH] ), &sp, &cp );
SinCos( DEG2RAD( angles[ROLL] ), &sr, &cr );
if (forward)
{
forward->x = cp*cy;
forward->y = cp*sy;
forward->z = -sp;
}
if (right)
{
right->x = (-1*sr*sp*cy+-1*cr*-sy);
right->y = (-1*sr*sp*sy+-1*cr*cy);
right->z = -1*sr*cp;
}
if (up)
{
up->x = (cr*sp*cy+-sr*-sy);
up->y = (cr*sp*sy+-sr*cy);
up->z = cr*cp;
}
}
void VectorAngles( const float *forward, float *angles )
{
//Assert( s_bMathlibInitialized );
float tmp, yaw, pitch;
if (forward[1] == 0 && forward[0] == 0)
{
yaw = 0;
if (forward[2] > 0)
pitch = 270;
else
pitch = 90;
}
else
{
yaw = (atan2(forward[1], forward[0]) * 180 / M_PI);
if (yaw < 0)
yaw += 360;
tmp = sqrt (forward[0]*forward[0] + forward[1]*forward[1]);
pitch = (atan2(-forward[2], tmp) * 180 / M_PI);
if (pitch < 0)
pitch += 360;
}
angles[0] = pitch;
angles[1] = yaw;
angles[2] = 0;
}