#include #include #include "vector3d.h" #include "vector4d.h" #include "matrix4x4.h" #include #define M_PI 3.14 using namespace std; /* Global variables */ char title[] = "Kormilo"; Vector3D camera(6.0, 6.0, 6.0); //Vector3D camera(0.01, 8.0, 0.01); int FPS = 60; double WINDOW_HEIGHT = 480; double aspectRatio = 640.0f / 480.0f; Vector3D A(1.02, 0.3, 1.52); Vector3D B(-0.5, 0.4, -1.6); Vector3D C(3.5, -1.2, 1.7); Vector3D centrarTela; Vector3D N; Vector3D forward_vector; vector>> wheel; vector>> valjci; vector createCircle(double r, int n, int axis) { double phi = 360.0 / n; Vector3D radius(0,0,0); if (axis == 1) { radius.m_z = r; } else { radius.m_x = r; } vector circle; Vector3D centar(0.0, 0.0, 0.0); circle.push_back(radius); for (int i = 0; i < n; i++) { Vector3D v = Matrix4x4::Rotate(circle[i], centar, axis, M_PI / 180.0 * phi); circle.push_back(v); } return circle; } vector> CreateTorus(double r, double n, double R, double l) { vector circle = createCircle(r, n, 3); Matrix4x4 Mt, Mr; Mt.loadTranslate(R, 0, 0); Mr.loadRotateZ(M_PI / 180.0 * 45.0); circle = Mr.Transform(circle); circle = Mt.Transform(circle); vector> torus; torus.push_back(circle); Vector3D centar(0.0, 0.0, 0.0); double phi = 360.0 / l; for (int i = 0; i < l; i++) { vector v = Matrix4x4::Rotate(torus[i], centar, 2, M_PI / 180.0 * phi); torus.push_back(v); } return torus; } vector> CreateValjak(double r, double n, double l, Vector3D centarA) { vector> valjak; vector circle = createCircle(r, n, 1); Matrix4x4 Mt; Mt.loadTranslate(l, 0, 0); // circle = Mt.Transform(circle); valjak.push_back(circle); valjak.push_back(Mt.Transform(valjak[0])); Mt.identity(); Mt.loadTranslate(centarA); valjak = Mt.Transform(valjak); return valjak; } void pushVertex(Vector3D &v) { glVertex3f(v.X(), v.Y(), v.Z()); } void drawTorus(vector> torus) { for (int i = 0; i < torus.size()-1; i++) { for (int j = 0; j < torus[i].size() - 1; j++) { if (j % 2 == 0) { glColor3f(0.6, 0.6, 0.6); } else { glColor3f(0.4, 0.4, 0.4); } glBegin(GL_POLYGON); pushVertex(torus[i][j]); pushVertex(torus[i][j+1]); pushVertex(torus[i+1][j+1]); pushVertex(torus[i+1][j]); glEnd(); } //glColor3f(0.3, 0.0, 0.0); //glBegin(GL_LINES); //for (int j = 0; j < torus[i].size() - 1; j++) //{ // pushVertex(torus[i][j]); //} //glEnd(); } } void drawValjak(vector> valjak) { for (int j = 0; j < valjak[0].size() - 1; j++) { if (j % 2 == 0) { glColor3f(0.5, 0.5, 0.5); } else { glColor3f(0.55, 0.55, 0.55); } glBegin(GL_POLYGON); pushVertex(valjak[0][j]); pushVertex(valjak[0][j + 1]); pushVertex(valjak[1][j + 1]); pushVertex(valjak[1][j]); glEnd(); } glColor3f(0.8, 0.8, 0.8); glBegin(GL_POLYGON); for (int j = 0; j < valjak[0].size(); j++) { pushVertex(valjak[0][j]); } glEnd(); glColor3f(0.8, 0.8, 0.8); glBegin(GL_POLYGON); for (int j = 0; j < valjak[1].size(); j++) { pushVertex(valjak[1][j]); } glEnd(); } void draw_axis() { Vector3D centar(0.0,0.0,0.0); Vector3D osaX(1.0, 0.0, 0.0); Vector3D osaY(0.0, 1.0, 0.0); Vector3D osaZ(0.0, 0.0, 1.0); glColor3f(1.0,0.0,0.0); glBegin(GL_LINES); glVertex3f(centar.X(), centar.Y(), centar.Z()); glVertex3f(2 * osaX.X(), 2 * osaX.Y(), 2 * osaX.Z()); glEnd(); glColor3f(0.0,1.0,0.0); glBegin(GL_LINES); glVertex3f(centar.X(), centar.Y(), centar.Z()); glVertex3f(2 * osaY.X(), 2 * osaY.Y(), 2 * osaY.Z()); glEnd(); glColor3f(0.0,0.0,1.0); glBegin(GL_LINES); glVertex3f(centar.X(), centar.Y(), centar.Z()); glVertex3f(2 * osaZ.X(), 2 * osaZ.Y(), 2 * osaZ.Z()); glEnd(); } void drawMap() { glColor3f(1.0, 0.0, 0.0); glBegin(GL_LINES); pushVertex(A); pushVertex(B); glEnd(); glColor3f(0.0, 1.0, 0.0); glBegin(GL_LINES); pushVertex(B); pushVertex(C); glEnd(); glColor3f(0.0, 0.0, 1.0); glBegin(GL_LINES); pushVertex(C); pushVertex(A); glEnd(); } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); draw_axis(); //drawMap(); glColor3f(0.3, 0.3, 0.3); for (int i = 0; i < wheel.size(); i++) { drawTorus(wheel[i]); } for (int i = 0; i < valjci.size(); i++) { drawValjak(valjci[i]); } //drawBase(base0, 0); //drawBase(base1, 1); //drawSides(); glutSwapBuffers(); // Swap the front and back frame buffers (double buffering) } void SetCamera() { glViewport(0, 0, WINDOW_HEIGHT*aspectRatio, WINDOW_HEIGHT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(80.0f, aspectRatio, 0.1f, 50.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(camera.m_x, camera.m_y, camera.m_z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } void timer(int v) { /*Matrix4x4 mr; mr = Matrix4x4::CreateRotationMatrix(centar, N, M_PI / 180.0 * 0.5); */ //Vector3D CR(0, 0, 0); //camera = Matrix4x4::Rotate(camera, CR , 2, M_PI / 180.0 * 0.5); Matrix4x4 MRotate, Mtransalte, M; MRotate = Matrix4x4::CreateRotationMatrix(centrarTela, N, M_PI / 180.0 * 0.5); Mtransalte.loadTranslate(forward_vector * 0.01); for (int i = 0; i < wheel.size(); i++) { wheel[i] = MRotate.Transform(wheel[i]); } for (int i = 0; i < valjci.size(); i++) { valjci[i] = MRotate.Transform(valjci[i]); } //for (int i = 0; i < wheel.size(); i++) //{ // wheel[i] = Mtransalte.Transform(wheel[i]); //} //for (int i = 0; i < valjci.size(); i++) //{ // valjci[i] = Mtransalte.Transform(valjci[i]); //} //centrarTela = Mtransalte.Transform(centrarTela); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(camera.m_x, camera.m_y, camera.m_z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glutTimerFunc(1000 / FPS, timer, v); glutPostRedisplay(); } void initGL() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque glShadeModel(GL_FLAT); glEnable(GL_DEPTH_TEST); // Enable depth testing for z-culling } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE); glutInitWindowSize(WINDOW_HEIGHT * aspectRatio, WINDOW_HEIGHT); glutInitWindowPosition(50, 50); glutCreateWindow(title); vector> t1 = CreateTorus(0.4, 4, 2, 50); vector> t2 = CreateTorus(0.4, 4, 5, 50); wheel.push_back(t1); wheel.push_back(t2); Vector3D CentarPrvogKruga(1.92, 0, 0); vector> valjak = CreateValjak(0.2, 20, 4.05, CentarPrvogKruga); valjci.push_back(valjak); Vector3D centarRotacije(0.0, 0.0, 0.0); double phi = 60; for (int i = 0; i < 5; i++) { vector> v = Matrix4x4::Rotate(valjci[i], centarRotacije, 2, M_PI / 180.0 * phi); valjci.push_back(v); } N.normal(A, B, C); centrarTela = B; Matrix4x4 MTranslateToCenatarTela; MTranslateToCenatarTela.loadTranslate(centrarTela); for (int i = 0; i < wheel.size(); i++) { wheel[i] = MTranslateToCenatarTela.Transform(wheel[i]); } for (int i = 0; i < valjci.size() ; i++) { valjci[i] = MTranslateToCenatarTela.Transform(valjci[i]); } Vector3D osaY(0.0, 1.0, 0.0); double angle = N.AngleBetween(osaY); Vector3D OsaRot = N.Cross(osaY); Matrix4x4 MRotate; MRotate = Matrix4x4::CreateRotationMatrix(centrarTela, OsaRot, angle); for (int i = 0; i < wheel.size(); i++) { wheel[i] = MRotate.Transform(wheel[i]); } for (int i = 0; i < valjci.size(); i++) { valjci[i] = MRotate.Transform(valjci[i]); } forward_vector = C - B; forward_vector.Normalize(); glutTimerFunc(1000 / FPS, timer, 1); glutDisplayFunc(display); SetCamera(); initGL(); glutMainLoop(); return 0; }