Open Broadcaster Software
Free, open source software for live streaming and recording
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:53
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