1 | #ifndef __DARKRL__VECTOR_HPP__ |
2 | #define __DARKRL__VECTOR_HPP__ |
3 | |
4 | #include <assert.h> |
5 | #include <algorithm> |
6 | #include <math.h> |
7 | #include <stdint.h> |
8 | |
9 | #include "Math.hpp" |
10 | |
11 | template<class T> |
12 | struct Vector2 |
13 | { |
14 | Vector2() : x( 0 ), y( 0 ) {} |
15 | Vector2( T v ) : x( v ), y( v ) {} |
16 | Vector2( T _x, T _y ) : x( _x ), y( _y ) {} |
17 | |
18 | bool operator==( const Vector2<T>& rhs ) const { return x == rhs.x && y == rhs.y; } |
19 | bool operator!=( const Vector2<T>& rhs ) const { return !( *this == rhs ); } |
20 | |
21 | Vector2<T>& operator+=( const Vector2<T>& rhs ) |
22 | { |
23 | x += rhs.x; |
24 | y += rhs.y; |
25 | return *this; |
26 | } |
27 | Vector2<T>& operator-=( const Vector2<T>& rhs ) |
28 | { |
29 | x -= rhs.x; |
30 | y -= rhs.y; |
31 | return *this; |
32 | } |
33 | Vector2<T>& operator*=( const Vector2<T>& rhs ) |
34 | { |
35 | x *= rhs.x; |
36 | y *= rhs.y; |
37 | return *this; |
38 | } |
39 | |
40 | T x, y; |
41 | }; |
42 | |
43 | template<class T> |
44 | Vector2<T> operator+( const Vector2<T>& lhs, const Vector2<T>& rhs ) |
45 | { |
46 | return Vector2<T>( lhs.x + rhs.x, lhs.y + rhs.y ); |
47 | } |
48 | |
49 | template<class T> |
50 | Vector2<T> operator-( const Vector2<T>& lhs, const Vector2<T>& rhs ) |
51 | { |
52 | return Vector2<T>( lhs.x - rhs.x, lhs.y - rhs.y ); |
53 | } |
54 | |
55 | template<class T> |
56 | Vector2<T> operator*( const Vector2<T>& lhs, const float& rhs ) |
57 | { |
58 | return Vector2<T>( lhs.x * rhs, lhs.y * rhs ); |
59 | } |
60 | |
61 | template<class T> |
62 | Vector2<T> operator/( const Vector2<T>& lhs, const T& rhs ) |
63 | { |
64 | return Vector2<T>( lhs.x / rhs, lhs.y / rhs ); |
65 | } |
66 | |
67 | |
68 | typedef Vector2<int32_t> v2i; |
69 | typedef Vector2<float> v2f; |
70 | |
71 | |
72 | template<class T> |
73 | struct Vector3 |
74 | { |
75 | Vector3() : x( 0 ), y( 0 ), z( 0 ) {} |
76 | Vector3( T v ) : x( v ), y( v ), z( v ) {} |
77 | Vector3( T _x, T _y, T _z ) : x( _x ), y( _y ), z( _z ) {} |
78 | template<class Y> |
79 | Vector3( const Vector3<Y>& v ) : x( T( v.x ) ), y( T( v.y ) ), z( T( v.z ) ) {} |
80 | |
81 | T Luminance() const { return T( x * 0.3f + y * 0.59f + z * 0.11f ); } |
82 | void Clamp() |
83 | { |
84 | x = std::min( T(1), std::max( T(0), x ) ); |
85 | y = std::min( T(1), std::max( T(0), y ) ); |
86 | z = std::min( T(1), std::max( T(0), z ) ); |
87 | } |
88 | |
89 | bool operator==( const Vector3<T>& rhs ) const { return x == rhs.x && y == rhs.y && z == rhs.z; } |
90 | bool operator!=( const Vector2<T>& rhs ) const { return !( *this == rhs ); } |
91 | |
92 | T& operator[]( unsigned int idx ) { assert( idx < 3 ); return ((T*)this)[idx]; } |
93 | const T& operator[]( unsigned int idx ) const { assert( idx < 3 ); return ((T*)this)[idx]; } |
94 | |
95 | Vector3<T> operator+=( const Vector3<T>& rhs ) |
96 | { |
97 | x += rhs.x; |
98 | y += rhs.y; |
99 | z += rhs.z; |
100 | return *this; |
101 | } |
102 | |
103 | Vector3<T> operator*=( const Vector3<T>& rhs ) |
104 | { |
105 | x *= rhs.x; |
106 | y *= rhs.y; |
107 | z *= rhs.z; |
108 | return *this; |
109 | } |
110 | |
111 | Vector3<T> operator*=( const float& rhs ) |
112 | { |
113 | x *= rhs; |
114 | y *= rhs; |
115 | z *= rhs; |
116 | return *this; |
117 | } |
118 | |
119 | T x, y, z; |
120 | T padding; |
121 | }; |
122 | |
123 | template<class T> |
124 | Vector3<T> operator+( const Vector3<T>& lhs, const Vector3<T>& rhs ) |
125 | { |
126 | return Vector3<T>( lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z ); |
127 | } |
128 | |
129 | template<class T> |
130 | Vector3<T> operator-( const Vector3<T>& lhs, const Vector3<T>& rhs ) |
131 | { |
132 | return Vector3<T>( lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z ); |
133 | } |
134 | |
135 | template<class T> |
136 | Vector3<T> operator*( const Vector3<T>& lhs, const Vector3<T>& rhs ) |
137 | { |
138 | return Vector3<T>( lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z ); |
139 | } |
140 | |
141 | template<class T> |
142 | Vector3<T> operator*( const Vector3<T>& lhs, const float& rhs ) |
143 | { |
144 | return Vector3<T>( T( lhs.x * rhs ), T( lhs.y * rhs ), T( lhs.z * rhs ) ); |
145 | } |
146 | |
147 | template<class T> |
148 | Vector3<T> operator/( const Vector3<T>& lhs, const T& rhs ) |
149 | { |
150 | return Vector3<T>( lhs.x / rhs, lhs.y / rhs, lhs.z / rhs ); |
151 | } |
152 | |
153 | template<class T> |
154 | bool operator<( const Vector3<T>& lhs, const Vector3<T>& rhs ) |
155 | { |
156 | return lhs.Luminance() < rhs.Luminance(); |
157 | } |
158 | |
159 | typedef Vector3<int32_t> v3i; |
160 | typedef Vector3<float> v3f; |
161 | typedef Vector3<uint8_t> v3b; |
162 | |
163 | |
164 | static inline v3b v3f_to_v3b( const v3f& v ) |
165 | { |
166 | return v3b( uint8_t( std::min( 1.f, v.x ) * 255 ), uint8_t( std::min( 1.f, v.y ) * 255 ), uint8_t( std::min( 1.f, v.z ) * 255 ) ); |
167 | } |
168 | |
169 | template<class T> |
170 | Vector3<T> Mix( const Vector3<T>& v1, const Vector3<T>& v2, float amount ) |
171 | { |
172 | return v1 + ( v2 - v1 ) * amount; |
173 | } |
174 | |
175 | template<> |
176 | inline v3b Mix( const v3b& v1, const v3b& v2, float amount ) |
177 | { |
178 | return v3b( v3f( v1 ) + ( v3f( v2 ) - v3f( v1 ) ) * amount ); |
179 | } |
180 | |
181 | template<class T> |
182 | Vector3<T> Desaturate( const Vector3<T>& v ) |
183 | { |
184 | T l = v.Luminance(); |
185 | return Vector3<T>( l, l, l ); |
186 | } |
187 | |
188 | template<class T> |
189 | Vector3<T> Desaturate( const Vector3<T>& v, float mul ) |
190 | { |
191 | T l = T( v.Luminance() * mul ); |
192 | return Vector3<T>( l, l, l ); |
193 | } |
194 | |
195 | template<class T> |
196 | Vector3<T> pow( const Vector3<T>& base, float exponent ) |
197 | { |
198 | return Vector3<T>( |
199 | pow( base.x, exponent ), |
200 | pow( base.y, exponent ), |
201 | pow( base.z, exponent ) ); |
202 | } |
203 | |
204 | template<class T> |
205 | Vector3<T> sRGB2linear( const Vector3<T>& v ) |
206 | { |
207 | return Vector3<T>( |
208 | sRGB2linear( v.x ), |
209 | sRGB2linear( v.y ), |
210 | sRGB2linear( v.z ) ); |
211 | } |
212 | |
213 | template<class T> |
214 | Vector3<T> linear2sRGB( const Vector3<T>& v ) |
215 | { |
216 | return Vector3<T>( |
217 | linear2sRGB( v.x ), |
218 | linear2sRGB( v.y ), |
219 | linear2sRGB( v.z ) ); |
220 | } |
221 | |
222 | #endif |
223 | |