[216] | 1 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
| 2 | /** |
---|
| 3 | * Contains code for 3D vectors. |
---|
| 4 | * \file IcePoint.h |
---|
| 5 | * \author Pierre Terdiman |
---|
| 6 | * \date April, 4, 2000 |
---|
| 7 | */ |
---|
| 8 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
| 9 | |
---|
| 10 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
| 11 | // Include Guard |
---|
| 12 | #ifndef __ICEPOINT_H__ |
---|
| 13 | #define __ICEPOINT_H__ |
---|
| 14 | |
---|
| 15 | // Forward declarations |
---|
| 16 | class HPoint; |
---|
| 17 | class Plane; |
---|
| 18 | class Matrix3x3; |
---|
| 19 | class Matrix4x4; |
---|
| 20 | |
---|
| 21 | #define CROSS2D(a, b) (a.x*b.y - b.x*a.y) |
---|
| 22 | |
---|
| 23 | const float EPSILON2 = 1.0e-20f; |
---|
| 24 | |
---|
| 25 | class ICEMATHS_API Point |
---|
| 26 | { |
---|
| 27 | public: |
---|
| 28 | |
---|
| 29 | //! Empty constructor |
---|
| 30 | inline_ Point() {} |
---|
| 31 | //! Constructor from a single float |
---|
| 32 | // inline_ Point(float val) : x(val), y(val), z(val) {} |
---|
| 33 | // Removed since it introduced the nasty "Point T = *Matrix4x4.GetTrans();" bug....... |
---|
| 34 | //! Constructor from floats |
---|
| 35 | inline_ Point(float xx, float yy, float zz) : x(xx), y(yy), z(zz) {} |
---|
| 36 | //! Constructor from array |
---|
| 37 | inline_ Point(const float f[3]) : x(f[X]), y(f[Y]), z(f[Z]) {} |
---|
| 38 | //! Copy constructor |
---|
| 39 | inline_ Point(const Point& p) : x(p.x), y(p.y), z(p.z) {} |
---|
| 40 | //! Destructor |
---|
| 41 | inline_ ~Point() {} |
---|
| 42 | |
---|
| 43 | //! Clears the vector |
---|
| 44 | inline_ Point& Zero() { x = y = z = 0.0f; return *this; } |
---|
| 45 | |
---|
| 46 | //! + infinity |
---|
| 47 | inline_ Point& SetPlusInfinity() { x = y = z = MAX_FLOAT; return *this; } |
---|
| 48 | //! - infinity |
---|
| 49 | inline_ Point& SetMinusInfinity() { x = y = z = MIN_FLOAT; return *this; } |
---|
| 50 | |
---|
| 51 | //! Sets positive unit random vector |
---|
| 52 | Point& PositiveUnitRandomVector(); |
---|
| 53 | //! Sets unit random vector |
---|
| 54 | Point& UnitRandomVector(); |
---|
| 55 | |
---|
| 56 | //! Assignment from values |
---|
| 57 | inline_ Point& Set(float xx, float yy, float zz) { x = xx; y = yy; z = zz; return *this; } |
---|
| 58 | //! Assignment from array |
---|
| 59 | inline_ Point& Set(const float f[3]) { x = f[X]; y = f[Y]; z = f[Z]; return *this; } |
---|
| 60 | //! Assignment from another point |
---|
| 61 | inline_ Point& Set(const Point& src) { x = src.x; y = src.y; z = src.z; return *this; } |
---|
| 62 | |
---|
| 63 | //! Adds a vector |
---|
| 64 | inline_ Point& Add(const Point& p) { x += p.x; y += p.y; z += p.z; return *this; } |
---|
| 65 | //! Adds a vector |
---|
| 66 | inline_ Point& Add(float xx, float yy, float zz) { x += xx; y += yy; z += zz; return *this; } |
---|
| 67 | //! Adds a vector |
---|
| 68 | inline_ Point& Add(const float f[3]) { x += f[X]; y += f[Y]; z += f[Z]; return *this; } |
---|
| 69 | //! Adds vectors |
---|
| 70 | inline_ Point& Add(const Point& p, const Point& q) { x = p.x+q.x; y = p.y+q.y; z = p.z+q.z; return *this; } |
---|
| 71 | |
---|
| 72 | //! Subtracts a vector |
---|
| 73 | inline_ Point& Sub(const Point& p) { x -= p.x; y -= p.y; z -= p.z; return *this; } |
---|
| 74 | //! Subtracts a vector |
---|
| 75 | inline_ Point& Sub(float xx, float yy, float zz) { x -= xx; y -= yy; z -= zz; return *this; } |
---|
| 76 | //! Subtracts a vector |
---|
| 77 | inline_ Point& Sub(const float f[3]) { x -= f[X]; y -= f[Y]; z -= f[Z]; return *this; } |
---|
| 78 | //! Subtracts vectors |
---|
| 79 | inline_ Point& Sub(const Point& p, const Point& q) { x = p.x-q.x; y = p.y-q.y; z = p.z-q.z; return *this; } |
---|
| 80 | |
---|
| 81 | //! this = -this |
---|
| 82 | inline_ Point& Neg() { x = -x; y = -y; z = -z; return *this; } |
---|
| 83 | //! this = -a |
---|
| 84 | inline_ Point& Neg(const Point& a) { x = -a.x; y = -a.y; z = -a.z; return *this; } |
---|
| 85 | |
---|
| 86 | //! Multiplies by a scalar |
---|
| 87 | inline_ Point& Mult(float s) { x *= s; y *= s; z *= s; return *this; } |
---|
| 88 | |
---|
| 89 | //! this = a * scalar |
---|
| 90 | inline_ Point& Mult(const Point& a, float scalar) |
---|
| 91 | { |
---|
| 92 | x = a.x * scalar; |
---|
| 93 | y = a.y * scalar; |
---|
| 94 | z = a.z * scalar; |
---|
| 95 | return *this; |
---|
| 96 | } |
---|
| 97 | |
---|
| 98 | //! this = a + b * scalar |
---|
| 99 | inline_ Point& Mac(const Point& a, const Point& b, float scalar) |
---|
| 100 | { |
---|
| 101 | x = a.x + b.x * scalar; |
---|
| 102 | y = a.y + b.y * scalar; |
---|
| 103 | z = a.z + b.z * scalar; |
---|
| 104 | return *this; |
---|
| 105 | } |
---|
| 106 | |
---|
| 107 | //! this = this + a * scalar |
---|
| 108 | inline_ Point& Mac(const Point& a, float scalar) |
---|
| 109 | { |
---|
| 110 | x += a.x * scalar; |
---|
| 111 | y += a.y * scalar; |
---|
| 112 | z += a.z * scalar; |
---|
| 113 | return *this; |
---|
| 114 | } |
---|
| 115 | |
---|
| 116 | //! this = a - b * scalar |
---|
| 117 | inline_ Point& Msc(const Point& a, const Point& b, float scalar) |
---|
| 118 | { |
---|
| 119 | x = a.x - b.x * scalar; |
---|
| 120 | y = a.y - b.y * scalar; |
---|
| 121 | z = a.z - b.z * scalar; |
---|
| 122 | return *this; |
---|
| 123 | } |
---|
| 124 | |
---|
| 125 | //! this = this - a * scalar |
---|
| 126 | inline_ Point& Msc(const Point& a, float scalar) |
---|
| 127 | { |
---|
| 128 | x -= a.x * scalar; |
---|
| 129 | y -= a.y * scalar; |
---|
| 130 | z -= a.z * scalar; |
---|
| 131 | return *this; |
---|
| 132 | } |
---|
| 133 | |
---|
| 134 | //! this = a + b * scalarb + c * scalarc |
---|
| 135 | inline_ Point& Mac2(const Point& a, const Point& b, float scalarb, const Point& c, float scalarc) |
---|
| 136 | { |
---|
| 137 | x = a.x + b.x * scalarb + c.x * scalarc; |
---|
| 138 | y = a.y + b.y * scalarb + c.y * scalarc; |
---|
| 139 | z = a.z + b.z * scalarb + c.z * scalarc; |
---|
| 140 | return *this; |
---|
| 141 | } |
---|
| 142 | |
---|
| 143 | //! this = a - b * scalarb - c * scalarc |
---|
| 144 | inline_ Point& Msc2(const Point& a, const Point& b, float scalarb, const Point& c, float scalarc) |
---|
| 145 | { |
---|
| 146 | x = a.x - b.x * scalarb - c.x * scalarc; |
---|
| 147 | y = a.y - b.y * scalarb - c.y * scalarc; |
---|
| 148 | z = a.z - b.z * scalarb - c.z * scalarc; |
---|
| 149 | return *this; |
---|
| 150 | } |
---|
| 151 | |
---|
| 152 | //! this = mat * a |
---|
| 153 | inline_ Point& Mult(const Matrix3x3& mat, const Point& a); |
---|
| 154 | |
---|
| 155 | //! this = mat1 * a1 + mat2 * a2 |
---|
| 156 | inline_ Point& Mult2(const Matrix3x3& mat1, const Point& a1, const Matrix3x3& mat2, const Point& a2); |
---|
| 157 | |
---|
| 158 | //! this = this + mat * a |
---|
| 159 | inline_ Point& Mac(const Matrix3x3& mat, const Point& a); |
---|
| 160 | |
---|
| 161 | //! this = transpose(mat) * a |
---|
| 162 | inline_ Point& TransMult(const Matrix3x3& mat, const Point& a); |
---|
| 163 | |
---|
| 164 | //! Linear interpolate between two vectors: this = a + t * (b - a) |
---|
| 165 | inline_ Point& Lerp(const Point& a, const Point& b, float t) |
---|
| 166 | { |
---|
| 167 | x = a.x + t * (b.x - a.x); |
---|
| 168 | y = a.y + t * (b.y - a.y); |
---|
| 169 | z = a.z + t * (b.z - a.z); |
---|
| 170 | return *this; |
---|
| 171 | } |
---|
| 172 | |
---|
| 173 | //! Hermite interpolate between p1 and p2. p0 and p3 are used for finding gradient at p1 and p2. |
---|
| 174 | //! this = p0 * (2t^2 - t^3 - t)/2 |
---|
| 175 | //! + p1 * (3t^3 - 5t^2 + 2)/2 |
---|
| 176 | //! + p2 * (4t^2 - 3t^3 + t)/2 |
---|
| 177 | //! + p3 * (t^3 - t^2)/2 |
---|
| 178 | inline_ Point& Herp(const Point& p0, const Point& p1, const Point& p2, const Point& p3, float t) |
---|
| 179 | { |
---|
| 180 | float t2 = t * t; |
---|
| 181 | float t3 = t2 * t; |
---|
| 182 | float kp0 = (2.0f * t2 - t3 - t) * 0.5f; |
---|
| 183 | float kp1 = (3.0f * t3 - 5.0f * t2 + 2.0f) * 0.5f; |
---|
| 184 | float kp2 = (4.0f * t2 - 3.0f * t3 + t) * 0.5f; |
---|
| 185 | float kp3 = (t3 - t2) * 0.5f; |
---|
| 186 | x = p0.x * kp0 + p1.x * kp1 + p2.x * kp2 + p3.x * kp3; |
---|
| 187 | y = p0.y * kp0 + p1.y * kp1 + p2.y * kp2 + p3.y * kp3; |
---|
| 188 | z = p0.z * kp0 + p1.z * kp1 + p2.z * kp2 + p3.z * kp3; |
---|
| 189 | return *this; |
---|
| 190 | } |
---|
| 191 | |
---|
| 192 | //! this = rotpos * r + linpos |
---|
| 193 | inline_ Point& Transform(const Point& r, const Matrix3x3& rotpos, const Point& linpos); |
---|
| 194 | |
---|
| 195 | //! this = trans(rotpos) * (r - linpos) |
---|
| 196 | inline_ Point& InvTransform(const Point& r, const Matrix3x3& rotpos, const Point& linpos); |
---|
| 197 | |
---|
| 198 | //! Returns MIN(x, y, z); |
---|
| 199 | inline_ float Min() const { return MIN(x, MIN(y, z)); } |
---|
| 200 | //! Returns MAX(x, y, z); |
---|
| 201 | inline_ float Max() const { return MAX(x, MAX(y, z)); } |
---|
| 202 | //! Sets each element to be componentwise minimum |
---|
| 203 | inline_ Point& Min(const Point& p) { x = MIN(x, p.x); y = MIN(y, p.y); z = MIN(z, p.z); return *this; } |
---|
| 204 | //! Sets each element to be componentwise maximum |
---|
| 205 | inline_ Point& Max(const Point& p) { x = MAX(x, p.x); y = MAX(y, p.y); z = MAX(z, p.z); return *this; } |
---|
| 206 | |
---|
| 207 | //! Clamps each element |
---|
| 208 | inline_ Point& Clamp(float min, float max) |
---|
| 209 | { |
---|
| 210 | if(x<min) x=min; if(x>max) x=max; |
---|
| 211 | if(y<min) y=min; if(y>max) y=max; |
---|
| 212 | if(z<min) z=min; if(z>max) z=max; |
---|
| 213 | return *this; |
---|
| 214 | } |
---|
| 215 | |
---|
| 216 | //! Computes square magnitude |
---|
| 217 | inline_ float SquareMagnitude() const { return x*x + y*y + z*z; } |
---|
| 218 | //! Computes magnitude |
---|
| 219 | inline_ float Magnitude() const { return sqrtf(x*x + y*y + z*z); } |
---|
| 220 | //! Computes volume |
---|
| 221 | inline_ float Volume() const { return x * y * z; } |
---|
| 222 | |
---|
| 223 | //! Checks the point is near zero |
---|
| 224 | inline_ bool ApproxZero() const { return SquareMagnitude() < EPSILON2; } |
---|
| 225 | |
---|
| 226 | //! Tests for exact zero vector |
---|
| 227 | inline_ BOOL IsZero() const |
---|
| 228 | { |
---|
| 229 | if(IR(x) || IR(y) || IR(z)) return FALSE; |
---|
| 230 | return TRUE; |
---|
| 231 | } |
---|
| 232 | |
---|
| 233 | //! Checks point validity |
---|
| 234 | inline_ BOOL IsValid() const |
---|
| 235 | { |
---|
| 236 | if(!IsValidFloat(x)) return FALSE; |
---|
| 237 | if(!IsValidFloat(y)) return FALSE; |
---|
| 238 | if(!IsValidFloat(z)) return FALSE; |
---|
| 239 | return TRUE; |
---|
| 240 | } |
---|
| 241 | |
---|
| 242 | //! Slighty moves the point |
---|
| 243 | void Tweak(udword coord_mask, udword tweak_mask) |
---|
| 244 | { |
---|
| 245 | if(coord_mask&1) { udword Dummy = IR(x); Dummy^=tweak_mask; x = FR(Dummy); } |
---|
| 246 | if(coord_mask&2) { udword Dummy = IR(y); Dummy^=tweak_mask; y = FR(Dummy); } |
---|
| 247 | if(coord_mask&4) { udword Dummy = IR(z); Dummy^=tweak_mask; z = FR(Dummy); } |
---|
| 248 | } |
---|
| 249 | |
---|
| 250 | #define TWEAKMASK 0x3fffff |
---|
| 251 | #define TWEAKNOTMASK ~TWEAKMASK |
---|
| 252 | //! Slighty moves the point out |
---|
| 253 | inline_ void TweakBigger() |
---|
| 254 | { |
---|
| 255 | udword Dummy = (IR(x)&TWEAKNOTMASK); if(!IS_NEGATIVE_FLOAT(x)) Dummy+=TWEAKMASK+1; x = FR(Dummy); |
---|
| 256 | Dummy = (IR(y)&TWEAKNOTMASK); if(!IS_NEGATIVE_FLOAT(y)) Dummy+=TWEAKMASK+1; y = FR(Dummy); |
---|
| 257 | Dummy = (IR(z)&TWEAKNOTMASK); if(!IS_NEGATIVE_FLOAT(z)) Dummy+=TWEAKMASK+1; z = FR(Dummy); |
---|
| 258 | } |
---|
| 259 | |
---|
| 260 | //! Slighty moves the point in |
---|
| 261 | inline_ void TweakSmaller() |
---|
| 262 | { |
---|
| 263 | udword Dummy = (IR(x)&TWEAKNOTMASK); if(IS_NEGATIVE_FLOAT(x)) Dummy+=TWEAKMASK+1; x = FR(Dummy); |
---|
| 264 | Dummy = (IR(y)&TWEAKNOTMASK); if(IS_NEGATIVE_FLOAT(y)) Dummy+=TWEAKMASK+1; y = FR(Dummy); |
---|
| 265 | Dummy = (IR(z)&TWEAKNOTMASK); if(IS_NEGATIVE_FLOAT(z)) Dummy+=TWEAKMASK+1; z = FR(Dummy); |
---|
| 266 | } |
---|
| 267 | |
---|
| 268 | //! Normalizes the vector |
---|
| 269 | inline_ Point& Normalize() |
---|
| 270 | { |
---|
| 271 | float M = x*x + y*y + z*z; |
---|
| 272 | if(M) |
---|
| 273 | { |
---|
| 274 | M = 1.0f / sqrtf(M); |
---|
| 275 | x *= M; |
---|
| 276 | y *= M; |
---|
| 277 | z *= M; |
---|
| 278 | } |
---|
| 279 | return *this; |
---|
| 280 | } |
---|
| 281 | |
---|
| 282 | //! Sets vector length |
---|
| 283 | inline_ Point& SetLength(float length) |
---|
| 284 | { |
---|
| 285 | float NewLength = length / Magnitude(); |
---|
| 286 | x *= NewLength; |
---|
| 287 | y *= NewLength; |
---|
| 288 | z *= NewLength; |
---|
| 289 | return *this; |
---|
| 290 | } |
---|
| 291 | |
---|
| 292 | //! Clamps vector length |
---|
| 293 | inline_ Point& ClampLength(float limit_length) |
---|
| 294 | { |
---|
| 295 | if(limit_length>=0.0f) // Magnitude must be positive |
---|
| 296 | { |
---|
| 297 | float CurrentSquareLength = SquareMagnitude(); |
---|
| 298 | |
---|
| 299 | if(CurrentSquareLength > limit_length * limit_length) |
---|
| 300 | { |
---|
| 301 | float Coeff = limit_length / sqrtf(CurrentSquareLength); |
---|
| 302 | x *= Coeff; |
---|
| 303 | y *= Coeff; |
---|
| 304 | z *= Coeff; |
---|
| 305 | } |
---|
| 306 | } |
---|
| 307 | return *this; |
---|
| 308 | } |
---|
| 309 | |
---|
| 310 | //! Computes distance to another point |
---|
| 311 | inline_ float Distance(const Point& b) const |
---|
| 312 | { |
---|
| 313 | return sqrtf((x - b.x)*(x - b.x) + (y - b.y)*(y - b.y) + (z - b.z)*(z - b.z)); |
---|
| 314 | } |
---|
| 315 | |
---|
| 316 | //! Computes square distance to another point |
---|
| 317 | inline_ float SquareDistance(const Point& b) const |
---|
| 318 | { |
---|
| 319 | return ((x - b.x)*(x - b.x) + (y - b.y)*(y - b.y) + (z - b.z)*(z - b.z)); |
---|
| 320 | } |
---|
| 321 | |
---|
| 322 | //! Dot product dp = this|a |
---|
| 323 | inline_ float Dot(const Point& p) const { return p.x * x + p.y * y + p.z * z; } |
---|
| 324 | |
---|
| 325 | //! Cross product this = a x b |
---|
| 326 | inline_ Point& Cross(const Point& a, const Point& b) |
---|
| 327 | { |
---|
| 328 | x = a.y * b.z - a.z * b.y; |
---|
| 329 | y = a.z * b.x - a.x * b.z; |
---|
| 330 | z = a.x * b.y - a.y * b.x; |
---|
| 331 | return *this; |
---|
| 332 | } |
---|
| 333 | |
---|
| 334 | //! Vector code ( bitmask = sign(z) | sign(y) | sign(x) ) |
---|
| 335 | inline_ udword VectorCode() const |
---|
| 336 | { |
---|
| 337 | return (IR(x)>>31) | ((IR(y)&SIGN_BITMASK)>>30) | ((IR(z)&SIGN_BITMASK)>>29); |
---|
| 338 | } |
---|
| 339 | |
---|
| 340 | //! Returns largest axis |
---|
| 341 | inline_ PointComponent LargestAxis() const |
---|
| 342 | { |
---|
| 343 | const float* Vals = &x; |
---|
| 344 | PointComponent m = X; |
---|
| 345 | if(Vals[Y] > Vals[m]) m = Y; |
---|
| 346 | if(Vals[Z] > Vals[m]) m = Z; |
---|
| 347 | return m; |
---|
| 348 | } |
---|
| 349 | |
---|
| 350 | //! Returns closest axis |
---|
| 351 | inline_ PointComponent ClosestAxis() const |
---|
| 352 | { |
---|
| 353 | const float* Vals = &x; |
---|
| 354 | PointComponent m = X; |
---|
| 355 | if(AIR(Vals[Y]) > AIR(Vals[m])) m = Y; |
---|
| 356 | if(AIR(Vals[Z]) > AIR(Vals[m])) m = Z; |
---|
| 357 | return m; |
---|
| 358 | } |
---|
| 359 | |
---|
| 360 | //! Returns smallest axis |
---|
| 361 | inline_ PointComponent SmallestAxis() const |
---|
| 362 | { |
---|
| 363 | const float* Vals = &x; |
---|
| 364 | PointComponent m = X; |
---|
| 365 | if(Vals[Y] < Vals[m]) m = Y; |
---|
| 366 | if(Vals[Z] < Vals[m]) m = Z; |
---|
| 367 | return m; |
---|
| 368 | } |
---|
| 369 | |
---|
| 370 | //! Refracts the point |
---|
| 371 | Point& Refract(const Point& eye, const Point& n, float refractindex, Point& refracted); |
---|
| 372 | |
---|
| 373 | //! Projects the point onto a plane |
---|
| 374 | Point& ProjectToPlane(const Plane& p); |
---|
| 375 | |
---|
| 376 | //! Projects the point onto the screen |
---|
| 377 | void ProjectToScreen(float halfrenderwidth, float halfrenderheight, const Matrix4x4& mat, HPoint& projected) const; |
---|
| 378 | |
---|
| 379 | //! Unfolds the point onto a plane according to edge(a,b) |
---|
| 380 | Point& Unfold(Plane& p, Point& a, Point& b); |
---|
| 381 | |
---|
| 382 | //! Hash function from Ville Miettinen |
---|
| 383 | inline_ udword GetHashValue() const |
---|
| 384 | { |
---|
| 385 | const udword* h = (const udword*)(this); |
---|
| 386 | udword f = (h[0]+h[1]*11-(h[2]*17)) & 0x7fffffff; // avoid problems with +-0 |
---|
| 387 | return (f>>22)^(f>>12)^(f); |
---|
| 388 | } |
---|
| 389 | |
---|
| 390 | //! Stuff magic values in the point, marking it as explicitely not used. |
---|
| 391 | void SetNotUsed(); |
---|
| 392 | //! Checks the point is marked as not used |
---|
| 393 | BOOL IsNotUsed() const; |
---|
| 394 | |
---|
| 395 | // Arithmetic operators |
---|
| 396 | |
---|
| 397 | //! Unary operator for Point Negate = - Point |
---|
| 398 | inline_ Point operator-() const { return Point(-x, -y, -z); } |
---|
| 399 | |
---|
| 400 | //! Operator for Point Plus = Point + Point. |
---|
| 401 | inline_ Point operator+(const Point& p) const { return Point(x + p.x, y + p.y, z + p.z); } |
---|
| 402 | //! Operator for Point Minus = Point - Point. |
---|
| 403 | inline_ Point operator-(const Point& p) const { return Point(x - p.x, y - p.y, z - p.z); } |
---|
| 404 | |
---|
| 405 | //! Operator for Point Mul = Point * Point. |
---|
| 406 | inline_ Point operator*(const Point& p) const { return Point(x * p.x, y * p.y, z * p.z); } |
---|
| 407 | //! Operator for Point Scale = Point * float. |
---|
| 408 | inline_ Point operator*(float s) const { return Point(x * s, y * s, z * s ); } |
---|
| 409 | //! Operator for Point Scale = float * Point. |
---|
| 410 | inline_ friend Point operator*(float s, const Point& p) { return Point(s * p.x, s * p.y, s * p.z); } |
---|
| 411 | |
---|
| 412 | //! Operator for Point Div = Point / Point. |
---|
| 413 | inline_ Point operator/(const Point& p) const { return Point(x / p.x, y / p.y, z / p.z); } |
---|
| 414 | //! Operator for Point Scale = Point / float. |
---|
| 415 | inline_ Point operator/(float s) const { s = 1.0f / s; return Point(x * s, y * s, z * s); } |
---|
| 416 | //! Operator for Point Scale = float / Point. |
---|
| 417 | inline_ friend Point operator/(float s, const Point& p) { return Point(s / p.x, s / p.y, s / p.z); } |
---|
| 418 | |
---|
| 419 | //! Operator for float DotProd = Point | Point. |
---|
| 420 | inline_ float operator|(const Point& p) const { return x*p.x + y*p.y + z*p.z; } |
---|
| 421 | //! Operator for Point VecProd = Point ^ Point. |
---|
| 422 | inline_ Point operator^(const Point& p) const |
---|
| 423 | { |
---|
| 424 | return Point( |
---|
| 425 | y * p.z - z * p.y, |
---|
| 426 | z * p.x - x * p.z, |
---|
| 427 | x * p.y - y * p.x ); |
---|
| 428 | } |
---|
| 429 | |
---|
| 430 | //! Operator for Point += Point. |
---|
| 431 | inline_ Point& operator+=(const Point& p) { x += p.x; y += p.y; z += p.z; return *this; } |
---|
| 432 | //! Operator for Point += float. |
---|
| 433 | inline_ Point& operator+=(float s) { x += s; y += s; z += s; return *this; } |
---|
| 434 | |
---|
| 435 | //! Operator for Point -= Point. |
---|
| 436 | inline_ Point& operator-=(const Point& p) { x -= p.x; y -= p.y; z -= p.z; return *this; } |
---|
| 437 | //! Operator for Point -= float. |
---|
| 438 | inline_ Point& operator-=(float s) { x -= s; y -= s; z -= s; return *this; } |
---|
| 439 | |
---|
| 440 | //! Operator for Point *= Point. |
---|
| 441 | inline_ Point& operator*=(const Point& p) { x *= p.x; y *= p.y; z *= p.z; return *this; } |
---|
| 442 | //! Operator for Point *= float. |
---|
| 443 | inline_ Point& operator*=(float s) { x *= s; y *= s; z *= s; return *this; } |
---|
| 444 | |
---|
| 445 | //! Operator for Point /= Point. |
---|
| 446 | inline_ Point& operator/=(const Point& p) { x /= p.x; y /= p.y; z /= p.z; return *this; } |
---|
| 447 | //! Operator for Point /= float. |
---|
| 448 | inline_ Point& operator/=(float s) { s = 1.0f/s; x *= s; y *= s; z *= s; return *this; } |
---|
| 449 | |
---|
| 450 | // Logical operators |
---|
| 451 | |
---|
| 452 | //! Operator for "if(Point==Point)" |
---|
| 453 | inline_ bool operator==(const Point& p) const { return ( (IR(x)==IR(p.x))&&(IR(y)==IR(p.y))&&(IR(z)==IR(p.z))); } |
---|
| 454 | //! Operator for "if(Point!=Point)" |
---|
| 455 | inline_ bool operator!=(const Point& p) const { return ( (IR(x)!=IR(p.x))||(IR(y)!=IR(p.y))||(IR(z)!=IR(p.z))); } |
---|
| 456 | |
---|
| 457 | // Arithmetic operators |
---|
| 458 | |
---|
| 459 | //! Operator for Point Mul = Point * Matrix3x3. |
---|
| 460 | inline_ Point operator*(const Matrix3x3& mat) const |
---|
| 461 | { |
---|
| 462 | class ShadowMatrix3x3{ public: float m[3][3]; }; // To allow inlining |
---|
| 463 | const ShadowMatrix3x3* Mat = (const ShadowMatrix3x3*)&mat; |
---|
| 464 | |
---|
| 465 | return Point( |
---|
| 466 | x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0], |
---|
| 467 | x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1], |
---|
| 468 | x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2] ); |
---|
| 469 | } |
---|
| 470 | |
---|
| 471 | //! Operator for Point Mul = Point * Matrix4x4. |
---|
| 472 | inline_ Point operator*(const Matrix4x4& mat) const |
---|
| 473 | { |
---|
| 474 | class ShadowMatrix4x4{ public: float m[4][4]; }; // To allow inlining |
---|
| 475 | const ShadowMatrix4x4* Mat = (const ShadowMatrix4x4*)&mat; |
---|
| 476 | |
---|
| 477 | return Point( |
---|
| 478 | x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0] + Mat->m[3][0], |
---|
| 479 | x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1] + Mat->m[3][1], |
---|
| 480 | x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2] + Mat->m[3][2]); |
---|
| 481 | } |
---|
| 482 | |
---|
| 483 | //! Operator for Point *= Matrix3x3. |
---|
| 484 | inline_ Point& operator*=(const Matrix3x3& mat) |
---|
| 485 | { |
---|
| 486 | class ShadowMatrix3x3{ public: float m[3][3]; }; // To allow inlining |
---|
| 487 | const ShadowMatrix3x3* Mat = (const ShadowMatrix3x3*)&mat; |
---|
| 488 | |
---|
| 489 | float xp = x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0]; |
---|
| 490 | float yp = x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1]; |
---|
| 491 | float zp = x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2]; |
---|
| 492 | |
---|
| 493 | x = xp; y = yp; z = zp; |
---|
| 494 | |
---|
| 495 | return *this; |
---|
| 496 | } |
---|
| 497 | |
---|
| 498 | //! Operator for Point *= Matrix4x4. |
---|
| 499 | inline_ Point& operator*=(const Matrix4x4& mat) |
---|
| 500 | { |
---|
| 501 | class ShadowMatrix4x4{ public: float m[4][4]; }; // To allow inlining |
---|
| 502 | const ShadowMatrix4x4* Mat = (const ShadowMatrix4x4*)&mat; |
---|
| 503 | |
---|
| 504 | float xp = x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0] + Mat->m[3][0]; |
---|
| 505 | float yp = x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1] + Mat->m[3][1]; |
---|
| 506 | float zp = x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2] + Mat->m[3][2]; |
---|
| 507 | |
---|
| 508 | x = xp; y = yp; z = zp; |
---|
| 509 | |
---|
| 510 | return *this; |
---|
| 511 | } |
---|
| 512 | |
---|
| 513 | // Cast operators |
---|
| 514 | |
---|
| 515 | //! Cast a Point to a HPoint. w is set to zero. |
---|
| 516 | operator HPoint() const; |
---|
| 517 | |
---|
| 518 | inline_ operator const float*() const { return &x; } |
---|
| 519 | inline_ operator float*() { return &x; } |
---|
| 520 | |
---|
| 521 | public: |
---|
| 522 | float x, y, z; |
---|
| 523 | }; |
---|
| 524 | |
---|
| 525 | FUNCTION ICEMATHS_API void Normalize1(Point& a); |
---|
| 526 | FUNCTION ICEMATHS_API void Normalize2(Point& a); |
---|
| 527 | |
---|
| 528 | #endif //__ICEPOINT_H__ |
---|