Open Broadcaster Software
Free, open source software for live streaming and recording
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
vec4.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 <xmmintrin.h>
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 struct vec3;
28 struct matrix4;
29 
30 struct vec4 {
31  union {
32  struct {
33  float x, y, z, w;
34  };
35  float ptr[4];
36  __m128 m;
37  };
38 };
39 
40 static inline void vec4_zero(struct vec4 *v)
41 {
42  v->m = _mm_setzero_ps();
43 }
44 
45 static inline void vec4_set(struct vec4 *dst, float x, float y, float z,
46  float w)
47 {
48  dst->m = _mm_set_ps(w, z, y, x);
49 }
50 
51 static inline void vec4_copy(struct vec4 *dst, const struct vec4 *v)
52 {
53  dst->m = v->m;
54 }
55 
56 EXPORT void vec4_from_vec3(struct vec4 *dst, const struct vec3 *v);
57 
58 static inline void vec4_add(struct vec4 *dst, const struct vec4 *v1,
59  const struct vec4 *v2)
60 {
61  dst->m = _mm_add_ps(v1->m, v2->m);
62 }
63 
64 static inline void vec4_sub(struct vec4 *dst, const struct vec4 *v1,
65  const struct vec4 *v2)
66 {
67  dst->m = _mm_sub_ps(v1->m, v2->m);
68 }
69 
70 static inline void vec4_mul(struct vec4 *dst, const struct vec4 *v1,
71  const struct vec4 *v2)
72 {
73  dst->m = _mm_mul_ps(v1->m, v2->m);
74 }
75 
76 static inline void vec4_div(struct vec4 *dst, const struct vec4 *v1,
77  const struct vec4 *v2)
78 {
79  dst->m = _mm_div_ps(v1->m, v2->m);
80 }
81 
82 static inline void vec4_addf(struct vec4 *dst, const struct vec4 *v,
83  float f)
84 {
85  dst->m = _mm_add_ps(v->m, _mm_set1_ps(f));
86 }
87 
88 static inline void vec4_subf(struct vec4 *dst, const struct vec4 *v,
89  float f)
90 {
91  dst->m = _mm_sub_ps(v->m, _mm_set1_ps(f));
92 }
93 
94 static inline void vec4_mulf(struct vec4 *dst, const struct vec4 *v,
95  float f)
96 {
97  dst->m = _mm_mul_ps(v->m, _mm_set1_ps(f));
98 }
99 
100 static inline void vec4_divf(struct vec4 *dst, const struct vec4 *v,
101  float f)
102 {
103  dst->m = _mm_div_ps(v->m, _mm_set1_ps(f));
104 }
105 
106 static inline float vec4_dot(const struct vec4 *v1, const struct vec4 *v2)
107 {
108  struct vec4 add;
109  __m128 mul = _mm_mul_ps(v1->m, v2->m);
110  add.m = _mm_add_ps(_mm_movehl_ps(mul, mul), mul);
111  add.m = _mm_add_ps(_mm_shuffle_ps(add.m, add.m, 0x55), add.m);
112  return add.x;
113 }
114 
115 static inline void vec4_neg(struct vec4 *dst, const struct vec4 *v)
116 {
117  dst->x = -v->x;
118  dst->y = -v->y;
119  dst->z = -v->z;
120  dst->w = -v->w;
121 }
122 
123 static inline float vec4_len(const struct vec4 *v)
124 {
125  float dot_val = vec4_dot(v, v);
126  return (dot_val > 0.0f) ? sqrtf(dot_val) : 0.0f;
127 }
128 
129 static inline float vec4_dist(const struct vec4 *v1, const struct vec4 *v2)
130 {
131  struct vec4 temp;
132  float dot_val;
133 
134  vec4_sub(&temp, v1, v2);
135  dot_val = vec4_dot(&temp, &temp);
136  return (dot_val > 0.0f) ? sqrtf(dot_val) : 0.0f;
137 }
138 
139 static inline void vec4_norm(struct vec4 *dst, const struct vec4 *v)
140 {
141  float dot_val = vec4_dot(v, v);
142  dst->m = (dot_val > 0.0f) ?
143  _mm_mul_ps(v->m, _mm_set1_ps(1.0f/sqrtf(dot_val))) :
144  _mm_setzero_ps();
145 }
146 
147 static inline int vec4_close(const struct vec4 *v1, const struct vec4 *v2,
148  float epsilon)
149 {
150  struct vec4 test;
151  vec4_sub(&test, v1, v2);
152  return test.x < epsilon &&
153  test.y < epsilon &&
154  test.z < epsilon &&
155  test.w < epsilon;
156 }
157 
158 static inline void vec4_min(struct vec4 *dst, const struct vec4 *v1,
159  const struct vec4 *v2)
160 {
161  dst->m = _mm_min_ps(v1->m, v2->m);
162 }
163 
164 static inline void vec4_minf(struct vec4 *dst, const struct vec4 *v,
165  float f)
166 {
167  dst->m = _mm_min_ps(v->m, _mm_set1_ps(f));
168 }
169 
170 static inline void vec4_max(struct vec4 *dst, const struct vec4 *v1,
171  const struct vec4 *v2)
172 {
173  dst->m = _mm_max_ps(v1->m, v2->m);
174 }
175 
176 static inline void vec4_maxf(struct vec4 *dst, const struct vec4 *v,
177  float f)
178 {
179  dst->m = _mm_max_ps(v->m, _mm_set1_ps(f));
180 }
181 
182 static inline void vec4_abs(struct vec4 *dst, const struct vec4 *v)
183 {
184  dst->x = fabsf(v->x);
185  dst->y = fabsf(v->y);
186  dst->z = fabsf(v->z);
187  dst->w = fabsf(v->w);
188 }
189 
190 static inline void vec4_floor(struct vec4 *dst, const struct vec4 *v)
191 {
192  dst->x = floorf(v->x);
193  dst->y = floorf(v->y);
194  dst->z = floorf(v->z);
195  dst->w = floorf(v->w);
196 }
197 
198 static inline void vec4_ceil(struct vec4 *dst, const struct vec4 *v)
199 {
200  dst->x = ceilf(v->x);
201  dst->y = ceilf(v->y);
202  dst->z = ceilf(v->z);
203  dst->w = ceilf(v->w);
204 }
205 
206 static inline uint32_t vec4_to_rgba(const struct vec4 *src)
207 {
208  uint32_t val;
209  val = (uint32_t)((double)src->x * 255.0);
210  val |= (uint32_t)((double)src->y * 255.0) << 8;
211  val |= (uint32_t)((double)src->z * 255.0) << 16;
212  val |= (uint32_t)((double)src->w * 255.0) << 24;
213  return val;
214 }
215 
216 static inline uint32_t vec4_to_bgra(const struct vec4 *src)
217 {
218  uint32_t val;
219  val = (uint32_t)((double)src->z * 255.0);
220  val |= (uint32_t)((double)src->y * 255.0) << 8;
221  val |= (uint32_t)((double)src->x * 255.0) << 16;
222  val |= (uint32_t)((double)src->w * 255.0) << 24;
223  return val;
224 }
225 
226 static inline void vec4_from_rgba(struct vec4 *dst, uint32_t rgba)
227 {
228  dst->x = (float)((double)(rgba&0xFF) * (1.0/255.0));
229  rgba >>= 8;
230  dst->y = (float)((double)(rgba&0xFF) * (1.0/255.0));
231  rgba >>= 8;
232  dst->z = (float)((double)(rgba&0xFF) * (1.0/255.0));
233  rgba >>= 8;
234  dst->w = (float)((double)(rgba&0xFF) * (1.0/255.0));
235 }
236 
237 static inline void vec4_from_bgra(struct vec4 *dst, uint32_t bgra)
238 {
239  dst->z = (float)((double)(bgra&0xFF) * (1.0/255.0));
240  bgra >>= 8;
241  dst->y = (float)((double)(bgra&0xFF) * (1.0/255.0));
242  bgra >>= 8;
243  dst->x = (float)((double)(bgra&0xFF) * (1.0/255.0));
244  bgra >>= 8;
245  dst->w = (float)((double)(bgra&0xFF) * (1.0/255.0));
246 }
247 
248 EXPORT void vec4_transform(struct vec4 *dst, const struct vec4 *v,
249  const struct matrix4 *m);
250 
251 #ifdef __cplusplus
252 }
253 #endif
EXPORT void vec4_transform(struct vec4 *dst, const struct vec4 *v, const struct matrix4 *m)
EXPORT void vec4_from_vec3(struct vec4 *dst, const struct vec3 *v)
unsigned uint32_t
Definition: vc_stdint.h:31
Definition: vec3.h:33
float ptr[4]
Definition: vec4.h:35
Definition: vec4.h:30
__m128 m
Definition: vec4.h:36
#define EXPORT
Definition: c99defs.h:49
Definition: matrix4.h:32
float w
Definition: vec4.h:33
float z
Definition: vec4.h:33
float x
Definition: vec4.h:33
float y
Definition: vec4.h:33