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,
88  float f)
89 {
90  dst->m = _mm_add_ps(v->m, _mm_set1_ps(f));
91  dst->w = 0.0f;
92 }
93 
94 static inline void vec3_subf(struct vec3 *dst, const struct vec3 *v,
95  float f)
96 {
97  dst->m = _mm_sub_ps(v->m, _mm_set1_ps(f));
98  dst->w = 0.0f;
99 }
100 
101 static inline void vec3_mulf(struct vec3 *dst, const struct vec3 *v,
102  float f)
103 {
104  dst->m = _mm_mul_ps(v->m, _mm_set1_ps(f));
105 }
106 
107 static inline void vec3_divf(struct vec3 *dst, const struct vec3 *v,
108  float f)
109 {
110  dst->m = _mm_div_ps(v->m, _mm_set1_ps(f));
111  dst->w = 0.0f;
112 }
113 
114 static inline float vec3_dot(const struct vec3 *v1, const struct vec3 *v2)
115 {
116  struct vec3 add;
117  __m128 mul = _mm_mul_ps(v1->m, v2->m);
118  add.m = _mm_add_ps(_mm_movehl_ps(mul, mul), mul);
119  add.m = _mm_add_ps(_mm_shuffle_ps(add.m, add.m, 0x55), add.m);
120  return add.x;
121 }
122 
123 static inline void vec3_cross(struct vec3 *dst, const struct vec3 *v1,
124  const struct vec3 *v2)
125 {
126  __m128 s1v1 = _mm_shuffle_ps(v1->m, v1->m, _MM_SHUFFLE(3, 0, 2, 1));
127  __m128 s1v2 = _mm_shuffle_ps(v2->m, v2->m, _MM_SHUFFLE(3, 1, 0, 2));
128  __m128 s2v1 = _mm_shuffle_ps(v1->m, v1->m, _MM_SHUFFLE(3, 1, 0, 2));
129  __m128 s2v2 = _mm_shuffle_ps(v2->m, v2->m, _MM_SHUFFLE(3, 0, 2, 1));
130  dst->m = _mm_sub_ps(_mm_mul_ps(s1v1, s1v2), _mm_mul_ps(s2v1, s2v2));
131 }
132 
133 static inline void vec3_neg(struct vec3 *dst, const struct vec3 *v)
134 {
135  dst->x = -v->x;
136  dst->y = -v->y;
137  dst->z = -v->z;
138  dst->w = 0.0f;
139 }
140 
141 static inline float vec3_len(const struct vec3 *v)
142 {
143  float dot_val = vec3_dot(v, v);
144  return (dot_val > 0.0f) ? sqrtf(dot_val) : 0.0f;
145 }
146 
147 static inline float vec3_dist(const struct vec3 *v1, const struct vec3 *v2)
148 {
149  struct vec3 temp;
150  float dot_val;
151 
152  vec3_sub(&temp, v1, v2);
153  dot_val = vec3_dot(&temp, &temp);
154  return (dot_val > 0.0f) ? sqrtf(dot_val) : 0.0f;
155 }
156 
157 static inline void vec3_norm(struct vec3 *dst, const struct vec3 *v)
158 {
159  float dot_val = vec3_dot(v, v);
160  dst->m = (dot_val > 0.0f) ?
161  _mm_mul_ps(v->m, _mm_set1_ps(1.0f/sqrtf(dot_val))) :
162  _mm_setzero_ps();
163 }
164 
165 static inline bool vec3_close(const struct vec3 *v1, const struct vec3 *v2,
166  float epsilon)
167 {
168  struct vec3 test;
169  vec3_sub(&test, v1, v2);
170  return test.x < epsilon && test.y < epsilon && test.z < epsilon;
171 }
172 
173 static inline void vec3_min(struct vec3 *dst, const struct vec3 *v1,
174  const struct vec3 *v2)
175 {
176  dst->m = _mm_min_ps(v1->m, v2->m);
177  dst->w = 0.0f;
178 }
179 
180 static inline void vec3_minf(struct vec3 *dst, const struct vec3 *v,
181  float f)
182 {
183  dst->m = _mm_min_ps(v->m, _mm_set1_ps(f));
184  dst->w = 0.0f;
185 }
186 
187 static inline void vec3_max(struct vec3 *dst, const struct vec3 *v1,
188  const struct vec3 *v2)
189 {
190  dst->m = _mm_max_ps(v1->m, v2->m);
191  dst->w = 0.0f;
192 }
193 
194 static inline void vec3_maxf(struct vec3 *dst, const struct vec3 *v,
195  float f)
196 {
197  dst->m = _mm_max_ps(v->m, _mm_set1_ps(f));
198  dst->w = 0.0f;
199 }
200 
201 static inline void vec3_abs(struct vec3 *dst, const struct vec3 *v)
202 {
203  dst->x = fabsf(v->x);
204  dst->y = fabsf(v->y);
205  dst->z = fabsf(v->z);
206  dst->w = 0.0f;
207 }
208 
209 static inline void vec3_floor(struct vec3 *dst, const struct vec3 *v)
210 {
211  dst->x = floorf(v->x);
212  dst->y = floorf(v->y);
213  dst->z = floorf(v->z);
214  dst->w = 0.0f;
215 }
216 
217 static inline void vec3_ceil(struct vec3 *dst, const struct vec3 *v)
218 {
219  dst->x = ceilf(v->x);
220  dst->y = ceilf(v->y);
221  dst->z = ceilf(v->z);
222  dst->w = 0.0f;
223 }
224 
225 EXPORT float vec3_plane_dist(const struct vec3 *v, const struct plane *p);
226 
227 EXPORT void vec3_transform(struct vec3 *dst, const struct vec3 *v,
228  const struct matrix4 *m);
229 
230 EXPORT void vec3_rotate(struct vec3 *dst, const struct vec3 *v,
231  const struct matrix3 *m);
232 EXPORT void vec3_transform3x4(struct vec3 *dst, const struct vec3 *v,
233  const struct matrix3 *m);
234 
235 EXPORT void vec3_mirror(struct vec3 *dst, const struct vec3 *v,
236  const struct plane *p);
237 EXPORT void vec3_mirrorv(struct vec3 *dst, const struct vec3 *v,
238  const struct vec3 *vec);
239 
240 EXPORT void vec3_rand(struct vec3 *dst, int positive_only);
241 
242 #ifdef __cplusplus
243 }
244 #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