| using System; |
| using UnityEngine; |
| using UnityEngine.Rendering; |
|
|
| namespace Unity.MLAgents.Sensors |
| { |
| |
| |
| |
| public class CameraSensor : ISensor, IBuiltInSensor, IDisposable |
| { |
| Camera m_Camera; |
| int m_Width; |
| int m_Height; |
| bool m_Grayscale; |
| string m_Name; |
| private ObservationSpec m_ObservationSpec; |
| SensorCompressionType m_CompressionType; |
| Texture2D m_Texture; |
|
|
| |
| |
| |
| public Camera Camera |
| { |
| get { return m_Camera; } |
| set { m_Camera = value; } |
| } |
|
|
| |
| |
| |
| public SensorCompressionType CompressionType |
| { |
| get { return m_CompressionType; } |
| set { m_CompressionType = value; } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public CameraSensor( |
| Camera camera, int width, int height, bool grayscale, string name, SensorCompressionType compression, ObservationType observationType = ObservationType.Default) |
| { |
| m_Camera = camera; |
| m_Width = width; |
| m_Height = height; |
| m_Grayscale = grayscale; |
| m_Name = name; |
| var channels = grayscale ? 1 : 3; |
| m_ObservationSpec = ObservationSpec.Visual(channels, height, width, observationType); |
| m_CompressionType = compression; |
| m_Texture = new Texture2D(width, height, TextureFormat.RGB24, false); |
| } |
|
|
| |
| |
| |
| |
| public string GetName() |
| { |
| return m_Name; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public ObservationSpec GetObservationSpec() |
| { |
| return m_ObservationSpec; |
| } |
|
|
| |
| |
| |
| |
| public byte[] GetCompressedObservation() |
| { |
| using (TimerStack.Instance.Scoped("CameraSensor.GetCompressedObservation")) |
| { |
| |
| var compressed = m_Texture.EncodeToPNG(); |
| return compressed; |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| public int Write(ObservationWriter writer) |
| { |
| using (TimerStack.Instance.Scoped("CameraSensor.WriteToTensor")) |
| { |
| var numWritten = writer.WriteTexture(m_Texture, m_Grayscale); |
| return numWritten; |
| } |
| } |
|
|
| |
| public void Update() |
| { |
| ObservationToTexture(m_Camera, m_Texture, m_Width, m_Height); |
| } |
|
|
| |
| public void Reset() { } |
|
|
| |
| public CompressionSpec GetCompressionSpec() |
| { |
| return new CompressionSpec(m_CompressionType); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public static void ObservationToTexture(Camera obsCamera, Texture2D texture2D, int width, int height) |
| { |
| if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Null) |
| { |
| Debug.LogError("GraphicsDeviceType is Null. This will likely crash when trying to render."); |
| } |
|
|
| var oldRec = obsCamera.rect; |
| obsCamera.rect = new Rect(0f, 0f, 1f, 1f); |
| var depth = 24; |
| var format = RenderTextureFormat.Default; |
| var readWrite = RenderTextureReadWrite.Default; |
|
|
| var tempRt = |
| RenderTexture.GetTemporary(width, height, depth, format, readWrite); |
|
|
| var prevActiveRt = RenderTexture.active; |
| var prevCameraRt = obsCamera.targetTexture; |
|
|
| |
| RenderTexture.active = tempRt; |
| obsCamera.targetTexture = tempRt; |
|
|
| obsCamera.Render(); |
|
|
| texture2D.ReadPixels(new Rect(0, 0, texture2D.width, texture2D.height), 0, 0); |
|
|
| obsCamera.targetTexture = prevCameraRt; |
| obsCamera.rect = oldRec; |
| RenderTexture.active = prevActiveRt; |
| RenderTexture.ReleaseTemporary(tempRt); |
| } |
|
|
| |
| public BuiltInSensorType GetBuiltInSensorType() |
| { |
| return BuiltInSensorType.CameraSensor; |
| } |
|
|
| |
| |
| |
| public void Dispose() |
| { |
| if (!ReferenceEquals(null, m_Texture)) |
| { |
| Utilities.DestroyTexture(m_Texture); |
| m_Texture = null; |
| } |
| } |
| } |
| } |
|
|