Open Broadcaster Software
Free, open source software for live streaming and recording
vec3.h
Go to the documentation of this file.
1 /******************************************************************************
2  Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
3 
4  This program is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program. If not, see <http://www.gnu.org/licenses/>.
16 ******************************************************************************/
17 
18 #pragma once
19 
20 #include "math-defs.h"
21 #include "vec4.h"
22 #include <xmmintrin.h>
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 struct plane;
29 struct matrix3;
30 struct matrix4;
31 struct quat;
32 
33 struct vec3 {
34  union {
35  struct {
36  float x, y, z, w;
37  };
38  float ptr[4];
39  __m128 m;
40  };
41 };
42 
43 static inline void vec3_zero(struct vec3 *v)
44 {
45  v->m = _mm_setzero_ps();
46 }
47 
48 static inline void vec3_set(struct vec3 *dst, float x, float y, float z)
49 {
50  dst->m = _mm_set_ps(0.0f, z, y, x);
51 }
52 
53 static inline void vec3_copy(struct vec3 *dst, const struct vec3 *v)
54 {
55  dst->m = v->m;
56 }
57 
58 EXPORT void vec3_from_vec4(struct vec3 *dst, const struct vec4 *v);
59 
60 static inline void vec3_add(struct vec3 *dst, const struct vec3 *v1,
61  const struct vec3 *v2)
62 {
63  dst->m = _mm_add_ps(v1->m, v2->m);
64  dst->w = 0.0f;
65 }
66 
67 static inline void vec3_sub(struct vec3 *dst, const struct vec3 *v1,
68  const struct vec3 *v2)
69 {
70  dst->m = _mm_sub_ps(v1->m, v2->m);
71  dst->w = 0.0f;
72 }
73 
74 static inline void vec3_mul(struct vec3 *dst, const struct vec3 *v1,
75  const struct vec3 *v2)
76 {
77  dst->m = _mm_mul_ps(v1->m, v2->m);
78 }
79 
80 static inline void vec3_div(struct vec3 *dst, const struct vec3 *v1,
81  const struct vec3 *v2)
82 {
83  dst->m = _mm_div_ps(v1->m, v2->m);
84  dst->w = 0.0f;
85 }
86 
87 static inline void vec3_addf(struct vec3 *dst, const struct vec3 *v, float f)
88 {
89  dst->m = _mm_add_ps(v->m, _mm_set1_ps(f));
90  dst->w = 0.0f;
91 }
92 
93 static inline void vec3_subf(struct vec3 *dst, const struct vec3 *v, float f)
94 {
95  dst->m = _mm_sub_ps(v->m, _mm_set1_ps(f));
96  dst->w = 0.0f;
97 }
98 
99 static inline void vec3_mulf(struct vec3 *dst, const struct vec3 *v, float f)
100 {
101  dst->m = _mm_mul_ps(v->m, _mm_set1_ps(f));
102 }
103 
104 static inline void vec3_divf(struct vec3 *dst, const struct vec3 *v, float f)
105 {
106  dst->m = _mm_div_ps(v->m, _mm_set1_ps(f));
107  dst->w = 0.0f;
108 }
109 
110 static inline float vec3_dot(const struct vec3 *v1, const struct vec3 *v2)
111 {
112  struct vec3 add;
113  __m128 mul = _mm_mul_ps(v1->m, v2->m);
114  add.m = _mm_add_ps(_mm_movehl_ps(mul, mul), mul);
115  add.m = _mm_add_ps(_mm_shuffle_ps(add.m, add.m, 0x55), add.m);
116  return add.x;
117 }
118 
119 static inline void vec3_cross(struct vec3 *dst, const struct vec3 *v1,
120  const struct vec3 *v2)
121 {
122  __m128 s1v1 = _mm_shuffle_ps(v1->m, v1->m, _MM_SHUFFLE(3, 0, 2, 1));
123  __m128 s1v2 = _mm_shuffle_ps(v2->m, v2->m, _MM_SHUFFLE(3, 1, 0, 2));
124  __m128 s2v1 = _mm_shuffle_ps(v1->m, v1->m, _MM_SHUFFLE(3, 1, 0, 2));
125  __m128 s2v2 = _mm_shuffle_ps(v2->m, v2->m, _MM_SHUFFLE(3, 0, 2, 1));
126  dst->m = _mm_sub_ps(_mm_mul_ps(s1v1, s1v2), _mm_mul_ps(s2v1, s2v2));
127 }
128 
129 static inline void vec3_neg(struct vec3 *dst, const struct vec3 *v)
130 {
131  dst->x = -v->x;
132  dst->y = -v->y;
133  dst->z = -v->z;
134  dst->w = 0.0f;
135 }
136 
137 static inline float vec3_len(const struct vec3 *v)
138 {
139  float dot_val = vec3_dot(v, v);
140  return (dot_val > 0.0f) ? sqrtf(dot_val) : 0.0f;
141 }
142 
143 static inline float vec3_dist(const struct vec3 *v1, const struct vec3 *v2)
144 {
145  struct vec3 temp;
146  float dot_val;
147 
148  vec3_sub(&temp, v1, v2);
149  dot_val = vec3_dot(&temp, &temp);
150  return (dot_val > 0.0f) ? sqrtf(dot_val) : 0.0f;
151 }
152 
153 static inline void vec3_norm(struct vec3 *dst, const struct vec3 *v)
154 {
155  float dot_val = vec3_dot(v, v);
156  dst->m = (dot_val > 0.0f)
157  ? _mm_mul_ps(v->m, _mm_set1_ps(1.0f / sqrtf(dot_val)))
158  : _mm_setzero_ps();
159 }
160 
161 static inline bool vec3_close(const struct vec3 *v1, const struct vec3 *v2,
162  float epsilon)
163 {
164  struct vec3 test;
165  vec3_sub(&test, v1, v2);
166  return test.x < epsilon && test.y < epsilon && test.z < epsilon;
167 }
168 
169 static inline void vec3_min(struct vec3 *dst, const struct vec3 *v1,
170  const struct vec3 *v2)
171 {
172  dst->m = _mm_min_ps(v1->m, v2->m);
173  dst->w = 0.0f;
174 }
175 
176 static inline void vec3_minf(struct vec3 *dst, const struct vec3 *v, float f)
177 {
178  dst->m = _mm_min_ps(v->m, _mm_set1_ps(f));
179  dst->w = 0.0f;
180 }
181 
182 static inline void vec3_max(struct vec3 *dst, const struct vec3 *v1,
183  const struct vec3 *v2)
184 {
185  dst->m = _mm_max_ps(v1->m, v2->m);
186  dst->w = 0.0f;
187 }
188 
189 static inline void vec3_maxf(struct vec3 *dst, const struct vec3 *v, float f)
190 {
191  dst->m = _mm_max_ps(v->m, _mm_set1_ps(f));
192  dst->w = 0.0f;
193 }
194 
195 static inline void vec3_abs(struct vec3 *dst, const struct vec3 *v)
196 {
197  dst->x = fabsf(v->x);
198  dst->y = fabsf(v->y);
199  dst->z = fabsf(v->z);
200  dst->w = 0.0f;
201 }
202 
203 static inline void vec3_floor(struct vec3 *dst, const struct vec3 *v)
204 {
205  dst->x = floorf(v->x);
206  dst->y = floorf(v->y);
207  dst->z = floorf(v->z);
208  dst->w = 0.0f;
209 }
210 
211 static inline void vec3_ceil(struct vec3 *dst, const struct vec3 *v)
212 {
213  dst->x = ceilf(v->x);
214  dst->y = ceilf(v->y);
215  dst->z = ceilf(v->z);
216  dst->w = 0.0f;
217 }
218 
219 EXPORT float vec3_plane_dist(const struct vec3 *v, const struct plane *p);
220 
221 EXPORT void vec3_transform(struct vec3 *dst, const struct vec3 *v,
222  const struct matrix4 *m);
223 
224 EXPORT void vec3_rotate(struct vec3 *dst, const struct vec3 *v,
225  const struct matrix3 *m);
226 EXPORT void vec3_transform3x4(struct vec3 *dst, const struct vec3 *v,
227  const struct matrix3 *m);
228 
229 EXPORT void vec3_mirror(struct vec3 *dst, const struct vec3 *v,
230  const struct plane *p);
231 EXPORT void vec3_mirrorv(struct vec3 *dst, const struct vec3 *v,
232  const struct vec3 *vec);
233 
234 EXPORT void vec3_rand(struct vec3 *dst, int positive_only);
235 
236 #ifdef __cplusplus
237 }
238 #endif
EXPORT float vec3_plane_dist(const struct vec3 *v, const struct plane *p)
EXPORT void vec3_rotate(struct vec3 *dst, const struct vec3 *v, const struct matrix3 *m)
Definition: vec3.h:33
EXPORT void vec3_from_vec4(struct vec3 *dst, const struct vec4 *v)
EXPORT void vec3_rand(struct vec3 *dst, int positive_only)
float w
Definition: vec3.h:36
Definition: matrix3.h:31
float z
Definition: vec3.h:36
Definition: vec4.h:30
#define EXPORT
Definition: c99defs.h:49
EXPORT void vec3_transform(struct vec3 *dst, const struct vec3 *v, const struct matrix4 *m)
EXPORT void vec3_mirrorv(struct vec3 *dst, const struct vec3 *v, const struct vec3 *vec)
__m128 m
Definition: vec3.h:39
Definition: matrix4.h:32
float ptr[4]
Definition: vec3.h:38
Definition: quat.h:41
EXPORT void vec3_transform3x4(struct vec3 *dst, const struct vec3 *v, const struct matrix3 *m)
float x
Definition: vec3.h:36
float y
Definition: vec3.h:36
EXPORT void vec3_mirror(struct vec3 *dst, const struct vec3 *v, const struct plane *p)
Definition: plane.h:30