Amerio.Stephane Posted April 15, 2022 Share Posted April 15, 2022 Hi, Could you provide an detailed example of the content of CIGI messages to be sent in order to display CIGI symbols (text and lines)? I tried displaying text and lines with HEmu by sending Symbol Surface Definition, Symbol Control, Symbol Text and Symbol Line. I tried both View attached and Entity attached, but no symbol was displayed (2.13.1 and 2.15.1). Thanks! Link to comment
silent Posted April 18, 2022 Share Posted April 18, 2022 Hi Stephane, As far as I understand all the symbols are compatible with original CIGI IGD. Maybe they are just too small? Like in this topic: How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
Amerio.Stephane Posted April 20, 2022 Author Share Posted April 20, 2022 That doesn't look like it, but maybe I'm wrong. Frsit, we are using plain CIGI message to (try to) draw symbol surfaces, no code here. And this is with a brand new project IG project, no user code at all. For example, trying to draw a red diagonal line over the viewport should be: But nothing is visible. When trying to draw text with I also get nothing, and a warning message in the cmd window: CigiThread::process(): can't create Host packet (OPCode: 0) packet type 0(0bytes) prev packet 30(24bytes) src_size 224 So... Could you please show us a sequence of CIGI messages that produces a symbol on screen (text and lines). I must be missing something obvious? Thanks! Link to comment
cash-metall Posted April 21, 2022 Share Posted April 21, 2022 Hello! at the moment cigi connector does not read symbol messages - this is a bug. you can try to read and send via api // AppSystemLogic.h //... // cigi void init_cigi(); Unigine::Plugins::IG::CIGI::Connector *cigi; void symbol_surface_def(Unigine::Plugins::IG::CIGI::CigiHostPacket* packet); void symbol_text_def(Unigine::Plugins::IG::CIGI::CigiHostPacket* packet); void symbol_circle_def(Unigine::Plugins::IG::CIGI::CigiHostPacket* packet); void symbol_line_def(Unigine::Plugins::IG::CIGI::CigiHostPacket* packet); void symbol_clone(Unigine::Plugins::IG::CIGI::CigiHostPacket* packet); void symbol_control(Unigine::Plugins::IG::CIGI::CigiHostPacket* packet); void symbol_short_control(Unigine::Plugins::IG::CIGI::CigiHostPacket* packet); //... // AppSystemLogic.cpp using namespace Unigine; using namespace Plugins; using namespace Math; using namespace IG; // ... void AppSystemLogic::init_cigi() { int index = Engine::get()->findPlugin("CIGIConnector"); // check CIGIConnector plugin load if (index < 0) return; // get CIGI interface cigi = IG::CIGI::Connector::get(); cigi->addOnReceivePacketCallback(CIGI::CIGI_OPCODE_SYMBOL_SURFACE_DEF, MakeCallback(this, &AppSystemLogic::symbol_surface_def)); cigi->addOnReceivePacketCallback(CIGI::CIGI_OPCODE_SYMBOL_CIRCLE_DEF, MakeCallback(this, &AppSystemLogic::symbol_circle_def)); cigi->addOnReceivePacketCallback(CIGI::CIGI_OPCODE_SYMBOL_CLONE, MakeCallback(this, &AppSystemLogic::symbol_clone)); cigi->addOnReceivePacketCallback(CIGI::CIGI_OPCODE_SYMBOL_CONTROL, MakeCallback(this, &AppSystemLogic::symbol_control)); cigi->addOnReceivePacketCallback(CIGI::CIGI_OPCODE_SYMBOL_LINE_DEF, MakeCallback(this, &AppSystemLogic::symbol_line_def)); cigi->addOnReceivePacketCallback(CIGI::CIGI_OPCODE_SYMBOL_SHORT_CONTROL, MakeCallback(this, &AppSystemLogic::symbol_short_control)); cigi->addOnReceivePacketCallback(CIGI::CIGI_OPCODE_SYMBOL_TEXT_DEF, MakeCallback(this, &AppSystemLogic::symbol_text_def)); } void AppSystemLogic::symbol_surface_def(Unigine::Plugins::IG::CIGI::CigiHostPacket *packet) { Plugins::IG::CIGI::CigiSymbolSurfaceDef *def = dynamic_cast<Plugins::IG::CIGI::CigiSymbolSurfaceDef *>(packet); if (def == nullptr) return; SymbolsPlane *plane = nullptr; // 1 != CIGI_STATE_DESTROYED! if (def->getSurfaceState() == 1) { ig_manager->getSymbolsController()->removePlane(def->getSurfaceID()); } else { //0 - entity, 1- view. if (def->getAttachType() == 0) { Entity *entity = ig_manager->getEntity(def->getEntityID()); plane = ig_manager->getSymbolsController()->createPlane(def->getSurfaceID(), entity); plane->setBillboard(def->getBillboard() == 1, def->getPerspective() == 1); plane->setPosition(def->getOffset()); plane->setRotation(ig_manager->getConverter()->eulerNEDToRotation(def->getRotation())); plane->setPhysicalSize(def->getWidth(), def->getHeight()); plane->setUVSize(def->getMin().x, def->getMin().y, def->getMax().x, def->getMax().y); } else { View *view = ig_manager->getView(def->getEntityID()); plane = ig_manager->getSymbolsController()->createPlane(def->getSurfaceID(), view); vec3 t1 = def->getOffset(); vec3 t2 = def->getRotation(); // left = t1.x | right = t1.y | top = t1.z | bottom = t2.x float width = Gui::get()->getWidth() - t1.x - t1.y; float height = Gui::get()->getHeight() - t1.z - t2.x; plane->setScreenSize(width, height, t1.x, t1.z); plane->setUVSize(def->getMin().x, def->getMin().y, def->getMax().x, def->getMax().y); } } } void AppSystemLogic::symbol_text_def(Unigine::Plugins::IG::CIGI::CigiHostPacket *packet) { CIGI::CigiSymbolTextDef *def = dynamic_cast<CIGI::CigiSymbolTextDef *>(packet); if (def == nullptr) return; SymbolText *symbol = dynamic_cast<SymbolText *>(ig_manager->getSymbolsController()->createSymbol(SymbolsController::SYMBOL_TYPE_TEXT, def->getSymbolID())); if (symbol == nullptr) { Log::error("%s:: cant create SymbolText\n", __FUNCTION__); return; } int alignV = def->getAlignment() / 3; int alignH = def->getAlignment() % 3; symbol->setAlign(SymbolText::ALIGN_HORIZONTAL(alignH), SymbolText::ALIGN_VERTICAL(alignV)); symbol->setOrientation(SymbolText::ORIENTATION(def->getOrientation())); symbol->setFont(def->getFontID()); symbol->setFontSize(def->getFontSize()); symbol->setText(def->getText().get()); } void AppSystemLogic::symbol_circle_def(Unigine::Plugins::IG::CIGI::CigiHostPacket *packet) { CIGI::CigiSymbolCircleDef *def = dynamic_cast<CIGI::CigiSymbolCircleDef *>(packet); if (def == nullptr) return; int num = def->getNumCircles(); for (int i = 0; i < num; ++i) { SymbolCircle *symbol = dynamic_cast<SymbolCircle *>(ig_manager->getSymbolsController()->createSymbol(SymbolsController::SYMBOL_TYPE_CIRCLE, def->getSymbolID())); if (symbol == nullptr) { Log::error("%s:: cant create SymbolText\n", __FUNCTION__); return; } symbol->setFill(def->getDrawStyle()); symbol->setLineWidth(def->getLineWidth()); symbol->setCenter(def->getCenter(i).x, def->getCenter(i).y); symbol->setRadius(def->getOuterRadius(i)); float innerRadius = def->getInnerRadius(i); if (compare(innerRadius, 0.0f) || innerRadius > def->getOuterRadius(i)) innerRadius = -1.0f; symbol->setInnerRadius(innerRadius); symbol->setSector(def->getStartAngle(i), def->getEndAngle(i)); } } void AppSystemLogic::symbol_line_def(Unigine::Plugins::IG::CIGI::CigiHostPacket *packet) { CIGI::CigiSymbolLineDef *def = dynamic_cast<CIGI::CigiSymbolLineDef *>(packet); if (def == nullptr) return; SymbolPolyline *symbol = dynamic_cast<SymbolPolyline *>(ig_manager->getSymbolsController()->createSymbol(SymbolsController::SYMBOL_TYPE_POLYLINE, def->getSymbolID())); if (symbol == nullptr) { Log::error("%s:: cant create SymbolText\n", __FUNCTION__); return; } switch (def->getPrimitiveType()) { case 3: symbol->setClosed(true); break; case 4: symbol->setFill(true); break; case 5: symbol->setFill(true); symbol->setVertexOrderStrip(true); break; case 6: symbol->setFill(true); break; } symbol->setLineWidth(def->getLineWidth()); int num = def->getNumVertex(); for (int i = 0; i < num; ++i) { symbol->addPoint(def->getVertex(i).x, def->getVertex(i).y); } } void AppSystemLogic::symbol_clone(Unigine::Plugins::IG::CIGI::CigiHostPacket *packet) { CIGI::CigiSymbolClone *clone_packet = dynamic_cast<CIGI::CigiSymbolClone *>(packet); if (clone_packet == nullptr) return; // TODO IG TEMPLATE SYMBOL??? // clone_packet->getSourceType(); Symbol *symbol = ig_manager->getSymbolsController()->cloneSymbol(clone_packet->getSourceID(), clone_packet->getSymbolID()); if (!symbol) { Log::error("%s:: cant clone symbol %d, to %d\n", __FUNCTION__, clone_packet->getSourceID(), clone_packet->getSymbolID()); return; } symbol->setVisible(false); } void AppSystemLogic::symbol_control(Unigine::Plugins::IG::CIGI::CigiHostPacket *packet) { CIGI::CigiSymbolControl *control = dynamic_cast<CIGI::CigiSymbolControl *>(packet); if (control == nullptr) return; if (control->getSymbolState() == CIGI::CIGI_STATE_DESTROYED) { ig_manager->getSymbolsController()->removeSymbol(control->getSymbolID()); } else { Symbol *symbol = ig_manager->getSymbolsController()->getSymbol(control->getSymbolID()); if (!symbol) { Log::error("%s:: cant get symbol %d \n", __FUNCTION__, control->getSymbolID()); return; } symbol->setVisible(control->getSymbolState() != 0); if (control->getAttachState()) { Symbol *parent = ig_manager->getSymbolsController()->getSymbol(control->getParentID()); if (!parent) { Log::error("%s:: cant get parent symbol %d \n", __FUNCTION__, control->getParentID()); return; } symbol->setParent(parent); } else { symbol->setParent(nullptr); } symbol->setColorInherit(control->getInheritColor()); if (symbol->getParent() == nullptr) { SymbolsPlane *plane = ig_manager->getSymbolsController()->getPlane(control->getSurfaceID()); plane->addSymbol(symbol); } symbol->setOrder(control->getLayer()); if (control->getFlashControl()) symbol->resetFlashProgram(); int flash = control->getFlashDuty(); Vector<float> flash_cicle; if (flash == 0) { symbol->setVisible(false); symbol->setFlashProgram(flash_cicle); } else if (flash == 100) { symbol->setVisible(true); symbol->setFlashProgram(flash_cicle); } else { flash_cicle.append(control->getFlashPeriod() * control->getFlashDuty() * 0.01f); flash_cicle.append(control->getFlashPeriod() * (1 - control->getFlashDuty() * 0.01f)); symbol->setFlashProgram(flash_cicle); } symbol->setOffset(control->getPosition().x, control->getPosition().y); symbol->setRotation(control->getRotation()); symbol->setColor(control->getColor()); symbol->setScale(control->getScale().x, control->getScale().y); } } void AppSystemLogic::symbol_short_control(Unigine::Plugins::IG::CIGI::CigiHostPacket *packet) { auto process = [this](int parameter, unsigned int data, Symbol *symbol) { switch (parameter) { case 1: { //surface if (symbol->getParent() == nullptr) { SymbolsPlane *plane = ig_manager->getSymbolsController()->getPlane(int(data)); if (!plane) { Log::error("%s:: cant get symbols plane %d \n", __FUNCTION__, int(data)); return; } plane->addSymbol(symbol); } break; } case 2: { Symbol *parent = ig_manager->getSymbolsController()->getSymbol(int(data)); if (!parent) { Log::error("%s:: cant get parent symbol %d \n", __FUNCTION__, int(data)); return; } symbol->setParent(parent); break; } case 3: { //layer symbol->setOrder(int(data)); break; } case 4: { //flash duty // TODO how to set flash duty, without flash period?? break; } case 5: { //flash period // TODO how to set flash period, without flash duty?? break; } case 6: { //pos u float v = symbol->getOffset().y; symbol->setOffset(*(float *)(&data), v); break; } case 7: { //pos v float u = symbol->getOffset().x; symbol->setOffset(u, *(float *)(&data)); break; } case 8: { //rotate symbol->setRotation(*(float *)(&data)); break; } case 9: { //color vec4 color; // NOTE: check it unsigned char *src = (unsigned char *)(&data); color.x = (src[0] / 255.0f); color.y = (src[1] / 255.0f); color.z = (src[2] / 255.0f); color.w = (src[3] / 255.0f); symbol->setColor(color); break; } case 10: { //scale u float v = symbol->getScale().y; symbol->setScale(*(float *)(&data), v); break; } case 11: { //scale v float u = symbol->getScale().x; symbol->setScale(u, *(float *)(&data)); break; } } }; CIGI::CigiSymbolShortControl *control = dynamic_cast<CIGI::CigiSymbolShortControl *>(packet); if (control == nullptr) return; if (control->getSymbolState() == CIGI::CIGI_STATE_DESTROYED) { ig_manager->getSymbolsController()->removeSymbol(control->getSymbolID()); } else { Symbol *symbol = ig_manager->getSymbolsController()->getSymbol(control->getSymbolID()); if (!symbol) { Log::error("%s:: cant get symbol %d \n", __FUNCTION__, control->getSymbolID()); return; } symbol->setVisible(control->getSymbolState() != 0); if (!control->getAttachState()) { symbol->setParent(nullptr); } if (control->getFlashControl()) symbol->resetFlashProgram(); symbol->setColorInherit(control->getInheritColor()); process(control->getSelect1(), control->getData1(), symbol); process(control->getSelect2(), control->getData2(), symbol); } } // ... as far as I remember in CIGI HEMU had some problems with sending symbol packets. especially: - SYMBOL_LINE_DEF - SYMBOL_CIRCLE_DEF if these packets do not work, check through WireShark that HEMU is indeed sending packets correctly. 1 Link to comment
silent Posted April 21, 2022 Share Posted April 21, 2022 This bug is also scheduled for fixing prior to 2.16 release. How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
Amerio.Stephane Posted April 21, 2022 Author Share Posted April 21, 2022 Thanks for the patch! I'll check this asap! Thanks! Link to comment
Amerio.Stephane Posted April 22, 2022 Author Share Posted April 22, 2022 So... just tested, and still nothing on screen :( You were correct though about HEmu as it spits invalid cigi packets. So I used our own CIGI sender, and still nothing. I attach here the three packets sent (symbol surface definition, symbol text definition, symbol control) in case you see a mistake here. Could you send me your test packets ? Note: I added a log trace in your callbacks and observed the log is printed twice for each message received. So your callbacks are called twice. Is it normal? cigi_symbols.pcapng Link to comment
cash-metall Posted April 25, 2022 Share Posted April 25, 2022 I checked your case - the problem is in the font size. we don't take into account the UV scale of the surface when calculating the font - it is always drawn in real size. Align and Orientation for TextSymbol is also does not work properly. As for double processing of packet - I can't reproduce this behavior. Сheck if init_cigi (addOnReceivePacketCallback) is called twice and adds callbacks a second time? 1 Link to comment
Amerio.Stephane Posted April 25, 2022 Author Share Posted April 25, 2022 Hi, it works with the size now! So okay, we'll have to set the UV size as the pixel size instead. Ok for now... For the double-call, sorry it was on my side, as you guessed. One more trouble: if I send a new text definition to change the text content for an existing symbol, then it disappears. I have to resend the symbol control after updating the the text. Is it the expected behavior? Thanks! Link to comment
cash-metall Posted April 25, 2022 Share Posted April 25, 2022 1 hour ago, Amerio.Stephane said: One more trouble: if I send a new text definition to change the text content for an existing symbol, then it disappears. I have to resend the symbol control after updating the the text. Is it the expected behavior? not really. createSymbol deletes a symbol if it has already been created. Try to take the symbol first, and if it doesn't exist, create it. void AppSystemLogic::symbol_text_def(Unigine::Plugins::IG::CIGI::CigiHostPacket *packet) { CIGI::CigiSymbolTextDef *def = dynamic_cast<CIGI::CigiSymbolTextDef *>(packet); if (def == nullptr) return; SymbolText *symbol = dynamic_cast<SymbolText *>(ig_manager->getSymbolsController()->getSymbol(def->getSymbolID())); if (!symbol) symbol = dynamic_cast<SymbolText *>(ig_manager->getSymbolsController()->createSymbol(SymbolsController::SYMBOL_TYPE_TEXT, def->getSymbolID())); if (!symbol) { Log::error("%s:: cant create SymbolText\n", __FUNCTION__); return; } //.... 1 Link to comment
Amerio.Stephane Posted April 25, 2022 Author Share Posted April 25, 2022 Indeed that fixed it. I did the same for the other symbols. Hope the next version will integrate these and the fixed font size :) but it'll be ok for now. Thanks! Link to comment
Amerio.Stephane Posted May 13, 2022 Author Share Posted May 13, 2022 Hi, I found a new issue with CIGI symbols. When the surface is defined as attached to the View, a rescale of the window does not trigger a rescale of the symbol surface. For example, if the surface is defined as view attached with UV=min(0,0)-max(1,1) and a text is displayed at UV(0.5,0.5) (the center), the text appears correctly in the center. But if I rescale the window (for example by maximizing the window) then the text is no longer in the center. How to fix this with the current code? Could this be fixed in the next version? Thanks! Link to comment
cash-metall Posted May 16, 2022 Share Posted May 16, 2022 On 5/13/2022 at 4:18 PM, Amerio.Stephane said: a rescale of the window does not trigger a rescale of the symbol surface. yes, you are right - window rescale doesnt trigger anything. screen size takes only when you send plane define packet. // left = t1.x | right = t1.y | top = t1.z | bottom = t2.x float width = Gui::get()->getWidth() - t1.x - t1.y; float height = Gui::get()->getHeight() - t1.z - t2.x; plane->setScreenSize(width, height, t1.x, t1.z); you can resend packet with plane defenition or try to catch rescale Vector<int> planes; void symbol_surface_def () { //.... auto *view = ig_manager->getView(def->getEntityID()); plane = ig_manager->getSymbolsController()->createPlane(def->getSurfaceID(), view); // save ids of view-attached plane if (!planes.contains(def->getSurfaceID())) planes.append(def->getSurfaceID()); //..... } int w = 0; int h = 0; void update() // somewhere in update { int new_w = App::getWidth(); int new_h = App::getHeigth(); if (new_w != w || new_h != h) // if sceen changed { for (auto it : planes) { auto plane = ig_manager->getSymbolsController()->getPlane(it); if (!plane) continue; // recalc screensize vec4 screen_size = plane->getScreenSize(); screen_size.x = new_w - (w-screen_size.x); screen_size.y = new_h - (h-screen_size.y); plane->setScreenSize(screen_size); } w = new_w; h = new_h; } } 1 Link to comment
Amerio.Stephane Posted May 19, 2022 Author Share Posted May 19, 2022 (edited) Hi, the latest window resize fix works correctly, thanks. But now we found out that a CIGI reset will crash in IG_double_x64d.dll with no usable stack trace if a symbol has been defined. Reproduction: launch with IG and CIGIConnector plugins send a SymbolSurfaceDefinition(View attached), a TextDefinition, a SymbolControl: text should be visible on screen Send a CIGI IG Ctrl reset -> crash Note: I tried to move all symbol code to a WorldLogic instead of a SystemLogic, and removing all callbacks and calling removeSymbol for all surfaceId but it still crashes. Edited May 19, 2022 by Amerio.Stephane Link to comment
cash-metall Posted May 20, 2022 Share Posted May 20, 2022 20 hours ago, Amerio.Stephane said: Reproduction: launch with IG and CIGIConnector plugins send a SymbolSurfaceDefinition(View attached), a TextDefinition, a SymbolControl: text should be visible on screen Send a CIGI IG Ctrl reset -> crash I cannot reproduce this crash. Symbols are destroyed on reset - may be you keep pointer on some of them? can you send any crash stacktrace (even useless)? Link to comment
Amerio.Stephane Posted May 23, 2022 Author Share Posted May 23, 2022 Hi, you actually need to have an active entity for the crash to happen (note: you have a typo in your SymbolsController::onEntityDestro*y*ed) Link to comment
Amerio.Stephane Posted June 1, 2022 Author Share Posted June 1, 2022 up! Any reproduction on your side? Link to comment
silent Posted June 2, 2022 Share Posted June 2, 2022 Thanks for the waiting, Stephane. We've successfully reproduced this crash. Bug fix is scheduled for the upcoming 2.16 release this summer. How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
Recommended Posts