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, float f)
83 {
84  dst->m = _mm_add_ps(v->m, _mm_set1_ps(f));
85 }
86 
87 static inline void vec4_subf(struct vec4 *dst, const struct vec4 *v, float f)
88 {
89  dst->m = _mm_sub_ps(v->m, _mm_set1_ps(f));
90 }
91 
92 static inline void vec4_mulf(struct vec4 *dst, const struct vec4 *v, float f)
93 {
94  dst->m = _mm_mul_ps(v->m, _mm_set1_ps(f));
95 }
96 
97 static inline void vec4_divf(struct vec4 *dst, const struct vec4 *v, float f)
98 {
99  dst->m = _mm_div_ps(v->m, _mm_set1_ps(f));
100 }
101 
102 static inline float vec4_dot(const struct vec4 *v1, const struct vec4 *v2)
103 {
104  struct vec4 add;
105  __m128 mul = _mm_mul_ps(v1->m, v2->m);
106  add.m = _mm_add_ps(_mm_movehl_ps(mul, mul), mul);
107  add.m = _mm_add_ps(_mm_shuffle_ps(add.m, add.m, 0x55), add.m);
108  return add.x;
109 }
110 
111 static inline void vec4_neg(struct vec4 *dst, const struct vec4 *v)
112 {
113  dst->x = -v->x;
114  dst->y = -v->y;
115  dst->z = -v->z;
116  dst->w = -v->w;
117 }
118 
119 static inline float vec4_len(const struct vec4 *v)
120 {
121  float dot_val = vec4_dot(v, v);
122  return (dot_val > 0.0f) ? sqrtf(dot_val) : 0.0f;
123 }
124 
125 static inline float vec4_dist(const struct vec4 *v1, const struct vec4 *v2)
126 {
127  struct vec4 temp;
128  float dot_val;
129 
130  vec4_sub(&temp, v1, v2);
131  dot_val = vec4_dot(&temp, &temp);
132  return (dot_val > 0.0f) ? sqrtf(dot_val) : 0.0f;
133 }
134 
135 static inline void vec4_norm(struct vec4 *dst, const struct vec4 *v)
136 {
137  float dot_val = vec4_dot(v, v);
138  dst->m = (dot_val > 0.0f)
139  ? _mm_mul_ps(v->m, _mm_set1_ps(1.0f / sqrtf(dot_val)))
140  : _mm_setzero_ps();
141 }
142 
143 static inline int vec4_close(const struct vec4 *v1, const struct vec4 *v2,
144  float epsilon)
145 {
146  struct vec4 test;
147  vec4_sub(&test, v1, v2);
148  return test.x < epsilon && test.y < epsilon && test.z < epsilon &&
149  test.w < epsilon;
150 }
151 
152 static inline void vec4_min(struct vec4 *dst, const struct vec4 *v1,
153  const struct vec4 *v2)
154 {
155  dst->m = _mm_min_ps(v1->m, v2->m);
156 }
157 
158 static inline void vec4_minf(struct vec4 *dst, const struct vec4 *v, float f)
159 {
160  dst->m = _mm_min_ps(v->m, _mm_set1_ps(f));
161 }
162 
163 static inline void vec4_max(struct vec4 *dst, const struct vec4 *v1,
164  const struct vec4 *v2)
165 {
166  dst->m = _mm_max_ps(v1->m, v2->m);
167 }
168 
169 static inline void vec4_maxf(struct vec4 *dst, const struct vec4 *v, float f)
170 {
171  dst->m = _mm_max_ps(v->m, _mm_set1_ps(f));
172 }
173 
174 static inline void vec4_abs(struct vec4 *dst, const struct vec4 *v)
175 {
176  dst->x = fabsf(v->x);
177  dst->y = fabsf(v->y);
178  dst->z = fabsf(v->z);
179  dst->w = fabsf(v->w);
180 }
181 
182 static inline void vec4_floor(struct vec4 *dst, const struct vec4 *v)
183 {
184  dst->x = floorf(v->x);
185  dst->y = floorf(v->y);
186  dst->z = floorf(v->z);
187  dst->w = floorf(v->w);
188 }
189 
190 static inline void vec4_ceil(struct vec4 *dst, const struct vec4 *v)
191 {
192  dst->x = ceilf(v->x);
193  dst->y = ceilf(v->y);
194  dst->z = ceilf(v->z);
195  dst->w = ceilf(v->w);
196 }
197 
198 static inline uint32_t vec4_to_rgba(const struct vec4 *src)
199 {
200  uint32_t val;
201  val = (uint32_t)((double)src->x * 255.0);
202  val |= (uint32_t)((double)src->y * 255.0) << 8;
203  val |= (uint32_t)((double)src->z * 255.0) << 16;
204  val |= (uint32_t)((double)src->w * 255.0) << 24;
205  return val;
206 }
207 
208 static inline uint32_t vec4_to_bgra(const struct vec4 *src)
209 {
210  uint32_t val;
211  val = (uint32_t)((double)src->z * 255.0);
212  val |= (uint32_t)((double)src->y * 255.0) << 8;
213  val |= (uint32_t)((double)src->x * 255.0) << 16;
214  val |= (uint32_t)((double)src->w * 255.0) << 24;
215  return val;
216 }
217 
218 static inline void vec4_from_rgba(struct vec4 *dst, uint32_t rgba)
219 {
220  dst->x = (float)((double)(rgba & 0xFF) * (1.0 / 255.0));
221  rgba >>= 8;
222  dst->y = (float)((double)(rgba & 0xFF) * (1.0 / 255.0));
223  rgba >>= 8;
224  dst->z = (float)((double)(rgba & 0xFF) * (1.0 / 255.0));
225  rgba >>= 8;
226  dst->w = (float)((double)(rgba & 0xFF) * (1.0 / 255.0));
227 }
228 
229 static inline void vec4_from_bgra(struct vec4 *dst, uint32_t bgra)
230 {
231  dst->z = (float)((double)(bgra & 0xFF) * (1.0 / 255.0));
232  bgra >>= 8;
233  dst->y = (float)((double)(bgra & 0xFF) * (1.0 / 255.0));
234  bgra >>= 8;
235  dst->x = (float)((double)(bgra & 0xFF) * (1.0 / 255.0));
236  bgra >>= 8;
237  dst->w = (float)((double)(bgra & 0xFF) * (1.0 / 255.0));
238 }
239 
240 EXPORT void vec4_transform(struct vec4 *dst, const struct vec4 *v,
241  const struct matrix4 *m);
242 
243 #ifdef __cplusplus
244 }
245 #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