Skip to content

Commit 7acea4a

Browse files
authored
Merge pull request #257 from Unity-Technologies/UNI-29415-export-lights
Uni 29415 export lights
2 parents 1a7f996 + e0499b5 commit 7acea4a

File tree

2 files changed

+148
-5
lines changed

2 files changed

+148
-5
lines changed

Assets/FbxExporters/Editor/FbxExporter.cs

Lines changed: 84 additions & 1 deletion
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>
@@ -838,6 +845,76 @@ protected bool ExportCamera (GameObject unityGO, FbxScene fbxScene, FbxNode fbxN
838845
return true;
839846
}
840847

848+
/// <summary>
849+
/// Exports light component.
850+
/// Supported types: point, spot and directional
851+
/// Cookie => Gobo
852+
/// </summary>
853+
protected bool ExportLight (GameObject unityGo, FbxScene fbxScene, FbxNode fbxNode)
854+
{
855+
Light unityLight = unityGo.GetComponent<Light> ();
856+
857+
if (unityLight == null)
858+
return false;
859+
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+
}
889+
}
890+
// The color of the light.
891+
var unityLightColor = unityLight.color;
892+
fbxLight.Color.Set (new FbxDouble3(unityLightColor.r, unityLightColor.g, unityLightColor.b));
893+
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*/ );
896+
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);
902+
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);
914+
915+
return true;
916+
}
917+
841918
/// <summary>
842919
/// configures default camera for the scene
843920
/// </summary>
@@ -911,8 +988,14 @@ protected int ExportComponents (
911988
}
912989

913990
// export camera, but only if no mesh was exported
991+
bool exportedCamera = false;
914992
if (!exportedMesh) {
915-
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);
916999
}
9171000

9181001
if (Verbose)

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)