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 
23 #include "../util/sse-intrin.h"
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 struct plane;
30 struct matrix3;
31 struct matrix4;
32 struct quat;
33 
34 struct vec3 {
35  union {
36  struct {
37  float x, y, z, w;
38  };
39  float ptr[4];
40  __m128 m;
41  };
42 };
43 
44 static inline void vec3_zero(struct vec3 *v)
45 {
46  v->m = _mm_setzero_ps();
47 }
48 
49 static inline void vec3_set(struct vec3 *dst, float x, float y, float z)
50 {
51  dst->m = _mm_set_ps(0.0f, z, y, x);
52 }
53 
54 static inline void vec3_copy(struct vec3 *dst, const struct vec3 *v)
55 {
56  dst->m = v->m;
57 }
58 
59 EXPORT void vec3_from_vec4(struct vec3 *dst, const struct vec4 *v);
60 
61 static inline void vec3_add(struct vec3 *dst, const struct vec3 *v1,
62  const struct vec3 *v2)
63 {
64  dst->m = _mm_add_ps(v1->m, v2->m);
65  dst->w = 0.0f;
66 }
67 
68 static inline void vec3_sub(struct vec3 *dst, const struct vec3 *v1,
69  const struct vec3 *v2)
70 {
71  dst->m = _mm_sub_ps(v1->m, v2->m);
72  dst->w = 0.0f;
73 }
74 
75 static inline void vec3_mul(struct vec3 *dst, const struct vec3 *v1,
76  const struct vec3 *v2)
77 {
78  dst->m = _mm_mul_ps(v1->m, v2->m);
79 }
80 
81 static inline void vec3_div(struct vec3 *dst, const struct vec3 *v1,
82  const struct vec3 *v2)
83 {
84  dst->m = _mm_div_ps(v1->m, v2->m);
85  dst->w = 0.0f;
86 }
87 
88 static inline void vec3_addf(struct vec3 *dst, const struct vec3 *v, 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, float f)
95 {
96  dst->m = _mm_sub_ps(v->m, _mm_set1_ps(f));
97  dst->w = 0.0f;
98 }
99 
100 static inline void vec3_mulf(struct vec3 *dst, const struct vec3 *v, float f)
101 {
102  dst->m = _mm_mul_ps(v->m, _mm_set1_ps(f));
103 }
104 
105 static inline void vec3_divf(struct vec3 *dst, const struct vec3 *v, float f)
106 {
107  dst->m = _mm_div_ps(v->m, _mm_set1_ps(f));
108  dst->w = 0.0f;
109 }
110 
111 static inline float vec3_dot(const struct vec3 *v1, const struct vec3 *v2)
112 {
113  struct vec3 add;
114  __m128 mul = _mm_mul_ps(v1->m, v2->m);
115  add.m = _mm_add_ps(_mm_movehl_ps(mul, mul), mul);
116  add.m = _mm_add_ps(_mm_shuffle_ps(add.m, add.m, 0x55), add.m);
117  return add.x;
118 }
119 
120 static inline void vec3_cross(struct vec3 *dst, const struct vec3 *v1,
121  const struct vec3 *v2)
122 {
123  __m128 s1v1 = _mm_shuffle_ps(v1->m, v1->m, _MM_SHUFFLE(3, 0, 2, 1));
124  __m128 s1v2 = _mm_shuffle_ps(v2->m, v2->m, _MM_SHUFFLE(3, 1, 0, 2));
125  __m128 s2v1 = _mm_shuffle_ps(v1->m, v1->m, _MM_SHUFFLE(3, 1, 0, 2));
126  __m128 s2v2 = _mm_shuffle_ps(v2->m, v2->m, _MM_SHUFFLE(3, 0, 2, 1));
127  dst->m = _mm_sub_ps(_mm_mul_ps(s1v1, s1v2), _mm_mul_ps(s2v1, s2v2));
128 }
129 
130 static inline void vec3_neg(struct vec3 *dst, const struct vec3 *v)
131 {
132  dst->x = -v->x;
133  dst->y = -v->y;
134  dst->z = -v->z;
135  dst->w = 0.0f;
136 }
137 
138 static inline float vec3_len(const struct vec3 *v)
139 {
140  float dot_val = vec3_dot(v, v);
141  return (dot_val > 0.0f) ? sqrtf(dot_val) : 0.0f;
142 }
143 
144 static inline float vec3_dist(const struct vec3 *v1, const struct vec3 *v2)
145 {
146  struct vec3 temp;
147  float dot_val;
148 
149  vec3_sub(&temp, v1, v2);
150  dot_val = vec3_dot(&temp, &temp);
151  return (dot_val > 0.0f) ? sqrtf(dot_val) : 0.0f;
152 }
153 
154 static inline void vec3_norm(struct vec3 *dst, const struct vec3 *v)
155 {
156  float dot_val = vec3_dot(v, v);
157  dst->m = (dot_val > 0.0f)
158  ? _mm_mul_ps(v->m, _mm_set1_ps(1.0f / sqrtf(dot_val)))
159  : _mm_setzero_ps();
160 }
161 
162 static inline bool vec3_close(const struct vec3 *v1, const struct vec3 *v2,
163  float epsilon)
164 {
165  struct vec3 test;
166  vec3_sub(&test, v1, v2);
167  return test.x < epsilon && test.y < epsilon && test.z < epsilon;
168 }
169 
170 static inline void vec3_min(struct vec3 *dst, const struct vec3 *v1,
171  const struct vec3 *v2)
172 {
173  dst->m = _mm_min_ps(v1->m, v2->m);
174  dst->w = 0.0f;
175 }
176 
177 static inline void vec3_minf(struct vec3 *dst, const struct vec3 *v, float f)
178 {
179  dst->m = _mm_min_ps(v->m, _mm_set1_ps(f));
180  dst->w = 0.0f;
181 }
182 
183 static inline void vec3_max(struct vec3 *dst, const struct vec3 *v1,
184  const struct vec3 *v2)
185 {
186  dst->m = _mm_max_ps(v1->m, v2->m);
187  dst->w = 0.0f;
188 }
189 
190 static inline void vec3_maxf(struct vec3 *dst, const struct vec3 *v, float f)
191 {
192  dst->m = _mm_max_ps(v->m, _mm_set1_ps(f));
193  dst->w = 0.0f;
194 }
195 
196 static inline void vec3_abs(struct vec3 *dst, const struct vec3 *v)
197 {
198  dst->x = fabsf(v->x);
199  dst->y = fabsf(v->y);
200  dst->z = fabsf(v->z);
201  dst->w = 0.0f;
202 }
203 
204 static inline void vec3_floor(struct vec3 *dst, const struct vec3 *v)
205 {
206  dst->x = floorf(v->x);
207  dst->y = floorf(v->y);
208  dst->z = floorf(v->z);
209  dst->w = 0.0f;
210 }
211 
212 static inline void vec3_ceil(struct vec3 *dst, const struct vec3 *v)
213 {
214  dst->x = ceilf(v->x);
215  dst->y = ceilf(v->y);
216  dst->z = ceilf(v->z);
217  dst->w = 0.0f;
218 }
219 
220 EXPORT float vec3_plane_dist(const struct vec3 *v, const struct plane *p);
221 
222 EXPORT void vec3_transform(struct vec3 *dst, const struct vec3 *v,
223  const struct matrix4 *m);
224 
225 EXPORT void vec3_rotate(struct vec3 *dst, const struct vec3 *v,
226  const struct matrix3 *m);
227 EXPORT void vec3_transform3x4(struct vec3 *dst, const struct vec3 *v,
228  const struct matrix3 *m);
229 
230 EXPORT void vec3_mirror(struct vec3 *dst, const struct vec3 *v,
231  const struct plane *p);
232 EXPORT void vec3_mirrorv(struct vec3 *dst, const struct vec3 *v,
233  const struct vec3 *vec);
234 
235 EXPORT void vec3_rand(struct vec3 *dst, int positive_only);
236 
237 #ifdef __cplusplus
238 }
239 #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:34
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:37
Definition: matrix3.h:31
float z
Definition: vec3.h:37
Definition: vec4.h:31
#define EXPORT
Definition: c99defs.h:37
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:40
Definition: matrix4.h:32
float ptr[4]
Definition: vec3.h:39
Definition: quat.h:42
EXPORT void vec3_transform3x4(struct vec3 *dst, const struct vec3 *v, const struct matrix3 *m)
float x
Definition: vec3.h:37
float y
Definition: vec3.h:37
EXPORT void vec3_mirror(struct vec3 *dst, const struct vec3 *v, const struct plane *p)
Definition: plane.h:30