Lightmetrica  0.0.1.50dbee3 (yosakoi)
 All Classes Functions Variables Typedefs Enumerations Enumerator
math.vector.h
1 /*
2  Lightmetrica : A research-oriented renderer
3 
4  Copyright (c) 2014 Hisanari Otsu
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #pragma once
21 #ifndef LIB_LIGHTMETRICA_VECTOR_H
22 #define LIB_LIGHTMETRICA_VECTOR_H
23 
24 #include "math.common.h"
25 #include "math.simd.h"
26 
27 LM_NAMESPACE_BEGIN
28 LM_MATH_NAMESPACE_BEGIN
29 
30 template <typename T> struct TVec2;
31 template <typename T> struct TVec3;
32 template <typename T> struct TVec4;
33 
39 template <typename T>
40 struct TVec2
41 {
42 
43  T x, y;
44 
45  LM_FORCE_INLINE TVec2();
46  LM_FORCE_INLINE TVec2(const TVec2<T>& v);
47  LM_FORCE_INLINE TVec2(const TVec3<T>& v);
48  LM_FORCE_INLINE TVec2(const TVec4<T>& v);
49  LM_FORCE_INLINE TVec2(const T& v);
50  LM_FORCE_INLINE TVec2(const T& x, const T& y);
51  LM_FORCE_INLINE T& operator[](int i);
52  LM_FORCE_INLINE const T& operator[](int i) const;
53  LM_FORCE_INLINE TVec2<T>& operator=(const TVec2<T>& v);
54  LM_FORCE_INLINE TVec2<T>& operator+=(const TVec2<T>& v);
55  LM_FORCE_INLINE TVec2<T>& operator-=(const TVec2<T>& v);
56  LM_FORCE_INLINE TVec2<T>& operator*=(const TVec2<T>& v);
57  LM_FORCE_INLINE TVec2<T>& operator*=(const T& s);
58  LM_FORCE_INLINE TVec2<T>& operator/=(const TVec2<T>& v);
59  LM_FORCE_INLINE TVec2<T>& operator/=(const T& s);
60 
61 };
62 
63 template <typename T> LM_FORCE_INLINE TVec2<T> operator+(const TVec2<T>& v1, const TVec2<T>& v2);
64 template <typename T> LM_FORCE_INLINE TVec2<T> operator-(const TVec2<T>& v1, const TVec2<T>& v2);
65 template <typename T> LM_FORCE_INLINE TVec2<T> operator*(const TVec2<T>& v, const T& s);
66 template <typename T> LM_FORCE_INLINE TVec2<T> operator*(const T& s, const TVec2<T>& v);
67 template <typename T> LM_FORCE_INLINE TVec2<T> operator*(const TVec2<T>& v1, const TVec2<T>& v2);
68 template <typename T> LM_FORCE_INLINE TVec2<T> operator/(const TVec2<T>& v, const T& s);
69 template <typename T> LM_FORCE_INLINE TVec2<T> operator/(const TVec2<T>& v1, const TVec2<T>& v2);
70 template <typename T> LM_FORCE_INLINE TVec2<T> operator-(const TVec2<T>& v);
71 template <typename T> LM_FORCE_INLINE bool operator==(const TVec2<T>& v1, const TVec2<T>& v2);
72 template <typename T> LM_FORCE_INLINE bool operator!=(const TVec2<T>& v1, const TVec2<T>& v2);
73 
74 template <typename T> LM_FORCE_INLINE T Length(const TVec2<T>& v);
75 template <typename T> LM_FORCE_INLINE T Length2(const TVec2<T>& v);
76 template <typename T> LM_FORCE_INLINE TVec2<T> Normalize(const TVec2<T>& v);
77 template <typename T> LM_FORCE_INLINE T Dot(const TVec2<T>& v1, const TVec2<T>& v2);
78 template <typename T> LM_FORCE_INLINE T LInfinityNorm(const TVec2<T>& v);
79 
80 template <typename T> LM_FORCE_INLINE TVec2<T> Min(const TVec2<T>& v1, const TVec2<T>& v2);
81 template <typename T> LM_FORCE_INLINE TVec2<T> Max(const TVec2<T>& v1, const TVec2<T>& v2);
82 
83 typedef TVec2<float> Vec2f;
84 typedef TVec2<double> Vec2d;
85 typedef TVec2<int> Vec2i;
86 
87 // --------------------------------------------------------------------------------
88 
94 template <typename T>
95 struct TVec3
96 {
97 
98  T x, y, z;
99 
100  LM_FORCE_INLINE TVec3();
101  LM_FORCE_INLINE TVec3(const TVec2<T>& v);
102  LM_FORCE_INLINE TVec3(const TVec3<T>& v);
103  LM_FORCE_INLINE TVec3(const TVec4<T>& v);
104  LM_FORCE_INLINE TVec3(const T& v);
105  LM_FORCE_INLINE TVec3(const T& x, const T& y, const T& z);
106  LM_FORCE_INLINE TVec3(const TVec2<T>& v, const T& z);
107  LM_FORCE_INLINE T& operator[](int i);
108  LM_FORCE_INLINE const T& operator[](int i) const;
109  LM_FORCE_INLINE TVec3<T>& operator=(const TVec3<T>& v);
110  LM_FORCE_INLINE TVec3<T>& operator+=(const TVec3<T>& v);
111  LM_FORCE_INLINE TVec3<T>& operator-=(const TVec3<T>& v);
112  LM_FORCE_INLINE TVec3<T>& operator*=(const TVec3<T>& v);
113  LM_FORCE_INLINE TVec3<T>& operator*=(const T& s);
114  LM_FORCE_INLINE TVec3<T>& operator/=(const TVec3<T>& v);
115  LM_FORCE_INLINE TVec3<T>& operator/=(const T& s);
116 
117 };
118 
119 template <typename T> LM_FORCE_INLINE TVec3<T> operator+(const TVec3<T>& v1, const TVec3<T>& v2);
120 template <typename T> LM_FORCE_INLINE TVec3<T> operator-(const TVec3<T>& v1, const TVec3<T>& v2);
121 template <typename T> LM_FORCE_INLINE TVec3<T> operator*(const TVec3<T>& v, const T& s);
122 template <typename T> LM_FORCE_INLINE TVec3<T> operator*(const T& s, const TVec3<T>& v);
123 template <typename T> LM_FORCE_INLINE TVec3<T> operator*(const TVec3<T>& v1, const TVec3<T>& v2);
124 template <typename T> LM_FORCE_INLINE TVec3<T> operator/(const TVec3<T>& v, const T& s);
125 template <typename T> LM_FORCE_INLINE TVec3<T> operator/(const TVec3<T>& v1, const TVec3<T>& v2);
126 template <typename T> LM_FORCE_INLINE TVec3<T> operator-(const TVec3<T>& v);
127 template <typename T> LM_FORCE_INLINE bool operator==(const TVec3<T>& v1, const TVec3<T>& v2);
128 template <typename T> LM_FORCE_INLINE bool operator!=(const TVec3<T>& v1, const TVec3<T>& v2);
129 
130 template <typename T> LM_FORCE_INLINE T Length(const TVec3<T>& v);
131 template <typename T> LM_FORCE_INLINE T Length2(const TVec3<T>& v);
132 template <typename T> LM_FORCE_INLINE TVec3<T> Normalize(const TVec3<T>& v);
133 template <typename T> LM_FORCE_INLINE T Dot(const TVec3<T>& v1, const TVec3<T>& v2);
134 template <typename T> LM_FORCE_INLINE TVec3<T> Cross(const TVec3<T>& v1, const TVec3<T>& v2);
135 template <typename T> LM_FORCE_INLINE T LInfinityNorm(const TVec3<T>& v);
136 
137 template <typename T> LM_FORCE_INLINE TVec3<T> Min(const TVec3<T>& v1, const TVec3<T>& v2);
138 template <typename T> LM_FORCE_INLINE TVec3<T> Max(const TVec3<T>& v1, const TVec3<T>& v2);
139 
140 template <typename T> LM_FORCE_INLINE T Luminance(const TVec3<T>& v);
141 template <typename T> LM_FORCE_INLINE bool IsZero(const TVec3<T>& v);
142 
143 // Useful trigonometric functions for shading coordinates.
144 // Theta is the angle between z axis and the given vector.
145 template <typename T> LM_FORCE_INLINE T CosThetaZUp(const TVec3<T>& v);
146 template <typename T> LM_FORCE_INLINE T AbsCosThetaZUp(const TVec3<T>& v);
147 template <typename T> LM_FORCE_INLINE T SinTheta2ZUp(const TVec3<T>& v);
148 template <typename T> LM_FORCE_INLINE T TanThetaZUp(const TVec3<T>& v);
149 template <typename T> LM_FORCE_INLINE TVec3<T> ReflectZUp(const TVec3<T>& wi);
150 template <typename T> LM_FORCE_INLINE TVec3<T> RefractZUp(const TVec3<T>& wi, const T& eta, const T& cosThetaT);
151 
152 typedef TVec3<float> Vec3f;
153 typedef TVec3<double> Vec3d;
154 typedef TVec3<int> Vec3i;
155 
156 // --------------------------------------------------------------------------------
157 
163 template <typename T>
164 struct TVec4
165 {
166 
167  T x, y, z, w;
168 
169  LM_FORCE_INLINE TVec4();
170  LM_FORCE_INLINE TVec4(const TVec2<T>& v);
171  LM_FORCE_INLINE TVec4(const TVec3<T>& v);
172  LM_FORCE_INLINE TVec4(const TVec4<T>& v);
173  LM_FORCE_INLINE TVec4(const T& v);
174  LM_FORCE_INLINE TVec4(const T& x, const T& y, const T& z, const T& w);
175  LM_FORCE_INLINE TVec4(const TVec3<T>& v, const T& w);
176  LM_FORCE_INLINE T& operator[](int i);
177  LM_FORCE_INLINE const T& operator[](int i) const;
178  LM_FORCE_INLINE TVec4<T>& operator=(const TVec4<T>& v);
179  LM_FORCE_INLINE TVec4<T>& operator+=(const TVec4<T>& v);
180  LM_FORCE_INLINE TVec4<T>& operator-=(const TVec4<T>& v);
181  LM_FORCE_INLINE TVec4<T>& operator*=(const TVec4<T>& v);
182  LM_FORCE_INLINE TVec4<T>& operator*=(const T& s);
183  LM_FORCE_INLINE TVec4<T>& operator/=(const TVec4<T>& v);
184  LM_FORCE_INLINE TVec4<T>& operator/=(const T& s);
185 
186 };
187 
188 template <typename T> LM_FORCE_INLINE TVec4<T> operator+(const TVec4<T>& v1, const TVec4<T>& v2);
189 template <typename T> LM_FORCE_INLINE TVec4<T> operator-(const TVec4<T>& v1, const TVec4<T>& v2);
190 template <typename T> LM_FORCE_INLINE TVec4<T> operator*(const TVec4<T>& v, const T& s);
191 template <typename T> LM_FORCE_INLINE TVec4<T> operator*(const T& s, const TVec4<T>& v);
192 template <typename T> LM_FORCE_INLINE TVec4<T> operator*(const TVec4<T>& v1, const TVec4<T>& v2);
193 template <typename T> LM_FORCE_INLINE TVec4<T> operator/(const TVec4<T>& v, const T& s);
194 template <typename T> LM_FORCE_INLINE TVec4<T> operator/(const TVec4<T>& v1, const TVec4<T>& v2);
195 template <typename T> LM_FORCE_INLINE TVec4<T> operator-(const TVec4<T>& v);
196 template <typename T> LM_FORCE_INLINE bool operator==(const TVec4<T>& v1, const TVec4<T>& v2);
197 template <typename T> LM_FORCE_INLINE bool operator!=(const TVec4<T>& v1, const TVec4<T>& v2);
198 
199 template <typename T> LM_FORCE_INLINE T Length(const TVec4<T>& v);
200 template <typename T> LM_FORCE_INLINE T Length2(const TVec4<T>& v);
201 template <typename T> LM_FORCE_INLINE TVec4<T> Normalize(const TVec4<T>& v);
202 template <typename T> LM_FORCE_INLINE T Dot(const TVec4<T>& v1, const TVec4<T>& v2);
203 
204 template <typename T> LM_FORCE_INLINE TVec4<T> Min(const TVec4<T>& v1, const TVec4<T>& v2);
205 template <typename T> LM_FORCE_INLINE TVec4<T> Max(const TVec4<T>& v1, const TVec4<T>& v2);
206 
207 typedef TVec4<float> Vec4f;
208 typedef TVec4<double> Vec4d;
209 typedef TVec4<int> Vec4i;
210 
211 // --------------------------------------------------------------------------------
212 
213 #if LM_SSE2
214 
219 template <>
220 struct LM_ALIGN_16 TVec3<float>
221 {
222 
223  union
224  {
225  __m128 v;
226  struct { float x, y, z, _; };
227  };
228 
229  LM_FORCE_INLINE TVec3();
230  LM_FORCE_INLINE TVec3(const Vec2f& v);
231  LM_FORCE_INLINE TVec3(const Vec3f& v);
232  LM_FORCE_INLINE TVec3(const Vec4f& v);
233  LM_FORCE_INLINE TVec3(float v);
234  LM_FORCE_INLINE TVec3(__m128 v);
235  LM_FORCE_INLINE TVec3(float x, float y, float z);
236  LM_FORCE_INLINE TVec3(const Vec2f& v, float z);
237  LM_FORCE_INLINE float operator[](int i) const;
238  LM_FORCE_INLINE Vec3f& operator=(const Vec3f& v);
239  LM_FORCE_INLINE Vec3f& operator+=(const Vec3f& v);
240  LM_FORCE_INLINE Vec3f& operator-=(const Vec3f& v);
241  LM_FORCE_INLINE Vec3f& operator*=(const Vec3f& v);
242  LM_FORCE_INLINE Vec3f& operator*=(float s);
243  LM_FORCE_INLINE Vec3f& operator/=(const Vec3f& v);
244  LM_FORCE_INLINE Vec3f& operator/=(float s);
245 
246 };
247 
248 template <> LM_FORCE_INLINE Vec3f operator+(const Vec3f& v1, const Vec3f& v2);
249 template <> LM_FORCE_INLINE Vec3f operator-(const Vec3f& v1, const Vec3f& v2);
250 template <> LM_FORCE_INLINE Vec3f operator*(const Vec3f& v, const float& s);
251 template <> LM_FORCE_INLINE Vec3f operator*(const float& s, const Vec3f& v);
252 template <> LM_FORCE_INLINE Vec3f operator*(const Vec3f& v1, const Vec3f& v2);
253 template <> LM_FORCE_INLINE Vec3f operator/(const Vec3f& v, const float& s);
254 template <> LM_FORCE_INLINE Vec3f operator/(const Vec3f& v1, const Vec3f& v2);
255 template <> LM_FORCE_INLINE Vec3f operator-(const Vec3f& v);
256 
257 template <> LM_FORCE_INLINE float Length(const Vec3f& v);
258 template <> LM_FORCE_INLINE float Length2(const Vec3f& v);
259 template <> LM_FORCE_INLINE Vec3f Normalize(const Vec3f& v);
260 template <> LM_FORCE_INLINE float Dot(const Vec3f& v1, const Vec3f& v2);
261 template <> LM_FORCE_INLINE Vec3f Cross(const Vec3f& v1, const Vec3f& v2);
262 template <> LM_FORCE_INLINE float LInfinityNorm(const Vec3f& v);
263 
264 template <> LM_FORCE_INLINE Vec3f Min(const Vec3f& v1, const Vec3f& v2);
265 template <> LM_FORCE_INLINE Vec3f Max(const Vec3f& v1, const Vec3f& v2);
266 
267 template <> LM_FORCE_INLINE bool IsZero(const Vec3f& v);
268 
269 // --------------------------------------------------------------------------------
270 
275 template <>
276 struct LM_ALIGN_16 TVec4<float>
277 {
278 
279  union
280  {
281  __m128 v;
282  struct { float x, y, z, w; };
283  };
284 
285  LM_FORCE_INLINE TVec4();
286  LM_FORCE_INLINE TVec4(const Vec2f& v);
287  LM_FORCE_INLINE TVec4(const Vec3f& v);
288  LM_FORCE_INLINE TVec4(const Vec4f& v);
289  LM_FORCE_INLINE TVec4(float v);
290  LM_FORCE_INLINE TVec4(__m128 v);
291  LM_FORCE_INLINE TVec4(float x, float y, float z, float w);
292  LM_FORCE_INLINE TVec4(const Vec3f& v, float w);
293  LM_FORCE_INLINE float operator[](int i) const;
294  LM_FORCE_INLINE Vec4f& operator=(const Vec4f& v);
295  LM_FORCE_INLINE Vec4f& operator+=(const Vec4f& v);
296  LM_FORCE_INLINE Vec4f& operator-=(const Vec4f& v);
297  LM_FORCE_INLINE Vec4f& operator*=(const Vec4f& v);
298  LM_FORCE_INLINE Vec4f& operator*=(float s);
299  LM_FORCE_INLINE Vec4f& operator/=(const Vec4f& v);
300  LM_FORCE_INLINE Vec4f& operator/=(float s);
301 
302 };
303 
304 template <> LM_FORCE_INLINE Vec4f operator+(const Vec4f& v1, const Vec4f& v2);
305 template <> LM_FORCE_INLINE Vec4f operator-(const Vec4f& v1, const Vec4f& v2);
306 template <> LM_FORCE_INLINE Vec4f operator*(const Vec4f& v, const float& s);
307 template <> LM_FORCE_INLINE Vec4f operator*(const float& s, const Vec4f& v);
308 template <> LM_FORCE_INLINE Vec4f operator*(const Vec4f& v1, const Vec4f& v2);
309 template <> LM_FORCE_INLINE Vec4f operator/(const Vec4f& v, const float& s);
310 template <> LM_FORCE_INLINE Vec4f operator/(const Vec4f& v1, const Vec4f& v2);
311 template <> LM_FORCE_INLINE Vec4f operator-(const Vec4f& v);
312 
313 template <> LM_FORCE_INLINE float Length(const Vec4f& v);
314 template <> LM_FORCE_INLINE float Length2(const Vec4f& v);
315 template <> LM_FORCE_INLINE Vec4f Normalize(const Vec4f& v);
316 template <> LM_FORCE_INLINE float Dot(const Vec4f& v1, const Vec4f& v2);
317 
318 template <> LM_FORCE_INLINE Vec4f Min(const Vec4f& v1, const Vec4f& v2);
319 template <> LM_FORCE_INLINE Vec4f Max(const Vec4f& v1, const Vec4f& v2);
320 
321 #endif
322 
323 // --------------------------------------------------------------------------------
324 
325 #if LM_AVX
326 
331 template <>
332 struct LM_ALIGN_32 TVec3<double>
333 {
334 
335  union
336  {
337  __m256d v;
338  struct { double x, y, z, _; };
339  };
340 
341  LM_FORCE_INLINE TVec3();
342  LM_FORCE_INLINE TVec3(const Vec2d& v);
343  LM_FORCE_INLINE TVec3(const Vec3d& v);
344  LM_FORCE_INLINE TVec3(const Vec4d& v);
345  LM_FORCE_INLINE TVec3(double v);
346  LM_FORCE_INLINE TVec3(__m256d v);
347  LM_FORCE_INLINE TVec3(double x, double y, double z);
348  LM_FORCE_INLINE TVec3(const Vec2d& v, double z);
349  LM_FORCE_INLINE double operator[](int i) const;
350  LM_FORCE_INLINE Vec3d& operator=(const Vec3d& v);
351  LM_FORCE_INLINE Vec3d& operator+=(const Vec3d& v);
352  LM_FORCE_INLINE Vec3d& operator-=(const Vec3d& v);
353  LM_FORCE_INLINE Vec3d& operator*=(const Vec3d& v);
354  LM_FORCE_INLINE Vec3d& operator*=(double s);
355  LM_FORCE_INLINE Vec3d& operator/=(const Vec3d& v);
356  LM_FORCE_INLINE Vec3d& operator/=(double s);
357 
358 };
359 
360 template <> LM_FORCE_INLINE Vec3d operator+(const Vec3d& v1, const Vec3d& v2);
361 template <> LM_FORCE_INLINE Vec3d operator-(const Vec3d& v1, const Vec3d& v2);
362 template <> LM_FORCE_INLINE Vec3d operator*(const Vec3d& v, const double& s);
363 template <> LM_FORCE_INLINE Vec3d operator*(const double& s, const Vec3d& v);
364 template <> LM_FORCE_INLINE Vec3d operator*(const Vec3d& v1, const Vec3d& v2);
365 template <> LM_FORCE_INLINE Vec3d operator/(const Vec3d& v, const double& s);
366 template <> LM_FORCE_INLINE Vec3d operator/(const Vec3d& v1, const Vec3d& v2);
367 template <> LM_FORCE_INLINE Vec3d operator-(const Vec3d& v);
368 
369 template <> LM_FORCE_INLINE double Length(const Vec3d& v);
370 template <> LM_FORCE_INLINE double Length2(const Vec3d& v);
371 template <> LM_FORCE_INLINE Vec3d Normalize(const Vec3d& v);
372 template <> LM_FORCE_INLINE double Dot(const Vec3d& v1, const Vec3d& v2);
373 template <> LM_FORCE_INLINE Vec3d Cross(const Vec3d& v1, const Vec3d& v2);
374 template <> LM_FORCE_INLINE double LInfinityNorm(const Vec3d& v);
375 
376 template <> LM_FORCE_INLINE Vec3d Min(const Vec3d& v1, const Vec3d& v2);
377 template <> LM_FORCE_INLINE Vec3d Max(const Vec3d& v1, const Vec3d& v2);
378 
379 template <> LM_FORCE_INLINE bool IsZero(const Vec3d& v);
380 
381 // --------------------------------------------------------------------------------
382 
387 template <>
388 struct LM_ALIGN_32 TVec4<double>
389 {
390 
391  // Be careful: direct manipulation of the x to w components could incur a performance penalty.
392  // http://www.gamedev.net/topic/434059-accessing-sse-__m128-vectors-fields/
393  union
394  {
395  __m256d v;
396  struct { double x, y, z, w; };
397  };
398 
399  LM_FORCE_INLINE TVec4();
400  LM_FORCE_INLINE TVec4(const Vec2d& v);
401  LM_FORCE_INLINE TVec4(const Vec3d& v);
402  LM_FORCE_INLINE TVec4(const Vec4d& v);
403  LM_FORCE_INLINE TVec4(double v);
404  LM_FORCE_INLINE TVec4(__m256d v);
405  LM_FORCE_INLINE TVec4(double x, double y, double z, double w);
406  LM_FORCE_INLINE TVec4(const Vec3d& v, double w);
407  LM_FORCE_INLINE double operator[](int i) const;
408  LM_FORCE_INLINE Vec4d& operator=(const Vec4d& v);
409  LM_FORCE_INLINE Vec4d& operator+=(const Vec4d& v);
410  LM_FORCE_INLINE Vec4d& operator-=(const Vec4d& v);
411  LM_FORCE_INLINE Vec4d& operator*=(const Vec4d& v);
412  LM_FORCE_INLINE Vec4d& operator*=(double s);
413  LM_FORCE_INLINE Vec4d& operator/=(const Vec4d& v);
414  LM_FORCE_INLINE Vec4d& operator/=(double s);
415 
416 };
417 
418 template <> LM_FORCE_INLINE Vec4d operator+(const Vec4d& v1, const Vec4d& v2);
419 template <> LM_FORCE_INLINE Vec4d operator-(const Vec4d& v1, const Vec4d& v2);
420 template <> LM_FORCE_INLINE Vec4d operator*(const Vec4d& v, const double& s);
421 template <> LM_FORCE_INLINE Vec4d operator*(const double& s, const Vec4d& v);
422 template <> LM_FORCE_INLINE Vec4d operator*(const Vec4d& v1, const Vec4d& v2);
423 template <> LM_FORCE_INLINE Vec4d operator/(const Vec4d& v, const double& s);
424 template <> LM_FORCE_INLINE Vec4d operator/(const Vec4d& v1, const Vec4d& v2);
425 template <> LM_FORCE_INLINE Vec4d operator-(const Vec4d& v);
426 
427 template <> LM_FORCE_INLINE double Length(const Vec4d& v);
428 template <> LM_FORCE_INLINE double Length2(const Vec4d& v);
429 template <> LM_FORCE_INLINE Vec4d Normalize(const Vec4d& v);
430 template <> LM_FORCE_INLINE double Dot(const Vec4d& v1, const Vec4d& v2);
431 
432 template <> LM_FORCE_INLINE Vec4d Min(const Vec4d& v1, const Vec4d& v2);
433 template <> LM_FORCE_INLINE Vec4d Max(const Vec4d& v1, const Vec4d& v2);
434 
435 #endif
436 
437 LM_MATH_NAMESPACE_END
438 LM_NAMESPACE_END
439 
440 #include "math.vector.inl"
441 
442 #endif // LIB_LIGHTMETRICA_VECTOR_H
Definition: math.vector.h:32
Definition: math.vector.h:31
Definition: math.vector.h:30