public override void Teardown() { InteractionC.DestroyShapeInstance(ref _scene, ref _shapeInstanceHandle); InteractionC.RemoveShapeDescription(ref _scene, ref _shapeDescriptionHandle); base.Teardown(); }
/// <summary> /// Forces the given object to be released by any hands currently holding it. Will return true /// only if there was at least one hand holding the object. /// </summary> public bool ReleaseObject(IInteractionBehaviour graspedObject) { if (!_graspedBehaviours.Remove(graspedObject)) { return(false); } foreach (var interactionHand in _idToInteractionHand.Values) { if (interactionHand.graspedObject == graspedObject) { if (interactionHand.isUntracked) { interactionHand.MarkTimeout(); } else { if (_graspingEnabled) { INTERACTION_HAND_RESULT result = new INTERACTION_HAND_RESULT(); result.classification = ManipulatorMode.Contact; result.handFlags = HandResultFlags.ManipulatorMode; result.instanceHandle = new INTERACTION_SHAPE_INSTANCE_HANDLE(); InteractionC.OverrideHandResult(ref _scene, (uint)interactionHand.hand.Id, ref result); } interactionHand.ReleaseObject(); } } } return(true); }
public override void Setup() { base.Setup(); INTERACTION_SPHERE_DESCRIPTION sphere = new INTERACTION_SPHERE_DESCRIPTION(); sphere.shape.type = ShapeType.Sphere; sphere.radius = 1.0f; IntPtr spherePtr = StructAllocator.AllocateStruct(ref sphere); InteractionC.AddShapeDescription(ref _scene, spherePtr, out _shapeDescriptionHandle); INTERACTION_CREATE_SHAPE_INFO info = new INTERACTION_CREATE_SHAPE_INFO(); info.shapeFlags = ShapeInfoFlags.None; INTERACTION_TRANSFORM transform = new INTERACTION_TRANSFORM(); transform.position = Vector3.zero.ToCVector(); transform.rotation = Quaternion.identity.ToCQuaternion(); transform.wallTime = 0; InteractionC.CreateShapeInstance(ref _scene, ref _shapeDescriptionHandle, ref transform, ref info, out _shapeInstanceHandle); }
protected virtual void updateTracking(Frame frame) { int handCount = frame.Hands.Count; IntPtr ptr = HandArrayBuilder.CreateHandArray(frame); InteractionC.UpdateHands(ref _scene, (uint)handCount, ptr); StructAllocator.CleanupAllocations(); }
public void GetDebugStrings() { InteractionC.EnableDebugFlags(ref _scene, (uint)DebugFlags.Strings); List <string> strings = new List <string>(); InteractionC.GetDebugStrings(ref _scene, strings); }
public void UpdateHands() { Frame frame = TestHandFactory.MakeTestFrame(0, true, true); IntPtr handPtr = HandArrayBuilder.CreateHandArray(frame); InteractionC.UpdateHands(ref _scene, 2, handPtr); StructAllocator.CleanupAllocations(); }
public void UpdateSceneInfo() { INTERACTION_SCENE_INFO info = new INTERACTION_SCENE_INFO(); info.gravity = Vector3.one.ToCVector(); info.sceneFlags = SceneInfoFlags.HasGravity; InteractionC.UpdateSceneInfo(ref _scene, ref info); }
/// <summary> /// Gets a handle to a convex mesh description that describes the given capsule. /// </summary> public INTERACTION_SHAPE_DESCRIPTION_HANDLE GetCapsule(Vector3 p0, Vector3 p1, float radius) { INTERACTION_SHAPE_DESCRIPTION_HANDLE handle; IntPtr capsulePtr = allocateCapsule(p0, p1, radius); InteractionC.AddShapeDescription(ref _scene, capsulePtr, out handle); StructAllocator.CleanupAllocations(); _allHandles[handle] = new ShapeInfo(isCached: false); return(handle); }
public void UpdateController() { INTERACTION_TRANSFORM transform = new INTERACTION_TRANSFORM(); transform.position = Vector3.one.ToCVector(); transform.rotation = Quaternion.identity.ToCQuaternion(); transform.wallTime = 0; InteractionC.UpdateController(ref _scene, ref transform); }
public void EnableContactThenUpdate() { INTERACTION_SCENE_INFO info = new INTERACTION_SCENE_INFO(); info.sceneFlags = SceneInfoFlags.ContactEnabled; InteractionC.UpdateSceneInfo(ref _scene, ref info); UpdateInstance(); }
public virtual void Setup() { InteractionC.CreateScene(ref _scene); INTERACTION_SCENE_INFO sceneInfo = new INTERACTION_SCENE_INFO(); sceneInfo.sceneFlags = SceneInfoFlags.ContactEnabled; InteractionC.UpdateSceneInfo(ref _scene, ref sceneInfo); }
protected virtual void destroyInteractionShape(IInteractionBehaviour interactionBehaviour) { INTERACTION_SHAPE_INSTANCE_HANDLE instanceHandle = interactionBehaviour.ShapeInstanceHandle; _instanceHandleToBehaviour.Remove(instanceHandle); InteractionC.DestroyShapeInstance(ref _scene, ref instanceHandle); interactionBehaviour.NotifyInteractionShapeDestroyed(); }
protected virtual void simulateInteraction() { var _controllerTransform = new INTERACTION_TRANSFORM(); _controllerTransform.position = _leapProvider.transform.position.ToCVector(); _controllerTransform.rotation = _leapProvider.transform.rotation.ToCQuaternion(); _controllerTransform.wallTime = Time.fixedTime; InteractionC.UpdateController(ref _scene, ref _controllerTransform); }
/// <summary> /// Removes and destroys all descriptions from the internal scene. /// </summary> public void RemoveAllShapes() { foreach (var handle in _allHandles.Keys) { var localHandle = handle; InteractionC.RemoveShapeDescription(ref _scene, ref localHandle); } _allHandles.Clear(); _sphereDescMap.Clear(); _obbDescMap.Clear(); _meshDescMap.Clear(); }
/// <summary> /// Removes and destroys all descriptions from the internal scene. /// </summary> public void RemoveAllShapes() { for (var it = _allHandles.GetEnumerator(); it.MoveNext();) { var handle = it.Current.Key; var localHandle = handle; InteractionC.RemoveShapeDescription(ref _scene, ref localHandle); } _allHandles.Clear(); _sphereDescMap.Clear(); _obbDescMap.Clear(); _meshDescMap.Clear(); }
/// <summary> /// Returns a shape handle into the pool. /// </summary> public void ReturnShape(INTERACTION_SHAPE_DESCRIPTION_HANDLE handle) { ShapeInfo info; if (!_allHandles.TryGetValue(handle, out info)) { throw new InvalidOperationException("Tried to return a handle that was not allocated."); } if (!info.isCached) { _allHandles.Remove(handle); InteractionC.RemoveShapeDescription(ref _scene, ref handle); } }
protected virtual void createInteractionShape(IInteractionBehaviour interactionBehaviour) { INTERACTION_SHAPE_DESCRIPTION_HANDLE descriptionHandle = interactionBehaviour.ShapeDescriptionHandle; INTERACTION_SHAPE_INSTANCE_HANDLE instanceHandle = new INTERACTION_SHAPE_INSTANCE_HANDLE(); INTERACTION_CREATE_SHAPE_INFO createInfo; INTERACTION_TRANSFORM createTransform; interactionBehaviour.GetInteractionShapeCreationInfo(out createInfo, out createTransform); InteractionC.CreateShapeInstance(ref _scene, ref descriptionHandle, ref createTransform, ref createInfo, out instanceHandle); _instanceHandleToBehaviour[instanceHandle] = interactionBehaviour; interactionBehaviour.NotifyInteractionShapeCreated(instanceHandle); }
public void UpdateInstance() { INTERACTION_TRANSFORM transform = new INTERACTION_TRANSFORM(); transform.position = Vector3.one.ToCVector(); transform.rotation = Quaternion.identity.ToCQuaternion(); transform.wallTime = 0; INTERACTION_UPDATE_SHAPE_INFO info = new INTERACTION_UPDATE_SHAPE_INFO(); info.angularAcceleration = Vector3.zero.ToCVector(); info.angularVelocity = Vector3.zero.ToCVector(); info.linearAcceleration = Vector3.zero.ToCVector(); info.linearVelocity = Vector3.zero.ToCVector(); InteractionC.UpdateShapeInstance(ref _scene, ref transform, ref info, ref _shapeInstanceHandle); }
/// <summary> /// Gets a handle to a convex mesh description of the provided mesh. Any changes /// to the mesh will not be reflected in the description once it is generated. /// This version always allocates a new handle for the transformed data. /// </summary> public INTERACTION_SHAPE_DESCRIPTION_HANDLE GetConvexPolyhedron(MeshCollider meshCollider, Matrix4x4 transform) { if (meshCollider.sharedMesh == null) { throw new NotImplementedException("MeshCollider missing sharedMesh."); } INTERACTION_SHAPE_DESCRIPTION_HANDLE handle; IntPtr meshPtr = allocateConvex(meshCollider, transform); InteractionC.AddShapeDescription(ref _scene, meshPtr, out handle); StructAllocator.CleanupAllocations(); _allHandles[handle] = new ShapeInfo(isCached: false); return(handle); }
protected virtual void createScene() { _scene.pScene = (IntPtr)0; UInt32 libraryVersion = InteractionC.GetLibraryVersion(); UInt32 expectedVersion = InteractionC.GetExpectedVersion(); if (libraryVersion != expectedVersion) { Debug.LogError("Leap Interaction dll version expected: " + expectedVersion + " got version: " + libraryVersion); throw new Exception("Leap Interaction library version wrong"); } InteractionC.CreateScene(ref _scene); _hasSceneBeenCreated = true; UpdateSceneInfo(); }
protected virtual INTERACTION_HAND_RESULT getHandResults(InteractionHand hand) { if (!_graspingEnabled) { INTERACTION_HAND_RESULT result = new INTERACTION_HAND_RESULT(); result.classification = ManipulatorMode.Contact; result.handFlags = HandResultFlags.ManipulatorMode; result.instanceHandle = new INTERACTION_SHAPE_INSTANCE_HANDLE(); return(result); } INTERACTION_HAND_RESULT handResult; InteractionC.GetHandResult(ref _scene, (uint)hand.hand.Id, out handResult); return(handResult); }
/// <summary> /// Gets a handle to a sphere shape description of the given radius /// </summary> public INTERACTION_SHAPE_DESCRIPTION_HANDLE GetSphere(float radius) { float roundedRadius = (int)(radius * DECIMAL_CACHING_PRECISION); INTERACTION_SHAPE_DESCRIPTION_HANDLE handle; if (!_sphereDescMap.TryGetValue(roundedRadius, out handle)) { IntPtr spherePtr = allocateSphere(radius); InteractionC.AddShapeDescription(ref _scene, spherePtr, out handle); StructAllocator.CleanupAllocations(); _sphereDescMap[roundedRadius] = handle; _allHandles[handle] = new ShapeInfo(isCached: true); } return(handle); }
protected virtual void updateInteractionRepresentations() { var active = _activityManager.ActiveBehaviours; for (int i = 0; i < active.Count; i++) { IInteractionBehaviour interactionBehaviour = active[i]; try { INTERACTION_SHAPE_INSTANCE_HANDLE shapeInstanceHandle = interactionBehaviour.ShapeInstanceHandle; INTERACTION_UPDATE_SHAPE_INFO updateInfo; INTERACTION_TRANSFORM updateTransform; interactionBehaviour.GetInteractionShapeUpdateInfo(out updateInfo, out updateTransform); InteractionC.UpdateShapeInstance(ref _scene, ref updateTransform, ref updateInfo, ref shapeInstanceHandle); } catch (Exception e) { _activityManager.NotifyMisbehaving(interactionBehaviour); Debug.LogException(e); } } }
/// <summary> /// Gets a handle to an OBB description of the given extents /// </summary> public INTERACTION_SHAPE_DESCRIPTION_HANDLE GetOBB(Vector3 extents) { Vector3 roundedExtents = new Vector3(); roundedExtents.x = (int)(extents.x * DECIMAL_CACHING_PRECISION); roundedExtents.y = (int)(extents.y * DECIMAL_CACHING_PRECISION); roundedExtents.z = (int)(extents.z * DECIMAL_CACHING_PRECISION); INTERACTION_SHAPE_DESCRIPTION_HANDLE handle; if (!_obbDescMap.TryGetValue(roundedExtents, out handle)) { IntPtr obbPtr = allocateObb(extents); InteractionC.AddShapeDescription(ref _scene, obbPtr, out handle); StructAllocator.CleanupAllocations(); _obbDescMap[roundedExtents] = handle; _allHandles[handle] = new ShapeInfo(isCached: true); } return(handle); }
protected virtual void dispatchSimulationResults() { InteractionC.GetShapeInstanceResults(ref _scene, _resultList); for (int i = 0; i < _resultList.Count; ++i) { INTERACTION_SHAPE_INSTANCE_RESULTS result = _resultList[i]; //Behaviour might have already been unregistered during an earlier callback for this simulation step IInteractionBehaviour interactionBehaviour; if (_instanceHandleToBehaviour.TryGetValue(result.handle, out interactionBehaviour)) { try { // ShapeInstanceResultFlags.None may be returned if requested when hands are not touching. interactionBehaviour.NotifyRecievedSimulationResults(result); } catch (Exception e) { _activityManager.NotifyMisbehaving(interactionBehaviour); Debug.LogException(e); } } } }
protected virtual void FixedUpdate() { Frame frame = _leapProvider.CurrentFixedFrame; if (OnPrePhysicalUpdate != null) { OnPrePhysicalUpdate(); } simulateFrame(frame); if (OnPostPhysicalUpdate != null) { OnPostPhysicalUpdate(); } if (_showDebugLines) { RuntimeGizmoDrawer gizmoDrawer; if (RuntimeGizmoManager.TryGetGizmoDrawer(gameObject, out gizmoDrawer)) { InteractionC.GetDebugLines(ref _scene, _debugLines); for (int i = 0; i < _debugLines.Count; i++) { var line = _debugLines[i]; gizmoDrawer.color = line.color.ToUnityColor(); gizmoDrawer.DrawLine(line.start.ToVector3(), line.end.ToVector3()); } } } if (_showDebugOutput) { InteractionC.GetDebugStrings(ref _scene, _debugOutput); } }
/// Force an update of the internal scene info. This should be called if gravity has changed. /// </summary> public void UpdateSceneInfo() { if (!_hasSceneBeenCreated) { return; // UpdateSceneInfo is a side effect of a lot of changes. } INTERACTION_SCENE_INFO info = getSceneInfo(); if (_graspingEnabled && !_enableGraspingLast) { using (LdatLoader.LoadLdat(ref info, _ldatPath)) { InteractionC.UpdateSceneInfo(ref _scene, ref info); } } else { InteractionC.UpdateSceneInfo(ref _scene, ref info); } _enableGraspingLast = _graspingEnabled; _cachedSimulationScale = _leapProvider.transform.lossyScale.x; _activityManager.OverlapRadius = _activationRadius * _cachedSimulationScale; }
protected virtual void updateInteractionStateChanges(Frame frame) { var hands = frame.Hands; INTERACTION_HAND_RESULT handResult = new INTERACTION_HAND_RESULT(); //First loop through all the hands and get their classifications from the engine for (int i = 0; i < hands.Count; i++) { Hand hand = hands[i]; bool handResultForced = false; //Get the InteractionHand associated with this hand id InteractionHand interactionHand; if (!_idToInteractionHand.TryGetValue(hand.Id, out interactionHand)) { //First we see if there is an untracked interactionHand that can be re-connected using this one InteractionHand untrackedInteractionHand = null; foreach (var pair in _idToInteractionHand) { //If the old ieHand is untracked, and the handedness matches, we re-connect it if (pair.Value.isUntracked && pair.Value.hand.IsLeft == hand.IsLeft) { untrackedInteractionHand = pair.Value; break; } } if (untrackedInteractionHand != null) { //If we found an untrackedIeHand, use it! interactionHand = untrackedInteractionHand; //Remove the old id from the mapping _idToInteractionHand.Remove(untrackedInteractionHand.hand.Id); _idToInteractionHand[hand.Id] = interactionHand; try { //This also dispatched InteractionObject.OnHandRegainedTracking() interactionHand.RegainTracking(hand); if (interactionHand.graspedObject == null) { continue; } // NotifyHandRegainedTracking() did not throw, continue on to NotifyHandsHoldPhysics(). dispatchOnHandsHolding(hands, interactionHand.graspedObject, isPhysics: true); } catch (Exception e) { _activityManager.NotifyMisbehaving(interactionHand.graspedObject); Debug.LogException(e); continue; } //Override the existing classification to force the hand to grab the old object handResultForced = true; handResult.classification = ManipulatorMode.Grasp; handResult.handFlags = HandResultFlags.ManipulatorMode; handResult.instanceHandle = interactionHand.graspedObject.ShapeInstanceHandle; if (_graspingEnabled) { InteractionC.OverrideHandResult(ref _scene, (uint)hand.Id, ref handResult); } } else { //Otherwise just create a new one interactionHand = new InteractionHand(hand); _idToInteractionHand[hand.Id] = interactionHand; } } if (!handResultForced) { handResult = getHandResults(interactionHand); } interactionHand.UpdateHand(hand); if (!interactionHand.isUserGrasp) { switch (handResult.classification) { case ManipulatorMode.Grasp: { IInteractionBehaviour interactionBehaviour; if (_instanceHandleToBehaviour.TryGetValue(handResult.instanceHandle, out interactionBehaviour)) { if (interactionHand.graspedObject == null) { if (!interactionBehaviour.IsBeingGrasped) { _graspedBehaviours.Add(interactionBehaviour); } try { interactionHand.GraspObject(interactionBehaviour, isUserGrasp: false); //the grasp callback might have caused the object to become ungrasped //the component might have also destroyed itself! if (interactionHand.graspedObject == interactionBehaviour && interactionBehaviour != null) { dispatchOnHandsHolding(hands, interactionBehaviour, isPhysics: true); } } catch (Exception e) { _activityManager.NotifyMisbehaving(interactionBehaviour); Debug.LogException(e); continue; } } } else { Debug.LogError("Recieved a hand result with an unkown handle " + handResult.instanceHandle.handle); } break; } case ManipulatorMode.Contact: { if (interactionHand.graspedObject != null) { if (interactionHand.graspedObject.GraspingHandCount == 1) { _graspedBehaviours.Remove(interactionHand.graspedObject); } try { interactionHand.ReleaseObject(); } catch (Exception e) { _activityManager.NotifyMisbehaving(interactionHand.graspedObject); Debug.LogException(e); continue; } } break; } default: throw new InvalidOperationException("Unexpected classification " + handResult.classification); } } } //Loop through all ieHands to check for timeouts and loss of tracking foreach (var pair in _idToInteractionHand) { var id = pair.Key; var ieHand = pair.Value; float handAge = Time.unscaledTime - ieHand.lastTimeUpdated; //Check to see if the hand is at least 1 frame old //We assume it has become untracked if this is the case if (handAge > 0) { //If the hand isn't grasping anything, just remove it if (ieHand.graspedObject == null) { _handIdsToRemove.Add(id); continue; } //If is isn't already marked as untracked, mark it as untracked if (!ieHand.isUntracked) { try { //This also dispatches InteractionObject.OnHandLostTracking() ieHand.MarkUntracked(); } catch (Exception e) { _activityManager.NotifyMisbehaving(ieHand.graspedObject); Debug.LogException(e); } } //If the age is longer than the timeout, we also remove it from the list if (handAge >= ieHand.maxSuspensionTime) { _handIdsToRemove.Add(id); try { if (ieHand.graspedObject.GraspingHandCount == 1) { _graspedBehaviours.Remove(ieHand.graspedObject); } //This also dispatched InteractionObject.OnHandTimeout() ieHand.MarkTimeout(); } catch (Exception e) { _activityManager.NotifyMisbehaving(ieHand.graspedObject); Debug.LogException(e); } } } } //Loop through the stale ids and remove them from the map for (int i = 0; i < _handIdsToRemove.Count; i++) { _idToInteractionHand.Remove(_handIdsToRemove[i]); } _handIdsToRemove.Clear(); }
protected virtual void applyDebugSettings() { InteractionC.EnableDebugFlags(ref _scene, (uint)DebugFlags); }
protected virtual void destroyScene() { InteractionC.DestroyScene(ref _scene); _hasSceneBeenCreated = false; }