Marsik Posted August 21, 2023 Posted August 21, 2023 (edited) Здравствуйте, при создании WidgetManipulator, часть окна становиться черной. Ниже скрин до и после добавления WidgetManipulator, а также код. Заранее спасибо. int numberDisplays = Displays::getNum(); if (numberDisplays > 2) numberDisplays = 2; Math::ivec2 positionD1; Math::ivec2 resolutionD1; Math::ivec2 positionD0 = Displays::getPosition(0); Math::ivec2 resolutionD0 = Displays::getResolution(0); if (numberDisplays < 2) { resolutionD0.x /= 2; resolutionD1 = resolutionD0; positionD1.x = positionD0.x + resolutionD1.x; } else { positionD1 = Displays::getPosition(1); resolutionD1 = Displays::getResolution(1); } EngineWindowViewportPtr window_0 = nullptr; if (WindowManager::getNumWindows() > 1) window_0 = checked_ptr_cast<EngineWindowViewport>(WindowManager::getWindow(1)); else window_0 = EngineWindowViewport::create(resolutionD1); auto updateWindow = [this](EngineWindowViewportPtr window, Math::ivec2 position, Math::ivec2 resolution) { if (!window) return; window->setBordersEnabled(false); window->setPosition(position); window->setSize(resolution); window->show(); }; EngineWindowViewportPtr main_window = WindowManager::getMainWindow(); updateWindow(main_window, positionD0, resolutionD0); updateWindow(window_0, positionD1, resolutionD1); EngineWindowGroupPtr groupWindow = WindowManager::stackWindows(main_window, window_0, EngineWindowGroup::GROUP_TYPE_HORIZONTAL); groupWindow->setTitleBarEnabled(false); groupWindow->setBordersEnabled(false); if (numberDisplays > 1) groupWindow->setPosition(positionD1); else groupWindow->setPosition(positionD0); auto resolution = resolutionD0; resolution.x += resolutionD1.x; groupWindow->setResizable(true); groupWindow->setSize(resolution); groupWindow->setResizable(false); auto gui = groupWindow->getSelfGui(); auto window = WidgetWindow::create(gui, "Панель Управления", 210, 135); window->setMoveable(false); window->setPosition(0, 20); auto btExit = WidgetButton::create(gui, "Выход"); btExit->setToolTip("Выйти"); btExit->setWidth(60); btExit->setPosition(305, 10); auto mTranslator = WidgetManipulatorTranslator::create(gui); gui->addChild(window, Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED); window->addChild(btExit, Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED); gui->addChild(mTranslator); btExit->addCallback(Gui::CLICKED, (CallbackBase *)MakeCallback([]() { Engine::get()->quit();})); Edited August 21, 2023 by Marsik
karpych11 Posted August 21, 2023 Posted August 21, 2023 Здравствуйте. Тут проблема в том, что виджеты добавляются напрямую в gui, который отвечает за лейаут группы. Если посмотреть на api для EngineWindowGroup, то в нём нет методов для добавления дочерних виджетов. Такое можно делать только для EngineWindowViewport. Чтобы исправить такое поведение, нужно добавить все виджеты в какое-то одно из окон. К примеру, main_window. Т.к. оно вложенное, то для получения gui используем getGui(), а не getSelfGui(). В этом случае получим gui, который отвечает за группу в самом начале иерархии. Используем этот gui для создания виджетов, а после добавляем их в окно: auto gui = main_window->getGui(); auto window = WidgetWindow::create(gui, "Панель Управления", 210, 135); window->setMoveable(false); window->setPosition(0, 20); auto btExit = WidgetButton::create(gui, "Выход"); btExit->setToolTip("Выйти"); btExit->setWidth(60); btExit->setPosition(305, 10); auto mTranslator = WidgetManipulatorTranslator::create(gui); main_window->addChild(window, Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED); window->addChild(btExit, Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED); main_window->addChild(mTranslator);
Marsik Posted August 22, 2023 Author Posted August 22, 2023 (edited) @karpych11 Спасибо. Но тогда делая дальше по инструкции Using Manipulators to Transform Objects, у меня получается манипулятор в стороне от объекта. int numberDisplays = Displays::getNum(); if (numberDisplays > 2) numberDisplays = 2; Math::ivec2 positionD1; Math::ivec2 resolutionD1; Math::ivec2 positionD0 = Displays::getPosition(0); Math::ivec2 resolutionD0 = Displays::getResolution(0); if (numberDisplays < 2) { resolutionD0.x /= 2; resolutionD1 = resolutionD0; positionD1.x = positionD0.x + resolutionD1.x; } else { positionD1 = Displays::getPosition(1); resolutionD1 = Displays::getResolution(1); } EngineWindowViewportPtr window_0 = nullptr; if (WindowManager::getNumWindows() > 1) window_0 = checked_ptr_cast<EngineWindowViewport>(WindowManager::getWindow(1)); else window_0 = EngineWindowViewport::create(resolutionD1); auto updateWindow = [this](EngineWindowViewportPtr window, Math::ivec2 position, Math::ivec2 resolution) { if (!window) return; window->setBordersEnabled(false); window->setPosition(position); window->setSize(resolution); window->show(); }; EngineWindowViewportPtr main_window = WindowManager::getMainWindow(); updateWindow(main_window, positionD0, resolutionD0); updateWindow(window_0, positionD1, resolutionD1); EngineWindowGroupPtr groupWindow = WindowManager::stackWindows(main_window, window_0, EngineWindowGroup::GROUP_TYPE_HORIZONTAL); groupWindow->setTitleBarEnabled(false); groupWindow->setBordersEnabled(false); if (numberDisplays > 1) groupWindow->setPosition(positionD1); else groupWindow->setPosition(positionD0); auto resolution = resolutionD0; resolution.x += resolutionD1.x; groupWindow->setResizable(true); groupWindow->setSize(resolution); groupWindow->setResizable(false); auto gui = main_window->getGui(); auto window = WidgetWindow::create(gui, "Панель Управления", 210, 135); window->setMoveable(false); window->setPosition(0, 20); auto btExit = WidgetButton::create(gui, "Выход"); btExit->setToolTip("Выйти из тренировки"); btExit->setWidth(60); btExit->setPosition(305, 10); auto mTranslator = WidgetManipulatorTranslator::create(gui); main_window->addChild(window, Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED); window->addChild(btExit, Gui::ALIGN_OVERLAP | Gui::ALIGN_FIXED); main_window->addChild(mTranslator); btExit->addCallback(Gui::CLICKED, (CallbackBase*)MakeCallback([]() { Engine::get()->quit(); })); auto player = Game::getPlayer(); mTranslator->setTransform(test_node->getWorldTransform()); mTranslator->setProjection(player->getProjection()); mTranslator->setModelview(player->getCamera()->getModelview()); Edited August 22, 2023 by Marsik
silent Posted August 23, 2023 Posted August 23, 2023 К сожалению, WidgetManipulator был написан давно и без учета многооконности, поэтому он берет не тот размер окна (общий размер всех окон, а не только текущего). Поэтому пока его не получится использовать в многооконных приложениях на текущий момент. Поправим в будущих версиях SDK (скорее всего даже в 2.18). How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN
dosma Posted June 17, 2024 Posted June 17, 2024 Здравствуйте! Попробуйте воспользоваться этим примером: #include "AppWorldLogic.h" #include <UnigineWindowManager.h> #include <UnigineGame.h> #include <UniginePrimitives.h> using namespace Unigine; using namespace Math; // World logic, it takes effect only when the world is loaded. // These methods are called right after corresponding world script's (UnigineScript) methods. AppWorldLogic::AppWorldLogic() {} AppWorldLogic::~AppWorldLogic() {} Unigine::NodePtr box; Unigine::EngineWindowViewportPtr window_translator; Unigine::EngineWindowViewportPtr window_rotator; Unigine::EngineWindowViewportPtr window_scaler; Unigine::WidgetManipulatorTranslatorPtr widget_translator; Unigine::WidgetManipulatorRotatorPtr widget_rotator; Unigine::WidgetManipulatorScalerPtr widget_scaler; int AppWorldLogic::init() { // create target object box = Primitives::createBox(vec3_one); box->setWorldPosition(Vec3(0.0f, 0.0f, 1.0f)); // create windows layout window_translator = EngineWindowViewport::create("Translator Window", 1280, 720, EngineWindow::FLAGS_MAIN | EngineWindow::FLAGS_CONSOLE_USAGE); window_rotator = EngineWindowViewport::create("Rotator Window", 1280, 720, EngineWindow::FLAGS_MAIN | EngineWindow::FLAGS_CONSOLE_USAGE); window_scaler = EngineWindowViewport::create("Scaler Window", 1280, 720, EngineWindow::FLAGS_MAIN | EngineWindow::FLAGS_CONSOLE_USAGE); auto group = WindowManager::stack(window_rotator, window_scaler, EngineWindowGroup::GROUP_TYPE_VERTICAL); group = WindowManager::stack(window_translator, group, EngineWindowGroup::GROUP_TYPE_HORIZONTAL); group->moveToCenter(); group->show(); // create widgets widget_translator = WidgetManipulatorTranslator::create(window_translator->getGui()); widget_translator->setLifetime(Widget::LIFETIME_WORLD); widget_translator->setTransform(box->getWorldTransform()); window_translator->addChild(widget_translator); widget_rotator = WidgetManipulatorRotator::create(window_rotator->getGui()); widget_rotator->setLifetime(Widget::LIFETIME_WORLD); widget_rotator->setTransform(box->getWorldTransform()); window_rotator->addChild(widget_rotator); widget_scaler = WidgetManipulatorScaler::create(window_scaler->getGui()); widget_scaler->setLifetime(Widget::LIFETIME_WORLD); widget_scaler->setTransform(box->getWorldTransform()); window_scaler->addChild(widget_scaler); return 1; } //////////////////////////////////////////////////////////////////////////////// // start of the main loop //////////////////////////////////////////////////////////////////////////////// int AppWorldLogic::update() { PlayerPtr player = Game::getPlayer(); if (player == nullptr) return 1; CameraPtr camera = player->getCamera(); if (camera == nullptr) return 1; Vec3 position(0.0f, 0.0f, 1.0f); quat rotation = quat_identity; vec3 scale = vec3_one; if (widget_translator.isValid()) { widget_translator->setProjection(camera->getProjection()); widget_translator->setModelview(camera->getModelview()); position = widget_translator->getTransform().getTranslate(); } if (widget_rotator.isValid()) { widget_rotator->setProjection(camera->getProjection()); widget_rotator->setModelview(camera->getModelview()); rotation = widget_rotator->getTransform().getRotate(); } if (widget_scaler.isValid()) { widget_scaler->setProjection(camera->getProjection()); widget_scaler->setModelview(camera->getModelview()); scale = widget_scaler->getTransform().getScale(); } Mat4 t; composeTransform(t, position, rotation, scale); box->setWorldTransform(t); if (widget_translator.isValid()) widget_translator->setTransform(t); if (widget_rotator.isValid()) widget_rotator->setTransform(t); if (widget_scaler.isValid()) widget_scaler->setTransform(t); return 1; } //////////////////////////////////////////////////////////////////////////////// // end of the main loop //////////////////////////////////////////////////////////////////////////////// int AppWorldLogic::shutdown() { window_translator.deleteLater(); window_rotator.deleteLater(); window_scaler.deleteLater(); return 1; } Все манипуляторы располагаются на своих местах.
Recommended Posts