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
11template<class T>
12struct 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
43template<class T>
44Vector2<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
49template<class T>
50Vector2<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
55template<class T>
56Vector2<T> operator*( const Vector2<T>& lhs, const float& rhs )
57{
58 return Vector2<T>( lhs.x * rhs, lhs.y * rhs );
59}
60
61template<class T>
62Vector2<T> operator/( const Vector2<T>& lhs, const T& rhs )
63{
64 return Vector2<T>( lhs.x / rhs, lhs.y / rhs );
65}
66
67
68typedef Vector2<int32_t> v2i;
69typedef Vector2<float> v2f;
70
71
72template<class T>
73struct 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
123template<class T>
124Vector3<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
129template<class T>
130Vector3<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
135template<class T>
136Vector3<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
141template<class T>
142Vector3<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
147template<class T>
148Vector3<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
153template<class T>
154bool operator<( const Vector3<T>& lhs, const Vector3<T>& rhs )
155{
156 return lhs.Luminance() < rhs.Luminance();
157}
158
159typedef Vector3<int32_t> v3i;
160typedef Vector3<float> v3f;
161typedef Vector3<uint8_t> v3b;
162
163
164static 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
169template<class T>
170Vector3<T> Mix( const Vector3<T>& v1, const Vector3<T>& v2, float amount )
171{
172 return v1 + ( v2 - v1 ) * amount;
173}
174
175template<>
176inline v3b Mix( const v3b& v1, const v3b& v2, float amount )
177{
178 return v3b( v3f( v1 ) + ( v3f( v2 ) - v3f( v1 ) ) * amount );
179}
180
181template<class T>
182Vector3<T> Desaturate( const Vector3<T>& v )
183{
184 T l = v.Luminance();
185 return Vector3<T>( l, l, l );
186}
187
188template<class T>
189Vector3<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
195template<class T>
196Vector3<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
204template<class T>
205Vector3<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
213template<class T>
214Vector3<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