Skip to content

Commit 99cc95f

Browse files
committed
deepconvert instead of converting while creating scene
1 parent 9383351 commit 99cc95f

File tree

2 files changed

+40
-86
lines changed

2 files changed

+40
-86
lines changed

com.unity.formats.fbx/Editor/FbxExporter.cs

Lines changed: 37 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ private bool ExportComponentAttributes (MeshInfo mesh, FbxMesh fbxMesh, int[] un
329329

330330
for (int n = 0; n < unmergedTriangles.Length; n++) {
331331
int unityTriangle = unmergedTriangles [n];
332-
fbxElementArray.Add (ConvertToRightHanded (mesh.Normals [unityTriangle]));
332+
fbxElementArray.Add (ConvertToFbxVector4 (mesh.Normals [unityTriangle]));
333333
}
334334

335335
fbxLayer.SetNormals (fbxLayerElement);
@@ -348,7 +348,7 @@ private bool ExportComponentAttributes (MeshInfo mesh, FbxMesh fbxMesh, int[] un
348348

349349
for (int n = 0; n < unmergedTriangles.Length; n++) {
350350
int unityTriangle = unmergedTriangles [n];
351-
fbxElementArray.Add (ConvertToRightHanded (mesh.Binormals [unityTriangle]));
351+
fbxElementArray.Add (ConvertToFbxVector4 (mesh.Binormals [unityTriangle]));
352352
}
353353
fbxLayer.SetBinormals (fbxLayerElement);
354354
}
@@ -366,7 +366,7 @@ private bool ExportComponentAttributes (MeshInfo mesh, FbxMesh fbxMesh, int[] un
366366

367367
for (int n = 0; n < unmergedTriangles.Length; n++) {
368368
int unityTriangle = unmergedTriangles [n];
369-
fbxElementArray.Add (ConvertToRightHanded (
369+
fbxElementArray.Add (ConvertToFbxVector4 (
370370
new Vector3 (
371371
mesh.Tangents [unityTriangle] [0],
372372
mesh.Tangents [unityTriangle] [1],
@@ -507,7 +507,7 @@ private bool ExportBlendShapes(MeshInfo mesh, FbxMesh fbxMesh, FbxScene fbxScene
507507
{
508508
int ni = ControlPointToIndex[basePoints[vi]];
509509
var v = basePoints[vi] + deltaPoints[vi];
510-
fbxShape.SetControlPointAt(ConvertToRightHanded(v, UnitScaleFactor), ni);
510+
fbxShape.SetControlPointAt(ConvertToFbxVector4(v, UnitScaleFactor), ni);
511511
}
512512

513513
// normals
@@ -522,7 +522,7 @@ private bool ExportBlendShapes(MeshInfo mesh, FbxMesh fbxMesh, FbxScene fbxScene
522522
{
523523
int vi = unmergedTriangles[ii];
524524
var n = baseNormals[vi] + deltaNormals[vi];
525-
dstNormals.SetAt(ii, ConvertToRightHanded(n));
525+
dstNormals.SetAt(ii, ConvertToFbxVector4(n));
526526
}
527527
}
528528

@@ -538,7 +538,7 @@ private bool ExportBlendShapes(MeshInfo mesh, FbxMesh fbxMesh, FbxScene fbxScene
538538
{
539539
int vi = unmergedTriangles[ii];
540540
var t = (Vector3)baseTangents[vi] + deltaTangents[vi];
541-
dstTangents.SetAt(ii, ConvertToRightHanded(t));
541+
dstTangents.SetAt(ii, ConvertToFbxVector4(t));
542542
}
543543
}
544544
}
@@ -555,11 +555,11 @@ private bool ExportBlendShapes(MeshInfo mesh, FbxMesh fbxMesh, FbxScene fbxScene
555555
///
556556
/// Remember you also need to flip the winding order on your polygons.
557557
/// </summary>
558-
internal static FbxVector4 ConvertToRightHanded(Vector3 leftHandedVector, float unitScale = 1f)
558+
internal static FbxVector4 ConvertToFbxVector4(Vector3 leftHandedVector, float unitScale = 1f)
559559
{
560560
// negating the x component of the vector converts it from left to right handed coordinates
561561
return unitScale * new FbxVector4 (
562-
-leftHandedVector[0],
562+
leftHandedVector[0],
563563
leftHandedVector[1],
564564
leftHandedVector[2]);
565565
}
@@ -813,7 +813,7 @@ bool ExportMesh (MeshInfo meshInfo, FbxNode fbxNode)
813813
foreach (var kvp in ControlPointToIndex) {
814814
var controlPoint = kvp.Key;
815815
var index = kvp.Value;
816-
fbxMesh.SetControlPointAt (ConvertToRightHanded(controlPoint, UnitScaleFactor), index);
816+
fbxMesh.SetControlPointAt (ConvertToFbxVector4(controlPoint, UnitScaleFactor), index);
817817
}
818818
}
819819

@@ -830,12 +830,14 @@ bool ExportMesh (MeshInfo meshInfo, FbxNode fbxNode)
830830
case MeshTopology.Triangles:
831831
polySize = 3;
832832
// flip winding order so that Maya and Unity import it properly
833-
vertOrder = new int[] { 0, 2, 1 };
833+
//vertOrder = new int[] { 0, 2, 1 };
834+
vertOrder = new int[] { 0, 1, 2 };
834835
break;
835836
case MeshTopology.Quads:
836837
polySize = 4;
837838
// flip winding order so that Maya and Unity import it properly
838-
vertOrder = new int[] { 0, 3, 2, 1 };
839+
//vertOrder = new int[] { 0, 3, 2, 1 };
840+
vertOrder = new int[] { 0, 1, 2, 3 };
839841
break;
840842
case MeshTopology.Lines:
841843
throw new System.NotImplementedException();
@@ -1139,39 +1141,7 @@ private bool ExportBindPose (SkinnedMeshRenderer skinnedMesh, FbxNode fbxMeshNod
11391141

11401142
return true;
11411143
}
1142-
1143-
/// <summary>
1144-
/// Takes a Quaternion and returns a Euler with XYZ rotation order.
1145-
/// Also converts from left (Unity) to righthanded (Maya) coordinates.
1146-
///
1147-
/// Note: Cannot simply use the FbxQuaternion.DecomposeSphericalXYZ()
1148-
/// function as this returns the angle in spherical coordinates
1149-
/// instead of Euler angles, which Maya does not import properly.
1150-
/// </summary>
1151-
/// <returns>Euler with XYZ rotation order.</returns>
1152-
internal static FbxDouble3 ConvertQuaternionToXYZEuler(Quaternion q)
1153-
{
1154-
FbxQuaternion quat = new FbxQuaternion (q.x, q.y, q.z, q.w);
1155-
FbxAMatrix m = new FbxAMatrix ();
1156-
m.SetQ (quat);
1157-
var vector4 = m.GetR ();
1158-
1159-
// Negate the y and z values of the rotation to convert
1160-
// from Unity to Maya coordinates (left to righthanded).
1161-
return new FbxDouble3 (vector4.X, -vector4.Y, -vector4.Z);
1162-
}
1163-
1164-
internal static FbxVector4 ConvertQuaternionToXYZEuler (FbxQuaternion quat)
1165-
{
1166-
FbxAMatrix m = new FbxAMatrix ();
1167-
m.SetQ (quat);
1168-
var vector4 = m.GetR ();
1169-
1170-
// Negate the y and z values of the rotation to convert
1171-
// from Unity to Maya coordinates (left to righthanded).
1172-
return new FbxVector4 (vector4.X, -vector4.Y, -vector4.Z, vector4.W);
1173-
}
1174-
1144+
11751145
internal static FbxDouble3 ToFbxDouble3(Vector3 v)
11761146
{
11771147
return new FbxDouble3(v.x, v.y, v.z);
@@ -1187,13 +1157,6 @@ internal static FbxVector4 ToFbxVector4(FbxDouble3 v)
11871157
return new FbxVector4(v.X, v.Y, v.Z);
11881158
}
11891159

1190-
internal static FbxDouble3 ConvertToRightHandedEuler(Vector3 rot)
1191-
{
1192-
rot.y *= -1;
1193-
rot.z *= -1;
1194-
return ToFbxDouble3(rot);
1195-
}
1196-
11971160
/// <summary>
11981161
/// Euler to quaternion without axis conversion.
11991162
/// </summary>
@@ -1227,7 +1190,7 @@ internal bool ExportTransform (UnityEngine.Transform unityTransform, FbxNode fbx
12271190
// Fixed by exporting the rotations as eulers with XYZ rotation order.
12281191
// Can't just set the rotation order to ZXY on export as Maya incorrectly imports the
12291192
// rotation. Appears to first convert to XYZ rotation then set rotation order to ZXY.
1230-
fbxNode.SetRotationOrder (FbxNode.EPivotSet.eSourcePivot, FbxEuler.EOrder.eOrderXYZ);
1193+
fbxNode.SetRotationOrder (FbxNode.EPivotSet.eSourcePivot, FbxEuler.EOrder.eOrderZXY);
12311194

12321195
UnityEngine.Vector3 unityTranslate;
12331196
FbxDouble3 fbxRotate;
@@ -1241,18 +1204,18 @@ internal bool ExportTransform (UnityEngine.Transform unityTransform, FbxNode fbx
12411204
break;
12421205
case TransformExportType.Global:
12431206
unityTranslate = GetRecenteredTranslation(unityTransform, newCenter);
1244-
fbxRotate = ConvertQuaternionToXYZEuler(unityTransform.rotation);
1207+
fbxRotate = ToFbxDouble3(unityTransform.eulerAngles);
12451208
unityScale = unityTransform.lossyScale;
12461209
break;
12471210
default: /*case TransformExportType.Local*/
12481211
unityTranslate = unityTransform.localPosition;
1249-
fbxRotate = ConvertQuaternionToXYZEuler(unityTransform.localRotation);
1212+
fbxRotate = ToFbxDouble3(unityTransform.localEulerAngles);
12501213
unityScale = unityTransform.localScale;
12511214
break;
12521215
}
12531216

12541217
// Transfer transform data from Unity to Fbx
1255-
var fbxTranslate = ConvertToRightHanded(unityTranslate, UnitScaleFactor);
1218+
var fbxTranslate = ConvertToFbxVector4(unityTranslate, UnitScaleFactor);
12561219
var fbxScale = new FbxDouble3 (unityScale.x, unityScale.y, unityScale.z);
12571220

12581221
// set the local position of fbxNode
@@ -1520,11 +1483,11 @@ private bool ExportPositionConstraint(IConstraint uniConstraint, FbxScene fbxSce
15201483
fbxPosConstraint.AffectY.Set((uniAffectedAxes & Axis.Y) == Axis.Y);
15211484
fbxPosConstraint.AffectZ.Set((uniAffectedAxes & Axis.Z) == Axis.Z);
15221485

1523-
var fbxTranslationOffset = ConvertToRightHanded(uniPosConstraint.translationOffset, UnitScaleFactor);
1486+
var fbxTranslationOffset = ConvertToFbxVector4(uniPosConstraint.translationOffset, UnitScaleFactor);
15241487
fbxPosConstraint.Translation.Set(ToFbxDouble3(fbxTranslationOffset));
15251488

15261489
// rest position is the position of the fbx node
1527-
var fbxRestTranslation = ConvertToRightHanded(uniPosConstraint.translationAtRest, UnitScaleFactor);
1490+
var fbxRestTranslation = ConvertToFbxVector4(uniPosConstraint.translationAtRest, UnitScaleFactor);
15281491
// set the local position of fbxNode
15291492
fbxNode.LclTranslation.Set(ToFbxDouble3(fbxRestTranslation));
15301493
return true;
@@ -1553,13 +1516,12 @@ private bool ExportRotationConstraint(IConstraint uniConstraint, FbxScene fbxSce
15531516

15541517
// Not converting rotation offset to XYZ euler as it gives the incorrect result in both Maya and Unity.
15551518
var uniRotationOffset = uniRotConstraint.rotationOffset;
1556-
var fbxRotationOffset = ConvertToRightHandedEuler(uniRotationOffset);
1519+
var fbxRotationOffset = ToFbxDouble3(uniRotationOffset);
15571520

15581521
fbxRotConstraint.Rotation.Set(fbxRotationOffset);
15591522

15601523
// rest rotation is the rotation of the fbx node
1561-
var uniRestRotationQuat = Quaternion.Euler(uniRotConstraint.rotationAtRest);
1562-
var fbxRestRotation = ConvertQuaternionToXYZEuler(uniRestRotationQuat);
1524+
var fbxRestRotation = ToFbxDouble3(uniRotConstraint.rotationAtRest);
15631525
// set the local rotation of fbxNode
15641526
fbxNode.LclRotation.Set(fbxRestRotation);
15651527
return true;
@@ -1620,12 +1582,11 @@ private bool ExportAimConstraint(IConstraint uniConstraint, FbxScene fbxScene, F
16201582
fbxAimConstraint.AffectZ.Set((uniAffectedAxes & Axis.Z) == Axis.Z);
16211583

16221584
var uniRotationOffset = uniAimConstraint.rotationOffset;
1623-
var fbxRotationOffset = ConvertToRightHandedEuler(uniRotationOffset);
1585+
var fbxRotationOffset = ToFbxDouble3(uniRotationOffset);
16241586
fbxAimConstraint.RotationOffset.Set(fbxRotationOffset);
16251587

16261588
// rest rotation is the rotation of the fbx node
1627-
var uniRestRotationQuat = Quaternion.Euler(uniAimConstraint.rotationAtRest);
1628-
var fbxRestRotation = ConvertQuaternionToXYZEuler(uniRestRotationQuat);
1589+
var fbxRestRotation = ToFbxDouble3(uniAimConstraint.rotationAtRest);
16291590
// set the local rotation of fbxNode
16301591
fbxNode.LclRotation.Set(fbxRestRotation);
16311592

@@ -1652,7 +1613,7 @@ private bool ExportAimConstraint(IConstraint uniConstraint, FbxScene fbxScene, F
16521613
}
16531614
fbxAimConstraint.WorldUpType.Set((int)fbxWorldUpType);
16541615

1655-
var uniAimVector = ConvertToRightHanded(uniAimConstraint.aimVector);
1616+
var uniAimVector = ConvertToFbxVector4(uniAimConstraint.aimVector);
16561617
fbxAimConstraint.AimVector.Set(ToFbxDouble3(uniAimVector));
16571618
fbxAimConstraint.UpVector.Set(ToFbxDouble3(uniAimConstraint.upVector));
16581619
fbxAimConstraint.WorldUpVector.Set(ToFbxDouble3(uniAimConstraint.worldUpVector));
@@ -1687,10 +1648,10 @@ private bool ExportParentConstraint(IConstraint uniConstraint, FbxScene fbxScene
16871648

16881649
fbxParentConstraint.AddConstraintSource(uniSource.node, uniSource.weight);
16891650

1690-
var fbxTranslationOffset = ConvertToRightHanded(uniTranslationOffset, UnitScaleFactor);
1651+
var fbxTranslationOffset = ConvertToFbxVector4(uniTranslationOffset, UnitScaleFactor);
16911652
fbxParentConstraint.SetTranslationOffset(uniSource.node, fbxTranslationOffset);
16921653

1693-
var fbxRotationOffset = ToFbxVector4(ConvertToRightHandedEuler(uniRotationOffset));
1654+
var fbxRotationOffset = ToFbxVector4(ToFbxDouble3(uniRotationOffset));
16941655
fbxParentConstraint.SetRotationOffset(uniSource.node, fbxRotationOffset);
16951656
}
16961657
ExportCommonConstraintProperties(uniParentConstraint, fbxParentConstraint, fbxNode);
@@ -1706,13 +1667,12 @@ private bool ExportParentConstraint(IConstraint uniConstraint, FbxScene fbxScene
17061667
fbxParentConstraint.AffectRotationZ.Set((uniRotationAxes & Axis.Z) == Axis.Z);
17071668

17081669
// rest position is the position of the fbx node
1709-
var fbxRestTranslation = ConvertToRightHanded(uniParentConstraint.translationAtRest, UnitScaleFactor);
1670+
var fbxRestTranslation = ConvertToFbxVector4(uniParentConstraint.translationAtRest, UnitScaleFactor);
17101671
// set the local position of fbxNode
17111672
fbxNode.LclTranslation.Set(ToFbxDouble3(fbxRestTranslation));
17121673

17131674
// rest rotation is the rotation of the fbx node
1714-
var uniRestRotationQuat = Quaternion.Euler(uniParentConstraint.rotationAtRest);
1715-
var fbxRestRotation = ConvertQuaternionToXYZEuler(uniRestRotationQuat);
1675+
var fbxRestRotation = ToFbxDouble3(uniParentConstraint.rotationAtRest);
17161676
// set the local rotation of fbxNode
17171677
fbxNode.LclRotation.Set(fbxRestRotation);
17181678
return true;
@@ -2016,11 +1976,6 @@ public UnityToMayaConvertSceneHelper(string uniPropertyName)
20161976
System.StringComparison cc = System.StringComparison.CurrentCulture;
20171977

20181978
bool partT = uniPropertyName.StartsWith("m_LocalPosition.", cc) || uniPropertyName.StartsWith("m_TranslationOffset", cc);
2019-
bool partTx = uniPropertyName.EndsWith("Position.x", cc) || uniPropertyName.EndsWith("T.x", cc) || (uniPropertyName.StartsWith("m_TranslationOffset") && uniPropertyName.EndsWith(".x", cc));
2020-
bool partRyz = uniPropertyName.StartsWith("m_RotationOffset", cc) && (uniPropertyName.EndsWith(".y") || uniPropertyName.EndsWith(".z"));
2021-
2022-
convertLtoR |= partTx;
2023-
convertLtoR |= partRyz;
20241979

20251980
convertDistance |= partT;
20261981
convertDistance |= uniPropertyName.StartsWith ("m_Intensity", cc);
@@ -2032,9 +1987,6 @@ public UnityToMayaConvertSceneHelper(string uniPropertyName)
20321987
if (convertDistance)
20331988
unitScaleFactor = ModelExporter.UnitScaleFactor;
20341989

2035-
if (convertLtoR)
2036-
unitScaleFactor = -unitScaleFactor;
2037-
20381990
if (convertToRadian)
20391991
{
20401992
unitScaleFactor *= (Mathf.PI / 180);
@@ -2891,14 +2843,14 @@ private bool ExportBoneTransform(
28912843

28922844
// Export bones with zero rotation, using a pivot instead to set the rotation
28932845
// so that the bones are easier to animate and the rotation shows up as the "joint orientation" in Maya.
2894-
fbxNode.LclTranslation.Set (new FbxDouble3(-translation.X*UnitScaleFactor, translation.Y*UnitScaleFactor, translation.Z*UnitScaleFactor));
2846+
fbxNode.LclTranslation.Set (new FbxDouble3(translation.X*UnitScaleFactor, translation.Y*UnitScaleFactor, translation.Z*UnitScaleFactor));
28952847
fbxNode.LclRotation.Set (new FbxDouble3(0,0,0));
28962848
fbxNode.LclScaling.Set (new FbxDouble3 (scale.X, scale.Y, scale.Z));
28972849

28982850
// TODO (UNI-34294): add detailed comment about why we export rotation as pre-rotation
28992851
fbxNode.SetRotationActive (true);
29002852
fbxNode.SetPivotState (FbxNode.EPivotSet.eSourcePivot, FbxNode.EPivotState.ePivotReference);
2901-
fbxNode.SetPreRotation (FbxNode.EPivotSet.eSourcePivot, new FbxVector4 (rotation.X, -rotation.Y, -rotation.Z));
2853+
fbxNode.SetPreRotation (FbxNode.EPivotSet.eSourcePivot, new FbxVector4 (rotation.X, rotation.Y, rotation.Z));
29022854

29032855
return true;
29042856
}
@@ -3392,7 +3344,10 @@ internal int ExportAll (
33923344
// The Maya axis system has Y up, Z forward, X to the left (right handed system with odd parity).
33933345
// We need to export right-handed for Maya because ConvertScene can't switch handedness:
33943346
// https://forums.autodesk.com/t5/fbx-forum/get-confused-with-fbxaxissystem-convertscene/td-p/4265472
3395-
fbxSettings.SetAxisSystem (FbxAxisSystem.MayaYUp);
3347+
fbxSettings.SetAxisSystem (new FbxAxisSystem(
3348+
FbxAxisSystem.EUpVector.eYAxis,
3349+
(FbxAxisSystem.EFrontVector)(-((int)FbxAxisSystem.EFrontVector.eParityOdd)),
3350+
FbxAxisSystem.ECoordSystem.eLeftHanded));
33963351

33973352
// export set of object
33983353
FbxNode fbxRootNode = fbxScene.GetRootNode ();
@@ -3476,6 +3431,8 @@ internal int ExportAll (
34763431
// Set the scene's default camera.
34773432
SetDefaultCamera (fbxScene);
34783433

3434+
FbxAxisSystem.MayaYUp.DeepConvertScene(fbxScene);
3435+
34793436
// Export the scene to the file.
34803437
status = fbxExporter.Export (fbxScene);
34813438

com.unity.formats.fbx/Editor/FbxRotationCurve.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,14 @@ protected override FbxQuaternion GetConvertedQuaternionRotation (float seconds,
170170
// The final animation, including the effect of pre-rotation.
171171
// If we have no curve, assume the node has the correct rotation right now.
172172
// We need to evaluate since we might only have keys in one of the axes.
173-
var unityFinalAnimation = Quaternion.Euler (
173+
var unityFinalAnimation = new Vector3 (
174174
(x == null) ? eulerRest [0] : x.Evaluate (seconds),
175175
(y == null) ? eulerRest [1] : y.Evaluate (seconds),
176176
(z == null) ? eulerRest [2] : z.Evaluate (seconds)
177177
);
178178

179179
// convert the final animation to righthanded coords
180-
var finalEuler = ModelExporter.ConvertQuaternionToXYZEuler(unityFinalAnimation);
180+
var finalEuler = ModelExporter.ToFbxDouble3(unityFinalAnimation);
181181

182182
return ModelExporter.EulerToQuaternion (new FbxVector4(finalEuler));
183183
}
@@ -236,10 +236,7 @@ protected override FbxQuaternion GetConvertedQuaternionRotation (float seconds,
236236
(z == null) ? restRotation[2] : z.Evaluate(seconds),
237237
(w == null) ? restRotation[3] : w.Evaluate(seconds));
238238

239-
// convert the final animation to righthanded coords
240-
var finalEuler = ModelExporter.ConvertQuaternionToXYZEuler(fbxFinalAnimation);
241-
242-
return ModelExporter.EulerToQuaternion (finalEuler);
239+
return fbxFinalAnimation;
243240
}
244241
}
245242

0 commit comments

Comments
 (0)