#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; void (*passiveMouseFunc)(int x, int y) = [](int x, int y) { static int last_x = x; static int last_y = y; const int diff_x = x - last_x; const int diff_y = y - last_y; last_x = x; last_y = y; const int distance = 5; static float angle_horizontal = 0.0; static float angle_vertical = 0.0; angle_horizontal += diff_x / 100.0f; angle_vertical += diff_y / 100.0f; angle_horizontal = fmod(angle_horizontal, 6.283185); angle_vertical = fmod(angle_vertical, 6.283185); float new_x = cos(angle_horizontal); float new_y = sin(angle_vertical); float new_z = sin(angle_horizontal); camera.SetPos(distance * new_x, distance * 12.5 * new_y, distance * new_z); }; // 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.SetTarget(Camera::Target::POINT); // center //camera.RotateYaw(0.01); // 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 if(a++ == 400) // ONCE // { // static float angle = 0; // const int distance = 5; // angle += 0.001f; // angle = fmod(angle, 360.0); // float new_x = cos(angle); // float new_z = sin(angle); // camera.SetPos(distance * new_x + 2, // distance * 12.5, // distance * new_z - 4); // } camera.Refresh(); // draw_origin(); // DRAW TRACKS: for(auto track : track_groups[random_group].second) draw(*track); glutPostRedisplay(); 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 */ 90.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 */ camera.SetTarget(Camera::Target::POINT); // center // handle mouse input glutPassiveMotionFunc(passiveMouseFunc); } 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 = fmin(track_groups[i].first.min.lat, track_groups[j].first.min.lat); track_groups[i].first.min.lon = fmin(track_groups[i].first.min.lon, track_groups[j].first.min.lon); track_groups[i].first.min.ele = fmin(track_groups[i].first.min.ele, track_groups[j].first.min.ele); track_groups[i].first.max.lat = fmax(track_groups[i].first.max.lat, track_groups[j].first.max.lat); track_groups[i].first.max.lon = fmax(track_groups[i].first.max.lon, track_groups[j].first.max.lon); track_groups[i].first.max.ele = 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.lon << "-" << track_group.first.max.lon << std::endl; std::cout << " ele" << " " << track_group.first.min.ele << "-" << track_group.first.max.ele << 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.min.lat -= lat_diff; track.min.lon -= lon_diff; for(auto &p : track.points) { p.lat -= lat_diff; p.lon -= lon_diff; p.lat *= 500; p.lon *= 500; // p.ele *= 0.001; p.ele *= 0.01; } } // } 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; }