// Lab1.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
//Utilized the following resources to complete this lab:
//http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/
//http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/
//Lab 0 -- SimpleGLUT.cpp
//
#include "pch.h"
#include <iostream>
using namespace std;
//#include "stdafx.h"
// standard
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <vector>
#define GLM_ENABLE_EXPERIMENTAL
// glut
#include <GL/glut.h>
// Include GLFW
//#include <GLFW/glfw3.h>
//GLFWwindow* window;
// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtx/euler_angles.hpp>
#include <glm/gtx/norm.hpp>
#include <glm/gtx/spline.hpp>
#include <glm/gtx/string_cast.hpp>
using namespace glm;
//================================
// global variables
//================================
// screen size
int g_screenWidth = 0;
int g_screenHeight = 0;
// frame index
int g_frameIndex = 0;
int rcount = 0;
//outputs for interpolations (Catmull Rom)
vec3 anglePos;
vec3 angleOri;
vec3 quatPos;
quat quatOri;
vec3 anglePosList[100];
vec3 angleOriList[100];
vec3 quatPosList[100];
quat quatOriList[100];
vec3 aquatOriList[100];
//outputs for interpolations (B)
vec3 pFinal;
vec3 oFinal;
vec3 qPFinal;
quat qOFinal;
vec3 bAnglePosList[100];
vec3 bAngleOriList[100];
vec3 bQuatPosList[100];
quat bQuatOriList[100];
vec3 abquatOriList[100];
//outputs for Rotations
quat norm;
mat4 eRot;
mat4 qRot;
//Initialize my Fixed Angle inputs (3 for coordinates, 3 for angles)
vec3 positions[3];
vec3 orientations[3];
vec3 ePosition1(0.0f, 0.0f, -5.0f);
vec3 eOrientation1(0, 0, 0);
vec3 ePosition2(0.1f, 0.1f, -5.0f);
vec3 eOrientation2(1.5708, 0, 0);
vec3 ePosition3(0.2f, 0.2f, -5.0f);
vec3 eOrientation3(0, 0, 0);
vec3 ePosition4(0.3f, 0.3f, -5.0f);
vec3 eOrientation4(0, 0, 0);
//Initialize my Quaternion inputs(3 for translation, 4 for rotation)
vec3 qPosition1(0.0f, 0.0f, -5.0f);
quat qOrientation1(.45, 0, 0, 0);
vec3 qPosition2(0.1f, 0.0f, -5.1f);
quat qOrientation2(0, 0, 1, 0);
vec3 qPosition3(0.2f, 0.0f, -4.8f);
quat qOrientation3(0, 0, 2, 0);
vec3 qPosition4(-0.1f, 0.0f, -5.0f);
quat qOrientation4(0, 0, 3, 0);
void fixedCatmullRom(void) {
int j = 0;
for (double i = .1; i < 10; i = i + .1) {
anglePos = glm::catmullRom(ePosition1, ePosition2, ePosition3, ePosition4, i);
anglePosList[j] = anglePos;
j++;
}
j = 0;
for (double i = .1; i < 10; i = i + .1) {
angleOri = glm::catmullRom(eOrientation1, eOrientation2, eOrientation3, eOrientation4, i);
angleOriList[j] = angleOri;
j++;
}
}
void quatCatmullRom(void) {
glm::vec3 nOrientation1 = glm::eulerAngles(qOrientation1);
glm::vec3 nOrientation2 = glm::eulerAngles(qOrientation2);
glm::vec3 nOrientation3 = glm::eulerAngles(qOrientation3);
glm::vec3 nOrientation4 = glm::eulerAngles(qOrientation4);
int j = 0;
for (double i = .1; i < 10; i = i + .1) {
quatPos = glm::catmullRom(qPosition1, qPosition2, ePosition3, ePosition4, i);
quatPosList[j] = quatPos;
j = j+1;
}
j = 0;
for (double i = .1; i < 10; i = i + .1) {
quatOri = glm::catmullRom(qOrientation1, qOrientation2, qOrientation3, qOrientation4, i);
quatOriList[j] = quatOri;
aquatOriList[j] = glm::eulerAngles(quatOri);
j++;
}
}
void fixedBCurve(void) {
int j = 0;
for (double t = .1; t < 10; t = t + .1){
//For position points
pFinal.x = pow(1 - t, 3) * ePosition1.x + pow(1 - t, 2) * 3 * t * ePosition2.x + (1 - t) * 3 * t * t * ePosition3.x + t * t * t * ePosition4.x;
pFinal.y = pow(1 - t, 3) * ePosition1.y + pow(1 - t, 2) * 3 * t * ePosition2.y + (1 - t) * 3 * t * t * ePosition3.y + t * t * t * ePosition4.y;
pFinal.z = pow(1 - t, 3) * ePosition1.z + pow(1 - t, 2) * 3 * t * ePosition2.z + (1 - t) * 3 * t * t * ePosition3.z + t * t * t * ePosition4.z;
bAnglePosList[j] = pFinal;
j++;
}
j = 0;
//For orientation points
for (double t = .1; t < 10; t = t + .1){
oFinal.x = pow(1 - t, 3) * eOrientation1.x + pow(1 - t, 2) * 3 * t * eOrientation2.x + (1 - t) * 3 * t * t * eOrientation3.x + t * t * t * eOrientation4.x;
oFinal.y = pow(1 - t, 3) * eOrientation1.y + pow(1 - t, 2) * 3 * t * eOrientation2.y + (1 - t) * 3 * t * t * eOrientation3.y + t * t * t * eOrientation4.y;
oFinal.z = pow(1 - t, 3) * eOrientation1.z + pow(1 - t, 2) * 3 * t * eOrientation2.z + (1 - t) * 3 * t * t * eOrientation3.z + t * t * t * eOrientation4.z;
bAngleOriList[j] = oFinal;
}
}
void quatBCurve(void) {
int j = 0;
for (double t = .1; t < 10; t = t + .1) {
//For position points
qPFinal.x = pow(1 - t, 3) * qPosition1.x + pow(1 - t, 2) * 3 * t * qPosition2.x + (1 - t) * 3 * t * t * qPosition3.x + t * t * t * qPosition4.x;
qPFinal.y = pow(1 - t, 3) * qPosition1.y + pow(1 - t, 2) * 3 * t * qPosition2.y + (1 - t) * 3 * t * t * qPosition3.y + t * t * t * qPosition4.y;
qPFinal.z = pow(1 - t, 3) * qPosition1.z + pow(1 - t, 2) * 3 * t * qPosition2.z + (1 - t) * 3 * t * t * qPosition3.z + t * t * t * qPosition4.z;
bQuatPosList[j] = qPFinal;
j++;
}
j = 0;
//For orientation points
for (double t = .1; t < 10; t = t + .1) {
qOFinal.w = pow(1 - t, 3) * qOrientation1.w + pow(1 - t, 2) * 3 * t * qOrientation2.w + (1 - t) * 3 * t * t * qOrientation3.w + t * t * t * qOrientation4.w;
qOFinal.x = pow(1 - t, 3) * qOrientation1.x + pow(1 - t, 2) * 3 * t * qOrientation2.x + (1 - t) * 3 * t * t * qOrientation3.x + t * t * t * qOrientation4.x;
qOFinal.y = pow(1 - t, 3) * qOrientation1.y + pow(1 - t, 2) * 3 * t * qOrientation2.y + (1 - t) * 3 * t * t * qOrientation3.y + t * t * t * qOrientation4.y;
qOFinal.z = pow(1 - t, 3) * qOrientation1.z + pow(1 - t, 2) * 3 * t * qOrientation2.z + (1 - t) * 3 * t * t * qOrientation3.z + t * t * t * qOrientation4.z;
bQuatOriList[j] = qOFinal;
abquatOriList[j] = glm::eulerAngles(qOFinal);
j++;
}
}
void fixedToRotation(vec3 Point) {
glRotated(Point.x, 1.0, 0.0, 0.0);
glRotated(Point.y, 0.0, 1.0, 0.0);
glRotated(Point.z, 0.0, 0.0, 1.0);
}
void readyForRender(vec3 Pos, vec3 Ori) {
glTranslatef(Pos.x, Pos.y, Pos.z);
fixedToRotation(Ori);
}
//================================
// render
//================================
void render(void) {
// clear buffer
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// render state
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
// enable lighting
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
// light source attributes
GLfloat LightAmbient[] = { 0.4f, 0.4f, 0.4f, 1.0f };
GLfloat LightDiffuse[] = { 0.3f, 0.3f, 0.3f, 1.0f };
GLfloat LightSpecular[] = { 0.4f, 0.4f, 0.4f, 1.0f };
GLfloat LightPosition[] = { 5.0f, 5.0f, 5.0f, 1.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpecular);
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
// surface material attributes
GLfloat material_Ka[] = { 0.11f, 0.06f, 0.11f, 1.0f };
GLfloat material_Kd[] = { 0.43f, 0.47f, 0.54f, 1.0f };
GLfloat material_Ks[] = { 0.33f, 0.33f, 0.52f, 1.0f };
GLfloat material_Ke[] = { 0.1f , 0.0f , 0.1f , 1.0f };
GLfloat material_Se = 10;
glMaterialfv(GL_FRONT, GL_AMBIENT, material_Ka);
glMaterialfv(GL_FRONT, GL_DIFFUSE, material_Kd);
glMaterialfv(GL_FRONT, GL_SPECULAR, material_Ks);
glMaterialfv(GL_FRONT, GL_EMISSION, material_Ke);
glMaterialf(GL_FRONT, GL_SHININESS, material_Se);
// modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
readyForRender(bQuatPosList[rcount], abquatOriList[rcount]);
// render objects
glutSolidTeapot(.5);
if (rcount < 100) {
rcount = rcount + 1;
}
else {
rcount = 0;
}
// disable lighting
glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);
// swap back and front buffers
glutSwapBuffers();
}
//================================
// keyboard input
//================================
void keyboard(unsigned char key, int x, int y) {
}
//================================
// reshape : update viewport and projection matrix when the window is resized
//================================
void reshape(int w, int h) {
// screen size
g_screenWidth = w;
g_screenHeight = h;
// viewport
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
// projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLfloat)w / (GLfloat)h, 1.0, 2000.0);
}
//================================
// timer : triggered every 16ms ( about 60 frames per second )
//================================
void timer(int value) {
// increase frame index
g_frameIndex++;
// render
glutPostRedisplay();
// reset timer
// 16 ms per frame ( about 60 frames per second )
glutTimerFunc(16, timer, 0);
}
int main(int argc, char** argv)
{
fixedCatmullRom();
quatCatmullRom();
fixedBCurve();
quatBCurve();
// create opengL window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(600, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
// set callback functions
glutDisplayFunc(render);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutTimerFunc(16, timer, 0);
// main loop
glutMainLoop();
//DEBUGGER
//for (int i = 0; i < 10; i++) {
//std:cout << glm::to_string(anglePosList[i]) << std::endl;
//std:cout << glm::to_string(angleOriList[i]) << std::endl;
//std:cout << glm::to_string(quatPosList[i]) << std::endl;
//std:cout << glm::to_string(quatOriList[i]) << std::endl;
//std::cout << glm::to_string(bAnglePosList[i]) << std::endl;
//std::cout << glm::to_string(bAngleOriList[i]) << std::endl;
//std::cout << glm::to_string(bQuatPosList[i]) << std::endl;
//std::cout << glm::to_string(bQuatOriList[i]) << std::endl;
//std::cout << (readyForRender(anglePosList[i], angleOriList[i])) << std::endl;
//}
return 0;
}