@@ -2176,7 +2176,303 @@ protected int ExportTransformHierarchy(
2176
2176
return numObjectsExported ;
2177
2177
}
2178
2178
2179
- protected bool ExportAnimationOnly ( GameObject unityGo , FbxScene fbxScene ) {
2179
+ protected void ExportAnimationOnly (
2180
+ GameObject unityGO ,
2181
+ FbxScene fbxScene ,
2182
+ int exportProgress ,
2183
+ int objectCount ,
2184
+ Vector3 newCenter ,
2185
+ HashSet < AnimationClip > animationClips ,
2186
+ HashSet < GameObject > goExportSet ,
2187
+ Dictionary < GameObject , System . Type > exportComponent ,
2188
+ TransformExportType exportType = TransformExportType . Local
2189
+ ) {
2190
+ // export any bones
2191
+ var skinnedMeshRenderers = unityGO . GetComponentsInChildren < SkinnedMeshRenderer > ( ) ;
2192
+
2193
+ foreach ( var skinnedMesh in skinnedMeshRenderers ) {
2194
+ var boneArray = skinnedMesh . bones ;
2195
+ var bones = new HashSet < GameObject > ( ) ;
2196
+ var boneDict = new Dictionary < Transform , int > ( ) ;
2197
+
2198
+ for ( int i = 0 ; i < boneArray . Length ; i ++ ) {
2199
+ bones . Add ( boneArray [ i ] . gameObject ) ;
2200
+ boneDict . Add ( boneArray [ i ] , i ) ;
2201
+ }
2202
+
2203
+ var rootBone = skinnedMesh . rootBone ;
2204
+
2205
+ // get the bones that are also in the export set
2206
+ bones . IntersectWith ( goExportSet ) ;
2207
+
2208
+ // remove the exported bones from the export set
2209
+ goExportSet . ExceptWith ( bones ) ;
2210
+
2211
+ foreach ( var bone in bones ) {
2212
+ FbxNode node ;
2213
+ ExportGameObjectAndParents (
2214
+ bone . gameObject , unityGO , fbxScene , out node , newCenter , exportType , exportProgress , objectCount , skinnedMesh , boneDict , rootBone , true
2215
+ ) ;
2216
+ }
2217
+ }
2218
+
2219
+ // export everything else
2220
+ foreach ( var go in goExportSet ) {
2221
+ FbxNode node ;
2222
+ ExportGameObjectAndParents (
2223
+ go , unityGO , fbxScene , out node , newCenter , exportType , exportProgress , objectCount
2224
+ ) ;
2225
+
2226
+ System . Type compType ;
2227
+ if ( exportComponent . TryGetValue ( go , out compType ) ) {
2228
+ if ( compType == typeof ( Light ) ) {
2229
+ ExportLight ( go , fbxScene , node ) ;
2230
+ } else if ( compType == typeof ( Camera ) ) {
2231
+ ExportCamera ( go , fbxScene , node ) ;
2232
+ }
2233
+ }
2234
+ }
2235
+
2236
+ // export animation
2237
+ foreach ( var animClip in animationClips ) {
2238
+ //ExportAnimationClip (animClip, animationRootObject, fbxScene);
2239
+ }
2240
+ }
2241
+
2242
+ private bool ExportGameObjectAndParents (
2243
+ GameObject unityGo ,
2244
+ GameObject rootObject ,
2245
+ FbxScene fbxScene ,
2246
+ out FbxNode fbxNode ,
2247
+ Vector3 newCenter ,
2248
+ TransformExportType exportType ,
2249
+ int exportProgress ,
2250
+ int objectCount ,
2251
+ SkinnedMeshRenderer skinnedMesh = null ,
2252
+ Dictionary < Transform , int > boneDict = null ,
2253
+ Transform rootBone = null ,
2254
+ bool isBone = false )
2255
+ {
2256
+ // node already exists
2257
+ if ( MapUnityObjectToFbxNode . TryGetValue ( unityGo , out fbxNode ) ) {
2258
+ return true ;
2259
+ }
2260
+
2261
+ if ( ExportSettings . mayaCompatibleNames ) {
2262
+ unityGo . name = ConvertToMayaCompatibleName ( unityGo . name ) ;
2263
+ }
2264
+
2265
+ // create an FbxNode and add it as a child of parent
2266
+ fbxNode = FbxNode . Create ( fbxScene , GetUniqueName ( unityGo . name ) ) ;
2267
+ MapUnityObjectToFbxNode [ unityGo ] = fbxNode ;
2268
+
2269
+ // Default inheritance type in FBX is RrSs, which causes scaling issues in Maya as
2270
+ // both Maya and Unity use RSrs inheritance by default.
2271
+ // Note: MotionBuilder uses RrSs inheritance by default as well, though it is possible
2272
+ // to select a different inheritance type in the UI.
2273
+ // Use RSrs as the scaling inhertiance instead.
2274
+ fbxNode . SetTransformationInheritType ( FbxTransform . EInheritType . eInheritRSrs ) ;
2275
+
2276
+ // TODO: check if GO is a bone and export accordingly
2277
+ var exportedBoneTransform = isBone ?
2278
+ ExportBoneTransform ( fbxNode , fbxScene , unityGo . transform , rootBone , skinnedMesh , boneDict ) : false ;
2279
+
2280
+ // export regular transform if we are not a bone or failed to export as a bone
2281
+ if ( ! exportedBoneTransform ) {
2282
+ ExportTransform ( unityGo . transform , fbxNode , newCenter , exportType ) ;
2283
+ }
2284
+
2285
+ if ( unityGo . transform . parent != null || unityGo . transform . parent != rootObject . transform . parent ) {
2286
+ var parentIsBone = false ;
2287
+ if ( isBone && rootBone != null && unityGo . transform != rootBone ) {
2288
+ parentIsBone = true ;
2289
+ }
2290
+
2291
+ FbxNode fbxNodeParent ;
2292
+ if ( ! ExportGameObjectAndParents (
2293
+ unityGo . transform . parent . gameObject ,
2294
+ rootObject ,
2295
+ fbxScene ,
2296
+ out fbxNodeParent ,
2297
+ newCenter ,
2298
+ TransformExportType . Local ,
2299
+ exportProgress ,
2300
+ objectCount ,
2301
+ skinnedMesh ,
2302
+ boneDict ,
2303
+ rootBone ,
2304
+ parentIsBone
2305
+ ) ) {
2306
+ Debug . LogWarningFormat ( "Failed to export GameObject {0}" , unityGo . transform . parent . name ) ;
2307
+ return false ;
2308
+ }
2309
+ fbxNodeParent . AddChild ( fbxNode ) ;
2310
+ }
2311
+
2312
+ if ( unityGo == rootObject ) {
2313
+ fbxScene . GetRootNode ( ) . AddChild ( fbxNode ) ;
2314
+ }
2315
+
2316
+ return true ;
2317
+ }
2318
+
2319
+ private bool ExportBoneTransform (
2320
+ FbxNode fbxNode , FbxScene fbxScene , Transform unityBone , Transform rootBone ,
2321
+ SkinnedMeshRenderer skinnedMesh , Dictionary < Transform , int > boneDict
2322
+ ) {
2323
+ if ( skinnedMesh == null || boneDict == null || unityBone == null ) {
2324
+ return false ;
2325
+ }
2326
+ if ( rootBone == null ) {
2327
+ rootBone = skinnedMesh . rootBone ;
2328
+ }
2329
+
2330
+ var fbxSkeleton = fbxNode . GetSkeleton ( ) ;
2331
+ if ( fbxSkeleton == null ) {
2332
+ fbxSkeleton = FbxSkeleton . Create ( fbxScene , unityBone . name + SkeletonPrefix ) ;
2333
+
2334
+ fbxSkeleton . Size . Set ( 1.0f * UnitScaleFactor ) ;
2335
+ fbxNode . SetNodeAttribute ( fbxSkeleton ) ;
2336
+ }
2337
+ var fbxSkeletonType = rootBone != unityBone
2338
+ ? FbxSkeleton . EType . eLimbNode : FbxSkeleton . EType . eRoot ;
2339
+ fbxSkeleton . SetSkeletonType ( fbxSkeletonType ) ;
2340
+
2341
+ var bindPoses = skinnedMesh . sharedMesh . bindposes ;
2342
+
2343
+ // get bind pose
2344
+ Matrix4x4 bindPose ;
2345
+ int index ;
2346
+ if ( boneDict . TryGetValue ( unityBone , out index ) ) {
2347
+ bindPose = bindPoses [ index ] ;
2348
+ } else {
2349
+ bindPose = unityBone . worldToLocalMatrix * skinnedMesh . transform . localToWorldMatrix ;
2350
+ }
2351
+
2352
+ Matrix4x4 pose ;
2353
+ if ( unityBone == rootBone ) {
2354
+ pose = ( unityBone . parent . worldToLocalMatrix * skinnedMesh . transform . localToWorldMatrix * bindPose . inverse ) ;
2355
+ } else {
2356
+ // get parent's bind pose
2357
+ int pIndex ;
2358
+ Matrix4x4 parentBindPose ;
2359
+ if ( boneDict . TryGetValue ( unityBone . parent , out pIndex ) ) {
2360
+ parentBindPose = bindPoses [ pIndex ] ;
2361
+ } else {
2362
+ parentBindPose = unityBone . parent . worldToLocalMatrix * skinnedMesh . transform . localToWorldMatrix ;
2363
+ }
2364
+
2365
+ pose = parentBindPose * bindPose . inverse ;
2366
+ }
2367
+
2368
+ // FBX is transposed relative to Unity: transpose as we convert.
2369
+ FbxMatrix matrix = new FbxMatrix ( ) ;
2370
+ matrix . SetColumn ( 0 , new FbxVector4 ( pose . GetRow ( 0 ) . x , pose . GetRow ( 0 ) . y , pose . GetRow ( 0 ) . z , pose . GetRow ( 0 ) . w ) ) ;
2371
+ matrix . SetColumn ( 1 , new FbxVector4 ( pose . GetRow ( 1 ) . x , pose . GetRow ( 1 ) . y , pose . GetRow ( 1 ) . z , pose . GetRow ( 1 ) . w ) ) ;
2372
+ matrix . SetColumn ( 2 , new FbxVector4 ( pose . GetRow ( 2 ) . x , pose . GetRow ( 2 ) . y , pose . GetRow ( 2 ) . z , pose . GetRow ( 2 ) . w ) ) ;
2373
+ matrix . SetColumn ( 3 , new FbxVector4 ( pose . GetRow ( 3 ) . x , pose . GetRow ( 3 ) . y , pose . GetRow ( 3 ) . z , pose . GetRow ( 3 ) . w ) ) ;
2374
+
2375
+ // FBX wants translation, rotation (in euler angles) and scale.
2376
+ // We assume there's no real shear, just rounding error.
2377
+ FbxVector4 translation , rotation , shear , scale ;
2378
+ double sign ;
2379
+ matrix . GetElements ( out translation , out rotation , out shear , out scale , out sign ) ;
2380
+
2381
+ // Export bones with zero rotation, using a pivot instead to set the rotation
2382
+ // so that the bones are easier to animate and the rotation shows up as the "joint orientation" in Maya.
2383
+ fbxNode . LclTranslation . Set ( new FbxDouble3 ( - translation . X * UnitScaleFactor , translation . Y * UnitScaleFactor , translation . Z * UnitScaleFactor ) ) ;
2384
+ fbxNode . LclRotation . Set ( new FbxDouble3 ( 0 , 0 , 0 ) ) ;
2385
+ fbxNode . LclScaling . Set ( new FbxDouble3 ( scale . X , scale . Y , scale . Z ) ) ;
2386
+
2387
+ // TODO (UNI-34294): add detailed comment about why we export rotation as pre-rotation
2388
+ fbxNode . SetRotationActive ( true ) ;
2389
+ fbxNode . SetPivotState ( FbxNode . EPivotSet . eSourcePivot , FbxNode . EPivotState . ePivotReference ) ;
2390
+ fbxNode . SetPreRotation ( FbxNode . EPivotSet . eSourcePivot , new FbxVector4 ( rotation . X , - rotation . Y , - rotation . Z ) ) ;
2391
+
2392
+ return true ;
2393
+ }
2394
+
2395
+ protected int AnimOnlyHierarchyCount (
2396
+ HashSet < GameObject > exportSet ,
2397
+ out HashSet < AnimationClip > animationClips ,
2398
+ out Dictionary < GameObject , HashSet < GameObject > > mapGameObjectToExportSet ,
2399
+ out Dictionary < GameObject , System . Type > exportComponent
2400
+ ) {
2401
+ animationClips = new HashSet < AnimationClip > ( ) ;
2402
+ mapGameObjectToExportSet = new Dictionary < GameObject , HashSet < GameObject > > ( ) ;
2403
+ exportComponent = new Dictionary < GameObject , System . Type > ( ) ;
2404
+
2405
+ foreach ( var go in exportSet ) {
2406
+ // gather all animation clips
2407
+ var legacyAnim = go . GetComponentsInChildren < Animation > ( ) ;
2408
+ var genericAnim = go . GetComponentsInChildren < Animator > ( ) ;
2409
+
2410
+ var goToExport = new HashSet < GameObject > ( ) ;
2411
+ mapGameObjectToExportSet . Add ( go , goToExport ) ;
2412
+
2413
+ foreach ( var anim in legacyAnim ) {
2414
+ var animClips = AnimationUtility . GetAnimationClips ( anim . gameObject ) ;
2415
+ GetObjectsInAnimationClips ( animClips , anim . gameObject , ref animationClips , ref goToExport , ref exportComponent ) ;
2416
+ }
2417
+
2418
+ foreach ( var anim in genericAnim ) {
2419
+ // Try the animator controller (mecanim)
2420
+ var controller = anim . runtimeAnimatorController ;
2421
+ if ( controller )
2422
+ {
2423
+ GetObjectsInAnimationClips ( controller . animationClips , anim . gameObject , ref animationClips , ref goToExport , ref exportComponent ) ;
2424
+ }
2425
+ }
2426
+ }
2427
+
2428
+ int count = 0 ;
2429
+ foreach ( var es in mapGameObjectToExportSet . Values ) {
2430
+ count += es . Count ;
2431
+ }
2432
+
2433
+ return count ;
2434
+ }
2435
+
2436
+ protected void GetObjectsInAnimationClips (
2437
+ AnimationClip [ ] animClips ,
2438
+ GameObject animationRootObject ,
2439
+ ref HashSet < AnimationClip > clipSet ,
2440
+ ref HashSet < GameObject > goToExport ,
2441
+ ref Dictionary < GameObject , System . Type > exportComponent
2442
+ ) {
2443
+ var cameraProps = new List < string > { "field of view" } ;
2444
+ var lightProps = new List < string > { "m_Intensity" , "m_SpotAngle" , "m_Color.r" , "m_Color.g" , "m_Color.b" } ;
2445
+
2446
+ foreach ( var animClip in animClips ) {
2447
+ if ( ! clipSet . Add ( animClip ) ) {
2448
+ // we have already exported gameobjects for this clip
2449
+ continue ;
2450
+ }
2451
+
2452
+ foreach ( EditorCurveBinding uniCurveBinding in AnimationUtility . GetCurveBindings ( animClip ) ) {
2453
+ Object uniObj = AnimationUtility . GetAnimatedObject ( animationRootObject , uniCurveBinding ) ;
2454
+ if ( ! uniObj ) {
2455
+ continue ;
2456
+ }
2457
+ //Debug.LogWarning (uniObj.name + ": " + uniCurveBinding.propertyName);
2458
+
2459
+ GameObject unityGo = GetGameObject ( uniObj ) ;
2460
+ if ( ! unityGo ) {
2461
+ continue ;
2462
+ }
2463
+
2464
+ if ( lightProps . Contains ( uniCurveBinding . propertyName ) ) {
2465
+ exportComponent . Add ( unityGo , typeof ( Light ) ) ;
2466
+ } else if ( cameraProps . Contains ( uniCurveBinding . propertyName ) ) {
2467
+ exportComponent . Add ( unityGo , typeof ( Camera ) ) ;
2468
+ }
2469
+
2470
+ goToExport . Add ( unityGo ) ;
2471
+ }
2472
+ }
2473
+ }
2474
+
2475
+ /*protected bool ExportAnimationOnly(GameObject unityGo, FbxScene fbxScene){
2180
2476
// gather all animation clips
2181
2477
var legacyAnim = unityGo.GetComponentsInChildren<Animation>();
2182
2478
var genericAnim = unityGo.GetComponentsInChildren<Animator> ();
@@ -2234,10 +2530,14 @@ private bool ExportAnimatedGameObjects(AnimationClip[] animClips, GameObject ani
2234
2530
}
2235
2531
FbxNode fbxNode;
2236
2532
ExportGameObjectAndParents (unityGo, exportRoot, fbxScene, out fbxNode);
2533
+
2534
+ // TODO: export animated components
2535
+ // check if animated property is part of a light or a camera and export accordingly
2237
2536
}
2238
- }
2239
2537
2240
- return false ;
2538
+ ExportAnimationClip (animClip, animationRootObject, fbxScene);
2539
+ }
2540
+ return true;
2241
2541
}
2242
2542
2243
2543
private bool ExportGameObjectAndParents(GameObject unityGo, GameObject rootObject, FbxScene fbxScene, out FbxNode fbxNode){
@@ -2261,6 +2561,8 @@ private bool ExportGameObjectAndParents(GameObject unityGo, GameObject rootObjec
2261
2561
// Use RSrs as the scaling inhertiance instead.
2262
2562
fbxNode.SetTransformationInheritType (FbxTransform.EInheritType.eInheritRSrs);
2263
2563
2564
+ // TODO: check if GO is a bone and export accordingly
2565
+
2264
2566
ExportTransform (unityGo.transform, fbxNode, Vector3.zero, TransformExportType.Local);//newCenter, exportType);
2265
2567
2266
2568
if (unityGo.transform.parent != null || unityGo.transform.parent != rootObject.transform.parent) {
@@ -2273,12 +2575,11 @@ private bool ExportGameObjectAndParents(GameObject unityGo, GameObject rootObjec
2273
2575
}
2274
2576
2275
2577
if (unityGo == rootObject) {
2276
- Debug . Log ( "over here" ) ;
2277
2578
fbxScene.GetRootNode ().AddChild (fbxNode);
2278
2579
}
2279
2580
2280
2581
return true;
2281
- }
2582
+ }*/
2282
2583
2283
2584
/// <summary>
2284
2585
/// Export components on this game object.
@@ -2578,7 +2879,23 @@ public int ExportAll (IEnumerable<UnityEngine.Object> unityExportSet)
2578
2879
var revisedExportSet = RemoveRedundantObjects ( unityExportSet ) ;
2579
2880
int count = GetHierarchyCount ( revisedExportSet ) ;
2580
2881
2581
- if ( revisedExportSet . Count == 1 ) {
2882
+ Vector3 center = Vector3 . zero ;
2883
+ var exportType = TransformExportType . Reset ;
2884
+ if ( revisedExportSet . Count != 1 ) {
2885
+ center = ExportSettings . centerObjects ? FindCenter ( revisedExportSet ) : Vector3 . zero ;
2886
+ exportType = TransformExportType . Global ;
2887
+ }
2888
+
2889
+ foreach ( var unityGo in revisedExportSet ) {
2890
+ exportProgress = this . ExportTransformHierarchy ( unityGo , fbxScene , fbxRootNode ,
2891
+ exportProgress , count , center , exportType ) ;
2892
+ if ( exportCancelled || exportProgress < 0 ) {
2893
+ Debug . LogWarning ( "Export Cancelled" ) ;
2894
+ return 0 ;
2895
+ }
2896
+ }
2897
+
2898
+ /*if(revisedExportSet.Count == 1){
2582
2899
foreach(var unityGo in revisedExportSet){
2583
2900
exportProgress = this.ExportTransformHierarchy (
2584
2901
unityGo, fbxScene, fbxRootNode, exportProgress,
@@ -2601,7 +2918,7 @@ public int ExportAll (IEnumerable<UnityEngine.Object> unityExportSet)
2601
2918
return 0;
2602
2919
}
2603
2920
}
2604
- }
2921
+ }*/
2605
2922
2606
2923
if ( ! ExportComponents ( fbxScene ) ) {
2607
2924
Debug . LogWarning ( "Export Cancelled" ) ;
0 commit comments