Open Broadcaster Software
Free, open source software for live streaming and recording
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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