Skip to content

Commit

Permalink
Merge pull request #1126 from leapmotion/rc-4.6.0
Browse files Browse the repository at this point in the history
Release Candidate: UnityModules 4.6.0
  • Loading branch information
zalo authored Oct 6, 2020
2 parents ed86781 + 0f42db3 commit ca42f3a
Show file tree
Hide file tree
Showing 340 changed files with 5,985 additions and 144 deletions.
198 changes: 163 additions & 35 deletions Assets/Plugins/LeapMotion/Core/Editor/LeapServiceProviderEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,45 @@
* between Ultraleap and you, your company or other organization. *
******************************************************************************/

using UnityEngine;
using LeapInternal;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;

namespace Leap.Unity {

[CustomEditor(typeof(LeapServiceProvider))]
public class LeapServiceProviderEditor : CustomEditorBase<LeapServiceProvider> {

internal const float INTERACTION_VOLUME_MODEL_IMPORT_SCALE_FACTOR = 0.001f;

protected Quaternion deviceRotation = Quaternion.identity;
protected bool isVRProvider = false;

protected Vector3 controllerOffset = Vector3.zero;

private const float BOX_RADIUS = 0.45f;
private const float BOX_WIDTH = 0.965f;
private const float BOX_DEPTH = 0.6671f;
private const float LMC_BOX_RADIUS = 0.45f;
private const float LMC_BOX_WIDTH = 0.965f;
private const float LMC_BOX_DEPTH = 0.6671f;

private Mesh _stereoIR170InteractionZoneMesh;
private Material _stereoIR170InteractionMaterial;
private readonly Vector3 _stereoIR170InteractionZoneMeshOffset = new Vector3(0.0523f, 0, 0.005f);

private LeapServiceProvider _leapServiceProvider;
private Controller _leapController;


protected override void OnEnable() {

base.OnEnable();

ParseStereoIR170InteractionMeshData();

specifyCustomDecorator("_frameOptimization", frameOptimizationWarning);

specifyConditionalDrawing("_frameOptimization",
Expand Down Expand Up @@ -61,79 +80,188 @@ private void frameOptimizationWarning(SerializedProperty property) {
}

public override void OnInspectorGUI() {
#if UNITY_2019_3_OR_NEWER

#if UNITY_2019_3_OR_NEWER
// Easily tracking VR-enabled-or-not requires an XR package installed, so remove this warning for now.
#else
#else
if (UnityEditor.PlayerSettings.virtualRealitySupported && !isVRProvider) {
EditorGUILayout.HelpBox(
"VR support is enabled. If your Leap is mounted to your headset, you should be "
+ "using LeapXRServiceProvider instead of LeapServiceProvider. (If your Leap "
+ "is not mounted to your headset, you can safely ignore this warning.)",
MessageType.Warning);
}
#endif
#endif

base.OnInspectorGUI();
}

public virtual void OnSceneGUI() {
Vector3 origin = target.transform.TransformPoint(controllerOffset);

Vector3 local_top_left, top_left, local_top_right, top_right,
local_bottom_left, bottom_left, local_bottom_right, bottom_right;
getLocalGlobalPoint(-1, 1, 1, out local_top_left, out top_left);
getLocalGlobalPoint(1, 1, 1, out local_top_right, out top_right);
getLocalGlobalPoint(-1, 1, -1, out local_bottom_left, out bottom_left);
getLocalGlobalPoint(1, 1, -1, out local_bottom_right, out bottom_right);
switch (GetSelectedInteractionVolume()) {
case LeapServiceProvider.InteractionVolumeVisualization.None:
break;
case LeapServiceProvider.InteractionVolumeVisualization.LeapMotionController:
DrawLeapMotionControllerInteractionZone(LMC_BOX_WIDTH, LMC_BOX_DEPTH, LMC_BOX_RADIUS, Color.white);
break;
case LeapServiceProvider.InteractionVolumeVisualization.StereoIR170:
DrawStereoIR170InteractionZoneMesh();
break;
case LeapServiceProvider.InteractionVolumeVisualization.Automatic:
DetectConnectedDevice();
break;
default:
break;
}

}

private void ParseStereoIR170InteractionMeshData() {

if (_stereoIR170InteractionZoneMesh == null) {
_stereoIR170InteractionZoneMesh = (Mesh)AssetDatabase.LoadAssetAtPath(Path.Combine("Assets", "Plugins", "LeapMotion", "Core", "Models", "StereoIR170-interaction-cone.obj"), typeof(Mesh));
}

if (_stereoIR170InteractionMaterial == null) {
_stereoIR170InteractionMaterial = (Material)AssetDatabase.LoadAssetAtPath(Path.Combine("Assets", "Plugins", "LeapMotion", "Core", "Materials", "StereoIR170InteractionVolume.mat"), typeof(Material));
}

}

private LeapServiceProvider LeapServiceProvider {
get {

if (this._leapServiceProvider != null) {
return this._leapServiceProvider;
}
else {
this._leapServiceProvider = this.target.GetComponent<LeapServiceProvider>();

return this._leapServiceProvider;
}
}
}

private Controller LeapController {
get {

if (this._leapController != null) {
return this._leapController;
}
else
{
this._leapController = LeapServiceProvider?.GetLeapController();

if (this._leapController != null) {
this._leapController.Device += _leapController_DeviceChanged;
this._leapController.DeviceLost += _leapController_DeviceChanged;
}

return this._leapController;
}
}
}

private void _leapController_DeviceChanged(object sender, DeviceEventArgs e) {
EditorWindow view = EditorWindow.GetWindow<SceneView>();
view.Repaint();
}

private void DetectConnectedDevice() {

if (LeapController?.Devices?.Count == 1)
{
if (LeapController.Devices.First().Type == Device.DeviceType.TYPE_RIGEL) {
DrawStereoIR170InteractionZoneMesh();
}
else if (LeapController.Devices.First().Type == Device.DeviceType.TYPE_PERIPHERAL) {
DrawLeapMotionControllerInteractionZone(LMC_BOX_WIDTH, LMC_BOX_DEPTH, LMC_BOX_RADIUS, Color.white);
}
}
}

private LeapServiceProvider.InteractionVolumeVisualization? GetSelectedInteractionVolume() {

return LeapServiceProvider?.SelectedInteractionVolumeVisualization;
}

private void DrawStereoIR170InteractionZoneMesh() {

if (_stereoIR170InteractionMaterial != null && _stereoIR170InteractionZoneMesh != null) {
_stereoIR170InteractionMaterial.SetPass(0);

Graphics.DrawMeshNow(_stereoIR170InteractionZoneMesh,
target.transform.localToWorldMatrix *
Matrix4x4.TRS(controllerOffset + _stereoIR170InteractionZoneMeshOffset, deviceRotation * Quaternion.Euler(-90, 0, 0), Vector3.one * 0.001f));
}
}

Handles.DrawLine(origin, top_left);
Handles.DrawLine(origin, top_right);
Handles.DrawLine(origin, bottom_left);
Handles.DrawLine(origin, bottom_right);
private void DrawLeapMotionControllerInteractionZone(float box_width, float box_depth, float box_radius, Color interactionZoneColor) {

drawControllerEdge(origin, local_top_left, local_top_right);
drawControllerEdge(origin, local_bottom_left, local_top_left);
drawControllerEdge(origin, local_bottom_left, local_bottom_right);
drawControllerEdge(origin, local_bottom_right, local_top_right);
Color previousColor = Handles.color;
Handles.color = interactionZoneColor;

Vector3 origin = target.transform.TransformPoint(controllerOffset);
getLocalGlobalPoint(-1, 1, 1, box_width, box_depth, box_radius, out Vector3 local_top_left, out Vector3 top_left);
getLocalGlobalPoint(1, 1, 1, box_width, box_depth, box_radius, out Vector3 local_top_right, out Vector3 top_right);
getLocalGlobalPoint(-1, 1, -1, box_width, box_depth, box_radius, out Vector3 local_bottom_left, out Vector3 bottom_left);
getLocalGlobalPoint(1, 1, -1, box_width, box_depth, box_radius, out Vector3 local_bottom_right, out Vector3 bottom_right);

Handles.DrawAAPolyLine(origin, top_left);
Handles.DrawAAPolyLine(origin, top_right);
Handles.DrawAAPolyLine(origin, bottom_left);
Handles.DrawAAPolyLine(origin, bottom_right);

drawControllerEdge(origin, local_top_left, local_top_right, box_radius);
drawControllerEdge(origin, local_bottom_left, local_top_left, box_radius);
drawControllerEdge(origin, local_bottom_left, local_bottom_right, box_radius);
drawControllerEdge(origin, local_bottom_right, local_top_right, box_radius);

drawControllerArc(origin, local_top_left, local_bottom_left, local_top_right,
local_bottom_right);
local_bottom_right, box_radius);
drawControllerArc(origin, local_top_left, local_top_right, local_bottom_left,
local_bottom_right);
local_bottom_right, box_radius);

Handles.color = previousColor;
}

private void getLocalGlobalPoint(int x, int y, int z,
out Vector3 local, out Vector3 global) {
local = deviceRotation * new Vector3(x * BOX_WIDTH, y * BOX_RADIUS, z * BOX_DEPTH);
private void getLocalGlobalPoint(int x, int y, int z, float box_width, float box_depth, float box_radius, out Vector3 local, out Vector3 global) {

local = deviceRotation * new Vector3(x * box_width, y * box_radius, z * box_depth);
global = target.transform.TransformPoint(controllerOffset
+ BOX_RADIUS * local.normalized);
+ box_radius * local.normalized);
}

private void drawControllerEdge(Vector3 origin,
Vector3 edge0, Vector3 edge1) {
Vector3 edge0, Vector3 edge1,
float box_radius) {
Vector3 right_normal = target.transform
.TransformDirection(Vector3.Cross(edge0, edge1));
float right_angle = Vector3.Angle(edge0, edge1);

Handles.DrawWireArc(origin, right_normal, target.transform.TransformDirection(edge0),
right_angle, target.transform.lossyScale.x * BOX_RADIUS);
right_angle, target.transform.lossyScale.x * box_radius);
}

private void drawControllerArc(Vector3 origin,
Vector3 edgeA0, Vector3 edgeA1,
Vector3 edgeB0, Vector3 edgeB1) {
Vector3 edgeB0, Vector3 edgeB1,
float box_radius) {

Vector3 faceA = target.transform.rotation * Vector3.Lerp(edgeA0, edgeA1, 0.5f);
Vector3 faceB = target.transform.rotation * Vector3.Lerp(edgeB0, edgeB1, 0.5f);

float resolutionIncrement = 1f / 50f;
for (float i = 0f; i < 1f; i += resolutionIncrement) {
Vector3 begin = Vector3.Lerp(faceA, faceB, i).normalized
* target.transform.lossyScale.x * BOX_RADIUS;
Vector3 end = Vector3.Lerp(faceA, faceB, i + resolutionIncrement).normalized
* target.transform.lossyScale.x * BOX_RADIUS;
* target.transform.lossyScale.x * box_radius;
Vector3 end = Vector3.Lerp(faceA, faceB, i + resolutionIncrement).normalized
* target.transform.lossyScale.x * box_radius;

Handles.DrawLine(origin + begin, origin + end);
Handles.DrawAAPolyLine(origin + begin, origin + end);
}
}
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ public class ProjectionPostProcessProvider : PostProcessProvider {
[Header("Projection")]
public Transform headTransform;

[Tooltip("The exponent of the projection of any hand distance from the approximated "
[Tooltip("The scale of the projection of any hand distance from the approximated "
+ "shoulder beyond the handMergeDistance.")]
[Range(0f, 5f)]
public float projectionExponent = 3.50f;
[Range(0f, 15f)]
public float projectionScale = 10f;

[Tooltip("The distance from the approximated shoulder beyond which any additional "
+ "distance is exponentiated by the projectionExponent.")]
[Range(0f, 1f)]
public float handMergeDistance = 0.30f;
public float handMergeDistance = 0.35f;

public override void ProcessFrame(ref Frame inputFrame) {
// Calculate the position of the head and the basis to calculate shoulder position.
Expand All @@ -35,16 +35,16 @@ public override void ProcessFrame(ref Frame inputFrame) {

foreach (var hand in inputFrame.Hands) {
// Approximate shoulder position with magic values.
var shoulderPos = headPos
+ (shoulderBasis * (new Vector3(0f, -0.2f, -0.1f)
+ Vector3.left * 0.1f * (hand.IsLeft ? 1f : -1f)));
Vector3 shoulderPos = headPos
+ (shoulderBasis * (new Vector3(0f, -0.13f, -0.1f)
+ Vector3.left * 0.15f * (hand.IsLeft ? 1f : -1f)));

// Calculate the projection of the hand if it extends beyond the
// handMergeDistance.
var shoulderToHand = hand.PalmPosition.ToVector3() - shoulderPos;
var handShoulderDist = shoulderToHand.magnitude;
var projectionDistance = Mathf.Max(0f, handShoulderDist - handMergeDistance);
var projectionAmount = Mathf.Pow(1 + projectionDistance, projectionExponent);
Vector3 shoulderToHand = hand.PalmPosition.ToVector3() - shoulderPos;
float handShoulderDist = shoulderToHand.magnitude;
float projectionDistance = Mathf.Max(0f, handShoulderDist - handMergeDistance);
float projectionAmount = 1f + (projectionDistance * projectionScale);
hand.SetTransform(shoulderPos + shoulderToHand * projectionAmount,
hand.Rotation.ToQuaternion());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: StereoIR170InteractionVolume
m_Shader: {fileID: 4800000, guid: d184816898f36e742a667d8c0f9efe59, type: 3}
m_ShaderKeywords: _REMOVEDIAG_ON
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 1
m_CustomRenderQueue: 3000
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _RemoveDiag: 1
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _WireframeVal: 0.279
- _ZWrite: 1
m_Colors:
- _BackColor: {r: 0.9528302, g: 0.049439307, b: 0.049439307, a: 0.77254903}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _FrontColor: {r: 1, g: 1, b: 1, a: 1}
Loading

0 comments on commit ca42f3a

Please sign in to comment.