using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.MemoryMappedFiles; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("Reso360Spout2.Renderer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+ee8c8eae18fcaddcd0802f601407b6587a92c31c")] [assembly: AssemblyProduct("Reso360Spout2.Renderer")] [assembly: AssemblyTitle("Reso360Spout2.Renderer")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace Reso360Spout2Renderer { public enum GammaConvertType { None, Linear_to_sRGB, Linear_to_BT709 } public class CubemapRenderer : IDisposable { private struct FaceInfo { public Quaternion Rotate; public CubemapFace Face; public Vector3 PositionShift; public FaceInfo(Quaternion r, CubemapFace f, Vector3 p) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) Rotate = r; Face = f; PositionShift = p; } } private Shader? _shader; private Material? _material; private Mesh? _mesh; private readonly int _cubemapSize; private RenderTexture? _cubemap; private RenderTexture? _tempRT; private CommandBuffer[]? _commandBuffers; private static readonly FaceInfo[] _faces = new FaceInfo[6] { new FaceInfo(Quaternion.Euler(0f, 90f, 0f), (CubemapFace)0, new Vector3(0f, 1f, 0f)), new FaceInfo(Quaternion.Euler(0f, -90f, 0f), (CubemapFace)1, new Vector3(0f, -1f, 0f)), new FaceInfo(Quaternion.Euler(-90f, 0f, 0f), (CubemapFace)2, Vector3.zero), new FaceInfo(Quaternion.Euler(90f, 0f, 0f), (CubemapFace)3, Vector3.zero), new FaceInfo(Quaternion.Euler(0f, 0f, 0f), (CubemapFace)4, new Vector3(1f, 0f, 0f)), new FaceInfo(Quaternion.Euler(0f, 180f, 0f), (CubemapFace)5, new Vector3(-1f, 0f, 0f)) }; private static readonly Vector3[] _meshVertices = (Vector3[])(object)new Vector3[4] { new Vector3(1f, 1f, 0f), new Vector3(-1f, 1f, 0f), new Vector3(-1f, -1f, 0f), new Vector3(1f, -1f, 0f) }; private static readonly int[] _meshIndices = new int[6] { 0, 1, 2, 2, 3, 0 }; public RenderTexture? Cubemap => _cubemap; public CubemapRenderer(int cubemapSize, Shader cubemapRendererShader) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown _cubemapSize = cubemapSize; _shader = cubemapRendererShader; _material = new Material(_shader); _mesh = new Mesh { vertices = _meshVertices, triangles = _meshIndices }; _cubemap = new RenderTexture(cubemapSize, cubemapSize, 0, (RenderTextureFormat)0); ((Texture)_cubemap).dimension = (TextureDimension)4; _cubemap.Create(); } public void Dispose() { DisposeCommandBuffers(); if ((Object)(object)_material != (Object)null) { Object.Destroy((Object)(object)_material); _material = null; } if ((Object)(object)_mesh != (Object)null) { Object.Destroy((Object)(object)_mesh); _mesh = null; } if ((Object)(object)_tempRT != (Object)null) { Object.Destroy((Object)(object)_tempRT); _tempRT = null; } if ((Object)(object)_cubemap != (Object)null) { Object.Destroy((Object)(object)_cubemap); _cubemap = null; } } private void DisposeCommandBuffers() { if (_commandBuffers != null) { CommandBuffer[] commandBuffers = _commandBuffers; for (int i = 0; i < commandBuffers.Length; i++) { commandBuffers[i].Dispose(); } _commandBuffers = null; } } private void RebuildCommandBuffers() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) DisposeCommandBuffers(); int num = Shader.PropertyToID("_MainTex"); _commandBuffers = (CommandBuffer[]?)(object)new CommandBuffer[_faces.Length]; for (int i = 0; i < _faces.Length; i++) { CommandBuffer val = new CommandBuffer(); val.SetGlobalTexture(num, RenderTargetIdentifier.op_Implicit((Texture)(object)_tempRT)); val.SetRenderTarget(RenderTargetIdentifier.op_Implicit((Texture)(object)_cubemap), 0, _faces[i].Face); val.DrawMesh(_mesh, Matrix4x4.identity, _material, 0, 0); _commandBuffers[i] = val; } } public void RenderCubemap(Camera camera, int faceMask, float ipdOffset, GammaConvertType gammaConvert, bool correctPosition) { //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_tempRT != (Object)null) { RenderTextureFormat val = (RenderTextureFormat)(camera.allowHDR ? 9 : 7); if (_tempRT.format != val) { Object.Destroy((Object)(object)_tempRT); _tempRT = null; } } if ((Object)(object)_tempRT == (Object)null) { _tempRT = new RenderTexture(_cubemapSize, _cubemapSize, 24, (RenderTextureFormat)(camera.allowHDR ? 9 : 7)); ((Texture)_tempRT).dimension = (TextureDimension)2; _tempRT.Create(); RebuildCommandBuffers(); } switch (gammaConvert) { case GammaConvertType.Linear_to_sRGB: SetKeyword("LINEAR_TO_SRGB", flag: true); SetKeyword("LINEAR_TO_BT709", flag: false); break; case GammaConvertType.Linear_to_BT709: SetKeyword("LINEAR_TO_SRGB", flag: false); SetKeyword("LINEAR_TO_BT709", flag: true); break; default: SetKeyword("LINEAR_TO_SRGB", flag: false); SetKeyword("LINEAR_TO_BT709", flag: false); break; } Quaternion localRotation = ((Component)camera).transform.localRotation; Vector3 localPosition = ((Component)camera).transform.localPosition; RenderTexture targetTexture = camera.targetTexture; bool orthographic = camera.orthographic; float aspect = camera.aspect; float fieldOfView = camera.fieldOfView; camera.orthographic = false; camera.aspect = 1f; camera.fieldOfView = 90f; camera.targetTexture = _tempRT; try { for (int i = 0; i < _commandBuffers.Length; i++) { if ((faceMask & (1 << (int)_faces[i].Face)) != 0) { camera.AddCommandBuffer((CameraEvent)20, _commandBuffers[i]); try { ((Component)camera).transform.localRotation = localRotation * _faces[i].Rotate; ((Component)camera).transform.localPosition = localPosition + (correctPosition ? (_faces[i].PositionShift * ipdOffset) : (Vector3.right * ipdOffset)); camera.Render(); } finally { camera.RemoveCommandBuffer((CameraEvent)20, _commandBuffers[i]); } } } } finally { ((Component)camera).transform.localRotation = localRotation; ((Component)camera).transform.localPosition = localPosition; camera.targetTexture = targetTexture; camera.orthographic = orthographic; camera.aspect = aspect; camera.fieldOfView = fieldOfView; } } private void SetKeyword(string keyword, bool flag) { if (!((Object)(object)_material == (Object)null)) { if (flag) { _material.EnableKeyword(keyword); } else { _material.DisableKeyword(keyword); } } } } public enum ProjectionType { Equirectangular_360, Equirectangular_180, FishEye_Circumference, FishEye_Diagonal } public enum FishEyeType { Equidistance, EquisolidAngle, Orthogonal } [RequireComponent(typeof(Camera))] public class CubemapToOtherProjection : MonoBehaviour { public RenderTexture? RenderTarget; public int CubemapSize = 1024; public ProjectionType ProjectionType; public FishEyeType FishEyeType; public bool UseUnityInternalCubemapRenderer; public GammaConvertType GammaConvertType; public bool RenderInStereo; public float StereoSeparation = 0.065f; public bool CorrectCameraPositionInStereoRendering; public Shader? CubemapShader; public Shader? CubemapRendererShader; private Camera _camera; private Material? _material; private RenderTexture? _cubemap; private CubemapRenderer? _cubemapRenderer; private void Start() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown _camera = ((Component)this).GetComponent(); _material = new Material(CubemapShader); _cubemap = new RenderTexture(CubemapSize, CubemapSize, 24, (RenderTextureFormat)0); ((Texture)_cubemap).dimension = (TextureDimension)4; if (!UseUnityInternalCubemapRenderer) { _cubemapRenderer = new CubemapRenderer(CubemapSize, CubemapRendererShader); } } public void Rendering() { //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)RenderTarget == (Object)null) { return; } switch (ProjectionType) { case ProjectionType.Equirectangular_360: SetUV((float)Math.PI * 2f, (float)Math.PI, 0f, 0f); SetKeyword("PROJ_FISHEYE", flag: false); SetKeyword("ANGLEFUNC_EQUISOLIDANGLE", flag: false); SetKeyword("ANGLEFUNC_ORTHGONAL", flag: false); break; case ProjectionType.Equirectangular_180: SetUV((float)Math.PI, (float)Math.PI, (float)Math.PI / 2f, 0f); SetKeyword("PROJ_FISHEYE", flag: false); SetKeyword("ANGLEFUNC_EQUISOLIDANGLE", flag: false); SetKeyword("ANGLEFUNC_ORTHGONAL", flag: false); break; case ProjectionType.FishEye_Circumference: SetUV(2f, 2f, -1f, -1f); SetKeyword("PROJ_FISHEYE", flag: true); SetFishEyeScale(1f); break; case ProjectionType.FishEye_Diagonal: SetUV(2f, 2f, -1f, -1f); SetKeyword("PROJ_FISHEYE", flag: true); SetFishEyeScale(1f / Mathf.Sqrt(2f)); break; } switch (FishEyeType) { case FishEyeType.Equidistance: SetKeyword("ANGLEFUNC_EQUISOLIDANGLE", flag: false); SetKeyword("ANGLEFUNC_ORTHGONAL", flag: false); break; case FishEyeType.EquisolidAngle: SetKeyword("ANGLEFUNC_EQUISOLIDANGLE", flag: true); SetKeyword("ANGLEFUNC_ORTHGONAL", flag: false); break; case FishEyeType.Orthogonal: SetKeyword("ANGLEFUNC_EQUISOLIDANGLE", flag: false); SetKeyword("ANGLEFUNC_ORTHGONAL", flag: true); break; } if (RenderInStereo) { float stereoSeparation = _camera.stereoSeparation; StereoTargetEyeMask stereoTargetEye = _camera.stereoTargetEye; _camera.stereoSeparation = StereoSeparation; _camera.stereoTargetEye = (StereoTargetEyeMask)0; if (ProjectionType == ProjectionType.Equirectangular_360) { Render((MonoOrStereoscopicEye)0, 1f, 0.5f, 0f, -0.5f); Render((MonoOrStereoscopicEye)1, 1f, 0.5f, 0f, 0.5f); } else { Render((MonoOrStereoscopicEye)0, 0.5f, 1f, -0.5f, 0f); Render((MonoOrStereoscopicEye)1, 0.5f, 1f, 0.5f, 0f); } _camera.stereoSeparation = stereoSeparation; _camera.stereoTargetEye = stereoTargetEye; } else { Render((MonoOrStereoscopicEye)2, 1f, 1f, 0f, 0f); } } private void OnDestroy() { if ((Object)(object)_material != (Object)null) { Object.Destroy((Object)(object)_material); _material = null; } if ((Object)(object)_cubemap != (Object)null) { Object.Destroy((Object)(object)_cubemap); _cubemap = null; } _cubemapRenderer?.Dispose(); _cubemapRenderer = null; } private void Render(MonoOrStereoscopicEye eye, float sx, float sy, float ox, float oy) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Invalid comparison between Unknown and I4 //IL_00ce: Unknown result type (might be due to invalid IL or missing references) if (UseUnityInternalCubemapRenderer) { ApplyGamma(); _camera.RenderToCubemap(_cubemap, 63, eye); SetPositionScale(sx, sy, ox, oy); _material.SetMatrix("_Matrix", Matrix4x4.Rotate(Quaternion.identity)); Graphics.Blit((Texture)(object)_cubemap, RenderTarget, _material); } else { float ipdOffset = (((int)eye == 0) ? ((0f - StereoSeparation) / 2f) : (((int)eye == 1) ? (StereoSeparation / 2f) : 0f)); _cubemapRenderer.RenderCubemap(_camera, (ProjectionType == ProjectionType.Equirectangular_360) ? 63 : 31, ipdOffset, GammaConvertType, CorrectCameraPositionInStereoRendering); SetPositionScale(sx, sy, ox, oy); _material.SetMatrix("_Matrix", Matrix4x4.identity); SetKeyword("LINEAR_TO_SRGB", flag: false); SetKeyword("LINEAR_TO_BT709", flag: false); Graphics.Blit((Texture)(object)_cubemapRenderer.Cubemap, RenderTarget, _material); } } private void ApplyGamma() { switch (GammaConvertType) { case GammaConvertType.Linear_to_sRGB: SetKeyword("LINEAR_TO_SRGB", flag: true); SetKeyword("LINEAR_TO_BT709", flag: false); break; case GammaConvertType.Linear_to_BT709: SetKeyword("LINEAR_TO_SRGB", flag: false); SetKeyword("LINEAR_TO_BT709", flag: true); break; default: SetKeyword("LINEAR_TO_SRGB", flag: false); SetKeyword("LINEAR_TO_BT709", flag: false); break; } } private void SetUV(float sx, float sy, float ox, float oy) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) Material? material = _material; if (material != null) { material.SetVector("_UVScaleOffset", new Vector4(sx, sy, ox, oy)); } } private void SetPositionScale(float sx, float sy, float ox, float oy) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) Material? material = _material; if (material != null) { material.SetVector("_PositionScaleOffset", new Vector4(sx, sy, ox, oy)); } } private void SetFishEyeScale(float s) { Material? material = _material; if (material != null) { material.SetFloat("_FishEyeDiameterScale", s); } } private void SetKeyword(string keyword, bool flag) { if (!((Object)(object)_material == (Object)null)) { if (flag) { _material.EnableKeyword(keyword); } else { _material.DisableKeyword(keyword); } } } } internal static class PluginEntry { internal enum Event { Update, Dispose } internal static bool IsAvailable => (int)SystemInfo.graphicsDeviceType == 2; [DllImport("KlakSpout_send", EntryPoint = "GetRenderEventFunc")] internal static extern IntPtr Sender_GetRenderEventFunc(); [DllImport("KlakSpout_send")] internal static extern IntPtr CreateSender(string name, int width, int height); [DllImport("KlakSpout_send")] internal static extern IntPtr GetTexturePointer(IntPtr ptr); [DllImport("KlakSpout_send")] internal static extern int GetTextureWidth(IntPtr ptr); [DllImport("KlakSpout_send")] internal static extern int GetTextureHeight(IntPtr ptr); [DllImport("KlakSpout")] internal static extern IntPtr CreateReceiver(string name); [DllImport("KlakSpout")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool CheckValid(IntPtr ptr); [DllImport("KlakSpout")] internal static extern int ScanSharedObjects(); [DllImport("KlakSpout")] internal static extern IntPtr GetSharedObjectName(int index); internal static string? GetSharedObjectNameString(int index) { IntPtr sharedObjectName = GetSharedObjectName(index); if (!(sharedObjectName != IntPtr.Zero)) { return null; } return Marshal.PtrToStringAnsi(sharedObjectName); } } [BepInPlugin("dev.kokoa.Reso360Spout2.Renderer", "Reso360Spout2 Renderer", "1.0.0")] public class RendererPlugin : BaseUnityPlugin { public enum CubeMapSize { Low = 512, Mid = 1024, High = 2048, Ultra = 3072 } public static ConfigEntry SPOUT_ENABLE; public static ConfigEntry PROJECTION_TYPE; public static ConfigEntry CUBEMAP_SIZE; public static ConfigEntry OUTPUT_WIDTH; public static ConfigEntry OUTPUT_HEIGHT; public static ConfigEntry RENDER_IN_STEREO; public static ConfigEntry NEAR_CLIP; public static ConfigEntry FAR_CLIP; public static ConfigEntry HIDE_LOCAL; public static ConfigEntry STEREO_SEPARATION; private string _pluginDir = ""; private UnityEntry? _unityEntry; private GameObject? _entryGo; public static RendererPlugin? Instance { get; private set; } private void Awake() { //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown Instance = this; _pluginDir = Path.GetDirectoryName(((object)this).GetType().Assembly.Location) ?? ""; SPOUT_ENABLE = ((BaseUnityPlugin)this).Config.Bind("General", "SPOUT_ENABLE", true, "Spout 出力を有効にする"); PROJECTION_TYPE = ((BaseUnityPlugin)this).Config.Bind("General", "PROJECTION_TYPE", ProjectionType.Equirectangular_180, "投影方式"); CUBEMAP_SIZE = ((BaseUnityPlugin)this).Config.Bind("General", "CUBEMAP_SIZE", CubeMapSize.High, "キューブマップサイズ"); OUTPUT_WIDTH = ((BaseUnityPlugin)this).Config.Bind("General", "OUTPUT_WIDTH", 6144, "出力幅 (px)"); OUTPUT_HEIGHT = ((BaseUnityPlugin)this).Config.Bind("General", "OUTPUT_HEIGHT", 3072, "出力高 (px)"); RENDER_IN_STEREO = ((BaseUnityPlugin)this).Config.Bind("General", "RENDER_IN_STEREO", true, "ステレオレンダリング"); NEAR_CLIP = ((BaseUnityPlugin)this).Config.Bind("General", "NEAR_CLIP", 0.01f, "ニアクリップ"); FAR_CLIP = ((BaseUnityPlugin)this).Config.Bind("General", "FAR_CLIP", 3000f, "ファークリップ"); HIDE_LOCAL = ((BaseUnityPlugin)this).Config.Bind("General", "HIDE_LOCAL", true, "ローカルユーザーを非表示"); STEREO_SEPARATION = ((BaseUnityPlugin)this).Config.Bind("General", "STEREO_SEPARATION", 0.065f, "ステレオ間距離 (IPD, m)"); _entryGo = new GameObject("___Reso360Spout2"); Object.DontDestroyOnLoad((Object)(object)_entryGo); _unityEntry = _entryGo.AddComponent(); _unityEntry.PluginDir = _pluginDir; HIDE_LOCAL.SettingChanged += delegate { _unityEntry?.ApplyHideLocal(); }; NEAR_CLIP.SettingChanged += delegate { if ((Object)(object)_unityEntry?.CameraComponent != (Object)null) { _unityEntry.CameraComponent.nearClipPlane = NEAR_CLIP.Value; } }; FAR_CLIP.SettingChanged += delegate { if ((Object)(object)_unityEntry?.CameraComponent != (Object)null) { _unityEntry.CameraComponent.farClipPlane = FAR_CLIP.Value; } }; CUBEMAP_SIZE.SettingChanged += delegate { if ((Object)(object)_unityEntry?.cubeComponent != (Object)null) { _unityEntry.cubeComponent.CubemapSize = (int)CUBEMAP_SIZE.Value; } }; PROJECTION_TYPE.SettingChanged += delegate { if ((Object)(object)_unityEntry?.cubeComponent != (Object)null) { _unityEntry.cubeComponent.ProjectionType = PROJECTION_TYPE.Value; } }; RENDER_IN_STEREO.SettingChanged += delegate { if ((Object)(object)_unityEntry?.cubeComponent != (Object)null) { _unityEntry.cubeComponent.RenderInStereo = RENDER_IN_STEREO.Value; } }; STEREO_SEPARATION.SettingChanged += delegate { if ((Object)(object)_unityEntry?.cubeComponent != (Object)null) { _unityEntry.cubeComponent.StereoSeparation = STEREO_SEPARATION.Value; } }; SPOUT_ENABLE.SettingChanged += delegate { _unityEntry?.UpdateSpoutState(); }; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Reso360Spout2 Renderer plugin loaded."); } } public class UnityEntry : MonoBehaviour { [CompilerGenerated] private sealed class d__15 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public UnityEntry <>4__this; object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown int num = <>1__state; UnityEntry unityEntry = <>4__this; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; if ((Object)(object)unityEntry.SourceTexture != (Object)null && unityEntry.Plugin != IntPtr.Zero) { unityEntry.cubeComponent.Rendering(); unityEntry.SendToSpout(); } } else { <>1__state = -1; } <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public Camera? CameraComponent; public CubemapToOtherProjection? cubeComponent; public IntPtr Plugin = IntPtr.Zero; public RenderTexture? SourceTexture; public Texture2D? SharedTexture; public string PluginDir = ""; private SharedMemoryReader _sharedMem = new SharedMemoryReader(); private GameObject? _cameraRoot; private int _initDelayFrames = 1000; private int _lastConfigVersion = -1; private void Start() { if (!_sharedMem.TryOpen()) { Debug.LogWarning((object)"[Reso360Spout2] Shared memory not yet available; will retry."); } CreateCamera(); LoadShaders(); ApplyInitialConfig(); ((MonoBehaviour)this).StartCoroutine(PostRenderLoop()); } private void LateUpdate() { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) try { if (!_sharedMem.IsOpen) { _sharedMem.TryOpen(); } if (_initDelayFrames > 0) { _initDelayFrames--; if (_initDelayFrames == 0 && RendererPlugin.SPOUT_ENABLE.Value) { Debug.Log((object)"[Reso360Spout2] Initializing Spout sender (deferred)..."); InitSpout(); } return; } if (_sharedMem.IsOpen) { int num = _sharedMem.ReadConfigVersion(); if (num != _lastConfigVersion && num != 0) { _lastConfigVersion = num; ApplyConfigFromHost(_sharedMem.ReadConfig()); } } ((Component)this).transform.position = _sharedMem.ReadPosition(); ((Component)this).transform.rotation = _sharedMem.ReadRotation(); ((Component)this).transform.localScale = _sharedMem.ReadScale(); } catch (Exception ex) { Debug.LogError((object)("[Reso360Spout2] " + ex)); } } private void OnDestroy() { _sharedMem.Dispose(); } private void ApplyInitialConfig() { RendererConfig rendererConfig = RendererConfig.Default; if (_sharedMem.IsOpen) { int num = _sharedMem.ReadConfigVersion(); if (num != 0) { _lastConfigVersion = num; rendererConfig = _sharedMem.ReadConfig(); Debug.Log((object)$"[Reso360Spout2] Initial config from host (version={num}): Projection={rendererConfig.ProjectionType}, CubemapSize={rendererConfig.CubemapSize}"); } } RendererPlugin.SPOUT_ENABLE.Value = rendererConfig.SpoutEnable; RendererPlugin.PROJECTION_TYPE.Value = rendererConfig.ProjectionType; RendererPlugin.CUBEMAP_SIZE.Value = (RendererPlugin.CubeMapSize)rendererConfig.CubemapSize; RendererPlugin.OUTPUT_WIDTH.Value = rendererConfig.OutputWidth; RendererPlugin.OUTPUT_HEIGHT.Value = rendererConfig.OutputHeight; RendererPlugin.RENDER_IN_STEREO.Value = rendererConfig.RenderInStereo; RendererPlugin.NEAR_CLIP.Value = rendererConfig.NearClip; RendererPlugin.FAR_CLIP.Value = rendererConfig.FarClip; RendererPlugin.HIDE_LOCAL.Value = rendererConfig.HideLocal; RendererPlugin.STEREO_SEPARATION.Value = rendererConfig.StereoSeparation; cubeComponent.CubemapSize = rendererConfig.CubemapSize; cubeComponent.ProjectionType = rendererConfig.ProjectionType; cubeComponent.RenderInStereo = rendererConfig.RenderInStereo; cubeComponent.StereoSeparation = rendererConfig.StereoSeparation; CameraComponent.nearClipPlane = rendererConfig.NearClip; CameraComponent.farClipPlane = rendererConfig.FarClip; ApplyHideLocal(rendererConfig.HideLocal); } private void ApplyConfigFromHost(RendererConfig cfg) { Debug.Log((object)$"[Reso360Spout2] Config updated from host: SpoutEnable={cfg.SpoutEnable}, Projection={cfg.ProjectionType}, CubemapSize={cfg.CubemapSize}, {cfg.OutputWidth}x{cfg.OutputHeight}"); RendererPlugin.SPOUT_ENABLE.Value = cfg.SpoutEnable; RendererPlugin.PROJECTION_TYPE.Value = cfg.ProjectionType; RendererPlugin.CUBEMAP_SIZE.Value = (RendererPlugin.CubeMapSize)cfg.CubemapSize; RendererPlugin.OUTPUT_WIDTH.Value = cfg.OutputWidth; RendererPlugin.OUTPUT_HEIGHT.Value = cfg.OutputHeight; RendererPlugin.RENDER_IN_STEREO.Value = cfg.RenderInStereo; RendererPlugin.NEAR_CLIP.Value = cfg.NearClip; RendererPlugin.FAR_CLIP.Value = cfg.FarClip; RendererPlugin.HIDE_LOCAL.Value = cfg.HideLocal; RendererPlugin.STEREO_SEPARATION.Value = cfg.StereoSeparation; } [IteratorStateMachine(typeof(d__15))] private IEnumerator PostRenderLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__15(0) { <>4__this = this }; } private void LoadShaders() { string text = Path.Combine(PluginDir, "cubeto360"); AssetBundle val = AssetBundle.LoadFromFile(text); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("[Reso360Spout2] AssetBundle not found: " + text)); return; } Shader cubemapShader = null; Shader cubemapRendererShader = null; Shader[] array = val.LoadAllAssets(); foreach (Shader val2 in array) { if (((Object)val2).name == "Unlit/CubemapToOtherProjection") { cubemapShader = val2; } else if (((Object)val2).name == "Unlit/CubemapRenderer") { cubemapRendererShader = val2; } } if ((Object)(object)cubeComponent != (Object)null) { cubeComponent.CubemapShader = cubemapShader; cubeComponent.CubemapRendererShader = cubemapRendererShader; } Debug.Log((object)"[Reso360Spout2] Shaders loaded."); } private void CreateCamera() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown _cameraRoot = new GameObject("CameraRoot"); _cameraRoot.transform.SetParent(((Component)this).transform, false); CameraComponent = _cameraRoot.AddComponent(); CameraComponent.depth = -128f; CameraComponent.fieldOfView = 90f; CameraComponent.stereoTargetEye = (StereoTargetEyeMask)0; CameraComponent.stereoSeparation = 0.065f; cubeComponent = _cameraRoot.AddComponent(); Debug.Log((object)"[Reso360Spout2] Camera created."); } private void InitSpout() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown int value = RendererPlugin.OUTPUT_WIDTH.Value; int value2 = RendererPlugin.OUTPUT_HEIGHT.Value; Plugin = PluginEntry.CreateSender("VRCam", value, value2); SourceTexture = new RenderTexture(value, value2, 24); cubeComponent.RenderTarget = SourceTexture; } private void SendToSpout() { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) if (Plugin == IntPtr.Zero) { Debug.LogWarning((object)"[Reso360Spout2] Spout sender not initialized; cannot send frame."); return; } SpoutUtil.IssueSenderPluginEvent(PluginEntry.Event.Update, Plugin); if ((Object)(object)SharedTexture == (Object)null) { IntPtr texturePointer = PluginEntry.GetTexturePointer(Plugin); if (texturePointer != IntPtr.Zero) { SharedTexture = Texture2D.CreateExternalTexture(PluginEntry.GetTextureWidth(Plugin), PluginEntry.GetTextureHeight(Plugin), (TextureFormat)5, false, false, texturePointer); ((Object)SharedTexture).hideFlags = (HideFlags)52; } } if ((Object)(object)SharedTexture == (Object)null) { Debug.LogWarning((object)"[Reso360Spout2] Failed to get shared texture pointer from Spout plugin."); return; } RenderTexture temporary = RenderTexture.GetTemporary(((Texture)SharedTexture).width, ((Texture)SharedTexture).height, 0, (RenderTextureFormat)0); Graphics.Blit((Texture)(object)SourceTexture, temporary, new Vector2(1f, -1f), new Vector2(0f, 1f)); Graphics.CopyTexture((Texture)(object)temporary, (Texture)(object)SharedTexture); RenderTexture.ReleaseTemporary(temporary); } public void ApplyHideLocal() { ApplyHideLocal(RendererPlugin.HIDE_LOCAL.Value); } public void ApplyHideLocal(bool hideLocal) { if (!((Object)(object)CameraComponent == (Object)null)) { if (hideLocal) { Camera? cameraComponent = CameraComponent; cameraComponent.cullingMask &= 0x1FFFFFFF; Camera? cameraComponent2 = CameraComponent; cameraComponent2.cullingMask &= -268435457; } else { Camera? cameraComponent3 = CameraComponent; cameraComponent3.cullingMask |= -536870912; Camera? cameraComponent4 = CameraComponent; cameraComponent4.cullingMask &= -268435457; } } } public void UpdateSpoutState() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown if (RendererPlugin.SPOUT_ENABLE.Value) { int value = RendererPlugin.OUTPUT_WIDTH.Value; int value2 = RendererPlugin.OUTPUT_HEIGHT.Value; Plugin = PluginEntry.CreateSender("VRCam", value, value2); SourceTexture = new RenderTexture(value, value2, 24); cubeComponent.RenderTarget = SourceTexture; return; } if (Plugin != IntPtr.Zero) { SpoutUtil.IssueSenderPluginEvent(PluginEntry.Event.Dispose, Plugin); } Plugin = IntPtr.Zero; SourceTexture = null; if ((Object)(object)cubeComponent != (Object)null) { cubeComponent.RenderTarget = null; } } } public class SharedMemoryReader : IDisposable { public const string MAP_NAME = "Reso360Spout2_Camera"; private const int MAP_SIZE = 84; private MemoryMappedFile? _mmf; private MemoryMappedViewAccessor? _view; private bool _disposed; public bool IsOpen => _view != null; public bool TryOpen() { if (IsOpen) { return true; } try { _mmf = MemoryMappedFile.CreateOrOpen("Reso360Spout2_Camera", 84L); _view = _mmf.CreateViewAccessor(0L, 84L, MemoryMappedFileAccess.ReadWrite); return true; } catch { return false; } } public Vector3 ReadPosition() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (_view == null) { return Vector3.zero; } return new Vector3(_view.ReadSingle(0L), _view.ReadSingle(4L), _view.ReadSingle(8L)); } public Quaternion ReadRotation() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) if (_view == null) { return Quaternion.identity; } Quaternion val = default(Quaternion); ((Quaternion)(ref val))..ctor(_view.ReadSingle(12L), _view.ReadSingle(16L), _view.ReadSingle(20L), _view.ReadSingle(24L)); if (val.x != 0f || val.y != 0f || val.z != 0f || val.w != 0f) { return val; } return Quaternion.identity; } public Vector3 ReadScale() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (_view == null) { return Vector3.one; } Vector3 result = default(Vector3); ((Vector3)(ref result))..ctor(_view.ReadSingle(28L), _view.ReadSingle(32L), _view.ReadSingle(36L)); if (!(((Vector3)(ref result)).sqrMagnitude < 1E-06f)) { return result; } return Vector3.one; } public int ReadConfigVersion() { return _view?.ReadInt32(40L) ?? 0; } public RendererConfig ReadConfig() { if (_view == null) { return RendererConfig.Default; } RendererConfig result = default(RendererConfig); result.SpoutEnable = _view.ReadInt32(44L) != 0; result.ProjectionType = (ProjectionType)_view.ReadInt32(48L); result.CubemapSize = _view.ReadInt32(52L); result.OutputWidth = _view.ReadInt32(56L); result.OutputHeight = _view.ReadInt32(60L); result.RenderInStereo = _view.ReadInt32(64L) != 0; result.NearClip = _view.ReadSingle(68L); result.FarClip = _view.ReadSingle(72L); result.HideLocal = _view.ReadInt32(76L) != 0; result.StereoSeparation = _view.ReadSingle(80L); return result; } public void Dispose() { if (!_disposed) { _disposed = true; _view?.Dispose(); _mmf?.Dispose(); } } } public struct RendererConfig { public bool SpoutEnable; public ProjectionType ProjectionType; public int CubemapSize; public int OutputWidth; public int OutputHeight; public bool RenderInStereo; public float NearClip; public float FarClip; public bool HideLocal; public float StereoSeparation; public static readonly RendererConfig Default = new RendererConfig { SpoutEnable = true, ProjectionType = ProjectionType.Equirectangular_180, CubemapSize = 2048, OutputWidth = 6144, OutputHeight = 3072, RenderInStereo = true, NearClip = 0.01f, FarClip = 3000f, HideLocal = true, StereoSeparation = 0.065f }; } internal static class SpoutUtil { private static CommandBuffer? _commandBuffer; internal static void IssueSenderPluginEvent(PluginEntry.Event pluginEvent, IntPtr ptr) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown if (_commandBuffer == null) { _commandBuffer = new CommandBuffer(); } _commandBuffer.IssuePluginEventAndData(PluginEntry.Sender_GetRenderEventFunc(), (int)pluginEvent, ptr); Graphics.ExecuteCommandBuffer(_commandBuffer); _commandBuffer.Clear(); } } }