이전글: 게임 수학 C++ | 2. 벡터
https://mpi-devlog.tistory.com/25
게임 수학 C++ | 2. 벡터
이전글: 게임 수학 C++ | 1. 기반 https://mpi-devlog.tistory.com/24 게임 수학 C++ | 1. 기반 과제겸 공부겸 게임 수학 관련해서 프로그래밍한 코드 쭉 올립니다 게시글에는 딱히 이론에 대한 이야기는 없으��
mpi-devlog.tistory.com
과제겸 공부겸 게임 수학 관련해서 프로그래밍한 코드 쭉 올립니다
게시글에는 딱히 이론에 대한 이야기는 없으니 먼저 이론을 알고 계셔야 코드 이해하실 수 있을 거예요
여기서는 4x4 행렬을 사용합니다.
행렬 연산과 이동, 회전, 크기 변환등을 한번에 넣어놨어요. 나중에 카메라나 프로젝션 변환도 추가할 예정입니다.
코드를 보시면 알겠지만, 연산에 있어서 반복문을 돌려 처리하거나 하지 않았어요.
코딩할때는 좀 힘들었지만 속도면에선 우위일 것입니다.
또 편법 계산방법이 있을 때, 그걸 그대로 사용할 수도 있어요.
저번과 마찬가지로 연산자 오버로딩 되어있고, 종속적이지 않은 계산은 static 함수로 되어있습니다.
- Matrix.h
- Matrix.cpp
Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include "Vector.h"
class mat
{
public:
float m[4][4];
public:
mat();
mat(float scalar);
mat(float m[2][2]);
mat(float m[3][3]);
mat(float m[4][4]);
mat operator+(const mat& operand);
mat operator-(const mat& operand);
mat operator*(const float& operand);
vec3 operator*(const vec3& operand);
mat operator*(const mat& operand);
public:
static mat Identity();
static mat Scale(float sx, float sy, float sz);
static mat RotateX(float rx);
static mat RotateY(float ry);
static mat RotateZ(float rz);
static mat Translate(float tx, float ty, float tz);
static mat Transpose(mat m); // 전치행렬
static float Determinant(mat m); // 행렬식
static mat Adjoint(mat m); // 수반행렬
static mat Inverse(mat m); // 역행렬
};
#endif
Matrix.cpp
#include "Matrix.h"
mat::mat()
{
std::fill(&m[0][0], &m[0][0] + (sizeof(m) / sizeof(float)), 0);
}
mat::mat(float scalar)
{
*this = Identity();
}
mat::mat(float m[2][2])
{
*this = Identity();
this->m[0][0] = m[0][0]; this->m[0][1] = m[0][1];
this->m[1][0] = m[1][0]; this->m[1][1] = m[1][1];
}
mat::mat(float m[3][3])
{
*this = Identity();
this->m[0][0] = m[0][0]; this->m[0][1] = m[0][1]; this->m[0][2] = m[0][2];
this->m[1][0] = m[1][0]; this->m[1][1] = m[1][1]; this->m[1][2] = m[1][2];
this->m[2][0] = m[2][0]; this->m[2][1] = m[2][1]; this->m[2][2] = m[2][2];
}
mat::mat(float m[4][4])
{
memcpy(this->m, m, sizeof(float) * 4 * 4);
}
mat mat::operator+(const mat& operand)
{
float m[4][4] =
{
{this->m[0][0] + operand.m[0][0], this->m[0][1] + operand.m[0][1], this->m[0][2] + operand.m[0][2], this->m[0][3] + operand.m[0][3]},
{this->m[1][0] + operand.m[1][0], this->m[1][1] + operand.m[1][1], this->m[1][2] + operand.m[1][2], this->m[1][3] + operand.m[1][3]},
{this->m[2][0] + operand.m[2][0], this->m[2][1] + operand.m[2][1], this->m[2][2] + operand.m[2][2], this->m[2][3] + operand.m[2][3]},
{this->m[3][0] + operand.m[3][0], this->m[3][1] + operand.m[3][1], this->m[3][2] + operand.m[3][2], this->m[3][3] + operand.m[3][3]}
};
return mat(m);
}
mat mat::operator-(const mat& operand)
{
float m[4][4] =
{
{this->m[0][0] - operand.m[0][0], this->m[0][1] - operand.m[0][1], this->m[0][2] - operand.m[0][2], this->m[0][3] - operand.m[0][3]},
{this->m[1][0] - operand.m[1][0], this->m[1][1] - operand.m[1][1], this->m[1][2] - operand.m[1][2], this->m[1][3] - operand.m[1][3]},
{this->m[2][0] - operand.m[2][0], this->m[2][1] - operand.m[2][1], this->m[2][2] - operand.m[2][2], this->m[2][3] - operand.m[2][3]},
{this->m[3][0] - operand.m[3][0], this->m[3][1] - operand.m[3][1], this->m[3][2] - operand.m[3][2], this->m[3][3] - operand.m[3][3]}
};
return mat(m);
}
mat mat::operator*(const float& operand)
{
float m[4][4] =
{
{this->m[0][0] * operand, this->m[0][1] * operand, this->m[0][2] * operand, this->m[0][3] * operand},
{this->m[1][0] * operand, this->m[1][1] * operand, this->m[1][2] * operand, this->m[1][3] * operand},
{this->m[2][0] * operand, this->m[2][1] * operand, this->m[2][2] * operand, this->m[2][3] * operand},
{this->m[3][0] * operand, this->m[3][1] * operand, this->m[3][2] * operand, this->m[3][3] * operand}
};
return mat(m);
}
vec3 mat::operator*(const vec3& operand)
{
vec3 result = vec3(
this->m[0][0] * operand.x + this->m[0][1] * operand.y + this->m[0][2] * operand.z + this->m[0][3] * 1,
this->m[1][0] * operand.x + this->m[1][1] * operand.y + this->m[1][2] * operand.z + this->m[1][3] * 1,
this->m[2][0] * operand.x + this->m[2][1] * operand.y + this->m[2][2] * operand.z + this->m[2][3] * 1
);
return result;
}
mat mat::operator*(const mat& operand)
{
float m[4][4] =
{
{this->m[0][0] * operand.m[0][0] + this->m[0][1] * operand.m[1][0] + this->m[0][2] * operand.m[2][0] + this->m[0][3] * operand.m[3][0], this->m[0][0] * operand.m[0][1] + this->m[0][1] * operand.m[1][1] + this->m[0][2] * operand.m[2][1] + this->m[0][3] * operand.m[3][1], this->m[0][0] * operand.m[0][2] + this->m[0][1] * operand.m[1][2] + this->m[0][2] * operand.m[2][2] + this->m[0][3] * operand.m[3][2], this->m[0][0] * operand.m[0][3] + this->m[0][1] * operand.m[1][3] + this->m[0][2] * operand.m[2][3] + this->m[0][3] * operand.m[3][3]},
{this->m[1][0] * operand.m[0][0] + this->m[1][1] * operand.m[1][0] + this->m[1][2] * operand.m[2][0] + this->m[1][3] * operand.m[3][0], this->m[1][0] * operand.m[0][1] + this->m[1][1] * operand.m[1][1] + this->m[1][2] * operand.m[2][1] + this->m[1][3] * operand.m[3][1], this->m[1][0] * operand.m[0][2] + this->m[1][1] * operand.m[1][2] + this->m[1][2] * operand.m[2][2] + this->m[1][3] * operand.m[3][2], this->m[1][0] * operand.m[0][3] + this->m[1][1] * operand.m[1][3] + this->m[1][2] * operand.m[2][3] + this->m[1][3] * operand.m[3][3]},
{this->m[2][0] * operand.m[0][0] + this->m[2][1] * operand.m[1][0] + this->m[2][2] * operand.m[2][0] + this->m[2][3] * operand.m[3][0], this->m[2][0] * operand.m[0][1] + this->m[2][1] * operand.m[1][1] + this->m[2][2] * operand.m[2][1] + this->m[2][3] * operand.m[3][1], this->m[2][0] * operand.m[0][2] + this->m[2][1] * operand.m[1][2] + this->m[2][2] * operand.m[2][2] + this->m[2][3] * operand.m[3][2], this->m[2][0] * operand.m[0][3] + this->m[2][1] * operand.m[1][3] + this->m[2][2] * operand.m[2][3] + this->m[2][3] * operand.m[3][3]},
{this->m[3][0] * operand.m[0][0] + this->m[3][1] * operand.m[1][0] + this->m[3][2] * operand.m[2][0] + this->m[3][3] * operand.m[3][0], this->m[3][0] * operand.m[0][1] + this->m[3][1] * operand.m[1][1] + this->m[3][2] * operand.m[2][1] + this->m[3][3] * operand.m[3][1], this->m[3][0] * operand.m[0][2] + this->m[3][1] * operand.m[1][2] + this->m[3][2] * operand.m[2][2] + this->m[3][3] * operand.m[3][2], this->m[3][0] * operand.m[0][3] + this->m[3][1] * operand.m[1][3] + this->m[3][2] * operand.m[2][3] + this->m[3][3] * operand.m[3][3]}
};
return mat(m);
}
mat mat::Identity()
{
float m[4][4] = {
{1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}
};
return mat(m);
}
mat mat::Scale(float sx, float sy, float sz)
{
float m[4][4] =
{
{ sx, 0.0f, 0.0f, 0.0f},
{0.0f, sy, 0.0f, 0.0f},
{0.0f, 0.0f, sz, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}
};
return mat(m);
}
mat mat::RotateX(float rx)
{
float m[4][4] =
{
{1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, cosf(rx), -sinf(rx), 0.0f},
{0.0f, sinf(rx), cosf(rx), 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}
};
return mat(m);
}
mat mat::RotateY(float ry)
{
float m[4][4] =
{
{ cosf(ry), 0.0f, sinf(ry), 0.0f},
{ 0.0f, 1.0f, 0.0f, 0.0f},
{-sinf(ry), 0.0f, cosf(ry), 0.0f},
{ 0.0f, 0.0f, 0.0f, 1.0f}
};
return mat(m);
}
mat mat::RotateZ(float rz)
{
float m[4][4] =
{
{cosf(rz), -sinf(rz), 0.0f, 0.0f},
{sinf(rz), cosf(rz), 0.0f, 0.0f},
{ 0.0f, 0.0f, 1.0f, 0.0f},
{ 0.0f, 0.0f, 0.0f, 1.0f}
};
return mat(m);
}
mat mat::Translate(float tx, float ty, float tz)
{
float m[4][4] =
{
{1.0f, 0.0f, 0.0f, tx},
{0.0f, 1.0f, 0.0f, ty},
{0.0f, 0.0f, 1.0f, tz},
{0.0f, 0.0f, 0.0f, 1.0f}
};
return mat(m);
}
mat mat::Transpose(mat m)
{
float r[4][4] =
{
{m.m[0][0], m.m[1][0], m.m[2][0], m.m[3][0]},
{m.m[0][1], m.m[1][1], m.m[2][1], m.m[3][1]},
{m.m[0][2], m.m[1][2], m.m[2][2], m.m[3][2]},
{m.m[0][3], m.m[1][3], m.m[2][3], m.m[3][3]}
};
return mat(r);
}
float mat::Determinant(mat m)
{
float det;
det = m.m[0][0] * m.m[1][1] * m.m[2][2] * m.m[3][3] + m.m[0][0] * m.m[1][2] * m.m[2][3] * m.m[3][1] + m.m[0][0] * m.m[1][3] * m.m[2][1] * m.m[3][1] +
m.m[0][1] * m.m[1][0] * m.m[2][3] * m.m[3][2] + m.m[0][1] * m.m[1][2] * m.m[2][0] * m.m[3][3] + m.m[0][1] * m.m[1][3] * m.m[2][2] * m.m[3][0] +
m.m[0][2] * m.m[1][0] * m.m[2][1] * m.m[3][3] + m.m[0][2] * m.m[1][1] * m.m[2][3] * m.m[3][0] + m.m[0][2] * m.m[1][3] * m.m[2][0] * m.m[3][1] +
m.m[0][3] * m.m[1][0] * m.m[2][2] * m.m[3][1] + m.m[0][3] * m.m[1][1] * m.m[2][0] * m.m[3][1] + m.m[0][3] * m.m[1][2] * m.m[2][1] * m.m[3][0] -
m.m[0][0] * m.m[1][1] * m.m[2][3] * m.m[3][2] - m.m[0][0] * m.m[1][2] * m.m[2][1] * m.m[3][3] - m.m[0][0] * m.m[1][3] * m.m[2][2] * m.m[3][1] -
m.m[0][1] * m.m[1][0] * m.m[2][2] * m.m[3][3] - m.m[0][1] * m.m[1][2] * m.m[2][3] * m.m[3][0] - m.m[0][1] * m.m[1][3] * m.m[2][0] * m.m[3][2] -
m.m[0][2] * m.m[1][0] * m.m[2][3] * m.m[3][1] - m.m[0][2] * m.m[1][1] * m.m[2][0] * m.m[3][3] - m.m[0][2] * m.m[1][3] * m.m[2][1] * m.m[3][0] -
m.m[0][3] * m.m[1][0] * m.m[2][1] * m.m[3][2] - m.m[0][3] * m.m[1][1] * m.m[2][2] * m.m[3][0] - m.m[0][3] * m.m[1][2] * m.m[2][0] * m.m[3][1];
return det;
}
mat mat::Adjoint(mat m)
{
float r[4][4];
r[0][0] = (m.m[1][1] * m.m[2][2] * m.m[3][3] + m.m[1][2] * m.m[2][3] * m.m[3][1] + m.m[1][3] * m.m[2][1] * m.m[3][2] -
m.m[1][1] * m.m[2][3] * m.m[3][2] - m.m[1][2] * m.m[2][1] * m.m[3][3] - m.m[1][3] * m.m[2][2] * m.m[3][1]);
r[0][1] = (m.m[0][1] * m.m[2][3] * m.m[3][1] + m.m[0][2] * m.m[2][1] * m.m[3][3] + m.m[0][3] * m.m[2][2] * m.m[3][1] -
m.m[0][1] * m.m[2][2] * m.m[3][3] - m.m[0][2] * m.m[2][3] * m.m[3][1] - m.m[0][3] * m.m[2][1] * m.m[3][2]);
r[0][2] = (m.m[0][1] * m.m[1][2] * m.m[3][3] + m.m[0][2] * m.m[1][3] * m.m[3][1] + m.m[0][3] * m.m[1][1] * m.m[3][2] -
m.m[0][1] * m.m[1][3] * m.m[3][2] - m.m[0][2] * m.m[1][1] * m.m[3][3] - m.m[0][3] * m.m[1][2] * m.m[3][1]);
r[0][3] = (m.m[0][1] * m.m[1][3] * m.m[2][2] + m.m[0][2] * m.m[1][1] * m.m[2][3] + m.m[0][3] * m.m[1][2] * m.m[2][1] -
m.m[0][1] * m.m[1][2] * m.m[2][3] - m.m[0][2] * m.m[1][3] * m.m[2][1] - m.m[0][3] * m.m[1][1] * m.m[2][2]);
r[1][0] = (m.m[1][0] * m.m[2][3] * m.m[3][2] + m.m[1][2] * m.m[2][0] * m.m[3][3] + m.m[1][3] * m.m[2][2] * m.m[3][0] -
m.m[1][0] * m.m[2][2] * m.m[3][3] - m.m[1][2] * m.m[2][3] * m.m[3][0] - m.m[1][3] * m.m[2][0] * m.m[3][2]);
r[1][1] = (m.m[0][0] * m.m[2][2] * m.m[3][3] + m.m[0][2] * m.m[2][3] * m.m[3][0] + m.m[0][3] * m.m[2][0] * m.m[3][2] -
m.m[0][0] * m.m[2][3] * m.m[3][2] - m.m[0][2] * m.m[2][0] * m.m[3][3] - m.m[0][3] * m.m[2][2] * m.m[3][0]);
r[1][2] = (m.m[0][0] * m.m[1][3] * m.m[3][2] + m.m[0][2] * m.m[1][0] * m.m[3][3] + m.m[0][3] * m.m[1][2] * m.m[3][0] -
m.m[0][0] * m.m[1][2] * m.m[3][3] - m.m[0][2] * m.m[1][3] * m.m[3][0] - m.m[0][3] * m.m[1][0] * m.m[3][2]);
r[1][3] = (m.m[0][0] * m.m[1][2] * m.m[2][3] + m.m[0][2] * m.m[1][3] * m.m[2][0] + m.m[0][3] * m.m[1][0] * m.m[2][2] -
m.m[0][0] * m.m[1][3] * m.m[2][2] - m.m[0][2] * m.m[1][0] * m.m[2][3] - m.m[0][3] * m.m[1][2] * m.m[2][0]);
r[2][0] = (m.m[1][0] * m.m[2][1] * m.m[3][3] + m.m[1][1] * m.m[2][3] * m.m[3][0] + m.m[1][3] * m.m[2][0] * m.m[3][1] -
m.m[1][0] * m.m[2][3] * m.m[3][1] - m.m[1][1] * m.m[2][0] * m.m[3][3] - m.m[1][3] * m.m[2][1] * m.m[3][0]);
r[2][1] = (m.m[0][0] * m.m[2][3] * m.m[3][1] + m.m[0][1] * m.m[2][0] * m.m[3][3] + m.m[0][3] * m.m[2][1] * m.m[3][0] -
m.m[0][0] * m.m[2][1] * m.m[3][3] - m.m[0][1] * m.m[2][3] * m.m[3][0] - m.m[0][3] * m.m[2][0] * m.m[3][1]);
r[2][2] = (m.m[0][0] * m.m[1][1] * m.m[3][3] + m.m[0][1] * m.m[1][3] * m.m[3][0] + m.m[0][3] * m.m[1][0] * m.m[3][1] -
m.m[0][0] * m.m[1][3] * m.m[3][1] - m.m[0][1] * m.m[1][0] * m.m[3][3] - m.m[0][3] * m.m[1][1] * m.m[3][0]);
r[2][3] = (m.m[0][0] * m.m[1][3] * m.m[2][1] + m.m[0][1] * m.m[1][0] * m.m[2][3] + m.m[0][3] * m.m[1][1] * m.m[2][0] -
m.m[0][0] * m.m[1][1] * m.m[2][3] - m.m[0][1] * m.m[1][3] * m.m[2][0] - m.m[0][3] * m.m[1][2] * m.m[2][1]);
r[3][0] = (m.m[1][0] * m.m[2][2] * m.m[3][1] + m.m[1][1] * m.m[2][0] * m.m[3][2] + m.m[1][2] * m.m[2][1] * m.m[3][0] -
m.m[1][0] * m.m[2][1] * m.m[3][2] - m.m[1][1] * m.m[2][2] * m.m[3][0] - m.m[1][2] * m.m[2][0] * m.m[3][1]);
r[3][1] = (m.m[0][0] * m.m[2][1] * m.m[3][2] + m.m[0][1] * m.m[2][2] * m.m[3][0] + m.m[0][2] * m.m[2][0] * m.m[3][1] -
m.m[0][0] * m.m[2][2] * m.m[3][1] - m.m[0][1] * m.m[2][0] * m.m[3][2] - m.m[0][2] * m.m[2][1] * m.m[3][0]);
r[3][2] = (m.m[0][0] * m.m[1][2] * m.m[3][1] + m.m[0][1] * m.m[1][0] * m.m[3][2] + m.m[0][2] * m.m[1][1] * m.m[3][0] -
m.m[0][0] * m.m[1][1] * m.m[3][2] - m.m[0][1] * m.m[1][2] * m.m[3][0] - m.m[0][2] * m.m[1][0] * m.m[3][1]);
r[3][3] = (m.m[0][0] * m.m[1][1] * m.m[2][2] + m.m[0][1] * m.m[1][2] * m.m[2][0] + m.m[0][2] * m.m[1][0] * m.m[2][1] -
m.m[0][0] * m.m[1][2] * m.m[2][1] - m.m[0][1] * m.m[1][0] * m.m[2][2] - m.m[0][2] * m.m[1][1] * m.m[2][0]);
return mat(r);
}
mat mat::Inverse(mat m)
{
float det = Determinant(m);
if (det == 0.0f)
{
return m;
}
det = (1.0f / det);
float r[4][4];
r[0][0] = det * (m.m[1][1] * m.m[2][2] * m.m[3][3] + m.m[1][2] * m.m[2][3] * m.m[3][1] + m.m[1][3] * m.m[2][1] * m.m[3][2] -
m.m[1][1] * m.m[2][3] * m.m[3][2] - m.m[1][2] * m.m[2][1] * m.m[3][3] - m.m[1][3] * m.m[2][2] * m.m[3][1]);
r[0][1] = det * (m.m[0][1] * m.m[2][3] * m.m[3][1] + m.m[0][2] * m.m[2][1] * m.m[3][3] + m.m[0][3] * m.m[2][2] * m.m[3][1] -
m.m[0][1] * m.m[2][2] * m.m[3][3] - m.m[0][2] * m.m[2][3] * m.m[3][1] - m.m[0][3] * m.m[2][1] * m.m[3][2]);
r[0][2] = det * (m.m[0][1] * m.m[1][2] * m.m[3][3] + m.m[0][2] * m.m[1][3] * m.m[3][1] + m.m[0][3] * m.m[1][1] * m.m[3][2] -
m.m[0][1] * m.m[1][3] * m.m[3][2] - m.m[0][2] * m.m[1][1] * m.m[3][3] - m.m[0][3] * m.m[1][2] * m.m[3][1]);
r[0][3] = det * (m.m[0][1] * m.m[1][3] * m.m[2][2] + m.m[0][2] * m.m[1][1] * m.m[2][3] + m.m[0][3] * m.m[1][2] * m.m[2][1] -
m.m[0][1] * m.m[1][2] * m.m[2][3] - m.m[0][2] * m.m[1][3] * m.m[2][1] - m.m[0][3] * m.m[1][1] * m.m[2][2]);
r[1][0] = det * (m.m[1][0] * m.m[2][3] * m.m[3][2] + m.m[1][2] * m.m[2][0] * m.m[3][3] + m.m[1][3] * m.m[2][2] * m.m[3][0] -
m.m[1][0] * m.m[2][2] * m.m[3][3] - m.m[1][2] * m.m[2][3] * m.m[3][0] - m.m[1][3] * m.m[2][0] * m.m[3][2]);
r[1][1] = det * (m.m[0][0] * m.m[2][2] * m.m[3][3] + m.m[0][2] * m.m[2][3] * m.m[3][0] + m.m[0][3] * m.m[2][0] * m.m[3][2] -
m.m[0][0] * m.m[2][3] * m.m[3][2] - m.m[0][2] * m.m[2][0] * m.m[3][3] - m.m[0][3] * m.m[2][2] * m.m[3][0]);
r[1][2] = det * (m.m[0][0] * m.m[1][3] * m.m[3][2] + m.m[0][2] * m.m[1][0] * m.m[3][3] + m.m[0][3] * m.m[1][2] * m.m[3][0] -
m.m[0][0] * m.m[1][2] * m.m[3][3] - m.m[0][2] * m.m[1][3] * m.m[3][0] - m.m[0][3] * m.m[1][0] * m.m[3][2]);
r[1][3] = det * (m.m[0][0] * m.m[1][2] * m.m[2][3] + m.m[0][2] * m.m[1][3] * m.m[2][0] + m.m[0][3] * m.m[1][0] * m.m[2][2] -
m.m[0][0] * m.m[1][3] * m.m[2][2] - m.m[0][2] * m.m[1][0] * m.m[2][3] - m.m[0][3] * m.m[1][2] * m.m[2][0]);
r[2][0] = det * (m.m[1][0] * m.m[2][1] * m.m[3][3] + m.m[1][1] * m.m[2][3] * m.m[3][0] + m.m[1][3] * m.m[2][0] * m.m[3][1] -
m.m[1][0] * m.m[2][3] * m.m[3][1] - m.m[1][1] * m.m[2][0] * m.m[3][3] - m.m[1][3] * m.m[2][1] * m.m[3][0]);
r[2][1] = det * (m.m[0][0] * m.m[2][3] * m.m[3][1] + m.m[0][1] * m.m[2][0] * m.m[3][3] + m.m[0][3] * m.m[2][1] * m.m[3][0] -
m.m[0][0] * m.m[2][1] * m.m[3][3] - m.m[0][1] * m.m[2][3] * m.m[3][0] - m.m[0][3] * m.m[2][0] * m.m[3][1]);
r[2][2] = det * (m.m[0][0] * m.m[1][1] * m.m[3][3] + m.m[0][1] * m.m[1][3] * m.m[3][0] + m.m[0][3] * m.m[1][0] * m.m[3][1] -
m.m[0][0] * m.m[1][3] * m.m[3][1] - m.m[0][1] * m.m[1][0] * m.m[3][3] - m.m[0][3] * m.m[1][1] * m.m[3][0]);
r[2][3] = det * (m.m[0][0] * m.m[1][3] * m.m[2][1] + m.m[0][1] * m.m[1][0] * m.m[2][3] + m.m[0][3] * m.m[1][1] * m.m[2][0] -
m.m[0][0] * m.m[1][1] * m.m[2][3] - m.m[0][1] * m.m[1][3] * m.m[2][0] - m.m[0][3] * m.m[1][2] * m.m[2][1]);
r[3][0] = det * (m.m[1][0] * m.m[2][2] * m.m[3][1] + m.m[1][1] * m.m[2][0] * m.m[3][2] + m.m[1][2] * m.m[2][1] * m.m[3][0] -
m.m[1][0] * m.m[2][1] * m.m[3][2] - m.m[1][1] * m.m[2][2] * m.m[3][0] - m.m[1][2] * m.m[2][0] * m.m[3][1]);
r[3][1] = det * (m.m[0][0] * m.m[2][1] * m.m[3][2] + m.m[0][1] * m.m[2][2] * m.m[3][0] + m.m[0][2] * m.m[2][0] * m.m[3][1] -
m.m[0][0] * m.m[2][2] * m.m[3][1] - m.m[0][1] * m.m[2][0] * m.m[3][2] - m.m[0][2] * m.m[2][1] * m.m[3][0]);
r[3][2] = det * (m.m[0][0] * m.m[1][2] * m.m[3][1] + m.m[0][1] * m.m[1][0] * m.m[3][2] + m.m[0][2] * m.m[1][1] * m.m[3][0] -
m.m[0][0] * m.m[1][1] * m.m[3][2] - m.m[0][1] * m.m[1][2] * m.m[3][0] - m.m[0][2] * m.m[1][0] * m.m[3][1]);
r[3][3] = det * (m.m[0][0] * m.m[1][1] * m.m[2][2] + m.m[0][1] * m.m[1][2] * m.m[2][0] + m.m[0][2] * m.m[1][0] * m.m[2][1] -
m.m[0][0] * m.m[1][2] * m.m[2][1] - m.m[0][1] * m.m[1][0] * m.m[2][2] - m.m[0][2] * m.m[1][1] * m.m[2][0]);
return mat(r);
}
눈이 좀 아프군요
지금까지의 결과와 win32 api의 다각형을 그리는 polygon함수를 사용한 응용 예시입니다.

사실 태양계처럼 항성하나, 행성하나, 행성에 위성하나가 자전과 공전을 하는 영상인데,
지금 보시는 것은 화면을 지우고 다시 그려야된다는 사실을 잊어버려서 나온 결과입니다.
결과가 이뻐서 솔직히 고치고싶지 않았어요.
하지만 고치느라 더블버퍼링도 사용해야했답니다...
지금 이 화면의 버텍스를 계산해내는 코드를 보여드리겠습니다
void OSolarSystemOrbit::Update(float deltaTime)
{
// solar rot
for (int i = 0; i < solarVertex.size(); i++)
{
solarVertex.at(i) = mat::RotateZ(degToRad(solarRotSpeed)) * solarVertex.at(i);
}
// planet1 rot
planet1Pos = mat::RotateZ(degToRad(planet1RotSpeed)) * planet1Pos;
// planet1 rev
for (int i = 0; i < planet1Vertex.size(); i++)
{
planet1Vertex.at(i) = mat::RotateZ(degToRad(planet1RevSpeed)) * planet1Vertex.at(i);
}
// satellite1_1 rev
satellite1_1Pos = mat::RotateZ(degToRad(satellite1_1RevSpeed)) * satellite1_1Pos;
// satellite1_1 rot
for (int i = 0; i < satellite1_1Vertex.size(); i++)
{
satellite1_1Vertex.at(i) = mat::RotateZ(degToRad(satellite1_1RotSpeed)) * satellite1_1Vertex.at(i);
}
/* Reday render vertex data */
solarRenderVertex.clear();
for (int i = 0; i < solarVertex.size(); i++)
{
solarRenderVertex.push_back(vec3(pos + solarPos + solarVertex.at(i)));
}
planet1RenderVertex.clear();
for (int i = 0; i < planet1Vertex.size(); i++)
{
planet1RenderVertex.push_back(vec3(pos + planet1Pos + planet1Vertex.at(i)));
}
satellite1_1RenderVertex.clear();
for (int i = 0; i < planet1Vertex.size(); i++)
{
satellite1_1RenderVertex.push_back(vec3(pos + planet1Pos + satellite1_1Pos + satellite1_1Vertex.at(i)));
}
}
여기서 뒤에 solarVertex 같은 변수들은 육각형의 각 꼭짓점 위치를 가지고있는 std::vector<vec3> 변수입니다.
뒷부분에 soloarRenderVertex와 같은 변수들은 실제 렌더링될 버텍스 위치값을 가집니다.
랜더 버텍스를 계산할 때 보이는 pos는 지금 이 항성계 자체의 위치입니다.
다음글: 게임 수학 C++ | 4. 기하학
(링크 예정)