Skip to content

Commit 6dbd8e5

Browse files
author
AJubrey
committed
Merge remote-tracking branch 'origin/master' into Uni-32154_use_MAYA_LOCATION
2 parents 43639f5 + 748c123 commit 6dbd8e5

File tree

11 files changed

+181
-108
lines changed

11 files changed

+181
-108
lines changed

Assets/FbxExporters/Editor/FbxExportSettings.cs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,7 @@ public override void OnInspectorGUI() {
6565
EditorGUILayout.SelectableLabel(pathLabel,
6666
EditorStyles.textField,
6767
GUILayout.MinWidth(SelectableLabelMinWidth),
68-
GUILayout.Height(EditorGUIUtility.singleLineHeight));
69-
GUILayout.EndHorizontal();
70-
GUILayout.BeginHorizontal();
71-
72-
GUILayout.Space(LabelWidth + BrowseButtonOffset);
68+
GUILayout.Height(EditorGUIUtility.singleLineHeight));
7369

7470
if (GUILayout.Button(new GUIContent("...", "Browse to a new location for saving model prefabs"), EditorStyles.miniButton, GUILayout.Width(BrowseButtonWidth)))
7571
{
@@ -105,6 +101,7 @@ public override void OnInspectorGUI() {
105101
}
106102
}
107103
}
104+
108105
GUILayout.EndHorizontal();
109106

110107
EditorGUILayout.Space();
@@ -123,11 +120,6 @@ public override void OnInspectorGUI() {
123120

124121
exportSettings.selectedDCCApp = EditorGUILayout.Popup(exportSettings.selectedDCCApp, options);
125122

126-
GUILayout.EndHorizontal();
127-
GUILayout.BeginHorizontal();
128-
129-
GUILayout.Space(LabelWidth + BrowseButtonOffset);
130-
131123
if (GUILayout.Button(new GUIContent("...", "Browse to a 3D application in a non-default location"), EditorStyles.miniButton, GUILayout.Width(BrowseButtonWidth))) {
132124
var ext = "";
133125
switch (Application.platform) {
@@ -178,13 +170,15 @@ public override void OnInspectorGUI() {
178170

179171
EditorGUILayout.Space();
180172

181-
173+
// disable button if no 3D application is available
174+
EditorGUI.BeginDisabledGroup (!ExportSettings.CanInstall());
182175
var installIntegrationContent = new GUIContent(
183176
"Install Unity Integration",
184177
"Install and configure the Unity integration for the selected 3D application so that you can import and export directly with this project.");
185178
if (GUILayout.Button (installIntegrationContent)) {
186179
FbxExporters.Editor.IntegrationsUI.InstallDCCIntegration ();
187180
}
181+
EditorGUI.EndDisabledGroup ();
188182

189183
GUILayout.FlexibleSpace ();
190184
GUILayout.EndScrollView ();
@@ -649,9 +643,8 @@ public static GUIContent[] GetDCCOptions(){
649643
instance.dccOptionNames = new List<string> ();
650644
FindDCCInstalls ();
651645
}
652-
653-
// store the selected app
654-
var prevSelection = instance.dccOptionPaths[instance.selectedDCCApp];
646+
// store the selected app if any
647+
string prevSelection = GetSelectedDCCPath();
655648

656649
// remove options that no longer exist
657650
List<string> pathsToDelete = new List<string>();
@@ -791,12 +784,21 @@ public static bool IsEarlierThanMax2017(string AppName){
791784

792785
public static string GetSelectedDCCPath()
793786
{
794-
return (instance.dccOptionPaths.Count>0) ? instance.dccOptionPaths [instance.selectedDCCApp] : "";
787+
return (instance.dccOptionPaths.Count>0 &&
788+
instance.selectedDCCApp >= 0 &&
789+
instance.selectedDCCApp < instance.dccOptionPaths.Count) ? instance.dccOptionPaths [instance.selectedDCCApp] : "";
795790
}
796791

797792
public static string GetSelectedDCCName()
798793
{
799-
return (instance.dccOptionPaths.Count>0) ? instance.dccOptionNames [instance.selectedDCCApp] : "";
794+
return (instance.dccOptionNames.Count>0 &&
795+
instance.selectedDCCApp >= 0 &&
796+
instance.selectedDCCApp < instance.dccOptionNames.Count) ? instance.dccOptionNames [instance.selectedDCCApp] : "";
797+
}
798+
799+
public static bool CanInstall()
800+
{
801+
return instance.dccOptionPaths.Count > 0;
800802
}
801803

802804
/// <summary>

Assets/FbxExporters/Editor/FbxExporter.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,11 @@ protected bool ExportCamera (GameObject unityGO, FbxScene fbxScene, FbxNode fbxN
839839

840840
fbxNode.SetNodeAttribute (fbxCamera);
841841

842+
// set +90 post rotation to counteract for FBX camera's facing +X direction by default
843+
fbxNode.SetPostRotation(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(0,90,0));
844+
// have to set rotation active to true in order for post rotation to be applied
845+
fbxNode.SetRotationActive (true);
846+
842847
// make the last camera exported the default camera
843848
DefaultCamera = fbxNode.GetName ();
844849

@@ -943,7 +948,12 @@ protected int ExportComponents (
943948
return -1;
944949
}
945950

946-
fbxNode.SetVisibility (unityGo.activeSelf);
951+
// Default inheritance type in FBX is RrSs, which causes scaling issues in Maya as
952+
// both Maya and Unity use RSrs inheritance by default.
953+
// Note: MotionBuilder uses RrSs inheritance by default as well, though it is possible
954+
// to select a different inheritance type in the UI.
955+
// Use RSrs as the scaling inhertiance instead.
956+
fbxNode.SetTransformationInheritType (FbxTransform.EInheritType.eInheritRSrs);
947957

948958
ExportTransform ( unityGo.transform, fbxNode, newCenter, exportType);
949959

Assets/FbxExporters/Editor/FbxPrefabAutoUpdater.cs

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,9 @@ public FbxRepresentation(Transform xfo, bool isRoot = true)
306306
m_children.Add(child.name, new FbxRepresentation(child, isRoot: false));
307307
}
308308
foreach(var component in xfo.GetComponents<Component>()) {
309+
// ignore missing components
310+
if (component == null) { continue; }
311+
309312
// Don't save the prefab link, to avoid a logic loop.
310313
if (component is FbxPrefab) { continue; }
311314

@@ -759,6 +762,10 @@ void ClassifyComponents(Transform newFbx, Transform prefab)
759762
componentTypes[componentType.ToString()] = componentType;
760763
}
761764
foreach(var component in prefab.GetComponentsInChildren<Component>()) {
765+
// ignore missing components
766+
if (component == null) {
767+
continue;
768+
}
762769
var componentType = component.GetType();
763770
componentTypes[componentType.ToString()] = componentType;
764771
}
@@ -983,13 +990,40 @@ public HashSet<GameObject> ImplementUpdates(FbxPrefab prefabInstance)
983990
prefabComponent = prefabXfo.gameObject.AddComponent(fbxComponent.t);
984991
Log("created component {0}:{1}", nodeName, fbxComponent.t);
985992
}
986-
// Check that the component exists before copying to it.
987-
// This happens for Rect Transform components as the fbx
988-
// contains a Transform which it tries to add/update on the
989-
// prefab, but fails because you cannot have both a Transform
990-
// and a Rect Transform
991-
// UNI-29179 TODO: better handling of Rect Transforms
993+
994+
//If the prefabComponent has not been assigned yet,
995+
//it means that we couldn't find it, and that we tried to add it but that it seems like it already exists.
992996
if (!prefabComponent) {
997+
//This is to confirm that it is a RectTransform
998+
index = prefabComponents.FindIndex(x => x.GetType() == typeof(RectTransform));
999+
1000+
if (index < 0)
1001+
{
1002+
Log("The component could not be found or added, and was not a RectTransform");
1003+
continue;
1004+
}
1005+
1006+
prefabComponent = prefabComponents[index];
1007+
prefabComponents.RemoveAt(index);
1008+
1009+
GameObject tempGameObject = new GameObject();
1010+
try
1011+
{
1012+
Transform tempTransform = tempGameObject.transform;
1013+
1014+
UnityEditor.EditorJsonUtility.FromJsonOverwrite(fbxComponent.jsonValue, tempTransform);
1015+
1016+
var rectTransform = prefabComponent as RectTransform;
1017+
rectTransform.localRotation = tempTransform.localRotation;
1018+
rectTransform.localPosition = tempTransform.localPosition;
1019+
rectTransform.localScale = tempTransform.localScale;
1020+
}
1021+
finally
1022+
{
1023+
GameObject.DestroyImmediate(tempGameObject);
1024+
}
1025+
1026+
Log("updated component {0}:{1}", nodeName, typeof(RectTransform));
9931027
continue;
9941028
}
9951029
// Now set the values.

Assets/FbxExporters/Editor/InstallIntegration.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ public int ConfigureMaya(string mayaPath)
352352
myProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
353353
myProcess.StartInfo.CreateNoWindow = true;
354354
myProcess.StartInfo.UseShellExecute = false;
355+
myProcess.StartInfo.RedirectStandardError = true;
355356

356357
string commandString;
357358

@@ -386,6 +387,14 @@ public int ConfigureMaya(string mayaPath)
386387
ExitCode = myProcess.ExitCode;
387388
Debug.Log(string.Format("Ran maya: [{0}]\nWith args [{1}]\nResult {2}",
388389
mayaPath, myProcess.StartInfo.Arguments, ExitCode));
390+
391+
// see if we got any error messages
392+
if(ExitCode != 0){
393+
string stderr = myProcess.StandardError.ReadToEnd();
394+
if(!string.IsNullOrEmpty(stderr)){
395+
Debug.LogError(string.Format("Maya installation error (exit code: {0}): {1}", ExitCode, stderr));
396+
}
397+
}
389398
}
390399
else
391400
{
@@ -625,6 +634,7 @@ public static int InstallMaxPlugin(string maxExe){
625634
myProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
626635
myProcess.StartInfo.CreateNoWindow = true;
627636
myProcess.StartInfo.UseShellExecute = false;
637+
myProcess.StartInfo.RedirectStandardOutput = true;
628638

629639
myProcess.StartInfo.Arguments = string.Format("-q -silent -mxs \"{0}\"", installScript);
630640

@@ -644,6 +654,14 @@ public static int InstallMaxPlugin(string maxExe){
644654
ExitCode = 0;
645655
}
646656

657+
// print any errors
658+
if(ExitCode != 0){
659+
string stderr = myProcess.StandardOutput.ReadToEnd();
660+
if(!string.IsNullOrEmpty(stderr)){
661+
Debug.LogError(string.Format("3ds Max installation error (exit code: {0}): {1}", ExitCode, stderr));
662+
}
663+
}
664+
647665
Debug.Log(string.Format("Ran max: [{0}]\nWith args [{1}]\nResult {2}",
648666
maxExe, myProcess.StartInfo.Arguments, ExitCode));
649667
}

Assets/FbxExporters/Editor/UnitTests/FbxExportSettingsTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,8 @@ public void TestFindPreferredProgram()
197197
ExportSettings.instance.SetDCCOptionNames(testList);
198198

199199
int preferred = ExportSettings.instance.GetPreferredDCCApp();
200-
//While Maya 2017 and 3ds Max 2017 are tied for most recent, Maya 2017 should win because we prefer Maya.
201-
Assert.AreEqual(preferred, 9);
200+
//While Maya 2017 and 3ds Max 2017 are tied for most recent, Maya 2017 (index 8) should win because we prefer Maya.
201+
Assert.AreEqual(preferred, 8);
202202

203203
ExportSettings.instance.ClearDCCOptionNames();
204204
//Try running it with an empty list

Assets/FbxExporters/Editor/UnitTests/FbxPrefabAutoUpdaterTest.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using NUnit.Framework;
44
using System.IO;
55
using System.Collections.Generic;
6+
using FbxExporters.Editor;
67

78
namespace FbxExporters.UnitTests
89
{
@@ -54,6 +55,62 @@ public void BasicTest ()
5455
imported));
5556
}
5657

58+
[Test]
59+
public void RectTransformTest ()
60+
{
61+
Vector3 scaleForward = new Vector3(1,2,3);
62+
Vector3 positionForward = new Vector3(100, 200, 300);
63+
Vector3 rotationForward = new Vector3(1,2,3);
64+
65+
Vector3 scaleBackward = new Vector3(3, 2, 1);
66+
Vector3 positionBackward = new Vector3(300, 200, 100);
67+
Vector3 rotationBackward = new Vector3(3,2,1);
68+
69+
//Create a hierarchy with a RectTransform
70+
var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
71+
var capsule = GameObject.CreatePrimitive(PrimitiveType.Capsule);
72+
capsule.AddComponent<RectTransform>();
73+
74+
capsule.GetComponent<RectTransform>().localScale = scaleForward;
75+
capsule.GetComponent<RectTransform>().localPosition = positionForward;
76+
capsule.GetComponent<RectTransform>().localRotation = Quaternion.Euler(rotationForward);
77+
78+
capsule.transform.parent = cube.transform;
79+
80+
string filePath = GetRandomFbxFilePath();
81+
82+
//instantiate our hierarchy as a prefab
83+
var oldInstance = ConvertToModel.Convert(cube, fbxFullPath: filePath);
84+
Assert.IsTrue(oldInstance);
85+
86+
Assert.IsTrue(oldInstance.transform.GetChild(0).GetComponent<RectTransform>().localScale == scaleForward);
87+
Assert.IsTrue(oldInstance.transform.GetChild(0).GetComponent<RectTransform>().localPosition == positionForward);
88+
Assert.IsTrue(oldInstance.transform.GetChild(0).GetComponent<RectTransform>().localRotation == Quaternion.Euler(rotationForward));
89+
90+
//Create an "updated" hierarchy
91+
var cube2 = GameObject.CreatePrimitive(PrimitiveType.Cube);
92+
var capsule2 = GameObject.CreatePrimitive(PrimitiveType.Capsule);
93+
capsule2.AddComponent<RectTransform>();
94+
95+
capsule2.GetComponent<RectTransform>().localScale = scaleBackward;
96+
capsule2.GetComponent<RectTransform>().localPosition = positionBackward;
97+
capsule2.GetComponent<RectTransform>().localRotation = Quaternion.Euler(rotationBackward);
98+
99+
capsule2.transform.parent = cube2.transform;
100+
101+
//export our updated hierarchy to the same file path as the original
102+
SleepForFileTimestamp();
103+
FbxExporters.Editor.ModelExporter.ExportObject(filePath, cube2);
104+
AssetDatabase.Refresh();
105+
106+
Assert.IsTrue(oldInstance.transform.GetChild(0).GetComponent<RectTransform>().localScale == scaleBackward);
107+
Assert.IsTrue(oldInstance.transform.GetChild(0).GetComponent<RectTransform>().localPosition == positionBackward);
108+
Assert.IsTrue(oldInstance.transform.GetChild(0).GetComponent<RectTransform>().localRotation == Quaternion.Euler(rotationBackward));
109+
110+
GameObject.DestroyImmediate(cube);
111+
GameObject.DestroyImmediate(cube2);
112+
}
113+
57114
[Test]
58115
public void ReplaceTest ()
59116
{

Assets/FbxExporters/Editor/UnitTests/IntegrationsTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void BasicTest() {
4141
LogNonEmptyString ("display name", mayaIntegration.DccDisplayName);
4242
LogNonEmptyString ("integration zip path", mayaIntegration.IntegrationZipPath);
4343

44-
Assert.IsFalse (Editor.MayaIntegration.IsHeadlessInstall () == 0);
44+
Assert.IsTrue (Editor.MayaIntegration.IsHeadlessInstall () == 0);
4545

4646
LogNonEmptyString ("module template path", mayaIntegration.GetModuleTemplatePath ());
4747
LogNonEmptyString ("package path", Editor.MayaIntegration.GetPackagePath ());

Assets/FbxExporters/Editor/UnitTests/ModelExporterTest.cs

Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ public void TestExportCamera(){
349349
camera.nearClipPlane = 19;
350350
camera.farClipPlane = 500.6f;
351351

352+
filename = GetRandomFbxFilePath (); // export to a different file
352353
fbxCamera = ExportCamera (filename, cameraObj);
353354
CompareCameraValues (camera, fbxCamera);
354355
Assert.AreEqual (camera.orthographicSize, fbxCamera.orthographicSize);
@@ -376,69 +377,5 @@ private void CompareCameraValues(Camera camera, Camera fbxCamera, float delta=0.
376377
Assert.AreEqual (camera.nearClipPlane, fbxCamera.nearClipPlane, delta);
377378
Assert.AreEqual (camera.farClipPlane, fbxCamera.farClipPlane, delta);
378379
}
379-
380-
[Test]
381-
public void TestNodeVisibility()
382-
{
383-
// create test hierarchy
384-
// root (enabled)
385-
// -- parent1 (enabled)
386-
// ---- child3 (disabled)
387-
// -- parent2 (disabled)
388-
// ---- child1 (disabled)
389-
// ---- child2 (enabled)
390-
391-
var root = GameObject.CreatePrimitive(PrimitiveType.Cube);
392-
root.name = "root";
393-
var parent1 = GameObject.CreatePrimitive(PrimitiveType.Cube);
394-
parent1.name = "parent1";
395-
var parent2 = GameObject.CreatePrimitive(PrimitiveType.Cube);
396-
parent2.name = "parent2";
397-
var child1 = GameObject.CreatePrimitive(PrimitiveType.Cube);
398-
child1.name = "child1";
399-
var child2 = GameObject.CreatePrimitive(PrimitiveType.Cube);
400-
child2.name = "child2";
401-
var child3 = GameObject.CreatePrimitive (PrimitiveType.Cube);
402-
child3.name = "child3";
403-
404-
parent1.transform.SetParent (root.transform);
405-
parent2.transform.SetParent (root.transform);
406-
child1.transform.SetParent (parent2.transform);
407-
child2.transform.SetParent (parent2.transform);
408-
child3.transform.SetParent (parent1.transform);
409-
410-
root.SetActive (true);
411-
parent1.SetActive (true);
412-
child2.SetActive (true);
413-
parent2.SetActive (false);
414-
child1.SetActive (false);
415-
child3.SetActive (false);
416-
417-
string filename = GetRandomFbxFilePath ();
418-
ModelExporter.ExportObject (filename, root);
419-
420-
GameObject fbxObj = AssetDatabase.LoadMainAssetAtPath (filename) as GameObject;
421-
422-
// check root
423-
CheckObjectVisibility (fbxObj, true);
424-
425-
// check child nodes
426-
foreach (Transform child in fbxObj.transform) {
427-
var isParent1 = child.name.Equals ("parent1");
428-
CheckObjectVisibility (child.gameObject, isParent1);
429-
430-
// all children should be disabled
431-
foreach (Transform c in child) {
432-
CheckObjectVisibility (c.gameObject, false);
433-
}
434-
}
435-
}
436-
437-
private void CheckObjectVisibility(GameObject obj, bool expectedVisibility){
438-
Assert.IsTrue (obj.activeSelf);
439-
var renderer = obj.GetComponent<MeshRenderer> ();
440-
Assert.IsNotNull (renderer);
441-
Assert.AreEqual(expectedVisibility, renderer.enabled);
442-
}
443380
}
444381
}

0 commit comments

Comments
 (0)