从0开发游戏引擎之游戏引擎底层数学库实现

简介: 从0开发游戏引擎之游戏引擎底层数学库实现

程序1.4


void Matrix3D::ZRotate(float angle)
{
  m[0][0] = cos(GL_PI / 180 * angle); m[0][1] = sin(GL_PI / 180 * angle);
  m[1][0] = -sin(GL_PI / 180 * angle);m[1][1] = cos(GL_PI / 180 * angle);
}


矩阵平移:直接往矩阵的设置三个空间信息就可以,这个没难度。


程序1.5


void Matrix3D::Translate(float x, float y, float z)
{
  m[3][0] = x;
  m[3][1] = y;
  m[3][2] = z;
}


矩阵缩放:直接往矩阵的设置三个空间信息就可以,这个没难度。


程序1.6


void Matrix3D::Scale(float x, float y, float z)
{
  m[0][0] *= x;
  m[1][1] *= y;
  m[2][2] *= z;
}


矩阵绕XYZ翻转:我们使用的方法是让x,y,z的旋转角度直接*-1 空间就翻转过来了。


程序1.7


void Matrix3D::FlipX()
{
  m[1][1] *=-1;
}
void Matrix3D::FlipY()
{
  m[0][0] *= -1;
}
void Matrix3D::FlipZ()
{
  m[3][3] *= -1;
}


代码太多了,还有一些复杂的运算,到时候有时间了再把矩阵求逆和矩阵转置讲一下,还有把摄像机的俯仰角算成矩阵的讲一下。剩下的都是些简单的运算就自己研究下把。先把代码贴出来。


GLMath.h


#pragma once
#define PI 3.141596
class Vector2
{ 
private:
public:
int PointNum=0;
float x, y;
    Vector2(float x, float y) { this->x = x;this->y = y; }
    void setXy(float x, float y) { this->x = x; this->y = y; }
    Vector2 &operator /= (float n)
    {
      this->x /= n;
      this->y /= n;
      return *this;
    }
    Vector2& operator *= (float n)
    {
      this->x *= n;
      this->y *= n;
      return *this;
    }
    Vector2& operator += (Vector2 &vec)
    {
      this->x += vec.x;
      this->y += vec.y;
      return *this;
    }
    Vector2& operator -= (Vector2 &vec)
    {
      this->x -= vec.x;
      this->y -= vec.y;
      return *this;
    }
    Vector2 operator* (float n)
    {
      Vector2 temp = *this;
      temp.x *= n;
      temp.y *= n;
      return temp;
    }
    Vector2 operator/ (float n)
    {
      Vector2 temp = *this;
      temp.x /= n;
      temp.y /= n;
      return temp;
    }
    Vector2 operator+ (Vector2 vec)
    {
      Vector2 temp = *this;
      temp.x += vec.x;
      temp.y += vec.y;
      return temp;
    }
    Vector2 operator- (Vector2 vec)
    {
      Vector2 temp = *this;
      temp.x -= vec.x;
      temp.y -= vec.y;
      return temp;
    }
    void normalize()
    {
      float len = sqrt(x*x + y*y);
      x /= len;
      y /= len;
    }
    Vector2 Normalize()
    {
      Vector2 temp = *this;
      float len = sqrt(temp.x*temp.x + temp.y*temp.y);//单位化
      temp.x /= len;
      temp.y /= len;
      return temp;
    }
    float length()
    {
      return sqrt(x*x + y*y);
    }
    float length2q()
    {
      return x*x + y*y;
    }
    float dot(Vector2 &vec)//点乘
    {
      return x*vec.x +y*vec.y;
    }
    Vector2 projection(Vector2&vec)//投影
    {
      Vector2 temp;
      temp = vec.Normalize();
      Vector2 temp1;
      temp1 = temp*dot(temp);
      return temp1;
    }
    Vector2 ortho()//正交
    {
      Vector2 temp=*this;
      temp.x = y;
      temp.y = -x;
      return temp;
    }
    float Cross(Vector2 &vec)//叉乘
    {
      Vector2 a = *this;
      return a.x * vec.x - a.y * vec.y;
    }
    Vector2::Vector2() { x = 0, y = 0; }
    Vector2::~Vector2() {}
};
class Vector3D
{
public:
  float x, y, z;
  Vector3D(float x, float y, float z) {this->x = x; this->y = y;this->z = z;}
  void setXYZ(float x, float y, float z){this->x = x; this->y = y; this->z = z;}
  void normalize()
  {
    float len = sqrt(x*x + y*y+z*z);
    x /= len;
    y /= len;
    z /= len;
  }
  Vector3D Normalize()
  { 
    Vector3D temp=*this;
    float len = sqrt(x*x + y*y + z*z);
    temp.x /= len;
    temp.y /= len;
    temp.z /= len;
    return temp;
  }
  float length()
  {
    return sqrt(x*x + y*y+z*z);
  }
  float length2q()
  {
    return x*x + y*y + z*z;
  }
  float dot(Vector3D &vec)//点乘
  {
    return x*vec.x +y*vec.y +z*vec.z;
  }
  Vector3D &operator /= (float n)
  {
    this->x /= n;
    this->y /= n;
    this->z /= n;
    return *this;
  }
  Vector3D& operator *= (float n)
  {
    this->x *= n;
    this->y *= n;
    this->z *= n;
    return *this;
  }
  Vector3D& operator += (Vector3D &vec)
  {
    this->x += vec.x;
    this->y += vec.y;
    this->z += vec.z;
    return *this;
  }
  Vector3D& operator -= (Vector3D &vec)
  {
    this->x -= vec.x;
    this->y -= vec.y;
    this->z -= vec.z;
    return *this;
  }
  Vector3D operator* (float n)
  {
    Vector3D temp = *this;
    temp.x *= n;
    temp.y *= n;
    temp.z *= n;
    return temp;
  }
  Vector3D operator/ (float n)
  {
    Vector3D temp = *this;
    temp.x /= n;
    temp.y /= n;
    temp.z /= n;
    return temp;
  }
  Vector3D operator+ (Vector3D vec)
  {
    Vector3D temp = *this;
    temp.x += vec.x;
    temp.y += vec.y;
    temp.z += vec.z;
    return temp;
  }
  Vector3D operator+(float n)
  {
    Vector3D temp = *this;
    temp.x += n;
    temp.y += n;
    temp.z += n;
    return temp;
  }
  Vector3D operator-()
  {
    Vector3D vec ;
    Vector3D temp = *this;
    vec.x =-temp.x;
    vec.y=-temp.y;
    vec.z = -temp.z;
    return vec;
  }
  Vector3D operator- (Vector3D vec)
  {
    Vector3D temp = *this;
    temp.x -= vec.x;
    temp.y -= vec.y;
    temp.z -= vec.z;
    return temp;
  }
  bool operator == (Vector3D &vec)
  {
    if (this->x == vec.x&&this->y == vec.y&&this->z==vec.z)
      return true;
    else
      return false;
  }
  bool operator >= (Vector3D &vec)
  {
    if (this->x >=vec.x&&this->y>=vec.y&&this->z>=vec.z)
      return true;
    else
      return false;
  }
  bool operator <= (Vector3D &vec)
  {
    if (this->x <= vec.x&&this->y <= vec.y&&this->z<=vec.z)
      return true;
    else
      return false;
  }
  bool operator %=(Vector3D &vec)
  {
    if (this->x <= vec.x&&this->y <= vec.y&&this->z >=vec.z)
      return true;
    else
      return false;
  }
  int operator || (Vector3D &vec)   //判断距离差的是正还是负
  {
    if (vec.x > 0 && vec.z > 0)
      return 1;
    else if(vec.x < 0 && vec.z < 0)
      return -1;
    else
      return 0;
  }
  Vector3D projection(Vector3D&vec)//投影
  {
    Vector3D temp;
    temp = vec.Normalize();
    Vector3D temp1;
    temp1 = temp*dot(temp);
    return temp1;
  }
  Vector3D cross(Vector3D &v)
  {
    Vector3D temp;
    temp.x = y * v.z - z * v.y;
    temp.y = z * v.x - x * v.z;
    temp.z = x * v.y - y * v.x;
    return temp;
  }
  Vector3D::Vector3D() {}
  Vector3D::~Vector3D() {}
};
Vector3D operator*(Vector3D vc1, Vector3D vc2);
struct Vector4D
{
public:
  float x, y, z, w;
  Vector4D(float x, float y, float z, float w)
  {
    this->x = x;this->y = y;
    this->z = z;this->w = w;
  }
  void setXYZW(float x, float y, float z, float w)
  {
    this->x = x;this->y = y;
    this->z = z;this->w = w; 
  }
  Vector4D() {}
  ~Vector4D() {}
};
class Matrix3
{
public:
  union {
    struct {
      float    _11, _21, _31,_41;   //_11,_12,_13,_14 |
      float        _12, _22, _32,_42;   //_21,_22,_23,_24 |转置后的矩阵
      float        _13, _23, _33,_43;   //_31,_32,_33,_34 |  
      float        _14, _24, _34,_44;   //_41,_42,_43,_44 |
    };                    //openGL用的是行矩阵,但是是列的算法
    float mat[16];
    float m[4][4];
  };
  Matrix3()
  {
    for (int i = 0; i < 4; ++i)
      for (int j = 0; j < 4; ++j)
        if (i == j)
          m[i][j] = 1;
        else
          m[i][j] = 0;
  }
  Matrix3 operator*(Matrix3& mat);//矩阵*矩阵
  Matrix3 &operator*=(const Matrix3 &mat);      //矩阵与矩阵
  Vector2 operator*(const Vector2 &v);      //矩阵与向量
  Matrix3 &Rotate(float angle);     //绕Z轴旋转
  Matrix3 &Translate(float x, float y,float z); //平移
  Matrix3 &Translate(float x, float y);
  Matrix3 &Scale(float x, float y);     //比例
  Matrix3 &FlipX();     //x轴翻转
  Matrix3 &FlipY();     //y轴翻转
  void Identity()//矩阵单位化
  {
    m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;
    m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = 0;
    m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = 0;
    m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
  } 
~Matrix3();
};
Matrix3 operator*(const Matrix3 &mat1, const Matrix3 &mat2);      //矩阵与矩阵
Vector2 operator*(const Vector2 &v, const Matrix3 &mat);      //矩阵与向量
Matrix3 &Rotate(Matrix3 &mat, float angle);     //绕Z轴旋转
Matrix3 &Translate(Matrix3 &mat, float x, float y,float z);     //平移
Matrix3 &Translate(Matrix3 &mat, float x, float y);
Matrix3 &Scale(Matrix3 &mat, float x, float y);     //比例
Matrix3 &FlipX(Matrix3 &mat);     //x轴翻转
Matrix3 &FlipY(Matrix3 &mat);     //y轴翻转
void Vec2TransformCoord(Vector2 &newVec, Vector2 &cornerPoint, Matrix3 &world_matrix);
//************3D*******************
class Matrix3D
{
public:
  union {
    struct {
      float    _11, _21, _31, _41;    //_11,_12,_13,_14 |
      float        _12, _22, _32, _42;    //_21,_22,_23,_24 |转置后的矩阵
      float        _13, _23, _33, _43;    //_31,_32,_33,_34 |  
      float        _14, _24, _34, _44;    //_41,_42,_43,_44 |
    };                    //openGL用的是行矩阵,但是是列的算法
    float mat[16];
    float m[4][4];
  };
  Matrix3D()
  {
    m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;
    m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = 0;
    m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = 0;
    m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
  }
  Matrix3D operator*(Matrix3D &mat);//矩阵*矩阵
  Matrix3D &operator*=(Matrix3D &mat);  //矩阵与矩阵
  Vector3D operator*(Vector3D &v);      //矩阵与向量
  Matrix3D MatrixInverse(Matrix3D &m);    //逆矩阵
  void XRotate(float angle);      //绕X轴旋转
  void YRotate(float angle);      //绕Y轴旋转
  void ZRotate(float angle);      //绕Z轴旋转
  void Translate(float x, float y, float z);//平移
  void Scale(float x, float y, float z);      //比例
  void FlipX();     //x轴翻转
  void FlipY();     //y轴翻转
  void FlipZ();          //z翻转
  void Identity()//矩阵单位化
  {
    m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;
    m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = 0;
    m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = 0;
    m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
  }
  ~Matrix3D(){};
};
Matrix3D MatrixRotationAxis(Vector3D &axis, float angle);
Matrix3D MatrixRotationAxisRad(Vector3D &axis, float radian);
Vector3D Vec3TransformCoord(Matrix3D &m, Vector3D &v);
Vector2 Vec3TransformCoord(Matrix3D &m, Vector2 &v);
Vector3D Vec3TransformNormal(Matrix3D &m, Vector3D &v);
Matrix3D YRotate(float angle);        //绕Y轴旋转(全局函数)
Matrix3D MatrixTranspose(Matrix3D &m);    //转置矩阵
Matrix3D MatrixInverse(Matrix3D &m);    //逆矩阵
Matrix3D FromToRotation(Vector3D from, Vector3D to);
Matrix3D &MatrixRotationYawPitchRoll(float Yaw, float Pitch, float Roll);
Matrix3D &MatrixRotationY(float angle);
struct sColor
{
public:
union {
  struct {
    float    r, g, b, a;
  };
  float color[4];//r,g,b,a的分量
};
  sColor()//默认颜色
  {
    color[0] = 1.0f;
    color[1] = 1.0f;
    color[2] = 1.0f;
    color[3] = 1.0f;
  }
  sColor(float r, float g, float b, float a)//外部初始化颜色
  {
    color[0] = r;
    color[1] = g;
    color[2] = b;
    color[3] = a;
  }
  float getR() { return color[0]; }
  float getG() { return color[1]; }
  float getB() { return color[2]; }
  float getA() { return color[3]; }
  void operator=(DWORD col)
  {
    color[0] = (col >> 16 & 0xff)*0.00392156862;
    color[1] = (col >> 8 & 0xff)*0.00392156862;
    color[2] = (col & 0xff)*0.00392156862;
    color[3] = (col >> 24)*0.00392156862;
  }
  void operator+=(float z)
  {
    r +=z;  g +=z;  b +=z;
  }
  bool operator==(float z)
  {
    if (r == z&&g == z&&b == z)
      return true;
    return false;
  }
  bool operator>=(float z)
  {
    if (r>=z&&g>=z&&b>=z)
      return true;
    return false;
  }
  bool operator <= (float z)
  {
    if (r <= z&&g <= z&&b <= z)
      return true;
    return false;
  }
};


GLMath.cpp


#include "Engine.h"
Vector2 Matrix3::operator*(const Vector2 &v)
{
  return Vector2(v.x*m[0][0] + v.y*m[1][0] + m[3][0], v.x*m[0][1] + v.y*m[1][1] + m[3][1]);
}
Matrix3 Matrix3::operator*(Matrix3&mat)
{
  Matrix3 temp;
  for (int i = 0; i < 4; i++)
  {
    for (int j = 0; j < 4; j++)
    {
      temp.m[i][j] =
      m[i][0] * mat.m[0][j] +
      m[i][1] * mat.m[1][j] +
      m[i][2] * mat.m[2][j] +
      m[i][3] * mat.m[3][j];
    }
  }
  return temp;
}
Matrix3 &Matrix3::operator*=(const Matrix3 &mat)
{
  Matrix3 cal=*this;
  for (int i = 0; i < 4; i++)
    for (int j = 0; j < 4; j++)
      m[i][j] =
      cal.m[i][0] * mat.m[0][j] +
      cal.m[i][1] * mat.m[1][j] +
      cal.m[i][2] * mat.m[2][j] +
      cal.m[i][3] * mat.m[3][j];
  return *this;
}
Matrix3 &Matrix3::Rotate(float angle)     //绕Z轴旋转
{
  return ::Rotate(*this, angle);
}
Matrix3 &Matrix3::Translate(float x, float y,float z)     //平移
{
  return ::Translate(*this, x, y,z);
}
Matrix3 &Matrix3::Translate(float x, float y)
{
  return ::Translate(*this, x, y);
}
Matrix3 &Matrix3::Scale(float x, float y)     //比例
{
  return ::Scale(*this, x, y);
}
Matrix3 &Matrix3::FlipX()     //x轴翻转
{
  return ::FlipX(*this);
}
Matrix3 &Matrix3::FlipY()     //y轴翻转
{
  return ::FlipY(*this);
}
void Vec2TransformCoord(Vector2 &newVec, Vector2 &cornerPoint, Matrix3 &world_matrix)
{
  Vector2 temp;
  temp.x = cornerPoint.x*world_matrix.m[0][0]+ cornerPoint.y*world_matrix.m[0][1]+ world_matrix.m[3][0];
  temp.y= cornerPoint.x*world_matrix.m[1][0] + cornerPoint.y*world_matrix.m[1][1]+ world_matrix.m[3][1];
  newVec = temp;
}
Matrix3::~Matrix3()
{
}
//以上为类成员函数
//以下为全局函数
Matrix3 operator*(const Matrix3 &mat1, const Matrix3 &mat2)
{
  Matrix3 temp;
  for (int i = 0; i < 4; i++)
  {
    for (int j = 0; j < 4; j++)
    {
      temp.m[i][j] =
        mat1.m[i][0] * mat2.m[0][j] +
        mat1.m[i][1] * mat2.m[1][j] +
        mat1.m[i][2] * mat2.m[2][j] +
        mat1.m[i][3] * mat2.m[3][j];
    }
  }
  return temp;
}
Vector2 operator*(const Vector2 &v, const Matrix3 &mat)
{
  return Vector2(v.x*mat.m[0][0] + v.y*mat.m[1][0] + mat.m[3][0], v.x*mat.m[0][1] + v.y*mat.m[1][1] + mat.m[3][1]);
}
Matrix3 &Rotate(Matrix3 &mat, float angle)
{
  mat.m[0][0] = cos(GL_PI / 180 * angle); mat.m[0][1] = sin(GL_PI / 180 * angle);
  mat.m[1][0] = -1 * sin(GL_PI / 180 * angle); mat.m[1][1] = cos(GL_PI / 180 * angle);
  return mat;
}
Matrix3 &Translate(Matrix3 &mat, float x, float y,float z)
{
  mat.m[3][0] = x;
  mat.m[3][1] = y;
  mat.m[3][2] = z;
  return mat;
}
Matrix3 &Translate(Matrix3 &mat, float x, float y)
{
  mat.m[3][0] = x;
  mat.m[3][1] = y;
  return mat;
}
Matrix3 &Scale(Matrix3 &mat, float x, float y)
{
  mat.m[0][0] *= x;
  mat.m[1][1] *= y;
  return mat;
}
Matrix3 &FlipX(Matrix3 &mat)      //x轴翻转
{
  mat.m[1][1] *= -1;
  return mat;
}
Matrix3 &FlipY(Matrix3 &mat)      //y轴翻转
{
  mat.m[0][0] *= -1;
  return mat;
}
//************3D******************
Matrix3D Matrix3D::operator*(Matrix3D &mat)
{
  Matrix3D temp;
  for (int i = 0; i < 4; i++)
  {
    for (int j = 0; j < 4; j++)
    {
      temp.m[i][j] =
        m[i][0] * mat.m[0][j] +
        m[i][1] * mat.m[1][j] +
        m[i][2] * mat.m[2][j] +
        m[i][3] * mat.m[3][j];
    }
  }
  return temp;
}
Matrix3D &Matrix3D::operator*=(Matrix3D &mat)
{
  Matrix3D cal = *this;
  for (int i = 0; i < 4; i++)
    for (int j = 0; j < 4; j++)
      m[i][j] =
      cal.m[i][0] * mat.m[0][j] +
      cal.m[i][1] * mat.m[1][j] +
      cal.m[i][2] * mat.m[2][j] +
      cal.m[i][3] * mat.m[3][j];
  return *this;
}
Vector3D Matrix3D::operator*(Vector3D&v)
{
  Vector3D res;
  res.x = m[0][0]*v.x+m[1][0]*v.y+m[2][0]*v.z ;
  res.y = m[0][1]*v.x+m[1][1]*v.y+m[2][2]*v.z;
  res.z = m[0][2]*v.x+m[1][2]*v.y+m[2][3]*v.z;
  return res;
}
Vector3D operator*(Vector3D v1, Vector3D v2)
{
  Vector3D temp;
  temp.x=v1.x*=v2.x;
  temp.y=v1.y*=v2.y;
  temp.z=v1.z*=v2.z;
  return temp;
}
void Matrix3D::XRotate(float angle)
{
  m[1][1] =cos(GL_PI/180*angle) ; m[1][2] =sin(GL_PI/180*angle) ;
  m[2][1] =-sin(GL_PI/180*angle); m[2][2] =cos(GL_PI/180*angle) ;
}
void Matrix3D::YRotate(float angle)
{
  m[0][0] =cos(GL_PI/180*angle); m[0][2] =-sin(GL_PI/180*angle) ;
  m[2][0] = sin(GL_PI / 180 * angle); m[2][2] =cos(GL_PI/180*angle);
}
void Matrix3D::ZRotate(float angle)
{
  m[0][0] = cos(GL_PI / 180 * angle); m[0][1] = sin(GL_PI / 180 * angle);
  m[1][0] = -sin(GL_PI / 180 * angle);m[1][1] = cos(GL_PI / 180 * angle);
}
void Matrix3D::Translate(float x, float y, float z)
{
  m[3][0] = x;
  m[3][1] = y;
  m[3][2] = z;
}
void Matrix3D::Scale(float x, float y, float z)
{
  m[0][0] *= x;
  m[1][1] *= y;
  m[2][2] *= z;
}
void Matrix3D::FlipX()
{
  m[1][1] *=-1;
}
void Matrix3D::FlipY()
{
  m[0][0] *= -1;
}
void Matrix3D::FlipZ()
{
  m[3][3] *= -1;
}
Matrix3D Matrix3D::MatrixInverse(Matrix3D &m)
{
  float fTemp[12], fDet;
  Matrix3D mTrans = MatrixTranspose(m);
  fTemp[0] = mTrans.mat[10] * mTrans.mat[15];
  fTemp[1] = mTrans.mat[11] * mTrans.mat[14];
  fTemp[2] = mTrans.mat[9] * mTrans.mat[15];
  fTemp[3] = mTrans.mat[11] * mTrans.mat[13];
  fTemp[4] = mTrans.mat[9] * mTrans.mat[14];
  fTemp[5] = mTrans.mat[10] * mTrans.mat[13];
  fTemp[6] = mTrans.mat[8] * mTrans.mat[15];
  fTemp[7] = mTrans.mat[11] * mTrans.mat[12];
  fTemp[8] = mTrans.mat[8] * mTrans.mat[14];
  fTemp[9] = mTrans.mat[10] * mTrans.mat[12];
  fTemp[10] = mTrans.mat[8] * mTrans.mat[13];
  fTemp[11] = mTrans.mat[9] * mTrans.mat[12];
  Matrix3D res;
  res.mat[0] = fTemp[0] * mTrans.mat[5] + fTemp[3] * mTrans.mat[6] + fTemp[4] * mTrans.mat[7];
  res.mat[0] -= fTemp[1] * mTrans.mat[5] + fTemp[2] * mTrans.mat[6] + fTemp[5] * mTrans.mat[7];
  res.mat[1] = fTemp[1] * mTrans.mat[4] + fTemp[6] * mTrans.mat[6] + fTemp[9] * mTrans.mat[7];
  res.mat[1] -= fTemp[0] * mTrans.mat[4] + fTemp[7] * mTrans.mat[6] + fTemp[8] * mTrans.mat[7];
  res.mat[2] = fTemp[2] * mTrans.mat[4] + fTemp[7] * mTrans.mat[5] + fTemp[10] * mTrans.mat[7];
  res.mat[2] -= fTemp[3] * mTrans.mat[4] + fTemp[6] * mTrans.mat[5] + fTemp[11] * mTrans.mat[7];
  res.mat[3] = fTemp[5] * mTrans.mat[4] + fTemp[8] * mTrans.mat[5] + fTemp[11] * mTrans.mat[6];
  res.mat[3] -= fTemp[4] * mTrans.mat[4] + fTemp[9] * mTrans.mat[5] + fTemp[10] * mTrans.mat[6];
  res.mat[4] = fTemp[1] * mTrans.mat[1] + fTemp[2] * mTrans.mat[2] + fTemp[5] * mTrans.mat[3];
  res.mat[4] -= fTemp[0] * mTrans.mat[1] + fTemp[3] * mTrans.mat[2] + fTemp[4] * mTrans.mat[3];
  res.mat[5] = fTemp[0] * mTrans.mat[0] + fTemp[7] * mTrans.mat[2] + fTemp[8] * mTrans.mat[3];
  res.mat[5] -= fTemp[1] * mTrans.mat[0] + fTemp[6] * mTrans.mat[2] + fTemp[9] * mTrans.mat[3];
  res.mat[6] = fTemp[3] * mTrans.mat[0] + fTemp[6] * mTrans.mat[1] + fTemp[11] * mTrans.mat[3];
  res.mat[6] -= fTemp[2] * mTrans.mat[0] + fTemp[7] * mTrans.mat[1] + fTemp[10] * mTrans.mat[3];
  res.mat[7] = fTemp[4] * mTrans.mat[0] + fTemp[9] * mTrans.mat[1] + fTemp[10] * mTrans.mat[2];
  res.mat[7] -= fTemp[5] * mTrans.mat[0] + fTemp[8] * mTrans.mat[1] + fTemp[11] * mTrans.mat[2];
  fTemp[0] = mTrans.mat[2] * mTrans.mat[7];
  fTemp[1] = mTrans.mat[3] * mTrans.mat[6];
  fTemp[2] = mTrans.mat[1] * mTrans.mat[7];
  fTemp[3] = mTrans.mat[3] * mTrans.mat[5];
  fTemp[4] = mTrans.mat[1] * mTrans.mat[6];
  fTemp[5] = mTrans.mat[2] * mTrans.mat[5];
  fTemp[6] = mTrans.mat[0] * mTrans.mat[7];
  fTemp[7] = mTrans.mat[3] * mTrans.mat[4];
  fTemp[8] = mTrans.mat[0] * mTrans.mat[6];
  fTemp[9] = mTrans.mat[2] * mTrans.mat[4];
  fTemp[10] = mTrans.mat[0] * mTrans.mat[5];
  fTemp[11] = mTrans.mat[1] * mTrans.mat[4];
  res.mat[8] = fTemp[0] * mTrans.mat[13] + fTemp[3] * mTrans.mat[14] + fTemp[4] * mTrans.mat[15];
  res.mat[8] -= fTemp[1] * mTrans.mat[13] + fTemp[2] * mTrans.mat[14] + fTemp[5] * mTrans.mat[15];
  res.mat[9] = fTemp[1] * mTrans.mat[12] + fTemp[6] * mTrans.mat[14] + fTemp[9] * mTrans.mat[15];
  res.mat[9] -= fTemp[0] * mTrans.mat[12] + fTemp[7] * mTrans.mat[14] + fTemp[8] * mTrans.mat[15];
  res.mat[10] = fTemp[2] * mTrans.mat[12] + fTemp[7] * mTrans.mat[13] + fTemp[10] * mTrans.mat[15];
  res.mat[10] -= fTemp[3] * mTrans.mat[12] + fTemp[6] * mTrans.mat[13] + fTemp[11] * mTrans.mat[15];
  res.mat[11] = fTemp[5] * mTrans.mat[12] + fTemp[8] * mTrans.mat[13] + fTemp[11] * mTrans.mat[14];
  res.mat[11] -= fTemp[4] * mTrans.mat[12] + fTemp[9] * mTrans.mat[13] + fTemp[10] * mTrans.mat[14];
  res.mat[12] = fTemp[2] * mTrans.mat[10] + fTemp[5] * mTrans.mat[11] + fTemp[1] * mTrans.mat[9];
  res.mat[12] -= fTemp[4] * mTrans.mat[11] + fTemp[0] * mTrans.mat[9] + fTemp[3] * mTrans.mat[10];
  res.mat[13] = fTemp[8] * mTrans.mat[11] + fTemp[0] * mTrans.mat[8] + fTemp[7] * mTrans.mat[10];
  res.mat[13] -= fTemp[6] * mTrans.mat[10] + fTemp[9] * mTrans.mat[11] + fTemp[1] * mTrans.mat[8];
  res.mat[14] = fTemp[6] * mTrans.mat[9] + fTemp[11] * mTrans.mat[11] + fTemp[3] * mTrans.mat[8];
  res.mat[14] -= fTemp[10] * mTrans.mat[11] + fTemp[2] * mTrans.mat[8] + fTemp[7] * mTrans.mat[9];
  res.mat[15] = fTemp[10] * mTrans.mat[10] + fTemp[4] * mTrans.mat[8] + fTemp[9] * mTrans.mat[9];
  res.mat[15] -= fTemp[8] * mTrans.mat[9] + fTemp[11] * mTrans.mat[10] + fTemp[5] * mTrans.mat[8];
  fDet = mTrans.mat[0] * res.mat[0] +
    mTrans.mat[1] * res.mat[1] +
    mTrans.mat[2] * res.mat[2] +
    mTrans.mat[3] * res.mat[3];
  fDet = 1 / fDet;
  res.mat[0] *= fDet;
  res.mat[1] *= fDet;
  res.mat[2] *= fDet;
  res.mat[3] *= fDet;
  res.mat[4] *= fDet;
  res.mat[5] *= fDet;
  res.mat[6] *= fDet;
  res.mat[7] *= fDet;
  res.mat[8] *= fDet;
  res.mat[9] *= fDet;
  res.mat[10] *= fDet;
  res.mat[11] *= fDet;
  res.mat[12] *= fDet;
  res.mat[13] *= fDet;
  res.mat[14] *= fDet;
  res.mat[15] *= fDet;
  return res;
}
Vector3D Vec3TransformCoord(Matrix3D &m, Vector3D &v)
{
  Vector3D res;
  res.x = m.m[0][0] * v.x + m.m[1][0] * v.y + m.m[2][0] * v.z+m.m[3][0];
  res.y = m.m[0][1] * v.x + m.m[1][1] * v.y + m.m[2][1] * v.z+m.m[3][1];
  res.z = m.m[0][2] * v.x + m.m[1][2] * v.y + m.m[2][2] * v.z+m.m[3][2];
  return res;
}
Vector2 Vec3TransformCoord(Matrix3D &worldMat, Vector2 &v)
{
  Vector2 temp;
  temp.x = v.x*worldMat.m[0][0] + v.y*worldMat.m[1][0] + worldMat.m[3][0];
  temp.y = v.x*worldMat.m[0][1] + v.y*worldMat.m[1][1] + worldMat.m[3][1];
  return temp;
}
Vector3D Vec3TransformNormal(Matrix3D &m, Vector3D &v)
{
  Vector3D res;
  res.x = m.m[0][0] * v.x + m.m[1][0] * v.y + m.m[2][0] * v.z;
  res.y = m.m[0][1] * v.x + m.m[1][1] * v.y + m.m[2][1] * v.z;
  res.z = m.m[0][2] * v.x + m.m[1][2] * v.y + m.m[2][2] * v.z;
  return res;
}
Matrix3D MatrixRotationAxis(Vector3D &axis, float angle)
{
  float s = sin(angle*PI / 180);
  float c = cos(angle*PI / 180);
  Vector3D v = axis.Normalize(); 
  Vector3D a = v*(1.0f - c);
  Matrix3D res;
  res.m[0][0] = a.x*v.x + c;    res.m[0][1] = a.y*v.x - v.z*s;  res.m[0][2] = a.z*v.x + v.y*s;  res.m[0][3] = 0;
  res.m[1][0] = a.x*v.y + v.z*s;  res.m[1][1] = a.y*v.y + c;    res.m[1][2] = a.z*v.y - v.x*s;  res.m[1][3] = 0.0f;
  res.m[2][0] = a.x*v.z - v.y*s;  res.m[2][1] = a.y*v.z + v.x*s;  res.m[2][2] = a.z*v.z + c;    res.m[2][3] = 0;
  res.m[3][0] = 0;        res.m[3][1] = 0;        res.m[3][2] = 0;        res.m[3][3] = 1;
  return res;
}
Matrix3D MatrixRotationAxisRad(Vector3D &axis, float radian)
{
  float s = sin(radian);
  float c = cos(radian);
  Vector3D v = axis.Normalize();
  Vector3D a = v*(1.0f - c);
  Matrix3D res;
  res.m[0][0] = a.x*v.x + c;    res.m[0][1] = a.y*v.x - v.z*s;  res.m[0][2] = a.z*v.x + v.y*s;  res.m[0][3] = 0;
  res.m[1][0] = a.x*v.y + v.z*s;  res.m[1][1] = a.y*v.y + c;    res.m[1][2] = a.z*v.y - v.x*s;  res.m[1][3] = 0.0f;
  res.m[2][0] = a.x*v.z - v.y*s;  res.m[2][1] = a.y*v.z + v.x*s;  res.m[2][2] = a.z*v.z + c;    res.m[2][3] = 0;
  res.m[3][0] = 0;        res.m[3][1] = 0;        res.m[3][2] = 0;        res.m[3][3] = 1;
  return res;
}
Matrix3D YRotate(float angle)
{
  Matrix3D mat;
  mat.m[0][0] = cos(GL_PI / 180 * angle); mat.m[0][2] = sin(GL_PI / 180 * angle);
  mat.m[2][0] = -sin(GL_PI / 180 * angle); mat.m[2][2] = cos(GL_PI / 180 * angle);
  return mat;
}
Matrix3D MatrixTranspose(Matrix3D &m)
{
  Matrix3D res;
  res.mat[0] = m.mat[0]; res.mat[1] = m.mat[4]; res.mat[2] = m.mat[8];   res.mat[3] = m.mat[12];
  res.mat[4] = m.mat[1]; res.mat[5] = m.mat[5]; res.mat[6] = m.mat[9];   res.mat[7] = m.mat[13];
  res.mat[8] = m.mat[2]; res.mat[9] = m.mat[6]; res.mat[10] = m.mat[10]; res.mat[11] = m.mat[14];
  res.mat[12] = m.mat[3]; res.mat[13] = m.mat[7]; res.mat[14] = m.mat[11]; res.mat[15] = m.mat[15];
  return res;
}
Matrix3D MatrixInverse(Matrix3D &m)
{
  float fTemp[12], fDet;
  Matrix3D mTrans = MatrixTranspose(m);
  fTemp[0] = mTrans.mat[10] * mTrans.mat[15];
  fTemp[1] = mTrans.mat[11] * mTrans.mat[14];
  fTemp[2] = mTrans.mat[9] * mTrans.mat[15];
  fTemp[3] = mTrans.mat[11] * mTrans.mat[13];
  fTemp[4] = mTrans.mat[9] * mTrans.mat[14];
  fTemp[5] = mTrans.mat[10] * mTrans.mat[13];
  fTemp[6] = mTrans.mat[8] * mTrans.mat[15];
  fTemp[7] = mTrans.mat[11] * mTrans.mat[12];
  fTemp[8] = mTrans.mat[8] * mTrans.mat[14];
  fTemp[9] = mTrans.mat[10] * mTrans.mat[12];
  fTemp[10] = mTrans.mat[8] * mTrans.mat[13];
  fTemp[11] = mTrans.mat[9] * mTrans.mat[12];
  Matrix3D res;
  res.mat[0] = fTemp[0] * mTrans.mat[5] + fTemp[3] * mTrans.mat[6] + fTemp[4] * mTrans.mat[7];
  res.mat[0] -= fTemp[1] * mTrans.mat[5] + fTemp[2] * mTrans.mat[6] + fTemp[5] * mTrans.mat[7];
  res.mat[1] = fTemp[1] * mTrans.mat[4] + fTemp[6] * mTrans.mat[6] + fTemp[9] * mTrans.mat[7];
  res.mat[1] -= fTemp[0] * mTrans.mat[4] + fTemp[7] * mTrans.mat[6] + fTemp[8] * mTrans.mat[7];
  res.mat[2] = fTemp[2] * mTrans.mat[4] + fTemp[7] * mTrans.mat[5] + fTemp[10] * mTrans.mat[7];
  res.mat[2] -= fTemp[3] * mTrans.mat[4] + fTemp[6] * mTrans.mat[5] + fTemp[11] * mTrans.mat[7];
  res.mat[3] = fTemp[5] * mTrans.mat[4] + fTemp[8] * mTrans.mat[5] + fTemp[11] * mTrans.mat[6];
  res.mat[3] -= fTemp[4] * mTrans.mat[4] + fTemp[9] * mTrans.mat[5] + fTemp[10] * mTrans.mat[6];
  res.mat[4] = fTemp[1] * mTrans.mat[1] + fTemp[2] * mTrans.mat[2] + fTemp[5] * mTrans.mat[3];
  res.mat[4] -= fTemp[0] * mTrans.mat[1] + fTemp[3] * mTrans.mat[2] + fTemp[4] * mTrans.mat[3];
  res.mat[5] = fTemp[0] * mTrans.mat[0] + fTemp[7] * mTrans.mat[2] + fTemp[8] * mTrans.mat[3];
  res.mat[5] -= fTemp[1] * mTrans.mat[0] + fTemp[6] * mTrans.mat[2] + fTemp[9] * mTrans.mat[3];
  res.mat[6] = fTemp[3] * mTrans.mat[0] + fTemp[6] * mTrans.mat[1] + fTemp[11] * mTrans.mat[3];
  res.mat[6] -= fTemp[2] * mTrans.mat[0] + fTemp[7] * mTrans.mat[1] + fTemp[10] * mTrans.mat[3];
  res.mat[7] = fTemp[4] * mTrans.mat[0] + fTemp[9] * mTrans.mat[1] + fTemp[10] * mTrans.mat[2];
  res.mat[7] -= fTemp[5] * mTrans.mat[0] + fTemp[8] * mTrans.mat[1] + fTemp[11] * mTrans.mat[2];
  fTemp[0] = mTrans.mat[2] * mTrans.mat[7];
  fTemp[1] = mTrans.mat[3] * mTrans.mat[6];
  fTemp[2] = mTrans.mat[1] * mTrans.mat[7];
  fTemp[3] = mTrans.mat[3] * mTrans.mat[5];
  fTemp[4] = mTrans.mat[1] * mTrans.mat[6];
  fTemp[5] = mTrans.mat[2] * mTrans.mat[5];
  fTemp[6] = mTrans.mat[0] * mTrans.mat[7];
  fTemp[7] = mTrans.mat[3] * mTrans.mat[4];
  fTemp[8] = mTrans.mat[0] * mTrans.mat[6];
  fTemp[9] = mTrans.mat[2] * mTrans.mat[4];
  fTemp[10] = mTrans.mat[0] * mTrans.mat[5];
  fTemp[11] = mTrans.mat[1] * mTrans.mat[4];
  res.mat[8] = fTemp[0] * mTrans.mat[13] + fTemp[3] * mTrans.mat[14] + fTemp[4] * mTrans.mat[15];
  res.mat[8] -= fTemp[1] * mTrans.mat[13] + fTemp[2] * mTrans.mat[14] + fTemp[5] * mTrans.mat[15];
  res.mat[9] = fTemp[1] * mTrans.mat[12] + fTemp[6] * mTrans.mat[14] + fTemp[9] * mTrans.mat[15];
  res.mat[9] -= fTemp[0] * mTrans.mat[12] + fTemp[7] * mTrans.mat[14] + fTemp[8] * mTrans.mat[15];
  res.mat[10] = fTemp[2] * mTrans.mat[12] + fTemp[7] * mTrans.mat[13] + fTemp[10] * mTrans.mat[15];
  res.mat[10] -= fTemp[3] * mTrans.mat[12] + fTemp[6] * mTrans.mat[13] + fTemp[11] * mTrans.mat[15];
  res.mat[11] = fTemp[5] * mTrans.mat[12] + fTemp[8] * mTrans.mat[13] + fTemp[11] * mTrans.mat[14];
  res.mat[11] -= fTemp[4] * mTrans.mat[12] + fTemp[9] * mTrans.mat[13] + fTemp[10] * mTrans.mat[14];
  res.mat[12] = fTemp[2] * mTrans.mat[10] + fTemp[5] * mTrans.mat[11] + fTemp[1] * mTrans.mat[9];
  res.mat[12] -= fTemp[4] * mTrans.mat[11] + fTemp[0] * mTrans.mat[9] + fTemp[3] * mTrans.mat[10];
  res.mat[13] = fTemp[8] * mTrans.mat[11] + fTemp[0] * mTrans.mat[8] + fTemp[7] * mTrans.mat[10];
  res.mat[13] -= fTemp[6] * mTrans.mat[10] + fTemp[9] * mTrans.mat[11] + fTemp[1] * mTrans.mat[8];
  res.mat[14] = fTemp[6] * mTrans.mat[9] + fTemp[11] * mTrans.mat[11] + fTemp[3] * mTrans.mat[8];
  res.mat[14] -= fTemp[10] * mTrans.mat[11] + fTemp[2] * mTrans.mat[8] + fTemp[7] * mTrans.mat[9];
  res.mat[15] = fTemp[10] * mTrans.mat[10] + fTemp[4] * mTrans.mat[8] + fTemp[9] * mTrans.mat[9];
  res.mat[15] -= fTemp[8] * mTrans.mat[9] + fTemp[11] * mTrans.mat[10] + fTemp[5] * mTrans.mat[8];
  fDet = mTrans.mat[0] * res.mat[0] +
    mTrans.mat[1] * res.mat[1] +
    mTrans.mat[2] * res.mat[2] +
    mTrans.mat[3] * res.mat[3];
  fDet = 1 / fDet;
  res.mat[0] *= fDet;
  res.mat[1] *= fDet;
  res.mat[2] *= fDet;
  res.mat[3] *= fDet;
  res.mat[4] *= fDet;
  res.mat[5] *= fDet;
  res.mat[6] *= fDet;
  res.mat[7] *= fDet;
  res.mat[8] *= fDet;
  res.mat[9] *= fDet;
  res.mat[10] *= fDet;
  res.mat[11] *= fDet;
  res.mat[12] *= fDet;
  res.mat[13] *= fDet;
  res.mat[14] *= fDet;
  res.mat[15] *= fDet;
  return res;
}
Matrix3D FromToRotation(Vector3D from, Vector3D to)
{
  from.Normalize();
  to.Normalize();
  float angle = acos(from.dot(to));
  if (angle == 0)
  {
    return Matrix3D();
  }
  Vector3D axis = from.cross(to);
  axis.Normalize();
  return MatrixRotationAxisRad(axis, angle);
}
Matrix3D &MatrixRotationYawPitchRoll(float Yaw, float Pitch, float Roll)
{
  Matrix3D res;
  float sx = sin(Pitch); float sy = sin(Yaw); float sz = sin(Roll);
  float cx = cos(Pitch); float cy = cos(Yaw); float cz = cos(Roll);
  res.mat[0] = cz * cy - sx * sy * sz; res.mat[1] = cy * sz + sx * sy * cz; res.mat[2] = -sy * cx; res.mat[3] = 0.0f;
  res.mat[4] = -cx * sz;        res.mat[5] = cx * cz;       res.mat[6] = sx;    res.mat[7] = 0.0f;
  res.mat[8] = sy * cz + sx * cy * sz; res.mat[9] = sy * sz - sx * cy * cz; res.mat[10] = cx * cy; res.mat[11] = 0.0f;
  res.mat[12] = 0.0f;         res.mat[13] = 0.0f;         res.mat[14] = 0.0f;   res.mat[15] = 1.0f;
  return res;
}
Matrix3D &MatrixRotationY(float angle)
{
  float s = sin(angle);
  float c = cos(angle);
  Matrix3D res;
  res.mat[0] = c; res.mat[1] = 0; res.mat[2] = -s; res.mat[3] = 0.0f;
  res.mat[4] = 0; res.mat[5] = 1; res.mat[6] = 0; res.mat[7] = 0.0f;
  res.mat[8] = s; res.mat[9] = 0; res.mat[10] = c; res.mat[11] = 0.0f;
  res.mat[12] = 0.0f; res.mat[13] = 0.0f; res.mat[14] = 0.0f; res.mat[15] = 1.0f;
  return res;
}


相关文章
|
人工智能 安全 Unix
游戏编程之九 设计工具之游戏引擎
游戏编程之九 设计工具之游戏引擎
81 0
|
1天前
|
设计模式 C# 图形学
Unity 游戏引擎 C# 编程:一分钟浅谈
本文介绍了在 Unity 游戏开发中使用 C# 的基础知识和常见问题。从 `MonoBehavior` 类的基础用法,到变量和属性的管理,再到空引用异常、资源管理和性能优化等常见问题的解决方法。文章还探讨了单例模式、事件系统和数据持久化等高级话题,旨在帮助开发者避免常见错误,提升游戏开发效率。
11 4
|
3月前
|
开发者 C# C++
揭秘:如何轻松驾驭Uno Platform,用C#和XAML打造跨平台神器——一步步打造你的高性能WebAssembly应用!
【8月更文挑战第31天】Uno Platform 是一个跨平台应用程序框架,支持使用 C# 和 XAML 创建多平台应用,包括 Web。通过编译为 WebAssembly,Uno Platform 可实现在 Web 上运行高性能、接近原生体验的应用。本文介绍如何构建高效的 WebAssembly 应用:首先确保安装最新版本的 Visual Studio 或 VS Code 并配置 Uno Platform 开发环境;接着创建新的 Uno Platform 项目;然后通过安装工具链并使用 Uno WebAssembly CLI 编译应用;最后添加示例代码并测试应用。
103 0
|
6月前
|
数据可视化 vr&ar 开发工具
Unity游戏开发引擎是什么?有哪些优点
Unity引擎是一款由Unity Technologies开发的跨平台游戏开发引擎,广泛用于创建2D和3D游戏以及其他交互式内容,如虚拟现实(VR)和增强现实(AR)应用程序。
116 3
|
6月前
|
开发框架 Linux API
初步探索Pyglet库:打造轻量级多媒体与游戏开发利器
初步探索Pyglet库:打造轻量级多媒体与游戏开发利器
85 0
BXA
|
程序员 C++ 开发者
使用C++特性构建游戏引擎
游戏引擎是用来设计、开发和构建计算机游戏的软件框架。它们由一些基本的工具和程序构成,可帮助游戏设计师和开发者轻松地创建、管理和优化游戏。基本上,游戏引擎是实现游戏的所有技术的一个集合
BXA
164 0
从0开发游戏引擎之游戏引擎底层数学库实现
矩阵相乘: 先说什么是行什么是列,横着的就是行,竖着的就是列。可以看一下图片1.1,别弄过了。不然一会计算一起全都弄饭了算起来就全错。 计算说的简单点就是每一行乘上每一列,然后把算出来的结果保存到一个新的矩阵对应的n行m列中。
从0开发游戏引擎之游戏引擎底层数学库实现
|
定位技术
从0开发游戏引擎之 序言(引擎内主要模块)
从0开发游戏引擎之 序言(引擎内主要模块)
从0开发游戏引擎之碰撞检测模块底层实现
从0开发游戏引擎之碰撞检测模块底层实现
Cocos2d-x - 开源跨平台游戏引擎
Cocos2D-X 是全球知名的开源跨平台游戏引擎,易学易用,目前已经支持iOS、Android、Windows桌面、Mac OSX、Linux、BlackBerry、Windows Phone等平台。
828 0