Does anyone else have this problem with Rotation on Y-Axis

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!
Fingers
Posts: 38
Joined: Thu Feb 10, 2005 10:17 am
Location: South Africa

Does anyone else have this problem with Rotation on Y-Axis

Post by Fingers »

When I Load s 3ds model with a scale of 1, rotation is not a problem, if I change the scale to 2, then after 3 degrees of rotation, the model disappears, if I change the scale back to 1, it runs fine.

If I Change the models in 3ds and scale it up, to any scale , it loads and runs fine, it only happens if I create the scenenode with a scale > 1.

My Attempts at isolating the problem ( Some Code Snippets )....

Loading the SceneNode

Code: Select all

int scale = 1;

ship = device.SceneManager.AddAnimatedMeshSceneNode( ss.ShipMesh, null, -1, new Vector3D(0,0,0),new Vector3D(0,0,0),new Vector3D(scale,scale,scale) );
The Rotation Routine

Code: Select all

		private void Rotate( Irrlicht.Core.Vector3D rot) {
			Irrlicht.Core.Matrix4 m = SceneNode.RelativeTransformation;
			Irrlicht.Core.Matrix4 n = new Irrlicht.Core.Matrix4();
			n.SetRotationDegrees(rot);
			m *= n;
			setRotation( Missing.Matrix4.getRotationDegrees( m ) );
		}

		//--- turn ship left or right ---
		protected void Turn( float rot) {
			Rotate( new Irrlicht.Core.Vector3D(0.0f, rot, 0.0f) );
		}
The Matrix getRotationDegrees ( This is where I Got to, I Cannot debug any further )

Code: Select all

		public static Irrlicht.Core.Vector3D getRotationDegrees( Irrlicht.Core.Matrix4 mat ) {
			const double GRAD_PI = 180.000f/Math.PI;
			float temp = mat.get_M(2,0);
			double Y = - Math.Asin( temp ); 
			double D = Y; 
			double C = Math.Cos(Y); 
			Y *= GRAD_PI;

			double rotx, roty, X, Z; 

			if ( Math.Abs(C) >0.0005f) {
				rotx = mat.get_M(2,2) / C; 
				roty = mat.get_M(2,1)  / C; 
				X = Math.Atan2( roty, rotx ) * GRAD_PI; 
				rotx = mat.get_M(0,0) / C; 
				roty = mat.get_M(1,0) / C; 
				Z = Math.Atan2( roty, rotx ) * GRAD_PI; 
			} else { 
				X  = 0.0f; 
				rotx = mat.get_M(1,1);
				roty = -mat.get_M(0,1);
				Z  = Math.Atan2( roty, rotx ) * (float)GRAD_PI; 
			} 

			if (X < 0.00) X += 360.00; 
			if (Y < 0.00) Y += 360.00; 
			if (Z < 0.00) Z += 360.00; 

			return new Irrlicht.Core.Vector3D((float)X,(float)Y,(float)Z);
		}
Now the line

float temp = mat.get_M(2,0);

is what I've added to the routine, and over here is where the problem starts, as the value of temp in the debugger is NaN

Anybody else got this, or anybody know a workaround

PS (I'm not that good at understanding the matrix, and I doubt I ever will.)

Thx
Guest

Post by Guest »

I doubt that this is causing the problem, but if you copied and pasted this from your program:

Code: Select all

private void Rotate( Irrlicht.Core.Vector3D rot) { 
         Irrlicht.Core.Matrix4 m = SceneNode.RelativeTransformation; 
         Irrlicht.Core.Matrix4 n = new Irrlicht.Core.Matrix4(); 
         n.SetRotationDegrees(rot); 
then you're doing something really nasty with the matrix n. new returns a pointer to a newly allocated matrix. But n is a matrix.
In other words, n is initialised with garbage, and I can imagine that setrotationdegrees only modifies the contents instead of overwriting them all. If this is causing trouble, you should get random results every time you use Rotate.

Anyway, basics on rotation matrices:

Code: Select all

      column
row  0, 1, 2
 0  Xx,Yx,Zx
 1  Xy,Yy,Zy
 2  Xz,Yz,Zz
(Xy means: the y-coordinate of vector X)
And the matrix addressing is matrix(row,column), so e.g. matrix(1,0) is the y coordinate of vector X.

With Xx at 0,0, and Zz at 2,2, this describes two interesting uses:
1. to rotate vector (x,y,z) to get (x',y',z'):
  • x' = x * Xx + y * Yx + z * Zx
    y' = x * Xy + y * Yy + z * Zy
    z' = x * Xz + y * Yz + z * Zz
2. The local X-axis is the vector (Xx,Xy,Xz), local Y-axis is (Yx,Yy,Yz), etc. In other words, to move in the object's X-direction, you can simply move over (Xx,Xy,Xz).

For translations, those are usually placed in an additional, 4th column. (Let's call that vector T)
You'd get x' = x*Xx + y*Yx + z*Zx + Tx etc.

Scale would normally be placed in an additional, 4th row.
This is often referred to as the w coordinate of the vector (I guess for weight). Thing is, that scale is included in the transformation matrix.
I'm not sure if Irrlicht scales "before" or "after" the rotation and translation.

My guess is, if you see something disappear, it's because the translation is performed before (and therefore multiplied by) the scale.
If you see it stretch when rotating, it's because the scale is not uniform (x,y,z are not the same) and the scale is applied AFTER the rotation.
IMO the only "sensible" use is to scale first, then rotate, then translate - but I'm not sure in which order Irrlicht's scenenode does things.
Fingers
Posts: 38
Joined: Thu Feb 10, 2005 10:17 am
Location: South Africa

Post by Fingers »

Thanks for the info on Matrix's

However, Rotation, using the same model and the same routine's, but rotationg on X or Z, there is no problem.... everything rotates fine, it's only Y ...????
And Only if the Scale is 2 or 3 or higher ??

That's what has got me .....
Guest

Post by Guest »

So, how do you set the scale?
Guest

Post by Guest »

Let me rephrase that: how are you currently setting the scale?
Fingers
Posts: 38
Joined: Thu Feb 10, 2005 10:17 am
Location: South Africa

Post by Fingers »

Code: Select all

ship = device.SceneManager.AddAnimatedMeshSceneNode( ss.ShipMesh, null, -1, new Vector3D(0,0,0),new Vector3D(0,0,0),new Vector3D(scale,scale,scale) ); 
If I Recall, the parameters are ( Mesh, Parent, ID, Position, Rotation, Scale )
Guest

Post by Guest »

OK, so you are applying a uniform scale.

So what happens if you scale by 1.5 for example?
Fingers
Posts: 38
Joined: Thu Feb 10, 2005 10:17 am
Location: South Africa

Post by Fingers »

Disappears as followes ( I Did a few )

Scale , Degrees to disappear
1.0, No Problem
1.1, After about 15
1.2, After about 9
1.5, After about 5
2.0, After about 3
Anything above, After 2

Ok, I Tried this as well, Didn't think of it before .....
0.9, it Stops rotating but does not disappear after about 20
Anything lower, Stops rotating sooner
0.5, I'm not seeing it rotate

Hope this info helps
Guest

Post by Guest »

Odd.

I can think of a couple of causes for strange behaviour:
1. gimbal lock
2. rounding

In your experiments, did the object appear to be rotated over the correct angle? (i.e. did it look like the object was rotated over 15 degrees when you tried to rotate it over 15)
Fingers
Posts: 38
Joined: Thu Feb 10, 2005 10:17 am
Location: South Africa

Post by Fingers »

Fter Re-Experimenting and actually looking at the rotations, I've Noted the following ... (I Used the ones that last the Longest )

At 1.1 The rotation seems to Accelerate (Turn Faster ) However it is set at 1 degree per second (Script timer)
At 0.9 It seems to Slow down as it's turning then stop .....

I Didn't notice this before .....
Fingers
Posts: 38
Joined: Thu Feb 10, 2005 10:17 am
Location: South Africa

Post by Fingers »

It looks like my Initial Thoughts are a bit wrong .... I Put some more debug code in it and this is the results at a scale 1.1

Told to turn 1 degree rotation.Y = 1.100012
Told to turn 21 degree ratation.Y = 10.4577

Dunno if this will help ...[/img]
Guest

Post by Guest »

So it would seem that in some way every time you rotate the rotation is multiplied by the scale or something.

So with a scale 1.1, you'd rotate over 1.1 * rotate, 1.21 * rotate, 1.331 * rotate. Question is why, though.

Now, if I understand correctly, AbsoluteTransformation and RelativeTransformation are updated every frame.

It would be very useful to have a look at what happens in the Prerender function. If the scale was just applied over and over again, the object would mutate every frame, not every time your rotate function is called.


Another thought: NaN would most likely be the result of an acos or asin on a value greater than 1.
I wonder how that Math object calculates its Atan2. Maybe it does not call the standard C function and also does not normalise its X and Y. Which would make it a bug in Math.Atan2 or in getRotationDegrees, because the size of the X/Y/Z vectors in the matrix does not need to be 1 to be a valid matrix.
Guest

Post by Guest »

Just to add another thing (not that it should make any significant difference for this issue)

to prevent loss of precision, store the rotation (heading,pitch,roll) and update that. Then in Prerender or after every update use Rotate on an identity matrix instead of the current relative transformation.
Fingers
Posts: 38
Joined: Thu Feb 10, 2005 10:17 am
Location: South Africa

Post by Fingers »

OK, I Wrote a Logger and recorded the results after each degree turn set at every 250ms

6 Models Loaded First 3 rorate on X Axis, Next 3 Y Axis and then next 3 Z Axis

In the groupings of 3, first is 0.5 scale, next 1.0 and then 1.5

Here are the first 45 degrees logged .... Y Continues its trend so no point in posting more

The logger outputs in csv format so you can cut and paste it into excel if ou want

Code: Select all

 Logger Initialised , 2005/02/24 , 09:32 PM
 Degree Rotated , 0.5 X Rot , 1.0 X Rot , 1.5 X Rot , 0.5 Y Rot , 1.0 Y Rot , 1.5 Y Rot , 0.5 Z Rot , 1.0 Z Rot , 1.5 Z Rot
 1 , 0.9999999 , 0.9999999 , 0.9999999 , 0.499981 , 0.9999999 , 1.500095 , 0.9999999 , 0.9999999 , 0.9999999
 2 , 2 , 2 , 2 , 0.7499262 , 2 , 3.751633 , 2 , 2 , 2
 3 , 3 , 3 , 3 , 0.8748611 , 3 , 7.137731 , 3 , 3 , 3
 4 , 4 , 4 , 4 , 0.937305 , 4 , 12.25892 , 4 , 4 , 4
 5 , 5 , 5 , 5 , 0.968514 , 5 , 20.12246 , 5 , 5 , 5
 6 , 6 , 6 , 6 , 0.9841118 , 6 , 32.72066 , 6 , 6 , 6
 7 , 7 , 7 , 7 , 0.9919072 , 7 , 56.37883 , 7 , 7 , 7
 8 , 8 , 8 , 8 , 0.9958031 , 8.000001 , NaN , 8 , 8 , 8
 9 , 9.000001 , 9.000001 , 9.000001 , 0.9977502 , 9.000003 , NaN , 9.000001 , 9.000001 , 9.000001
 10 , 10 , 10 , 10 , 0.9987233 , 10 , NaN , 10 , 10 , 10
 11 , 11 , 11 , 11 , 0.9992096 , 11 , NaN , 11 , 11 , 11
 12 , 12 , 12 , 12 , 0.9994526 , 12.00001 , NaN , 12 , 12 , 12
 13 , 13 , 13 , 13 , 0.9995741 , 13.00001 , NaN , 13 , 13 , 13
 14 , 14 , 14 , 14 , 0.9996348 , 14.00001 , NaN , 14 , 14 , 14
 15 , 15 , 15 , 15 , 0.9996653 , 15.00001 , NaN , 15 , 15 , 15
 16 , 16.00001 , 16.00001 , 16 , 0.9996804 , 16.00001 , NaN , 16.00001 , 16.00001 , 16
 17 , 17.00001 , 17.00001 , 17.00001 , 0.999688 , 17.00001 , NaN , 17.00001 , 17.00001 , 17.00001
 18 , 18.00001 , 18.00001 , 18.00001 , 0.9996918 , 18.00001 , NaN , 18.00001 , 18.00001 , 18.00001
 19 , 19.00001 , 19.00001 , 19.00001 , 0.9996938 , 19.00002 , NaN , 19.00001 , 19.00001 , 19.00001
 20 , 20.00001 , 20.00001 , 20.00001 , 0.9996947 , 20.00002 , NaN , 20.00001 , 20.00001 , 20.00001
 21 , 21.00001 , 21.00001 , 21.00001 , 0.9996951 , 21.00002 , NaN , 21.00001 , 21.00001 , 21.00001
 22 , 22.00001 , 22.00001 , 22.00001 , 0.9996954 , 22.00002 , NaN , 22.00001 , 22.00001 , 22.00001
 23 , 23.00001 , 23.00001 , 23.00001 , 0.9996954 , 23.00002 , NaN , 23.00001 , 23.00001 , 23.00001
 24 , 24.00002 , 24.00002 , 24.00001 , 0.9996955 , 24.00003 , NaN , 24.00002 , 24.00002 , 24.00001
 25 , 25.00002 , 25.00002 , 25.00001 , 0.9996955 , 25.00003 , NaN , 25.00002 , 25.00002 , 25.00001
 26 , 26.00002 , 26.00002 , 26.00001 , 0.9996955 , 26.00003 , NaN , 26.00002 , 26.00002 , 26.00001
 27 , 27.00002 , 27.00002 , 27.00001 , 0.9996955 , 27.00004 , NaN , 27.00002 , 27.00002 , 27.00001
 28 , 28.00002 , 28.00002 , 28.00002 , 0.9996955 , 28.00004 , NaN , 28.00002 , 28.00002 , 28.00002
 29 , 29.00002 , 29.00002 , 29.00002 , 0.9996955 , 29.00004 , NaN , 29.00002 , 29.00002 , 29.00002
 30 , 30.00002 , 30.00002 , 30.00002 , 0.9996955 , 30.00004 , NaN , 30.00002 , 30.00002 , 30.00002
 31 , 31.00002 , 31.00002 , 31.00002 , 0.9996955 , 31.00004 , NaN , 31.00002 , 31.00002 , 31.00002
 32 , 32.00003 , 32.00003 , 32.00003 , 0.9996955 , 32.00005 , NaN , 32.00003 , 32.00003 , 32.00003
 33 , 33.00003 , 33.00003 , 33.00003 , 0.9996955 , 33.00005 , NaN , 33.00003 , 33.00003 , 33.00003
 34 , 34.00003 , 34.00003 , 34.00003 , 0.9996955 , 34.00005 , NaN , 34.00003 , 34.00003 , 34.00003
 35 , 35.00004 , 35.00004 , 35.00003 , 0.9996955 , 35.00006 , NaN , 35.00004 , 35.00004 , 35.00003
 36 , 36.00004 , 36.00004 , 36.00003 , 0.9996955 , 36.00006 , NaN , 36.00004 , 36.00004 , 36.00003
 37 , 37.00004 , 37.00004 , 37.00003 , 0.9996955 , 37.00006 , NaN , 37.00004 , 37.00004 , 37.00003
 38 , 38.00005 , 38.00005 , 38.00003 , 0.9996955 , 38.00006 , NaN , 38.00005 , 38.00005 , 38.00003
 39 , 39.00005 , 39.00005 , 39.00003 , 0.9996955 , 39.00006 , NaN , 39.00005 , 39.00005 , 39.00004
 40 , 40.00005 , 40.00005 , 40.00003 , 0.9996955 , 40.00006 , NaN , 40.00005 , 40.00005 , 40.00004
 41 , 41.00005 , 41.00005 , 41.00004 , 0.9996955 , 41.00007 , NaN , 41.00005 , 41.00005 , 41.00004
 42 , 42.00005 , 42.00005 , 42.00004 , 0.9996955 , 42.00008 , NaN , 42.00005 , 42.00005 , 42.00004
 43 , 43.00006 , 43.00006 , 43.00005 , 0.9996955 , 43.00008 , NaN , 43.00006 , 43.00006 , 43.00004
 44 , 44.00006 , 44.00006 , 44.00005 , 0.9996955 , 44.00008 , NaN , 44.00006 , 44.00006 , 44.00005
 45 , 45.00006 , 45.00006 , 45.00005 , 0.9996955 , 45.00009 , NaN , 45.00006 , 45.00006 , 45.00005

PS : It doesn't make sense to me ....

Thx
Fingers
Posts: 38
Joined: Thu Feb 10, 2005 10:17 am
Location: South Africa

Post by Fingers »

Then in Prerender or after every update use Rotate on an identity matrix instead of the current relative transformation.
As best as I Can understand, in the rotate function above, ( Matrix4 n ) is created as a Identity matrix...


Another thing, the test results from above, it was turning 1 degree approx every 250ms, and the framerate was about 150fps, so I Changed the speed to ratate every 500ms and the log files matched, (i.e. varing rendering of the objects before turning them didn't make a difference in the results )

** More confused than before **
Post Reply