작업 조건 분석 기능 개발
This commit is contained in:
@@ -0,0 +1,363 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2012-2022 RenderHeads Ltd. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace RenderHeads.Media.AVProMovieCapture.Editor
|
||||
{
|
||||
public class EditorScreenshot : MonoBehaviour
|
||||
{
|
||||
internal enum ImageFormat
|
||||
{
|
||||
PNG,
|
||||
JPG,
|
||||
TGA,
|
||||
EXR,
|
||||
}
|
||||
|
||||
internal enum ExrPrecision
|
||||
{
|
||||
Half,
|
||||
Float,
|
||||
}
|
||||
|
||||
internal enum ExrCompression
|
||||
{
|
||||
None,
|
||||
ZIP,
|
||||
RLE,
|
||||
PIZ,
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
internal class Options
|
||||
{
|
||||
[SerializeField, Range(1, 100)]
|
||||
internal int jpgQuality = 75;
|
||||
|
||||
[SerializeField]
|
||||
internal ExrPrecision exrPrecision;
|
||||
|
||||
[SerializeField]
|
||||
internal ExrCompression exrCompression;
|
||||
|
||||
internal Texture2D.EXRFlags GetExrFlags()
|
||||
{
|
||||
Texture2D.EXRFlags result = Texture2D.EXRFlags.None;
|
||||
if (exrPrecision == ExrPrecision.Float) result |= Texture2D.EXRFlags.OutputAsFloat;
|
||||
if (exrCompression == ExrCompression.ZIP) result |= Texture2D.EXRFlags.CompressZIP;
|
||||
else if (exrCompression == ExrCompression.RLE) result |= Texture2D.EXRFlags.CompressRLE;
|
||||
else if (exrCompression == ExrCompression.PIZ) result |= Texture2D.EXRFlags.CompressPIZ;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private const string SceneCameraName = "SceneCamera";
|
||||
|
||||
internal static RenderTexture GetSceneViewTexture()
|
||||
{
|
||||
RenderTexture result = null;
|
||||
Camera[] cameras = FindAllCameras();
|
||||
if (cameras != null)
|
||||
{
|
||||
Camera camera = FindCameraByName(cameras.Length, cameras, SceneCameraName);
|
||||
if (camera != null)
|
||||
{
|
||||
if (camera.targetTexture != null)
|
||||
{
|
||||
// Note we have to force a render
|
||||
camera.Render();
|
||||
result = camera.targetTexture;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static RenderTexture GetSceneViewTexture2()
|
||||
{
|
||||
RenderTexture result = null;
|
||||
RenderTexture[] rts = Resources.FindObjectsOfTypeAll<RenderTexture>();
|
||||
foreach (RenderTexture rt in rts)
|
||||
{
|
||||
if (rt.name == "SceneView RT")
|
||||
{
|
||||
result = rt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static void SceneViewToFile(string fileNamePrefix, string folderPath, ImageFormat format, Options options)
|
||||
{
|
||||
RenderTexture cameraTexture = GetSceneViewTexture();
|
||||
if (cameraTexture != null)
|
||||
{
|
||||
Texture2D texture = GetReadableTexture(cameraTexture, format == ImageFormat.EXR);
|
||||
if (texture != null)
|
||||
{
|
||||
string filePath = EditorScreenshot.GenerateFilename(fileNamePrefix, format, texture.width, texture.height);
|
||||
filePath = GenerateFilePath(folderPath, filePath);
|
||||
TextureToFile(texture, filePath, format, options);
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
Destroy(texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyImmediate(texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("SceneView texture isn't available, make sure the view is visible");
|
||||
}
|
||||
}
|
||||
|
||||
internal static Texture2D GetReadableTexture(RenderTexture texture, bool supportHDR)
|
||||
{
|
||||
var oldRT = RenderTexture.active;
|
||||
TextureFormat format = TextureFormat.RGBA32;
|
||||
if (supportHDR)
|
||||
{
|
||||
format = TextureFormat.RGBAFloat;
|
||||
}
|
||||
Texture2D destTex = new Texture2D(texture.width, texture.height, format, false, supportHDR);
|
||||
RenderTexture.active = texture;
|
||||
destTex.ReadPixels(new Rect(0, 0, texture.width, texture.height), 0, 0);
|
||||
destTex.Apply();
|
||||
RenderTexture.active = oldRT;
|
||||
return destTex;
|
||||
}
|
||||
|
||||
internal static bool SupportsTGA()
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static bool SupportsGameViewJPGTGAEXR()
|
||||
{
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
return Application.isPlaying;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static bool SupportsGameViewEXR()
|
||||
{
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
return Application.isPlaying;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static void TextureToFile(Texture2D texture, string filePath, ImageFormat format, Options options)
|
||||
{
|
||||
byte[] data = null;
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
switch (format)
|
||||
{
|
||||
case ImageFormat.PNG:
|
||||
data = ImageConversion.EncodeToPNG(texture);
|
||||
break;
|
||||
case ImageFormat.JPG:
|
||||
data = ImageConversion.EncodeToJPG(texture, options.jpgQuality);
|
||||
break;
|
||||
case ImageFormat.TGA:
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
data = ImageConversion.EncodeToTGA(texture);
|
||||
#endif
|
||||
break;
|
||||
case ImageFormat.EXR:
|
||||
data = ImageConversion.EncodeToEXR(texture, options.GetExrFlags());
|
||||
break;
|
||||
}
|
||||
#else
|
||||
switch (format)
|
||||
{
|
||||
case ImageFormat.PNG:
|
||||
data = texture.EncodeToPNG();
|
||||
break;
|
||||
case ImageFormat.JPG:
|
||||
data = texture.EncodeToJPG(options.jpgQuality);
|
||||
break;
|
||||
case ImageFormat.EXR:
|
||||
data = texture.EncodeToEXR(options.GetExrFlags());
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (data != null)
|
||||
{
|
||||
System.IO.File.WriteAllBytes(filePath, data);
|
||||
OnFileWritten(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void GameViewToPNG(string filePath, int superSize = 1)
|
||||
{
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
ScreenCapture.CaptureScreenshot(filePath, superSize);
|
||||
#else
|
||||
Application.CaptureScreenshot(filePath, superSize);
|
||||
#endif
|
||||
|
||||
// The screenshot will not be generated until the frame has finished (at least in Application.CaptureScreenshot())
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
|
||||
}
|
||||
|
||||
OnFileWritten(filePath);
|
||||
}
|
||||
|
||||
internal static void OnFileWritten(string filePath)
|
||||
{
|
||||
Debug.Log("[AVProMovieCapture] File written: " + filePath);
|
||||
CaptureBase.LastFileSaved = filePath;
|
||||
}
|
||||
|
||||
|
||||
internal static void RenderTextureToFile(string filePath, ImageFormat format, Options options, RenderTexture rt)
|
||||
{
|
||||
Texture2D texture = GetReadableTexture(rt, format == ImageFormat.EXR);
|
||||
if (texture != null)
|
||||
{
|
||||
TextureToFile(texture, filePath, format, options);
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
Destroy(texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyImmediate(texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void GameViewToFile(string filePath, ImageFormat format, Options options, int superSize = 1)
|
||||
{
|
||||
// Coroutines aren't supported in editor mode, so we fake it using a GameObject with EditorCoroutine component
|
||||
GameObject go = new GameObject("temp-screenshot");
|
||||
go.hideFlags = HideFlags.HideAndDontSave;
|
||||
EditorCoroutine co = go.AddComponent<EditorCoroutine>();
|
||||
co.RunCoroutine(EditorScreenshot.GameViewToFileCoroutine(filePath, format, options, go, superSize));
|
||||
}
|
||||
|
||||
internal static IEnumerator GameViewToFileCoroutine(string filePath, ImageFormat format, Options options, GameObject go, int superSize = 1)
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
Texture2D texture = null;
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
if (format != ImageFormat.EXR)
|
||||
{
|
||||
texture = ScreenCapture.CaptureScreenshotAsTexture(superSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
// For EXR we want floating point textures which CaptureScreenshotAsTexture() doesn't provide
|
||||
RenderTextureFormat rtFormat = (options.exrPrecision == ExrPrecision.Float) ? RenderTextureFormat.ARGBFloat : RenderTextureFormat.ARGBHalf;
|
||||
RenderTexture rt = new RenderTexture(Screen.width * superSize, Screen.height * superSize, 24, rtFormat);
|
||||
rt.Create();
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
ScreenCapture.CaptureScreenshotIntoRenderTexture(rt);
|
||||
#endif
|
||||
texture = GetReadableTexture(rt, true);
|
||||
Destroy(rt);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (texture != null)
|
||||
{
|
||||
TextureToFile(texture, filePath, format, options);
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
Destroy(texture);
|
||||
Destroy(go);
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyImmediate(texture);
|
||||
DestroyImmediate(go);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static Camera[] FindAllCameras()
|
||||
{
|
||||
return Resources.FindObjectsOfTypeAll<Camera>();
|
||||
}
|
||||
|
||||
static Camera FindCameraByName(int cameraCount, Camera[] cameras, string name)
|
||||
{
|
||||
Camera result = null;
|
||||
for (int i = 0; i < cameraCount; i++)
|
||||
{
|
||||
Camera c = cameras[i];
|
||||
if (c.name == name)
|
||||
{
|
||||
result = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static string GetExtension(ImageFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case ImageFormat.PNG:
|
||||
return "png";
|
||||
case ImageFormat.JPG:
|
||||
return "jpg";
|
||||
case ImageFormat.TGA:
|
||||
return "tga";
|
||||
case ImageFormat.EXR:
|
||||
return "exr";
|
||||
}
|
||||
throw new Exception("Unknown image format");
|
||||
}
|
||||
|
||||
internal static Vector2 GetGameViewSize()
|
||||
{
|
||||
Vector2 result = Vector2.zero;
|
||||
string[] res = UnityStats.screenRes.Split('x');
|
||||
if (res.Length == 2)
|
||||
{
|
||||
result.x = int.Parse(res[0]);
|
||||
result.y = int.Parse(res[1]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static string GenerateFilename(string filenamePrefix, ImageFormat format, int width, int height)
|
||||
{
|
||||
string filenameExtension = GetExtension(format);
|
||||
string dateTime = DateTime.Now.ToString("yyyyMMdd-HHmmss");
|
||||
string filename = string.Format("{0}-{1}-{2}x{3}.{4}", filenamePrefix, dateTime, width, height, filenameExtension);
|
||||
return filename;
|
||||
}
|
||||
|
||||
internal static string GenerateFilePath(string folderPath, string fileName)
|
||||
{
|
||||
if (!System.IO.Directory.Exists(folderPath))
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(folderPath);
|
||||
}
|
||||
return System.IO.Path.Combine(folderPath, fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user