/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#ifndef QDENGINE_XMATH_H
#define QDENGINE_XMATH_H
#include "common/scummsys.h"
namespace QDEngine {
class Archive;
class Vect2f;
class Vect2i;
class Vect2s;
class Vect3f;
enum eAxis {
X_AXIS = 0,
Y_AXIS = 1,
Z_AXIS = 2,
W_AXIS = 3
};
///////////////////////////////////////////////////////////////////////////////
// Constants
///////////////////////////////////////////////////////////////////////////////
#undef M_PI
#define M_PI 3.14159265358979323846f
#undef M_PI_2
#define M_PI_2 1.57079632679489661923f
#undef M_PI_4
#define M_PI_4 0.785398163397448309616f
const double DBL_EPS = 1.e-15;
const double DBL_INF = 1.e+100;
const double DBL_COMPARE_TOLERANCE = 1.e-10;
const float FLT_EPS = 1.192092896e-07f; //1.e-7f;
const float FLT_INF = 1.e+30f;
const float FLT_COMPARE_TOLERANCE = 1.e-5f;
const int INT_INF = 0x7fffffff;
inline float invSqrtFast(float x) {
x += 1e-7f; // Добавка, устраняющая деление на 0
float xhalf = 0.5f * x;
uint32 i;
memcpy(&i, &x, 4);
i = 0x5f375a86 - (i >> 1); // gives initial guess y0
memcpy(&x, &i, 4);
x = x * (1.5f - xhalf * x * x); // Newton step, repeating increases accuracy
return x;
}
inline float cycle(float f, float size) {
return fmod(fmod(f, size) + size, size);
}
inline float getDist(float v0, float v1, float size) {
float d = fmod(v0 - v1, size);
float ad = (float)fabs(d);
float dd = size - ad;
if (ad <= dd) return d;
return d < 0 ? d + size : d - size;
}
inline float getDeltaAngle(float to, float from) {
return getDist(to, from, 2 * M_PI);
}
inline float cycleAngle(float a) {
return cycle(a, 2 * M_PI);
}
///////////////////////////////////////////////////////////////////////////////
//
// Scalar Functions
//
///////////////////////////////////////////////////////////////////////////////
template
inline T sqr(const T &x) {
return x*x;
}
#define G2R(x) ((x)*M_PI/180.f)
#define R2G(x) ((x)*180.f/M_PI)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// class Vect2f
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class Vect2f {
public:
float x, y;
inline Vect2f() { x = y = 0.0; }
inline Vect2f(float x_, float y_) {
x = x_;
y = y_;
}
typedef float float2[2];
inline Vect2f(const float2 &v) {
x = v[0];
y = v[1];
}
inline Vect2f(const Vect2i &v);
inline Vect2f(const Vect2s &v);
inline Vect2f &set(float x_, float y_) {
x = x_;
y = y_;
return *this;
}
inline Vect2f operator - () const {
return Vect2f(-x, -y);
}
inline int xi() const {
return round(x);
}
inline int yi() const {
return round(y);
}
inline const float &operator[](int i) const {
return *(&x + i);
}
inline float &operator[](int i) {
return *(&x + i);
}
inline Vect2f &operator += (const Vect2f &v) {
x += v.x;
y += v.y;
return *this;
}
inline Vect2f &operator -= (const Vect2f &v) {
x -= v.x;
y -= v.y;
return *this;
}
inline Vect2f &operator *= (const Vect2f &v) {
x *= v.x;
y *= v.y;
return *this;
}
inline Vect2f &operator /= (const Vect2f &v) {
x /= v.x;
y /= v.y;
return *this;
}
inline Vect2f &operator *= (float f) {
x *= f;
y *= f;
return *this;
}
inline Vect2f &operator /= (float f) {
if (f != 0.f) f = 1 / f;
else f = 0.0001f;
x *= f;
y *= f;
return *this;
}
inline Vect2f operator + (const Vect2f &v) const {
return Vect2f(*this) += v;
}
inline Vect2f operator - (const Vect2f &v) const {
return Vect2f(*this) -= v;
}
inline Vect2f operator * (const Vect2f &v) const {
return Vect2f(*this) *= v;
}
inline Vect2f operator / (const Vect2f &v) const {
return Vect2f(*this) /= v;
}
inline Vect2f operator * (float f) const {
return Vect2f(*this) *= f;
}
inline Vect2f operator / (float f) const {
return Vect2f(*this) /= f;
}
inline bool eq(const Vect2f &v, float delta = FLT_COMPARE_TOLERANCE) const {
return fabsf(v.x - x) < delta && fabsf(v.y - y) < delta;
}
inline float dot(const Vect2f &v) const {
return x * v.x + y * v.y;
}
inline friend float dot(const Vect2f &u, const Vect2f &v) {
return u.dot(v);
}
inline float operator % (const Vect2f &v) const {
return x * v.y - y * v.x;
}
inline Vect2f &scaleAdd(const Vect2f &u, float lambda) {
x += lambda * u.x;
y += lambda * u.y;
return *this;
}
inline Vect2f &interpolate(const Vect2f &u, const Vect2f &v, float lambda); // (1-lambda)*u + lambda*v
inline float norm() const {
return sqrtf(x * x + y * y);
}
inline float norm2() const {
return x * x + y * y;
}
inline Vect2f &normalize(float norma) {
float f = norma * invSqrtFast(x * x + y * y);
x *= f;
y *= f;
return *this;
}
inline float distance(const Vect2f &v) const {
return sqrtf(distance2(v));
}
inline float distance2(const Vect2f &v) const {
float dx = x - v.x, dy = y - v.y;
return dx * dx + dy * dy;
}
inline void swap(Vect2f &v) {
Vect2f tmp = v;
v = *this;
*this = tmp;
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// class Vect2i
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class Vect2i {
public:
int x, y;
inline Vect2i() { x = y = 0; }
inline Vect2i(int x_, int y_) {
x = x_;
y = y_;
}
inline Vect2i(float x_, float y_) {
x = round(x_);
y = round(y_);
}
inline Vect2i(const Vect2f &v) {
x = round(v.x);
y = round(v.y);
}
inline Vect2i(const Vect2s &v);
inline void set(int x_, int y_) {
x = x_;
y = y_;
}
inline void set(float x_, float y_) {
x = round(x_);
y = round(y_);
}
inline Vect2i operator - () const {
return Vect2i(-x, -y);
}
inline const int &operator[](int i) const {
return *(&x + i);
}
inline int &operator[](int i) {
return *(&x + i);
}
inline Vect2i &operator += (const Vect2i &v) {
x += v.x;
y += v.y;
return *this;
}
inline Vect2i &operator -= (const Vect2i &v) {
x -= v.x;
y -= v.y;
return *this;
}
inline Vect2i &operator *= (const Vect2i &v) {
x *= v.x;
y *= v.y;
return *this;
}
inline Vect2i &operator /= (const Vect2i &v) {
x /= v.x;
y /= v.y;
return *this;
}
inline Vect2i operator + (const Vect2i &v) const {
return Vect2i(*this) += v;
}
inline Vect2i operator - (const Vect2i &v) const {
return Vect2i(*this) -= v;
}
inline Vect2i operator * (const Vect2i &v) const {
return Vect2i(*this) *= v;
}
inline Vect2i &operator *= (int f) {
x *= f;
y *= f;
return *this;
}
inline Vect2i operator * (int f) const {
return Vect2i(*this) *= f;
}
inline Vect2i &operator >>= (int n) {
x >>= n;
y >>= n;
return *this;
}
inline Vect2i operator >> (int n) const {
return Vect2i(*this) >>= n;
}
inline Vect2i &operator *= (float f) {
x = round(x * f);
y = round(y * f);
return *this;
}
inline Vect2i &operator /= (float f) {
return *this *= 1.f / f;
}
inline Vect2i operator * (float f) const {
return Vect2i(*this) *= f;
}
inline Vect2i operator / (float f) const {
return Vect2i(*this) /= f;
}
inline int dot(const Vect2i &v) const {
return x * v.x + y * v.y;
}
inline friend int dot(const Vect2i &u, const Vect2i &v) {
return u.dot(v);
}
inline int operator % (const Vect2i &v) const {
return x * v.y - y * v.x;
}
inline int norm() const {
return round(sqrtf(float(x * x + y * y)));
}
inline int norm2() const {
return x * x + y * y;
}
inline void normalize(int norma) {
float f = (float)norma * invSqrtFast((float)(x * x + y * y));
x = round(x * f);
y = round(y * f);
}
inline int distance2(const Vect2i &v) const {
return sqr(x - v.x) + sqr(y - v.y);
}
inline int operator == (const Vect2i &v) const {
return x == v.x && y == v.y;
}
inline int operator != (const Vect2i &v) const {
return x != v.x || y != v.y;
}
inline void swap(Vect2i &v) {
Vect2i tmp = v;
v = *this;
*this = tmp;
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// class Vect2s
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class Vect2s {
public:
int16 x, y;
inline Vect2s() { x = y = 0; }
inline Vect2s(int x_, int y_) {
x = x_;
y = y_;
}
inline Vect2s(const Vect2f &v) {
x = round(v.x);
y = round(v.y);
}
inline Vect2s(const Vect2i &v) {
x = v.x;
y = v.y;
}
inline void set(int x_, int y_) {
x = x_;
y = y_;
}
inline Vect2s operator - () const {
return Vect2s(-x, -y);
}
inline const int16 &operator[](int i) const {
return *(&x + i);
}
inline int16 &operator[](int i) {
return *(&x + i);
}
inline Vect2s &operator += (const Vect2s &v) {
x += v.x;
y += v.y;
return *this;
}
inline Vect2s &operator -= (const Vect2s &v) {
x -= v.x;
y -= v.y;
return *this;
}
inline Vect2s &operator *= (const Vect2s &v) {
x *= v.x;
y *= v.y;
return *this;
}
inline Vect2s &operator *= (float f) {
x = round(x * f);
y = round(y * f);
return *this;
}
inline Vect2s &operator /= (float f) {
if (f != 0.f) f = 1 / f;
else f = 0.0001f;
x = round(x * f);
y = round(y * f);
return *this;
}
inline Vect2s operator - (const Vect2s &v) const {
return Vect2s(x - v.x, y - v.y);
}
inline Vect2s operator + (const Vect2s &v) const {
return Vect2s(x + v.x, y + v.y);
}
inline Vect2s operator * (const Vect2s &v) const {
return Vect2s(x * v.x, y * v.y);
}
inline Vect2s operator * (float f) const {
Vect2s tmp(round(x * f), round(y * f));
return tmp;
}
inline Vect2s operator / (float f) const {
if (f != 0.f) f = 1 / f;
else f = 0.0001f;
Vect2s tmp(round(x * f), round(y * f));
return tmp;
}
inline int operator == (const Vect2s &v) const {
return x == v.x && y == v.y;
}
inline int norm() const {
return round(sqrtf((float)(x * x + y * y)));
}
inline int norm2() const {
return x * x + y * y;
}
inline int distance(const Vect2s &v) const {
int dx = v.x - x, dy = v.y - y;
return round(sqrtf((float)(dx * dx + dy * dy)));
}
inline void normalize(int norma) {
float f = (float)norma * invSqrtFast((float)((int)x * x + (int)y * y));
x = round(x * f);
y = round(y * f);
}
inline void swap(Vect2s &v) {
Vect2s tmp = v;
v = *this;
*this = tmp;
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// class Vect3f
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class Vect3f {
public:
typedef float float3[3];
float x, y, z;
// constructors //////////////////////////////////////////////////////////////
inline Vect3f() { x = y = z = 0.0;}
inline Vect3f(float x_, float y_, float z_) {
x = x_;
y = y_;
z = z_;
}
explicit inline Vect3f(const Vect2f &v, float z_ = 0) {
x = v.x;
y = v.y;
z = z_;
}
inline Vect3f(const float3 &v) {
x = v[0];
y = v[1];
z = v[2];
}
inline operator const Vect2f &() const {
return *reinterpret_cast(this);
}
// setters / accessors / translators /////////////////////////////////////////
inline Vect3f &set(float x_, float y_, float z_) {
x = x_;
y = y_;
z = z_;
return *this;
}
inline Vect3f &setSpherical(float psi, float theta, float radius);
// index-based access: 0=x, 1=y, 2=z.
inline const float &operator[](int i) const {
return *(&x + i);
}
inline float &operator[](int i) {
return *(&x + i);
}
// Fortran index-based access: 1=x, 2=y, 3=z.
inline const float &operator()(int i) const {
return *(&x + i - 1);
}
inline float &operator()(int i) {
return *(&x + i - 1);
}
// Conversion to int ///////
inline int xi() const {
return round(x);
}
inline int yi() const {
return round(y);
}
inline int zi() const {
return round(z);
}
// Negate ////////////////////////////////////
inline Vect3f operator- () const;
inline Vect3f &negate(const Vect3f &v);
inline Vect3f &negate();
// Logical operations ////////////////////////////////
inline bool eq(const Vect3f &v, float delta = FLT_COMPARE_TOLERANCE) const;
// Addition and substruction ////////////////////
inline Vect3f &add(const Vect3f &u, const Vect3f &v);
inline Vect3f &add(const Vect3f &v);
inline Vect3f &sub(const Vect3f &u, const Vect3f &v);
inline Vect3f &sub(const Vect3f &v);
inline Vect3f &operator+= (const Vect3f &v) {
return add(v);
}
inline Vect3f &operator-= (const Vect3f &v) {
return sub(v);
}
inline Vect3f operator+ (const Vect3f &v) const {
Vect3f u;
return u.add(*this, v);
}
inline Vect3f operator- (const Vect3f &v) const {
Vect3f u;
return u.sub(*this, v);
}
// Component-wise multiplication and division ////////////////
inline Vect3f &mult(const Vect3f &u, const Vect3f &v);
inline Vect3f &mult(const Vect3f &v);
inline Vect3f &div(const Vect3f &u, const Vect3f &v);
inline Vect3f &div(const Vect3f &v);
inline Vect3f &operator*= (const Vect3f &v) {
return mult(v);
}
inline Vect3f &operator/= (const Vect3f &v) {
return div(v);
}
inline Vect3f operator* (const Vect3f &v) const {
Vect3f u;
return u.mult(*this, v);
}
inline Vect3f operator/ (const Vect3f &v) const {
Vect3f u;
return u.div(*this, v);
}
// Cross product //////////////////////
inline Vect3f &cross(const Vect3f &u, const Vect3f &v);// u x v [!]
inline Vect3f &precross(const Vect3f &v); // v x this [!]
inline Vect3f &postcross(const Vect3f &v); // this x v [!]
inline Vect3f &operator%= (const Vect3f &v) {
return postcross(v); // this x v [!]
}
inline Vect3f operator% (const Vect3f &v) const {
Vect3f u;
return u.cross(*this, v);
}
// Dot product //////////////////////
inline float dot(const Vect3f &other) const;
inline friend float dot(const Vect3f &u, const Vect3f &v) {
return u.dot(v);
}
// Multiplication & division by scalar ///////////
inline Vect3f &scale(const Vect3f &v, float s);
inline Vect3f &scale(float s);
inline Vect3f &operator*= (float s) {
return scale(s);
}
inline Vect3f &operator/= (float s) {
return scale(1 / s);
}
inline Vect3f operator* (float s) const {
Vect3f u;
return u.scale(*this, s);
}
inline Vect3f operator/ (float s) const {
Vect3f u;
return u.scale(*this, 1 / s);
}
inline friend Vect3f operator* (float s, const Vect3f &v) {
Vect3f u;
return u.scale(v, s);
}
// Normalize ///////////////////////////
inline Vect3f &normalize(float r = 1.0f);
inline Vect3f &normalize(const Vect3f &v, float r = 1.0f);
// Operation returning scalar ////////////
inline float norm() const;
inline float norm2() const; // norm^2
inline float distance(const Vect3f &other) const;
inline float distance2(const Vect3f &other) const; // distance^2
inline float psi() const;
inline float theta() const;
inline float min() const;
inline float max() const;
inline float minAbs() const;
inline float maxAbs() const;
inline float sumAbs() const; // |x| + |y| + |z|
// Composite functions ////////////////////////////////
inline Vect3f &crossAdd(const Vect3f &u, const Vect3f &v, const Vect3f &w); // u x v + w [!] this must be distinct from u and v, but not necessarily from w.
inline Vect3f &crossAdd(const Vect3f &u, const Vect3f &v); // u x v + this [!]
inline Vect3f &scaleAdd(const Vect3f &v, const Vect3f &u, float lambda); // v + lambda * u
inline Vect3f &scaleAdd(const Vect3f &u, float lambda);// this + lambda * u
inline Vect3f &interpolate(const Vect3f &u, const Vect3f &v, float lambda); // (1-lambda)*u + lambda*v
// Swap /////////////////////////
inline void swap(Vect3f &other);
inline friend void swap(Vect3f &u, Vect3f &v) {
u.swap(v);
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Miscellaneous functions
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Decomposition ////////////////////////////////
inline void decomposition(const Vect3f &axis, const Vect3f &v, Vect3f &v_normal, Vect3f &v_tangent) {
// axis - axis of decomposition, v_normal - collinear to axis, v_tangent - perpendicular to axis
v_normal.scale(axis, dot(axis, v) / ((axis).norm2()));
v_tangent.sub(v, v_normal);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////
//// DEFINITIONS
////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
// Vect2 definitions
//
///////////////////////////////////////////////////////////////////////////////
inline Vect2i::Vect2i(const Vect2s &v) {
x = v.x;
y = v.y;
}
inline Vect2f::Vect2f(const Vect2i &v) {
x = float(v.x);
y = float(v.y);
}
inline Vect2f::Vect2f(const Vect2s &v) {
x = v.x;
y = v.y;
}
Vect2f &Vect2f::interpolate(const Vect2f &u, const Vect2f &v, float lambda) {
float lambda2 = 1.0f - lambda;
x = lambda2 * u.x + lambda * v.x;
y = lambda2 * u.y + lambda * v.y;
return *this;
}
///////////////////////////////////////////////////////////////////////////////
//
// Vect3f inline definitions
//
///////////////////////////////////////////////////////////////////////////////
// Dot product //////////////////////
//inline double dot(const Vect3d& u, const Vect3f& v) { return u.dot(v); }
//inline float dot(const Vect3f& u, const Vect3d& v) { return u.dot(v); }
bool Vect3f::eq(const Vect3f &other, float delta) const {
return fabs(x - other.x) < delta &&
fabs(y - other.y) < delta &&
fabs(z - other.z) < delta;
}
Vect3f Vect3f::operator- () const {
return Vect3f(-x, -y, -z);
}
// Norm operations /////////
float Vect3f::sumAbs() const {
return (float)(fabs(x) + fabs(y) + fabs(z));
}
// Descart - spherical function //////////////
float Vect3f::psi() const {
return (float)atan2(y, x);
}
float Vect3f::theta() const {
return (float)acos(z / (norm() + FLT_EPS));
}
Vect3f &Vect3f::setSpherical(float psi, float theta, float radius) {
x = radius * (float)sin(theta);
y = x * (float)sin(psi);
x = x * (float)cos(psi);
z = radius * (float)cos(theta);
return *this;
}
float Vect3f::dot(const Vect3f &other) const {
return x * other.x + y * other.y + z * other.z;
}
float Vect3f::norm() const {
return (float)sqrt(x * x + y * y + z * z);
}
float Vect3f::norm2() const {
return (x * x + y * y + z * z);
}
float Vect3f::distance(const Vect3f &other) const {
Vect3f w;
w.sub(other, *this);
return w.norm();
}
float Vect3f::distance2(const Vect3f &other) const {
Vect3f w;
w.sub(other, *this);
return w.norm2();
}
float Vect3f::min() const {
return (x <= y) ? ((x <= z) ? x : z) : ((y <= z) ? y : z);
}
float Vect3f::max() const {
return (x >= y) ? ((x >= z) ? x : z) : ((y >= z) ? y : z);
}
float Vect3f::minAbs() const {
float ax, ay, az;
ax = (float)fabs(x);
ay = (float)fabs(y);
az = (float)fabs(z);
return (ax <= ay) ? ((ax <= az) ? ax : az) : ((ay <= az) ? ay : az);
}
float Vect3f::maxAbs() const {
float ax, ay, az;
ax = (float)fabs(x);
ay = (float)fabs(y);
az = (float)fabs(z);
return (ax >= ay) ? ((ax >= az) ? ax : az) : ((ay >= az) ? ay : az);
}
void Vect3f::swap(Vect3f &other) {
Vect3f tmp;
tmp = *this;
*this = other;
other = tmp;
}
Vect3f &Vect3f::normalize(const Vect3f &v, float r) {
float s = r * invSqrtFast(v.x * v.x + v.y * v.y + v.z * v.z);
x = s * v.x;
y = s * v.y;
z = s * v.z;
return *this;
}
Vect3f &Vect3f::normalize(float r) {
float s = r * invSqrtFast(x * x + y * y + z * z);
x *= s;
y *= s;
z *= s;
return *this;
}
Vect3f &Vect3f::negate(const Vect3f &v) {
x = - v.x;
y = - v.y;
z = - v.z;
return *this;
}
Vect3f &Vect3f::negate() {
x = - x;
y = - y;
z = - z;
return *this;
}
Vect3f &Vect3f::add(const Vect3f &u, const Vect3f &v) {
x = u.x + v.x;
y = u.y + v.y;
z = u.z + v.z;
return *this;
}
Vect3f &Vect3f::add(const Vect3f &v) {
x += v.x;
y += v.y;
z += v.z;
return *this;
}
Vect3f &Vect3f::sub(const Vect3f &u, const Vect3f &v) {
x = u.x - v.x;
y = u.y - v.y;
z = u.z - v.z;
return *this;
}
Vect3f &Vect3f::sub(const Vect3f &v) {
x -= v.x;
y -= v.y;
z -= v.z;
return *this;
}
Vect3f &Vect3f::mult(const Vect3f &u, const Vect3f &v) {
x = u.x * v.x;
y = u.y * v.y;
z = u.z * v.z;
return *this;
}
Vect3f &Vect3f::mult(const Vect3f &v) {
x *= v.x;
y *= v.y;
z *= v.z;
return *this;
}
Vect3f &Vect3f::div(const Vect3f &u, const Vect3f &v) {
x = u.x / v.x;
y = u.y / v.y;
z = u.z / v.z;
return *this;
}
Vect3f &Vect3f::div(const Vect3f &v) {
x /= v.x;
y /= v.y;
z /= v.z;
return *this;
}
Vect3f &Vect3f::scale(const Vect3f &v, float s) {
x = s * v.x;
y = s * v.y;
z = s * v.z;
return *this;
}
Vect3f &Vect3f::scale(float s) {
x *= s;
y *= s;
z *= s;
return *this;
}
Vect3f &Vect3f::cross(const Vect3f &u, const Vect3f &v) {
x = u.y * v.z - u.z * v.y;
y = u.z * v.x - u.x * v.z;
z = u.x * v.y - u.y * v.x;
return *this;
}
Vect3f &Vect3f::precross(const Vect3f &v) {
float ox, oy;
ox = x;
oy = y;
x = v.y * z - v.z * oy;
y = v.z * ox - v.x * z;
z = v.x * oy - v.y * ox;
return *this;
}
Vect3f &Vect3f::postcross(const Vect3f &v) {
float ox, oy;
ox = x;
oy = y;
x = oy * v.z - z * v.y;
y = z * v.x - ox * v.z;
z = ox * v.y - oy * v.x;
return *this;
}
Vect3f &Vect3f::crossAdd(const Vect3f &u, const Vect3f &v, const Vect3f &w) {
x = u.y * v.z - u.z * v.y + w.x;
y = u.z * v.x - u.x * v.z + w.y;
z = u.x * v.y - u.y * v.x + w.z;
return *this;
}
Vect3f &Vect3f::crossAdd(const Vect3f &u, const Vect3f &v) {
x += u.y * v.z - u.z * v.y;
y += u.z * v.x - u.x * v.z;
z += u.x * v.y - u.y * v.x;
return *this;
}
Vect3f &Vect3f::scaleAdd(const Vect3f &v, const Vect3f &u, float lambda) {
x = v.x + lambda * u.x;
y = v.y + lambda * u.y;
z = v.z + lambda * u.z;
return *this;
}
Vect3f &Vect3f::scaleAdd(const Vect3f &u, float lambda) {
x += lambda * u.x;
y += lambda * u.y;
z += lambda * u.z;
return *this;
}
Vect3f &Vect3f::interpolate(const Vect3f &u, const Vect3f &v, float lambda) {
float lambda2 = 1.0f - lambda;
x = lambda2 * u.x + lambda * v.x;
y = lambda2 * u.y + lambda * v.y;
z = lambda2 * u.z + lambda * v.z;
return *this;
}
} // namespace QDEngine
#endif // QDENGINE_XMATH_H