/
wmigor
/
z-plane
Обзор
Документация
Войти
/
wmigor
/
z-plane
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
app/src/Hud.cpp
169 строк
6 KB
wmigor
Плавное управление мышкой
04 июн 2026, 23:00
Верифицирован
04 июн 2026, 23:00
43aa585
Код
Авторство
О чём код?
#include "Hud.h" #include <osg/Matrix> #include <osg/Geode> #include <asim/Constants.h> #include <format> #include <glm/ext.hpp> Hud::Hud(Aircraft* aircraft): _aircraft(aircraft) { osg::Matrix matrix; auto width = 1280; auto height = 720; matrix.makeOrtho2D(-width / 2, width / 2, -height / 2, height / 2); setProjectionMatrix(matrix); setViewMatrix(osg::Matrix::identity()); setRenderOrder(osg::Camera::POST_RENDER); setClearMask(GL_DEPTH_BUFFER_BIT); setReferenceFrame(osg::Transform::ABSOLUTE_RF); getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); setAllowEventFocus(false); _text = new osgText::Text(); _text->setCharacterSize(16.0); _text->setAxisAlignment(osgText::Text::SCREEN); _text->setPosition(osg::Vec3(10.0 - width / 2, height / 2 - 20.0, 0.0)); _text->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0)); _text->setDataVariance(osg::Object::DYNAMIC); auto info = new osgText::Text(); info->setCharacterSize(16.0); info->setAxisAlignment(osgText::Text::SCREEN); info->setPosition(osg::Vec3(width / 2 - 200.0, height / 2 - 20.0, 0.0)); info->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0)); info->setText("Aileros: A/D/Mouse\nElevator: W/S/Mouse\nRudder: Q/E\nFlaps: I/K\nBrake: Space\nThrottle: +/-"); osg::Geode* geode = new osg::Geode(); geode->addDrawable(_text); geode->addDrawable(info); addChild(geode); setUpdateCallback(new HudUpdateCallback()); createControl(150.0, osg::Vec3(1.0, 0.0, 0.0), osg::Vec3(0.0, 300.0, 0.0), asim::ControlSurfaceType::Aileron); createControl(150.0, osg::Vec3(0.0, -1.0, 0.0), osg::Vec3(100.0, 225.0, 0.0), asim::ControlSurfaceType::Elevator); createControl(150.0, osg::Vec3(-1.0, 0.0, 0.0), osg::Vec3(0.0, 150.0, 0.0), asim::ControlSurfaceType::Rudder); } void Hud::update() { auto body = _aircraft->getBody(); auto physics = _aircraft->getPhysics(); auto forward = body->rotation * asim::Constants::Forward; auto speed = glm::dot(forward, body->linearVelocity); auto wind = -(glm::inverse(body->rotation) * body->linearVelocity); auto angleOfAttack = glm::degrees(glm::atan2(wind.y, wind.z)); auto rpm = physics->getThrusters().size() > 0 ? (int) (physics->getThrusters()[0]->getEngine()->angularVelocity * asim::Constants::TO_RPM) : 0; _text->setText(std::format("F speed: {:.0f} km/h {:.0f} kn\nV speed: {:.1f} m/s\nAlttitude: {:.0f} m\nAoA: {:.1f}\nThrottle: {:.0f}%\nRPM: {}", speed * 3.6, speed * 1.94384, body->linearVelocity.y, body->position.y, angleOfAttack, _aircraft->input.throttle * 100.0, rpm)); } void Hud::createControl(double size, const osg::Vec3 &axis, const osg::Vec3 &position, asim::ControlSurfaceType type) { auto transform = new osg::PositionAttitudeTransform(); transform->setPosition(position); auto geode = new osg::Geode(); auto geometry = new osg::Geometry(); auto vertices = new osg::Vec3Array(); auto cross = axis ^ osg::Vec3(0.0, 0.0, 1.0); auto tip = axis * size * 0.5; auto crossSize = 5.0; vertices->push_back(-tip); vertices->push_back(tip); vertices->push_back(osg::Vec3(0.0, 0.0, 0.0)); vertices->push_back(cross * crossSize); vertices->push_back(-tip); vertices->push_back(cross * crossSize - tip); vertices->push_back(tip); vertices->push_back(cross * crossSize + tip); auto colors = new osg::Vec4Array(); colors->push_back(osg::Vec4(0.0, 1.0, 0.0, 1.0)); geometry->setVertexArray(vertices); geometry->setColorArray(colors, osg::Array::BIND_OVERALL); geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINES, 0, vertices->size())); geode->addDrawable(geometry); geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); transform->addChild(geode); addChild(transform); auto indicator = createIndicator(size / 10.0, axis, type); indicator->setUpdateCallback(new IndicatorUpdateCallback(_aircraft, size, axis, type)); transform->addChild(indicator); } osg::PositionAttitudeTransform *Hud::createIndicator(double size, const osg::Vec3 &axis, asim::ControlSurfaceType type) { auto transform = new osg::PositionAttitudeTransform(); auto geode = new osg::Geode(); auto geometry = new osg::Geometry(); auto vertices = new osg::Vec3Array(); auto cross = axis ^ osg::Vec3(0.0, 0.0, 1.0); auto start = -cross * size * 0.25; vertices->push_back(osg::Vec3(0.0, 0.0, 0.0)); vertices->push_back(start); vertices->push_back(start); vertices->push_back(start - (cross + axis * 0.5) * size); vertices->push_back(vertices->at(vertices->size() - 1)); vertices->push_back(start - (cross - axis * 0.5) * size); vertices->push_back(vertices->at(vertices->size() - 1)); vertices->push_back(start); auto colors = new osg::Vec4Array(); colors->push_back(osg::Vec4(0.0, 1.0, 0.0, 1.0)); geometry->setVertexArray(vertices); geometry->setColorArray(colors, osg::Array::BIND_OVERALL); geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINES, 0, vertices->size())); geode->addDrawable(geometry); geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); transform->addChild(geode); return transform; } void HudUpdateCallback::operator()(osg::Node *node, osg::NodeVisitor *nv) { auto hud = dynamic_cast<Hud *>(node); if (hud != NULL) hud->update(); traverse(node, nv); } IndicatorUpdateCallback::IndicatorUpdateCallback( Aircraft *aircraft, double size, const osg::Vec3 &axis, asim::ControlSurfaceType type): _aircraft(aircraft), _size(size), _axis(axis), _type(type) { } void IndicatorUpdateCallback::operator()(osg::Node *node, osg::NodeVisitor *nv) { auto transform = dynamic_cast<osg::PositionAttitudeTransform *>(node); if (transform != NULL) { auto value = _type == asim::ControlSurfaceType::Aileron ? -_aircraft->input.ailerons : _type == asim::ControlSurfaceType::Rudder ? -_aircraft->input.rudder : -_aircraft->input.elevator; transform->setPosition(_axis * _size * value * 0.5); } traverse(node, nv); }