CameraVisitor.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. using UnityEngine;
  2. using Autodesk.Fbx;
  3. using UnityEditor.Formats.Fbx.Exporter.CustomExtensions;
  4. using System.Collections.Generic;
  5. namespace UnityEditor.Formats.Fbx.Exporter
  6. {
  7. namespace Visitors
  8. {
  9. internal static class CameraVisitor
  10. {
  11. private static Dictionary<Camera.GateFitMode, FbxCamera.EGateFit> s_mapGateFit = new Dictionary<Camera.GateFitMode, FbxCamera.EGateFit>()
  12. {
  13. { Camera.GateFitMode.Fill, FbxCamera.EGateFit.eFitFill },
  14. { Camera.GateFitMode.Horizontal, FbxCamera.EGateFit.eFitHorizontal },
  15. { Camera.GateFitMode.None, FbxCamera.EGateFit.eFitNone },
  16. { Camera.GateFitMode.Overscan, FbxCamera.EGateFit.eFitOverscan },
  17. { Camera.GateFitMode.Vertical, FbxCamera.EGateFit.eFitVertical }
  18. };
  19. /// <summary>
  20. /// Visit Object and configure FbxCamera
  21. /// </summary>
  22. public static void ConfigureCamera (Camera unityCamera, FbxCamera fbxCamera)
  23. {
  24. if (unityCamera.usePhysicalProperties)
  25. ConfigurePhysicalCamera(fbxCamera, unityCamera);
  26. else
  27. ConfigureGameCamera(fbxCamera, unityCamera);
  28. }
  29. /// <summary>
  30. /// Configure FbxCameras from GameCamera
  31. /// </summary>
  32. private static void ConfigureGameCamera (FbxCamera fbxCamera, Camera unityCamera)
  33. {
  34. // Configure FilmBack settings as a 35mm TV Projection (0.816 x 0.612)
  35. float aspectRatio = unityCamera.aspect;
  36. float apertureHeightInInches = 0.612f;
  37. float apertureWidthInInches = aspectRatio * apertureHeightInInches;
  38. FbxCamera.EProjectionType projectionType =
  39. unityCamera.orthographic ? FbxCamera.EProjectionType.eOrthogonal : FbxCamera.EProjectionType.ePerspective;
  40. fbxCamera.ProjectionType.Set(projectionType);
  41. fbxCamera.FilmAspectRatio.Set(aspectRatio);
  42. fbxCamera.SetApertureWidth (apertureWidthInInches);
  43. fbxCamera.SetApertureHeight (apertureHeightInInches);
  44. fbxCamera.SetApertureMode (FbxCamera.EApertureMode.eVertical);
  45. // Focal Length
  46. double focalLength = fbxCamera.ComputeFocalLength (unityCamera.fieldOfView);
  47. fbxCamera.FocalLength.Set(focalLength);
  48. // Field of View
  49. fbxCamera.FieldOfView.Set (unityCamera.fieldOfView);
  50. // NearPlane
  51. fbxCamera.SetNearPlane (unityCamera.nearClipPlane.Meters().ToCentimeters());
  52. // FarPlane
  53. fbxCamera.SetFarPlane (unityCamera.farClipPlane.Meters().ToCentimeters());
  54. return ;
  55. }
  56. public static Vector2 GetSizeOfMainGameView()
  57. {
  58. System.Type T = System.Type.GetType("UnityEditor.GameView,UnityEditor");
  59. System.Reflection.MethodInfo GetSizeOfMainGameView = T.GetMethod("GetSizeOfMainGameView", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
  60. System.Object Res = GetSizeOfMainGameView.Invoke(null, null);
  61. return (Vector2)Res;
  62. }
  63. /// <summary>
  64. /// Configure FbxCameras from a Physical Camera
  65. /// </summary>
  66. private static void ConfigurePhysicalCamera (FbxCamera fbxCamera, Camera unityCamera)
  67. {
  68. Debug.Assert(unityCamera.usePhysicalProperties);
  69. // Configure FilmBack settings
  70. float apertureHeightInInches = unityCamera.sensorSize.y.Millimeters().ToInches();
  71. float apertureWidthInInches = unityCamera.sensorSize.x.Millimeters().ToInches();
  72. float aspectRatio = apertureWidthInInches / apertureHeightInInches;
  73. FbxCamera.EProjectionType projectionType = unityCamera.orthographic
  74. ? FbxCamera.EProjectionType.eOrthogonal
  75. : FbxCamera.EProjectionType.ePerspective;
  76. // NOTE: it is possible to match some of the sensor sizes to the
  77. // predefined EApertureFormats : e16mmTheatrical, eSuper16mm,
  78. // e35mmFullAperture, eIMAX. However the round in the sizes is not
  79. // consistent between Unity and FBX so we choose
  80. // to leave the values as a eCustomAperture setting.
  81. fbxCamera.ProjectionType.Set(projectionType);
  82. fbxCamera.FilmAspectRatio.Set(aspectRatio);
  83. Vector2 gameViewSize = GetSizeOfMainGameView();
  84. fbxCamera.SetAspect(FbxCamera.EAspectRatioMode.eFixedRatio, gameViewSize.x/gameViewSize.y, 1.0);
  85. fbxCamera.SetApertureWidth (apertureWidthInInches);
  86. fbxCamera.SetApertureHeight (apertureHeightInInches);
  87. // Fit the resolution gate horizontally within the film gate.
  88. fbxCamera.GateFit.Set(s_mapGateFit[unityCamera.gateFit]);
  89. // Lens Shift ( Film Offset ) as a percentage 0..1
  90. // FBX FilmOffset is in inches
  91. fbxCamera.FilmOffsetX.Set(apertureWidthInInches * Mathf.Clamp(Mathf.Abs(unityCamera.lensShift.x), 0f, 1f) * Mathf.Sign(unityCamera.lensShift.x));
  92. fbxCamera.FilmOffsetY.Set(apertureHeightInInches * Mathf.Clamp(Mathf.Abs(unityCamera.lensShift.y), 0f, 1f) * Mathf.Sign(unityCamera.lensShift.y));
  93. // Focal Length
  94. fbxCamera.SetApertureMode (FbxCamera.EApertureMode.eFocalLength);
  95. double focalLength = (double)unityCamera.focalLength;
  96. fbxCamera.FocalLength.Set(focalLength); /* in millimeters */
  97. // NearPlane
  98. fbxCamera.SetNearPlane ((double)unityCamera.nearClipPlane.Meters().ToCentimeters());
  99. // FarPlane
  100. fbxCamera.SetFarPlane ((float)unityCamera.farClipPlane.Meters().ToCentimeters());
  101. return ;
  102. }
  103. }
  104. }
  105. }