#include "camera/Camera.h" #include "Xml.h" #include "Track.h" #include #include #include #include #include #include // fmod #include #include GLfloat light_diffuse[] = {1.0, 0.0, 0.0, 1.0}; /* Red diffuse light. */ GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0}; /* Infinite light location. */ Camera camera; // TODO(dev): // As per https://www.opengl.org/resources/libraries/glut/spec3/node11.html // "Therefore, GLUT programs should not assume the window was created at the specified size or position. // A GLUT program should use the window's reshape callback to determine the true size of the window." void draw_origin() { // X: glBegin(GL_LINE_STRIP); glColor3d(0, 0, 0); glVertex3f(-10.0f, 0.0f, 0.0f); glColor3d(255, 0, 0); glVertex3f(0.0f, 0.0f, 0.0f); glColor3d(0, 0, 0); glVertex3f(10.0f, 0.0f, 0.0f); glEnd(); // Y: glBegin(GL_LINE_STRIP); glVertex3f(0.0f, -10.0f, 0.0f); glColor3d(0, 255, 0); glVertex3f(0.0f, 0.0f, 0.0f); glColor3d(0, 0, 0); glVertex3f(0.0f, 10.0f, 0.0f); glEnd(); // Z: glBegin(GL_LINE_STRIP); glVertex3f(0.0f, 0.0f, -10.0f); glColor3d(0, 0, 255); glVertex3f(0.0f, 0.0f, 0.0f); glColor3d(0, 0, 0); glVertex3f(0.0f, 0.0f, 10.0f); glEnd(); } void display() { // RESET: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glLineWidth(1.0f); //camera.RotateYaw(0.01); static double asdf = -10.0; asdf += 0.02; if(asdf > 15.0) asdf = -15.0; // gluLookAt(-15.0, 30.0, -asdf, /* eye is at */ // 0.0, 5.0, 0.0, /* center is at */ // 0.0, 1.0, 0.0); /* up is in positive Y direction */ static int a = 0; if(a < 400) { camera.RotatePitch(0.03f); camera.RotateYaw(0.01f); camera.Move(-0.1f); if(++a == 200) camera.SetTarget(Camera::Target::POINT); // center } else { static float angle = 0; const int distance = 50; angle += 0.01f; angle = fmod(angle, 360.0); float new_x = cos(angle); float new_z = sin(angle); camera.SetPos(distance * new_x, distance, distance * new_z); } draw_origin(); // DRAW TRACKS: for(auto track : track_groups[random_group].second) draw(*track); glutSwapBuffers(); } void init() { glColor3d(1.0, 1.0, 1.0); /* Enable a single OpenGL light. */ // glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); // glLightfv(GL_LIGHT0, GL_POSITION, light_position); // glEnable(GL_LIGHT0); // glEnable(GL_LIGHTING); /* Use depth buffering for hidden surface elimination. */ glEnable(GL_DEPTH_TEST); /* Setup the view of the cube. */ glMatrixMode(GL_PROJECTION); gluPerspective( /* field of view in degree */ 70.0, /* aspect ratio */ 1.0, /* Z near */ 1.0, /* Z far */ 1000.0); glMatrixMode(GL_MODELVIEW); gluLookAt(-10.0, 25.0, -10.0, /* eye is at */ 0.0, 0.0, 0.0, /* center is at */ 0.0, 1.0, 0.0); /* up is in positive Y direction */ } int main(int argc, char *argv[]) { if(argc != 2) { std::cerr << "You pust pass the folder which contains gpx files." << std::endl; return -1; } // dvereb: srand(time(NULL)); std::vector files; for(const auto& entry : std::experimental::filesystem::directory_iterator(argv[1])) { auto extension = entry.path().extension(); if(extension == ".gpx") files.push_back(entry.path().string()); } for(auto file : files) ParseFile(tracks, file); // NORMALIZE TRACKS TO VIEWPORT: bool first = true; // NOTE(dev): // We're trying to determine groups of tracks that overlap // First, put all the tracks in their own group // Second, keep checking to see if any groups overlap until there are no changes // std::vector>> track_groups; for(auto &track : tracks) { // Build a header-only copy of each track Track header; header.min = track.min; header.max = track.max; std::vector vec; vec.push_back(&track); std::pair> p; p.first = header; p.second = vec; // Point to the actual Track with the header info track_groups.push_back(p); } for(bool no_changes = false; !no_changes; ) { no_changes = true; for(auto i = 0; i < track_groups.size(); ++i) { for(auto j = 0; j < track_groups.size(); /* no increment here */) { if(j == i) { ++j; continue; } bool lat_overlap = false; bool lon_overlap = false; if(track_groups[j].first.min.lat <= track_groups[i].first.max.lat && track_groups[j].first.max.lat >= track_groups[i].first.min.lat) lat_overlap = true; if(track_groups[j].first.min.lon <= track_groups[i].first.max.lon && track_groups[j].first.max.lon >= track_groups[i].first.min.lon) lon_overlap = true; if(lat_overlap && lon_overlap) { no_changes = false; track_groups[i].first.min.lat = std::fmin(track_groups[i].first.min.lat, track_groups[j].first.min.lat); track_groups[i].first.min.lon = std::fmin(track_groups[i].first.min.lon, track_groups[j].first.min.lon); track_groups[i].first.min.ele = std::fmin(track_groups[i].first.min.ele, track_groups[j].first.min.ele); track_groups[i].first.max.lat = std::fmax(track_groups[i].first.max.lat, track_groups[j].first.max.lat); track_groups[i].first.max.lon = std::fmax(track_groups[i].first.max.lon, track_groups[j].first.max.lon); track_groups[i].first.max.ele = std::fmax(track_groups[i].first.max.ele, track_groups[j].first.max.ele); // std::cout << "first.min.lat: " << track_groups[i].first.min.lat << ", " // << "first.min.lon: " << track_groups[i].first.min.lon << ", " // << "first.min.lon: " << track_groups[i].first.min.ele << ", " // << "first.min.lon: " << track_groups[i].first.max.lat << ", " // << "first.min.lon: " << track_groups[i].first.max.lon << ", " // << "first.min.lon: " << track_groups[i].first.max.ele << ", " // << std::endl; // Add tracks vector to make one big one track_groups[i].second.insert(track_groups[i].second.end(), track_groups[j].second.begin(), track_groups[j].second.end()); track_groups.erase(track_groups.begin() + j); if(j < i) --i; } else ++j; } } } std::cout << "Generated " << track_groups.size() << " track groups:" << std::endl; int count = 0; for(const auto &track_group : track_groups) { ++count; std::cout << "Track #" << count << ", including " << track_group.second.size() << " tracks:" << std::endl; std::cout << " lat" << " " << track_group.first.min.lat << "-" << track_group.first.max.lat << std::endl; std::cout << " lon" << " " << track_group.first.min.lat << "-" << track_group.first.max.lat << std::endl; std::cout << " ele" << " " << track_group.first.min.lat << "-" << track_group.first.max.lat << std::endl; } std::cout << std::endl; random_group = 0; float min_lat, max_lat, min_lon, max_lon, min_ele, max_ele; first = true; // reset! for(auto &track : track_groups[random_group].second) { for(auto &p : track->points) { if(first) { first = false; min_lat = max_lat = p.lat; min_lon = max_lon = p.lon; min_ele = max_ele = p.ele; } else { if(p.lat < min_lat) min_lat = p.lat; else if(p.lat > max_lat) max_lat = p.lat; if(p.lon < min_lon) min_lon = p.lon; else if(p.lon > max_lon) max_lon = p.lon; if(p.ele < min_ele) min_ele = p.ele; else if(p.ele > max_ele) max_ele = p.ele; } } } std::cout << "min_lat: " << min_lat << " max_lat: " << max_lat << ", " << "min_lon: " << min_lon << " max_lon: " << max_lon << ", " << "min_ele: " << min_ele << " max_ele: " << max_ele << std::endl; auto lat_diff = min_lat + ((max_lat - min_lat) / 2.0); auto lon_diff = min_lon + ((max_lon - min_lon) / 2.0); // auto ele_diff = min_ele; std::cout << "lat_diff: " << lat_diff << ", " << "lon_diff: " << lon_diff << ", " // << "ele_diff: " << ele_diff << ", " << std::endl; // for(Track &track : track_groups[random_group].second) // { for(auto &track : tracks) { track.max.lat -= lat_diff; track.max.lon -= lon_diff; // track.max.ele -= ele_diff; track.min.lat -= lat_diff; track.min.lon -= lon_diff; // track.min.ele -= ele_diff; for(auto &p : track.points) { p.lat -= lat_diff; p.lon -= lon_diff; // p.ele -= ele_diff; p.lat *= 500; p.lon *= 500; p.ele *= 0.1; } } // } glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA | GLUT_MULTISAMPLE); glutInit(&argc, argv); glutCreateWindow("3D GPX Viewer"); glutDisplayFunc(display); // NOTE(dev): lmfao: // glutSetCursor(GLUT_CURSOR_SPRAY); glutSetCursor(GLUT_CURSOR_FULL_CROSSHAIR); init(); camera.Init(); // camera.Strafe(-15); // camera.RotatePitch(-89 * M_PI / 180.0); glutMainLoop(); return 0; }