@@ -37,15 +37,15 @@ public static class AnimationCurveExtension
37
37
// This is an extension method for the AnimationCurve class
38
38
// The first parameter takes the "this" modifier
39
39
// and specifies the type for which the method is defined.
40
- public static void Dump ( this AnimationCurve animCurve , string message , float [ ] keyTimesExpected = null , float [ ] keyValuesExpected = null )
40
+ public static void Dump ( this AnimationCurve animCurve , string message , float [ ] keyTimesExpected = null , float [ ] keyValuesExpected = null )
41
41
{
42
42
int idx = 0 ;
43
43
foreach ( var key in animCurve . keys ) {
44
44
if ( keyTimesExpected != null && keyValuesExpected != null ) {
45
45
Debug . Log ( string . Format ( "{5} keys[{0}] {1}({3}) {2} ({4})" ,
46
- idx , key . time , key . value ,
47
- keyTimesExpected [ idx ] , keyValuesExpected [ idx ] ,
48
- message ) ) ;
46
+ idx , key . time , key . value ,
47
+ keyTimesExpected [ idx ] , keyValuesExpected [ idx ] ,
48
+ message ) ) ;
49
49
} else {
50
50
Debug . Log ( string . Format ( "{3} keys[{0}] {1} {2}" , idx , key . time , key . value , message ) ) ;
51
51
}
@@ -128,7 +128,6 @@ static ModelExporter Create ()
128
128
/// <summary>
129
129
/// Which components map from Unity Object to Fbx Object
130
130
/// </summary>
131
- ///
132
131
public enum FbxNodeRelationType
133
132
{
134
133
NodeAttribute ,
@@ -165,7 +164,7 @@ public enum FbxNodeRelationType
165
164
/// <summary>
166
165
/// Map the name of a prefab to an FbxMesh (for preserving instances)
167
166
/// </summary>
168
- Dictionary < string , FbxMesh > SharedMeshes = new Dictionary < string , FbxMesh > ( ) ;
167
+ Dictionary < string , FbxMesh > SharedMeshes = new Dictionary < string , FbxMesh > ( ) ;
169
168
170
169
/// <summary>
171
170
/// Map for the Name of an Object to number of objects with this name.
@@ -191,13 +190,14 @@ public static EditorTools.ExportSettings ExportSettings {
191
190
public static Material DefaultMaterial {
192
191
get {
193
192
if ( ! s_defaultMaterial ) {
194
- var obj = GameObject . CreatePrimitive ( PrimitiveType . Quad ) ;
195
- s_defaultMaterial = obj . GetComponent < Renderer > ( ) . sharedMaterial ;
196
- Object . DestroyImmediate ( obj ) ;
193
+ var obj = GameObject . CreatePrimitive ( PrimitiveType . Quad ) ;
194
+ s_defaultMaterial = obj . GetComponent < Renderer > ( ) . sharedMaterial ;
195
+ Object . DestroyImmediate ( obj ) ;
197
196
}
198
197
return s_defaultMaterial ;
199
198
}
200
199
}
200
+
201
201
static Material s_defaultMaterial = null ;
202
202
203
203
static Dictionary < UnityEngine . LightType , FbxLight . EType > MapLightType = new Dictionary < UnityEngine . LightType , FbxLight . EType > ( ) {
@@ -254,10 +254,10 @@ public static string GetVersionFromReadme()
254
254
int newLayerIndex = fbxMesh . CreateLayer ( ) ;
255
255
if ( newLayerIndex <= maxLayerIndex ) {
256
256
// Error!
257
- throw new System . Exception (
258
- "Internal error: Unable to create mesh layer "
259
- + ( maxLayerIndex + 1 )
260
- + " on mesh " + fbxMesh . GetName ( ) ) ;
257
+ throw new System . Exception (
258
+ "Internal error: Unable to create mesh layer "
259
+ + ( maxLayerIndex + 1 )
260
+ + " on mesh " + fbxMesh . GetName ( ) ) ;
261
261
}
262
262
maxLayerIndex = newLayerIndex ;
263
263
}
@@ -773,9 +773,14 @@ SkinnedMeshRenderer unitySkin
773
773
return false ;
774
774
}
775
775
776
+ if ( Verbose )
777
+ Debug . Log ( string . Format ( "exporting {0} {1}" , "Skin" , fbxNode . GetName ( ) ) ) ;
778
+
779
+
780
+ Dictionary < SkinnedMeshRenderer , Transform [ ] > skinnedMeshToBonesMap ;
776
781
// export skeleton
777
- if ( ! ExportSkeleton ( unitySkin , fbxScene ) ) {
778
- Debug . LogWarning ( "failed to export skeleton" ) ;
782
+ if ( ! ExportSkeleton ( unitySkin , fbxScene , out skinnedMeshToBonesMap ) ) {
783
+ Debug . LogWarning ( "failed to export skeleton" ) ;
779
784
return false ;
780
785
}
781
786
@@ -796,44 +801,58 @@ SkinnedMeshRenderer unitySkin
796
801
ExportSkin ( unitySkin , meshInfo , fbxScene , fbxMesh , fbxNode ) ;
797
802
798
803
// add bind pose
799
- ExportBindPose ( unitySkin , fbxNode , fbxScene ) ;
804
+ ExportBindPose ( unitySkin , fbxNode , fbxScene , skinnedMeshToBonesMap ) ;
800
805
801
- if ( Verbose )
802
- Debug . Log ( string . Format ( "exporting {0} {1}" , "Skin" , fbxNode . GetName ( ) ) ) ;
803
-
804
806
return true ;
805
807
}
806
808
807
- private bool IsBone ( Transform t , Dictionary < Transform , int > bones ) {
809
+ /// <summary>
810
+ /// Determines whether this Transform is a bone.
811
+ /// A transform is a bone if it is in the skinned meshes bone list (represented here as a bones dict),
812
+ /// or if it has both an ancestor or descendant that are bones (i.e. if it is sandwiched between two bones,
813
+ /// it should be a bone as well).
814
+ /// </summary>
815
+ /// <returns><c>true</c> if this transform is a bone; otherwise, <c>false</c>.</returns>
816
+ /// <param name="t">Transform.</param>
817
+ /// <param name="bones">Skinned meshes bones.</param>
818
+ private bool IsBone ( Transform t , Dictionary < Transform , int > bones )
819
+ {
808
820
if ( bones . ContainsKey ( t ) ) {
809
821
return true ;
810
822
}
811
823
812
824
foreach ( Transform child in t ) {
813
825
if ( IsBone ( child , bones ) ) {
814
- //Debug.LogError ("our child is a bone: " + t.name);
815
826
return true ;
816
827
}
817
828
}
818
829
return false ;
819
830
}
820
831
821
- private Dictionary < SkinnedMeshRenderer , Transform [ ] > SkinnedMeshToBonesMap = new Dictionary < SkinnedMeshRenderer , Transform [ ] > ( ) ;
822
-
823
832
/// <summary>
824
833
/// Export bones of skinned mesh, if this is a skinned mesh with
825
834
/// bones and bind poses.
826
835
/// </summary>
827
- private bool ExportSkeleton ( SkinnedMeshRenderer skinnedMesh , FbxScene fbxScene )
836
+ private bool ExportSkeleton ( SkinnedMeshRenderer skinnedMesh , FbxScene fbxScene , out Dictionary < SkinnedMeshRenderer , Transform [ ] > skinnedMeshToBonesMap )
828
837
{
829
- if ( ! skinnedMesh ) { return false ; }
838
+ skinnedMeshToBonesMap = new Dictionary < SkinnedMeshRenderer , Transform [ ] > ( ) ;
839
+
840
+ if ( ! skinnedMesh ) {
841
+ return false ;
842
+ }
830
843
var bones = skinnedMesh . bones ;
831
- if ( bones == null || bones . Length == 0 ) { return false ; }
844
+ if ( bones == null || bones . Length == 0 ) {
845
+ return false ;
846
+ }
832
847
var mesh = skinnedMesh . sharedMesh ;
833
- if ( ! mesh ) { return false ; }
848
+ if ( ! mesh ) {
849
+ return false ;
850
+ }
834
851
835
852
var bindPoses = mesh . bindposes ;
836
- if ( bindPoses == null || bindPoses . Length != bones . Length ) { return false ; }
853
+ if ( bindPoses == null || bindPoses . Length != bones . Length ) {
854
+ return false ;
855
+ }
837
856
838
857
// Three steps:
839
858
// 0. Set up the map from bone to index.
@@ -888,7 +907,7 @@ private bool ExportSkeleton (SkinnedMeshRenderer skinnedMesh, FbxScene fbxScene)
888
907
889
908
var boneList = boneSet . ToArray ( ) ;
890
909
891
- SkinnedMeshToBonesMap . Add ( skinnedMesh , boneList ) ;
910
+ skinnedMeshToBonesMap . Add ( skinnedMesh , boneList ) ;
892
911
893
912
// Step 2: Get bindposes
894
913
var boneToBindPose = new Dictionary < Transform , Matrix4x4 > ( ) ;
@@ -956,8 +975,8 @@ private bool ExportSkeleton (SkinnedMeshRenderer skinnedMesh, FbxScene fbxScene)
956
975
/// Export binding of mesh to skeleton
957
976
/// </summary>
958
977
private bool ExportSkin ( SkinnedMeshRenderer skinnedMesh ,
959
- MeshInfo meshInfo , FbxScene fbxScene , FbxMesh fbxMesh ,
960
- FbxNode fbxRootNode )
978
+ MeshInfo meshInfo , FbxScene fbxScene , FbxMesh fbxMesh ,
979
+ FbxNode fbxRootNode )
961
980
{
962
981
FbxSkin fbxSkin = FbxSkin . Create ( fbxScene , ( skinnedMesh . name + "_Skin" ) ) ;
963
982
@@ -1032,7 +1051,8 @@ boneWeights [i].weight3
1032
1051
/// <summary>
1033
1052
/// Export bind pose of mesh to skeleton
1034
1053
/// </summary>
1035
- protected bool ExportBindPose ( SkinnedMeshRenderer skinnedMesh , FbxNode fbxMeshNode , FbxScene fbxScene )
1054
+ protected bool ExportBindPose ( SkinnedMeshRenderer skinnedMesh , FbxNode fbxMeshNode ,
1055
+ FbxScene fbxScene , Dictionary < SkinnedMeshRenderer , Transform [ ] > skinnedMeshToBonesMap )
1036
1056
{
1037
1057
FbxPose fbxPose = FbxPose . Create ( fbxScene , fbxMeshNode . GetName ( ) ) ;
1038
1058
@@ -1041,7 +1061,7 @@ protected bool ExportBindPose (SkinnedMeshRenderer skinnedMesh, FbxNode fbxMeshN
1041
1061
1042
1062
// assume each bone node has one weighted vertex cluster
1043
1063
Transform [ ] bones ;
1044
- if ( ! SkinnedMeshToBonesMap . TryGetValue ( skinnedMesh , out bones ) ) {
1064
+ if ( ! skinnedMeshToBonesMap . TryGetValue ( skinnedMesh , out bones ) ) {
1045
1065
return false ;
1046
1066
}
1047
1067
for ( int i = 0 ; i < bones . Length ; i ++ ) {
@@ -1093,13 +1113,13 @@ public static FbxDouble3 ConvertQuaternionToXYZEuler(Quaternion q)
1093
1113
1094
1114
public static FbxVector4 ConvertQuaternionToXYZEuler ( FbxQuaternion quat )
1095
1115
{
1096
- FbxAMatrix m = new FbxAMatrix ( ) ;
1097
- m . SetQ ( quat ) ;
1098
- var vector4 = m . GetR ( ) ;
1116
+ FbxAMatrix m = new FbxAMatrix ( ) ;
1117
+ m . SetQ ( quat ) ;
1118
+ var vector4 = m . GetR ( ) ;
1099
1119
1100
- // Negate the y and z values of the rotation to convert
1101
- // from Unity to Maya coordinates (left to righthanded).
1102
- return new FbxVector4 ( vector4 . X , - vector4 . Y , - vector4 . Z , vector4 . W ) ;
1120
+ // Negate the y and z values of the rotation to convert
1121
+ // from Unity to Maya coordinates (left to righthanded).
1122
+ return new FbxVector4 ( vector4 . X , - vector4 . Y , - vector4 . Z , vector4 . W ) ;
1103
1123
}
1104
1124
1105
1125
// get a fbxNode's global default position.
@@ -1450,8 +1470,8 @@ public static bool TryGetValue(string uniPropertyName, out FbxPropertyChannelPai
1450
1470
return true ;
1451
1471
}
1452
1472
if ( uniPropertyName . StartsWith ( "m_LocalPosition.z" , ct ) || uniPropertyName . EndsWith ( "T.z" , ct ) ) {
1453
- prop = new FbxPropertyChannelPair ( "Lcl Translation" , Globals . FBXSDK_CURVENODE_COMPONENT_Z ) ;
1454
- return true ;
1473
+ prop = new FbxPropertyChannelPair ( "Lcl Translation" , Globals . FBXSDK_CURVENODE_COMPONENT_Z ) ;
1474
+ return true ;
1455
1475
}
1456
1476
1457
1477
if ( uniPropertyName . StartsWith ( "m_Intensity" , ct ) )
@@ -1681,7 +1701,7 @@ protected void ExportAnimationClip (AnimationClip uniAnimClip, GameObject uniRoo
1681
1701
if ( Verbose )
1682
1702
{
1683
1703
Debug . Log ( string . Format ( "Exporting animation curve bound to {0} {1}" ,
1684
- uniCurveBinding . propertyName , uniCurveBinding . path ) ) ;
1704
+ uniCurveBinding . propertyName , uniCurveBinding . path ) ) ;
1685
1705
}
1686
1706
1687
1707
int index = QuaternionCurve . GetQuaternionIndex ( uniCurveBinding . propertyName ) ;
@@ -1830,9 +1850,9 @@ protected int ExportNodes(
1830
1850
1831
1851
numObjectsExported ++ ;
1832
1852
if ( EditorUtility . DisplayCancelableProgressBar (
1833
- ProgressBarTitle ,
1834
- string . Format ( "Creating FbxNode {0}/{1}" , numObjectsExported , objectCount ) ,
1835
- ( numObjectsExported / ( float ) objectCount ) * 0.25f ) ) {
1853
+ ProgressBarTitle ,
1854
+ string . Format ( "Creating FbxNode {0}/{1}" , numObjectsExported , objectCount ) ,
1855
+ ( numObjectsExported / ( float ) objectCount ) * 0.25f ) ) {
1836
1856
// cancel silently
1837
1857
return - 1 ;
1838
1858
}
@@ -1866,9 +1886,9 @@ protected bool ExportComponents(FbxScene fbxScene)
1866
1886
foreach ( KeyValuePair < GameObject , FbxNode > entry in MapUnityObjectToFbxNode ) {
1867
1887
numObjectsExported ++ ;
1868
1888
if ( EditorUtility . DisplayCancelableProgressBar (
1869
- ProgressBarTitle ,
1870
- string . Format ( "Exporting Components for GameObject {0}/{1}" , numObjectsExported , objectCount ) ,
1871
- ( ( numObjectsExported / ( float ) objectCount ) * 0.25f ) + 0.25f ) ) {
1889
+ ProgressBarTitle ,
1890
+ string . Format ( "Exporting Components for GameObject {0}/{1}" , numObjectsExported , objectCount ) ,
1891
+ ( ( numObjectsExported / ( float ) objectCount ) * 0.25f ) + 0.25f ) ) {
1872
1892
// cancel silently
1873
1893
return false ;
1874
1894
}
@@ -1895,7 +1915,7 @@ protected bool ExportComponents(FbxScene fbxScene)
1895
1915
}
1896
1916
1897
1917
// now (try) export animation
1898
- ExportAnimation ( unityGo , fbxScene ) ;
1918
+ ExportAnimation ( unityGo , fbxScene ) ;
1899
1919
1900
1920
}
1901
1921
return true ;
@@ -2341,7 +2361,8 @@ public Vector3 [] Normals { get {
2341
2361
m_normals = mesh . normals ;
2342
2362
}
2343
2363
return m_normals ;
2344
- } }
2364
+ }
2365
+ }
2345
2366
2346
2367
/// <summary>
2347
2368
/// Gets the binormals for the vertices.
@@ -2382,7 +2403,8 @@ public Vector4 [] Tangents { get {
2382
2403
m_tangents = mesh . tangents ;
2383
2404
}
2384
2405
return m_tangents ;
2385
- } }
2406
+ }
2407
+ }
2386
2408
2387
2409
/// <summary>
2388
2410
/// Gets the vertex colors for the vertices.
@@ -2394,7 +2416,8 @@ public Color32 [] VertexColors { get {
2394
2416
m_vertexColors = mesh . colors32 ;
2395
2417
}
2396
2418
return m_vertexColors ;
2397
- } }
2419
+ }
2420
+ }
2398
2421
2399
2422
/// <summary>
2400
2423
/// Gets the uvs.
@@ -2406,7 +2429,8 @@ public Vector2 [] UV { get {
2406
2429
m_UVs = mesh . uv ;
2407
2430
}
2408
2431
return m_UVs ;
2409
- } }
2432
+ }
2433
+ }
2410
2434
2411
2435
/// <summary>
2412
2436
/// The material(s) used.
@@ -2421,7 +2445,8 @@ public BoneWeight[] BoneWeights { get {
2421
2445
m_boneWeights = mesh . boneWeights ;
2422
2446
}
2423
2447
return m_boneWeights ;
2424
- } }
2448
+ }
2449
+ }
2425
2450
2426
2451
/// <summary>
2427
2452
/// Set up the MeshInfo with the given mesh and materials.
@@ -2523,10 +2548,10 @@ public static void RegisterMeshCallback<T>(GetMeshForComponent<T> callback, bool
2523
2548
where T : UnityEngine . MonoBehaviour
2524
2549
{
2525
2550
// Under the hood we lose type safety, but don't let the user notice!
2526
- RegisterMeshCallback ( typeof ( T ) ,
2527
- ( ModelExporter exporter , MonoBehaviour component , FbxNode fbxNode ) =>
2528
- callback ( exporter , ( T ) component , fbxNode ) ,
2529
- replace ) ;
2551
+ RegisterMeshCallback ( typeof ( T ) ,
2552
+ ( ModelExporter exporter , MonoBehaviour component , FbxNode fbxNode ) =>
2553
+ callback ( exporter , ( T ) component , fbxNode ) ,
2554
+ replace ) ;
2530
2555
}
2531
2556
2532
2557
/// <summary>
@@ -2728,6 +2753,7 @@ private static void OnExport ()
2728
2753
: System . IO . Path . GetDirectoryName ( LastFilePath ) ;
2729
2754
2730
2755
GameObject [ ] selectedGOs = Selection . GetFiltered < GameObject > ( SelectionMode . TopLevel ) ;
2756
+ GameObject [ ] selectedGOs = Selection . GetFiltered < GameObject > ( SelectionMode . TopLevel ) ;
2731
2757
string filename = null ;
2732
2758
if ( selectedGOs . Length == 1 ) {
2733
2759
filename = ConvertToValidFilename ( selectedGOs [ 0 ] . name + ".fbx" ) ;
0 commit comments