### Camera & View Matrix

Perspective & Orthogonal Projection Matrix

Projection = glm::perspective(g_fovy, g_aspect, g_zNear, g_zFar);

Projection = glm::ortho(-5.0f, 5.0f, -5.0f, 5.0f, g_zNear, g_zFar);

Camera & View Matrix

camera class를 사용하여 x/y/x축 카메라의 위치이동과 x/y/x축 카메라의 방향이동
F1&F2 – x축 카메라 위치이동
F3&F4 – y축 카메라 위치이동
F5&F6 – z축 카메라 위치이동
F7&F8 – x축 카메라 방향이동 (PITCH)
F9&F10 – y축 카메라 방향이동 (YAW)
HOME&END – z축 카메라 방향이동 (ROLL)

// main.cpp ——————————————
Camera camera1(FLY);void init( void )
{
// 중간생략..
View = camera1.lookAt(g_eye, g_at, g_up);}void display( void )
{// 중간생략..
View = camera1.View();}void specialkey(int key, int x, int y)
{
if (key == GLUT_KEY_F1) // x-movement
camera1.strafe(0.5);
else if (key == GLUT_KEY_F2)
camera1.strafe(-0.5);
else if (key == GLUT_KEY_F3) // y-movement
camera1.fly(0.5);
else if (key == GLUT_KEY_F4)
camera1.fly(-0.5);
else if (key == GLUT_KEY_F5) // z-movement
camera1.walk(0.5);
else if (key == GLUT_KEY_F6)
camera1.walk(-0.5);
else if (key == GLUT_KEY_F7) // yaw (by y-axis)
camera1.yaw(2.5);
else if (key == GLUT_KEY_F8)
camera1.yaw(-2.5);
else if (key == GLUT_KEY_F9) // pitch (by x-axis)
camera1.pitch(2.5);
else if (key == GLUT_KEY_F10)
camera1.pitch(-2.5);
else if (key == GLUT_KEY_HOME) // roll (by z-axis)
camera1.roll(2.5);
else if (key == GLUT_KEY_END)
camera1.roll(-2.5);
else if (key == GLUT_KEY_LEFT) // same as town
camera1.yaw(2.5);
else if (key == GLUT_KEY_RIGHT)
camera1.yaw(-2.5);
else if (key == GLUT_KEY_UP)
camera1.walk(0.5);
else if (key == GLUT_KEY_DOWN)
camera1.walk(-0.5);
glutPostRedisplay();
}

### glm::lookAt

template <typename T, precision P>
GLM_FUNC_QUALIFIER tmat4x4<T, P> lookAt(tvec3<T, P> const & eye, tvec3<T, P> const & center, tvec3<T, P> const & up)
{
# if GLM_COORDINATE_SYSTEM == GLM_LEFT_HANDED
return lookAtLH(eye, center, up);
# else
return lookAtRH(eye, center, up);
# endif
}

template <typename T, precision P>
GLM_FUNC_QUALIFIER tmat4x4<T, P> lookAtRH
(
tvec3<T, P> const & eye,
tvec3<T, P> const & center,
tvec3<T, P> const & up
)
{
tvec3<T, P> const f(normalize(center – eye));
tvec3<T, P> const s(normalize(cross(f, up)));
tvec3<T, P> const u(cross(s, f));

tmat4x4<T, P> Result(1);
Result[0][0] = s.x;
Result[1][0] = s.y;
Result[2][0] = s.z;
Result[0][1] = u.x;
Result[1][1] = u.y;
Result[2][1] = u.z;
Result[0][2] =-f.x;
Result[1][2] =-f.y;
Result[2][2] =-f.z;
Result[3][0] =-dot(s, eye);
Result[3][1] =-dot(u, eye);
Result[3][2] = dot(f, eye);
return Result;
}

template <typename T, precision P>
GLM_FUNC_QUALIFIER tmat4x4<T, P> lookAtLH
(
tvec3<T, P> const & eye,
tvec3<T, P> const & center,
tvec3<T, P> const & up
)
{
tvec3<T, P> const f(normalize(center – eye));
tvec3<T, P> const s(normalize(cross(up, f)));
tvec3<T, P> const u(cross(f, s));

tmat4x4<T, P> Result(1);
Result[0][0] = s.x;
Result[1][0] = s.y;
Result[2][0] = s.z;
Result[0][1] = u.x;
Result[1][1] = u.y;
Result[2][1] = u.z;
Result[0][2] = f.x;
Result[1][2] = f.y;
Result[2][2] = f.z;
Result[3][0] = -dot(s, eye);
Result[3][1] = -dot(u, eye);
Result[3][2] = -dot(f, eye);
return Result;
}

### Projection Matrix

Orthographic Projection

```template <typename T>
GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> ortho
(
T left,
T right,
T bottom,
T top,
T zNear,
T zFar
)
{
tmat4x4<T, defaultp> Result(1);
Result[0][0] = static_cast<T>(2) / (right - left);
Result[1][1] = static_cast<T>(2) / (top - bottom);
Result[2][2] = - static_cast<T>(2) / (zFar - zNear);
Result[3][0] = - (right + left) / (right - left);
Result[3][1] = - (top + bottom) / (top - bottom);
Result[3][2] = - (zFar + zNear) / (zFar - zNear);
return Result;
}```

Perspective Projection

``` template <typename T>
GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> frustum
(
T left,
T right,
T bottom,
T top,
T nearVal,
T farVal
)
{
tmat4x4<T, defaultp> Result(0);
Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left);
Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom);
Result[2][0] = (right + left) / (right - left);
Result[2][1] = (top + bottom) / (top - bottom);
Result[2][2] = -(farVal + nearVal) / (farVal - nearVal);
Result[2][3] = static_cast<T>(-1);
Result[3][2] = -(static_cast<T>(2) * farVal * nearVal) / (farVal - nearVal);
return Result;
}```

http://www.songho.ca/opengl/gl_projectionmatrix.html

### glm::eulerAngleZXY vs glm::yawPitchRoll

``` template GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZXY ( T const & t1, T const & t2, T const & t3 ) { T c1 = glm::cos(t1); T s1 = glm::sin(t1); T c2 = glm::cos(t2); T s2 = glm::sin(t2); T c3 = glm::cos(t3); T s3 = glm::sin(t3);```

mat<4, 4, T, defaultp> Result;
Result[0][0] = c1 * c3 – s1 * s2 * s3;
Result[0][1] = c3 * s1 + c1 * s2 * s3;
Result[0][2] =-c2 * s3;
Result[0][3] = static_cast(0);
Result[1][0] =-c2 * s1;
Result[1][1] = c1 * c2;
Result[1][2] = s2;
Result[1][3] = static_cast(0);
Result[2][0] = c1 * s3 + c3 * s1 * s2;
Result[2][1] = s1 * s3 – c1 * c3 * s2;
Result[2][2] = c2 * c3;
Result[2][3] = static_cast(0);
Result[3][0] = static_cast(0);
Result[3][1] = static_cast(0);
Result[3][2] = static_cast(0);
Result[3][3] = static_cast(1);
return Result;
}

template
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> yawPitchRoll
(
T const& yaw,
T const& pitch,
T const& roll
)
{
T tmp_ch = glm::cos(yaw);
T tmp_sh = glm::sin(yaw);
T tmp_cp = glm::cos(pitch);
T tmp_sp = glm::sin(pitch);
T tmp_cb = glm::cos(roll);
T tmp_sb = glm::sin(roll);

mat<4, 4, T, defaultp> Result;
Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb;
Result[0][1] = tmp_sb * tmp_cp;
Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb;
Result[0][3] = static_cast(0);
Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb;
Result[1][1] = tmp_cb * tmp_cp;
Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb;
Result[1][3] = static_cast(0);
Result[2][0] = tmp_sh * tmp_cp;
Result[2][1] = -tmp_sp;
Result[2][2] = tmp_ch * tmp_cp;
Result[2][3] = static_cast(0);
Result[3][0] = static_cast(0);
Result[3][1] = static_cast(0);
Result[3][2] = static_cast(0);
Result[3][3] = static_cast(1);
return Result;
}

### Midterm

중간고사

일시: 10/19(화) 오전 0:00 – 23:59

범위: 처음부터 – 배운데까지

### Catmull Rom Spline

``````
// Loop around the total time if necessary
if (elapsedTime >= endTime) {
if (loop) {
while (elapsedTime > endTime)
elapsedTime -= endTime;
}
else {
position = frames[frames.size() - 1].position;
return;
}
}

int i = 0;
// Find the index of the current frame
while (frames[i+1].time < elapsedTime) i++;

// Find the time since the beginning of this frame
elapsedTime -= frames[i].time;

// Find how far we are between the current and next frame (0 to 1)
float fraction = (float)(elapsedTime / (frames[i + 1].time - frames[i].time));

// Interpolate position and rotation values between frames
position = glm::catmullRom (
frames[wrap(i - 1, frames.size() - 1)].position,
frames[wrap(i, frames.size() - 1)].position,
frames[wrap(i + 1, frames.size() - 1)].position,
frames[wrap(i + 2, frames.size() - 1)].position,
fraction);
``````
``````template<typename genType>
GLM_FUNC_QUALIFIER genType catmullRom(
genType const& v1,
genType const& v2,
genType const& v3,
genType const& v4,
typename genType::value_type const& s
) {
typename genType::value_type s2 = pow2(s);
typename genType::value_type s3 = pow3(s);

typename genType::value_type f1 = -s3 + typename genType::value_type(2) * s2 - s;
typename genType::value_type f2 = typename genType::value_type(3) * s3 - typename genType::value_type(5) * s2 + typename genType::value_type(2);
typename genType::value_type f3 = typename genType::value_type(-3) * s3 + typename genType::value_type(4) * s2 + s;
typename genType::value_type f4 = s3 - s2;

return (f1 * v1 + f2 * v2 + f3 * v3 + f4 * v4) / typename genType::value_type(2);
}
``````

http://www.lighthouse3d.com/tutorials/maths/catmull-rom-spline/

``````f(x) = [1, x, x^2, x^3] * M * [v1, v2, v3, v4]
``````

``````/* Coefficients for Matrix M */
#define M11	 0.0
#define M12	 1.0
#define M13	 0.0
#define M14	 0.0
#define M21	-0.5
#define M22	 0.0
#define M23	 0.5
#define M24	 0.0
#define M31	 1.0
#define M32	-2.5
#define M33	 2.0
#define M34	-0.5
#define M41	-0.5
#define M42	 1.5
#define M43	-1.5
#define M44	 0.5

double catmullRomSpline(float x, float v1,float v2, float v3,float v4) {
double c1,c2,c3,c4;

c1 =  	      M12*v2;
c2 = M21*v1          + M23*v3;
c3 = M31*v1 + M32*v2 + M33*v3 + M34*v4;
c4 = M41*v1 + M42*v2 + M43*v3 + M44*v4;

return(((c4*x + c3)*x +c2)*x + c1);
}
``````

### lab8

-Simple Car (c-key)

-Solar System (s-key)

-Robot (r-key)

-Mobile (m-key)

-Geo (g-key)