Advertisement
Guest User

Controller.cs

a guest
Jun 23rd, 2019
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 28.44 KB | None | 0 0
  1. /******************************************************************************
  2.  * Copyright (C) Leap Motion, Inc. 2011-2018.                                 *
  3.  * Leap Motion proprietary and confidential.                                  *
  4.  *                                                                            *
  5.  * Use subject to the terms of the Leap Motion SDK Agreement available at     *
  6.  * https://developer.leapmotion.com/sdk_agreement, or another agreement       *
  7.  * between Leap Motion and you, your company or other organization.           *
  8.  ******************************************************************************/
  9.  
  10.  /* Modified
  11.   * by: Zacryon
  12.   * Date: 23.06.2019
  13.   * Notes: Added a delay functionality. Modifications not marked.
  14.   */
  15.  
  16. namespace Leap {
  17.   using System;
  18.   using System.Threading;
  19.     using System.Collections.Concurrent;
  20.     using System.Timers;
  21.     using Timer = System.Timers.Timer;
  22.     using UnityEngine;
  23.   using LeapInternal;
  24.  
  25.   /// <summary>
  26.   /// The Controller class is your main interface to the Leap Motion Controller.
  27.   ///
  28.   /// Create an instance of this Controller class to access frames of tracking
  29.   /// data and configuration information.Frame data can be polled at any time
  30.   /// using the Controller.Frame() function.Call frame() or frame(0) to get the
  31.   /// most recent frame.Set the history parameter to a positive integer to access
  32.   /// previous frames.A controller stores up to 60 frames in its frame history.
  33.   ///
  34.   ///
  35.   /// Polling is an appropriate strategy for applications which already have an
  36.   /// intrinsic update loop, such as a game. You can also subscribe to the FrameReady
  37.   /// event to get tracking frames through an event delegate.
  38.   ///
  39.   /// If the current thread implements a SynchronizationContext that contains a message
  40.   /// loop, events are posted to that threads message loop. Otherwise, events are called
  41.   /// on an independent thread and applications must perform any needed synchronization
  42.   /// or marshalling of data between threads. Note that Unity3D does not create an
  43.   /// appropriate SynchronizationContext object. Typically, event handlers cannot access
  44.   /// any Unity objects.
  45.   ///
  46.   /// @since 1.0
  47.   /// </summary>
  48.   public class Controller :
  49.     IController {
  50.     Connection _connection;
  51.     bool _disposed = false;
  52.     Config _config;
  53.  
  54.         #region Delay attributes
  55.         /// <summary>
  56.         /// These attributes are required for the operation in delay mode.
  57.         /// </summary>
  58.         private bool delayActive = false;
  59.         private double delay;
  60.         private ConcurrentQueue<Frame> frameBuffer;
  61.         private ConcurrentQueue<Timer> timerBuffer;
  62.         private Frame delayedFrame;
  63.         #endregion
  64.  
  65.         /// <summary>
  66.         /// The SynchronizationContext used for dispatching events.
  67.         ///
  68.         /// By default the synchronization context of the thread creating the controller
  69.         /// instance is used. You can change the context if desired.
  70.         /// </summary>
  71.         public SynchronizationContext EventContext {
  72.       get {
  73.         return _connection.EventContext;
  74.       }
  75.       set {
  76.         _connection.EventContext = value;
  77.       }
  78.     }
  79.  
  80.     /// <summary>
  81.     /// Dispatched when the connection is initialized (but not necessarily connected).
  82.     ///
  83.     /// Can be dispatched more than once, if connection is restarted.
  84.     /// @since 3.0
  85.     /// </summary>
  86.     public event EventHandler<LeapEventArgs> Init {
  87.       add {
  88.         if (_hasInitialized)
  89.           value(this, new LeapEventArgs(LeapEvent.EVENT_INIT));
  90.         _init += value;
  91.       }
  92.       remove { _init -= value; }
  93.     }
  94.  
  95.     private bool _hasInitialized = false;
  96.     private EventHandler<LeapEventArgs> _init;
  97.  
  98.     /// <summary>
  99.     /// Dispatched when the connection to the service is established.
  100.     /// @since 3.0
  101.     /// </summary>
  102.     public event EventHandler<ConnectionEventArgs> Connect {
  103.       add {
  104.         if (_hasConnected)
  105.           value(this, new ConnectionEventArgs());
  106.         _connect += value;
  107.       }
  108.       remove { _connect -= value; }
  109.     }
  110.  
  111.     private bool _hasConnected = false;
  112.     private EventHandler<ConnectionEventArgs> _connect;
  113.  
  114.     /// <summary>
  115.     /// Dispatched if the connection to the service is lost.
  116.     /// @since 3.0
  117.     /// </summary>
  118.     public event EventHandler<ConnectionLostEventArgs> Disconnect {
  119.       add {
  120.         _connection.LeapConnectionLost += value;
  121.       }
  122.       remove {
  123.         _connection.LeapConnectionLost -= value;
  124.       }
  125.     }
  126.  
  127.     /// <summary>
  128.     /// Dispatched when a tracking frame is ready.
  129.     /// @since 3.0
  130.     /// </summary>
  131.     public event EventHandler<FrameEventArgs> FrameReady {
  132.       add {
  133.         _connection.LeapFrame += value;
  134.       }
  135.       remove {
  136.         _connection.LeapFrame -= value;
  137.       }
  138.     }
  139.  
  140.     /// <summary>
  141.     /// Dispatched when an internal tracking frame is ready.
  142.     /// @since 3.0
  143.     /// </summary>
  144.     public event EventHandler<InternalFrameEventArgs> InternalFrameReady {
  145.       add {
  146.         _connection.LeapInternalFrame += value;
  147.       }
  148.       remove {
  149.         _connection.LeapInternalFrame -= value;
  150.       }
  151.     }
  152.  
  153.     /// <summary>
  154.     /// Dispatched when a Leap Motion device is connected.
  155.     /// @since 3.0
  156.     /// </summary>
  157.     public event EventHandler<DeviceEventArgs> Device {
  158.       add {
  159.         _connection.LeapDevice += value;
  160.       }
  161.       remove {
  162.         _connection.LeapDevice -= value;
  163.       }
  164.     }
  165.  
  166.     /// <summary>
  167.     /// Dispatched when a Leap Motion device is disconnected.
  168.     /// @since 3.0
  169.     /// </summary>
  170.     public event EventHandler<DeviceEventArgs> DeviceLost {
  171.       add {
  172.         _connection.LeapDeviceLost += value;
  173.       }
  174.       remove {
  175.         _connection.LeapDeviceLost -= value;
  176.       }
  177.     }
  178.  
  179.     /// <summary>
  180.     /// Dispatched when a Leap device fails to initialize.
  181.     /// @since 3.0
  182.     /// </summary>
  183.     public event EventHandler<DeviceFailureEventArgs> DeviceFailure {
  184.       add {
  185.         _connection.LeapDeviceFailure += value;
  186.       }
  187.       remove {
  188.         _connection.LeapDeviceFailure -= value;
  189.       }
  190.     }
  191.  
  192.     /// <summary>
  193.     /// Dispatched when the system generates a loggable event.
  194.     /// @since 3.0
  195.     /// </summary>
  196.     public event EventHandler<LogEventArgs> LogMessage {
  197.       add {
  198.         _connection.LeapLogEvent += value;
  199.       }
  200.       remove {
  201.         _connection.LeapLogEvent -= value;
  202.       }
  203.     }
  204.  
  205.     /// <summary>
  206.     /// Dispatched when a policy changes.
  207.     /// @since 3.0
  208.     /// </summary>
  209.     public event EventHandler<PolicyEventArgs> PolicyChange {
  210.       add {
  211.         _connection.LeapPolicyChange += value;
  212.       }
  213.       remove {
  214.         _connection.LeapPolicyChange -= value;
  215.       }
  216.     }
  217.  
  218.     /// <summary>
  219.     /// Dispatched when a configuration setting changes.
  220.     /// @since 3.0
  221.     /// </summary>
  222.     public event EventHandler<ConfigChangeEventArgs> ConfigChange {
  223.       add {
  224.         _connection.LeapConfigChange += value;
  225.       }
  226.       remove {
  227.         _connection.LeapConfigChange -= value;
  228.       }
  229.     }
  230.  
  231.     /// <summary>
  232.     /// Dispatched when the image distortion map changes.
  233.     /// The distortion map can change when the Leap device switches orientation,
  234.     /// or a new device becomes active.
  235.     /// @since 3.0
  236.     /// </summary>
  237.     public event EventHandler<DistortionEventArgs> DistortionChange {
  238.       add {
  239.         _connection.LeapDistortionChange += value;
  240.       }
  241.       remove {
  242.         _connection.LeapDistortionChange -= value;
  243.       }
  244.     }
  245.  
  246.     /// <summary>
  247.     /// Dispatched when the service drops a tracking frame.
  248.     /// </summary>
  249.     public event EventHandler<DroppedFrameEventArgs> DroppedFrame {
  250.       add {
  251.         _connection.LeapDroppedFrame += value;
  252.       }
  253.       remove {
  254.         _connection.LeapDroppedFrame -= value;
  255.       }
  256.     }
  257.  
  258.     /// <summary>
  259.     /// Dispatched when an unrequested image is ready.
  260.     /// @since 4.0
  261.     /// </summary>
  262.     public event EventHandler<ImageEventArgs> ImageReady {
  263.       add {
  264.         _connection.LeapImage += value;
  265.       }
  266.       remove {
  267.         _connection.LeapImage -= value;
  268.       }
  269.     }
  270.  
  271.     /// <summary>
  272.     /// Dispatched whenever a thread wants to start profiling for a custom thread.
  273.     /// The event is always dispatched from the thread itself.
  274.     ///
  275.     /// The event data will contain the name of the thread, as well as an array of
  276.     /// all possible profiling blocks that could be entered on that thread.
  277.     ///
  278.     /// @since 4.0
  279.     /// </summary>
  280.     public event Action<BeginProfilingForThreadArgs> BeginProfilingForThread {
  281.       add {
  282.         _connection.LeapBeginProfilingForThread += value;
  283.       }
  284.       remove {
  285.         _connection.LeapBeginProfilingForThread -= value;
  286.       }
  287.     }
  288.  
  289.     /// <summary>
  290.     /// Dispatched whenever a thread is finished profiling.  The event is always
  291.     /// dispatched from the thread itself.
  292.     ///
  293.     /// @since 4.0
  294.     /// </summary>
  295.     public event Action<EndProfilingForThreadArgs> EndProfilingForThread {
  296.       add {
  297.         _connection.LeapEndProfilingForThread += value;
  298.       }
  299.       remove {
  300.         _connection.LeapEndProfilingForThread -= value;
  301.       }
  302.     }
  303.  
  304.     /// <summary>
  305.     /// Dispatched whenever a thread enters a profiling block.  The event is always
  306.     /// dispatched from the thread itself.
  307.     ///
  308.     /// The event data will contain the name of the profiling block.
  309.     ///
  310.     /// @since 4.0
  311.     /// </summary>
  312.     public event Action<BeginProfilingBlockArgs> BeginProfilingBlock {
  313.       add {
  314.         _connection.LeapBeginProfilingBlock += value;
  315.       }
  316.       remove {
  317.         _connection.LeapBeginProfilingBlock -= value;
  318.       }
  319.     }
  320.  
  321.     /// <summary>
  322.     /// Dispatched whenever a thread ends a profiling block.  The event is always
  323.     /// dispatched from the thread itself.
  324.     ///
  325.     /// The event data will contain the name of the profiling block.
  326.     ///
  327.     /// @since 4.0
  328.     /// </summary>
  329.     public event Action<EndProfilingBlockArgs> EndProfilingBlock {
  330.       add {
  331.         _connection.LeapEndProfilingBlock += value;
  332.       }
  333.       remove {
  334.         _connection.LeapEndProfilingBlock -= value;
  335.       }
  336.     }
  337.  
  338.     /// <summary>
  339.     /// Dispatched when point mapping change events are generated by the service.
  340.     /// @since 4.0
  341.     /// </summary>
  342.     public event EventHandler<PointMappingChangeEventArgs> PointMappingChange {
  343.       add {
  344.         _connection.LeapPointMappingChange += value;
  345.       }
  346.       remove {
  347.         _connection.LeapPointMappingChange -= value;
  348.       }
  349.     }
  350.  
  351.     /// <summary>
  352.     /// Dispatched when a new HeadPose is available.
  353.     /// </summary>
  354.     public event EventHandler<HeadPoseEventArgs> HeadPoseChange {
  355.       add {
  356.         _connection.LeapHeadPoseChange += value;
  357.       }
  358.       remove {
  359.         _connection.LeapHeadPoseChange -= value;
  360.       }
  361.     }
  362.  
  363.         #region Additional delay methods
  364.         /// <summary>
  365.         /// Enables or disables the delay mode depending on the parameter value.
  366.         /// </summary>
  367.         /// <param name="delayEnable">Enables delay mode if set to true. Otherwise disables delay mode.</param>
  368.         public void SetDelayActive(bool delayEnable)
  369.         {
  370.             delayActive = delayEnable;
  371.             if (!delayActive)
  372.                 delayedFrame = null;
  373.         }
  374.         /// <summary>
  375.         /// Event handler for elapsed timer events. Here the delayed frame is set to the first frame in the queue.
  376.         /// Also disposes used timers.
  377.         /// </summary>
  378.         protected void FrameTimerElapsedHandler(System.Object sender, EventArgs evtArgs)
  379.         {
  380.             if (delayedFrame == null)
  381.                 delayedFrame = new Frame();
  382.  
  383.             Frame timerElapsedTmpFrame;
  384.             if (frameBuffer.TryDequeue(out timerElapsedTmpFrame))
  385.                     delayedFrame.CopyFrom(timerElapsedTmpFrame);
  386.  
  387.             Timer tmpTimer;
  388.             if (timerBuffer.TryDequeue(out tmpTimer))
  389.             {
  390.                 tmpTimer.Elapsed -= FrameTimerElapsedHandler;
  391.                 tmpTimer.Dispose();
  392.             }
  393.         }
  394.         #endregion
  395.  
  396.         public void Dispose() {
  397.       Dispose(true);
  398.       GC.SuppressFinalize(this);
  399.     }
  400.  
  401.     // Protected implementation of Dispose pattern.
  402.     protected virtual void Dispose(bool disposing) {
  403.       if (_disposed) {
  404.         return;
  405.       }
  406.  
  407.       _disposed = true;
  408.     }
  409.  
  410.     /// <summary>
  411.     /// Constructs a Controller object.
  412.     ///
  413.     /// The default constructor uses a connection key of 0.
  414.     ///
  415.     /// @since 1.0
  416.     ///
  417.     /// By default the delay mode is disabled. It can be set from the moment of construction on.
  418.     /// Furthermore the delay time can be set. Otherwise it defaults to 350 milliseconds.
  419.     /// </summary>
  420.     public Controller(bool delayEnabled = false, double delayInMs = 350) : this(0)
  421.     {
  422.             delayActive = delayEnabled;
  423.             delay = delayInMs;
  424.             frameBuffer = new ConcurrentQueue<Frame>();
  425.             timerBuffer = new ConcurrentQueue<Timer>();
  426.             delayedFrame = null;
  427.     }
  428.     /// <summary>
  429.     /// Constructs a Controller object using the specified connection key.
  430.     ///
  431.     /// All controller instances using the same key will use the same connection
  432.     /// to the service. In general, an application should not use more than one connection
  433.     /// for all its controllers. Each connection keeps its own cache of frames and images.
  434.     ///
  435.     /// @param connectionKey An identifier specifying the connection to use. If a
  436.     /// connection with the specified key already exists, that connection is used.
  437.     /// Otherwise, a new connection is created.
  438.     /// @since 3.0
  439.     /// </summary>
  440.     public Controller(int connectionKey) {
  441.       _connection = Connection.GetConnection(connectionKey);
  442.       _connection.EventContext = SynchronizationContext.Current;
  443.  
  444.       _connection.LeapInit += OnInit;
  445.       _connection.LeapConnection += OnConnect;
  446.       _connection.LeapConnectionLost += OnDisconnect;
  447.  
  448.       _connection.Start();
  449.     }
  450.  
  451.     /// <summary>
  452.     /// Starts the connection.
  453.     ///
  454.     /// A connection starts automatically when created, but you can
  455.     /// use this function to restart the connection after stopping it.
  456.     ///
  457.     /// @since 3.0
  458.     /// </summary>
  459.     public void StartConnection() {
  460.       _connection.Start();
  461.     }
  462.  
  463.     /// <summary>
  464.     /// Stops the connection.
  465.     ///
  466.     /// No more frames or other events are received from a stopped connection. You can
  467.     /// restart with StartConnection().
  468.     ///
  469.     /// @since 3.0
  470.     /// </summary>
  471.     public void StopConnection() {
  472.       _connection.Stop();
  473.     }
  474.  
  475.     /// <summary>
  476.     /// Reports whether your application has a connection to the Leap Motion
  477.     /// daemon/service. Can be true even if the Leap Motion hardware is not available.
  478.     /// @since 1.2
  479.     /// </summary>
  480.     public bool IsServiceConnected {
  481.       get {
  482.         return _connection.IsServiceConnected;
  483.       }
  484.     }
  485.  
  486.     /// <summary>
  487.     /// Requests setting a policy.
  488.     ///  
  489.     /// A request to change a policy is subject to user approval and a policy
  490.     /// can be changed by the user at any time (using the Leap Motion settings dialog).
  491.     /// The desired policy flags must be set every time an application runs.
  492.     ///  
  493.     /// Policy changes are completed asynchronously and, because they are subject
  494.     /// to user approval or system compatibility checks, may not complete successfully. Call
  495.     /// Controller.IsPolicySet() after a suitable interval to test whether
  496.     /// the change was accepted.
  497.     /// @since 2.1.6
  498.     /// </summary>
  499.     public void SetPolicy(PolicyFlag policy) {
  500.       _connection.SetPolicy(policy);
  501.     }
  502.  
  503.     /// <summary>
  504.     /// Requests clearing a policy.
  505.     ///
  506.     /// Policy changes are completed asynchronously and, because they are subject
  507.     /// to user approval or system compatibility checks, may not complete successfully. Call
  508.     /// Controller.IsPolicySet() after a suitable interval to test whether
  509.     /// the change was accepted.
  510.     /// @since 2.1.6
  511.     /// </summary>
  512.     public void ClearPolicy(PolicyFlag policy) {
  513.       _connection.ClearPolicy(policy);
  514.     }
  515.  
  516.     /// <summary>
  517.     /// Gets the active setting for a specific policy.
  518.     ///
  519.     /// Keep in mind that setting a policy flag is asynchronous, so changes are
  520.     /// not effective immediately after calling setPolicyFlag(). In addition, a
  521.     /// policy request can be declined by the user. You should always set the
  522.     /// policy flags required by your application at startup and check that the
  523.     /// policy change request was successful after an appropriate interval.
  524.     ///
  525.     /// If the controller object is not connected to the Leap Motion software, then the default
  526.     /// state for the selected policy is returned.
  527.     ///
  528.     /// @since 2.1.6
  529.     /// </summary>
  530.     public bool IsPolicySet(PolicyFlag policy) {
  531.       return _connection.IsPolicySet(policy);
  532.     }
  533.        
  534.         /// <summary>
  535.         /// In most cases you should get Frame objects using the LeapProvider.CurrentFrame
  536.         /// property. The data in Frame objects taken directly from a Leap.Controller instance
  537.         /// is still in the Leap Motion frame of reference and will not match the hands
  538.         /// displayed in a Unity scene.
  539.         ///
  540.         /// Returns a frame of tracking data from the Leap Motion software. Use the optional
  541.         /// history parameter to specify which frame to retrieve. Call frame() or
  542.         /// frame(0) to access the most recent frame; call frame(1) to access the
  543.         /// previous frame, and so on. If you use a history value greater than the
  544.         /// number of stored frames, then the controller returns an empty frame.
  545.         ///
  546.         /// @param history The age of the frame to return, counting backwards from
  547.         /// the most recent frame (0) into the past and up to the maximum age (59).
  548.         /// @returns The specified frame; or, if no history parameter is specified,
  549.         /// the newest frame. If a frame is not available at the specified history
  550.         /// position, an invalid Frame is returned.
  551.         /// @since 1.0
  552.         /// </summary>
  553.         public Frame Frame(int history = 0)
  554.         {
  555.                 Frame frame = new Frame();
  556.                 Frame(frame, history);
  557.                 return frame;
  558.         }
  559.  
  560.         /// <summary>
  561.         /// Identical to Frame(history) but instead of constructing a new frame and returning
  562.         /// it, the user provides a frame object to be filled with data instead.
  563.         /// If a delay mode is activated, the frames will be filled to the object after a given delay.
  564.         /// Until the first delay timer elapses frames will be filled to the object without delay.
  565.         /// </summary>
  566.         public void Frame(Frame toFill, int history = 0)
  567.         {
  568.             if (!delayActive)
  569.             {
  570.                 LEAP_TRACKING_EVENT trackingEvent;
  571.                 _connection.Frames.Get(out trackingEvent, history);
  572.                 toFill.CopyFrom(ref trackingEvent);
  573.             }
  574.             else
  575.             {
  576.                 LEAP_TRACKING_EVENT trackingEvent;
  577.                 _connection.Frames.Get(out trackingEvent, history);
  578.  
  579.                 if (delayedFrame != null)
  580.                     toFill.CopyFrom(delayedFrame);
  581.                 else
  582.                     toFill.CopyFrom(ref trackingEvent);
  583.  
  584.                 frameBuffer.Enqueue(new Frame().CopyFrom(ref trackingEvent));
  585.                 Timer delayTimerFrame = new Timer(delay);
  586.                 delayTimerFrame.Elapsed += FrameTimerElapsedHandler;
  587.                 delayTimerFrame.AutoReset = false;
  588.                 delayTimerFrame.Start();
  589.                 timerBuffer.Enqueue(delayTimerFrame);
  590.             }
  591.         }
  592.  
  593.         /// <summary>
  594.         /// Returns the timestamp of a recent tracking frame.  Use the
  595.         /// optional history parameter to specify how many frames in the past
  596.         /// to retrieve the timestamp.  Leave the history parameter as
  597.         /// it's default value to return the timestamp of the most recent
  598.         /// tracked frame.
  599.         /// </summary>
  600.         public long FrameTimestamp(int history = 0) {
  601.       LEAP_TRACKING_EVENT trackingEvent;
  602.       _connection.Frames.Get(out trackingEvent, history);
  603.       return trackingEvent.info.timestamp;
  604.     }
  605.  
  606.     /// <summary>
  607.     /// Returns the frame object with all hands transformed by the specified
  608.     /// transform matrix.
  609.     /// </summary>
  610.     public Frame GetTransformedFrame(LeapTransform trs, int history = 0) {
  611.       return new Frame().CopyFrom(Frame(history)).Transform(trs);
  612.     }
  613.  
  614.     /// <summary>
  615.     /// Returns the Frame at the specified time, interpolating the data between existing frames, if necessary.
  616.     /// </summary>
  617.     public Frame GetInterpolatedFrame(Int64 time) {
  618.       return _connection.GetInterpolatedFrame(time);
  619.     }
  620.  
  621.     /// <summary>
  622.     /// Fills the Frame with data taken at the specified time, interpolating the data between existing frames, if necessary.
  623.     /// </summary>
  624.     public void GetInterpolatedFrame(Frame toFill, Int64 time) {
  625.       _connection.GetInterpolatedFrame(toFill, time);
  626.     }
  627.  
  628.     /// <summary>
  629.     /// Returns the Head pose at the specified time, interpolating the data between existing frames, if necessary.
  630.     /// </summary>
  631.     public LEAP_HEAD_POSE_EVENT GetInterpolatedHeadPose(Int64 time) {
  632.       return _connection.GetInterpolatedHeadPose(time);
  633.     }
  634.  
  635.     public void GetInterpolatedHeadPose(ref LEAP_HEAD_POSE_EVENT toFill, Int64 time) {
  636.       _connection.GetInterpolatedHeadPose(ref toFill, time);
  637.     }
  638.  
  639.     public void TelemetryProfiling(ref LEAP_TELEMETRY_DATA telemetryData) {
  640.       _connection.TelemetryProfiling(ref telemetryData);
  641.     }
  642.  
  643.     public UInt64 TelemetryGetNow() {
  644.       return LeapC.TelemetryGetNow();
  645.     }
  646.  
  647.     public void GetPointMapping(ref PointMapping pointMapping) {
  648.       _connection.GetPointMapping(ref pointMapping);
  649.     }
  650.  
  651.     /// <summary>
  652.     /// This is a special variant of GetInterpolatedFrameFromTime, for use with special
  653.     /// features that only require the position and orientation of the palm positions, and do
  654.     /// not care about pose data or any other data.
  655.     ///
  656.     /// You must specify the id of the hand that you wish to get a transform for.  If you specify
  657.     /// an id that is not present in the interpolated frame, the output transform will be the
  658.     /// identity transform.
  659.     /// </summary>
  660.     public void GetInterpolatedLeftRightTransform(Int64 time,
  661.                                                   Int64 sourceTime,
  662.                                                   int leftId,
  663.                                                   int rightId,
  664.                                               out LeapTransform leftTransform,
  665.                                               out LeapTransform rightTransform) {
  666.       _connection.GetInterpolatedLeftRightTransform(time, sourceTime, leftId, rightId, out leftTransform, out rightTransform);
  667.     }
  668.  
  669.     public void GetInterpolatedFrameFromTime(Frame toFill, Int64 time, Int64 sourceTime) {
  670.       _connection.GetInterpolatedFrameFromTime(toFill, time, sourceTime);
  671.     }
  672.  
  673.     /// <summary>
  674.     /// Returns a timestamp value as close as possible to the current time.
  675.     /// Values are in microseconds, as with all the other timestamp values.
  676.     ///
  677.     /// @since 2.2.7
  678.     /// </summary>
  679.     public long Now() {
  680.       return LeapC.GetNow();
  681.     }
  682.  
  683.     /// <summary>
  684.     /// Reports whether this Controller is connected to the Leap Motion service and
  685.     /// the Leap Motion hardware is plugged in.
  686.     ///
  687.     /// When you first create a Controller object, isConnected() returns false.
  688.     /// After the controller finishes initializing and connects to the Leap Motion
  689.     /// software and if the Leap Motion hardware is plugged in, isConnected() returns true.
  690.     ///
  691.     /// You can either handle the onConnect event using a Listener instance or
  692.     /// poll the isConnected() function if you need to wait for your
  693.     /// application to be connected to the Leap Motion software before performing some other
  694.     /// operation.
  695.     ///
  696.     /// @since 1.0
  697.     /// </summary>
  698.     public bool IsConnected {
  699.       get {
  700.         return IsServiceConnected && Devices.Count > 0;
  701.       }
  702.     }
  703.  
  704.     /// <summary>
  705.     /// Returns a Config object, which you can use to query the Leap Motion system for
  706.     /// configuration information.
  707.     ///
  708.     /// @since 1.0
  709.     /// </summary>
  710.     public Config Config {
  711.       get {
  712.         if (_config == null)
  713.           _config = new Config(this._connection.ConnectionKey);
  714.         return _config;
  715.       }
  716.     }
  717.  
  718.     /// <summary>
  719.     /// The list of currently attached and recognized Leap Motion controller devices.
  720.     ///
  721.     /// The Device objects in the list describe information such as the range and
  722.     /// tracking volume.
  723.     ///
  724.     /// Currently, the Leap Motion Controller only allows a single active device at a time,
  725.     /// however there may be multiple devices physically attached and listed here.  Any active
  726.     /// device(s) are guaranteed to be listed first, however order is not determined beyond that.
  727.     ///
  728.     /// @since 1.0
  729.     /// </summary>
  730.     public DeviceList Devices {
  731.       get {
  732.         return _connection.Devices;
  733.       }
  734.     }
  735.  
  736.     /// <summary>
  737.     /// A list of any Leap Motion hardware devices that are physically connected to
  738.     /// the client computer, but are not functioning correctly. The list contains
  739.     /// FailedDevice objects containing the pnpID and the reason for failure. No
  740.     /// other device information is available.
  741.     ///
  742.     /// @since 3.0
  743.     /// </summary>
  744.     public FailedDeviceList FailedDevices() {
  745.       return _connection.FailedDevices;
  746.     }
  747.  
  748.     /// <summary>
  749.     /// The supported controller policies.
  750.     ///
  751.     /// The supported policy flags are:
  752.     ///
  753.     /// **POLICY_BACKGROUND_FRAMES** -- requests that your application receives frames
  754.     ///   when it is not the foreground application for user input.
  755.     ///
  756.     ///   The background frames policy determines whether an application
  757.     ///   receives frames of tracking data while in the background. By
  758.     ///   default, the Leap Motion  software only sends tracking data to the foreground application.
  759.     ///   Only applications that need this ability should request the background
  760.     ///   frames policy. The "Allow Background Apps" checkbox must be enabled in the
  761.     ///   Leap Motion Control Panel or this policy will be denied.
  762.     ///
  763.     /// **POLICY_OPTIMIZE_HMD** -- request that the tracking be optimized for head-mounted
  764.     ///   tracking.
  765.     ///
  766.     ///   The optimize HMD policy improves tracking in situations where the Leap
  767.     ///   Motion hardware is attached to a head-mounted display. This policy is
  768.     ///   not granted for devices that cannot be mounted to an HMD, such as
  769.     ///   Leap Motion controllers embedded in a laptop or keyboard.
  770.     ///
  771.     /// Some policies can be denied if the user has disabled the feature on
  772.     /// their Leap Motion control panel.
  773.     ///
  774.     /// @since 1.0
  775.     /// </summary>
  776.     public enum PolicyFlag {
  777.       /// <summary>
  778.       /// The default policy.
  779.       /// </summary>
  780.       POLICY_DEFAULT = 0,
  781.       /// <summary>
  782.       /// Receive background frames.
  783.       /// </summary>
  784.       POLICY_BACKGROUND_FRAMES = (1 << 0),
  785.       /// <summary>
  786.       /// Allow streaming images.
  787.       /// </summary>
  788.       POLICY_IMAGES = (1 << 1),
  789.       /// <summary>
  790.       /// Optimize the tracking for head-mounted device.
  791.       /// </summary>
  792.       POLICY_OPTIMIZE_HMD = (1 << 2),
  793.       /// <summary>
  794.       /// Allow pausing and unpausing of the Leap Motion service.
  795.       /// </summary>
  796.       POLICY_ALLOW_PAUSE_RESUME = (1 << 3),
  797.       /// <summary>
  798.       /// Allow streaming map point
  799.       /// </summary>
  800.       POLICY_MAP_POINTS = (1 << 7),
  801.     }
  802.  
  803.     protected virtual void OnInit(object sender, LeapEventArgs eventArgs) {
  804.       _hasInitialized = true;
  805.     }
  806.  
  807.     protected virtual void OnConnect(object sender, ConnectionEventArgs eventArgs) {
  808.       _hasConnected = true;
  809.     }
  810.  
  811.     protected virtual void OnDisconnect(object sender, ConnectionLostEventArgs eventArgs) {
  812.       _hasInitialized = false;
  813.       _hasConnected = false;
  814.     }
  815.   }
  816. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement