using System; using GCSeries.Core; using UnityEngine; namespace GCSeries.zView { public class GVirtualCameraStandard : GVirtualCamera { void Awake() { // Dynamically create a new Unity camera and disable it to allow for manual // rendering via Camera.Render(). _camera = this.gameObject.AddComponent(); if (_camera == null) { Debug.LogError("GVirtualCameraStandard.Awake():创建相机失败!"); } else { _camera.enabled = false; _camera.targetDisplay = 1; _camera.stereoTargetEye = StereoTargetEyeMask.None; } } ////////////////////////////////////////////////////////////////// // Virtual Camera Overrides ////////////////////////////////////////////////////////////////// public override void SetUp(GView zView, IntPtr connection, GView.ModeSetupPhase phase) { _zCameraRig = FindObjectOfType(); _camera.enabled = true; _camera.cullingMask = _camera.cullingMask & ~(zView.StandardModeIgnoreLayers); switch (phase) { case GView.ModeSetupPhase.Initialization: //this.UpdateImageResolution(zView, connection); _imageWidth = zView.imageWidth; _imageHeight = zView.imageHeight; RenderTextureDescriptor descriptor = new RenderTextureDescriptor(_imageWidth, _imageHeight, RenderTextureFormat.ARGB32); descriptor.dimension = UnityEngine.Rendering.TextureDimension.Tex2D; descriptor.depthBufferBits = 0; if (_renderTexture == null) _renderTexture = Resources.Load("gViewRT"); // Cache the render texture's native texture pointer. Per Unity documentation, // calling GetNativeTexturePtr() when using multi-threaded rendering will // synchronize with the rendering thread (which is a slow operation). So, only // call and cache once upon initialization. _nativeTexturePtr = _renderTexture.GetNativeTexturePtr(); // Cache the camera's culling mask to be restored after it renders the frame. int cullingMask = _camera.cullingMask; if (zView.ActiveZCamera == null) { Debug.LogWarning("ZView's public property ActiveZCamera" + "is null, but must be assigned."); return; } if (zView.ActiveZCamera.transform != this._zCameraTransform) { this._zCameraTransform = zView.ActiveZCamera.transform; this._zCameraCamera = this._zCameraTransform.GetComponent(); } // Copy the center eye camera's attributes to the standard mode primary camera. _camera.CopyFrom(this._zCameraCamera); _camera.enabled = false; _camera.stereoTargetEye = StereoTargetEyeMask.None; // Render the scene. _camera.cullingMask = cullingMask & ~(zView.StandardModeIgnoreLayers); _camera.targetTexture = _renderTexture; break; case GView.ModeSetupPhase.Completion: // Grab the image dimensions from the connection settings. // Create the render texture. break; default: break; } } public override void TearDown() { // Reset the camera's target texture. _camera.targetTexture = null; _camera.enabled = false; // Reset the render texture's native texture pointer. _nativeTexturePtr = IntPtr.Zero; // Clean up the existing render texture. // if (_renderTexture != null) // { // UnityEngine.Object.Destroy(_renderTexture); // _renderTexture = null; // } // Reset the image width and height. _imageWidth = 0; _imageHeight = 0; } public override void Render(GView zView, IntPtr connection, IntPtr receivedFrame) { _calculator.SetVector(_zCameraRig.Frame.transform.localToWorldMatrix.MultiplyPoint(new Vector3(-ZProvider.DisplaySize.x / 2f, ZProvider.DisplaySize.y / 2f, 0f)), _zCameraRig.Frame.transform.localToWorldMatrix.MultiplyPoint(new Vector3(-ZProvider.DisplaySize.x / 2f, -ZProvider.DisplaySize.y / 2f, 0f)), _zCameraRig.Frame.transform.localToWorldMatrix.MultiplyPoint(new Vector3(ZProvider.DisplaySize.x / 2f, -ZProvider.DisplaySize.y / 2f, 0f))); _camera.transform.position = _zCameraRig.transform.localToWorldMatrix.MultiplyPoint(Vector3.back * ZProvider.WindowSize.magnitude); _camera.transform.rotation = _zCameraRig.transform.rotation; _camera.projectionMatrix = _calculator.GeneralizedPerspectiveProjection(_camera.transform.position, _camera.nearClipPlane, _camera.farClipPlane); _camera.Render(); } public override IntPtr[] GetNativeTexturePtr(out int count) { count = 1; return new IntPtr[] { _nativeTexturePtr }; } public override RenderTexture[] GetRenderTexture(out int count) { count = 1; return new RenderTexture[] { _renderTexture }; } ////////////////////////////////////////////////////////////////// // Private Methods ////////////////////////////////////////////////////////////////// private void UpdateImageResolution(GView zView, IntPtr connection) { Debug.LogError("GVirtualCameraStandard.UpdateImageResolution():设置图像分辨率没实现"); } private Matrix4x4 FlipHandedness(Matrix4x4 matrix) { return s_flipHandednessMap * matrix * s_flipHandednessMap; } ////////////////////////////////////////////////////////////////// // Private Members ////////////////////////////////////////////////////////////////// private static readonly Matrix4x4 s_flipHandednessMap = Matrix4x4.Scale(new Vector4(1.0f, 1.0f, -1.0f)); private ZCameraRig _zCameraRig; private ProjectionMatrixCalc _calculator = new ProjectionMatrixCalc(); private Camera _zCameraCamera = null; private Transform _zCameraTransform = null; private Camera _camera = null; private static RenderTexture _renderTexture = null; private IntPtr _nativeTexturePtr = IntPtr.Zero; private UInt16 _imageWidth = 0; private UInt16 _imageHeight = 0; } }