Amerio.Stephane Posted January 23, 2020 Share Posted January 23, 2020 Hello, I'm trying to change at runtime the ViewportMask of some object on the slaves, when some event happens on the master. The object is part of a dynamic CIGI entity. On the master, I successfully find the ObjectPtr of the part of the entity I need to change. Here is what I tried: addSyncNode: that doesn't seem to forward the ViewportMask? send a custom msg to the slaves with the node ID of the ObjectPtr (on the master) when received, this node ID does not match anything on the slave, so I tried Slave::getSlaveNodeId but this returns -1 This is with 2.9.0.2. What can I try next? Thanks! Link to comment
alexander Posted January 24, 2020 Share Posted January 24, 2020 Hello Stephane, Open the "Syncker Debug Window" on both Master and Slave. Select the node the ViewportMask of which you want to change. Is it yellow on both machines? Please send us screenshots. Best regards, Alexander Link to comment
Amerio.Stephane Posted January 24, 2020 Author Share Posted January 24, 2020 Here it is: Left is Master, Right is Slave. Both shows the same view from CIGI ownship. The ownship is created with entity ID 0, type = 160 (an H160 basic model). First, without calling addSyncNode. The nodes for which I'm switching off the viewportMask are all under "static" Now when calling addSyncNode, all the relevant nodes turns yellow (so the sync is active): As you can see, the mesh are masked in the master, but not in the slave. Here is the relevant code, called in WorldLogic::update(): if (IG::IEntity* ownship = _ig_manager->getEntity(0)) { if (NodeReferencePtr nodeRef = ownship->getNodeReference()) { if (nodeRef->getVariable("done").getInt() != 1) { nodeRef->setVariable("done", Variable(1)); if (NodePtr node = nodeRef->getReference()) { Log::message("node %s\n",node->getName()); if (NodePtr nodeToHide = Util::getChild(node, "static", true)) { struct { void operator()(Syncker::MasterInterface* master, NodePtr root, int mask) { for (int i = 0; i < root->getNumChildren(); ++i) { (*this)(master, root->getChild(i), mask); if (ObjectPtr obj = Object::cast(root->getChild(i))) { Log::message("hide %s\n", obj->getName()); master->addSyncNode(obj->getNode()); for (int j = 0; j < obj->getNumSurfaces(); ++j) obj->setViewportMask(mask, j); } } } } hide; hide(_syncker_manager->getMaster(), nodeToHide, 0x0); } } } } } Link to comment
silent Posted January 27, 2020 Share Posted January 27, 2020 Stephane, Thanks for the additional description. We will need some additional time to reproduce this (I believe it could take up to 2-3 days) and find a way to fix this. 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
alexander Posted January 27, 2020 Share Posted January 27, 2020 Hi Stephane, AddSyncNode: that doesn't seem to forward the ViewportMask? Yes, it doesn't synchronize the ViewportMask. Use the Object::setEnabled(enabled, surface). Or Node::setEnabled(enabled). It works as expected. void operator()(Syncker::MasterInterface* master, NodePtr root, int enabled) { for (int i = 0; i < root->getNumChildren(); ++i) { (*this)(master, root->getChild(i), enabled); if (ObjectPtr obj = Object::cast(root->getChild(i))) { Log::message("hide %s\n", obj->getName()); master->addSyncNode(obj->getNode()); for (int j = 0; j < obj->getNumSurfaces(); ++j) obj->setEnabled(enabled, j); // use this instead of setViewportMask } } } Send a custom msg to the slaves with the node ID of the ObjectPtr (on the master) when received, this node ID does not match anything on the slave, so I tried Slave::getSlaveNodeId but this returns -1 It's very strange. I tried to reproduce it but all seems to work: // AppWorldLogic.h class AppWorldLogic : public Unigine::WorldLogic { // ... private: // ... Unigine::Syncker::ManagerInterface *_syncker_manager = nullptr; void tcp_receive(Unigine::BlobPtr &received_message); // ... }; // AppWorldLogic.cpp int AppWorldLogic::init() { // ... if (Engine::get()->findPlugin("Syncker") != -1) { _syncker_manager = (Syncker::ManagerInterface*)Engine::get()->getPluginData(Engine::get()->findPlugin("Syncker")); _syncker_manager->getSyncker()->addCallback(Syncker::MasterInterface::TCP_USER_RECEIVE, MakeCallback(this, &AppWorldLogic::tcp_receive)); } return 1; } void AppWorldLogic::tcp_receive(BlobPtr &received_message) { int master_id = received_message->readInt(); int slave_id = _syncker_manager->getSlave()->getSlaveNodeID(master_id); Log::message("Master ID: %d, Slave ID: %d\n", master_id, slave_id); } int AppWorldLogic::update() { // ... for (int i = 0; i < root->getNumChildren(); ++i) { (*this)(master, root->getChild(i), enabled); if (ObjectPtr obj = Object::cast(root->getChild(i))) { Log::message("hide %s\n", obj->getName()); master->addSyncNode(obj->getNode()); for (int j = 0; j < obj->getNumSurfaces(); ++j) obj->setEnabled(enabled, j); // send custom TCP message to all slaves BlobPtr blob = Blob::create(); blob->writeInt(obj->getID()); master->sendTCPUser(~0, blob); } // ... } Best regards, Alexander Link to comment
Amerio.Stephane Posted January 27, 2020 Author Share Posted January 27, 2020 Actually, I can't use setEnabled(), because this totally disable the node: the shadows would also disappear. (granted, in the sample code I provided I used 0x00, but that was just that, a sample). Will the surfacemask be added to sync in the future? Maybe as an option/new function? (addSyncMasks?) I'll give getSlaveNodeID another look, as suggested. I must have overlooked something! Thanks! Link to comment
Amerio.Stephane Posted January 29, 2020 Author Share Posted January 29, 2020 Hello, I implemented the tcp_receive as suggested, but I still get a invalid ID on the slave: Here I'm just sending the ID for the "static" node from the master. The console shown is on the slave, and it receives the correct ID, but the getSlaveNodeID returns -1. Surely I'm missing something. Link to comment
Amerio.Stephane Posted January 29, 2020 Author Share Posted January 29, 2020 ok, found it. I actually still need to call "addSyncNode" on my "static" node, even though I don't modify the node from the master any more. I think the doc of "getSlaveNodeID" should state more clearly that the node must be actively sync'ed from the master! a new function like "addSyncMasks" may be a good addition in a future release :) Thanks! Link to comment
Recommended Posts