Jump to content

[SOLVED] accessing World nodes


photo

Recommended Posts

Hi,

Implementing Editor plugin, I'm currently trying to get all nodes visible in world nodes panel and that user can typically move.

World::getNodes get them all, not only world nodes panel ones. 

World::getNodesByType let filter by type but in theory "Hidden and system nodes are ignored."...
So I gave a try this way:

Vector< Ptr<Node>> nodes;
Vector< Ptr<Node>> tmp; //required because getNodesByType empty given collection.. -> doc could be clearer on that
//collect nodes
for (int e = Unigine::Node::NODE_BEGIN; e <= Unigine::Node::NODE_END; e++)
{
  ::World::getNodesByType(e, tmp);
  nodes.append(tmp);
}
//collect obj
for (int e = Unigine::Node::OBJECT_BEGIN; e <= Unigine::Node::OBJECT_END; e++)
{
  ::World::getNodesByType(e, tmp);
  nodes.append(tmp);
}

But:

1. I get cache nodes as well, e.g. selecting a node to get access to its parameters
These cache nodes return getName empty.. is there directly a bool to check?
By the way, if user move the node.. which one will be impacted? the named one? a cached one? how can I get the link?

3 root nodes: lighting 1368583642 ;Cuboid 187947863 ;ground 784603924 ;
3 root nodes: lighting 1368583642 ;Cuboid 187947863 ;ground 784603924 ;
3 root nodes: lighting 1368583642 ;Cuboid 187947863 ;ground 784603924 ;
3 root nodes: lighting 1368583642 ;Cuboid 187947863 ;ground 784603924 ;
5 root nodes: lighting 1368583642 ;Cuboid 187947863 ; 500394619 ; 1761205259 ;ground 784603924 ;
5 root nodes: lighting 1368583642 ;Cuboid 187947863 ; 500394619 ; 1761205259 ;ground 784603924 ;
7 root nodes: lighting 1368583642 ;Cuboid 187947863 ; 500394619 ; 1761205259 ; 1592480752 ; 1741290753 ;ground 784603924 ;

2. Is there a more convenient / efficient way?  

Kind regards,
Charles

Link to comment

Ok, sorry.. I could read bit more the doc

Vector< Ptr<Node>> nodes;
Vector< Ptr<Node>> tmp;

::World::getNodes(tmp);
for (auto& it : tmp)
  if (it->isShowInEditorEnabled())
  nodes.append(it);

 

  • Thanks 1
Link to comment
  • silent changed the title to [SOLVED] accessing World nodes
  • 2 weeks later...

Hi,

Even if solved, hope it is still possible to follow-up on this thread.. otherwise I open new one.

Related to current Editor plugin dev, how would it be possible to get event world reloaded?
In the plugin, I maintain some NodePtr and after reload of the world I have the editor crashing.
Instead of using NodePtr, I could use NodeID and check systematically before use if related NodePtr are still consistent.. but it is not so elegant.

For you to get more info, the plugin starts an independent thread tick 10ms:
- globalSelectionChanged() event from UI with Selection::getSelectorNodes() to know wich nodes are currently manipulated
- process() checking if something changed, in this case sending some info

All is fine and robust.. until world reload occurs.
Would you see smthg to do?

Kind regards,
Charles

Link to comment

Hello,

You can get event about world reload. Here's the snippet:

class AppEditorLogic : public Unigine::EditorLogic
{
public:
	int worldInit() override
	{
		// Your code to do something
		return 1;
	}
	int worldShutdown() override
	{
		// Your code to do something
		return 1;
	}	
};

{
	AppEditorLogic *logic = new AppEditorLogic();
	Unigine::Engine::get()->addEditorLogic(logic);
}

 

  • Thanks 1
Link to comment

Hi,

Excellent, thanks for reactivity and solution!

Implemented, works fine.
But I solved my issue in between, well at least understood what was wrong:
- In order to detect any diff, I simply create some clones of selected nodes, with all suitable setxxxEnabled to false.
- These clones are continuously compared to current nodes on some fields, e.g. position or orientation, if (diff) {do smthg and update clones}
- A world reload is of course invalidating any current selected nodes I may use in monitoring thread.. but it seems to do as well with the clones :-o
  Bit surprising given the fact I am not using Node::getCloneNode(node) but node->clone() and thought these clones are more let's say independent of current world.
- So, I simply checked before use if clone is still valid.. but with your suggestion it is no required anymore.

By the way, in cpp, would you know a way to automate a bit the filed comparison between 2 nodes, even if there's no introspection C# like?
Currently, it is direct coded on specific fields.

Kind regards,
Charles

Link to comment

Hello,

If you want to compare only specific fields, I can suggest a way with macros.

bool compare_fields(const NodePtr &old_node, const NodePtr &new_node)
{
#define COMPARE_SPECIFIC_FIELD(NAME)	\
	if (old_node->is##NAME() != new_node->is##NAME()) return false;

	COMPARE_SPECIFIC_FIELD(Enabled)
	COMPARE_SPECIFIC_FIELD(Decal)

#undef COMPARE_SPECIFIC_FIELD

	return true;
}

If you want to compare all the states of some node, you can use node->saveState, and then you are able to compare two chunks of memory by using 'memcmp', for example.

It's pseudocode of this operation.

BlobPtr blob_old = Blob::create();
node->saveState(blob_old);

// do something

BlobPtr blob_new = Blob::create();
node->saveState(blob_new);

if ((blob_old->getSize() == blob_new->getSize()) && (memcmp(blob_old->getData(), blob_new->getData(), blob_old->getSize()) == 0))
{
	// They are equal
}
else
{
	// They are different
	// May be:
	// node->restoreState(blob_old);
}

 

  • Like 1
  • Thanks 1
Link to comment
×
×
  • Create New...