Advertisement
Guest User

Untitled

a guest
Dec 15th, 2017
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.12 KB | None | 0 0
  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3.  
  4. #include "dialogmodel.h"
  5. #include "dialogship.h"
  6.  
  7. #include <list>
  8. #include "camera.h"
  9.  
  10. MainWindow::MainWindow(QWidget *parent) :
  11. QMainWindow(parent),
  12. ui(new Ui::MainWindow),
  13. zbuffer(screen_size_x, screen_size_y)
  14. {
  15. ui->setupUi(this);
  16. connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(updateSliderBPos(int)));
  17. setFixedSize(window_size_x, window_size_y);
  18.  
  19. ui->graphicsView->setFixedSize(screen_size_x, screen_size_y);
  20. ui->graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  21. ui->graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  22. scene.setSceneRect(-screen_size_x / 2, -screen_size_y / 2,
  23. screen_size_x, screen_size_y);
  24. ui->graphicsView->setScene(&scene);
  25.  
  26. pixmap = new QPixmap(screen_size_x, screen_size_y);
  27. painter = new QPainter(pixmap);
  28.  
  29. connect(ui->about, SIGNAL(triggered()), this, SLOT(about()));
  30. connect(ui->InfoButtons, SIGNAL(triggered()), this, SLOT(info_buttons()));
  31. connect(ui->exit, SIGNAL(triggered()), this, SLOT(close()));
  32. }
  33.  
  34. MainWindow::~MainWindow()
  35. {
  36. delete painter;
  37. delete pixmap;
  38. delete ui;
  39. }
  40.  
  41. void MainWindow::info_buttons() {
  42. QMessageBox::information(this, "Help", "Some text");
  43. }
  44.  
  45. void MainWindow::about() {
  46. QMessageBox::information(this, "Help", "Some text");
  47. }
  48.  
  49. void MainWindow::create_model() {
  50. DialogModel dmodel;
  51. dmodel.exec();
  52.  
  53. if ((dmodel.Lvalue() != 0) && (dmodel.Wvalue() != 0) && (dmodel.Hvalue() != 0) ) {
  54. model_s.L = dmodel.Lvalue();
  55. model_s.H = dmodel.Hvalue();
  56. model_s.W = dmodel.Wvalue();
  57. }
  58.  
  59. Model m(model_s.L, model_s.H, model_s.W);
  60. add_model(m);
  61. ui->graphicsView->setFocus();
  62.  
  63. visualize_model();
  64. }
  65.  
  66. void MainWindow::add_model(Model &model) {
  67. QString str = QString("Груз ") + QString::number(manager.num_of_models());
  68.  
  69. ui->modelList->addItem(str);
  70. manager.add_model(model);
  71. ui->modelList->setCurrentRow(ui->modelList->count() - 1);
  72. manager.active_object = &(manager.model_list[ui->modelList->currentRow()]);
  73. }
  74.  
  75. void MainWindow::create_ship() {
  76. DialogShip dship;
  77. dship.exec();
  78.  
  79. if ((dship.Lvalue() != 0) && (dship.Wbvalue() != 0) && (dship.Hvalue() != 0) && (dship.Wtvalue() != 0)) {
  80. ship_s.H = dship.Hvalue();
  81. ship_s.L = dship.Lvalue();
  82. ship_s.Wb = dship.Wbvalue();
  83. ship_s.Wt = dship.Wtvalue();
  84. }
  85.  
  86. manager.ship.createShip(ship_s.L, ship_s.H, ship_s.Wt, ship_s.Wb);
  87. manager.active_object = &(manager.ship);
  88. ui->ship->setChecked(true);
  89.  
  90. visualize_ship();
  91. }
  92.  
  93. void MainWindow::load_model() {
  94. QString file_path = QFileDialog::getOpenFileName(this, tr("Выберите файл"), tr(""), tr("*.txt"));
  95. if (file_path.isEmpty()) {
  96. return;
  97. }
  98.  
  99. QFile file(file_path);
  100. if (!file.open(QIODevice::ReadOnly)) {
  101. QMessageBox::information(this, tr("Невозможно открыть файл"), file.errorString());
  102. return;
  103. }
  104.  
  105. QTextStream in(&file);
  106.  
  107. while (in.status() == QTextStream::Ok) {
  108.  
  109. float l, w, h;
  110. in >> l >> h >> w;
  111.  
  112. model_s.H = h;
  113. model_s.L = l;
  114. model_s.W = w;
  115. }
  116.  
  117. file.close();
  118. }
  119.  
  120. void MainWindow::load_ship() {
  121. QString file_path = QFileDialog::getOpenFileName(this, tr("Выберите файл"), tr(""), tr("*.txt"));
  122. if (file_path.isEmpty()) {
  123. return;
  124. }
  125.  
  126. QFile file(file_path);
  127. if (!file.open(QIODevice::ReadOnly)) {
  128. QMessageBox::information(this, tr("Невозможно открыть файл"), file.errorString());
  129. return;
  130. }
  131.  
  132. QTextStream in(&file);
  133.  
  134. while (in.status() == QTextStream::Ok) {
  135.  
  136. float l, wb, h, wt;
  137. in >> l >> h >> wt >> wb;
  138.  
  139. ship_s.L = l;
  140. ship_s.H = h;
  141. ship_s.Wt = wt;
  142. ship_s.Wb = wb;
  143.  
  144. }
  145.  
  146. file.close();
  147. }
  148.  
  149. void MainWindow::visualize_model() {
  150.  
  151. for (Model& m : manager.model_list) {
  152. for (Polygon& pol : m.polygons) {
  153. if (manager.check_visible_m(m)) {
  154. QVector<QPoint> polyvector;
  155. for (Point& point : pol.points) {
  156. polyvector.push_back(manager.camera.to_screen(point));
  157. }
  158.  
  159. QPolygon polygon(polyvector);
  160. scene.addPolygon(polygon,QPen(Qt::black));
  161. }
  162. }
  163. }
  164.  
  165. }
  166.  
  167. void MainWindow::visualize_ship() {
  168.  
  169. for (Polygon& pol : manager.ship.polygons) {
  170. if (manager.check_visible_s()) {
  171. QVector<QPoint> polyvector;
  172. for (Point& point : pol.points) {
  173. polyvector.push_back(manager.camera.to_screen(point));
  174. }
  175. QPolygon polygon(polyvector);
  176. scene.addPolygon(polygon, QPen());
  177. }
  178. }
  179. }
  180.  
  181. void MainWindow::on_clearScr_clicked()
  182. {
  183. scene.clear();
  184. }
  185.  
  186. void MainWindow::on_ship_toggled(bool checked)
  187. {
  188. if (checked) {
  189. manager.active_object = &(manager.ship);
  190. }
  191. }
  192.  
  193. void MainWindow::keyPressEvent(QKeyEvent *e) {
  194. scene.clear();
  195. ui->graphicsView->setFocus();
  196. if (manager.active_object != nullptr) {
  197. Point zero(manager.ship.get_center());
  198. switch(e->key()) {
  199. // move
  200. case Qt::Key_Q :
  201. if (ui->cameraButton->isChecked()) {
  202. for (Model& m: manager.model_list) {
  203. m.move(0, 0, -move_speed);
  204. }
  205. manager.ship.move(0, 0, -move_speed);
  206. } else {
  207. manager.active_object->move(0, 0, move_speed);
  208. }
  209. break;
  210.  
  211. case Qt::Key_E:
  212. if (ui->cameraButton->isChecked()) {
  213. for (Model& m: manager.model_list) {
  214. m.move(0, 0, move_speed);
  215. }
  216. manager.ship.move(0, 0, move_speed);
  217. } else {
  218. manager.active_object->move(0, 0, -move_speed);
  219. }
  220. break;
  221. case Qt::Key_W:
  222. if (ui->cameraButton->isChecked()) {
  223. for (Model& m: manager.model_list){
  224. m.move(0, move_speed, 0);
  225. }
  226. manager.ship.move(0, move_speed, 0);
  227. } else {
  228. if (ui->models->isChecked()) {
  229. Model curr_model = manager.model_list[ui->modelList->currentRow()];
  230. curr_model.move(0, -move_speed, 0);
  231. if(able_to_move(curr_model)) {
  232. manager.active_object->move(0, -move_speed, 0);
  233. }
  234. } else {
  235. manager.active_object->move(0, -move_speed, 0);
  236. }
  237.  
  238. }
  239. break;
  240. case Qt::Key_S:
  241. if (ui->cameraButton->isChecked()) {
  242. for (Model& m: manager.model_list){
  243. m.move(0, -move_speed, 0);
  244. }
  245. manager.ship.move(0, -move_speed, 0);
  246. } else {
  247. manager.active_object->move(0, move_speed, 0);
  248. }
  249. break;
  250.  
  251. case Qt::Key_A :
  252. if (ui->cameraButton->isChecked()) {
  253. for (Model& m: manager.model_list){
  254. m.move(move_speed, 0, 0);
  255. }
  256. manager.ship.move(move_speed, 0, 0);
  257. } else {
  258. manager.active_object->move(-move_speed, 0, 0);
  259. }
  260. break;
  261.  
  262. case Qt::Key_D:
  263. if (ui->cameraButton->isChecked()) {
  264. for (Model& m: manager.model_list){
  265. m.move(-move_speed, 0, 0);
  266. }
  267. manager.ship.move(-move_speed, 0, 0);
  268. } else {
  269. manager.active_object->move(move_speed, 0, 0);
  270. }
  271. break;
  272. // rotate
  273. case Qt::Key_K:
  274. if (ui->cameraButton->isChecked()) {
  275. for (Model& m: manager.model_list) {
  276. m.rotate(0, -rotate_speed, 0, zero);
  277. }
  278. manager.ship.rotate(0, -rotate_speed, 0, zero);
  279. } else {
  280. manager.active_object->rotate(0, rotate_speed, 0);
  281. }
  282. break;
  283. case Qt::Key_I:
  284. if (ui->cameraButton->isChecked()) {
  285. for (Model& m: manager.model_list) {
  286. m.rotate(0, rotate_speed, 0, zero);
  287. }
  288. manager.ship.rotate(0, rotate_speed, 0, zero);
  289. } else {
  290. manager.active_object->rotate(0, -rotate_speed, 0);
  291. }
  292. break;
  293. case Qt::Key_L:
  294. if (ui->cameraButton->isChecked()) {
  295. for (Model& m: manager.model_list) {
  296. m.rotate(0, 0, -rotate_speed, zero);
  297. }
  298. manager.ship.rotate(0, 0, -rotate_speed, zero);
  299. } else {
  300. manager.active_object->rotate(0, 0, rotate_speed);
  301. }
  302. break;
  303. case Qt::Key_J:
  304. if (ui->cameraButton->isChecked()) {
  305. for (Model& m: manager.model_list) {
  306. m.rotate(0, 0, rotate_speed, zero);
  307. }
  308. manager.ship.rotate(0, 0, rotate_speed, zero);
  309. } else {
  310. manager.active_object->rotate(0, 0, -rotate_speed);
  311. }
  312. break;
  313. case Qt::Key_O:
  314. if (ui->cameraButton->isChecked()) {
  315. for (Model& m: manager.model_list) {
  316. m.rotate(-rotate_speed, 0, 0, zero);
  317. }
  318. manager.ship.rotate(-rotate_speed, 0, 0, zero);
  319. } else {
  320. manager.active_object->rotate(-rotate_speed, 0, 0);
  321. }
  322. break;
  323. case Qt::Key_U:
  324. if (ui->cameraButton->isChecked()) {
  325. for (Model& m: manager.model_list) {
  326. m.rotate(rotate_speed, 0, 0, zero);
  327. }
  328.  
  329. manager.ship.rotate(rotate_speed, 0, 0, zero);
  330. } else {
  331. manager.active_object->rotate(rotate_speed, 0, 0);
  332. }
  333. break;
  334. // resize
  335. case Qt::Key_T:
  336. manager.active_object->resize(resize_speed);
  337. break;
  338. case Qt::Key_Y:
  339. manager.active_object->resize(1/resize_speed);
  340. break;
  341. default:
  342. break;
  343. }
  344. }
  345. manager.ship.setColor();
  346. for (Model& m: manager.model_list) {
  347. if (m.insideShip(manager.ship) == true) {
  348. m.setColor(Qt::green);
  349. } else {
  350. m.setColor(Qt::red);
  351. }
  352. }
  353.  
  354. if (ui->DrawBox->isChecked()) {
  355. mydrawZBuffer();
  356. } else {
  357. visualize_model();
  358. visualize_ship();
  359. }
  360. }
  361.  
  362. void MainWindow::mydrawZBuffer() {
  363. scene.clear();
  364. pixmap->fill(QColor(234, 238, 242));
  365.  
  366. std::list<Polygon> waiting_polygons;
  367. transform_points_for_zbuffer(waiting_polygons);
  368.  
  369. std::list<Polygon> active_polygons;
  370.  
  371. // проходимся по каждой строке экрана
  372. for (int x = 0; x < screen_size_x; ++x) {
  373. double real_x = x - screen_size_x_half;
  374. // здесь нужно посмотреть в список ждущих полигонов и если минимальное значение х меньше или равно текущему
  375. // нужно убрать данный полигон из списка ждущих и добавить его в список активных
  376. auto it = waiting_polygons.cbegin();
  377. while (it != waiting_polygons.cend()) {
  378. double min_x = (*it).min_x();
  379. if (min_x <= real_x) {
  380. active_polygons.push_back(*it);
  381. it = waiting_polygons.erase(it);
  382. } else {
  383. ++it;
  384. }
  385. }
  386.  
  387. std::list<Polygon> active_polygons_y;
  388. std::list<Polygon> waiting_polygons_y(active_polygons);
  389.  
  390. // если список активных полигонов пуст, скипаем цикл
  391. if (active_polygons.size() > 0) {
  392. for (int y = 0; y < screen_size_y; ++y) {
  393. double real_y = y - screen_size_y_half;
  394.  
  395. auto it = waiting_polygons_y.cbegin();
  396. while (it != waiting_polygons_y.cend()) {
  397. double min_y = (*it).min_y();
  398. if (min_y <= real_y) {
  399. active_polygons_y.push_back(*it);
  400. it = waiting_polygons_y.erase(it);
  401. } else {
  402. ++it;
  403. }
  404. }
  405. // проходимся по списку активных полигонов и смотрим глубину пикселя для этого полигона, если она меньше,
  406. // чем хранящаяся в zbuffer-е, записываем ее туда вместе с цветом
  407. if (active_polygons_y.size() > 0) {
  408. double max_depth = std::numeric_limits<double>::lowest();
  409. QColor max_color = QColor(234, 238, 242);
  410.  
  411. for (const Polygon& polygon : active_polygons_y) {
  412. double depth = polygon.depth_of_pixel(real_x, real_y);
  413. if (depth > max_depth && polygon.in_polygon(real_x, real_y)) {
  414. max_depth = depth;
  415. max_color = polygon.polygon_color;
  416. }
  417. }
  418.  
  419. painter->setPen(max_color);
  420. painter->drawPoint(x, y);
  421.  
  422. it = active_polygons_y.cbegin();
  423. while (it != active_polygons_y.cend()) {
  424. double max_y = (*it).max_y();
  425. if (max_y <= real_y) {
  426. it = active_polygons_y.erase(it);
  427. } else {
  428. ++it;
  429. }
  430. }
  431. }
  432. }
  433. }
  434.  
  435. // проходимся по списку активных полигонов и смотрим, если максимальный х для полигона равен текущему, то убираем
  436. // его из списка активных (в список ждущих НЕ добавляем)
  437. it = active_polygons.cbegin();
  438. while (it != active_polygons.cend()) {
  439. double max_x = (*it).max_x();
  440. if (max_x <= real_x) {
  441. it = active_polygons.erase(it);
  442. } else {
  443. ++it;
  444. }
  445. }
  446. }
  447. QGraphicsPixmapItem* it = scene.addPixmap(*pixmap);
  448. it->setPos(-screen_size_x / 2, -screen_size_y / 2);
  449. }
  450.  
  451. void MainWindow::transform_points_for_zbuffer(std::list<Polygon>& transformed_polygons) {
  452. for (Model& m: manager.model_list) {
  453. for (Polygon& polygon : m.polygons) {
  454. for (unsigned i = 2; i < polygon.points.size(); ++i) {
  455. Polygon transformed_polygon;
  456. transformed_polygon.polygon_color = polygon.polygon_color;
  457.  
  458. transformed_polygon.points.push_back(polygon.points[0]);
  459. transformed_polygon.points.push_back(polygon.points[i - 1]);
  460. transformed_polygon.points.push_back(polygon.points[i]);
  461.  
  462. for (Point& point : transformed_polygon.points) {
  463. point = manager.camera.to_screen_3d(point);
  464. }
  465.  
  466. transformed_polygon.setup_flatness();
  467.  
  468. transformed_polygons.push_back(transformed_polygon);
  469. }
  470. }
  471. }
  472.  
  473.  
  474. for (Polygon& polygon : manager.ship.polygons) {
  475. if (polygon.polygon_color.alpha() != 0) {
  476. for (unsigned i = 2; i < polygon.points.size(); ++i) {
  477. Polygon transformed_polygon;
  478. transformed_polygon.polygon_color = polygon.polygon_color;
  479.  
  480. transformed_polygon.points.push_back(polygon.points[0]);
  481. transformed_polygon.points.push_back(polygon.points[i - 1]);
  482. transformed_polygon.points.push_back(polygon.points[i]);
  483.  
  484. for (Point& point : transformed_polygon.points) {
  485. point = manager.camera.to_screen_3d(point);
  486. }
  487.  
  488. transformed_polygon.setup_flatness();
  489. transformed_polygons.push_back(transformed_polygon);
  490. }
  491. }
  492. }
  493. }
  494.  
  495.  
  496. void MainWindow::on_DrawBox_toggled()
  497. {
  498. manager.ship.setColor();
  499. for (Model& m: manager.model_list) {
  500. if (m.insideShip(manager.ship) == true) {
  501. m.setColor(Qt::green);
  502. } else {
  503. m.setColor(Qt::red);
  504. }
  505. }
  506.  
  507. mydrawZBuffer();
  508. }
  509.  
  510. void MainWindow::on_ModelButton_clicked()
  511. {
  512. create_model();
  513. }
  514.  
  515. void MainWindow::on_ShipButton_clicked()
  516. {
  517. create_ship();
  518. }
  519.  
  520. void MainWindow::on_DrawBox_clicked()
  521. {
  522. if (ui->DrawBox->isChecked()) {
  523. mydrawZBuffer();
  524. } else {
  525. scene.clear();
  526. visualize_model();
  527. visualize_ship();
  528. }
  529. }
  530.  
  531. void MainWindow::updateSliderBPos(int value) {
  532. ui->label_2->setText(QString("%1").arg(value));
  533. move_speed = value;
  534. }
  535.  
  536. void MainWindow::on_modelList_currentRowChanged(int currentRow)
  537. {
  538. manager.active_object = &(manager.model_list[currentRow]);
  539. ui->graphicsView->setFocus();
  540.  
  541. ui->models->setChecked(true);
  542. }
  543.  
  544. void MainWindow::on_modelList_clicked(const QModelIndex &index)
  545. {
  546. manager.active_object = &(manager.model_list[index.row()]);
  547. ui->graphicsView->setFocus();
  548.  
  549. ui->models->setChecked(true);
  550. }
  551.  
  552. void MainWindow::on_models_toggled(bool checked)
  553. {
  554. if (checked) {
  555. if (manager.model_list.empty()) {
  556. manager.active_object = nullptr;
  557. } else {
  558. manager.active_object = &(manager.model_list[ui->modelList->currentRow()]);
  559. }
  560. }
  561. }
  562.  
  563. bool MainWindow::able_to_move(Model &new_model) {
  564. for (int i = 0; i < manager.model_list.size(); i++) {
  565. if (i != ui->modelList->currentRow()) {
  566. for (const Polygon& new_pol: new_model.polygons) {
  567. for (const Point& new_p: new_pol.points) {
  568. for (const Polygon& pol: manager.model_list[i].polygons) {
  569. for (const Point& p : pol.points) {
  570. if (new_pol.infront(new_p) == pol.infront(p)) {
  571. return false;
  572. }
  573. }
  574. }
  575. }
  576. }
  577. }
  578. }
  579. return true;
  580. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement