/
wmigor
/
z-plane
Обзор
Документация
Войти
/
wmigor
/
z-plane
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
app/src/AircraftDebugView.cpp
290 строк
9 KB
wmigor
сохранение/загрузка
7 часов назад
7 часов назад
81be381
Код
Авторство
О чём код?
#include "AircraftDebugView.h" #include "converters.h" #include "Wheel.h" #include "WheelCallback.h" #include <osg/Geometry> #include <osg/ShapeDrawable> #include <osg/PositionAttitudeTransform> #include <asim/Constants.h> using namespace asim; AircraftDebugView::AircraftDebugView(Aircraft *aircraft): osg::MatrixTransform(), _aircraft(aircraft) { _gizmo = new AircraftGizmo(aircraft); _debugView = createDebugView(); addChild(_debugView); setUpdateCallback(_aircraft); createWheels(); for (auto thruster : aircraft->getPhysics()->getThrusters()) { auto propeller = dynamic_cast<Propeller *>(thruster); if (propeller != NULL) addChild(createPropellerDebugView(propeller)); } createFuselages(); } void AircraftDebugView::switchMode() { _mode = (_mode + 1) % 3; removeChild(_gizmo); removeChild(_debugView); if (_mode == 0 || _mode == 1) addChild(_gizmo); if (_mode == 0 || _mode == 2) addChild(_debugView); } osg::Geode *AircraftDebugView::createDebugView() { auto geode = new osg::Geode(); for (const auto wing : _aircraft->getPhysics()->getWings()) geode->addChild(createWingDebugView(wing)); return geode; } osg::Geode *AircraftDebugView::createWingDebugView(const asim::Wing *wing) { auto geode = new osg::Geode(); auto color = osg::Vec4(0.0, 1.0, 0.0, 1.0); auto controlSurfaceColor = osg::Vec4(0.8, 0.4, 0.0, 1.0); for (const auto &element : wing->getElements()) { const auto controlSurface = element.controlSurface; auto position = element.position; auto rotation = element.rotation; if (controlSurface.type == asim::ControlSurfaceType::None || controlSurface.fraction <= 0.0) { auto elementTransform = new osg::PositionAttitudeTransform(); elementTransform->setPosition(toVec3(position - rotation * asim::Constants::Forward * 0.25 * element.chord)); elementTransform->setAttitude(toQuat(rotation)); auto elementGeode = new osg::Geode(); auto elementView = new osg::Box(osg::Vec3d(0.0, 0.0, 0.0), element.length, 0.05, element.chord); auto drawable = new osg::ShapeDrawable(elementView); drawable->setUpdateCallback(new WingElementColorCallback(&element)); drawable->setColor(color); elementGeode->addDrawable(drawable); elementTransform->addChild(elementGeode); geode->addChild(elementTransform); } else { auto controlSurfaceChord = element.chord * controlSurface.fraction; auto elementChord = element.chord - controlSurfaceChord; auto elementPosition = asim::Constants::Forward * (controlSurfaceChord / 2.0); auto controlSurfacePosition = asim::Constants::Forward * (controlSurfaceChord * 0.5 - elementChord / 2.0); auto elementTransform = new osg::PositionAttitudeTransform(); elementTransform->setPosition(toVec3(position - rotation * asim::Constants::Forward * 0.25 * element.chord)); elementTransform->setAttitude(toQuat(rotation)); auto elementGeode = new osg::Geode(); auto elementView = new osg::Box(toVec3(elementPosition), element.length, 0.05, elementChord); auto drawable = new osg::ShapeDrawable(elementView); drawable->setUpdateCallback(new WingElementColorCallback(&element)); drawable->setColor(color); elementGeode->addDrawable(drawable); elementTransform->addChild(elementGeode); geode->addChild(elementTransform); auto controlSurfaceGeode = new osg::Geode(); auto controlSurfaceView = new osg::Box(osg::Vec3d(0.0, 0.0, controlSurfaceChord * 0.5), element.length, 0.05, controlSurfaceChord); drawable = new osg::ShapeDrawable(controlSurfaceView); drawable->setColor(controlSurfaceColor); controlSurfaceGeode->addDrawable(drawable); auto controlSurfaceTransform = new osg::PositionAttitudeTransform(); controlSurfaceTransform->setUpdateCallback(new ControlSurfaceCallback(&element, toVec3(asim::Constants::Right))); controlSurfaceTransform->setPosition(toVec3(controlSurfacePosition)); controlSurfaceTransform->addChild(controlSurfaceGeode); elementTransform->addChild(controlSurfaceTransform); } } return geode; } void AircraftDebugView::createWheels() { for (auto force :_aircraft->getBody()->getForces()) { const auto wheel = dynamic_cast<::Wheel *>(force); if (wheel == NULL) continue; const auto &config = wheel->getConfig(); auto cylinder = new osg::Cylinder(osg::Vec3(0.0, 0.0, 0.0), (float) config.radius, config.radius / 4); cylinder->setRotation(osg::Quat(3.14 / 2.0, osg::Vec3d(0.0, 1.0, 0.0))); auto drawable = new osg::ShapeDrawable(cylinder); drawable->setColor(osg::Vec4(1.0, 0.2, 0.2, 1.0)); auto root = new osg::PositionAttitudeTransform(); auto transform = new osg::PositionAttitudeTransform(); root->addChild(transform); root->setPosition(toVec3(config.position)); auto wheelGeode = new osg::Geode(); wheelGeode->addDrawable(drawable); transform->addUpdateCallback(new WheelCallback(wheel)); transform->addChild(wheelGeode); _debugView->addChild(root); } } osg::PositionAttitudeTransform *AircraftDebugView::createPropellerDebugView(const asim::Propeller *propeller) { auto root = new osg::PositionAttitudeTransform(); root->setUpdateCallback(new ThrusterCallback(propeller)); root->setPosition(toVec3(propeller->position)); root->setAttitude(toQuat(propeller->rotation)); auto bladeCount = propeller->getConfig().bladeCount; for (auto i = 0; i < bladeCount; i++) { auto bladeGeode = new osg::Geode(); auto bladeTranform = new osg::PositionAttitudeTransform(); bladeTranform->setAttitude(osg::Quat(i * osg::PI * 2.0 / bladeCount, toVec3(Constants::Forward))); bladeTranform->addChild(bladeGeode); root->addChild(bladeTranform); for (const auto &element : propeller->getElements()) { auto position = toVec3(asim::Constants::Right * element.radius); auto elementView = new osg::Box(position, element.length, element.chord, element.length * 0.1); elementView->setRotation(osg::Quat(element.pitch, toVec3(Constants::Right))); auto drawable = new osg::ShapeDrawable(elementView); drawable->setUpdateCallback(new PropellerElementColorCallback(&element)); drawable->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0)); bladeGeode->addDrawable(drawable); } } return root; } void AircraftDebugView::createFuselages() { auto geode = new osg::Geode(); auto color = osg::Vec4(1.0, 0.5, 0.0, 1.0); for (const auto &fuselage : _aircraft->getPhysics()->getFuselages()) { for (const auto &element : fuselage->getElements()) { auto elementView = new osg::Cylinder(toVec3(element.position), element.radius, element.length); auto drawable = new osg::ShapeDrawable(elementView); drawable->setColor(color); geode->addDrawable(drawable); } } addChild(geode); } ControlSurfaceCallback::ControlSurfaceCallback(const asim::Wing::Element *element, const osg::Vec3d &axis): _element(element), _axis(axis) { } void ControlSurfaceCallback::operator()(osg::Node *node, osg::NodeVisitor *nv) { auto transform = dynamic_cast<osg::PositionAttitudeTransform *>(node); if (transform != NULL) transform->setAttitude(osg::Quat(_element->airfoilWingData.flapDeflection, _axis)); traverse(node, nv); } ThrusterCallback::ThrusterCallback(const asim::Thruster *thruster): _thruster(thruster) { } void ThrusterCallback::operator()(osg::Node *node, osg::NodeVisitor *nv) { auto transform = dynamic_cast<osg::PositionAttitudeTransform *>(node); if (transform != NULL) { auto axis = toVec3(_thruster->rotation * Constants::Forward); auto rotation = transform->getAttitude(); auto delta = 1.0 / 60.0; auto angularVelocity = _thruster->getAngularVelocity(); auto rpm = angularVelocity * Constants::TO_RPM; auto minRpm = 10 * glm::pi<double>() * Constants::TO_RPM; if (rpm < minRpm) { auto angle = angularVelocity * delta; rotation *= osg::Quat(angle, axis); } else { auto deltaAngle = 2.0 * glm::pi<double>() / 8.0; auto speed = deltaAngle * (rpm - minRpm) / (2700.0 - minRpm)/ 0.25; rotation *= osg::Quat(deltaAngle + speed * delta, axis); } transform->setAttitude(rotation); } traverse(node, nv); } void ElementColorCallback::operator()(osg::Node *node, osg::NodeVisitor *nv) { auto drawable = dynamic_cast<osg::ShapeDrawable *>(node); if (drawable == NULL) { traverse(node, nv); return; } auto state = getState(); if (state != _state) { _state = state; if (state == 1) drawable->setColor(osg::Vec4(0.0, 1.0, 0.0, 1.0)); else if (state == 2) drawable->setColor(osg::Vec4(1.0, 0.5, 0.0, 1.0)); else if (state == 3) drawable->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0)); } traverse(node, nv); } WingElementColorCallback::WingElementColorCallback(const asim::Wing::Element *element): ElementColorCallback(), _element(element) { } int WingElementColorCallback::getState() const { auto stall = _element->stallFactor; if (stall <= 0.0) return 1; return stall < 1.0 ? 2 : 3; } PropellerElementColorCallback::PropellerElementColorCallback(const asim::Propeller::Element* element): ElementColorCallback(), _element(element) { } int PropellerElementColorCallback::getState() const { if (_element->stallFactor <= 0.0) return 1; return _element->stallFactor < 1.0 ? 2 : 3; }