⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matrix.h

📁 大型多人在线游戏开发,该书光盘上附带的源码
💻 H
📖 第 1 页 / 共 3 页
字号:
/*
s_p_oneil@hotmail.com
Copyright (c) 2000, Sean O'Neil
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.
* Neither the name of this project nor the names of its contributors
  may be used to endorse or promote products derived from this software
  without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef __Matrix_h__
#define __Matrix_h__

#include "Noise.h"	// Has some useful defines and inline functions

class CMatrix;
class CQuaternion;
class C3DObject;

/*******************************************************************************
* Template Class: TVector
********************************************************************************
* This template class implements a simple 3D vector with x, y, and z coordinates.
* Several functions and operators are defined to make working with vectors easier,
* and because it's templatized, any numeric type can be used with it. Macros are
* defined for the most common types.
*******************************************************************************/
#define CVector			TVector<float>
#define CDoubleVector	TVector<double>
#define CIntVector		TVector<int>
#define CByteVector		TVector<unsigned char>
template <class T> class TVector
{
public:
	T x, y, z;

	// Constructors
	TVector()									{}
	TVector(const T a, const T b, const T c)	{ x = a; y = b; z = c; }
	TVector(const T t)							{ *this = t; }
	TVector(const T *pt)						{ *this = pt; }
	TVector(const TVector<T> &v)				{ *this = v; }

	// Casting and unary operators
	operator TVector<float>()					{ return TVector<float>((float)x, (float)y, (float)z); }
	operator TVector<double>()					{ return TVector<double>((double)x, (double)y, (double)z); }
	operator T*()								{ return &x; }
	T &operator[](const int n)					{ return (&x)[n]; }
	operator const T*() const					{ return &x; }
	T operator[](const int n) const				{ return (&x)[n]; }
	TVector<T> operator-() const				{ return TVector<T>(-x, -y, -z); }

	// Equal and comparison operators
	void operator=(const T t)					{ x = y = z = t; }
	void operator=(const T *pt)					{ x = pt[0]; y = pt[1]; z = pt[2]; }
	void operator=(const TVector<T> &v)			{ x = v.x; y = v.y; z = v.z; }
	bool operator==(TVector<T> &v) const		{ return (Abs(x - v.x) <= (T)0.001f && Abs(y - v.y) <= 0.001f && Abs(z - v.z) <= 0.001f); }
	bool operator!=(TVector<T> &v) const		{ return !(*this == v); }

	// Arithmetic operators (vector with scalar)
	TVector<T> operator+(const T t) const		{ return TVector<T>(x+t, y+t, z+t); }
	TVector<T> operator-(const T t) const		{ return TVector<T>(x-t, y-t, z-t); }
	TVector<T> operator*(const T t) const		{ return TVector<T>(x*t, y*t, z*t); }
	TVector<T> operator/(const T t) const		{ return TVector<T>(x/t, y/t, z/t); }
	void operator+=(const T t)					{ x += t; y += t; z += t; }
	void operator-=(const T t)					{ x -= t; y -= t; z -= t; }
	void operator*=(const T t)					{ x *= t; y *= t; z *= t; }
	void operator/=(const T t)					{ x /= t; y /= t; z /= t; }

	// Arithmetic operators (vector with vector)
	TVector<T> operator+(const TVector<T> &v) const	{ return TVector<T>(x+v.x, y+v.y, z+v.z); }
	TVector<T> operator-(const TVector<T> &v) const	{ return TVector<T>(x-v.x, y-v.y, z-v.z); }
	TVector<T> operator*(const TVector<T> &v) const	{ return TVector<T>(x*v.x, y*v.y, z*v.z); }
	TVector<T> operator/(const TVector<T> &v) const	{ return TVector<T>(x/v.x, y/v.y, z/v.z); }
	void operator+=(const TVector<T> &v)		{ x += v.x; y += v.y; z += v.z; }
	void operator-=(const TVector<T> &v)		{ x -= v.x; y -= v.y; z -= v.z; }
	void operator*=(const TVector<T> &v)		{ x *= v.x; y *= v.y; z *= v.z; }
	void operator/=(const TVector<T> &v)		{ x /= v.x; y /= v.y; z /= v.z; }

	// Dot and cross product operators
	T operator|(const TVector<T> &v) const		{ return x*v.x + y*v.y + z*v.z; }
	TVector<T> operator^(const TVector<T> &v) const	{ return TVector<T>(y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x); }
	void operator^=(const TVector<T> &v)		{ *this = *this ^ v; }

	// Magnitude/distance methods
	T MagnitudeSquared() const					{ return x*x + y*y + z*z; }
	T Magnitude() const							{ return (T)sqrt(MagnitudeSquared()); }
	T DistanceSquared(const TVector<T> &v) const{ return (*this - v).MagnitudeSquared(); }
	T Distance(const TVector<T> &v) const		{ return (*this - v).Magnitude(); }
	TVector<T> Midpoint(const TVector<T> &v) const	{ return CVector((*this - v) / 2 + v); }
	TVector<T> Average(const TVector<T> &v) const	{ return CVector((*this + v) / 2); }

	// Advanced methods (should only be used with float or double types)
	void Normalize()							{ *this /= Magnitude(); }
	double Angle(const TVector<T> &v) const		{ return acos(*this | v); }
	TVector<T> Reflect(const TVector<T> &n) const
	{
		T t = (T)Magnitude();
		TVector<T> v = *this / t;
		return (v - n * (2 * (v | n))) * t;
	}
	TVector<T> Rotate(const T tAngle, const CVector &n) const
	{
		T tCos = (T)cos(tAngle);
		T tSin = (T)sin(tAngle);
		return TVector<T>(*this * tCos + ((n * *this) * (1 - tCos)) * n + (*this ^ n) * tSin);
	}
};

// Returns the normal vector of two vectors (the normalized cross product)
template <class T> inline TVector<T> NormalVector(const TVector<T> &v1, const TVector<T> &v2)
{
	TVector<T> v = v1 ^ v2;
	v.Normalize();
	return v;
}

// Returns the normal vector of a triangle or 3 points on a plane (assumes counter-clockwise orientation)
template <class T> inline TVector<T> NormalVector(const TVector<T> &p1, const TVector<T> &p2, const TVector<T> &p3)
{
	return NormalVector(p2-p1, p3-p1);
}

// Returns the direction vector between two points
template <class T> inline TVector<T> DirectionVector(const TVector<T> &p1, const TVector<T> &p2)
{
	TVector<T> v = p2 - p1;
	v.Normalize();
	return v;
}


/*******************************************************************************
* Template Class: TVector4
********************************************************************************
* This template class implements a simple 4D vector with x, y, z, and w
* coordinates. Like TVector, it is templatized and macros are defined for the
* most common types.
*******************************************************************************/
#define CVector4		TVector4<float>
#define CDoubleVector4	TVector4<double>
#define CIntVector4		TVector4<int>
#define CByteVector4	TVector4<unsigned char>
template <class T> class TVector4
{
public:
	T x, y, z, w;

	// Constructors
	TVector4()									{}
	TVector4(const T a, const T b, const T c, const T d)	{ x = a; y = b; z = c; w = d; }
	TVector4(const T t)							{ *this = t; }
	TVector4(const T *pt)						{ *this = pt; }
	TVector4(const TVector<T> &v)				{ *this = v; }
	TVector4(const TVector4<T> &v)				{ *this = v; }

	// Casting and unary operators
	operator T*()								{ return &x; }
	T &operator[](const int n)					{ return (&x)[n]; }
	operator const T*() const					{ return &x; }
	T operator[](const int n) const				{ return (&x)[n]; }
	TVector4<T> operator-() const				{ return TVector4<T>(-x, -y, -z, -w); }

	// Equal and comparison operators
	void operator=(const T t)					{ x = y = z = w = t; }
	void operator=(const T *pt)					{ x = pt[0]; y = pt[1]; z = pt[2]; w = pt[3]; }
	void operator=(const TVector<T> &v)			{ x = v.x; y = v.y; z = v.z; w = 0; }
	void operator=(const TVector4<T> &v)		{ x = v.x; y = v.y; z = v.z; w = v.w; }
	bool operator==(TVector4<T> &v) const		{ return (Abs(x - v.x) <= (T)DELTA && Abs(y - v.y) <= (T)DELTA && Abs(z - v.z) <= (T)DELTA && Abs(w - v.w) <= (T)DELTA); }
	bool operator!=(TVector4<T> &v) const		{ return !(*this == v); }

	// Arithmetic operators (vector with scalar)
	TVector4<T> operator+(const T t) const		{ return TVector4<T>(x+t, y+t, z+t, w+t); }
	TVector4<T> operator-(const T t) const		{ return TVector4<T>(x-t, y-t, z-t, w-t); }
	TVector4<T> operator*(const T t) const		{ return TVector4<T>(x*t, y*t, z*t, w*t); }
	TVector4<T> operator/(const T t) const		{ return TVector4<T>(x/t, y/t, z/t, w/t); }
	void operator+=(const T t)					{ x += t; y += t; z += t; w += t; }
	void operator-=(const T t)					{ x -= t; y -= t; z -= t; w -= t; }
	void operator*=(const T t)					{ x *= t; y *= t; z *= t; w *= t; }
	void operator/=(const T t)					{ x /= t; y /= t; z /= t; w /= t; }

	// Arithmetic operators (vector with vector)
	TVector4<T> operator+(const TVector4<T> &v) const	{ return TVector4<T>(x+v.x, y+v.y, z+v.z, w+v.w); }
	TVector4<T> operator-(const TVector4<T> &v) const	{ return TVector4<T>(x-v.x, y-v.y, z-v.z, w-v.w); }
	TVector4<T> operator*(const TVector4<T> &v) const	{ return TVector4<T>(x*v.x, y*v.y, z*v.z, w*v.w); }
	TVector4<T> operator/(const TVector4<T> &v) const	{ return TVector4<T>(x/v.x, y/v.y, z/v.z, w/v.w); }
	void operator+=(const TVector4<T> &v)		{ x += v.x; y += v.y; z += v.z; w += v.w; }
	void operator-=(const TVector4<T> &v)		{ x -= v.x; y -= v.y; z -= v.z; w -= v.w; }
	void operator*=(const TVector4<T> &v)		{ x *= v.x; y *= v.y; z *= v.z; w *= v.w; }
	void operator/=(const TVector4<T> &v)		{ x /= v.x; y /= v.y; z /= v.z; w /= v.w; }

	// Magnitude/normalize methods
	T MagnitudeSquared() const					{ return x*x + y*y + z*z + w*w; }
	T Magnitude() const							{ return (T)sqrt(MagnitudeSquared()); }
	void Normalize()							{ *this /= Magnitude(); }
};


/*******************************************************************************
* Class: CQuaternion
********************************************************************************
* This class implements a 4D quaternion. Several functions and operators are
* defined to make working with quaternions easier. Quaternions are often used to
* represent rotations, and have a number of advantages over other constructs.
* Their main disadvantage is that they are unintuitive.
*
* Note: This class is not templatized because integral data types don't make sense
*       and there's no need for double-precision.
*******************************************************************************/
class CQuaternion
{
public:
	float x, y, z, w;

	// Constructors
	CQuaternion()								{}
	CQuaternion(const float a, const float b, const float c, const float d)	{ x = a; y = b; z = c; w = d; }
	CQuaternion(const CVector &v, const float f){ SetAxisAngle(v, f); }
	CQuaternion(const CVector &v)				{ *this = v; }
	CQuaternion(const CQuaternion &q)			{ *this = q; }
	CQuaternion(const CMatrix &m)				{ *this = m; }
	CQuaternion(const float *p)					{ *this = p; }

	// Casting and unary operators
	operator float*()							{ return &x; }
	float &operator[](const int n)				{ return (&x)[n]; }
	operator const float*() const				{ return &x; }
	float operator[](const int n) const			{ return (&x)[n]; }
	CQuaternion operator-() const				{ return CQuaternion(-x, -y, -z, -w); }

	// Equal and comparison operators
	void operator=(const CVector &v)			{ x = v.x; y = v.y; z = v.z; w = 0; }
	void operator=(const CQuaternion &q)		{ x = q.x; y = q.y; z = q.z; w = q.w; }
	void operator=(const CMatrix &m);
	void operator=(const float *p)				{ x = p[0]; y = p[1]; z = p[2]; w = p[3]; }

	// Arithmetic operators (quaternion and scalar)
	CQuaternion operator+(const float f) const	{ return CQuaternion(x+f, y+f, z+f, w+f); }
	CQuaternion operator-(const float f) const	{ return CQuaternion(x-f, y-f, z-f, w-f); }
	CQuaternion operator*(const float f) const	{ return CQuaternion(x*f, y*f, z*f, w*f); }
	CQuaternion operator/(const float f) const	{ return CQuaternion(x/f, y/f, z/f, w/f); }
	void operator+=(const float f)				{ x+=f; y+=f; z+=f; w+=f; }
	void operator-=(const float f)				{ x-=f; y-=f; z-=f; w-=f; }
	void operator*=(const float f)				{ x*=f; y*=f; z*=f; w*=f; }
	void operator/=(const float f)				{ x/=f; y/=f; z/=f; w/=f; }

	// Arithmetic operators (quaternion and quaternion)
	CQuaternion operator+(const CQuaternion &q) const	{ return CQuaternion(x+q.x, y+q.y, z+q.z, w+q.w); }
	CQuaternion operator-(const CQuaternion &q) const	{ return CQuaternion(x-q.x, y-q.y, z-q.z, w-q.w); }
	CQuaternion operator*(const CQuaternion &q) const;	// Multiplying quaternions is a special operation
	void operator+=(const CQuaternion &q)	{ x+=q.x; y+=q.y; z+=q.z; w+=q.w; }
	void operator-=(const CQuaternion &q)	{ x-=q.x; y-=q.y; z-=q.z; w-=q.w; }
	void operator*=(const CQuaternion &q)	{ *this = *this * q; }

	// Magnitude/normalize methods
	float MagnitudeSquared() const			{ return x*x + y*y + z*z + w*w; }
	float Magnitude() const					{ return sqrtf(MagnitudeSquared()); }
	void Normalize()						{ *this /= Magnitude(); }

	// Advanced quaternion methods
	CQuaternion Conjugate() const			{ return CQuaternion(-x, -y, -z, w); }
	CQuaternion Inverse() const				{ return Conjugate() / MagnitudeSquared(); }
	CQuaternion UnitInverse() const			{ return Conjugate(); }
	CVector RotateVector(const CVector &v) const	{ return (*this * CQuaternion(v) * UnitInverse()); }

	void SetAxisAngle(const CVector &vAxis, const float fAngle)
	{
		// 4 muls, 2 trig function calls
		float f = fAngle * 0.5f;
		*this = vAxis * sinf(f);
		w = cosf(f);
	}
	void GetAxisAngle(CVector &vAxis, float &fAngle) const
	{
		// 4 muls, 1 div, 2 trig function calls
		fAngle = acosf(w);
		vAxis = *this / sinf(fAngle);
		fAngle *= 2.0f;
	}

	void Rotate(const CQuaternion &q)			{ *this = q * *this; }
	void Rotate(const CVector &vAxis, const float fAngle)
	{
		CQuaternion q;
		q.SetAxisAngle(vAxis, fAngle);
		Rotate(q);
	}

	CVector GetViewAxis() const
	{
		// 6 muls, 7 adds
		float x2 = x + x, y2 = y + y, z2 = z + z;
		float xx = x * x2, xz = x * z2;
		float yy = y * y2, yz = y * z2;
		float wx = w * x2, wy = w * y2;
		return -CVector(xz+wy, yz-wx, 1-(xx+yy));
	}
	CVector GetUpAxis() const
	{
		// 6 muls, 7 adds
		float x2 = x + x, y2 = y + y, z2 = z + z;
		float xx = x * x2, xy = x * y2;
		float yz = y * z2, zz = z * z2;
		float wx = w * x2, wz = w * z2;
		return CVector(xy-wz, 1-(xx+zz), yz+wx);
	}
	CVector GetRightAxis() const
	{
		// 6 muls, 7 adds
		float x2 = x + x, y2 = y + y, z2 = z + z;
		float xy = x * y2, xz = x * z2;
		float yy = y * y2, zz = z * z2;
		float wy = w * y2, wz = w * z2;
		return CVector(1-(yy+zz), xy+wz, xz-wy);
	}
};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -