#include "drone_controller.hh" #include "opengl_widget.hh" #include #include DroneController::DroneController(const QJsonObject &json) :framerate(json["framerate"].toInt()) { QJsonArray ja = json["drones"].toArray(); drones.reserve(ja.size()); for (const QJsonValue &o : ja) { drones.append(Drone(o.toObject())); } for (const Drone &d : drones) { for (const Waypoint &wp : d.getWaypoints()) { if (wp.frame > duration) duration = wp.frame; } } OpenGLWidget::instance->makeCurrent(); QOpenGLTexture *ground_tex = new QOpenGLTexture(QImage(":/img/ground.jpg").mirrored()); ground_tex->setMagnificationFilter(QOpenGLTexture::LinearMipMapLinear); ground_tex->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); ground_tex->setWrapMode(QOpenGLTexture::MirroredRepeat); OpenGLMesh *ground = new OpenGLMesh({ -1000, 0, -1000, 0, 1000, 0, 0, 0, 1000, 0, -1000, 0, 1000, 0, 1000, 0, -1000, 0, 1000, 0, 1000, 0, 0, 1000, 1000, 0, -1000, 0, 1000, 0, 1000, 0, -1000, 0, 1000, 0, 1000, 0, 0, 1000, 1000, 0, 1000, 0, 1000, 0, 1000, 1000, }, ground_tex); OpenGLWidget::instance->meshes.append(*ground); OpenGLWidget::instance->doneCurrent(); connect(&timer, &QTimer::timeout, this, &DroneController::step); } int DroneController::getDuration() const { return duration; } void DroneController::step() { for (Drone d : drones) { d.setTo(frame); } OpenGLWidget::instance->update(); emit frameChanged(frame); if (frame == duration) { pause(); } else { frame++; } } void DroneController::play() { if (!paused) return; paused = false; timer.start(1000. / framerate); emit playing(); } void DroneController::pause() { if (paused) return; paused = true; timer.stop(); emit pausing(); } void DroneController::suspend() { if (!paused) { pause(); paused = false; } } void DroneController::resume() { if (!paused) { paused = true; play(); } } void DroneController::seek(int frame) { if (this->frame == frame) return; this->frame = frame; step(); } void DroneController::computeCollisions(double sphere_radius) { double sqDist = sphere_radius * sphere_radius * 2; for (int i = 0; i < duration; i++) { for (Drone &a : drones) { a.setTo(i); for (Drone &b : drones) { b.setTo(i); if (&a == &b) continue; if (collides(a, b, sqDist)) { emit collision(a.getId(), b.getId(), i); } } } } seek(frame); } bool DroneController::collides(const Drone &a, const Drone &b, double sqDist) { return (b.getPos() - a.getPos()).lengthSquared() < sqDist; }