add basic collision detection
This commit is contained in:
parent
87f8c49cff
commit
861d505606
@ -12,9 +12,11 @@ SOURCES += src/opengl_mesh.cc
|
|||||||
SOURCES += src/opengl_widget.cc
|
SOURCES += src/opengl_widget.cc
|
||||||
SOURCES += src/drone_controller.cc
|
SOURCES += src/drone_controller.cc
|
||||||
SOURCES += src/load_obj.cc
|
SOURCES += src/load_obj.cc
|
||||||
|
SOURCES += src/settings_pane.cc
|
||||||
|
|
||||||
HEADERS += src/main_window.hh
|
HEADERS += src/main_window.hh
|
||||||
HEADERS += src/opengl_mesh.hh
|
HEADERS += src/opengl_mesh.hh
|
||||||
HEADERS += src/opengl_widget.hh
|
HEADERS += src/opengl_widget.hh
|
||||||
HEADERS += src/drone_controller.hh
|
HEADERS += src/drone_controller.hh
|
||||||
HEADERS += src/load_obj.hh
|
HEADERS += src/load_obj.hh
|
||||||
|
HEADERS += src/settings_pane.hh
|
||||||
|
@ -22,7 +22,8 @@ Waypoint::Waypoint(const QJsonObject &json)
|
|||||||
bool Drone::mesh_initialized = false;
|
bool Drone::mesh_initialized = false;
|
||||||
OpenGLMesh *Drone::mesh = nullptr;
|
OpenGLMesh *Drone::mesh = nullptr;
|
||||||
|
|
||||||
Drone::Drone() {
|
Drone::Drone(int id)
|
||||||
|
:id(id) {
|
||||||
if (!mesh_initialized) {
|
if (!mesh_initialized) {
|
||||||
QVector<GLfloat> verts = load_obj(":/mdl/dji600.obj", LOAD_OBJ_NORMALS | LOAD_OBJ_UVS);
|
QVector<GLfloat> verts = load_obj(":/mdl/dji600.obj", LOAD_OBJ_NORMALS | LOAD_OBJ_UVS);
|
||||||
QOpenGLTexture *texture = new QOpenGLTexture(QImage(":/img/dji600.jpg").mirrored());
|
QOpenGLTexture *texture = new QOpenGLTexture(QImage(":/img/dji600.jpg").mirrored());
|
||||||
@ -35,7 +36,7 @@ Drone::Drone() {
|
|||||||
|
|
||||||
|
|
||||||
Drone::Drone(const QJsonObject &json)
|
Drone::Drone(const QJsonObject &json)
|
||||||
:Drone() {
|
:Drone(json["id"].toInt()) {
|
||||||
QJsonArray ja = json["waypoints"].toArray();
|
QJsonArray ja = json["waypoints"].toArray();
|
||||||
waypoints.reserve(ja.size());
|
waypoints.reserve(ja.size());
|
||||||
for (const QJsonValue &o : ja) {
|
for (const QJsonValue &o : ja) {
|
||||||
@ -65,12 +66,23 @@ void Drone::setTo(int frame) {
|
|||||||
OpenGLMesh &mesh = OpenGLWidget::instance->meshes[mesh_id];
|
OpenGLMesh &mesh = OpenGLWidget::instance->meshes[mesh_id];
|
||||||
mesh.mat = QMatrix4x4();
|
mesh.mat = QMatrix4x4();
|
||||||
if (next > -1 && prev == -1) {
|
if (next > -1 && prev == -1) {
|
||||||
mesh.mat.translate(next_wp->pos);
|
pos = next_wp->pos;
|
||||||
} else if (prev > -1 && next == -1) {
|
} else if (prev > -1 && next == -1) {
|
||||||
mesh.mat.translate(prev_wp->pos);
|
pos = prev_wp->pos;
|
||||||
} else {
|
} else {
|
||||||
mesh.mat.translate(lerp(prev_wp->pos, next_wp->pos, (double) (frame-prev) / (next-prev)));
|
pos = lerp(prev_wp->pos, next_wp->pos, (double) (frame-prev) / (next-prev));
|
||||||
}
|
}
|
||||||
|
mesh.mat.translate(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QVector3D Drone::getPos() const {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Drone::getId() const {
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -164,3 +176,23 @@ void DroneController::seek(int frame) {
|
|||||||
this->frame = frame;
|
this->frame = frame;
|
||||||
step();
|
step();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DroneController::computeCollisions(double sphere_radius) {
|
||||||
|
double sqDist = sphere_radius * sphere_radius * 2;
|
||||||
|
for (int i = 0; i < duration; i++) {
|
||||||
|
for (const Drone &a : drones) {
|
||||||
|
for (const Drone &b : drones) {
|
||||||
|
if (&a == &b) continue;
|
||||||
|
if (collides(a, b, sqDist)) {
|
||||||
|
emit collision(a.getId(), b.getId(), frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DroneController::collides(const Drone &a, const Drone &b, double sqDist) {
|
||||||
|
return (b.getPos() - a.getPos()).lengthSquared() < sqDist;
|
||||||
|
}
|
||||||
|
@ -29,12 +29,16 @@ class Drone {
|
|||||||
|
|
||||||
QVector<Waypoint> waypoints;
|
QVector<Waypoint> waypoints;
|
||||||
int mesh_id;
|
int mesh_id;
|
||||||
|
QVector3D pos;
|
||||||
|
int id;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Drone();
|
Drone(int id);
|
||||||
Drone(const QJsonObject &json);
|
Drone(const QJsonObject &json);
|
||||||
const QVector<Waypoint> getWaypoints() const;
|
const QVector<Waypoint> getWaypoints() const;
|
||||||
void setTo(int frame);
|
void setTo(int frame);
|
||||||
|
QVector3D getPos() const;
|
||||||
|
int getId() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -48,6 +52,8 @@ class DroneController : public QObject {
|
|||||||
QTimer timer;
|
QTimer timer;
|
||||||
bool paused = true;
|
bool paused = true;
|
||||||
|
|
||||||
|
static bool collides(const Drone &a, const Drone &b, double radius);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DroneController(const QJsonObject &json);
|
DroneController(const QJsonObject &json);
|
||||||
int getDuration() const;
|
int getDuration() const;
|
||||||
@ -56,6 +62,7 @@ signals:
|
|||||||
void frameChanged(int frame);
|
void frameChanged(int frame);
|
||||||
void playing();
|
void playing();
|
||||||
void pausing();
|
void pausing();
|
||||||
|
void collision(int idA, int idB, int frame);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void step();
|
void step();
|
||||||
@ -66,6 +73,7 @@ public slots:
|
|||||||
void suspend();
|
void suspend();
|
||||||
void resume();
|
void resume();
|
||||||
void seek(int frame);
|
void seek(int frame);
|
||||||
|
void computeCollisions(double sphere_radius);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
|
#include <QDockWidget>
|
||||||
|
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent) {
|
MainWindow::MainWindow(QWidget *parent) {
|
||||||
@ -25,6 +26,12 @@ MainWindow::MainWindow(QWidget *parent) {
|
|||||||
slider = new QSlider(Qt::Horizontal);
|
slider = new QSlider(Qt::Horizontal);
|
||||||
bottom_tb.addWidget(slider);
|
bottom_tb.addWidget(slider);
|
||||||
slider->setEnabled(false);
|
slider->setEnabled(false);
|
||||||
|
|
||||||
|
QDockWidget *dock = new QDockWidget("Outils", this);
|
||||||
|
dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||||
|
settings_pane = new SettingsPane();
|
||||||
|
dock->setWidget(settings_pane);
|
||||||
|
addDockWidget(Qt::RightDockWidgetArea, dock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -65,6 +72,8 @@ void MainWindow::open(const QString &path) {
|
|||||||
connect(slider, &QSlider::sliderReleased, dc, &DroneController::resume);
|
connect(slider, &QSlider::sliderReleased, dc, &DroneController::resume);
|
||||||
connect(slider, &QSlider::valueChanged, dc, &DroneController::seek);
|
connect(slider, &QSlider::valueChanged, dc, &DroneController::seek);
|
||||||
connect(dc, &DroneController::frameChanged, slider, &QSlider::setValue);
|
connect(dc, &DroneController::frameChanged, slider, &QSlider::setValue);
|
||||||
|
connect(dc, &DroneController::collision, settings_pane, &SettingsPane::addCollision);
|
||||||
|
dc->computeCollisions(10);
|
||||||
pause();
|
pause();
|
||||||
slider->setEnabled(true);
|
slider->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "opengl_widget.hh"
|
#include "opengl_widget.hh"
|
||||||
#include "drone_controller.hh"
|
#include "drone_controller.hh"
|
||||||
|
#include "settings_pane.hh"
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
@ -20,6 +21,7 @@ class MainWindow : public QMainWindow {
|
|||||||
QAction *open_action;
|
QAction *open_action;
|
||||||
QAction *playpause_action;
|
QAction *playpause_action;
|
||||||
QSlider *slider;
|
QSlider *slider;
|
||||||
|
SettingsPane *settings_pane;
|
||||||
DroneController *dc = nullptr;
|
DroneController *dc = nullptr;
|
||||||
void play();
|
void play();
|
||||||
void pause();
|
void pause();
|
||||||
|
44
src/settings_pane.cc
Normal file
44
src/settings_pane.cc
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include "settings_pane.hh"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QFormLayout>
|
||||||
|
|
||||||
|
|
||||||
|
SettingsPane::SettingsPane(QWidget *parent)
|
||||||
|
:QWidget(parent) {
|
||||||
|
QDoubleSpinBox *sphere_radius = new QDoubleSpinBox();
|
||||||
|
QCheckBox *show_trajectories = new QCheckBox();
|
||||||
|
QCheckBox *show_support_lines = new QCheckBox();
|
||||||
|
collisions = new QListWidget();
|
||||||
|
|
||||||
|
connect(sphere_radius, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
|
||||||
|
this, &SettingsPane::sphereRadiusChanged);
|
||||||
|
connect(show_trajectories, &QCheckBox::stateChanged,
|
||||||
|
this, &SettingsPane::toggledTrajectories);
|
||||||
|
connect(show_support_lines, &QCheckBox::stateChanged,
|
||||||
|
this, &SettingsPane::toggledSupportLines);
|
||||||
|
|
||||||
|
QFormLayout *layout = new QFormLayout;
|
||||||
|
layout->addRow("Taille de la sphère de collision", sphere_radius);
|
||||||
|
layout->addRow("Afficher les trajectoires", show_trajectories);
|
||||||
|
layout->addRow("Afficher les lignes de support", show_support_lines);
|
||||||
|
layout->addRow(collisions);
|
||||||
|
setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SettingsPane::addCollision(int idA, int idB, int frame) {
|
||||||
|
QListWidgetItem *item = new QListWidgetItem(QString::number(frame) + ": "
|
||||||
|
+ QString::number(idA) + " / " + QString::number(idB));
|
||||||
|
item->setFlags(Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
|
||||||
|
collisions->addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SettingsPane::clearCollisions() {
|
||||||
|
QListWidgetItem *item;
|
||||||
|
while ((item = collisions->takeItem(0)) != nullptr) {
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
}
|
27
src/settings_pane.hh
Normal file
27
src/settings_pane.hh
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef SETTINGS_PANE_HH
|
||||||
|
#define SETTINGS_PANE_HH
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QListWidget>
|
||||||
|
|
||||||
|
|
||||||
|
class SettingsPane : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
QListWidget *collisions = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SettingsPane(QWidget *parent=nullptr);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void addCollision(int idA, int idB, int frame);
|
||||||
|
void clearCollisions();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void sphereRadiusChanged(double sqRadius);
|
||||||
|
void toggledTrajectories(int shown);
|
||||||
|
void toggledSupportLines(int shown);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user