@@ -52,9 +52,9 @@ public class ModelExporter : System.IDisposable
52
52
const int UnitScaleFactor = 100 ;
53
53
54
54
/// <summary>
55
- /// Create instance of example
55
+ /// Create instance of exporter.
56
56
/// </summary>
57
- public static ModelExporter Create ( )
57
+ static ModelExporter Create ( )
58
58
{
59
59
return new ModelExporter ( ) ;
60
60
}
@@ -119,7 +119,8 @@ public static string GetVersionFromReadme()
119
119
}
120
120
121
121
/// <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.
123
124
/// </summary>
124
125
///
125
126
public static FbxLayer GetOrCreateLayer ( FbxMesh fbxMesh , int layer = 0 /* default layer */ )
@@ -135,7 +136,7 @@ public static string GetVersionFromReadme()
135
136
/// <summary>
136
137
/// Export the mesh's attributes using layer 0.
137
138
/// </summary>
138
- public void ExportComponentAttributes ( MeshInfo mesh , FbxMesh fbxMesh , int [ ] unmergedTriangles )
139
+ void ExportComponentAttributes ( MeshInfo mesh , FbxMesh fbxMesh , int [ ] unmergedTriangles )
139
140
{
140
141
// Set the normals on Layer 0.
141
142
FbxLayer fbxLayer = GetOrCreateLayer ( fbxMesh ) ;
@@ -149,11 +150,11 @@ public void ExportComponentAttributes (MeshInfo mesh, FbxMesh fbxMesh, int[] unm
149
150
150
151
for ( int n = 0 ; n < unmergedTriangles . Length ; n ++ ) {
151
152
int unityTriangle = unmergedTriangles [ n ] ;
152
- fbxElementArray . Add ( CreateRightHandedFbxVector4 ( mesh . Normals [ unityTriangle ] ) ) ;
153
+ fbxElementArray . Add ( ConvertNormalToRightHanded ( mesh . Normals [ unityTriangle ] ) ) ;
153
154
}
154
155
155
- fbxLayer . SetNormals ( fbxLayerElement ) ;
156
- }
156
+ fbxLayer . SetNormals ( fbxLayerElement ) ;
157
+ }
157
158
158
159
/// Set the binormals on Layer 0.
159
160
using ( var fbxLayerElement = FbxLayerElementBinormal . Create ( fbxMesh , "Binormals" ) )
@@ -166,7 +167,7 @@ public void ExportComponentAttributes (MeshInfo mesh, FbxMesh fbxMesh, int[] unm
166
167
167
168
for ( int n = 0 ; n < unmergedTriangles . Length ; n ++ ) {
168
169
int unityTriangle = unmergedTriangles [ n ] ;
169
- fbxElementArray . Add ( CreateRightHandedFbxVector4 ( mesh . Binormals [ unityTriangle ] ) ) ;
170
+ fbxElementArray . Add ( ConvertNormalToRightHanded ( mesh . Binormals [ unityTriangle ] ) ) ;
170
171
}
171
172
fbxLayer . SetBinormals ( fbxLayerElement ) ;
172
173
}
@@ -182,7 +183,7 @@ public void ExportComponentAttributes (MeshInfo mesh, FbxMesh fbxMesh, int[] unm
182
183
183
184
for ( int n = 0 ; n < unmergedTriangles . Length ; n ++ ) {
184
185
int unityTriangle = unmergedTriangles [ n ] ;
185
- fbxElementArray . Add ( CreateRightHandedFbxVector4 (
186
+ fbxElementArray . Add ( ConvertNormalToRightHanded (
186
187
new Vector3 (
187
188
mesh . Tangents [ unityTriangle ] [ 0 ] ,
188
189
mesh . Tangents [ unityTriangle ] [ 1 ] ,
@@ -231,7 +232,7 @@ public void ExportComponentAttributes (MeshInfo mesh, FbxMesh fbxMesh, int[] unm
231
232
/// <param name="fbxMesh">Fbx mesh.</param>
232
233
/// <param name="mesh">Mesh.</param>
233
234
/// <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 )
235
236
{
236
237
Vector2 [ ] [ ] uvs = new Vector2 [ ] [ ] {
237
238
mesh . UV ,
@@ -275,11 +276,15 @@ protected static void ExportUVs(FbxMesh fbxMesh, MeshInfo mesh, int[] unmergedTr
275
276
}
276
277
277
278
/// <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.
280
286
/// </summary>
281
- /// <returns>The right-handed FbxVector4.</returns>
282
- private static FbxVector4 CreateRightHandedFbxVector4 ( Vector3 leftHandedVector )
287
+ public static FbxVector4 ConvertNormalToRightHanded ( Vector3 leftHandedVector )
283
288
{
284
289
// negating the x component of the vector converts it from left to right handed coordinates
285
290
return new FbxVector4 (
@@ -289,8 +294,30 @@ private static FbxVector4 CreateRightHandedFbxVector4(Vector3 leftHandedVector)
289
294
}
290
295
291
296
/// <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.
293
304
/// </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>
294
321
public void ExportTexture ( Material unityMaterial , string unityPropName ,
295
322
FbxSurfaceMaterial fbxMaterial , string fbxPropName )
296
323
{
@@ -316,8 +343,9 @@ public void ExportTexture (Material unityMaterial, string unityPropName,
316
343
// get absolute filepath to texture
317
344
textureSourceFullPath = Path . GetFullPath ( textureSourceFullPath ) ;
318
345
319
- if ( Verbose )
346
+ if ( Verbose ) {
320
347
Debug . Log ( string . Format ( "{2}.{1} setting texture path {0}" , textureSourceFullPath , fbxPropName , fbxMaterial . GetName ( ) ) ) ;
348
+ }
321
349
322
350
// Find the corresponding property on the fbx material.
323
351
var fbxMaterialProperty = fbxMaterial . FindProperty ( fbxPropName ) ;
@@ -467,13 +495,13 @@ private void AssignLayerElementMaterial(FbxMesh fbxMesh, Mesh mesh, int material
467
495
}
468
496
469
497
/// <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.
472
499
/// </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 )
474
501
{
475
- if ( ! meshInfo . IsValid )
502
+ if ( ! meshInfo . IsValid ) {
476
503
return null ;
504
+ }
477
505
478
506
NumMeshes ++ ;
479
507
NumTriangles += meshInfo . Triangles . Length / 3 ;
@@ -496,15 +524,9 @@ public FbxMesh ExportMesh (MeshInfo meshInfo, FbxNode fbxNode, FbxScene fbxScene
496
524
}
497
525
fbxMesh . InitControlPoints ( NumControlPoints ) ;
498
526
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.
502
527
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 ] ) ;
508
530
}
509
531
} else {
510
532
NumControlPoints = meshInfo . VertexCount ;
@@ -513,12 +535,7 @@ public FbxMesh ExportMesh (MeshInfo meshInfo, FbxNode fbxNode, FbxScene fbxScene
513
535
// copy control point data from Unity to FBX
514
536
for ( int v = 0 ; v < NumControlPoints ; v ++ )
515
537
{
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 ) ;
522
539
}
523
540
}
524
541
@@ -600,7 +617,7 @@ meshInfo.Vertices [v].z*UnitScaleFactor
600
617
/// instead of Euler angles, which Maya does not import properly.
601
618
/// </summary>
602
619
/// <returns>Euler with XYZ rotation order.</returns>
603
- public static FbxDouble3 QuaternionToXYZEuler ( Quaternion q )
620
+ public static FbxDouble3 ConvertQuaternionToXYZEuler ( Quaternion q )
604
621
{
605
622
FbxQuaternion quat = new FbxQuaternion ( q . x , q . y , q . z , q . w ) ;
606
623
FbxAMatrix m = new FbxAMatrix ( ) ;
@@ -624,41 +641,33 @@ protected void ExportTransform (UnityEngine.Transform unityTransform, FbxNode fb
624
641
fbxNode . SetRotationOrder ( FbxNode . EPivotSet . eSourcePivot , FbxEuler . EOrder . eOrderXYZ ) ;
625
642
626
643
UnityEngine . Vector3 unityTranslate ;
627
- FbxDouble3 unityRotate ;
644
+ FbxDouble3 fbxRotate ;
628
645
UnityEngine . Vector3 unityScale ;
629
646
630
647
switch ( exportType ) {
631
648
case TransformExportType . Reset :
632
649
unityTranslate = Vector3 . zero ;
633
- unityRotate = new FbxDouble3 ( 0 ) ;
650
+ fbxRotate = new FbxDouble3 ( 0 ) ;
634
651
unityScale = Vector3 . one ;
635
652
break ;
636
653
case TransformExportType . Global :
637
654
unityTranslate = GetRecenteredTranslation ( unityTransform , newCenter ) ;
638
- unityRotate = QuaternionToXYZEuler ( unityTransform . rotation ) ;
655
+ fbxRotate = ConvertQuaternionToXYZEuler ( unityTransform . rotation ) ;
639
656
unityScale = unityTransform . lossyScale ;
640
657
break ;
641
658
default : /*case TransformExportType.Local*/
642
659
unityTranslate = unityTransform . localPosition ;
643
- unityRotate = QuaternionToXYZEuler ( unityTransform . localRotation ) ;
660
+ fbxRotate = ConvertQuaternionToXYZEuler ( unityTransform . localRotation ) ;
644
661
unityScale = unityTransform . localScale ;
645
662
break ;
646
663
}
647
664
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 ) ;
658
667
var fbxScale = new FbxDouble3 ( unityScale . x , unityScale . y , unityScale . z ) ;
659
668
660
669
// set the local position of fbxNode
661
- fbxNode . LclTranslation . Set ( fbxTranslate ) ;
670
+ fbxNode . LclTranslation . Set ( new FbxDouble3 ( fbxTranslate . X , fbxTranslate . Y , fbxTranslate . Z ) ) ;
662
671
fbxNode . LclRotation . Set ( fbxRotate ) ;
663
672
fbxNode . LclScaling . Set ( fbxScale ) ;
664
673
@@ -1144,7 +1153,7 @@ public static void DisplayNoSelectionDialog()
1144
1153
///<summary>
1145
1154
///Information about the mesh that is important for exporting.
1146
1155
///</summary>
1147
- public class MeshInfo
1156
+ class MeshInfo
1148
1157
{
1149
1158
/// <summary>
1150
1159
/// The transform of the mesh.
0 commit comments