11using System.Collections.
Generic;
14using System.Text.RegularExpressions;
23 internal const float INTERACTION_VOLUME_MODEL_IMPORT_SCALE_FACTOR = 0.001f;
30 private const float LMC_BOX_RADIUS = 0.45f;
31 private const float LMC_BOX_WIDTH = 0.965f;
32 private const float LMC_BOX_DEPTH = 0.6671f;
34 private Mesh _stereoIR170InteractionZoneMesh;
35 private Material _stereoIR170InteractionMaterial;
36 private readonly Vector3 _stereoIR170InteractionZoneMeshOffset =
new Vector3(0.0523f, 0, 0.005f);
46 ParseStereoIR170InteractionMeshData();
52 "_physicsExtrapolation",
53 "_physicsExtrapolationTime");
57 "_physicsExtrapolationTime");
69 private void frameOptimizationWarning(SerializedProperty property) {
75 warningText =
"Reusing update frames for physics introduces a frame of latency "
76 +
"for physics interactions.";
79 warningText =
"This optimization REQUIRES physics framerate to match your "
80 +
"target framerate EXACTLY.";
86 EditorGUILayout.HelpBox(warningText, MessageType.Warning);
91#if UNITY_2019_3_OR_NEWER
95 EditorGUILayout.HelpBox(
96 "VR support is enabled. If your Leap is mounted to your headset, you should be "
97 +
"using LeapXRServiceProvider instead of LeapServiceProvider. (If your Leap "
98 +
"is not mounted to your headset, you can safely ignore this warning.)",
103 base.OnInspectorGUI();
108 switch (GetSelectedInteractionVolume()) {
112 DrawLeapMotionControllerInteractionZone(LMC_BOX_WIDTH, LMC_BOX_DEPTH, LMC_BOX_RADIUS,
Color.white);
115 DrawStereoIR170InteractionZoneMesh();
118 DetectConnectedDevice();
126 private void ParseStereoIR170InteractionMeshData() {
128 if (_stereoIR170InteractionZoneMesh ==
null) {
129 _stereoIR170InteractionZoneMesh = (Mesh)AssetDatabase.LoadAssetAtPath(Path.Combine(
"Assets",
"Plugins",
"LeapMotion",
"Core",
"Models",
"StereoIR170-interaction-cone.obj"), typeof(Mesh));
132 if (_stereoIR170InteractionMaterial ==
null) {
133 _stereoIR170InteractionMaterial = (Material)AssetDatabase.LoadAssetAtPath(Path.Combine(
"Assets",
"Plugins",
"LeapMotion",
"Core",
"Materials",
"StereoIR170InteractionVolume.mat"), typeof(Material));
141 if (this._leapServiceProvider !=
null) {
142 return this._leapServiceProvider;
147 return this._leapServiceProvider;
155 if (this._leapController !=
null) {
156 return this._leapController;
162 if (this._leapController !=
null) {
163 this._leapController.
Device += _leapController_DeviceChanged;
164 this._leapController.
DeviceLost += _leapController_DeviceChanged;
167 return this._leapController;
172 private void _leapController_DeviceChanged(
object sender,
DeviceEventArgs e) {
173 EditorWindow view = EditorWindow.GetWindow<SceneView>();
177 private void DetectConnectedDevice() {
179 if (LeapController?.Devices?.Count == 1)
182 DrawStereoIR170InteractionZoneMesh();
185 DrawLeapMotionControllerInteractionZone(LMC_BOX_WIDTH, LMC_BOX_DEPTH, LMC_BOX_RADIUS,
Color.white);
195 private void DrawStereoIR170InteractionZoneMesh() {
197 if (_stereoIR170InteractionMaterial !=
null && _stereoIR170InteractionZoneMesh !=
null) {
198 _stereoIR170InteractionMaterial.SetPass(0);
200 Graphics.DrawMeshNow(_stereoIR170InteractionZoneMesh,
201 target.transform.localToWorldMatrix *
206 private void DrawLeapMotionControllerInteractionZone(
float box_width,
float box_depth,
float box_radius,
Color interactionZoneColor) {
208 Color previousColor = Handles.color;
209 Handles.color = interactionZoneColor;
212 Vector3 local_top_left, top_left, local_top_right, top_right, local_bottom_left, bottom_left, local_bottom_right, bottom_right;
213 getLocalGlobalPoint(-1, 1, 1, box_width, box_depth, box_radius, out local_top_left , out top_left);
214 getLocalGlobalPoint( 1, 1, 1, box_width, box_depth, box_radius, out local_top_right , out top_right);
215 getLocalGlobalPoint(-1, 1, -1, box_width, box_depth, box_radius, out local_bottom_left , out bottom_left);
216 getLocalGlobalPoint( 1, 1, -1, box_width, box_depth, box_radius, out local_bottom_right, out bottom_right);
218 Handles.DrawAAPolyLine(origin, top_left);
219 Handles.DrawAAPolyLine(origin, top_right);
220 Handles.DrawAAPolyLine(origin, bottom_left);
221 Handles.DrawAAPolyLine(origin, bottom_right);
223 drawControllerEdge(origin, local_top_left, local_top_right, box_radius);
224 drawControllerEdge(origin, local_bottom_left, local_top_left, box_radius);
225 drawControllerEdge(origin, local_bottom_left, local_bottom_right, box_radius);
226 drawControllerEdge(origin, local_bottom_right, local_top_right, box_radius);
228 drawControllerArc(origin, local_top_left, local_bottom_left, local_top_right,
229 local_bottom_right, box_radius);
230 drawControllerArc(origin, local_top_left, local_top_right, local_bottom_left,
231 local_bottom_right, box_radius);
233 Handles.color = previousColor;
236 private void getLocalGlobalPoint(
int x,
int y,
int z,
float box_width,
float box_depth,
float box_radius, out Vector3 local, out Vector3 global) {
240 + box_radius * local.normalized);
243 private void drawControllerEdge(Vector3 origin,
244 Vector3 edge0, Vector3 edge1,
247 .TransformDirection(
Vector3.Cross(edge0, edge1));
248 float right_angle =
Vector3.Angle(edge0, edge1);
250 Handles.DrawWireArc(origin, right_normal,
target.transform.TransformDirection(edge0),
251 right_angle,
target.transform.lossyScale.x * box_radius);
254 private void drawControllerArc(Vector3 origin,
255 Vector3 edgeA0, Vector3 edgeA1,
256 Vector3 edgeB0, Vector3 edgeB1,
262 float resolutionIncrement = 1f / 50f;
263 for (
float i = 0f; i < 1f; i += resolutionIncrement) {
265 *
target.transform.lossyScale.x * box_radius;
266 Vector3 end =
Vector3.Lerp(faceA, faceB, i + resolutionIncrement).normalized
267 *
target.transform.lossyScale.x * box_radius;
269 Handles.DrawAAPolyLine(origin + begin, origin + end);
The Controller class is your main interface to the Leap Motion Controller.
EventHandler< DeviceEventArgs > DeviceLost
Dispatched when a Leap Motion device is disconnected.
DeviceList Devices
The list of currently attached and recognized Leap Motion controller devices.
EventHandler< DeviceEventArgs > Device
Dispatched when a Leap Motion device is connected.
Dispatched when a device is plugged in.
The Device class represents a physically connected device.
DeviceType
The available types of Leap Motion controllers.
void specifyConditionalDrawing(string conditionalName, params string[] dependantProperties)
Specify a list of properties that should only be displayed if the conditional property has a value of...
void deferProperty(string propertyName)
Defer rendering of a property until the end of the inspector. Deferred properties are drawn in the RE...
void addPropertyToFoldout(string propertyName, string foldoutName, bool foldoutStartOpen=false)
Condition the drawing of a property based on the status of a foldout drop-down.
void specifyCustomDecorator(string propertyName, Action< SerializedProperty > decoratorDrawer)
Specify a callback to be used to draw a decorator for a specific named property. Should be called in ...
virtual void OnSceneGUI()
Quaternion deviceRotation
override void OnInspectorGUI()
The LeapServiceProvider provides tracked Leap Hand data and images from the device via the Leap servi...
Controller GetLeapController()
Returns the Leap Controller instance.
InteractionVolumeVisualization
InteractionVolumeVisualization SelectedInteractionVolumeVisualization
The LeapXRServiceProvider expands on the standard LeapServiceProvider to account for the offset of th...