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