Skip to content

Commit 4d9b4c4

Browse files
authored
Merge pull request #46 from Unity-Technologies/UNI-21787-export-with-common-center
Uni 21787 export with common center
2 parents 78d78fc + 5ae2981 commit 4d9b4c4

File tree

2 files changed

+96
-11
lines changed

2 files changed

+96
-11
lines changed

Assets/FbxExporters/Editor/FbxExportSettings.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,13 @@ public override void OnInspectorGUI() {
3333
" and unexpected character replacements in Maya.")
3434
),
3535
exportSettings.mayaCompatibleNames);
36-
36+
37+
exportSettings.centerObjects = EditorGUILayout.Toggle (
38+
new GUIContent("Center Objects:",
39+
"Export objects centered around the union of the bounding box of selected objects"),
40+
exportSettings.centerObjects
41+
);
42+
3743
GUILayout.BeginHorizontal ();
3844
GUILayout.Label (new GUIContent (
3945
"Model Prefab Path:",
@@ -92,6 +98,7 @@ public class ExportSettings : FbxExporters.EditorTools.ScriptableSingleton<Expor
9298
public bool weldVertices = true;
9399
public bool embedTextures = false;
94100
public bool mayaCompatibleNames = true;
101+
public bool centerObjects = true;
95102
public string convertToModelSavePath;
96103

97104
void OnEnable()

Assets/FbxExporters/Editor/FbxExporter.cs

Lines changed: 88 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ meshInfo.Vertices [v].z*UnitScaleFactor
503503
}
504504

505505
// get a fbxNode's global default position.
506-
protected void ExportTransform (UnityEngine.Transform unityTransform, FbxNode fbxNode, TransformExportType exportType)
506+
protected void ExportTransform (UnityEngine.Transform unityTransform, FbxNode fbxNode, Vector3 newCenter, TransformExportType exportType)
507507
{
508508
// Fbx rotation order is XYZ, but Unity rotation order is ZXY.
509509
// This causes issues when converting euler to quaternion, causing the final
@@ -516,13 +516,13 @@ protected void ExportTransform (UnityEngine.Transform unityTransform, FbxNode fb
516516
UnityEngine.Vector3 unityScale;
517517

518518
switch (exportType) {
519-
case TransformExportType.Zeroed:
519+
case TransformExportType.Reset:
520520
unityTranslate = Vector3.zero;
521521
unityRotate = Vector3.zero;
522522
unityScale = Vector3.one;
523523
break;
524524
case TransformExportType.Global:
525-
unityTranslate = unityTransform.position;
525+
unityTranslate = GetRecenteredTranslation(unityTransform, newCenter);
526526
unityRotate = unityTransform.rotation.eulerAngles;
527527
unityScale = unityTransform.lossyScale;
528528
break;
@@ -592,7 +592,8 @@ protected bool ExportInstance (GameObject unityGo, FbxNode fbxNode, FbxScene fbx
592592
/// </summary>
593593
protected int ExportComponents (
594594
GameObject unityGo, FbxScene fbxScene, FbxNode fbxNodeParent,
595-
int exportProgress, int objectCount, TransformExportType exportType = TransformExportType.Local)
595+
int exportProgress, int objectCount, Vector3 newCenter,
596+
TransformExportType exportType = TransformExportType.Local)
596597
{
597598
int numObjectsExported = exportProgress;
598599

@@ -613,7 +614,7 @@ protected int ExportComponents (
613614
return -1;
614615
}
615616

616-
ExportTransform ( unityGo.transform, fbxNode, exportType);
617+
ExportTransform ( unityGo.transform, fbxNode, newCenter, exportType);
617618

618619
// try exporting mesh as an instance, export regularly if we cannot
619620
if (!ExportInstance (unityGo, fbxNode, fbxScene)) {
@@ -628,7 +629,7 @@ protected int ExportComponents (
628629

629630
// now unityGo through our children and recurse
630631
foreach (Transform childT in unityGo.transform) {
631-
numObjectsExported = ExportComponents (childT.gameObject, fbxScene, fbxNode, numObjectsExported, objectCount);
632+
numObjectsExported = ExportComponents (childT.gameObject, fbxScene, fbxNode, numObjectsExported, objectCount, newCenter);
632633
}
633634
return numObjectsExported;
634635
}
@@ -691,7 +692,79 @@ public static HashSet<GameObject> RemoveRedundantObjects(IEnumerable<UnityEngine
691692
return toExport;
692693
}
693694

694-
public enum TransformExportType { Local, Global, Zeroed };
695+
/// <summary>
696+
/// Recursively go through the hierarchy, unioning the bounding box centers
697+
/// of all the children, to find the combined bounds.
698+
/// </summary>
699+
/// <param name="t">Transform.</param>
700+
/// <param name="boundsUnion">The Bounds that is the Union of all the bounds on this transform's hierarchy.</param>
701+
private void EncapsulateBounds(Transform t, ref Bounds boundsUnion)
702+
{
703+
var bounds = GetBounds (t);
704+
boundsUnion.Encapsulate (bounds);
705+
706+
foreach (Transform child in t) {
707+
EncapsulateBounds (child, ref boundsUnion);
708+
}
709+
}
710+
711+
/// <summary>
712+
/// Gets the bounds of a transform.
713+
/// Looks first at the Renderer, then Mesh, then Collider.
714+
/// Default to a bounds with center transform.position and size zero.
715+
/// </summary>
716+
/// <returns>The bounds.</returns>
717+
/// <param name="t">Transform.</param>
718+
private Bounds GetBounds(Transform t)
719+
{
720+
var renderer = t.GetComponent<Renderer> ();
721+
if (renderer) {
722+
return renderer.bounds;
723+
}
724+
var mesh = t.GetComponent<Mesh> ();
725+
if (mesh) {
726+
return mesh.bounds;
727+
}
728+
var collider = t.GetComponent<Collider> ();
729+
if (collider) {
730+
return collider.bounds;
731+
}
732+
return new Bounds(t.position, Vector3.zero);
733+
}
734+
735+
/// <summary>
736+
/// Finds the center of a group of GameObjects.
737+
/// </summary>
738+
/// <returns>Center of gameObjects.</returns>
739+
/// <param name="gameObjects">Game objects.</param>
740+
private Vector3 FindCenter(IEnumerable<GameObject> gameObjects)
741+
{
742+
Bounds bounds = new Bounds();
743+
// Assign the initial bounds to first GameObject's bounds
744+
// (if we initialize the bounds to 0, then 0 will be part of the bounds)
745+
foreach (var go in gameObjects) {
746+
var tempBounds = GetBounds (go.transform);
747+
bounds = new Bounds (tempBounds.center, tempBounds.size);
748+
break;
749+
}
750+
foreach (var go in gameObjects) {
751+
EncapsulateBounds (go.transform, ref bounds);
752+
}
753+
return bounds.center;
754+
}
755+
756+
/// <summary>
757+
/// Gets the recentered translation.
758+
/// </summary>
759+
/// <returns>The recentered translation.</returns>
760+
/// <param name="t">Transform.</param>
761+
/// <param name="center">Center point.</param>
762+
private Vector3 GetRecenteredTranslation(Transform t, Vector3 center)
763+
{
764+
return t.position - center;
765+
}
766+
767+
public enum TransformExportType { Local, Global, Reset };
695768

696769
/// <summary>
697770
/// Export all the objects in the set.
@@ -764,17 +837,22 @@ public int ExportAll (IEnumerable<UnityEngine.Object> unityExportSet)
764837

765838
if(revisedExportSet.Count == 1){
766839
foreach(var unityGo in revisedExportSet){
767-
exportProgress = this.ExportComponents (unityGo, fbxScene, fbxRootNode, exportProgress, count, TransformExportType.Zeroed);
840+
exportProgress = this.ExportComponents (
841+
unityGo, fbxScene, fbxRootNode, exportProgress,
842+
count, Vector3.zero, TransformExportType.Reset);
768843
if (exportProgress < 0) {
769844
Debug.LogWarning ("Export Cancelled");
770845
return 0;
771846
}
772847
}
773848
}
774849
else{
850+
// find the center of the export set
851+
Vector3 center = EditorTools.ExportSettings.instance.centerObjects? FindCenter(revisedExportSet) : Vector3.zero;
852+
775853
foreach (var unityGo in revisedExportSet) {
776-
exportProgress = this.ExportComponents (unityGo, fbxScene, fbxRootNode, exportProgress, count,
777-
unityGo.transform.parent == null? TransformExportType.Local : TransformExportType.Global);
854+
exportProgress = this.ExportComponents (unityGo, fbxScene, fbxRootNode,
855+
exportProgress, count, center, TransformExportType.Global);
778856
if (exportProgress < 0) {
779857
Debug.LogWarning ("Export Cancelled");
780858
return 0;

0 commit comments

Comments
 (0)