Skip to content

Commit 9539f35

Browse files
committed
Uni-45921-physical-camera
1 parent c1adaf3 commit 9539f35

File tree

1 file changed

+135
-24
lines changed

1 file changed

+135
-24
lines changed

Assets/com.unity.formats.fbx/Editor/Scripts/FbxExporter.cs

Lines changed: 135 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,44 @@ namespace FbxExporters
1313
{
1414
namespace CustomExtensions
1515
{
16+
public class MetricDistance {
17+
18+
public static readonly MetricDistance Millimeter = new MetricDistance(0.001f);
19+
public static readonly MetricDistance Centimeter = new MetricDistance(0.01f);
20+
public static readonly MetricDistance Meter = new MetricDistance(1.0f);
21+
22+
private float _meters;
23+
24+
public MetricDistance(float m) {
25+
this._meters = m;
26+
}
27+
28+
public float ToMeters() {
29+
return this._meters;
30+
}
31+
public float ToCentimeters() {
32+
return this._meters * Centimeter.ToMeters();
33+
}
34+
35+
public float ToInches() {
36+
return _meters * 39.3701f;
37+
}
38+
}
39+
40+
//Extension methods must be defined in a static class
41+
public static class FloatExtension
42+
{
43+
public static MetricDistance Meters(this float that) {
44+
return new MetricDistance(that);
45+
}
46+
public static MetricDistance Millimeters(this float that) {
47+
return new MetricDistance(MetricDistance.Millimeter.ToMeters() * that);
48+
}
49+
public static MetricDistance Centimeters(this float that) {
50+
return new MetricDistance(MetricDistance.Centimeter.ToMeters() * that);
51+
}
52+
}
53+
1654
//Extension methods must be defined in a static class
1755
public static class Vector3Extension
1856
{
@@ -1251,7 +1289,7 @@ protected bool ExportInstance (GameObject unityGo, FbxNode fbxNode, FbxScene fbx
12511289
if (unityPrefabType != PrefabType.PrefabInstance &&
12521290
unityPrefabType != PrefabType.ModelPrefabInstance) return false;
12531291

1254-
Object unityPrefabParent = PrefabUtility.GetPrefabParent (unityGo);
1292+
Object unityPrefabParent = PrefabUtility.GetCorrespondingObjectFromSource (unityGo);
12551293

12561294
if (Verbose)
12571295
Debug.Log (string.Format ("exporting instance {0}({1})", unityGo.name, unityPrefabParent.name));
@@ -1290,29 +1328,18 @@ protected bool ExportInstance (GameObject unityGo, FbxNode fbxNode, FbxScene fbx
12901328
}
12911329

12921330
/// <summary>
1293-
/// Exports camera component
1331+
/// Configure FbxCameras from GameCamera
12941332
/// </summary>
1295-
protected bool ExportCamera (GameObject unityGO, FbxScene fbxScene, FbxNode fbxNode)
1333+
protected FbxCamera ConfigureGameCamera (FbxCamera fbxCamera, Camera uniCamera)
12961334
{
1297-
Camera unityCamera = unityGO.GetComponent<Camera> ();
1298-
if (unityCamera == null) {
1299-
return false;
1300-
}
1301-
1302-
FbxCamera fbxCamera = FbxCamera.Create (fbxScene.GetFbxManager(), unityCamera.name);
1303-
if (fbxCamera == null) {
1304-
return false;
1305-
}
1306-
1307-
float aspectRatio = unityCamera.aspect;
1335+
// Configure FilmBack settings as a 35mm TV Projection (0.816 x 0.612)
1336+
float aspectRatio = uniCamera.aspect;
13081337

1309-
#region Configure Film Camera from Game Camera
1310-
// Configure FilmBack settings: 35mm TV Projection (0.816 x 0.612)
13111338
float apertureHeightInInches = 0.612f;
13121339
float apertureWidthInInches = aspectRatio * apertureHeightInInches;
13131340

13141341
FbxCamera.EProjectionType projectionType =
1315-
unityCamera.orthographic ? FbxCamera.EProjectionType.eOrthogonal : FbxCamera.EProjectionType.ePerspective;
1342+
uniCamera.orthographic ? FbxCamera.EProjectionType.eOrthogonal : FbxCamera.EProjectionType.ePerspective;
13161343

13171344
fbxCamera.ProjectionType.Set(projectionType);
13181345
fbxCamera.FilmAspectRatio.Set(aspectRatio);
@@ -1321,19 +1348,104 @@ protected bool ExportCamera (GameObject unityGO, FbxScene fbxScene, FbxNode fbxN
13211348
fbxCamera.SetApertureMode (FbxCamera.EApertureMode.eVertical);
13221349

13231350
// Focal Length
1324-
fbxCamera.FocalLength.Set(fbxCamera.ComputeFocalLength (unityCamera.fieldOfView));
1351+
double focalLength = fbxCamera.ComputeFocalLength (uniCamera.fieldOfView);
1352+
1353+
fbxCamera.FocalLength.Set(focalLength);
1354+
1355+
// Field of View
1356+
fbxCamera.FieldOfView.Set (uniCamera.fieldOfView);
1357+
1358+
// NearPlane
1359+
fbxCamera.SetNearPlane (uniCamera.nearClipPlane.Meters().ToCentimeters());
1360+
1361+
// FarPlane
1362+
fbxCamera.SetFarPlane (uniCamera.farClipPlane.Meters().ToCentimeters());
1363+
1364+
return fbxCamera;
1365+
}
1366+
1367+
/// <summary>
1368+
/// Configure FbxCameras from a Physical Camera
1369+
/// </summary>
1370+
protected FbxCamera ConfigurePhysicalCamera (FbxCamera fbxCamera, Camera uniCamera)
1371+
{
1372+
#if UNITY_2018_2_OR_NEWER
1373+
Debug.Assert(uniCamera.usePhysicalProperties);
1374+
1375+
// Configure FilmBack settings
1376+
float apertureHeightInInches = uniCamera.sensorSize.y.Millimeters().ToInches();
1377+
float apertureWidthInInches = uniCamera.sensorSize.x.Millimeters().ToInches();
1378+
float aspectRatio = apertureWidthInInches / apertureHeightInInches;
1379+
1380+
FbxCamera.EProjectionType projectionType = uniCamera.orthographic
1381+
? FbxCamera.EProjectionType.eOrthogonal
1382+
: FbxCamera.EProjectionType.ePerspective;
1383+
1384+
// NOTE: it is possible to match some of the sensor sizes to the
1385+
// predefined EApertureFormats : e16mmTheatrical, eSuper16mm,
1386+
// e35mmFullAperture, eIMAX. However the round in the sizes is not
1387+
// consistent between Unity and FBX so we choose
1388+
// to leave the values as a eCustomAperture setting.
1389+
1390+
fbxCamera.ProjectionType.Set(projectionType);
1391+
fbxCamera.FilmAspectRatio.Set(aspectRatio);
1392+
fbxCamera.SetApertureWidth (apertureWidthInInches);
1393+
fbxCamera.SetApertureHeight (apertureHeightInInches);
1394+
fbxCamera.SetApertureMode (FbxCamera.EApertureMode.eFocalLength);
1395+
1396+
// Fit the resolution gate horizontally within the film gate.
1397+
fbxCamera.GateFit.Set(FbxCamera.EGateFit.eFitHorizontal);
1398+
1399+
// Lens Shift ( Film Offset ) as a percentage 0..1
1400+
Debug.Assert(uniCamera.lensShift.x >= 0f && uniCamera.lensShift.x <= 1f);
1401+
Debug.Assert(uniCamera.lensShift.y >= 0f && uniCamera.lensShift.y <= 1f);
1402+
fbxCamera.FilmOffsetX.Set(uniCamera.lensShift.x);
1403+
fbxCamera.FilmOffsetY.Set(uniCamera.lensShift.y);
1404+
1405+
// Focal Length
1406+
double focalLength = uniCamera.focalLength;
1407+
1408+
fbxCamera.FocalLength.Set(focalLength); /* in millimeters */
13251409

13261410
// Field of View
1327-
fbxCamera.FieldOfView.Set (unityCamera.fieldOfView);
1411+
fbxCamera.FieldOfView.Set (uniCamera.fieldOfView); /* in degrees */
13281412

13291413
// NearPlane
1330-
fbxCamera.SetNearPlane (unityCamera.nearClipPlane*UnitScaleFactor);
1414+
fbxCamera.SetNearPlane (uniCamera.nearClipPlane.Meters().ToCentimeters());
13311415

13321416
// FarPlane
1333-
fbxCamera.SetFarPlane (unityCamera.farClipPlane*UnitScaleFactor);
1334-
#endregion
1417+
fbxCamera.SetFarPlane (uniCamera.farClipPlane.Meters().ToCentimeters());
1418+
#else
1419+
throw System.NotImplementedException;
1420+
#endif
13351421

1336-
fbxNode.SetNodeAttribute (fbxCamera);
1422+
return fbxCamera;
1423+
}
1424+
1425+
/// <summary>
1426+
/// Exports camera component
1427+
/// </summary>
1428+
protected bool ExportCamera (GameObject unityGO, FbxScene fbxScene, FbxNode fbxNode)
1429+
{
1430+
Camera unityCamera = unityGO.GetComponent<Camera> ();
1431+
if (unityCamera == null) {
1432+
return false;
1433+
}
1434+
1435+
FbxCamera fbxCamera = FbxCamera.Create (fbxScene.GetFbxManager(), unityCamera.name);
1436+
if (fbxCamera == null) {
1437+
return false;
1438+
}
1439+
1440+
fbxNode.SetNodeAttribute (
1441+
#if UNITY_2018_2_OR_NEWER
1442+
unityCamera.usePhysicalProperties
1443+
? ConfigurePhysicalCamera(fbxCamera, unityCamera)
1444+
: ConfigureGameCamera(fbxCamera, unityCamera)
1445+
#else
1446+
ConfigureGameCamera(fbxCamera, unityCamera)
1447+
#endif
1448+
);
13371449

13381450
// set +90 post rotation to counteract for FBX camera's facing +X direction by default
13391451
fbxNode.SetPostRotation(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(0,90,0));
@@ -1634,7 +1746,6 @@ public UnityToMayaConvertSceneHelper(string uniPropertyName)
16341746

16351747
public float Convert(float value)
16361748
{
1637-
// left handed to right handed conversion
16381749
// meters to centimetres conversion
16391750
return unitScaleFactor * value;
16401751
}

0 commit comments

Comments
 (0)