////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2007-2020 , Inc. All Rights Reserved. // ////////////////////////////////////////////////////////////////////////// using System; using System.Collections; using System.Collections.Generic; using System.Text; using UnityEngine; using GCSeries.Core; namespace GCSeries.zView { public partial class ZView : MonoBehaviour { ////////////////////////////////////////////////////////////////// // Events ////////////////////////////////////////////////////////////////// public delegate void EventHandler(ZView sender, IntPtr connection); /// /// Event dispatched when a connection has been accepted. /// public event EventHandler ConnectionAccepted; /// /// Event dispatched when a connection has switched modes. /// public event EventHandler ConnectionModeSwitched; /// /// Event dispatched when a connection has transitioned /// to the ModeActive connection state. /// public event EventHandler ConnectionModeActive; /// /// Event dispatched when a connection has transitioned /// to the ModePaused connection state. /// public event EventHandler ConnectionModePaused; /// /// Event dispatched when a connection has been closed. /// public event EventHandler ConnectionClosed; /// /// Event dispatched when a connection error has occurred. /// public event EventHandler ConnectionError; /// /// Event dispatched when video recording has transitioned to /// an inactive state. /// public event EventHandler VideoRecordingInactive; /// /// Event dispatched when video recording has transitioned to /// an active recording state. /// public event EventHandler VideoRecordingActive; /// /// Event dispatched when video recording has finished. /// public event EventHandler VideoRecordingFinished; /// /// Event dispatched when video recording has paused. /// public event EventHandler VideoRecordingPaused; /// /// Event dispatched when a video recording error has occurred. /// public event EventHandler VideoRecordingError; /// /// Event dispatched when the video recording quality has changed. /// public event EventHandler VideoRecordingQualityChanged; ////////////////////////////////////////////////////////////////// // Enumerations ////////////////////////////////////////////////////////////////// /// /// Defines the types of zView nodes that can exist. /// public enum NodeType { Presenter = 0, Viewer = 1, } /// /// Defines the availability states for zView modes. /// public enum ModeAvailability { /// /// Mode is available. /// Available = 0, /// /// Mode is not available. /// NotAvailable = 1, /// /// Mode is not available because no webcam hardware is available. /// NotAvailableNoWebcam = 2, /// /// Mode is not available because necessary calibration has not been /// performed. /// NotAvailableNotCalibrated = 3, } /// /// Defines the optional capabilities that may be implemented by a zView /// node. /// public enum Capability { /// /// The node supports video recording via the video recording APIs. /// /// /// /// A zView connection will support this capability as long as the viewer /// node in the connection supports this capability. The presenter node /// need not support this capability. /// VideoRecording = 0, /// /// The node supports responding to requests to exit the application /// hosting the node when a zView connection is closed. /// /// /// /// For a zView node to support this capability, the application hosting /// the node must call GetConnectionCloseAction() whenever a zView /// connection enters the ConnectionState.Closed state and then exit /// if the close action is ConnectionCloseAction.ExitApplication. /// RemoteApplicationExit = 1, } /// /// Defines the keys for all mode and mode spec attributes. /// public enum ModeAttributeKey { /// /// The version of the mode. /// Datatype: UInt32. /// /// /// /// Different versions of a mode may function differently and may have /// different settings and frame data/buffers. /// Version = 0, /// /// The mode's compositing mode. /// Datatype: CompositingMode (get/set as UInt32). /// /// /// /// This indicates how the viewer node should composite the images it /// receives from the presenter node. /// CompositingMode = 1, /// /// The mode's presenter camera mode. /// Datatype: CameraMode (get/set as UInt32). /// /// /// /// This indicates how the presenter node's camera should function when the /// mode is active. /// PresenterCameraMode = 2, /// /// The order of rows of pixels in images generated for the mode. /// Datatype: ImageRowOrder (get/set as UInt32). /// /// /// /// Any images generated by either the presenter or viewer node for the /// mode should have their rows of pixels in this order. /// ImageRowOrder = 3, /// /// The format of pixels in color images generated for the mode. /// Datatype: PixelFormat (get/set as UInt32). /// /// /// /// Any color images generated by either the presenter or viewer node for /// the mode should use this pixel format. The pixel format specifies the /// number, type, order, and size of the channels in a pixel. /// ColorImagePixelFormat = 4, } /// /// Defines the possible zView mode compositing modes. /// /// /// /// This specifies the valid values that can be used to set the /// ModeAttributeKey.CompositingMode mode/mode spec attribute. /// public enum CompositingMode { /// /// No compositing will be performed. /// None = 0, /// /// Images will be composited on top of images from an augmented /// reality camera video stream. /// AugmentedRealityCamera = 1, } /// /// Defines the possible zView mode camera modes. /// /// /// /// This currently specifies the valid values that can be used to set the /// ModeAttributeKey.PresenterCameraMode mode/mode spec attribute. /// public enum CameraMode { /// /// The camera should have a fixed pose that never changes. /// Fixed = 0, /// /// The camera's pose should change according to head tracking /// information obtained on the local zView node. /// LocalHeadTracked = 1, /// /// The camera's pose should change according to information sent /// from the remote zView node. /// RemoteMovable = 2, } /// /// Defines the possible image pixel formats. /// /// /// /// This currently specifies the valid values that can be used to set the /// ModeAttributeKey.ColorImagePixelFormat mode/mode spec attribute. /// public enum PixelFormat { /// /// Pixel format with four 8-bit channels in the following order: /// red, green, blue, and alpha. /// R8G8B8A8 = 0, } /// /// Defines the possible orderings for pixel rows within images. /// /// /// /// This currently specifies the valid values that can be used to set the /// ModeAttributeKey.ImageRowOrder mode/mode spec attribute. /// public enum ImageRowOrder { /// /// The top row of pixels occurs first in the image data and the /// remaining rows are ordered from top to bottom. /// TopToBottom = 0, /// /// The bottom row of pixels occurs first in the image data and the /// remaining rows are ordered from bottom to top. /// BottomToTop = 1, } /// /// Defines the possible zView connection states. /// public enum ConnectionState { /// /// The connection is initializing. /// /// /// /// In this state, client code should not perform any zView operations /// using the connection. /// /// The connection will automatically transition to the /// AwaitingConnectionAcceptance state when it has /// finished initializing. /// ConnectionInitialization = 0, /// /// The connection is waiting to be locally accepted or rejected. /// /// /// /// If the connection is accepted, it will transition to the /// SwitchingModes state. If the connection is rejected, it will /// transition to the Closed state. /// AwaitingConnectionAcceptance = 1, /// /// The connection is internally switching between zView modes. /// /// /// /// In this state, client code is not required to perform any zView /// operations using the connection. /// /// The connection will automatically transition to the NoMode state (if /// a switch to the NULL mode was requested) or to the ModeSetup state /// (if a switch a non-NULL mode was requested) when it has finished switching /// modes internally. /// SwitchingModes = 2, /// /// The connection is not currently in any zView mode. /// /// /// /// In this state, client code is not required to perform any zView /// operations using the connection. /// /// The connection can be switched into a mode by calling /// SetConnectionMode(). /// NoMode = 3, /// /// The connection is setting up the current zView mode. /// /// /// /// The connection will transition to the ModeActive state once all /// mode setup phases for the current mode have been completed by both /// the local and remote nodes. /// ModeSetup = 4, /// /// The connection's current zView mode is active. /// /// /// /// In this state, client code should be sending frames to and/or receiving /// frames from the remote zView node. /// /// The connection's current zView mode can be paused by calling PauseMode(). /// This will transition the connection into the ModePaused state. /// ModeActive = 5, /// /// The connection's current zView mode is paused. /// /// /// /// In this state, client code should not be sending frames to nor /// receiving frames from the remote zView node. Client code is not /// required to perform any zView operations while the connection is in /// this state. /// /// The connection's current zView mode can be resumed by calling /// ResumeMode(). This will transition the connection into the /// ModeResuming state. /// ModePaused = 6, /// /// The connection's current zView mode is resuming. /// /// /// /// The connection will automatically transition to the ModeActive state /// or to the ModeSetup state when it has finished resuming the current mode. /// The ModeSetup state is only transitioned to if there changes have been /// made to mode-specific settings (while the mode was paused) that require /// one or more mode setup phases to be rerun. /// ModeResuming = 7, /// /// The connection is internally processing a change to a /// mode-specific setting that will require one or more mode setup phases /// to be rerun. /// /// /// /// The connection will automatically transition to the ModeSetup state when it /// has finished internally processing the mode-specific settings change. /// ProcessingModeSettingsChange = 8, /// /// The connection is closed and should be cleaned up and destroyed. /// /// /// /// In this state, client code may call GetConnectionCloseReason() to /// determine why the connection was closed. /// /// In this state client code may call GetConnectionCloseAction() and /// then optionally perform the requested action. /// Closed = 9, /// /// An error has occurred and the connection is no longer usable. /// /// /// /// In this state, client code may call GetConnectionError() to /// determine the type of error that occurred. /// Error = 10, } /// /// Defines the possible zView connection close actions. /// /// /// /// When closing a connection by calling CloseConnection(), one of these /// actions must be specified as the action that the remote zView node should /// take after the connection is closed. /// /// Once a connection enters the ConnectionState.Closed state, the close /// action for the connection can be queried by calling GetConnectionCloseAction(). /// public enum ConnectionCloseAction { /// /// The application hosting the zView node should not perform any /// additional action after the connection is closed. /// None = 0, /// /// The application hosting the zView node should exit after the /// connection is closed. /// /// /// /// zView nodes may not perform this action is they do not support the /// Capability.RemoteApplicationExit capability. /// ExitApplication = 1, } /// /// Defines the possible reasons why a zView connection was closed. /// /// /// /// When closing a connection by calling CloseConnection(), one of these /// reasons must be specified to indicate why the connection is being closed. /// /// Once a connection enters the ConnectionState.Closed state, the close /// reason for the connection can be queried by calling /// GetConnectionCloseReason(). /// public enum ConnectionCloseReason { /// /// The connection was closed for an unknown reason. /// Unknown = 0, /// /// The connection was closed because the remote zView node's zView /// API context was shut down. /// ShutDown = 1, /// /// The connection was closed because a user requested it to be /// closed. /// UserRequested = 2, /// /// The connection was closed because is was rejected by one of the /// zView nodes involved in the connection. /// ConnectionRejected = 3, } /// /// Defines the possible phases that the setup of a zView mode can go /// through. /// /// /// /// In this version of the zView API, all modes use all of the mode setup /// phases defined by this enum. However, future versions of the zView API may /// introduce mode setup phases that are only used by some modes. /// public enum ModeSetupPhase { /// /// Mode setup is initializing. /// /// /// /// When in this mode setup phase, client code must set any settings that /// the remote node will need to complete mode setup. Exactly which /// settings must be set depends on the current mode. Client code may also /// begin performing other setup tasks related to the current mode during /// this setup phase (e.g. client code might begin creating or loading /// resources needed for the current mode). /// Initialization = 0, /// /// Mode setup is completing. /// /// /// /// When in this mode setup phase, client code must finish any setup that /// is necessary prior to the current mode becoming active. Exactly what /// setup must be performed depends on the current mode. /// Completion = 1, } /// /// Defines the possible states that a connection setting can be in. /// /// /// /// A setting's state can be queried by calling GetSettingState(). /// public enum SettingState { /// /// Setting's value is up to date. /// UpToDate = 0, /// /// Setting's value was changed during the most recent call to /// LateUpdate(). State will transition to UpToDate on the next /// frame's LateUpdate(). /// Changed = 1, /// /// Setting's value was changed locally, but the change has not /// yet been accepted by the other side of the connection. /// ChangePending = 2, } /// /// Defines the keys for all possible zView connection settings. /// public enum SettingKey { /// /// The width, in pixels, of the primary images for the connection's /// current mode. /// Datatype: UInt16. /// /// /// /// In standard mode family modes, this should be set by the presenter node /// during the ModeSetupPhase.Initialization mode setup phase. In /// augmented reality mode family modes, this should be set by the viewer /// node during the ModeSetupPhase.Initialization mode setup phase. /// /// If this setting is set after the ModeSetupPhase.Initialization /// mode setup phase (i.e. in a later mode setup phase or while the mode is /// active or paused), then the connection will automatically transition /// back to the ConnectionState.ModeSetup state in the /// ModeSetupPhase.Completion mode setup phase in order to allow /// both nodes to take into account the new setting value (e.g. by /// reallocating image buffers to use the new width). /// /// This setting should generally be set in a batch (by calling /// BeginSettingsBatch() and EndSettingsBatch()) with the the /// ImageHeight setting. Doing this ensures that remote /// nodes will see image width and height changes at the same time (instead /// of possibly seeing one of these settings change during one frame and /// then the other change in the next frame). /// ImageWidth = 0, /// /// The height, in pixels, of the primary images for the connection's current mode. /// Datatype: UInt16. /// /// /// /// In standard mode family modes, this should be set by the presenter node /// during the ModeSetupPhase.Initialization mode setup phase. In /// augmented reality mode family modes, this should be set by the viewer /// node during the ::ModeSetupPhase.Initialization mode setup phase. /// /// If this setting is set after the ModeSetupPhase.Initialization /// mode setup phase (i.e. in a later mode setup phase or while the mode is /// active or paused), then the connection will automatically transition /// back to the ConnectionState.ModeSetup state in the /// ModeSetupPhase.Completion mode setup phase in order to allow /// both nodes to take into account the new setting value (e.g. by /// reallocating image buffers to use the new height). /// /// This setting should generally be set in a batch (by calling /// BeginSettingsBatch() and EndSettingsBatch()) with the the /// ImageWidth setting. Doing this ensures that remote /// nodes will see image width and height changes at the same time (instead /// of possibly seeing one of these settings change during one frame and /// then the other change in the next frame). /// ImageHeight = 1, /// /// The connection's current video recording quality. /// Datatype: VideoRecordingQuality (get/set as UInt32). /// /// /// /// This setting may only be set if the connection's video recording state /// is currently VideoRecordingState.NotRecording. /// /// Whenever a video recording is started, the current value of this /// setting is used as the quality level for the new video recording. /// VideoRecordingQuality = 2, /// /// The current horizontal offset, in pixels, of the primary image /// overlay displayed by the viewer node (default 0.0f). /// Datatype: float. /// /// /// /// This is only available for augmented reality mode family modes. For /// these modes the viewer node will use this value to offset the position /// of the presenter's color images from the augmented reality mode camera /// video stream images when the two are composited. /// OverlayOffsetX = 3, /// /// The current vertical offset, in pixels, of the primary image /// overlay displayed by the viewer node (default 0.0f). /// Datatype: float. /// /// /// /// This is only available for augmented reality mode family modes. For /// these modes the viewer node will use this value to offset the position /// of the presenter's color images from the augmented reality mode camera /// video stream images when the two are composited. /// OverlayOffsetY = 4, /// /// The current horizontal scale factor for the primary image /// overlay displayed by the viewer node (default 1.0f). /// Datatype: float. /// /// /// /// This is only available for augmented reality mode family modes. For /// these modes the viewer node will use this value to scale the /// presenter's color images before they are composited with the augmented /// reality mode camera video stream images. /// OverlayScaleX = 5, /// /// The current vertical scale factor for the primary image overlay /// displayed by the viewer node (default 1.0f). /// Datatype: float. /// /// /// /// This is only available for augmented reality mode family modes. For /// these modes the viewer node will use this value to scale the /// presenter's color images before they are composited with the augmented /// reality mode camera video stream images. /// OverlayScaleY = 6, } /// /// Defines the possible streams that may be used by a zView mode for /// sending frame data between the nodes involved in a zView connection. /// public enum Stream { /// /// Stream used sending the primary image data between nodes for a /// mode. May also be used to send metadata related to the images being /// sent or data necessary for generating images to be sent. /// Image = 0, } /// /// Defines the keys for all possible pieces of frame data for a zView /// mode. /// public enum FrameDataKey { /// /// The frame's frame number. /// Datatype: UInt64. /// /// /// /// This is used for Stream.Image frames in both standard mode family /// and augmented reality mode family modes. /// FrameNumber = 0, /// /// The camera pose matrix (position and orientation) to use for rendering the current /// mode's primary images. /// Datatype: Matrix4x4. /// /// /// /// This is only used for Stream.Image frames sent from the viewer /// node to the presenter node in augmented reality mode family modes. /// CameraPose = 1, /// /// The camera focal length to use for rendering the current mode's /// primary images. /// Datatype: float. /// /// /// /// This is only used for Stream.Image frames sent from the viewer /// node to the presenter node in augmented reality mode family modes. /// CameraFocalLength = 2, /// /// The horizontal offset of the camera's principal point to use for /// rendering the current mode's primary images. /// Datatype: float. /// /// /// /// This is only used for Stream.Image frames sent from the viewer /// node to the presenter node in augmented reality mode family modes. /// CameraPrincipalPointOffsetX = 3, /// /// The vertical offset of the camera's principal point to use for /// rendering the current mode's primary images. /// Datatype: float. /// /// /// /// This is only used for Stream.Image frames sent from the viewer /// node to the presenter node in augmented reality mode family modes. /// CameraPrincipalPointOffsetY = 4, /// /// The camera pixel aspect ratio to use for rendering the current /// mode's primary images. /// Datatype: float. /// /// /// /// This is only used for Stream.Image frames sent from the viewer /// node to the presenter node in augmented reality mode family modes. /// CameraPixelAspectRatio = 5, /// /// The camera axis skew to use for rendering the current mode's /// primary images. /// Datatype: float. /// /// /// /// This is only used for Stream.Image frames sent from the viewer /// node to the presenter node in augmented reality mode family modes. /// CameraAxisSkew = 6, } /// /// Defines the keys for all possible frame buffers for a zView mode. /// public enum FrameBufferKey { /// /// Frame buffer for storing the first color image associated with a /// zView mode. /// ImageColor0 = 0, } /// /// Defines the possible zView connection video recording states. /// /// /// /// A connection's current video recording state can be queried by calling /// GetVideoRecordingState(). /// public enum VideoRecordingState { /// /// Video recording capability is not currently available and cannot be used. /// /// /// /// A connection's video recording state will automatically transition from /// this state to the NotRecording state if the connection supports the /// Capability.VideoRecording capability. This transition will occur once the /// connection is fully initialized. /// NotAvailable = 0, /// /// Not actively recording and no current recording exists. /// /// /// /// A video recording can be started by calling StartVideoRecording(). /// This will transition the video recording state to the Starting state. /// NotRecording = 1, /// /// Video recording is in the process of starting. /// /// /// /// A connection's video recording state will automatically transition from /// this state to the Recording state once video recording has fully started. /// Starting = 2, /// /// Acively recording. /// /// /// /// Recording can be finished by calling FinishVideoRecording(), which will /// transition the video recording state to the Finishing state. Recording /// can be paused by calling PauseVideoRecording(), which will transition the /// video recording state to the Pausing state. /// Recording = 3, /// /// Video recording is in the process of finishing. /// /// /// /// A connection's video recording state will automatically transition /// fromthis state to the Finished state once video recording has completed /// finishing. /// Finishing = 4, /// /// Not actively recording; current finished recording exists. /// /// /// /// The finished recording can be saved by calling SaveVideoRecording(), /// which will transition the video recording state to the Saving state. /// The finished recording can be discarded by calling DiscardVideoRecording(), /// which will transition the video recording state to the Discarding state. /// Finished = 5, /// /// Video recording is in the process of pausing. /// /// /// /// A connection's video recording state will automatically transition from /// this state to the Paused state once video recording has completed pausing. /// Pausing = 6, /// /// Not actively recording; current resumable recording exists. /// /// /// /// Recording can be resumed by calling ResumeVideoRecording(), which /// will transition the video recording state to the Resuming state. /// Recording can be finished by calling FinishVideoRecording(), which /// will transition the video recording state to the Finishing state. /// Paused = 7, /// /// Video recording is in the process of resuming. /// /// /// /// A connection's video recording state will automatically transition from /// this state to the Recording state once video recording has completed resuming. /// Resuming = 8, /// /// The current finished video recording is in the process of being /// saved. /// /// /// /// A connection's video recording state will automatically transition from /// this state to the NotRecording state once saving is complete. /// Saving = 9, /// /// The current finished video recording is in the process of being /// discarded. /// /// /// /// A connection's video recording state will automatically transition from /// this state to the NotRecording state once discarding is complete. /// Discarding = 10, /// /// A recoverable video-recording-related error occurred. /// /// /// /// In this state, client code should call ClearVideoRecordingError() to /// clear the error and allow new video recordings to be started. This /// will transition the video recording state to the ClearingError state. /// /// In this state, client code may call GetVideoRecordingError() to /// determine the type of error that occurred. /// Error = 11, /// /// The most recent video recording error is in the process of being /// cleared. /// /// /// /// A connection's video recording state will automatically transition from /// this state to the NotRecording state once clearing of the video recording /// error is complete. /// ClearingError = 12, } /// /// Defines the possible video recording quality levels. /// public enum VideoRecordingQuality { Unknown = -1, /// /// Video recording with 854 x 480 pixel resolution. /// Resolution480p = 0, /// /// Video recording with 1280 x 720 pixel resolution. /// Resolution720p = 1, /// /// Video recording with 1920 x 1080 pixel resolution. /// Resolution1080p = 2, } ////////////////////////////////////////////////////////////////// // Compound Types ////////////////////////////////////////////////////////////////// /// /// Class representing a mode that is supported by a zView node along /// with the current availability of that mode. /// public class SupportedMode { /// /// The handle of the mode that is supported. /// public IntPtr Mode { get; private set; } /// /// The supported mode's current availability. /// public ModeAvailability ModeAvailability { get; private set; } public SupportedMode(IntPtr mode, ModeAvailability modeAvailability) { this.Mode = mode; this.ModeAvailability = modeAvailability; } } ////////////////////////////////////////////////////////////////// // Unity Inspector Fields ////////////////////////////////////////////////////////////////// /// /// Layers to be ignored by the standard mode's default /// virtual camera. /// public int StandardModeIgnoreLayers = 0; /// /// Layers to be ignored by the augmented reality mode's /// default virtual camera. /// public int ARModeIgnoreLayers = 0; /// /// Layers to cull out by the augmented reality mode's /// default virtual camera if geometry protrudes into /// negative parallax outside the bounds of the viewport. /// public int ARModeEnvironmentLayers = 0; /// /// Layer (0 - 31) to be assigned to the augmented reality mode's /// box mask. This layer must be unique and should not be used for /// any objects in the scene other than the box mask. /// public int ARModeMaskLayer = 31; /// /// The render queue priority for the augmented reality mode's /// box mask. This is only used when ARModeEnableTransparency /// is enabled and should generally be assigned values less than /// 2000 (opaque geometry) to ensure that its depth will be rendered /// prior to rendering any opaque geometry. /// public int ARModeMaskRenderQueue = 1900; /// /// The size of the augmented reality mode's box mask in meters. /// public Vector3 ARModeMaskSize = Vector3.one * 2.0f; /// /// Enables debug visualization for the augmented reality mode's /// box mask in the Unity Editor's SceneView window. /// public bool ARModeShowMask = false; /// /// If not enabled, force all non-mask pixels rendered by the augmented /// reality mode's virtual camera to have an alpha value of 1. By default, /// this is disabled due to the fact that most standard shaders associated /// with both opaque and transparent geometry either have incorrect values /// in their alpha channels, or do not write their alpha channels to the /// frame buffer. /// public bool ARModeEnableTransparency = false; /// /// ZView requires a reference to the active ZCamera. ZView will try /// to find an instance of ZCamera on awake if left unassigned. If the /// ZCamera is destroyed during the life of the current scene, this /// value must be assigned manually. /// public ZCamera ActiveZCamera = null; ////////////////////////////////////////////////////////////////// // Unity Monobehaviour Callbacks ////////////////////////////////////////////////////////////////// void Awake() { // Force initialization of the global state. GlobalState globalState = GlobalState.Instance; if (globalState == null || !globalState.IsInitialized) { Debug.LogWarning("Failed to initialize global state. Disabling zView GameObject."); this.gameObject.SetActive(false); return; } // Get the first found instance of ZCamera if a reference has not // been manually assigned. if (this.ActiveZCamera == null) { this.ActiveZCamera = GameObject.FindObjectOfType(); if (this.ActiveZCamera == null) { Debug.LogWarning("No instance of ZCamera has been found " + "in the scene. ZView will not work correctly unless " + "ZView.Instance.ActiveZCamera is not null"); } } // Continue initialization. this.InitializeVirtualCameras(); // Initialize whether the application is in windowed or fullscreen mode. _wasFullScreen = Screen.fullScreen; // Kick off the end of frame update coroutine. this.StartCoroutine(EndOfFrameUpdate()); } void Start() { // Handle transitioning from a zView-enabled scene while there // is currently an active connection. this.HandleSceneTransition(); } void LateUpdate() { // Cache whether the application is in windowed or fullscreen mode. _wasFullScreen = Screen.fullScreen; } IEnumerator EndOfFrameUpdate() { while (true) { yield return new WaitForEndOfFrame(); this.UpdateConnections(); } } void OnApplicationQuit() { GlobalState.DestroyInstance(); // Notify the native plugin to destroy any resources // that may have been allocated. ZView.IssuePluginEvent(PluginEvent.DestroyResources); } void OnDrawGizmos() { // Draw the bounds of the AR mode box mask. if (this.ARModeShowMask) { if (this.ActiveZCamera == null) return; // Cache original color and matrix to be restored after // drawing is finished. Color originalGizmosColor = Gizmos.color; Matrix4x4 originalGizmosMatrix = Gizmos.matrix; Gizmos.color = Color.white; // ZCamera's parent represents viewport center and // therefore where we align the box mask to it. // If ZCamera has no parent, then it will align the // box mask to world center as is done with ZCamera. Gizmos.matrix = this.ActiveZCamera.transform.parent?.localToWorldMatrix ?? Matrix4x4.identity; Vector3 center = new Vector3(0.0f, 0.0f, -this.ARModeMaskSize.z * 0.5f); Vector3 size = this.ARModeMaskSize; Gizmos.DrawWireCube(center, size); // Restore original color and matrix. Gizmos.color = originalGizmosColor; Gizmos.matrix = originalGizmosMatrix; } } ////////////////////////////////////////////////////////////////// // Public API ////////////////////////////////////////////////////////////////// /// /// Checks whether the zView SDK was properly initialized. /// /// /// /// True if initialized. False otherwise. /// public bool IsInitialized() { return GlobalState.Instance.IsInitialized; } /// /// Gets the current version of the zView Unity plugin. /// /// /// /// The plugin version in major.minor.patch string format. /// public string GetPluginVersion() { int major = 0; int minor = 0; int patch = 0; zvuGetPluginVersion(out major, out minor, out patch); return string.Format("{0}.{1}.{2}", major, minor, patch); } /// /// Gets the current runtime version of the zView SDK. /// /// /// /// The runtime version in major.minor.patch string format. /// public string GetRuntimeVersion() { int major = 0; int minor = 0; int patch = 0; PluginError error = zvuGetRuntimeVersion(GlobalState.Instance.Context, out major, out minor, out patch); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return string.Format("{0}.{1}.{2}", major, minor, patch); } /// /// Get the node type of the current context. /// /// /// /// The node type of the current context. /// public NodeType GetNodeType() { NodeType type; PluginError error = zvuGetNodeType(GlobalState.Instance.Context, out type); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return type; } /// /// Get the node ID of the current context. /// /// /// /// The byte buffer to fill with the node ID of the current context. /// public byte[] GetNodeId() { // Get the node id's size in bytes. int size = 0; PluginError error = zvuGetNodeIdSize(GlobalState.Instance.Context, out size); if (error != PluginError.Ok) { throw this.NewPluginException(error); } // Get the node id. byte[] id = new byte[size]; error = zvuGetNodeId(GlobalState.Instance.Context, id, size); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return id; } /// /// Get the node name string associated with the current context. /// /// /// /// The node name string associated with the current context. /// public string GetNodeName() { // Get the size of the node name. int size = 0; PluginError error = zvuGetNodeNameSize(GlobalState.Instance.Context, out size); if (error != PluginError.Ok) { throw this.NewPluginException(error); } // Get the node name. byte[] name = new byte[size]; error = zvuGetNodeName(GlobalState.Instance.Context, name, size); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return ZView.NativeUtf8ToString(name); } /// /// Set the node name string associated with the current context. /// /// /// /// The new node name to use. /// public void SetNodeName(string name) { PluginError error = zvuSetNodeName(GlobalState.Instance.Context, ZView.StringToNativeUtf8(name)); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Get the node status string associated with the current context. /// /// /// /// The node status string associated with the current context. /// public string GetNodeStatus() { // Get the node status size. int size = 0; PluginError error = zvuGetNodeStatusSize(GlobalState.Instance.Context, out size); if (error != PluginError.Ok) { throw this.NewPluginException(error); } // Get the node status. byte[] status = new byte[size]; error = zvuGetNodeStatus(GlobalState.Instance.Context, status, size); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return ZView.NativeUtf8ToString(status); } /// /// Set the node status string associated with the current context. /// /// /// /// The new node status to use. /// public void SetNodeStatus(string status) { PluginError error = zvuSetNodeStatus(GlobalState.Instance.Context, ZView.StringToNativeUtf8(status)); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Get the number of modes supported by the current context. /// /// /// /// The number of modes supported by the current context. /// public int GetNumSupportedModes() { int numModes = 0; PluginError error = zvuGetNumSupportedModes(GlobalState.Instance.Context, out numModes); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return numModes; } /// /// Get a supported mode from the list of supported modes for the /// current context. /// /// /// /// The index of the supported mode to get. This must be /// greater than or equal to 0 and less than the number of /// supported modes queried via GetNumSupportedModes(). /// /// /// /// The requested supported mode. /// /// /// /// Thrown if the mode index is out of range. /// public SupportedMode GetSupportedMode(int modeIndex) { ZVSupportedMode mode; PluginError error = zvuGetSupportedMode(GlobalState.Instance.Context, modeIndex, out mode); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return ZView.Convert(mode); } /// /// Set the modes supported by the current context. /// /// /// /// The list of supported modes. /// /// /// /// Thrown if any supported mode references an invalid mode. /// public void SetSupportedModes(IList modes) { int numModes = modes.Count; ZVSupportedMode[] temp = new ZVSupportedMode[numModes]; for (int i = 0; i < numModes; ++i) { temp[i] = ZView.Convert(modes[i]); } PluginError error = zvuSetSupportedModes(GlobalState.Instance.Context, temp, numModes); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Get the number of capabilities supported by the current context. /// /// /// /// The number of capabilities supported by the current context. /// public int GetNumSupportedCapabilities() { int numCapabilities = 0; PluginError error = zvuGetNumSupportedCapabilities(GlobalState.Instance.Context, out numCapabilities); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return numCapabilities; } /// /// Get a supported capability from the list of supported capabilities for /// the current context. /// /// /// /// The index of the supported capability to get. This must be greater than /// or equal to 0 and less than the number of supported capabilities queried /// via GetNumSupportedCapabilities(). /// /// /// /// The requested supported capability. /// /// /// /// Thrown if the capability index is out of range. /// public Capability GetSupportedCapability(int capabilityIndex) { Capability capability; PluginError error = zvuGetSupportedCapability(GlobalState.Instance.Context, capabilityIndex, out capability); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return capability; } /// /// Get the value of the specified mode attribute of type UInt32 for the /// specified mode. /// /// /// /// The mode to get the attribute value of. /// /// /// The mode attribute key to get the value of. /// /// /// /// The value associated with specified mode and mode attribute key. /// /// /// /// Thrown if the mode is null (IntPtr.Zero). /// /// /// Thrown if the mode is invalid. /// /// /// Thrown if the mode attribute key is invalid. /// public UInt32 GetModeAttributeUInt32(IntPtr mode, ModeAttributeKey key) { UInt32 value = 0; PluginError error = zvuGetModeAttributeU32(mode, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Connect to the default viewer using the current context. /// /// /// /// This method performs its work asynchronously. Once a connection /// to the default viewer is created, it will be accessible via /// GetConnection() or GetCurrentActiveConnection() after the next /// LateUpdate(). /// public void ConnectToDefaultViewer() { PluginError error = zvuConnectToDefaultViewer(GlobalState.Instance.Context, IntPtr.Zero); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Close the specified connection. /// /// /// /// The close action will be queriable by the remote node /// once the connection has entered the Closed state. Note: The node /// that calls this function for a connection will not be able to query /// the action it specifies via GetConnectionCloseAction(), since the /// action is meant for the remote node. Instead, GetConnectionCloseAction() /// will always return None when called by the node that called this /// method. /// /// /// /// The connection to close. /// /// /// The action that should be performed by the remote node after the /// connection is closed. /// /// /// The reason why the connection is being closed. This will be queriable /// via the GetConnectionCloseReason() function once the connection has /// entered the Closed state. /// /// /// Additional details on the reason why the connection is being closed. /// This is purely for logging purposes and will not be displayed to the /// user. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is already in a Closed or Error state. /// public void CloseConnection(IntPtr connection, ConnectionCloseAction action, ConnectionCloseReason reason, string reasonDetails) { PluginError error = zvuCloseConnection(connection, action, reason, ZView.StringToNativeUtf8(reasonDetails)); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Get the number of currently visible connections for the current context. /// /// /// /// The number of currently visible connections will change over the lifetime /// of a context. However, the number connections queried by this function /// will only change during LateUpdate() (i.e. the value will remain /// stable between calls to LateUpdate()). /// /// /// /// The number of visible connections for the specified context. /// public int GetNumConnections() { int numConnections = 0; PluginError error = zvuGetNumConnections(GlobalState.Instance.Context, out numConnections); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return numConnections; } /// /// Get a connection from the list of currently visible connections for the /// current context. /// /// /// /// The list of currently visible connections will change over the lifetime of /// a context. However, the list of connections that is accessible via this /// function will only change during LateUpdate() (i.e. the list will /// remain stable between calls to LateUpdate()). /// /// /// /// The index of the connection to get. This must be greater than or equal /// to 0 and less than the number of connections queried via GetNumConnections(). /// /// /// /// The requested connection. /// /// /// /// Thrown if the connection index is out of range. /// public IntPtr GetConnection(int connectionIndex) { IntPtr connection = IntPtr.Zero; PluginError error = zvuGetConnection(GlobalState.Instance.Context, connectionIndex, out connection); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return connection; } /// /// Get the current active connection if it exists. /// /// /// /// The current active connection if it exists. Otherwise IntPtr.Zero. /// public IntPtr GetCurrentActiveConnection() { return GlobalState.Instance.Connection; } /// /// Get the state of the specified connection. /// /// /// /// The state of a connection will change over the lifetime of the connection. /// However, the state queried via this function will only change during /// LateUpdate() (i.e. the state will remain stable between calls to LateUpdate()). /// /// /// /// The connection to get the state of. /// /// /// /// The state of the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// public ConnectionState GetConnectionState(IntPtr connection) { ConnectionState state = ConnectionState.Error; PluginError error = zvuGetConnectionState(connection, out state); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return state; } /// /// Get the error code associated with the specified connection. /// /// /// /// It is only valid to query the error code associated with a connection when it /// is in the Error state (i.e. through callbacks registered against the /// ConnectionError event). /// /// /// /// The connection to get the error code of. /// /// /// /// The error code associated with the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is not in the Error state. /// public PluginError GetConnectionError(IntPtr connection) { PluginError connectionError = PluginError.Unknown; PluginError error = zvuGetConnectionError(connection, out connectionError); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return connectionError; } /// /// Check whether the specified connection was initiated locally or remotely. /// /// /// /// The connection to check whether it was locally initiated. /// /// /// /// Whether the connection was locally initiated. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// public bool WasConnectionLocallyInitiated(IntPtr connection) { bool wasLocallyInitiated = false; PluginError error = zvuWasConnectionLocallyInitiated(connection, out wasLocallyInitiated); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return wasLocallyInitiated; } /// /// Gets the node ID of the remote node that the specified connection is /// connected to. /// /// /// /// The connection to get the remote node ID of. /// /// /// /// The byte buffer to fill with the node ID of the remote node that the /// specified connection is connected to. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// public byte[] GetConnectedNodeId(IntPtr connection) { // Get the node id's size in bytes. int size = 0; PluginError error = zvuGetConnectedNodeIdSize(connection, out size); if (error != PluginError.Ok) { throw this.NewPluginException(error); } // Get the node id. byte[] id = new byte[size]; error = zvuGetConnectedNodeId(connection, id, size); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return id; } /// /// Gets the node name string of the remote node that the specified connection /// is connected to. /// /// /// /// The connection to get the remote node name of. /// /// /// /// The node name string of the remote node that the specified connection /// is connected to. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// public string GetConnectedNodeName(IntPtr connection) { // Get the node name's size in bytes. int size = 0; PluginError error = zvuGetConnectedNodeNameSize(connection, out size); if (error != PluginError.Ok) { throw this.NewPluginException(error); } // Get the node name. byte[] name = new byte[size]; error = zvuGetConnectedNodeName(connection, name, size); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return ZView.NativeUtf8ToString(name); } /// /// Gets the node status string of the remote node that the specified /// connection is connected to. /// /// /// /// The connection to get the remote node status of. /// /// /// /// The node status string of the remote node that the specified /// connection is connected to. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// public string GetConnectedNodeStatus(IntPtr connection) { // Get the node status's size in bytes. int size = 0; PluginError error = zvuGetConnectedNodeStatusSize(connection, out size); if (error != PluginError.Ok) { throw this.NewPluginException(error); } // Get the node status. byte[] status = new byte[size]; error = zvuGetConnectedNodeStatus(connection, status, size); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return ZView.NativeUtf8ToString(status); } /// /// Check if the specified connection supports the specified capability. /// /// /// /// The connection to check the capability support of. /// /// /// The capability to check for support of. /// /// /// /// Whether the specified capability is supported by the specified /// connection or not. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// public bool DoesConnectionSupportCapability(IntPtr connection, Capability capability) { bool isSupported = false; PluginError error = zvuDoesConnectionSupportCapability(connection, capability, out isSupported); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return isSupported; } /// /// Get the number of modes supported by the specified connection. /// /// /// /// The number of modes supported by a connection may change over the lifetime /// of the connection. However, the number of supported modes returned by this /// function will only change during LateUpdate() (i.e. the value will remain /// stable between calls to LateUpdate()). /// /// /// /// The connection to get the number of supported modes for. /// /// /// /// The number of modes supported by the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// public int GetNumConnectionSupportedModes(IntPtr connection) { int numSupportedModes = 0; PluginError error = zvuGetNumConnectionSupportedModes(connection, out numSupportedModes); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return numSupportedModes; } /// /// Get a supported mode and associated mode availability information from the /// list of modes supported by the specified connection. /// /// /// /// The list of modes supported by a connection may change over the lifetime of /// the connection. However, the list of supported modes accessible via this /// function will only change during LateUpdate() (i.e. the value will remain /// stable between calls to LateUpdate()). /// /// /// /// The connection to get a supported mode from. /// /// /// The index of the supported mode to get. This must be greater than or equal /// to 0 and less than the number of supported modes queried via the /// GetNumConnectionSupportedModes() function. /// /// /// /// The requested supported mode with associated mode availability information. /// /// /// /// Thrown if the connection is null (IntPtr.Zero) or the supported mode index /// is out of range. /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// public SupportedMode GetConnectionSupportedMode(IntPtr connection, int supportedModeIndex) { ZVSupportedMode supportedMode; PluginError error = zvuGetConnectionSupportedMode(connection, supportedModeIndex, out supportedMode); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return new SupportedMode(supportedMode.mode, supportedMode.modeAvailability); } /// /// Get the standard mode handle. /// /// /// /// The standard mode handle. /// public IntPtr GetStandardMode() { return GlobalState.Instance.ModeStandard; } /// /// Get the augmented reality mode handle. /// /// /// /// The augmented reality mode. /// public IntPtr GetAugmentedRealityMode() { return GlobalState.Instance.ModeAugmentedReality; } /// /// Get the current mode of the specified connection. /// /// /// /// The current mode of a connection will change over the lifetime of the /// connection. However, the mode queried via this function will only change /// during LateUpdate() (i.e. the value will remain stable between calls to /// LateUpdate()). /// /// /// /// The connection to set the current mode of. /// /// /// /// The current mode of the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// public IntPtr GetConnectionMode(IntPtr connection) { IntPtr mode = IntPtr.Zero; PluginError error = zvuGetConnectionMode(connection, out mode); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return mode; } /// /// Set the current mode of the specified connection. /// /// /// /// If the current mode of the specified connection is not equal to the mode /// specified when this function is called, then this function will initiate a /// mode switch (the actual mode switch will occur asynchronously and will only /// become visible after the next LateUpdate() is called). /// /// /// /// The connection to set the current mode of. /// /// /// The new mode to use as the current mode of the specified connection. /// Passing IntPtr.Zero for this argument makes it so that there is no current /// mode and transitions the connection into the NodeMode state. /// /// /// /// Thrown if the connection or the mode is null (IntPtr.Zero). Also thrown /// if the mode is not supported or not available. /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the mode is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// public void SetConnectionMode(IntPtr connection, IntPtr mode) { PluginError error = zvuSetConnectionMode(connection, mode); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Get the user data associated with the specified connection. /// /// /// /// The connection to get the user data of. /// /// /// /// The user data of the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// public IntPtr GetConnectionUserData(IntPtr connection) { IntPtr userData = IntPtr.Zero; PluginError error = zvuGetConnectionUserData(connection, out userData); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return userData; } /// /// Set the user data associated with the specified connection. /// /// /// /// The connection to get the user data of. /// /// /// The user data of the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// public void SetConnectionUserData(IntPtr connection, IntPtr userData) { PluginError error = zvuSetConnectionUserData(connection, userData); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Get the close action associated with the specified connection. /// /// /// /// The client code should perform this action if possible after a connection /// enters the Closed state. /// /// It is only valid to call this function for a connection that is in the /// Closed state or in a callback registered against the ConnectedClosed event. /// /// /// /// The connection to get the close action of. /// /// /// /// The close action of the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is not in the Closed state. /// public ConnectionCloseAction GetConnectionCloseAction(IntPtr connection) { ConnectionCloseAction action = ConnectionCloseAction.None; PluginError error = zvuGetConnectionCloseAction(connection, out action); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return action; } /// /// Get the close reason associated with the specified connection. /// /// /// /// It is only valid to call this function for a connection that is in the /// Closed state or in a callback registered against the ConnectedClosed event. /// /// /// /// The connection to get the close reason of. /// /// /// /// The close reason of the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is not in the Closed state. /// public ConnectionCloseReason GetConnectionCloseReason(IntPtr connection) { ConnectionCloseReason reason = ConnectionCloseReason.Unknown; PluginError error = zvuGetConnectionCloseReason(connection, out reason); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return reason; } /// /// Request that current mode be paused for the specified connection. /// /// /// /// Pausing will occur asynchronously and eventually become visible after a /// call to LateUpdate(). /// /// It is only valid to call this function for a connection that is in the /// ModeActive state. /// /// /// /// The connection to pause frame sending for. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is not in the ModeActive state. /// public void PauseMode(IntPtr connection) { PluginError error = zvuPauseMode(connection); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Request that the current mode be resumed for the specified connection. /// /// /// /// Resuming will occur asynchronously and eventually become visible after a /// call to LateUpdate(). /// /// It is only valid to call this function for a connection that is in the /// ModePaused state. /// /// /// /// The connection to resume frame sending for. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is not in the ModePaused state. /// public void ResumeMode(IntPtr connection) { PluginError error = zvuResumeMode(connection); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Begin a settings batch for the specified connection. /// /// /// /// While a settings batch is active for a connection, changes to setting /// values will not be sent over the connection until the settings batch is /// ended (via a call to EndSettingsBatch()). This allows multiple settings /// value changes to be sent as an atomic unit. This is necessary when a group /// of settings are interrelated and changing one setting in the group requires /// other settings in the group to also be changed in order to keep all /// settings in the group in a consistent state. /// /// At most one settings batch can be active at any time for a particular /// connection. Attempting to begin a settings batch for a connection when the /// connection already has an active settings batch will result in an error. /// /// /// /// The connection to begin a settings batch for. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// public void BeginSettingsBatch(IntPtr connection) { PluginError error = zvuBeginSettingsBatch(connection); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// End a settings batch for the specified connection. /// /// /// /// Attempting to end a setting batch for a connection that does not have an /// active settings batch will result in an error. /// /// /// /// The connection to end a settings batch for. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// public void EndSettingsBatch(IntPtr connection) { PluginError error = zvuEndSettingsBatch(connection); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Get the value of the specified setting of type bool for the specified /// connection. /// /// /// /// The connection to get the setting value for. /// /// /// The setting key to get the value of. /// /// /// /// The value associated with specified connection and setting key. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public bool GetSettingBool(IntPtr connection, SettingKey key) { bool value = false; PluginError error = zvuGetSettingB(connection, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified setting of type sbyte (Int8) for the /// specified connection. /// /// /// /// The connection to get the setting value for. /// /// /// The setting key to get the value of. /// /// /// /// The value associated with specified connection and setting key. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public sbyte GetSettingInt8(IntPtr connection, SettingKey key) { sbyte value = 0; PluginError error = zvuGetSettingI8(connection, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified setting of type Int16 for the specified /// connection. /// /// /// /// The connection to get the setting value for. /// /// /// The setting key to get the value of. /// /// /// /// The value associated with specified connection and setting key. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public Int16 GetSettingInt16(IntPtr connection, SettingKey key) { Int16 value = 0; PluginError error = zvuGetSettingI16(connection, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified setting of type Int32 for the specified /// connection. /// /// /// /// The connection to get the setting value for. /// /// /// The setting key to get the value of. /// /// /// /// The value associated with specified connection and setting key. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public Int32 GetSettingInt32(IntPtr connection, SettingKey key) { Int32 value = 0; PluginError error = zvuGetSettingI32(connection, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified setting of type Int64 for the specified /// connection. /// /// /// /// The connection to get the setting value for. /// /// /// The setting key to get the value of. /// /// /// /// The value associated with specified connection and setting key. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public Int64 GetSettingInt64(IntPtr connection, SettingKey key) { Int64 value = 0; PluginError error = zvuGetSettingI64(connection, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified setting of type byte (UInt8) for the /// specified connection. /// /// /// /// The connection to get the setting value for. /// /// /// The setting key to get the value of. /// /// /// /// The value associated with specified connection and setting key. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public byte GetSettingUInt8(IntPtr connection, SettingKey key) { byte value = 0; PluginError error = zvuGetSettingU8(connection, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified setting of type UInt16 for the specified /// connection. /// /// /// /// The connection to get the setting value for. /// /// /// The setting key to get the value of. /// /// /// /// The value associated with specified connection and setting key. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public UInt16 GetSettingUInt16(IntPtr connection, SettingKey key) { UInt16 value = 0; PluginError error = zvuGetSettingU16(connection, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified setting of type UInt32 for the specified /// connection. /// /// /// /// The connection to get the setting value for. /// /// /// The setting key to get the value of. /// /// /// /// The value associated with specified connection and setting key. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public UInt32 GetSettingUInt32(IntPtr connection, SettingKey key) { UInt32 value = 0; PluginError error = zvuGetSettingU32(connection, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified setting of type UInt64 for the specified /// connection. /// /// /// /// The connection to get the setting value for. /// /// /// The setting key to get the value of. /// /// /// /// The value associated with specified connection and setting key. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public UInt64 GetSettingUInt64(IntPtr connection, SettingKey key) { UInt64 value = 0; PluginError error = zvuGetSettingU64(connection, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified setting of type float for the specified /// connection. /// /// /// /// The connection to get the setting value for. /// /// /// The setting key to get the value of. /// /// /// /// The value associated with specified connection and setting key. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public float GetSettingFloat(IntPtr connection, SettingKey key) { float value = 0; PluginError error = zvuGetSettingF32(connection, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified setting of type double for the specified /// connection. /// /// /// /// The connection to get the setting value for. /// /// /// The setting key to get the value of. /// /// /// /// The value associated with specified connection and setting key. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public double GetSettingDouble(IntPtr connection, SettingKey key) { double value = 0; PluginError error = zvuGetSettingF64(connection, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified setting of type Vector3 for the specified /// connection. /// /// /// /// The connection to get the setting value for. /// /// /// The setting key to get the value of. /// /// /// /// The value associated with specified connection and setting key. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public Vector3 GetSettingVector3(IntPtr connection, SettingKey key) { ZSVector3 value; PluginError error = zvuGetSettingV3(connection, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return ZView.Convert(value, true); } /// /// Get the value of the specified setting of type Matrix4x4 for the specified /// connection. /// /// /// /// The connection to get the setting value for. /// /// /// The setting key to get the value of. /// /// /// /// The value associated with specified connection and setting key. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public Matrix4x4 GetSettingMatrix4x4(IntPtr connection, SettingKey key) { ZSMatrix4 value; PluginError error = zvuGetSettingM4(connection, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return ZView.Convert(value, true); } /// /// Set the value of the specified setting of type bool for the specified /// connection. /// /// /// /// When the value of a setting is set, its state will transition to /// ChangePending until the new value has been accepted by the other side /// of the associated connection. /// /// /// /// The connection to set the setting value for. /// /// /// The setting key to set the value of. /// /// /// The new value for the specified setting key for the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public void SetSetting(IntPtr connection, SettingKey key, bool value) { PluginError error = zvuSetSettingB(connection, key, value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Set the value of the specified setting of type sbyte (Int8) for the /// specified connection. /// /// /// /// When the value of a setting is set, its state will transition to /// ChangePending until the new value has been accepted by the other side /// of the associated connection. /// /// /// /// The connection to set the setting value for. /// /// /// The setting key to set the value of. /// /// /// The new value for the specified setting key for the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public void SetSetting(IntPtr connection, SettingKey key, sbyte value) { PluginError error = zvuSetSettingI8(connection, key, value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Set the value of the specified setting of type Int16 for the specified /// connection. /// /// /// /// When the value of a setting is set, its state will transition to /// ChangePending until the new value has been accepted by the other side /// of the associated connection. /// /// /// /// The connection to set the setting value for. /// /// /// The setting key to set the value of. /// /// /// The new value for the specified setting key for the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public void SetSetting(IntPtr connection, SettingKey key, Int16 value) { PluginError error = zvuSetSettingI16(connection, key, value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Set the value of the specified setting of type Int32 for the specified /// connection. /// /// /// /// When the value of a setting is set, its state will transition to /// ChangePending until the new value has been accepted by the other side /// of the associated connection. /// /// /// /// The connection to set the setting value for. /// /// /// The setting key to set the value of. /// /// /// The new value for the specified setting key for the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public void SetSetting(IntPtr connection, SettingKey key, Int32 value) { PluginError error = zvuSetSettingI32(connection, key, value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Set the value of the specified setting of type Int64 for the specified /// connection. /// /// /// /// When the value of a setting is set, its state will transition to /// ChangePending until the new value has been accepted by the other side /// of the associated connection. /// /// /// /// The connection to set the setting value for. /// /// /// The setting key to set the value of. /// /// /// The new value for the specified setting key for the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public void SetSetting(IntPtr connection, SettingKey key, Int64 value) { PluginError error = zvuSetSettingI64(connection, key, value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Set the value of the specified setting of type byte (UInt8) for the /// specified connection. /// /// /// /// When the value of a setting is set, its state will transition to /// ChangePending until the new value has been accepted by the other side /// of the associated connection. /// /// /// /// The connection to set the setting value for. /// /// /// The setting key to set the value of. /// /// /// The new value for the specified setting key for the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public void SetSetting(IntPtr connection, SettingKey key, byte value) { PluginError error = zvuSetSettingU8(connection, key, value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Set the value of the specified setting of type UInt16 for the specified /// connection. /// /// /// /// When the value of a setting is set, its state will transition to /// ChangePending until the new value has been accepted by the other side /// of the associated connection. /// /// /// /// The connection to set the setting value for. /// /// /// The setting key to set the value of. /// /// /// The new value for the specified setting key for the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public void SetSetting(IntPtr connection, SettingKey key, UInt16 value) { PluginError error = zvuSetSettingU16(connection, key, value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Set the value of the specified setting of type UInt32 for the specified /// connection. /// /// /// /// When the value of a setting is set, its state will transition to /// ChangePending until the new value has been accepted by the other side /// of the associated connection. /// /// /// /// The connection to set the setting value for. /// /// /// The setting key to set the value of. /// /// /// The new value for the specified setting key for the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public void SetSetting(IntPtr connection, SettingKey key, UInt32 value) { PluginError error = zvuSetSettingU32(connection, key, value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Set the value of the specified setting of type UInt64 for the specified /// connection. /// /// /// /// When the value of a setting is set, its state will transition to /// ChangePending until the new value has been accepted by the other side /// of the associated connection. /// /// /// /// The connection to set the setting value for. /// /// /// The setting key to set the value of. /// /// /// The new value for the specified setting key for the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public void SetSetting(IntPtr connection, SettingKey key, UInt64 value) { PluginError error = zvuSetSettingU64(connection, key, value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Set the value of the specified setting of type float for the specified /// connection. /// /// /// /// When the value of a setting is set, its state will transition to /// ChangePending until the new value has been accepted by the other side /// of the associated connection. /// /// /// /// The connection to set the setting value for. /// /// /// The setting key to set the value of. /// /// /// The new value for the specified setting key for the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public void SetSetting(IntPtr connection, SettingKey key, float value) { PluginError error = zvuSetSettingF32(connection, key, value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Set the value of the specified setting of type double for the specified /// connection. /// /// /// /// When the value of a setting is set, its state will transition to /// ChangePending until the new value has been accepted by the other side /// of the associated connection. /// /// /// /// The connection to set the setting value for. /// /// /// The setting key to set the value of. /// /// /// The new value for the specified setting key for the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public void SetSetting(IntPtr connection, SettingKey key, double value) { PluginError error = zvuSetSettingF64(connection, key, value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Set the value of the specified setting of type Vector3 for the specified /// connection. /// /// /// /// When the value of a setting is set, its state will transition to /// ChangePending until the new value has been accepted by the other side /// of the associated connection. /// /// /// /// The connection to set the setting value for. /// /// /// The setting key to set the value of. /// /// /// The new value for the specified setting key for the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public void SetSetting(IntPtr connection, SettingKey key, Vector3 value) { PluginError error = zvuSetSettingV3(connection, key, ZView.Convert(value, true)); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Set the value of the specified setting of type Matrix4x4 for the specified /// connection. /// /// /// /// When the value of a setting is set, its state will transition to /// ChangePending until the new value has been accepted by the other side /// of the associated connection. /// /// /// /// The connection to set the setting value for. /// /// /// The setting key to set the value of. /// /// /// The new value for the specified setting key for the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the setting key is invalid. /// public void SetSetting(IntPtr connection, SettingKey key, Matrix4x4 value) { PluginError error = zvuSetSettingM4(connection, key, ZView.Convert(value, true)); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Get the state of the specified setting for the specified connection /// /// /// /// The connection to get the setting state for. /// /// /// The setting key to get the state of. /// /// /// /// The state of the specified setting state for the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// public SettingState GetSettingState(IntPtr connection, SettingKey key) { SettingState state; PluginError error = zvuGetSettingState(connection, key, out state); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return state; } /// /// Get the value of the specified frame data of type bool for the /// specified frame. /// /// /// /// The frame to get frame data from. /// /// /// The frame data key to get the value of. /// /// /// /// The value associated with specified frame and frame data key. /// /// /// /// Thrown if the frame is null (IntPtr.Zero). /// /// /// Thrown if the frame is invalid. /// /// /// Thrown if the frame data key is invalid. /// public bool GetFrameDataBool(IntPtr frame, FrameDataKey key) { bool value = false; PluginError error = zvuGetFrameDataB(frame, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified frame data of type sbyte (Int8) for the /// specified frame. /// /// /// /// The frame to get frame data from. /// /// /// The frame data key to get the value of. /// /// /// /// The value associated with specified frame and frame data key. /// /// /// /// Thrown if the frame is null (IntPtr.Zero). /// /// /// Thrown if the frame is invalid. /// /// /// Thrown if the frame data key is invalid. /// public sbyte GetFrameDataInt8(IntPtr frame, FrameDataKey key) { sbyte value = 0; PluginError error = zvuGetFrameDataI8(frame, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified frame data of type Int16 for the /// specified frame. /// /// /// /// The frame to get frame data from. /// /// /// The frame data key to get the value of. /// /// /// /// The value associated with specified frame and frame data key. /// /// /// /// Thrown if the frame is null (IntPtr.Zero). /// /// /// Thrown if the frame is invalid. /// /// /// Thrown if the frame data key is invalid. /// public Int16 GetFrameDataInt16(IntPtr frame, FrameDataKey key) { Int16 value = 0; PluginError error = zvuGetFrameDataI16(frame, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified frame data of type Int32 for the /// specified frame. /// /// /// /// The frame to get frame data from. /// /// /// The frame data key to get the value of. /// /// /// /// The value associated with specified frame and frame data key. /// /// /// /// Thrown if the frame is null (IntPtr.Zero). /// /// /// Thrown if the frame is invalid. /// /// /// Thrown if the frame data key is invalid. /// public Int32 GetFrameDataInt32(IntPtr frame, FrameDataKey key) { Int32 value = 0; PluginError error = zvuGetFrameDataI32(frame, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified frame data of type Int64 for the /// specified frame. /// /// /// /// The frame to get frame data from. /// /// /// The frame data key to get the value of. /// /// /// /// The value associated with specified frame and frame data key. /// /// /// /// Thrown if the frame is null (IntPtr.Zero). /// /// /// Thrown if the frame is invalid. /// /// /// Thrown if the frame data key is invalid. /// public Int64 GetFrameDataInt64(IntPtr frame, FrameDataKey key) { Int64 value = 0; PluginError error = zvuGetFrameDataI64(frame, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified frame data of type byte (UInt8) for the /// specified frame. /// /// /// /// The frame to get frame data from. /// /// /// The frame data key to get the value of. /// /// /// /// The value associated with specified frame and frame data key. /// /// /// /// Thrown if the frame is null (IntPtr.Zero). /// /// /// Thrown if the frame is invalid. /// /// /// Thrown if the frame data key is invalid. /// public byte GetFrameDataUInt8(IntPtr frame, FrameDataKey key) { byte value = 0; PluginError error = zvuGetFrameDataU8(frame, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified frame data of type UInt16 for the /// specified frame. /// /// /// /// The frame to get frame data from. /// /// /// The frame data key to get the value of. /// /// /// /// The value associated with specified frame and frame data key. /// /// /// /// Thrown if the frame is null (IntPtr.Zero). /// /// /// Thrown if the frame is invalid. /// /// /// Thrown if the frame data key is invalid. /// public UInt16 GetFrameDataUInt16(IntPtr frame, FrameDataKey key) { UInt16 value = 0; PluginError error = zvuGetFrameDataU16(frame, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified frame data of type UInt32 for the /// specified frame. /// /// /// /// The frame to get frame data from. /// /// /// The frame data key to get the value of. /// /// /// /// The value associated with specified frame and frame data key. /// /// /// /// Thrown if the frame is null (IntPtr.Zero). /// /// /// Thrown if the frame is invalid. /// /// /// Thrown if the frame data key is invalid. /// public UInt32 GetFrameDataUInt32(IntPtr frame, FrameDataKey key) { UInt32 value = 0; PluginError error = zvuGetFrameDataU32(frame, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified frame data of type UInt64 for the /// specified frame. /// /// /// /// The frame to get frame data from. /// /// /// The frame data key to get the value of. /// /// /// /// The value associated with specified frame and frame data key. /// /// /// /// Thrown if the frame is null (IntPtr.Zero). /// /// /// Thrown if the frame is invalid. /// /// /// Thrown if the frame data key is invalid. /// public UInt64 GetFrameDataUInt64(IntPtr frame, FrameDataKey key) { UInt64 value = 0; PluginError error = zvuGetFrameDataU64(frame, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified frame data of type float for the /// specified frame. /// /// /// /// The frame to get frame data from. /// /// /// The frame data key to get the value of. /// /// /// /// The value associated with specified frame and frame data key. /// /// /// /// Thrown if the frame is null (IntPtr.Zero). /// /// /// Thrown if the frame is invalid. /// /// /// Thrown if the frame data key is invalid. /// public float GetFrameDataFloat(IntPtr frame, FrameDataKey key) { float value = 0; PluginError error = zvuGetFrameDataF32(frame, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified frame data of type double for the /// specified frame. /// /// /// /// The frame to get frame data from. /// /// /// The frame data key to get the value of. /// /// /// /// The value associated with specified frame and frame data key. /// /// /// /// Thrown if the frame is null (IntPtr.Zero). /// /// /// Thrown if the frame is invalid. /// /// /// Thrown if the frame data key is invalid. /// public double GetFrameDataDouble(IntPtr frame, FrameDataKey key) { double value = 0; PluginError error = zvuGetFrameDataF64(frame, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return value; } /// /// Get the value of the specified frame data of type Vector3 for the /// specified frame. /// /// /// /// The frame to get frame data from. /// /// /// The frame data key to get the value of. /// /// /// /// The value associated with specified frame and frame data key. /// /// /// /// Thrown if the frame is null (IntPtr.Zero). /// /// /// Thrown if the frame is invalid. /// /// /// Thrown if the frame data key is invalid. /// public Vector3 GetFrameDataVector3(IntPtr frame, FrameDataKey key) { ZSVector3 value; PluginError error = zvuGetFrameDataV3(frame, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return ZView.Convert(value, true); } /// /// Get the value of the specified frame data of type Matrix4x4 for the /// specified frame. /// /// /// /// The frame to get frame data from. /// /// /// The frame data key to get the value of. /// /// /// /// The value associated with specified frame and frame data key. /// /// /// /// Thrown if the frame is null (IntPtr.Zero). /// /// /// Thrown if the frame is invalid. /// /// /// Thrown if the frame data key is invalid. /// public Matrix4x4 GetFrameDataMatrix4x4(IntPtr frame, FrameDataKey key) { ZSMatrix4 value; PluginError error = zvuGetFrameDataM4(frame, key, out value); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return ZView.Convert(value, true); } /// /// Get the current video recording state of the specified connection. /// /// /// /// The connection to get the video recording state of. /// /// /// /// The video recording state of the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// public VideoRecordingState GetVideoRecordingState(IntPtr connection) { VideoRecordingState state; PluginError error = zvuGetVideoRecordingState(connection, out state); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return state; } /// /// Get the current video recording error code of the specified connection. /// /// /// /// Calling this method will fail unless the current video recording state is /// Error. /// /// /// /// The connection to get the video recording error code of. /// /// /// /// The video recording error code of the specified connection. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the connection does not support the video recording capability. /// /// /// Thrown if the video recording is not in the Error state. /// public PluginError GetVideoRecordingError(IntPtr connection) { PluginError videoRecordingError = PluginError.Unknown; PluginError error = zvuGetVideoRecordingError(connection, out videoRecordingError); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return videoRecordingError; } /// /// Clear the video recording error code of the specified connection. /// /// /// /// Transitions the video recording state of the connection from Error to some /// other non-error state. Exactly which video recording state is transitioned /// to depends on the video recording state that the connection was in prior to /// it entering the Error state. In most cases, this function will transition the /// video recording state to NotRecording. A notable exception is when the /// video recording state of the connection was Saving prior to it entering the /// Error state. In this case, the video recording state may transition back to /// Finished after calling this function if a recoverable save error occurred and /// it is still possible that the current video recording could be saved (e.g. with /// a different file name or after some disk space has been freed). /// /// Calling this function will fail unless the current video recording state is /// Error. /// /// /// /// The connection to clear the video recording error code of. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the connection does not support the video recording capability. /// /// /// Thrown if the video recording is not in the Error state. /// public void ClearVideoRecordingError(IntPtr connection) { PluginError error = zvuClearVideoRecordingError(connection); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Start video recording on the specified connection. /// /// /// /// Transitions the video recording state of the connection to Recording. While the /// video recording state transition is taking place, the video recording state will be /// Starting. /// /// Calling this function will fail unless the current video recording state is /// NotRecording. /// /// /// /// The connection to start video recording on. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the connection does not support the video recording capability. /// /// /// Thrown if the video recording is not in the NotRecording state. /// public void StartVideoRecording(IntPtr connection) { PluginError error = zvuStartVideoRecording(connection); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Finish video recording on the specified connection. /// /// /// /// Transitions the video recording state of the connection to Finished. While /// the video recording state transition is taking place, the video recording state /// will be Finishing. /// /// Calling this function will fail unless the current video recording state is /// Recording or Paused. /// /// /// /// The connection to finish video recording on. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the connection does not support the video recording capability. /// /// /// Thrown if the video recording is not in the Recording or Paused state. /// public void FinishVideoRecording(IntPtr connection) { PluginError error = zvuFinishVideoRecording(connection); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Pause video recording on the specified connection. /// /// /// /// Transitions the video recording state of the connection to Paused. While the /// video recording state transition is taking place, the video recording state will /// be Pausing. /// /// Calling this function will fail unless the current video recording state is /// Recording. /// /// /// /// The connection to pause video recording on. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the connection does not support the video recording capability. /// /// /// Thrown if the video recording is not in the Recording state. /// public void PauseVideoRecording(IntPtr connection) { PluginError error = zvuPauseVideoRecording(connection); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Resume video recording on the specified connection. /// /// /// /// Transitions the video recording state of the connection to Recording. While the /// video recording state transition is taking place, the video recording state will be /// Resuming. /// /// Calling this function will fail unless the current video recording state is /// Paused. /// /// /// /// The connection to resume video recording on. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the connection does not support the video recording capability. /// /// /// Thrown if the video recording is not in the Paused state. /// public void ResumeVideoRecording(IntPtr connection) { PluginError error = zvuResumeVideoRecording(connection); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Begin saving the specified connection's current video recording to the /// specified file name. /// /// /// /// Transitions the video recording state of the connection to Saving. Saving occurs /// asynchronously and the video recording state of the connection will automatically /// transition to NotRecording if saving finishes successfully. If saving fails, then /// the video recording state will automatically transition to Error. /// /// Calling this function will fail unless the current video recording state is /// Finished. /// /// /// /// The connection to save the current video recording of. /// /// /// The file name to save the video recording to. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the connection does not support the video recording capability. /// /// /// Thrown if the video recording is not in the Finished state. /// public void SaveVideoRecording(IntPtr connection, string fileName) { PluginError error = zvuSaveVideoRecording(connection, ZView.StringToNativeUtf8(fileName)); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Begin discarding the specified connection's current video recording. /// /// /// /// Transitions the video recording state of the connection to Discarding. /// Discarding occurs asynchronously and the video recording state of the connection /// will automatically transition to Recording when discarding is finished. /// /// Calling this function will fail unless the current video recording state is /// Finished. /// /// /// /// Transitions the video recording state of the connection to Discarding. /// Discarding occurs asynchronously and the video recording state of the /// connection will automatically transition to NotRecording when discarding is /// finished. /// /// Calling this function will fail unless the current video recording state is /// Finished. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the connection does not support the video recording capability. /// /// /// Thrown if the video recording is not in the Finished state. /// public void DiscardVideoRecording(IntPtr connection) { PluginError error = zvuDiscardVideoRecording(connection); if (error != PluginError.Ok) { throw this.NewPluginException(error); } } /// /// Get the amount of time that has elapsed, in milliseconds, since the /// specified connection's current video recording began. /// /// /// /// The connection to get the current video recording time of. /// /// /// /// The current video recording time of the specified connection, /// in milliseconds. /// /// /// /// Thrown if the connection is null (IntPtr.Zero). /// /// /// Thrown if the connection is invalid. /// /// /// Thrown if the connection is in the Closed or Error state. /// /// /// Thrown if the connection does not support the video recording capability. /// /// /// Thrown if the video recording is in the NotAvailable, NotRecording, Starting, /// Error, or ClearingError state. /// public UInt64 GetVideoRecordingTime(IntPtr connection) { UInt64 timeInMilliseconds = 0; PluginError error = zvuGetVideoRecordingTime(connection, out timeInMilliseconds); if (error != PluginError.Ok) { throw this.NewPluginException(error); } return timeInMilliseconds; } /// /// Set the specified mode's current active virtual camera. /// /// /// /// If null is specified for the virtual camera, the mode's virtual camera /// will be reset to its default implementation. /// /// /// /// The mode to specify the virtual camera. /// /// /// The virtual camera associated with the specified mode. /// public void SetVirtualCamera(IntPtr mode, VirtualCamera virtualCamera) { // If the incoming virtual camera is null, restore the specified // mode's virtual camera to the default. if (virtualCamera == null) { if (!_defaultVirtualCameras.TryGetValue(mode, out virtualCamera)) { Debug.LogError(string.Format("Failed to find default virtual camera for mode: {0}.", mode)); return; } } // Check if the mode is already using the specified virtual camera. VirtualCamera existingVirtualCamera = null; if (_virtualCameras.TryGetValue(mode, out existingVirtualCamera)) { if (virtualCamera == existingVirtualCamera) { // Do nothing. return; } } // If the virtual camera was changed during an active connection, // make sure it is properly set up. IntPtr connection = GlobalState.Instance.Connection; if (connection != IntPtr.Zero) { ConnectionState connectionState = ConnectionState.Error; PluginError error = zvuGetConnectionState(connection, out connectionState); if (error == PluginError.Ok && connectionState == ConnectionState.ModeActive) { IntPtr currentMode = IntPtr.Zero; error = zvuGetConnectionMode(connection, out currentMode); if (error == PluginError.Ok && mode == currentMode) { virtualCamera.TearDown(); virtualCamera.SetUp(this, connection, ModeSetupPhase.Completion); } } } // Cache the mode's specified virtual camera. _virtualCameras[mode] = virtualCamera; } /// /// Get the current active virtual camera associated with the specified mode. /// /// /// /// The mode to get the virtual camera for. /// /// /// /// The current active virtual camera associated with the specified mode. /// public VirtualCamera GetVirtualCamera(IntPtr mode) { VirtualCamera virtualCamera = null; if (!_virtualCameras.TryGetValue(mode, out virtualCamera)) { Debug.LogError(string.Format("Failed to find virtual camera for mode: {0}.", mode)); } return virtualCamera; } /// /// Start ignoring (i.e. not processing) any connections with the /// specified user data. /// /// /// The user data for which to ignore connections for. /// public void RegisterConnectionUserDataToIgnore(IntPtr userData) { _connectionUserDatasToIgnore.Add(userData); } /// /// Stop ignoring (i.e. not processing) any connections with the /// specified user data. /// /// /// The user data for which to no longer ignore connections for. /// public void UnregisterConnectionUserDataToIgnore(IntPtr userData) { _connectionUserDatasToIgnore.Remove(userData); } ////////////////////////////////////////////////////////////////// // Private Methods ////////////////////////////////////////////////////////////////// private void InitializeVirtualCameras() { // Create the default virtual camera for standard mode. GameObject virtualCameraStandardObject = new GameObject("VirtualCameraStandard"); virtualCameraStandardObject.transform.parent = this.transform; VirtualCamera virtualCameraStandard = virtualCameraStandardObject.AddComponent(); _defaultVirtualCameras[GlobalState.Instance.ModeStandard] = virtualCameraStandard; _virtualCameras[GlobalState.Instance.ModeStandard] = virtualCameraStandard; // Create the default virtual camera for AR mode. GameObject virtualCameraARObject = new GameObject("VirtualCameraAR"); virtualCameraARObject.transform.parent = this.transform; VirtualCamera virtualCameraAR = virtualCameraARObject.AddComponent(); _defaultVirtualCameras[GlobalState.Instance.ModeAugmentedReality] = virtualCameraAR; _virtualCameras[GlobalState.Instance.ModeAugmentedReality] = virtualCameraAR; } private void UpdateConnections() { PluginError error = PluginError.Unknown; // Update the context's list of connections. error = zvuUpdateConnectionList(GlobalState.Instance.Context); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to update connection list: ({0})", error)); return; } // Get the number of connections. int numConnections = 0; error = zvuGetNumConnections(GlobalState.Instance.Context, out numConnections); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to get number of connections: ({0})", error)); return; } // Update each available connection. for (int i = 0; i < numConnections; ++i) { // Get a handle to the connection. IntPtr connection = IntPtr.Zero; error = zvuGetConnection(GlobalState.Instance.Context, i, out connection); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to get connection at index {0}: ({1})", i, error)); continue; } this.UpdateConnection(connection); } } private void UpdateConnection(IntPtr connection) { PluginError error = PluginError.Unknown; // Update the connection. error = zvuUpdateConnection(connection); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to update connection: ({0})", error)); return; } // Get the current connection user data. IntPtr connectionUserData = IntPtr.Zero; error = zvuGetConnectionUserData(connection, out connectionUserData); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to get connection user data: ({0})", error)); return; } // Ignore the connection (i.e. do no further processing of it) if // its user data has been registered as user data to ignore. if (_connectionUserDatasToIgnore.Contains(connectionUserData)) { return; } // Get the current connection state. ConnectionState connectionState = ConnectionState.Error; error = zvuGetConnectionState(connection, out connectionState); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to get connection state: ({0})", error)); return; } // Process the connection based on its current state. switch (connectionState) { case ConnectionState.ConnectionInitialization: // Do nothing. break; case ConnectionState.AwaitingConnectionAcceptance: this.HandleAwaitingConnectionAcceptance(connection); break; case ConnectionState.SwitchingModes: // Do nothing. break; case ConnectionState.NoMode: this.UpdateCachedMode(connection); break; case ConnectionState.ModeSetup: this.UpdateCachedMode(connection); this.HandleModeSetup(connection); break; case ConnectionState.ModeActive: this.HandleModeActive(connection); break; case ConnectionState.ModePaused: this.HandleModePaused(connection); break; case ConnectionState.ModeResuming: // Do nothing. break; case ConnectionState.ProcessingModeSettingsChange: // Do nothing. break; case ConnectionState.Closed: this.HandleClosed(connection); break; case ConnectionState.Error: this.HandleError(connection); break; default: break; } // Update the connection's cached connection state. ConnectionInfo connectionInfo = null; if (_connectionInfos.TryGetValue(connection, out connectionInfo)) { if (connectionInfo.ConnectionState == ConnectionState.AwaitingConnectionAcceptance && (connectionState != ConnectionState.AwaitingConnectionAcceptance && connectionState != ConnectionState.Closed && connectionState != ConnectionState.Error)) { // Generate connection accepted event. if (this.ConnectionAccepted != null) { this.ConnectionAccepted(this, connection); } } connectionInfo.ConnectionState = connectionState; } // Update the connection's cached video recording state. this.UpdateCachedVideoRecordingState(connection); // Update the connection's cached video recording quality. if (connectionState != ConnectionState.ConnectionInitialization && connectionState != ConnectionState.Closed && connectionState != ConnectionState.Error) { this.UpdateCachedVideoRecordingQuality(connection); } } private void UpdateCachedMode(IntPtr connection) { IntPtr mode = IntPtr.Zero; PluginError error = zvuGetConnectionMode(connection, out mode); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to get mode: ({0})", error)); return; } // Get the connection's cached info. ConnectionInfo connectionInfo = null; if (!_connectionInfos.TryGetValue(connection, out connectionInfo)) { Debug.LogError("Failed to get cached info for the connection."); return; } // If the mode has changed since the previous frame, generate // the ConnectionModeSwitched event. if (mode != connectionInfo.Mode) { if (this.ConnectionModeSwitched != null) { this.ConnectionModeSwitched(this, connection); } } connectionInfo.Mode = mode; } private void UpdateCachedVideoRecordingState(IntPtr connection) { // Get the connection's latest video recording state. VideoRecordingState videoRecordingState = VideoRecordingState.NotAvailable; PluginError error = zvuGetVideoRecordingState(connection, out videoRecordingState); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to get video recording state: ({0})", error)); return; } // If video recording is not available, early out. if (videoRecordingState == VideoRecordingState.NotAvailable) { // Do nothing. return; } // Get the connection's cached info. ConnectionInfo connectionInfo = null; if (!_connectionInfos.TryGetValue(connection, out connectionInfo)) { Debug.LogError("Failed to get cached info for the connection."); return; } // If the video recording state has changed since the previous // frame, generate the appropriate video recording event. if (videoRecordingState != connectionInfo.VideoRecordingState) { switch (videoRecordingState) { case VideoRecordingState.NotRecording: if (this.VideoRecordingInactive != null) { this.VideoRecordingInactive(this, connection); } break; case VideoRecordingState.Recording: if (this.VideoRecordingActive != null) { this.VideoRecordingActive(this, connection); } break; case VideoRecordingState.Finished: if (this.VideoRecordingFinished != null) { this.VideoRecordingFinished(this, connection); } break; case VideoRecordingState.Paused: if (this.VideoRecordingPaused != null) { this.VideoRecordingPaused(this, connection); } break; case VideoRecordingState.Error: if (this.VideoRecordingError != null) { this.VideoRecordingError(this, connection); } break; default: break; } } connectionInfo.VideoRecordingState = videoRecordingState; } private void UpdateCachedVideoRecordingQuality(IntPtr connection) { // Get the connection's current video recording quality. UInt32 videoRecordingQuality = (UInt32)VideoRecordingQuality.Resolution480p; PluginError error = zvuGetSettingU32(connection, SettingKey.VideoRecordingQuality, out videoRecordingQuality); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to get video recording quality: ({0})", error)); return; } // Get the connection's cached info. ConnectionInfo connectionInfo = null; if (!_connectionInfos.TryGetValue(connection, out connectionInfo)) { Debug.LogError("Failed to get cached info for the connection."); return; } // If the video recording quality has changed since the previous // frame, generate the video recording quality changed event. if ((VideoRecordingQuality)videoRecordingQuality != connectionInfo.VideoRecordingQuality) { if (this.VideoRecordingQualityChanged != null) { this.VideoRecordingQualityChanged(this, connection); } } connectionInfo.VideoRecordingQuality = (VideoRecordingQuality)videoRecordingQuality; } private void HandleAwaitingConnectionAcceptance(IntPtr connection) { PluginError error = PluginError.Unknown; if (GlobalState.Instance.Connection == IntPtr.Zero) { // If there is no current active connection, accept the new incoming connection. error = zvuAcceptConnection(connection); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to accept connection: ({0})", error)); return; } // Cache the accepted connection as the current active connection. GlobalState.Instance.Connection = connection; // Create a new entry in the connection infos dictionary for // the newly accepted connection. _connectionInfos[connection] = new ConnectionInfo(connection); } else { // Ignore all connection requests if there is currently an active connection. error = zvuCloseConnection( connection, ConnectionCloseAction.None, ConnectionCloseReason.ConnectionRejected, ZView.StringToNativeUtf8("Presenter can only support one active connection.")); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to close connection: ({0})", error)); return; } } } private void HandleModeSetup(IntPtr connection) { PluginError error = PluginError.Unknown; // Get the connection's cached info. ConnectionInfo connectionInfo = null; if (!_connectionInfos.TryGetValue(connection, out connectionInfo)) { Debug.LogError("Failed to get cached info for the connection."); return; } // Get the current mode setup phase. ModeSetupPhase modeSetupPhase; bool isAwaitingCompletion; error = zvuGetConnectionModeSetupPhase(connection, out modeSetupPhase, out isAwaitingCompletion); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to get connection mode setup phase: ({0})", error)); return; } if (isAwaitingCompletion) { // Do nothing. return; } // Grab the mode's associated virtual camera. VirtualCamera virtualCamera = this.GetVirtualCamera(connectionInfo.Mode); switch (modeSetupPhase) { case ModeSetupPhase.Initialization: // Handle setup initialization for the mode's associated virtual camera. if (virtualCamera != null) { virtualCamera.TearDown(); virtualCamera.SetUp(this, connection, ModeSetupPhase.Initialization); } // Complete the initialization mode setup phase. error = zvuCompleteModeSetupPhase(connection, ModeSetupPhase.Initialization); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to complete ModeSetupPhase.Initialization: ({0})", error)); return; } break; case ModeSetupPhase.Completion: // Reset the connection's received frame and frame to send. connectionInfo.ReceivedFrame = IntPtr.Zero; connectionInfo.FrameToSend = IntPtr.Zero; // Handle setup completion for the mode's associated virtual camera. if (virtualCamera != null) { virtualCamera.SetUp(this, connection, ModeSetupPhase.Completion); } // Complete the completion mode setup phase. error = zvuCompleteModeSetupPhase(connection, ModeSetupPhase.Completion); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to complete ModeSetupPhase.Completion: ({0})", error)); return; } break; default: break; } } private void HandleModeActive(IntPtr connection) { PluginError error = PluginError.Unknown; // Get the connection's cached info. ConnectionInfo connectionInfo = null; if (!_connectionInfos.TryGetValue(connection, out connectionInfo)) { Debug.LogError("Failed to get cached info for the connection."); return; } // Generate the connection mode paused event if the connection // state transitioned to ModeActive. if (connectionInfo.ConnectionState != ConnectionState.ModeActive) { if (this.ConnectionModeActive != null) { this.ConnectionModeActive(this, connection); } } // Get the mode's associated virtual camera. If no virtual // camera is found, early out since there is nothing to render. VirtualCamera virtualCamera = this.GetVirtualCamera(connectionInfo.Mode); if (virtualCamera == null) { return; } // Check if the application has changed from windowed to full screen // mode (or vice versa) and make sure to reset the current virtual camera. if (Screen.fullScreen != _wasFullScreen) { virtualCamera.TearDown(); virtualCamera.SetUp(this, connection, ModeSetupPhase.Completion); } // Check to make sure there are no received frames from the // previous update that have not been released. if (connectionInfo.ReceivedFrame != IntPtr.Zero) { error = zvuReleaseReceivedFrame(connectionInfo.ReceivedFrame); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to release received frame: ({0})", error)); } connectionInfo.ReceivedFrame = IntPtr.Zero; } // Get the current frame number. UInt64 frameNumber = System.Convert.ToUInt64(Time.frameCount); // Receive the most recent incoming frame (currently only supported // in augmented reality mode). IntPtr receivedFrame = IntPtr.Zero; if (connectionInfo.Mode == GlobalState.Instance.ModeAugmentedReality) { error = zvuReceiveFrame(connection, Stream.Image, out receivedFrame); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to receive frame: ({0})", error)); return; } // Cache the received frame. connectionInfo.ReceivedFrame = receivedFrame; // If there are no frames available to receive, early out. if (connectionInfo.ReceivedFrame == IntPtr.Zero) { return; } // Get the received frame's number. error = zvuGetFrameDataU64(connectionInfo.ReceivedFrame, FrameDataKey.FrameNumber, out frameNumber); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to get the received frame's number: ({0})", error)); } } // Get the next frame to send. IntPtr frameToSend = IntPtr.Zero; error = zvuGetNextFrameToSend(connection, Stream.Image, out frameToSend); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to get next frame to send: ({0})", error)); } // Cache the frame to send. connectionInfo.FrameToSend = frameToSend; // If the frame to send is valid, render the frame. if (connectionInfo.FrameToSend != IntPtr.Zero) { // Set frame data (i.e. frame number). error = zvuSetFrameDataU64(connectionInfo.FrameToSend, FrameDataKey.FrameNumber, frameNumber); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to set the frame number: ({0})", error)); } // Force the virtual camera to render. try { virtualCamera.Render(this, connection, connectionInfo.ReceivedFrame); } catch { Debug.LogError("Failed to render frame."); } // Set the outgoing frame's associated frame information (i.e. native // texture pointer). zvuSetCurrentFrameInfo(connectionInfo.FrameToSend, virtualCamera.GetNativeTexturePtr()); // Notify the native plugin to send the frame data to // the presenter. ZView.IssuePluginEvent(PluginEvent.SendFrame); } // Release the received frame. if (connectionInfo.ReceivedFrame != IntPtr.Zero) { error = zvuReleaseReceivedFrame(connectionInfo.ReceivedFrame); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to release received frame: ({0})", error)); } connectionInfo.ReceivedFrame = IntPtr.Zero; } } private void HandleModePaused(IntPtr connection) { // Get the connection's cached info. ConnectionInfo connectionInfo = null; if (!_connectionInfos.TryGetValue(connection, out connectionInfo)) { Debug.LogError("Failed to get cached info for the connection."); return; } // Generate the connection mode paused event if the connection // state transitioned to ModePaused. if (connectionInfo.ConnectionState != ConnectionState.ModePaused) { if (this.ConnectionModePaused != null) { this.ConnectionModePaused(this, connection); } } } private void HandleClosed(IntPtr connection) { // Generate connection closed event. if (this.ConnectionClosed != null) { this.ConnectionClosed(this, connection); } // Destroy the connection. this.DestroyConnection(connection); } private void HandleError(IntPtr connection) { // Generate connection error event. if (this.ConnectionError != null) { this.ConnectionError(this, connection); } // Destroy the connection. this.DestroyConnection(connection); } /// /// Set up the current mode's virtual camera if there is /// a connection in the ModeActive state. This logic is necessary /// for the purpose of handling scene transitions between two zView-enabled /// scenes while a connection is currently active. /// private void HandleSceneTransition() { IntPtr connection = GlobalState.Instance.Connection; if (connection == IntPtr.Zero) { return; } // Get the current connection state. ConnectionState connectionState = ConnectionState.Error; PluginError error = zvuGetConnectionState(connection, out connectionState); if (error != PluginError.Ok) { return; } // Create and cache connection info for the current connection. ConnectionInfo connectionInfo = new ConnectionInfo(connection); connectionInfo.ConnectionState = connectionState; _connectionInfos[connection] = connectionInfo; // Get the current connection mode if the current connection is // in the ModeActive or ModePaused state. if (connectionState == ConnectionState.ModeActive || connectionState == ConnectionState.ModePaused) { // Update the cached mode info. IntPtr mode = IntPtr.Zero; error = zvuGetConnectionMode(connection, out mode); if (error == PluginError.Ok) { connectionInfo.Mode = mode; } else { Debug.LogError(string.Format("Failed to get mode: ({0})", error)); } // Update the cached video recording state. VideoRecordingState videoRecordingState = VideoRecordingState.NotAvailable; error = zvuGetVideoRecordingState(connection, out videoRecordingState); if (error == PluginError.Ok) { connectionInfo.VideoRecordingState = videoRecordingState; } else { Debug.LogError(string.Format("Failed to get video recording state: ({0})", error)); } // Update the cached video recording quality. UInt32 videoRecordingQuality = (UInt32)VideoRecordingQuality.Resolution480p; error = zvuGetSettingU32(connection, SettingKey.VideoRecordingQuality, out videoRecordingQuality); if (error == PluginError.Ok) { connectionInfo.VideoRecordingQuality = (VideoRecordingQuality)videoRecordingQuality; } else { Debug.LogError(string.Format("Failed to get video recording quality: ({0})", error)); } // Get the virtual camera associated with the current mode. if (connectionInfo.Mode != IntPtr.Zero) { VirtualCamera virtualCamera = this.GetVirtualCamera(connectionInfo.Mode); if (virtualCamera != null) { virtualCamera.TearDown(); virtualCamera.SetUp(this, connection, ModeSetupPhase.Completion); } } } } private void DestroyConnection(IntPtr connection) { if (GlobalState.Instance.Connection == connection) { GlobalState.Instance.Connection = IntPtr.Zero; } // Remove the connection's entry from the connection infos dictionary. if (_connectionInfos.ContainsKey(connection)) { _connectionInfos.Remove(connection); } // Destroy the connection. PluginError error = zvuDestroyConnection(connection); if (error != PluginError.Ok) { Debug.LogError(string.Format("Failed to destroy connection: ({0})", error)); return; } } private static SupportedMode Convert(ZVSupportedMode s) { return new SupportedMode(s.mode, s.modeAvailability); } private static ZVSupportedMode Convert(SupportedMode s) { ZVSupportedMode temp; temp.mode = s.Mode; temp.modeAvailability = s.ModeAvailability; return temp; } private static Vector3 Convert(ZSVector3 v, bool flipHandedness) { return new Vector3(v.x, v.y, flipHandedness ? -v.z : v.z); } private static ZSVector3 Convert(Vector3 v, bool flipHandedness) { ZSVector3 temp; temp.x = v.x; temp.y = v.y; temp.z = flipHandedness ? -v.z : v.z; return temp; } private static Matrix4x4 Convert(ZSMatrix4 m, bool flipHandedness) { Matrix4x4 temp = Matrix4x4.identity; temp[0, 0] = m.m00; temp[0, 1] = m.m01; temp[0, 2] = m.m02; temp[0, 3] = m.m03; temp[1, 0] = m.m10; temp[1, 1] = m.m11; temp[1, 2] = m.m12; temp[1, 3] = m.m13; temp[2, 0] = m.m20; temp[2, 1] = m.m21; temp[2, 2] = m.m22; temp[2, 3] = m.m23; temp[3, 0] = m.m30; temp[3, 1] = m.m31; temp[3, 2] = m.m32; temp[3, 3] = m.m33; if (flipHandedness) { temp = ZView.FlipHandedness(temp); } return temp; } private static ZSMatrix4 Convert(Matrix4x4 m, bool flipHandedness) { if (flipHandedness) { m = ZView.FlipHandedness(m); } ZSMatrix4 temp; temp.m00 = m[0, 0]; temp.m01 = m[0, 1]; temp.m02 = m[0, 2]; temp.m03 = m[0, 3]; temp.m10 = m[1, 0]; temp.m11 = m[1, 1]; temp.m12 = m[1, 2]; temp.m13 = m[1, 3]; temp.m20 = m[2, 0]; temp.m21 = m[2, 1]; temp.m22 = m[2, 2]; temp.m23 = m[2, 3]; temp.m30 = m[3, 0]; temp.m31 = m[3, 1]; temp.m32 = m[3, 2]; temp.m33 = m[3, 3]; return temp; } private static Matrix4x4 FlipHandedness(Matrix4x4 matrix) { return s_flipHandednessMap * matrix * s_flipHandednessMap; } private static byte[] StringToNativeUtf8(string s) { int size = Encoding.UTF8.GetByteCount(s); // Create a buffer with additional room for the terminating // null character (size + 1). byte[] buffer = new byte[size + 1]; Encoding.UTF8.GetBytes(s, 0, s.Length, buffer, 0); return buffer; } private static string NativeUtf8ToString(byte[] b) { if (b.Length < 1) { return string.Empty; } // Make sure to exclude the null terminator at the end // of the native Utf8 string before converting to System.String. return Encoding.UTF8.GetString(b, 0, b.Length - 1); } ////////////////////////////////////////////////////////////////// // Private Compound Types ////////////////////////////////////////////////////////////////// private class ConnectionInfo { public IntPtr Connection { get; private set; } public ConnectionState ConnectionState { get; set; } public IntPtr Mode { get; set; } public IntPtr ReceivedFrame { get; set; } public IntPtr FrameToSend { get; set; } public VideoRecordingState VideoRecordingState { get; set; } public VideoRecordingQuality VideoRecordingQuality { get; set; } public ConnectionInfo(IntPtr connection) { this.Connection = connection; this.ConnectionState = ConnectionState.Error; this.Mode = IntPtr.Zero; this.ReceivedFrame = IntPtr.Zero; this.FrameToSend = IntPtr.Zero; this.VideoRecordingState = VideoRecordingState.NotAvailable; this.VideoRecordingQuality = VideoRecordingQuality.Unknown; } } ////////////////////////////////////////////////////////////////// // Private Members ////////////////////////////////////////////////////////////////// private static readonly Matrix4x4 s_flipHandednessMap = Matrix4x4.Scale(new Vector4(1.0f, 1.0f, -1.0f)); private Dictionary _connectionInfos = new Dictionary(); private Dictionary _defaultVirtualCameras = new Dictionary(); private Dictionary _virtualCameras = new Dictionary(); private HashSet _connectionUserDatasToIgnore = new HashSet(); private bool _wasFullScreen = false; } }