-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvclass.h
140 lines (112 loc) · 3.07 KB
/
vclass.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//--------------------------------------------------------------------------------------
// File: vclass.h
//--------------------------------------------------------------------------------------
#ifndef __VCLASS__
#define __VCLASS__
///////////////////////////////////////////////////////////////////////////////
// This example class shows a sketch of how many SIMD game math libraries are
// commonly designed, i.e., encapsulating data and functions inside a class.
// Also it encapsulates overloaded operators to make the design clean and
// friendly to the programmers.
//
// Nonethelss this approach causes the **INEVITABLE CODE BLOAT** when
// performing more complex math expressions.
///////////////////////////////////////////////////////////////////////////////
namespace VCLASS
{
class Vec4
{
public:
inline Vec4() {}
inline Vec4(float *pVec)
: xyzw(_mm_load_ps(pVec))
{ }
inline Vec4(float f)
: xyzw(_mm_set_ps1(f))
{ }
inline Vec4(const __m128& qword)
: xyzw(qword)
{ }
inline Vec4(float x, float y, float z, float w)
: xyzw(_mm_set_ps(x, y, z, w))
{ }
inline Vec4(const Vec4& copy)
: xyzw(copy.xyzw)
{ }
inline Vec4& operator= (const Vec4& copy)
{
xyzw = copy.xyzw;
return *this;
}
inline Vec4& operator+=(const Vec4 &rhs)
{
xyzw = _mm_add_ps(xyzw, rhs.xyzw);
return *this;
}
inline Vec4& operator-=(const Vec4 &rhs)
{
xyzw = _mm_sub_ps(xyzw, rhs.xyzw);
return *this;
}
inline Vec4& operator*=(const Vec4 &rhs)
{
xyzw = _mm_mul_ps(xyzw, rhs.xyzw);
return *this;
}
inline Vec4 operator+(const Vec4 &rhs) const
{
return Vec4(_mm_add_ps(xyzw, rhs.xyzw));
}
inline Vec4 operator*(const Vec4 &rhs) const
{
return Vec4(_mm_mul_ps(xyzw, rhs.xyzw));
}
inline Vec4 operator-(const Vec4 &rhs) const
{
return Vec4(_mm_sub_ps(xyzw, rhs.xyzw));
}
inline Vec4 operator/(const Vec4 &rhs) const
{
return Vec4(_mm_div_ps(xyzw, rhs.xyzw));
}
inline void Store(float *pVec) const
{
_mm_store_ps(pVec, xyzw);
}
inline void Bc()
{
xyzw = _mm_shuffle_ps(xyzw, xyzw, _MM_SHUFFLE(3,3,3,3));
}
static inline Vec4 Dot(const Vec4& va, const Vec4& vb)
{
const __m128 t0 = _mm_mul_ps(va.xyzw, vb.xyzw);
const __m128 t1 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(1,0,3,2));
const __m128 t2 = _mm_add_ps(t0, t1);
const __m128 t3 = _mm_shuffle_ps(t2, t2, _MM_SHUFFLE(2,3,0,1));
return Vec4(_mm_add_ps(t3, t2));
}
static inline Vec4 Sqrt(const Vec4& va)
{
return Vec4(_mm_sqrt_ps(va.xyzw));
}
static inline Vec4 VAdd(const Vec4& va, const Vec4& vb)
{
return Vec4(_mm_add_ps(va.xyzw, vb.xyzw));
}
static inline Vec4 VSub(const Vec4& va, const Vec4& vb)
{
return Vec4(_mm_sub_ps(va.xyzw, vb.xyzw));
}
static inline Vec4 VMul(const Vec4& va, const Vec4& vb)
{
return Vec4(_mm_mul_ps(va.xyzw, vb.xyzw));
}
static inline void GetX(float *p, const Vec4& v)
{
_mm_store_ss(p, v.xyzw);
}
private:
__m128 xyzw;
};
}
#endif // #ifndef __VCLASS__