Skip to content

Commit 222483d

Browse files
author
Benoit Hudson
committed
API cleanup.
Make some functions public static; make some functions private that were public; add some tests to the public statics.
1 parent 141d821 commit 222483d

File tree

2 files changed

+82
-51
lines changed

2 files changed

+82
-51
lines changed

Assets/FbxExporters/Editor/FbxExporter.cs

Lines changed: 60 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ public class ModelExporter : System.IDisposable
5252
const int UnitScaleFactor = 100;
5353

5454
/// <summary>
55-
/// Create instance of example
55+
/// Create instance of exporter.
5656
/// </summary>
57-
public static ModelExporter Create ()
57+
static ModelExporter Create ()
5858
{
5959
return new ModelExporter ();
6060
}
@@ -119,7 +119,8 @@ public static string GetVersionFromReadme()
119119
}
120120

121121
/// <summary>
122-
/// return layer for mesh
122+
/// Get a layer (to store UVs, normals, etc) on the mesh.
123+
/// If it doesn't exist yet, create it.
123124
/// </summary>
124125
///
125126
public static FbxLayer GetOrCreateLayer(FbxMesh fbxMesh, int layer = 0 /* default layer */)
@@ -135,7 +136,7 @@ public static string GetVersionFromReadme()
135136
/// <summary>
136137
/// Export the mesh's attributes using layer 0.
137138
/// </summary>
138-
public void ExportComponentAttributes (MeshInfo mesh, FbxMesh fbxMesh, int[] unmergedTriangles)
139+
void ExportComponentAttributes (MeshInfo mesh, FbxMesh fbxMesh, int[] unmergedTriangles)
139140
{
140141
// Set the normals on Layer 0.
141142
FbxLayer fbxLayer = GetOrCreateLayer(fbxMesh);
@@ -149,11 +150,11 @@ public void ExportComponentAttributes (MeshInfo mesh, FbxMesh fbxMesh, int[] unm
149150

150151
for (int n = 0; n < unmergedTriangles.Length; n++) {
151152
int unityTriangle = unmergedTriangles [n];
152-
fbxElementArray.Add (CreateRightHandedFbxVector4 (mesh.Normals [unityTriangle]));
153+
fbxElementArray.Add (ConvertNormalToRightHanded (mesh.Normals [unityTriangle]));
153154
}
154155

155-
fbxLayer.SetNormals (fbxLayerElement);
156-
}
156+
fbxLayer.SetNormals (fbxLayerElement);
157+
}
157158

158159
/// Set the binormals on Layer 0.
159160
using (var fbxLayerElement = FbxLayerElementBinormal.Create (fbxMesh, "Binormals"))
@@ -166,7 +167,7 @@ public void ExportComponentAttributes (MeshInfo mesh, FbxMesh fbxMesh, int[] unm
166167

167168
for (int n = 0; n < unmergedTriangles.Length; n++) {
168169
int unityTriangle = unmergedTriangles [n];
169-
fbxElementArray.Add (CreateRightHandedFbxVector4 (mesh.Binormals [unityTriangle]));
170+
fbxElementArray.Add (ConvertNormalToRightHanded (mesh.Binormals [unityTriangle]));
170171
}
171172
fbxLayer.SetBinormals (fbxLayerElement);
172173
}
@@ -182,7 +183,7 @@ public void ExportComponentAttributes (MeshInfo mesh, FbxMesh fbxMesh, int[] unm
182183

183184
for (int n = 0; n < unmergedTriangles.Length; n++) {
184185
int unityTriangle = unmergedTriangles [n];
185-
fbxElementArray.Add (CreateRightHandedFbxVector4(
186+
fbxElementArray.Add (ConvertNormalToRightHanded(
186187
new Vector3(
187188
mesh.Tangents[unityTriangle][0],
188189
mesh.Tangents[unityTriangle][1],
@@ -231,7 +232,7 @@ public void ExportComponentAttributes (MeshInfo mesh, FbxMesh fbxMesh, int[] unm
231232
/// <param name="fbxMesh">Fbx mesh.</param>
232233
/// <param name="mesh">Mesh.</param>
233234
/// <param name="unmergedTriangles">Unmerged triangles.</param>
234-
protected static void ExportUVs(FbxMesh fbxMesh, MeshInfo mesh, int[] unmergedTriangles)
235+
static void ExportUVs(FbxMesh fbxMesh, MeshInfo mesh, int[] unmergedTriangles)
235236
{
236237
Vector2[][] uvs = new Vector2[][] {
237238
mesh.UV,
@@ -275,11 +276,15 @@ protected static void ExportUVs(FbxMesh fbxMesh, MeshInfo mesh, int[] unmergedTr
275276
}
276277

277278
/// <summary>
278-
/// Takes in a left-handed Vector3, and returns a right-handed FbxVector4.
279-
/// Helper for ExportComponentAttributes()
279+
/// Takes in a left-handed UnityEngine.Vector3 denoting a normal,
280+
/// returns a right-handed FbxVector4.
281+
///
282+
/// Unity is left-handed, Maya and Max are right-handed.
283+
/// The FbxSdk conversion routines can't handle changing handedness.
284+
///
285+
/// Remember you also need to flip the winding order on your polygons.
280286
/// </summary>
281-
/// <returns>The right-handed FbxVector4.</returns>
282-
private static FbxVector4 CreateRightHandedFbxVector4(Vector3 leftHandedVector)
287+
public static FbxVector4 ConvertNormalToRightHanded(Vector3 leftHandedVector)
283288
{
284289
// negating the x component of the vector converts it from left to right handed coordinates
285290
return new FbxVector4 (
@@ -289,8 +294,30 @@ private static FbxVector4 CreateRightHandedFbxVector4(Vector3 leftHandedVector)
289294
}
290295

291296
/// <summary>
292-
/// Export an Unity Texture
297+
/// Takes in a left-handed UnityEngine.Vector3 denoting a position,
298+
/// returns a right-handed FbxVector4.
299+
///
300+
/// Unity is left-handed, Maya and Max are right-handed.
301+
/// The FbxSdk conversion routines can't handle changing handedness.
302+
///
303+
/// Remember you also need to flip the winding order on your polygons.
293304
/// </summary>
305+
public static FbxVector4 ConvertPositionToRightHanded(Vector3 leftHandedVector)
306+
{
307+
return UnitScaleFactor * ConvertNormalToRightHanded(leftHandedVector);
308+
}
309+
310+
/// <summary>
311+
/// Exports a texture from Unity to FBX.
312+
/// The texture must be a property on the unityMaterial; it gets
313+
/// linked to the FBX via a property on the fbxMaterial.
314+
///
315+
/// The texture file must be a file on disk; it is not embedded within the FBX.
316+
/// </summary>
317+
/// <param name="unityMaterial">Unity material.</param>
318+
/// <param name="unityPropName">Unity property name, e.g. "_MainTex".</param>
319+
/// <param name="fbxMaterial">Fbx material.</param>
320+
/// <param name="fbxPropName">Fbx property name, e.g. <c>FbxSurfaceMaterial.sDiffuse</c>.</param>
294321
public void ExportTexture (Material unityMaterial, string unityPropName,
295322
FbxSurfaceMaterial fbxMaterial, string fbxPropName)
296323
{
@@ -316,8 +343,9 @@ public void ExportTexture (Material unityMaterial, string unityPropName,
316343
// get absolute filepath to texture
317344
textureSourceFullPath = Path.GetFullPath (textureSourceFullPath);
318345

319-
if (Verbose)
346+
if (Verbose) {
320347
Debug.Log (string.Format ("{2}.{1} setting texture path {0}", textureSourceFullPath, fbxPropName, fbxMaterial.GetName ()));
348+
}
321349

322350
// Find the corresponding property on the fbx material.
323351
var fbxMaterialProperty = fbxMaterial.FindProperty (fbxPropName);
@@ -467,13 +495,13 @@ private void AssignLayerElementMaterial(FbxMesh fbxMesh, Mesh mesh, int material
467495
}
468496

469497
/// <summary>
470-
/// Unconditionally export this mesh object to the file.
471-
/// We have decided; this mesh is definitely getting exported.
498+
/// Export this mesh object to the file.
472499
/// </summary>
473-
public FbxMesh ExportMesh (MeshInfo meshInfo, FbxNode fbxNode, FbxScene fbxScene, bool weldVertices = true)
500+
FbxMesh ExportMesh (MeshInfo meshInfo, FbxNode fbxNode, FbxScene fbxScene, bool weldVertices = true)
474501
{
475-
if (!meshInfo.IsValid)
502+
if (!meshInfo.IsValid) {
476503
return null;
504+
}
477505

478506
NumMeshes++;
479507
NumTriangles += meshInfo.Triangles.Length / 3;
@@ -496,15 +524,9 @@ public FbxMesh ExportMesh (MeshInfo meshInfo, FbxNode fbxNode, FbxScene fbxScene
496524
}
497525
fbxMesh.InitControlPoints (NumControlPoints);
498526

499-
// Copy control point data from Unity to FBX.
500-
// As we do so, scale the points by 100 to convert
501-
// from m to cm.
502527
foreach (var controlPoint in ControlPointToIndex.Keys) {
503-
fbxMesh.SetControlPointAt (new FbxVector4 (
504-
-controlPoint.x*UnitScaleFactor,
505-
controlPoint.y*UnitScaleFactor,
506-
controlPoint.z*UnitScaleFactor
507-
), ControlPointToIndex [controlPoint]);
528+
fbxMesh.SetControlPointAt (ConvertPositionToRightHanded(controlPoint),
529+
ControlPointToIndex [controlPoint]);
508530
}
509531
} else {
510532
NumControlPoints = meshInfo.VertexCount;
@@ -513,12 +535,7 @@ public FbxMesh ExportMesh (MeshInfo meshInfo, FbxNode fbxNode, FbxScene fbxScene
513535
// copy control point data from Unity to FBX
514536
for (int v = 0; v < NumControlPoints; v++)
515537
{
516-
// convert from left to right-handed by negating x (Unity negates x again on import)
517-
fbxMesh.SetControlPointAt(new FbxVector4 (
518-
-meshInfo.Vertices [v].x*UnitScaleFactor,
519-
meshInfo.Vertices [v].y*UnitScaleFactor,
520-
meshInfo.Vertices [v].z*UnitScaleFactor
521-
), v);
538+
fbxMesh.SetControlPointAt(ConvertPositionToRightHanded(meshInfo.Vertices[v]), v);
522539
}
523540
}
524541

@@ -600,7 +617,7 @@ meshInfo.Vertices [v].z*UnitScaleFactor
600617
/// instead of Euler angles, which Maya does not import properly.
601618
/// </summary>
602619
/// <returns>Euler with XYZ rotation order.</returns>
603-
public static FbxDouble3 QuaternionToXYZEuler(Quaternion q)
620+
public static FbxDouble3 ConvertQuaternionToXYZEuler(Quaternion q)
604621
{
605622
FbxQuaternion quat = new FbxQuaternion (q.x, q.y, q.z, q.w);
606623
FbxAMatrix m = new FbxAMatrix ();
@@ -624,41 +641,33 @@ protected void ExportTransform (UnityEngine.Transform unityTransform, FbxNode fb
624641
fbxNode.SetRotationOrder (FbxNode.EPivotSet.eSourcePivot, FbxEuler.EOrder.eOrderXYZ);
625642

626643
UnityEngine.Vector3 unityTranslate;
627-
FbxDouble3 unityRotate;
644+
FbxDouble3 fbxRotate;
628645
UnityEngine.Vector3 unityScale;
629646

630647
switch (exportType) {
631648
case TransformExportType.Reset:
632649
unityTranslate = Vector3.zero;
633-
unityRotate = new FbxDouble3 (0);
650+
fbxRotate = new FbxDouble3 (0);
634651
unityScale = Vector3.one;
635652
break;
636653
case TransformExportType.Global:
637654
unityTranslate = GetRecenteredTranslation(unityTransform, newCenter);
638-
unityRotate = QuaternionToXYZEuler(unityTransform.rotation);
655+
fbxRotate = ConvertQuaternionToXYZEuler(unityTransform.rotation);
639656
unityScale = unityTransform.lossyScale;
640657
break;
641658
default: /*case TransformExportType.Local*/
642659
unityTranslate = unityTransform.localPosition;
643-
unityRotate = QuaternionToXYZEuler(unityTransform.localRotation);
660+
fbxRotate = ConvertQuaternionToXYZEuler(unityTransform.localRotation);
644661
unityScale = unityTransform.localScale;
645662
break;
646663
}
647664

648-
// transfer transform data from Unity to Fbx
649-
// Negating the x value of the translation to convert from Unity
650-
// to Maya coordinates (left to righthanded).
651-
// Scaling the translation by 100 to convert from m to cm.
652-
var fbxTranslate = new FbxDouble3 (
653-
-unityTranslate.x*UnitScaleFactor,
654-
unityTranslate.y*UnitScaleFactor,
655-
unityTranslate.z*UnitScaleFactor
656-
);
657-
var fbxRotate = unityRotate;
665+
// Transfer transform data from Unity to Fbx
666+
var fbxTranslate = ConvertPositionToRightHanded(unityTranslate);
658667
var fbxScale = new FbxDouble3 (unityScale.x, unityScale.y, unityScale.z);
659668

660669
// set the local position of fbxNode
661-
fbxNode.LclTranslation.Set (fbxTranslate);
670+
fbxNode.LclTranslation.Set (new FbxDouble3(fbxTranslate.X, fbxTranslate.Y, fbxTranslate.Z));
662671
fbxNode.LclRotation.Set (fbxRotate);
663672
fbxNode.LclScaling.Set (fbxScale);
664673

@@ -1144,7 +1153,7 @@ public static void DisplayNoSelectionDialog()
11441153
///<summary>
11451154
///Information about the mesh that is important for exporting.
11461155
///</summary>
1147-
public class MeshInfo
1156+
class MeshInfo
11481157
{
11491158
/// <summary>
11501159
/// The transform of the mesh.

Assets/FbxExporters/Editor/UnitTests/ModelExporterTest.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public void TestBasics ()
2222
{
2323
Assert.That(!string.IsNullOrEmpty(ModelExporter.GetVersionFromReadme()));
2424

25+
// Test GetOrCreateLayer
2526
using (var fbxManager = FbxManager.Create()) {
2627
var fbxMesh = FbxMesh.Create(fbxManager, "name");
2728
var layer0 = ModelExporter.GetOrCreateLayer(fbxMesh);
@@ -31,6 +32,27 @@ public void TestBasics ()
3132
Assert.That(layer5, Is.Not.Null);
3233
Assert.That(layer5, Is.Not.EqualTo(layer0));
3334
}
35+
36+
// Test axis conversion: a x b in left-handed is the same as b x a
37+
// in right-handed (that's why we need to flip the winding order).
38+
var a = new Vector3(1,0,0);
39+
var b = new Vector3(0,0,1);
40+
var crossLeft = Vector3.Cross(a,b);
41+
42+
var afbx = ModelExporter.ConvertNormalToRightHanded(a);
43+
var bfbx = ModelExporter.ConvertNormalToRightHanded(b);
44+
Assert.AreEqual(ModelExporter.ConvertNormalToRightHanded(crossLeft), bfbx.CrossProduct(afbx));
45+
46+
// Test scale conversion. Nothing complicated here...
47+
var afbxPosition = ModelExporter.ConvertPositionToRightHanded(a);
48+
Assert.AreEqual(100, afbxPosition.Length());
49+
50+
// Test rotation conversion.
51+
var q = Quaternion.Euler(new Vector3(0, 90, 0));
52+
var fbxAngles = ModelExporter.ConvertQuaternionToXYZEuler(q);
53+
Assert.AreEqual(fbxAngles.X, 0);
54+
Assert.That(fbxAngles.Y, Is.InRange(-90.001, -89.999));
55+
Assert.AreEqual(fbxAngles.Z, 0);
3456
}
3557

3658
[Test]

0 commit comments

Comments
 (0)