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);
        }
Exemple #8
0
        /// <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);
        }
Exemple #14
0
        /// <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();
        }
Exemple #15
0
        /// <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();
        }
Exemple #16
0
        /// <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);
        }
Exemple #19
0
        /// <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);
        }
Exemple #22
0
        /// <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);
                }
            }
        }
Exemple #24
0
        /// <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;
 }