source: GTP/trunk/App/Demos/Illum/pathmap/Vector.hpp @ 2197

Revision 2197, 5.9 KB checked in by szirmay, 17 years ago (diff)
Line 
1#pragma once
2
3#include <d3dx9math.h>
4#include <float.h>
5#include <math.h>
6#include <iostream>
7
8/*!
9\brief 3D vector class with overloaded operators.
10Used for positions, directions, colors, etc. It has the same memory layout as D3DXVECTOR3.
11*/
12class Vector {
13public:
14        //constants
15        static const Vector RGBBLACK;
16        static const Vector RGBWHITE;
17        static const Vector RGBRED;
18        static const Vector RGBGREEN;
19        static const Vector RGBBLUE;
20        static const Vector RGBLIGHTBLUE;
21        static const Vector RGBYELLOW;
22        static const Vector RGBORANGE;
23        static const Vector RGBDARKGRAY;
24        static const Vector RGBLIGHTYELLOW;
25
26
27        //Vector is also used for storing colours
28        //data can be accessed through various aliases
29        union{
30                float v[3];
31                struct{ float x; float y; float z; };
32                struct{ float r; float g; float b; };
33                };
34
35        Vector(){}
36
37        Vector(const D3DXVECTOR3& d)
38        {
39                v[0] = d.x;
40                v[1] = d.y;
41                v[2] = d.z;
42        }
43
44        Vector(const D3DXVECTOR2& d)
45        {
46                v[0] = d.x;
47                v[1] = d.y;
48                v[2] = 0.0;
49        }
50
51        Vector(const float x, const float y, const float z)
52        {
53                v[0] = x; v[1] = y; v[2] = z;
54        }
55
56        void set(const float x, const float y, const float z)
57        {
58                v[0] = x; v[1] = y; v[2] = z;
59        }
60
61        void setScaled(float s, const Vector& a)
62        {
63                v[0] = s * a[0]; v[1] = s * a[1]; v[2] = s * a[2];
64        }
65
66        void addScaled(float s, const Vector& a)
67        {
68                v[0] += s * a[0]; v[1] += s * a[1]; v[2] += s * a[2];
69        }
70
71        void clear()
72        {
73                v[0] = v[1] = v[2] = 0;
74        }
75
76        void setDifference(const Vector& a, const Vector& b)
77        {
78                v[0] = a.v[0] - b.v[0];
79                v[1] = a.v[1] - b.v[1];
80                v[2] = a.v[2] - b.v[2];
81        }
82
83        Vector operator-() const
84        {
85                return Vector(-v[0], -v[1], -v[2]);
86        }
87
88        Vector operator+(const Vector& addOperand) const
89        {
90                return Vector ( v[0] + addOperand.v[0],
91                                                v[1] + addOperand.v[1],
92                                                v[2] + addOperand.v[2]);
93        }
94
95        Vector operator-(const Vector& substractOperand) const
96        {
97                return Vector(  v[0] - substractOperand.v[0],
98                                                v[1] - substractOperand.v[1],
99                                                v[2] - substractOperand.v[2]);
100        }
101
102        void operator-=(const Vector& a)
103        {
104                v[0] -= a[0];
105                v[1] -= a[1];
106                v[2] -= a[2];
107        }
108
109        void operator+=(const Vector& a)
110        {
111                v[0] += a[0];
112                v[1] += a[1];
113                v[2] += a[2];
114        }
115
116        //blend operator
117        void operator%=(const Vector& a)
118        {
119                v[0] *= a[0];
120                v[1] *= a[1];
121                v[2] *= a[2];
122        }
123
124        //scale operator
125        void operator*=(const float scale)
126        {
127                v[0] *= scale;
128                v[1] *= scale;
129                v[2] *= scale;
130        }
131
132        //blend operator
133        Vector operator%(const Vector& blendOperand) const
134        {
135                return Vector(  v[0] * blendOperand.v[0],
136                                                v[1] * blendOperand.v[1],
137                                                v[2] * blendOperand.v[2]);
138        }
139
140        //scale operator
141        Vector operator*(const float scale) const
142        {
143                return Vector(scale * v[0], scale * v[1], scale * v[2]);
144        }
145
146        //dot product operator
147        float operator*(const Vector& dotProductOperand) const
148        {
149                return  v[0] * dotProductOperand[0] +
150                                v[1] * dotProductOperand[1] +
151                                v[2] * dotProductOperand[2];
152        }
153
154        //cross product operator
155        Vector operator&&(const Vector& crossProductOperand) const
156        {
157                return Vector(
158                        v[1] * crossProductOperand[2] - v[2] * crossProductOperand[1],
159                        v[2] * crossProductOperand[0] - v[0] * crossProductOperand[2],
160                        v[0] * crossProductOperand[1] - v[1] * crossProductOperand[0]);
161        }
162
163        void setCrossProduct(const Vector& a, const Vector& b)
164        {
165                v[0] = a[1] * b[2] - a[2] * b[1];
166                v[1] = a[2] * b[0] - a[0] * b[2];
167                v[2] = a[0] * b[1] - a[1] * b[0];
168        }
169
170        float norm () const
171        {
172                return sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
173        }
174
175        float norm2 () const
176        {
177                return v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
178        }
179
180        void normalize ()
181        {
182                float length = 1.0f / sqrtf (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
183                v[0] *= length;
184                v[1] *= length;
185                v[2] *= length;
186        }
187
188        float sum () const
189        {
190                return v[0] + v[1] + v[2];
191        }
192
193        const Vector& operator=(const Vector& other)
194        {
195                v[0] = other.v[0];
196                v[1] = other.v[1];
197                v[2] = other.v[2];
198                return *this;
199        }
200
201        float& operator[](const int index)
202        {
203                return v[index];
204        }
205
206        float operator[](const int index) const
207        {
208                return v[index];
209        }
210
211        //accumulate minimum operator
212        void operator<= ( const Vector& zsmall)
213        {
214                if(v[0] > zsmall[0]) v[0] = zsmall[0];
215                if(v[1] > zsmall[1]) v[1] = zsmall[1];
216                if(v[2] > zsmall[2]) v[2] = zsmall[2];
217        }
218
219        //accumulate maximum operator
220        void operator>= ( const Vector& large)
221        {
222                if(v[0] < large[0]) v[0] = large[0];
223                if(v[1] < large[1]) v[1] = large[1];
224                if(v[2] < large[2]) v[2] = large[2];
225        }
226
227        void setIdealReflectedDirection (const Vector& in, const Vector& normal)
228        {
229                *this = in - normal * (2.0f * (normal * in));
230        }
231
232        void setIdealRefractedDirection (const Vector& in, const Vector& normal, float rf)
233        {
234                float nDotIn = in * normal;
235                if(nDotIn < 0.0f)
236                {
237                        float anna = -nDotIn * rf;
238                        float det = anna * anna - rf * rf + 1.0f;
239                        if(det < 0.0f)
240                        { //total reflection
241                                *this = in - normal * (2.0f * (normal * in));
242                                return;
243                        }
244                        float sigma = - anna + sqrt(det);
245                        *this = (in * rf);     
246                        *this += (normal * -sigma);
247                }
248                else
249                {
250                        rf = 1.0f / rf;
251                        float anna = nDotIn * rf;
252                        float det = anna * anna - rf * rf + 1.0f;
253                        if(det < 0.0f)
254                        { //total reflection
255                                *this = in - normal * (2.0f * (normal * in));
256                                return;
257                        }
258                        float sigma = - anna + sqrt(det);
259                        *this = (in * rf);     
260                        *this += (normal * sigma);
261                }
262        }
263
264        void addAccumBlendReflecBlendEmissionScaleDist(const Vector& accum,
265                                                                                                        const Vector& reflec,
266                                                                                                        const Vector& emission,
267                                                                                                        const float dist2inv)
268        {
269                v[0] += accum.v[0] * reflec.v[0] * emission.v[0] * dist2inv;
270                v[1] += accum.v[1] * reflec.v[1] * emission.v[1] * dist2inv;
271                v[2] += accum.v[2] * reflec.v[2] * emission.v[2] * dist2inv;
272        }
273
274        static const double PI;
275};
276
277std::istream& operator>>(std::istream& cin, Vector& v);
278std::ostream& operator<<(std::ostream& cout, const Vector& v);
Note: See TracBrowser for help on using the repository browser.