Jump to content

[SOLVED] Syncker::loadNode and sync mask don't work as expected


photo

Recommended Posts

Hello,

Something is not working as  expected (or at least, I don't understand the current behaviors). SDK 2.18.1

  1. On master, syncker->loadNode("test.obj") will produce a bunch of WARNING: Move immovable node: "default"
    This happens during the loadNode, even before I even try to move the loaded node. (the loading itself work).
    As I may want to move the node around, I will setImmovable(false) on all of the node hierarchy anyway.
  2. On master, syncker->loadNode("othertest.node") works correctly and the node position is not syncked to slaves (as expected).
    But syncker->loadNode("othertest.node", Plugins::Syncker::Master::BASE) forces continuously the object position at 0,0,0, quite unexpectedly. So I can't move the node at all.
    This one is quite blocking at the moment.
Link to comment

Hello! 

1. At the moment, there is no way to bypass this issue when loading OBJ files.
In this case, we recommend either using .node files or simply suppressing the warning by using:

World::setMovingImmovableNodeMode(World::MOVING_IMMOVABLE_NODES_MODE_ALLOW);

 

2. loadNode(path, BASE) works as expected. The BASE flag does not assume that the node will move, and its transformation is not synchronized.
To synchronize the position, you need to set the TRANSFORM flag:

master->loadNode(path,  Plugins::Syncker::Master::BASE &  Plugins::Syncker::Master::TRANSFORM);

However, if the position only needs to be set once, you can use the third argument:

master->loadNode(path, 0, init_transform);

This is useful for creating a static object without further synchronization.

Link to comment
Quote

At the moment, there is no way to bypass this issue when loading OBJ files.
In this case, we recommend either using .node files or simply suppressing the warning by using:

World::setMovingImmovableNodeMode(World::MOVING_IMMOVABLE_NODES_MODE_ALLOW);

This is an acceptable workaround at the moment. But is it an overlook in the implementation (meaning we should have a way to specifiy movable/immovable per object when importing not-a-node). I don't remember having this kind of issue in 2.16

Quote

loadNode(path, BASE) works as expected. The BASE flag does not assume that the node will move, and its transformation is not synchronized.
To synchronize the position, you need to set the TRANSFORM flag

Now I don't understand, because the documentation and your header specifically states the contrary:

https://developer.unigine.com/en/docs/2.19/api/library/plugins/syncker/class.syncker_master?rlang=cpp

SYNC_MASK

Node synchronization mask.

Name Description
NODE_FLAGS = 1 Update only simple node flag (enabled, etc.)
TRANSFORM = 1 << 1 Update node transform (with interpolation).
BASE = 3 Update base information NODEFLAGS & TRANSFORM.

So BASE should definitively include TRANSFORM. Or something is broken (doc or code). If not, what should be the behavior of TRANSFORM only? What if we need to sync also the enabled state? And what does BASE sync exactly then, compared to NODE_FLAGS?

On a side note, thanks for reminding that I can also set just the initial transform, that can also be helpful!

Link to comment

Yes, you're right, BASE does include TRANSFORM!
That was my mistake - I rushed to answer without checking the enum properly.

I tried to reproduce the issue based on the SynckerDemo, specifically in the third example: LoadNode

void MasterLogic3::on_button_clicked()
{
	// transform
	Vec3 pos = Vec3(
		Game::getRandomFloat(-5.0f, 5.0f),
		Game::getRandomFloat(-10.0f, 0.0f),
		Game::getRandomFloat(5.0f, 15.0f));
	quat rot = quat(
		Game::getRandomFloat(0.0f, 360.0f),
		Game::getRandomFloat(0.0f, 360.0f),
		Game::getRandomFloat(0.0f, 360.0f));

	// spawn node
	last_node = master->loadNode(spawn_node, Syncker::Master::BASE);
	last_node->setWorldPosition(pos);
	last_node->setWorldRotation(rot);
}

It looks like everything is working as expected. 

Which version of the SDK are you using? (UPD i see 2.18, its also work for 2.18)

image.png

Link to comment

Indeed, it works in the sample; So... I rolled a quick sample test and here is my finding: the first call(s) to setPosition are simply ignored.

int AppWorldLogic::init()
{
	Mat4 mat;
	mat.setTranslate({ 0,0,5 });  //<---- This transform is actually applied
	auto s = Syncker::Manager::get()->getMaster();
	node = s->loadNode("Box.node", Syncker::Master::BASE, mat);
	node->setWorldPosition({ 5,0,5 }); //<---- this call has no effect
	return 1;
}

If then I call setWorldPosition in the update loop, then it will work. Feels very strange to me.

Link to comment

Here is attached a quick sample, showing the surprising behavior. Output here is:

09:54:30 Master::init(): waiting for 0 slaves...
09:54:30 After loadnode: 1 (expected: 1)
09:54:30 After setwpos:  1 (expected: 2)
09:54:30 Master::wait_connections(): Starting session...
09:54:30 After update:   2 (expected: 3)
09:54:30 Master::session_starting(): session started
09:54:30 After update:   1 (expected: 3)
09:54:30 After update:   3 (expected: 3)
09:54:30 After update:   3 (expected: 3)
09:54:30 After update:   3 (expected: 3)

Rationale: we need to spawn a node at a precise location lat&lon, but the altitude and orientation depends of the object itself, so we must spawn it and then reorient and move it (it's moved both after being spawn and measured, and later it may also be moved by a component in the spawned node). With 2.18, the object is not correctly relocated after being spawn, as the first calls to setWorldPosition have no effect.

test_loadnode.zip

  • Thanks 1
Link to comment
  • silent changed the title to [SOLVED] Syncker::loadNode and sync mask don't work as expected
×
×
  • Create New...