Skip to content

Commit e1f5874

Browse files
author
AJubrey
committed
Merge branch 'master' into Uni-33058_unitTest_for_VendorLocations
# Conflicts: # Assets/FbxExporters/Editor/FbxExportSettings.cs # Assets/FbxExporters/Editor/UnitTests/FbxExportSettingsTest.cs
2 parents 64f9648 + 7acea4a commit e1f5874

File tree

5 files changed

+209
-54
lines changed

5 files changed

+209
-54
lines changed

Assets/FbxExporters/Editor/FbxExportSettings.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,13 @@ public override void OnInspectorGUI() {
158158
EditorGUILayout.Space();
159159

160160
exportSettings.launchAfterInstallation = EditorGUILayout.Toggle(
161-
new GUIContent("Keep open:",
161+
new GUIContent("Keep Open:",
162162
"Keep the selected 3D application open after Unity integration install has completed."),
163163
exportSettings.launchAfterInstallation
164164
);
165165

166166
exportSettings.HideSendToUnityMenu = EditorGUILayout.Toggle(
167-
new GUIContent("Hide native menu:",
167+
new GUIContent("Hide Native Menu:",
168168
"Replace Maya's native 'Send to Unity' menu with the Unity Integration's menu"),
169169
exportSettings.HideSendToUnityMenu
170170
);
@@ -451,6 +451,11 @@ public void SetDCCOptionNames(List<string> newList)
451451
dccOptionNames = newList;
452452
}
453453

454+
public void SetDCCOptionPaths(List<string> newList)
455+
{
456+
dccOptionPaths = newList;
457+
}
458+
454459
public void ClearDCCOptionNames()
455460
{
456461
dccOptionNames.Clear();

Assets/FbxExporters/Editor/FbxExporter.cs

Lines changed: 79 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,13 @@ public static Material DefaultMaterial {
124124
}
125125
static Material s_defaultMaterial = null;
126126

127+
static Dictionary<UnityEngine.LightType, FbxLight.EType> MapLightType = new Dictionary<UnityEngine.LightType, FbxLight.EType> () {
128+
{ UnityEngine.LightType.Directional, FbxLight.EType.eDirectional },
129+
{ UnityEngine.LightType.Spot, FbxLight.EType.eSpot },
130+
{ UnityEngine.LightType.Point, FbxLight.EType.ePoint },
131+
{ UnityEngine.LightType.Area, FbxLight.EType.eArea },
132+
};
133+
127134
/// <summary>
128135
/// Gets the version number of the FbxExporters plugin from the readme.
129136
/// </summary>
@@ -825,18 +832,6 @@ protected bool ExportCamera (GameObject unityGO, FbxScene fbxScene, FbxNode fbxN
825832
fbxCamera.SetFarPlane (unityCamera.farClipPlane*UnitScaleFactor);
826833
#endregion
827834

828-
// Export backgroundColor as a custom property
829-
// NOTE: export on fbxNode so that it will show up in Maya
830-
ExportColorProperty (fbxNode, unityCamera.backgroundColor,
831-
MakeName("backgroundColor"),
832-
"The color with which the screen will be cleared.");
833-
834-
// Export clearFlags as a custom property
835-
// NOTE: export on fbxNode so that it will show up in Maya
836-
ExportIntProperty (fbxNode, (int)unityCamera.clearFlags,
837-
MakeName("clearFlags"),
838-
"How the camera clears the background.");
839-
840835
fbxNode.SetNodeAttribute (fbxCamera);
841836

842837
// set +90 post rotation to counteract for FBX camera's facing +X direction by default
@@ -851,55 +846,84 @@ protected bool ExportCamera (GameObject unityGO, FbxScene fbxScene, FbxNode fbxN
851846
}
852847

853848
/// <summary>
854-
/// configures default camera for the scene
849+
/// Exports light component.
850+
/// Supported types: point, spot and directional
851+
/// Cookie => Gobo
855852
/// </summary>
856-
protected void SetDefaultCamera (FbxScene fbxScene)
853+
protected bool ExportLight (GameObject unityGo, FbxScene fbxScene, FbxNode fbxNode)
857854
{
858-
if (DefaultCamera == "")
859-
DefaultCamera = Globals.FBXSDK_CAMERA_PERSPECTIVE;
855+
Light unityLight = unityGo.GetComponent<Light> ();
860856

861-
fbxScene.GetGlobalSettings ().SetDefaultCamera (DefaultCamera);
862-
}
857+
if (unityLight == null)
858+
return false;
863859

864-
/// <summary>
865-
/// Export Component's color property
866-
/// </summary>
867-
bool ExportColorProperty (FbxObject fbxObject, Color value, string name, string label)
868-
{
869-
// create a custom property for component value
870-
var fbxProperty = FbxProperty.Create (fbxObject, Globals.FbxColor4DT, name, label);
871-
if (!fbxProperty.IsValid ()) {
872-
throw new System.NullReferenceException ();
860+
FbxLight.EType fbxLightType;
861+
862+
// Is light type supported?
863+
if (!MapLightType.TryGetValue (unityLight.type, out fbxLightType))
864+
return false;
865+
866+
FbxLight fbxLight = FbxLight.Create (fbxScene.GetFbxManager (), unityLight.name);
867+
868+
// Set the type of the light.
869+
fbxLight.LightType.Set(fbxLightType);
870+
871+
switch (unityLight.type)
872+
{
873+
case LightType.Directional : {
874+
break;
875+
}
876+
case LightType.Spot : {
877+
// Set the angle of the light's spotlight cone in degrees.
878+
fbxLight.InnerAngle.Set(unityLight.spotAngle);
879+
fbxLight.OuterAngle.Set(unityLight.spotAngle);
880+
break;
881+
}
882+
case LightType.Point : {
883+
break;
884+
}
885+
case LightType.Area : {
886+
// TODO: areaSize: The size of the area light by scaling the node XY
887+
break;
888+
}
873889
}
890+
// The color of the light.
891+
var unityLightColor = unityLight.color;
892+
fbxLight.Color.Set (new FbxDouble3(unityLightColor.r, unityLightColor.g, unityLightColor.b));
874893

875-
FbxColor fbxColor = new FbxColor(value.r, value.g, value.b, value.a );
894+
// Set the Intensity of a light is multiplied with the Light color.
895+
fbxLight.Intensity.Set (unityLight.intensity * UnitScaleFactor /*compensate for Maya scaling by system units*/ );
876896

877-
fbxProperty.Set (fbxColor);
897+
// Set the range of the light.
898+
// applies-to: Point & Spot
899+
// => FarAttenuationStart, FarAttenuationEnd
900+
fbxLight.FarAttenuationStart.Set (0.01f /* none zero start */);
901+
fbxLight.FarAttenuationEnd.Set(unityLight.range*UnitScaleFactor);
878902

879-
// Must be marked user-defined or it won't be shown in most DCCs
880-
fbxProperty.ModifyFlag (FbxPropertyFlags.EFlags.eUserDefined, true);
881-
fbxProperty.ModifyFlag (FbxPropertyFlags.EFlags.eAnimatable, true);
903+
// shadows Set how this light casts shadows
904+
// applies-to: Point & Spot
905+
bool unityLightCastShadows = unityLight.shadows != LightShadows.None;
906+
fbxLight.CastShadows.Set (unityLightCastShadows);
907+
908+
fbxNode.SetNodeAttribute (fbxLight);
909+
910+
// set +90 post rotation on x to counteract for FBX light's facing -Y direction by default
911+
fbxNode.SetPostRotation(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(90,0,0));
912+
// have to set rotation active to true in order for post rotation to be applied
913+
fbxNode.SetRotationActive (true);
882914

883915
return true;
884916
}
885917

886918
/// <summary>
887-
/// Export Component's int property
919+
/// configures default camera for the scene
888920
/// </summary>
889-
bool ExportIntProperty (FbxObject fbxObject, int value, string name, string label)
921+
protected void SetDefaultCamera (FbxScene fbxScene)
890922
{
891-
// create a custom property for component value
892-
var fbxProperty = FbxProperty.Create (fbxObject, Globals.FbxIntDT, name, label);
893-
if (!fbxProperty.IsValid ()) {
894-
throw new System.NullReferenceException ();
895-
}
896-
fbxProperty.Set (value);
897-
898-
// Must be marked user-defined or it won't be shown in most DCCs
899-
fbxProperty.ModifyFlag (FbxPropertyFlags.EFlags.eUserDefined, true);
900-
fbxProperty.ModifyFlag (FbxPropertyFlags.EFlags.eAnimatable, true);
923+
if (DefaultCamera == "")
924+
DefaultCamera = Globals.FBXSDK_CAMERA_PERSPECTIVE;
901925

902-
return true;
926+
fbxScene.GetGlobalSettings ().SetDefaultCamera (DefaultCamera);
903927
}
904928

905929
/// <summary>
@@ -964,8 +988,14 @@ protected int ExportComponents (
964988
}
965989

966990
// export camera, but only if no mesh was exported
991+
bool exportedCamera = false;
967992
if (!exportedMesh) {
968-
ExportCamera (unityGo, fbxScene, fbxNode);
993+
exportedCamera = ExportCamera (unityGo, fbxScene, fbxNode);
994+
}
995+
996+
// export light, but only if no mesh or camera was exported
997+
if (!exportedMesh && !exportedCamera) {
998+
ExportLight (unityGo, fbxScene, fbxNode);
969999
}
9701000

9711001
if (Verbose)
@@ -1318,6 +1348,9 @@ private void ReplaceFile ()
13181348
} catch (IOException) {
13191349
}
13201350

1351+
// refresh the database so Unity knows the file's been deleted
1352+
AssetDatabase.Refresh();
1353+
13211354
if (File.Exists (m_lastFilePath)) {
13221355
Debug.LogWarning ("Failed to delete file: " + m_lastFilePath);
13231356
}

Assets/FbxExporters/Editor/UnitTests/FbxExportSettingsTest.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,57 @@ public void TestFindPreferredProgram()
214214
}
215215

216216
[Test]
217+
public void TestGetDCCOptions()
218+
{
219+
//Our.exe file
220+
string executableName = "/maya.exe";
221+
222+
//Our folder names
223+
string firstSubFolder = "/maya 3000";
224+
string secondSubFolder = "/maya 3001";
225+
226+
//Make a folder structure to mimic an 'autodesk' type hierarchy
227+
string testFolder = Path.GetRandomFileName();
228+
var firstPath = Directory.CreateDirectory(testFolder + firstSubFolder);
229+
var secondPath = Directory.CreateDirectory(testFolder + secondSubFolder);
230+
231+
try
232+
{
233+
//Create any files we need within the folders
234+
FileInfo firstExe = new FileInfo(firstPath.FullName + executableName);
235+
using (FileStream s = firstExe.Create()) { }
236+
237+
//Add the paths which will be copied to DCCOptionPaths
238+
List<string> testPathList = new List<string>();
239+
testPathList.Add(firstPath.FullName + executableName); //this path is valid!
240+
testPathList.Add(secondPath.FullName + executableName);
241+
testPathList.Add(null);
242+
testPathList.Add("cookies/milk/foo/bar");
243+
244+
//Add the names which will be copied to DCCOptionNames
245+
List<string> testNameList = new List<string>();
246+
testNameList.Add(firstSubFolder.TrimStart('/'));
247+
testNameList.Add(secondSubFolder.TrimStart('/'));
248+
testNameList.Add(null);
249+
testNameList.Add("Cookies & Milk");
250+
251+
ExportSettings.instance.SetDCCOptionNames(testNameList);
252+
ExportSettings.instance.SetDCCOptionPaths(testPathList);
253+
254+
GUIContent[] options = ExportSettings.GetDCCOptions();
255+
256+
//We expect 1, as the others are purposefully bogus
257+
Assert.AreEqual(options.Length, 1);
258+
259+
Assert.IsTrue(options[0].text == "maya 3000");
260+
}
261+
finally
262+
{
263+
Directory.Delete(testFolder, true);
264+
}
265+
}
266+
267+
[Test]
217268
public void FindDCCInstallsTest1()
218269
{
219270
string rootDir1 = GetRandomFileNamePath(extName: "");

Assets/FbxExporters/Editor/UnitTests/FbxPrefabTest.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,10 +425,16 @@ public void TestTransformAndReparenting()
425425
var newCopyPath = ModelExporter.ExportObject(
426426
GetRandomFbxFilePath(), root);
427427
SleepForFileTimestamp();
428+
429+
var destFile = new FbxPrefabAutoUpdater.FbxPrefabUtility (original.GetComponent<FbxPrefab> ()).GetFbxAssetPath ();
430+
if (System.IO.File.Exists (destFile)) {
431+
System.IO.File.Delete (destFile);
432+
}
433+
AssetDatabase.Refresh ();
428434
System.IO.File.Copy(
429435
newCopyPath,
430-
new FbxPrefabAutoUpdater.FbxPrefabUtility(original.GetComponent<FbxPrefab>()).GetFbxAssetPath(),
431-
overwrite: true);
436+
destFile,
437+
overwrite: false);
432438
AssetDatabase.Refresh();
433439

434440
// Make sure the update took.

Assets/FbxExporters/Editor/UnitTests/ModelExporterTest.cs

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,13 +362,24 @@ public void TestExportCamera(){
362362
/// <param name="filename">Filename.</param>
363363
/// <param name="cameraObj">Camera object.</param>
364364
private Camera ExportCamera(string filename, GameObject cameraObj){
365-
ModelExporter.ExportObject (filename, cameraObj);
365+
return ExportComponent<Camera> (filename, cameraObj);
366+
}
367+
368+
/// <summary>
369+
/// Exports the GameObject and returns component of type T.
370+
/// </summary>
371+
/// <returns>The component.</returns>
372+
/// <param name="filename">Filename.</param>
373+
/// <param name="obj">Object.</param>
374+
/// <typeparam name="T">The component type.</typeparam>
375+
private T ExportComponent<T>(string filename, GameObject obj) where T : Component {
376+
ModelExporter.ExportObject (filename, obj);
366377

367378
GameObject fbxObj = AssetDatabase.LoadMainAssetAtPath(filename) as GameObject;
368-
var fbxCamera = fbxObj.GetComponent<Camera> ();
379+
var fbxComponent = fbxObj.GetComponent<T> ();
369380

370-
Assert.IsNotNull (fbxCamera);
371-
return fbxCamera;
381+
Assert.IsNotNull (fbxComponent);
382+
return fbxComponent;
372383
}
373384

374385
private void CompareCameraValues(Camera camera, Camera fbxCamera, float delta=0.001f){
@@ -377,5 +388,54 @@ private void CompareCameraValues(Camera camera, Camera fbxCamera, float delta=0.
377388
Assert.AreEqual (camera.nearClipPlane, fbxCamera.nearClipPlane, delta);
378389
Assert.AreEqual (camera.farClipPlane, fbxCamera.farClipPlane, delta);
379390
}
391+
392+
[Test]
393+
public void TestExportLight()
394+
{
395+
// create a Unity light
396+
GameObject lightObj = new GameObject("TestLight");
397+
Light light = lightObj.AddComponent<Light> ();
398+
399+
light.type = LightType.Spot;
400+
light.spotAngle = 55.4f;
401+
light.color = Color.blue;
402+
light.intensity = 2.3f;
403+
light.range = 45;
404+
light.shadows = LightShadows.Soft;
405+
406+
string filename = GetRandomFbxFilePath ();
407+
var fbxLight = ExportComponent<Light> (filename, lightObj);
408+
CompareLightValues (light, fbxLight);
409+
410+
light.type = LightType.Point;
411+
light.color = Color.red;
412+
light.intensity = 0.4f;
413+
light.range = 120;
414+
light.shadows = LightShadows.Hard;
415+
416+
filename = GetRandomFbxFilePath ();
417+
fbxLight = ExportComponent<Light> (filename, lightObj);
418+
CompareLightValues (light, fbxLight);
419+
}
420+
421+
private void CompareLightValues(Light light, Light fbxLight, float delta=0.001f){
422+
Assert.AreEqual (light.type, fbxLight.type);
423+
if (light.type == LightType.Spot) {
424+
Assert.AreEqual (light.spotAngle, fbxLight.spotAngle, delta);
425+
}
426+
Assert.AreEqual (light.color, fbxLight.color);
427+
Assert.AreEqual (light.intensity, fbxLight.intensity, delta);
428+
Assert.AreEqual (light.range, fbxLight.range, delta);
429+
430+
// compare shadows
431+
// make sure that if we exported without shadows, don't import with shadows
432+
if (light.shadows == LightShadows.None) {
433+
Assert.AreEqual (LightShadows.None, fbxLight.shadows);
434+
} else {
435+
Assert.AreNotEqual (LightShadows.None, fbxLight.shadows);
436+
}
437+
438+
Assert.IsTrue (light.transform.rotation == fbxLight.transform.rotation);
439+
}
380440
}
381441
}

0 commit comments

Comments
 (0)