이전글: 게임 수학 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. 기하학
(링크 예정)
'개발 > 게임\그래픽스' 카테고리의 다른 글
게임 수학 C++ | 2. 벡터 (0) | 2020.05.22 |
---|---|
게임 수학 C++ | 1. 기반 (0) | 2020.05.22 |
WinAPI_비트맵 실습 (0) | 2019.12.29 |
WinApi 메모장 (0) | 2019.11.08 |
2019_Under the Chamber (0) | 2019.10.26 |