Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coordinate System #257

Closed
Jennilein1991 opened this issue Sep 28, 2018 · 8 comments
Closed

Coordinate System #257

Jennilein1991 opened this issue Sep 28, 2018 · 8 comments

Comments

@Jennilein1991
Copy link

Hello :)
Is it right, that UnityGLTF is using a right coordinate system with y down?
So y down, x to the right and z to the screen.

I am asking since i saw in your code that you are using a 180 degree rotation around x to transform Unity coord to yours.

Jenni

@dave-hill
Copy link
Contributor

Hi Jenni,

Unity's coordinate system is left-handed, and glTF's coordinate system is right-handed. UnityGLTF converts between these coordinate systems on import an export by inverting the x component of positions and directions. You can see where this is defined in SchemaExtensions.cs.

// glTF matrix: column vectors, column-major storage, +Y up, +Z forward, -X right, right-handed
// unity matrix: column vectors, column-major storage, +Y up, +Z forward, +X right, left-handed
// multiply by a negative X scale to convert handedness
public static readonly GLTF.Math.Vector3 CoordinateSpaceConversionScale = new GLTF.Math.Vector3(-1, 1, 1);

You can see this being used in GLTFSceneImporter.TransformAttributes and GLTFSceneExporter.TransformAttributes.

Have you been experiencing issues when importing/exporting models? Could you provide any more info on where there's a 180° rotation in the code?

Thanks,
Dave

@Jennilein1991
Copy link
Author

Jennilein1991 commented Oct 5, 2018

Thanks for the answer!
By a 180 degree rotation I mean this part of code :

public static GLTF.Math.Quaternion ToGltfQuaternionConvert(this Quaternion unityQuat)
		{
			// get the original axis and apply conversion scale as well as potential rotation axis flip
			Vector3 origAxis = new Vector3(unityQuat.x, unityQuat.y, unityQuat.z);
			float axisFlipScale = CoordinateSpaceConversionRequiresHandednessFlip ? -1.0f : 1.0f;
			Vector3 newAxis = axisFlipScale * Vector3.Scale(origAxis, CoordinateSpaceConversionScale.ToUnityVector3Raw());

			// then put the quaternion back together and return it
			return new GLTF.Math.Quaternion(newAxis.x, newAxis.y, newAxis.z, unityQuat.w);
		}

By applying this method a 180 degree rotation around the x axis is applied.
This is necessary to convert the rotation from right handed to left handed?

@bghgary
Copy link
Contributor

bghgary commented Oct 5, 2018

A positive rotation in Unity rotates clockwise, while a positive rotation in glTF rotates counterclockwise. To convert from Unity's Quaternion rotations to glTF, the code should flip the direction of rotation. This can be done for example by negating the (y and z) or (x and w) components of a quaternion.

Edit: fixed axes because of the forward convention

@Jennilein1991
Copy link
Author

A positive rotation in Unity rotates clockwise, while a positive rotation in glTF rotates counterclockwise. To convert from Unity's Quaternion rotations to glTF, the code should flip the direction of rotation. This can be done for example by negating the (x and y) or (z and w) components of a quaternion.

But by calculation the variable newAxis the y and z axis gets negated, right?
Because when we have an origAxis = (x, y, z) then after Vector3.Scale(origAxis, CoordinateSpaceConversionScale.ToUnityVector3Raw()) we have (-x, y, z). And after doing the axisFlipScale it goes to (x, -y, -z), right?

@Jennilein1991
Copy link
Author

Jennilein1991 commented Nov 11, 2018

Hi Jenni,

Unity's coordinate system is left-handed, and glTF's coordinate system is right-handed. UnityGLTF converts between these coordinate systems on import an export by inverting the x component of positions and directions. You can see where this is defined in SchemaExtensions.cs.

// glTF matrix: column vectors, column-major storage, +Y up, +Z forward, -X right, right-handed
// unity matrix: column vectors, column-major storage, +Y up, +Z forward, +X right, left-handed
// multiply by a negative X scale to convert handedness
public static readonly GLTF.Math.Vector3 CoordinateSpaceConversionScale = new GLTF.Math.Vector3(-1, 1, 1);

You can see this being used in GLTFSceneImporter.TransformAttributes and GLTFSceneExporter.TransformAttributes.

Have you been experiencing issues when importing/exporting models? Could you provide any more info on where there's a 180° rotation in the code?

Thanks,
Dave

In GLTFSceneExporter the function TransformAttributes does not exist, right? So where is this transformation done?

@bghgary
Copy link
Contributor

bghgary commented Nov 12, 2018

Sorry, I didn't mean the code is necessarily doing it correctly. @dave-hill Can you investigate?

@dave-hill
Copy link
Contributor

dave-hill commented Nov 13, 2018

Sure thing, thanks Gary.

Hi Jenni, you're right that the net result of the logic in ToGltfQuaternionConvert is to negate the y and z components of the rotation quaternion. This turns a clockwise rotation into a counter-clockwise rotation and vice-versa, as Gary described. I've just been testing this code by exporting a scene with various rotations and verified that the output result was correct each time. Note that negating the components of a quaternion doesn't behave in the same way as negating the components of a position vector - the rotation direction is mirrored rather than applying a 180° rotation.

Could you tell me a bit more about any issue you're seeing here, and maybe some repro steps? Are you seeing incorrect rotations when importing or exporting to glTF? Or did the code just look weird and you just wanted to make sure it was right? It took me a while to work out what was going on in that function!

Edit: After writing this, I dug further into the code and wrote a bit more about what the code is doing as a comment to #256. I think the code is correct and we can consider closing these issues after giving people a chance to comment.

Thanks,
Dave

@dave-hill
Copy link
Contributor

I've just created PR #294 to add some comments to help explain how some of this math works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants