Page 1 of 1

Convert XNA Framework Quaternion to BEPUutilities.Quaternion

Posted: Tue Sep 20, 2016 11:56 pm
by mos
I need help converting Quaternions. I have this code:

Code: Select all

public static BEPUutilities.Quaternion BEPUQuaternion(Quaternion xnaQuarternion)
{
	BEPUutilities.Quaternion bepuQuaternion = new BEPUutilities.Quaternion();

	bepuQuaternion.W = xnaQuarternion.W;
	bepuQuaternion.X = xnaQuarternion.X;
	bepuQuaternion.Y = xnaQuarternion.Y;
	bepuQuaternion.Z = xnaQuarternion.Z;

	return bepuQuaternion;
}
I use it like this:

Code: Select all

Quaternion rotation = Quaternion.CreateFromYawPitchRoll(0, MathHelper.ToRadians(90), 0)));
body.Box.Orientation = ConvertTo.BEPUQuaternion(rotation);
Box is Box box = new Box(...). When I do this, some of the fields inside of Box end up becoming "NaN" such as the WorldTransform. Subsequently, I'm not able to add it to the world Space because I get an error saying "Function does not accept floating point Not-a-Number values."

How do I convert it correctly?

Re: Convert XNA Framework Quaternion to BEPUutilities.Quater

Posted: Wed Sep 21, 2016 12:11 am
by Norbo
That's the proper conversion; there's nothing tricky about it. Something else is probably going on to trigger the NaNs. Try walking through the code in the debugger to find the first place where they start showing up.

Re: Convert XNA Framework Quaternion to BEPUutilities.Quater

Posted: Wed Sep 21, 2016 12:34 am
by mos
I put break point on each line of the conversion and when I call the conversion method. As soon as it is returned from the Conversion method and goes to the next line after body.Box.Orientation = ConvertTo.BEPUQuaternion(rotation), the values become NaN.

You can see it here:

Image

Re: Convert XNA Framework Quaternion to BEPUutilities.Quater

Posted: Wed Sep 21, 2016 12:46 am
by Norbo
Does the quaternion being set to the property have any nonzero values? The Orientation property normalizes the input, so an invalid zero length quaternion will result in NaNs.

Re: Convert XNA Framework Quaternion to BEPUutilities.Quater

Posted: Wed Sep 21, 2016 12:49 am
by mos
I pass the rotation in the constructor like this: Quaternion rotation = default(Quaternion) as an optional parameter. I set it like this: this.rotation = rotation.

I go through the break points, and if I don't set a rotation the values are zero according to the debugger. So there shouldn't be any negative values.

Re: Convert XNA Framework Quaternion to BEPUutilities.Quater

Posted: Wed Sep 21, 2016 1:16 am
by Norbo
Negative values are okay- the only requirement for orientation quaternions is that it is unit length. So, sqrt(X*X+Y*Y+Z*Z+W*W) == 1. If all components are zero, as is the case when using default(Quaternion), then the length is 0. Passing that into the Orientation property will result in a division by zero, which results in NaNs. If you want a default value for an orientation quaternion, use Quaternion.Identity instead.

Re: Convert XNA Framework Quaternion to BEPUutilities.Quater

Posted: Wed Sep 21, 2016 1:39 am
by mos
Thank you very much! In case I run into another problem like this again, how would I find something like that out? I looked in the method CreateFromYawPitchRoll here: https://bepuphysics.codeplex.com/Source ... ternion.cs but didn't see anything about dividing by zero. Did I not look in the right place?

Re: Convert XNA Framework Quaternion to BEPUutilities.Quater

Posted: Wed Sep 21, 2016 1:59 am
by Norbo
The actual division by zero occurs in the Entity.Orientation property, in the Quaternion.Normalize function.

Unfortunately, when there isn't an explicit error catching mechanism like an exception or assert, it can be difficult to know when you've messed something like this up unless you're already familiar with the underlying math. The library just assumes the user is familiar with how to treat a quaternion as an orientation, and partially trusts them to do things correctly. The same applies for things like the OrientationMatrix. For example, sticking arbitrary values in a Matrix3x3 does not generally result in a rotation matrix; it requires a very specific form (orthonormal with determinant of 1).

Compiling with the CHECKMATH compilation symbol can sometimes catch NaN-related problems nearer to their source with extra asserts, but it doesn't always help with figuring out the underlying mathy reasons.

Re: Convert XNA Framework Quaternion to BEPUutilities.Quater

Posted: Wed Sep 21, 2016 2:15 am
by mos
Ahh ok, that makes sense. I guess I have a bit of reading to do then on what kind of math actually goes on behind the scenes. Thanks again!