152 lines
4.9 KiB
C++
152 lines
4.9 KiB
C++
#pragma once
|
|
|
|
|
|
#include <cstdlib>
|
|
#include <cmath>
|
|
#include <numbers>
|
|
#include <QObject>
|
|
#include <QMutex>
|
|
#include <QElapsedTimer>
|
|
#include <bgtu/computer_graphics_lab_work/renderer_api/point.hpp>
|
|
#include <bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp>
|
|
#include <bgtu/computer_graphics_lab_work/utilities/matrix.hpp>
|
|
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
|
|
#include <bgtu/computer_graphics_lab_work/utilities/zoomed_voxel_painter.hpp>
|
|
|
|
|
|
namespace BGTU::ComputerGraphicsLabWork::Lab1 {
|
|
class _Lab1SpriteData_Provider;
|
|
|
|
|
|
struct Lab1SpriteData {
|
|
public:
|
|
struct ShapeData {
|
|
public:
|
|
double rotation_radians;
|
|
RendererApi::PointI<2>::component_t radius;
|
|
RendererApi::PointI<2>::component_t diameter;
|
|
|
|
private:
|
|
|
|
[[nodiscard]] inline RendererApi::PointI<2> _rotated(RendererApi::PointI<2>::component_t custom_radius, double base_angle_radians, double angle_degrees) const {
|
|
double angle_radians = angle_degrees * (std::numbers::pi_v<double> / 180);
|
|
return {
|
|
(RendererApi::PointI<2>::component_t) (std::cos(base_angle_radians + angle_radians) * custom_radius),
|
|
(RendererApi::PointI<2>::component_t) (std::sin(base_angle_radians + angle_radians) * custom_radius),
|
|
};
|
|
}
|
|
|
|
public:
|
|
|
|
[[nodiscard]] inline RendererApi::PointI<2> static_rotated(RendererApi::PointI<2>::component_t custom_radius, double angle_degrees) const {
|
|
return this->_rotated(custom_radius, 0, angle_degrees);
|
|
}
|
|
|
|
[[nodiscard]] inline RendererApi::PointI<2> pos_rotated(RendererApi::PointI<2>::component_t custom_radius, double angle_degrees) const {
|
|
return this->_rotated(custom_radius, this->rotation_radians, angle_degrees);
|
|
}
|
|
|
|
[[nodiscard]] inline RendererApi::PointI<2> neg_rotated(RendererApi::PointI<2>::component_t custom_radius, double angle_degrees) const {
|
|
return this->_rotated(custom_radius, -this->rotation_radians, angle_degrees);
|
|
|
|
}
|
|
};
|
|
|
|
RendererApi::PointI<2> central_pixel_tl;
|
|
std::size_t pixel_size;
|
|
bool show_grid;
|
|
ShapeData shape_data;
|
|
RendererApi::Sprite<ShapeData, Utilities::ZoomedVoxelPainter<Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl>> *const *sub_sprites;
|
|
std::size_t sub_sprites_count;
|
|
|
|
using Provider = _Lab1SpriteData_Provider;
|
|
|
|
};
|
|
|
|
class _Lab1SpriteData_Provider : public QObject, public RendererApi::Sprite<Lab1SpriteData, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl>::SpriteDataProvider {
|
|
Q_OBJECT
|
|
private:
|
|
QMutex sync;
|
|
QElapsedTimer time;
|
|
|
|
std::size_t pixel_size;
|
|
double radians_per_second;
|
|
bool show_grid;
|
|
RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t w, h;
|
|
RendererApi::Sprite<Lab1SpriteData::ShapeData, Utilities::ZoomedVoxelPainter<Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl>> *const *sub_sprites;
|
|
std::size_t sub_sprites_count;
|
|
|
|
public:
|
|
explicit _Lab1SpriteData_Provider(double radians_per_second) :
|
|
sync{}, time{},
|
|
pixel_size{1}, radians_per_second{radians_per_second}, show_grid{false},
|
|
w{0}, h{0},
|
|
sub_sprites{nullptr}, sub_sprites_count{0} {}
|
|
|
|
Lab1SpriteData get_sprite_data() override {
|
|
this->sync.lock();
|
|
RendererApi::PointI<2>::component_t radius = (((this->w < this->h) ? this->w : this->h) * 7 / 16) / this->pixel_size;
|
|
Lab1SpriteData cached{
|
|
.central_pixel_tl = (RendererApi::PointI<2>) (RendererApi::PointF<2>(this->w, this->h) / 2.0 - RendererApi::PointF<2>(this->pixel_size, this->pixel_size) / 2.0),
|
|
.pixel_size = this->pixel_size,
|
|
.show_grid = this->show_grid,
|
|
.shape_data = {
|
|
.rotation_radians = std::fmod(this->time.elapsed() / 1000.0 * radians_per_second, std::numbers::pi * 2),
|
|
.radius = radius,
|
|
.diameter = radius * 2
|
|
},
|
|
.sub_sprites = this->sub_sprites,
|
|
.sub_sprites_count = this->sub_sprites_count,
|
|
};
|
|
this->sync.unlock();
|
|
return cached;
|
|
}
|
|
|
|
public slots:
|
|
|
|
void set_pixel_size(std::size_t s) {
|
|
this->sync.lock();
|
|
this->pixel_size = s;
|
|
this->sync.unlock();
|
|
}
|
|
|
|
void increase_pixel_size() {
|
|
this->sync.lock();
|
|
this->pixel_size++;
|
|
this->sync.unlock();
|
|
}
|
|
|
|
void decrease_pixel_size() {
|
|
this->sync.lock();
|
|
if (this->pixel_size > 1)
|
|
this->pixel_size--;
|
|
this->sync.unlock();
|
|
}
|
|
|
|
void set_frame_size(RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t ww, RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t hh) {
|
|
this->sync.lock();
|
|
this->w = ww;
|
|
this->h = hh;
|
|
this->sync.unlock();
|
|
}
|
|
|
|
void set_show_grid(bool f) {
|
|
this->sync.lock();
|
|
this->show_grid = f;
|
|
this->sync.unlock();
|
|
}
|
|
|
|
void invert_show_grid() {
|
|
this->sync.lock();
|
|
this->show_grid = !this->show_grid;
|
|
this->sync.unlock();
|
|
}
|
|
|
|
void set_sub_sprites(RendererApi::Sprite<Lab1SpriteData::ShapeData, Utilities::ZoomedVoxelPainter<Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl>> *const *s, std::size_t c) {
|
|
this->sync.lock();
|
|
this->sub_sprites = s;
|
|
this->sub_sprites_count = c;
|
|
this->sync.unlock();
|
|
}
|
|
};
|
|
} |