Synching node position and rotation

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
The_Fallen
Posts: 4
Joined: Tue May 01, 2007 8:56 am

Synching node position and rotation

Post by The_Fallen »

Hi,

I'm currently working on a small project using Irrlicht and Raknet. It's just to do _something_ in C++, since in my job I'm only working with PHP and Java and I'm afraid that I forget all about C++... ;-)
So, my problem is now, how to synch the position and the rotation of a node between server and client. It seems quite straightforward, and for the position it really is. But if I do some client prediction and interpolation on the client I can run into problems, if I send the rotation in degrees. Just imagine: the client's rotation about the x axis is 3 degrees, while the latest snapshot from the server says 358 degrees. In fact this is just a 5 degree difference, but the client (at least in a naive implementation) would try to increase the angle until its 358, instead of decreasing it by 5 degrees.
So what do you do about this? I was thinking about sending front and up vector instead of rotation in degrees, but that would be twice the amount of data...

thx
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Uh...

Code: Select all

    if(deltaRotation >= 180.f)
        deltaRotation -= 360.f;
And if deltaRotation < 0.f, then rotate anticlockwise.

Am I misunderstanding your requirements?
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
The_Fallen
Posts: 4
Joined: Tue May 01, 2007 8:56 am

Post by The_Fallen »

Hey,

thanks for your reply. But my question was more a general one: what do you send to the client's in order to update a node's rotation?
I actually have done it the way you suggested, but that doesn't really work. I rotate nodes using matrices:

Code: Select all

irr::core::matrix4 m;
m.setRotationDegrees(_sceneNode->getRotation());
irr::core::matrix4 n;
n.setRotationDegrees(rot);
m *= n;
_sceneNode->setRotation(m.getRotationDegrees());
_sceneNode->updateAbsolutePosition();
But unfortunately, when I rotate around the y axis, the results are weird. It only seems to have a range of -90°<y<90°, and whenever it reaches these limits, the x and z rotations get inverted (i.e. 0°->180°). For interpolation this unsteady behavior is quite bad...
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

I'm still not sure that I understand your requirements.

First, are the rotations that you're sending relative or absolute? I.e. are you sending (considering e.g. Y only):
"Yaw +30 degrees", then "Yaw -45 degrees" (= Yaw 345 degrees)
or
"Yaw = 30 degrees" then "Yaw = 345 degrees"


I ask because I'm not sure why you're using matrix multiplication to modify 3 Euler rotations, or what results you expect to see from that.

Personally I'd send absolute rotations, and then (if I wanted to smooth the results on the client) interpolate towards each required axis rotation independently, e.g.:

Code: Select all

	// Upon receipt of the required absolute rotation from server, store it.
	requiredNodeRotation = rotationFromServer;


	// Then each frame
	f32 const frameDelta = someDeltaTime;
	//...

	vector3df nodeRotation = _sceneNode->getRotation();

	// Rotate towards the required rotation
	if(!equals(nodeRotation.X, requiredNodeRotation.X))
	{
		f32 deltaX = requiredNodeRotation.X - nodeRotation.X;
		if(deltaX > 180.f)
			deltaX = 360.f - deltaX;
		else if(deltaX < -180.f)
			deltaX += 360.f;

		f32 const availableRotation = frameDelta * X_ROTATION_SPEED;
		if(fabs(deltaX) <= availableRotation)
		{
			nodeRotation.X = requiredNodeRotation.X;
		}
		else
		{
			if(deltaX > 0.f)
			{
				nodeRotation.X += availableRotation;
				if(nodeRotation.X >= 360.f)
					nodeRotation.X -= 360.f;
			}
			else
			{
				nodeRotation.X -= availableRotation;
				if(nodeRotation.X < 0.f)
					nodeRotation.X += 360.f;
			}
		}
	}

	// ... same again for Y and Z ...

	// Then finally
	_sceneNode->setRotation(nodeRotation);
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
The_Fallen
Posts: 4
Joined: Tue May 01, 2007 8:56 am

Post by The_Fallen »

Ok, I feel a little stupid now, since I seems that there is something that I don't understand correctly. In fact I'm doing more or less what you suggested... So let me explain what I am doing.

The server simulates the world and moves the nodes around. It's a space shooter, so all the nodes have 6 degrees of freedom (3 in translation, 3 in rotation). At least for the players I need to do the rotation depending on the current view direction, i.e. around the node's local axes. Best way to do this (at least I think so) is to create a rotation matrix and multiply it with the current rotation of the node, The result again is a set of three angles, representing the new rotation of the node.

Now I send those three angles to the clients, which change the node's rotation smoothly over time to the position sent by the server using interpolation. With the x and z axis this is no problem. When I start looking in (0,0,1) direction and start turning around the x axis, the angle increases steadily to 360° and starts from 0° again. Same on the z axis. But if I turn around the y axis, the angle goes up to 90°, where both the angle around the x and the z axis jump to 180°, then the y angle goes down to -90° where the same happens (x and z to 0°). Then it goes up to 90° degrees again and so on. All while just turning in the same direction. This makes it quite impossible to do interpolation, when the angles are jumping around unsteadily...

I think I just have to write down everything and just calculate it through, so I can actually see the results. But at the moment I just find it weird...
patricklucas
Posts: 34
Joined: Sun Jul 06, 2008 5:05 am
Location: NC, USA

Post by patricklucas »

This miiiiight be the same thing that was suggested to me a few days ago: Gimbal lock.
The_Fallen
Posts: 4
Joined: Tue May 01, 2007 8:56 am

Post by The_Fallen »

So what do you suggest? Using quaternions instead?
master_zion
Posts: 15
Joined: Wed Jan 09, 2008 3:43 pm
Location: Brazil
Contact:

small sample

Post by master_zion »

Small sample (whith source)
http://www.supernovagames.com.br/pc.php

Image
Post Reply