zoukankan      html  css  js  c++  java
  • 41.D3D数学库 && GameProject7

      要介绍的引擎中出现的第一个新文件是mathDefines.h头文件。该文件保存了所有的define语句,这些语句是数学库、引擎及游戏都要用到的内容。这些define语句包含了π(圆周率,圆的周长与直径的比值)的定义、平面结果和将度转换成弧度的宏。该文件随着本书的深入而不断扩充,但目前它非常小,只包含几个define语句。程序清单8.30给出了mathDefines.h头文件的内容。

    mathDefines.h头文件

    #ifndef _UGP_MATH_DEF_H_
    #define _UGP_MATH_DEF_H_


    #define UGP_FRONT 0
    #define UGP_BACK 1
    #define UGP_ON_PLANE 2
    #define UGP_CLIPPED 3
    #define UGP_CULLED 4
    #define UGP_VISIBLE 5

    #ifndef PI
    #define PI 3.14159265358979323846
    #endif

    // 将度转换成弧度
    #define GET_RADIANS(degree) (float)(degree / 180.0f * PI)

    #endif

         接下来是mathLibrary.h头文件。该头文件保存所有与数学相关及一些前面类原型的include语句。这对马上需要使用大量数学的引擎或游戏的内容而言大有好处。该文件将随本书的进展而扩充,其内容如程序清单8.31所示。

    #ifndef _UGP_MATH_LIBRARY_H_
    #define _UGP_MATH_LIBRARY_H_


    #include
    "Vector.h" // 向量(即矢量)相关
    #include"Matrix.h" // 矩阵相关
    #include"Quaternion.h" // 四元组相关
    #include"Physics.h" // 物理学相关

    class CRay; // 射线类
    class CPlane; // 平面类
    class CPolygon; // 多边形类

    #include
    "Ray.h"
    #include
    "Plane.h"
    #include
    "Polygon.h"
    #include
    "MathDefines.h"


    #endif

      

    下一个要介绍的文件和数学结构是矢量类。对本书的游戏和引擎而言,将使用3D矢量(x、y和z)。矢量类包含了对等号、减号、加号、乘号和除号的重载操作符。矢量对象自身不仅可以使用这些操作符,而且浮点数也可以使用这些操作符。

           矢量类还实现了两个矢量的叉积、矢量归一化、计算矢量长度、计算两个矢量的点积及三角形归一化。完整的vector.h头文件如程序清单8.32所示。

    #ifndef _UGP_VECTOR_H_
    #define _UGP_VECTOR_H_


    #include
    <math.h>


    class CVector3
    {
    public:
    CVector3();
    CVector3(
    float X, float Y, float Z);

    void operator=(CVector3 &v);
    CVector3
    operator-(CVector3 &v);
    CVector3
    operator+(CVector3 &v);
    CVector3
    operator*(CVector3 &v);
    CVector3
    operator/(CVector3 &v);

    CVector3
    operator+(float f);
    CVector3
    operator-(float f);
    CVector3
    operator*(float f);
    CVector3
    operator/(float f);

    void operator +=(CVector3 &v);
    void operator -=(CVector3 &v);
    void operator *=(CVector3 &v);
    void operator /=(CVector3 &v);
    void operator +=(float f);
    void operator -=(float f);
    void operator *=(float f);
    void operator /=(float f);

    void CrossProduct(CVector3 &v1, CVector3 &v2);
    float DotProduct3(CVector3 &v1);
    float GetLength();
    void Normal();
    void Normalize(CVector3 &v1, CVector3 &v2, CVector3 &v3);

    float x, y, z;
    };

    #endif

      vector.cpp源文件中的重载操作符函数

    #include"Vector.h"
    #include
    "MathDefines.h"


    CVector3::CVector3()
    {
    x
    = y = z = 0.0;
    }


    CVector3::CVector3(
    float X, float Y, float Z)
    {
    x
    = X;
    y
    = Y;
    z
    = Z;
    }


    void CVector3::operator =(CVector3 &v)
    {
    x
    = v.x;
    y
    = v.y;
    z
    = v.z;
    }


    CVector3 CVector3::
    operator -(CVector3 &v)
    {
    return CVector3(x - v.x, y - v.y, z - v.z);
    }


    CVector3 CVector3::
    operator +(CVector3 &v)
    {
    return CVector3(x + v.x, y + v.y, z + v.z);
    }


    CVector3 CVector3::
    operator *(CVector3 &v)
    {
    return CVector3(x * v.x, y * v.y, z * v.z);
    }


    CVector3 CVector3::
    operator /(CVector3 &v)
    {
    return CVector3(x / v.x, y / v.y, z / v.z);
    }


    CVector3 CVector3::
    operator +(float f)
    {
    return CVector3(x + f, y + f, z + f);
    }


    CVector3 CVector3::
    operator -(float f)
    {
    return CVector3(x - f, y - f, z - f);
    }


    CVector3 CVector3::
    operator *(float f)
    {
    return CVector3(x * f, y * f, z * f);
    }


    CVector3 CVector3::
    operator /(float f)
    {
    f
    = 1/f;

    return CVector3(x * f, y * f, z * f);
    }

    void CVector3::operator +=(CVector3 &v)
    {
    x
    += v.x;
    y
    += v.y;
    z
    += v.z;
    }


    void CVector3::operator -=(CVector3 &v)
    {
    x
    -= v.x;
    y
    -= v.y;
    z
    -= v.z;
    }


    void CVector3::operator *=(CVector3 &v)
    {
    x
    *= v.x;
    y
    *= v.y;
    z
    *= v.z;
    }


    void CVector3::operator /=(CVector3 &v)
    {
    x
    /= v.x;
    y
    /= v.y;
    z
    /= v.z;
    }


    void CVector3::operator +=(float f)
    {
    x
    += f;
    y
    += f;
    z
    += f;
    }


    void CVector3::operator -=(float f)
    {
    x
    -= f;
    y
    -= f;
    z
    -= f;
    }


    void CVector3::operator *=(float f)
    {
    x
    *= f;
    y
    *= f;
    z
    *= f;
    }


    void CVector3::operator /=(float f)
    {
    f
    = 1/f;

    x
    *= f;
    y
    *= f;
    z
    *= f;
    }


    void CVector3::CrossProduct(CVector3 &v1, CVector3 &v2)
    {
    x
    = ((v1.y * v2.z) - (v1.z * v2.y));
    y
    = ((v1.z * v2.x) - (v1.x * v2.z));
    z
    = ((v1.x * v2.y) - (v1.y * v2.x));
    }


    float CVector3::DotProduct3(CVector3 &v1)
    {
    return x * v1.x + y * v1.y + z * v1.z;
    }


    float CVector3::GetLength()
    {
    return (float)sqrt((x * x + y * y + z * z));
    }


    void CVector3::Normal()
    {
    float lenght = GetLength();

    if(lenght == 0.0f) lenght = 1.0f;

    x
    = x/lenght;
    y
    = y/lenght;
    z
    = z/lenght;
    }


    void CVector3::Normalize(CVector3 &v1, CVector3 &v2, CVector3 &v3)
    {
    CVector3 e1, e2;

    e1.x
    = v2.x - v1.x;
    e1.y
    = v2.y - v1.y;
    e1.z
    = v2.z - v1.z;
    e1.Normal();

    e2.x
    = v3.x - v1.x;
    e2.y
    = v3.y - v1.y;
    e2.z
    = v3.z - v1.z;
    e2.Normal();

    CrossProduct(e1, e2);
    Normal();
    }

      在引擎/游戏中涉及的矩阵类型是4×4矩阵。4×4矩阵是一个由4行4列共16个浮点变量构成的2D数组。程序清单8.35给出了单位矩阵完整的matrix.h头文件

    #ifndef _MATRIX_H_
    #define _MATRIX_H_


    #include
    "Vector.h"


    class CMatrix4x4
    {
    public:
    CMatrix4x4() { Identity(); }
    CMatrix4x4(
    const CMatrix4x4 &m);
    CMatrix4x4(
    float r11, float r12, float r13, float r14,
    float r21, float r22, float r23, float r24,
    float r31, float r32, float r33, float r34,
    float r41, float r42, float r43, float r44);
    ~CMatrix4x4() {}

    void Identity();

    void operator=(CMatrix4x4 &m);
    CMatrix4x4
    operator-(CMatrix4x4 &m);
    CMatrix4x4
    operator+(CMatrix4x4 &m);
    CMatrix4x4
    operator*(CMatrix4x4 &m);

    CMatrix4x4
    operator*(float f);
    CMatrix4x4
    operator/(float f);

    void operator +=(CMatrix4x4 &m);
    void operator -=(CMatrix4x4 &m);
    void operator *=(CMatrix4x4 &m);

    void operator *=(float f);
    void operator /=(float f);

    // 平移矩阵
    // @Translate 平移的向量
    void Translate(CVector3 &Translate);
    // @x,y,z 在x,y,z坐标上分别移动的距离
    void Translate(float x, float y, float z);

    // 反向平移
    void inverseTranslate();

    // 旋转矩阵
    // @angle 旋转度数
    // @x 若非0,则绕x轴旋转angle度
    // @y 若非0,则绕y轴旋转angle度
    // @z 若非0,则绕z轴旋转angle度
    void Rotate(double angle, int x, int y, int z);

    // 得到向量v与矩阵的积并输出 1x4 4x4
    CVector3 VectorMatrixMultiply(CVector3 &v);
    // 1x3 3x3
    CVector3 VectorMatrixMultiply3x3(CVector3 &v);

    float matrix[16];
    };

    #endif

      

    #include"Matrix.h"
    #include"MathDefines.h"
    
    
    CMatrix4x4::CMatrix4x4(const CMatrix4x4 &m)
    {
       matrix[0]  = m.matrix[0];
       matrix[4]  = m.matrix[4];
       matrix[8]  = m.matrix[8];
       matrix[12] = m.matrix[12];
    
       matrix[1]  = m.matrix[1];
       matrix[5]  = m.matrix[5];
       matrix[9]  = m.matrix[9];
       matrix[13] = m.matrix[13];
    
       matrix[2]  = m.matrix[2];
       matrix[6]  = m.matrix[6];
       matrix[10] = m.matrix[10];
       matrix[14] = m.matrix[14];
    
       matrix[3]  = m.matrix[3];
       matrix[7]  = m.matrix[7];
       matrix[11] = m.matrix[11];
       matrix[15] = m.matrix[15];
    }
    
    
    CMatrix4x4::CMatrix4x4(float r11, float r12, float r13, float r14,
                           float r21, float r22, float r23, float r24,
                           float r31, float r32, float r33, float r34,
                           float r41, float r42, float r43, float r44)
    {
       matrix[0]  = r11; matrix[1]  = r12; matrix[2]  = r13; matrix[3]  = r14;
    	matrix[4]  = r21; matrix[5]  = r22; matrix[6]  = r23; matrix[7]  = r24;
    	matrix[8]  = r31; matrix[9]  = r32; matrix[10] = r33; matrix[11] = r34;
    	matrix[12] = r41; matrix[13] = r42; matrix[14] = r43; matrix[15] = r44;
    }
    
    
    void CMatrix4x4::Identity()
    {
       matrix[0]  = 1.0f; matrix[1]  = 0.0f; matrix[2]  = 0.0f; matrix[3]  = 0.0f;
    	matrix[4]  = 0.0f; matrix[5]  = 1.0f; matrix[6]  = 0.0f; matrix[7]  = 0.0f;
    	matrix[8]  = 0.0f; matrix[9]  = 0.0f; matrix[10] = 1.0f; matrix[11] = 0.0f;
    	matrix[12] = 0.0f; matrix[13] = 0.0f; matrix[14] = 0.0f; matrix[15] = 1.0f;
    }
    
    
    void CMatrix4x4::operator =(CMatrix4x4 &m)
    {
       matrix[0]  = m.matrix[0]; matrix[1] = m.matrix[1];
       matrix[2] = m.matrix[2]; matrix[3]  = m.matrix[3];
    	matrix[4]  = m.matrix[4]; matrix[5] = m.matrix[5];
    	matrix[6] = m.matrix[6]; matrix[7]  = m.matrix[7];
    	matrix[8]  = m.matrix[8]; matrix[9] = m.matrix[9];
    	matrix[10] = m.matrix[10]; matrix[11] = m.matrix[11];
    	matrix[12] = m.matrix[12]; matrix[13] = m.matrix[13];
    	matrix[14] = m.matrix[14]; matrix[15] = m.matrix[15];
    }
    
    
    CMatrix4x4 CMatrix4x4::operator -(CMatrix4x4 &m)
    {
       return CMatrix4x4(matrix[0] - m.matrix[0], matrix[1] - m.matrix[1], matrix[2] - m.matrix[2],
                         matrix[3] - m.matrix[3], matrix[4] - m.matrix[4], matrix[5] - m.matrix[5],
                         matrix[6] - m.matrix[6], matrix[7] - m.matrix[7], matrix[8] - m.matrix[8],
                         matrix[9] - m.matrix[9], matrix[10] - m.matrix[10], matrix[11] - m.matrix[11],
                         matrix[12] - m.matrix[12], matrix[13] - m.matrix[13],
                         matrix[14] - m.matrix[14], matrix[15] - m.matrix[15]);
    }
    
    
    CMatrix4x4 CMatrix4x4::operator +(CMatrix4x4 &m)
    {
       return CMatrix4x4(matrix[0] + m.matrix[0], matrix[1] + m.matrix[1], matrix[2] + m.matrix[2],
                         matrix[3] + m.matrix[3], matrix[4] + m.matrix[4], matrix[5] + m.matrix[5],
                         matrix[6] + m.matrix[6], matrix[7] + m.matrix[7], matrix[8] + m.matrix[8],
                         matrix[9] + m.matrix[9], matrix[10] + m.matrix[10], matrix[11] + m.matrix[11],
                         matrix[12] + m.matrix[12], matrix[13] + m.matrix[13],
                         matrix[14] + m.matrix[14], matrix[15] + m.matrix[15]);
    }
    
    
    CMatrix4x4 CMatrix4x4::operator *(CMatrix4x4 &m)
    {
       return CMatrix4x4(matrix[0] * m.matrix[0] + matrix[4] * m.matrix[1] + matrix[8] *
                         m.matrix[2] + matrix[12] * m.matrix[3],
    						   matrix[1] * m.matrix[0] + matrix[5] * m.matrix[1] + matrix[9] *
                         m.matrix[2] + matrix[13] * m.matrix[3],
    						   matrix[2] * m.matrix[0] + matrix[6] * m.matrix[1] + matrix[10] *
                         m.matrix[2] + matrix[14] * m.matrix[3],
    						   matrix[3] * m.matrix[0] + matrix[7] * m.matrix[1] + matrix[11] *
                         m.matrix[2] + matrix[15] * m.matrix[3],
    						   matrix[0] * m.matrix[4] + matrix[4] * m.matrix[5] + matrix[8] *
                         m.matrix[6] + matrix[12] * m.matrix[7],
    						   matrix[1] * m.matrix[4] + matrix[5] * m.matrix[5] + matrix[9] *
                         m.matrix[6] + matrix[13] * m.matrix[7],
    						   matrix[2] * m.matrix[4] + matrix[6] * m.matrix[5] + matrix[10] *
                         m.matrix[6] + matrix[14] * m.matrix[7],
    						   matrix[3] * m.matrix[4] + matrix[7] * m.matrix[5] + matrix[11] *
                         m.matrix[6] + matrix[15] * m.matrix[7],
    						   matrix[0] * m.matrix[8] + matrix[4] * m.matrix[9] + matrix[8] *
                         m.matrix[10] + matrix[12] * m.matrix[11],
    						   matrix[1] * m.matrix[8] + matrix[5] * m.matrix[9] + matrix[9] *
                         m.matrix[10] + matrix[13] * m.matrix[11],
    						   matrix[2] * m.matrix[8] + matrix[6] * m.matrix[9] + matrix[10] *
                         m.matrix[10] + matrix[14] * m.matrix[11],
    						   matrix[3] * m.matrix[8] + matrix[7] * m.matrix[9] + matrix[11] *
                         m.matrix[10] + matrix[15] * m.matrix[11],
    						   matrix[0] * m.matrix[12] + matrix[4] * m.matrix[13] + matrix[8] *
                         m.matrix[14] + matrix[12] * m.matrix[15],
    						   matrix[1] * m.matrix[12] + matrix[5] * m.matrix[13] + matrix[9] *
                         m.matrix[14] + matrix[13] * m.matrix[15],
    						   matrix[2] * m.matrix[12] + matrix[6] * m.matrix[13] + matrix[10] *
                         m.matrix[14] + matrix[14] * m.matrix[15],
    						   matrix[3] * m.matrix[12] + matrix[7] * m.matrix[13] + matrix[11] *
                         m.matrix[14] + matrix[15] * m.matrix[15]);
    }
    
    
    CMatrix4x4 CMatrix4x4::operator *(float f)
    {
       return CMatrix4x4(matrix[0]  * f, matrix[1]  * f, matrix[2]  * f, matrix[3]  * f,
                         matrix[4]  * f, matrix[5]  * f, matrix[6]  * f, matrix[7]  * f,
                         matrix[8]  * f, matrix[9]  * f, matrix[10] * f, matrix[11] * f,
                         matrix[12] * f, matrix[13] * f, matrix[14] * f, matrix[15] * f);
    }
    
    
    CMatrix4x4 CMatrix4x4::operator /(float f)
    {
       if(f == 0) f = 1;
       f = 1/f;
    
       return CMatrix4x4(matrix[0]  * f, matrix[1]  * f, matrix[2]  * f, matrix[3]  * f,
                         matrix[4]  * f, matrix[5]  * f, matrix[6]  * f, matrix[7]  * f,
                         matrix[8]  * f, matrix[9]  * f, matrix[10] * f, matrix[11] * f,
                         matrix[12] * f, matrix[13] * f, matrix[14] * f, matrix[15] * f);
    }
    
    
    void CMatrix4x4::operator +=(CMatrix4x4 &m)
    {
       (*this) = (*this) + m;
    }
    
    
    void CMatrix4x4::operator -=(CMatrix4x4 &m)
    {
       (*this) = (*this) - m;
    }
    
    
    void CMatrix4x4::operator *=(CMatrix4x4 &m)
    {
       (*this) = (*this) * m;
    }
    
    
    void CMatrix4x4::operator *=(float f)
    {
       (*this) = (*this) * f;
    }
    
    
    void CMatrix4x4::operator /=(float f)
    {
       (*this) = (*this) / f;
    }
    
    
    void CMatrix4x4::Translate(CVector3 &Translate)
    {
       matrix[12] = Translate.x;
       matrix[13] = Translate.y;
       matrix[14] = Translate.z;
       matrix[15] = 1.0f;
    }
    
    
    void CMatrix4x4::Translate(float x, float y, float z)
    {
       matrix[12] = x;
       matrix[13] = y;
       matrix[14] = z;
       matrix[15] = 1.0f;
    }
    
    
    void CMatrix4x4::inverseTranslate()
    {
       matrix[12] = -matrix[12];
       matrix[13] = -matrix[13];
       matrix[14] = -matrix[14];
    }
    
    
    void CMatrix4x4::Rotate(double angle, int x, int y, int z)
    {
       angle = angle * PI / 180;
       float cosAngle = cosf((float)angle);
       float sineAngle = sinf((float)angle);
    
       if(z)
          {
              matrix[0] = cosAngle;
    	      matrix[1] = sineAngle;
    	      matrix[4] = -sineAngle;
    	      matrix[5] = cosAngle;
          }
    
       if(y)
          {
              matrix[0]  = cosAngle;
    	      matrix[2]  = -sineAngle;
    	      matrix[8]  = sineAngle;
    	      matrix[10] = cosAngle;
          }
    
       if(x)
          {
    	      matrix[5]  = cosAngle;
    	      matrix[6]  = sineAngle;
    	      matrix[9]  = -sineAngle;
    	      matrix[10] = cosAngle;
          }
    }
    
    
    CVector3 CMatrix4x4::VectorMatrixMultiply(CVector3 &v)
    {
       CVector3 out;
    
       out.x = (v.x * matrix[0]) + (v.y * matrix[4]) + (v.z * matrix[8]) + matrix[12] /** 1*/;
       out.y = (v.x * matrix[1]) + (v.y * matrix[5]) + (v.z * matrix[9]) + matrix[13]/* * 1*/;
       out.z = (v.x * matrix[2]) + (v.y * matrix[6]) + (v.z * matrix[10]) + matrix[14]/* * 1*/;
    
       return out;
    }
    
    
    CVector3 CMatrix4x4::VectorMatrixMultiply3x3(CVector3 &v)
    {
       CVector3 out;
    
       out.x = (v.x * matrix[0]) + (v.y * matrix[4]) + (v.z * matrix[8]);
       out.y = (v.x * matrix[1]) + (v.y * matrix[5]) + (v.z * matrix[9]);
       out.z = (v.x * matrix[2]) + (v.y * matrix[6]) + (v.z * matrix[10]);
    
       return out;
    }
    

         接下来将为数学库添加四元组类。如您所想,四元组类用于存储四元组对象,这样就可以在3D中实现平滑的旋转和内插操作。四元组类也包含一些重载运算符,如“=”、“×”和“/”等,另外,还包含一些针对四元组的成员函数。这些函数包括从轴创建四元组、获取四元组长度、归一化四元组、查找四元组共轭(四元组共轭也就是四元组的共轭转置)、计算两个四元组的叉积、旋转四元组、由四元组创建矩阵及对两个四元组进行球形内插。程序清单8.38给出了完整的quaternion.h头文件。

    #ifndef _QUATERNION_H_
    #define _QUATERNION_H_
    
    #include<math.h>
    #include"Vector.h"
    #include"MathDefines.h"
    
    
    class CQuaternion 
    {
    public:
    	CQuaternion();
    	CQuaternion(float xAxis, float yAxis,
    		float zAxis, float wAxis);
    
    	void operator=(const CQuaternion &q);
    	CQuaternion operator*(const CQuaternion &q);
    	CQuaternion operator+(const CQuaternion &q);
    
    	void CreateQuatFromAxis(CVector3 &a, float radians);
    
    	float Length();
    	void Normal();
    
    	// 共轭
    	CQuaternion Conjugate();
    	// 叉积
    	CQuaternion CrossProduct(const CQuaternion &q);
    
    	void Rotatef(float amount, float xAxis, float yAxis, float zAxis);
    	void RotationRadiansf(double X, double Y, double Z);
    
    	// 从该四元组创建矩阵,该矩阵对于将四元组转换成Direct3D和OpenGL
    	// 可用的形式非常有用.
    	void CreateMatrix(float *pMatrix);
    
    	// 球形内插函数。球形内插函数(SLERP)用于创建两个四元组对象之间的平滑内插。
    	// 球形内插的应用较普遍,尤其是在骨骼动画中用得更多。
    	void Slerp(const CQuaternion &q1, const CQuaternion &q2, float t);
    
    	float w, x, y, z;
    };
    
    #endif
    

      

    #include"Quaternion.h"
    
    
    CQuaternion::CQuaternion()
    {
       x = y = z = 0.0f;
       w = 1.0f;
    }
    
    
    CQuaternion::CQuaternion(float xAxis, float yAxis,
                             float zAxis, float wAxis) 
    {
    	x = xAxis; y = yAxis; z = zAxis;
       w = wAxis;
    }
    
    
    void CQuaternion::operator=(const CQuaternion &q)
    {
       w = q.w; x = q.x; y = q.y; z = q.z;
    }
    
    
    CQuaternion CQuaternion::operator*(const CQuaternion &q)
    {
       return CQuaternion(w * q.x + x * q.w + y * q.z - z * q.y,
                            w * q.y - x * q.z + y * q.w + z * q.x,
                            w * q.z + x * q.y - y * q.x + z * q.w,
                            w * q.w - x * q.x - y * q.y - z * q.z);
    }
    
    CQuaternion CQuaternion::operator+(const CQuaternion &q)
    {
       CQuaternion result;
    
       CVector3 v1(x, y, z), v2(q.x, q.y, q.z), cross, v3;
       float newW = 0;
    
       cross.CrossProduct(v2, v1);
       v1 *= q.w;
       v2 *= w;
       
       v3 = v1 + v2;
       v3 = cross + v3;
    
       newW = w * q.w - (x * q.x + y * q.y + z * q.z);
       
       result.x = v3.x; result.y = v3.y;
       result.z = v3.z; result.w = newW;
    
       return result;
    }
    
    void CQuaternion::CreateQuatFromAxis(CVector3 &a, float radians)
    {
       float sine = 0.0f;
       
       radians = radians * 0.5f;
       sine = (float)sin(radians);
       
       a.Normal();
    
       x = a.x; y = a.y; z = a.z;
    
       x *= sine;
       y *= sine;
       z *= sine;
       w = (float)cos(radians);
    }
    
    float CQuaternion::Length()
    {
       return (float)sqrt(x * x + y * y + z * z + w * w);
    }
    
    
    void CQuaternion::Normal()
    {
       float len = Length();
       len = 1 / len;
    
       x = x * len;
       y = y * len;
       z = z * len;
       w = w * len;
    }
    
    
    CQuaternion CQuaternion::Conjugate()
    {
       return CQuaternion(-x, -y, -z, w);
    }
    
    
    CQuaternion CQuaternion::CrossProduct(const CQuaternion &q)
    {
       CQuaternion crossProduct;
    
       crossProduct.x = w * q.x + x * q.w + y * q.z - z * q.y;
       crossProduct.y = w * q.y + x * q.z + y * q.w - z * q.x;
       crossProduct.z = w * q.z + x * q.y + y * q.x - z * q.w;
       crossProduct.w = w * q.w - x * q.x - y * q.y - z * q.z;
    
       return crossProduct;
    }
    
    void CQuaternion::Rotatef(float amount, float xAxis,
                              float yAxis, float zAxis)
    {
       if((xAxis + yAxis + zAxis) != 1)
       {
          float length = (float)sqrt(xAxis * xAxis +
                                     yAxis * yAxis +
                                     zAxis * zAxis);
          xAxis /= length; yAxis /= length; zAxis /= length;
       }
    
       float angle = GET_RADIANS(amount);
    	float sine = (float)sin(angle / 2.0f);
    
    	x = xAxis * sine;
    	y = yAxis * sine;
    	z = zAxis * sine;
       w = (float)cos(angle / 2.0f);
    }
    
    void CQuaternion::RotationRadiansf(double X, double Y, double Z)
    {
       double cosX, cosY, cosZ;
       double sinX, sinY, sinZ;
       double cosXY, sinXY;
    
       sinX = sin(X * 0.5);
       cosX = cos(X * 0.5);
       
       sinY = sin(Y * 0.5);
       cosY = cos(Y * 0.5);
       
       sinZ = sin(Z * 0.5);
       cosZ = cos(Z * 0.5);
    
       cosXY = cosX * cosY;
       sinXY = sinX * sinY;
    
       x = (float)(sinX * cosY * cosZ - cosX * sinY * sinZ);
       y = (float)(cosX * sinY * cosZ + sinX * cosY * sinZ);
       z = (float)(cosXY * sinZ - sinXY * cosZ);
       w = (float)(cosXY * cosZ + sinXY * sinZ); 
    }
    
    void CQuaternion::CreateMatrix(float *pMatrix)
    {
    	if(!pMatrix) return;
    
       pMatrix[0]  = 1.0f - 2.0f * (y * y + z * z); 
       pMatrix[1]  = 2.0f * (x * y + z * w);
       pMatrix[2]  = 2.0f * (x * z - y * w);
       pMatrix[3]  = 0.0f;  
    
       pMatrix[4]  = 2.0f * (x * y - z * w);  
       pMatrix[5]  = 1.0f - 2.0f * (x * x + z * z); 
       pMatrix[6]  = 2.0f * (z * y + x * w);  
       pMatrix[7]  = 0.0f;  
    
       pMatrix[8]  = 2.0f * (x * z + y * w);
       pMatrix[9]  = 2.0f * (y * z - x * w);
       pMatrix[10] = 1.0f - 2.0f * (x * x + y * y);  
       pMatrix[11] = 0.0f;  
    
       pMatrix[12] = 0;  
       pMatrix[13] = 0;  
       pMatrix[14] = 0;  
       pMatrix[15] = 1.0f;
    }
    
    void CQuaternion::Slerp(const CQuaternion &q1, const CQuaternion &q2, float t)
    {
       float cosTheta = 0.0f;
       float sinTheta = 0.0f;
       float beta = 0.0f;
       float q2Array[4];
    
       q2Array[0] = q2.x; q2Array[1] = q2.y;
       q2Array[2] = q2.z; q2Array[3] = q2.w;
    
       cosTheta = q1.x * q2.x + q1.y * q2.y +
                  q1.z * q2.z + q1.w * q2.w;
    
       if(cosTheta < 0.0f)
          {
             // Flip sigh if so.
             q2Array[0] = -q2Array[0]; q2Array[1] = -q2Array[1];
             q2Array[2] = -q2Array[2]; q2Array[3] = -q2Array[3];
             cosTheta = -cosTheta;
          }
    
       beta = 1.0f - t;
    
       if(1.0f - cosTheta > 0.001f)
          {
             // We are using spherical interpolation.
             cosTheta = (float)acos(cosTheta);
             sinTheta = 1.0f / (float)sin(cosTheta);
             beta = (float)sin(cosTheta * beta) * sinTheta;
             t = (float)sin(cosTheta * t) * sinTheta;
          }
    
       // Interpolation.
       x = beta * q1.x + t * q2Array[0];
       y = beta * q1.y + t * q2Array[1];
       z = beta * q1.z + t * q2Array[2];
       w = beta * q1.w + t * q2Array[3];
    }
    

      射线类用于测试射线是否和球、三角形或平面相交。这主要用于碰撞检测,随着本书的进展将在该类中添加一些处理代码。射线类简单明了,它包含了两个成员对象,分别代表原点(位置)和射线方向。程序清单8.41给出了完整的ray.h头文件。

      



  • 相关阅读:
    一则浏览器兼容性解决案例(搜狗)
    使用sass命令行,包含bourbon,neat包的项目
    指针例1
    数学建模四0-1规划
    数学建模3
    数学建模2.生产计划
    复数的实现1.3
    多文件操作1.2.5
    函数及参数类型1.2.4
    指针类型1.2.3
  • 原文地址:https://www.cnblogs.com/kex1n/p/2174782.html
Copyright © 2011-2022 走看看