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