//[SerializeField]
    //string eventNameToListenFor = "New Layer Penetrated";
    //
    //private void Start()
    //{
    //    EventManager.StartListening(eventNameToListenFor, OnNewLayerPenetrated);
    //}

    public void OnLayerChange()
    {
        if (HapticNativePlugin.isPatientPenetrated())
        {
            PenetrableMaterial lastLayerPenetrated = PenetrableMaterial.GetLayer(HapticNativePlugin.getLastLayerPenetratedID());
            arduino.SetResistance((float)lastLayerPenetrated.m_fluidResistance);
        }
        else
        {
            lastLayerPenetrated = null;

            arduino.SetResistance(0.0f);
            //Debug.Log ("not resisting");
        }
    }
    //sets attempt details and returns true if success
    bool EndAttempt()
    {
        isTestRunning = false;

        ProcedureAttempt currentAttempt = attempts[attemptNum];

        if (currentAttempt != null)
        {
            currentAttempt.timeEnded = Time.realtimeSinceStartup;
            var currentLayer = PenetrableMaterial.GetLayer(HapticNativePlugin.getLastLayerPenetratedID());
            currentAttempt.notes = "ended in: " + currentLayer.m_name;
            if (duraPunctured)
            {
                currentAttempt.notes += ", Dura punctured";
            }

            currentAttempt.success = (currentLayer == targetLayer);

            string result;

            if (currentAttempt.success)
            {
                result = "success";
            }
            else
            {
                result = "failure, ";
            }

            currentAttempt.summaryText = "Attempt # " + attemptNum + ": " + result + ", Duration: " + (currentAttempt.timeEnded - currentAttempt.timeStarted) + ", " + currentAttempt.notes;;
            return(currentAttempt.success);
        }
        else
        {
            return(false);
        }
    }
    void RaycastLayers(Ray needleRay, float distance)
    {
        ////////////////////////////

        //raycast to determine what is in the needle's path
        RaycastHit[] hits = Physics.RaycastAll(needleRay, distance, needleLayerMask);

        //ensure only haptic objects are evaluated, and sort them by distance
        sortedHits = SortAndFilterPenetrations(hits);
        int numLayers = sortedHits.Count;

        // Tell plugin how many layers were encountered
        HapticNativePlugin.setPatientNumLayersToUse(numLayers);

        // iterate through layers, in order of closest to farthest
        var iterator = sortedHits.First;

        //if (sortedHits.Count <= 0) // if not touching anything
        //{
        //    constraint.SetEnabled(false);
        //}

        if (numLayers > 0)
        {
            // For each layer in order of raycast
            ////////////////////////////
            for (int layerDepthIdx = 0; layerDepthIdx < numLayers; layerDepthIdx++)
            {
                RaycastHit hit = iterator.Value;

                float layerDepth;

                if (layerDepthIdx == 0) // for the first collision
                {
                    layerDepth = 0.0f;

                    ////// they ray casts a little farther than the needle itself
                    if ((hit.distance) < (needleLength)) // if needle has hit the skin
                    {
                        if (needleDepth < 0.0)
                        {
                            SetPuncturePoint(hit.point, hit.normal);
                        }
                    }
                    else
                    {
                        UnPuncture();
                    }
                    ////
                }
                else
                {
                    layerDepth = Vector3.Distance(hit.point, (punctureData.entryPoint));  // depth of penetration from the first contact point
                }


                // Send new layer data to plugin
                PenetrableMaterial material = hit.collider.gameObject.GetComponent <PenetrableMaterial>();

                HapticNativePlugin.setHapticLayerProperties(
                    layerDepthIdx, // depth order
                    material.GetID(),
                    material.m_stiffness,
                    material.m_stiffnessExponent,
                    material.m_maxFrictionForce,
                    material.m_penetrationThreshold,
                    material.m_malleability,
                    layerDepth);

                // to next raycast
                iterator = iterator.Next;
            }

            needleDepth = Vector3.Distance(transform.position, punctureData.entryPoint);

#if UNITY_EDITOR
            {
                // debug drawing
                {
                    Debug.DrawRay(needleRay.origin, needleRay.direction * needleLength, Color.green);
                }

                // debug drawing
                {
                    // look-ahead portion
                    Debug.DrawLine(needleRay.origin,
                                   needleRay.origin + (needleRay.direction * (needleLength)),
                                   Color.yellow);

                    Vector3 entryPoint = punctureData.entryPoint;

                    if (sortedHits.Count > 0)
                    {
                        // unpenetrating portion
                        Debug.DrawLine(needleRay.origin,
                                       entryPoint,
                                       Color.green);

                        // penetrating portion
                        Debug.DrawLine(entryPoint,         //needleRay.origin + needleRay.direction * ((RaycastHit)sortedHits[0]).distance,
                                       transform.position, //needleRay.direction * (float)punctureData.collisions[(punctureData.collisions.Length - 1)].depth,
                                       Color.red);

                        // surface normal
                        Debug.DrawRay(entryPoint,
                                      punctureData.entrySurfaceNormal * 0.01f,
                                      Color.cyan);
                    }
                }
            }
#endif
        } // if hits.Length > 0
        else
        {
            UnPuncture();
        }
    } // method scope
Esempio n. 4
0
    void CheckForNewPuncture()
    {
        //if (HapticNativePlugin.isPatientPenetrated())
        //{
        PenetrableMaterial currentLayer = PenetrableMaterial.GetLayer(HapticNativePlugin.getLastLayerPenetratedID());
        int currentLayerDepth           = HapticNativePlugin.getCurrentLayerDepth();

        if (currentLayer != lastLayer)
        {
            // send layer change event
            OnLayerChange.Invoke();
            EventManager.TriggerEvent(newLayerMessage);

            // leaving a layer i.e. needle moving outwards
            if (currentLayerDepth < lastLayerDepth)
            {
                // send last layer event
                EventManager.TriggerEvent(leftLayerKey + lastLayer.m_name);
                OnLeaveLayer.Invoke();

                if (currentLayer != null)
                {
                    /////////////////   !!!!!!!!   /////////////////
                    // unlock rotation if entering an unlocked layer
                    // POTENTIAL BUG here, because this check does not cover all possible cases!
                    // e.g. if you go from a layer that is locked to a new layer further in that is not locked. In that case you should still be locked, but this code will unlock you
                    /////////////////   !!!!!!!!   /////////////////
                    if (lastLayer.m_locksRotation && !currentLayer.m_locksRotation)
                    {
                        // last layer should never be null because you cannot go lower than -1 current layer depth
                        EventManager.TriggerEvent(unlockRotationEvent);
                        OnUnlockRotation.Invoke();
                    }
                }
                else
                {
                    // entered air therefore unlock
                    OnUnlockRotation.Invoke();
                    OnNoPunctures.Invoke();
                }
            }
            else
            {
                // entering a further layer i.e. needle moving inwards
                if (currentLayer != null)
                {
                    if (lastLayer == null)
                    {
                        // if going from nothing to something then that is a puncture. Send the event
                        OnFirstPuncture.Invoke();
                    }


                    // send new layer event
                    EventManager.TriggerEvent(penetratedLayerKey + currentLayer.m_name);
                    OnEnterLayer.Invoke();

                    // send lock rotation event
                    if (currentLayer.m_locksRotation)
                    {
                        EventManager.TriggerEvent(lockRotationEvent);
                        OnLockRotation.Invoke();
                    }
                }
            }


            // update info UI
            if (LayerInfoUI != null)
            {
                if (currentLayer != null)
                {
                    LayerInfoUI.text = currentLayer.m_name;
                }
                else
                {
                    LayerInfoUI.text = "";
                }
            }

            lastLayerDepth = currentLayerDepth;
            lastLayer      = currentLayer;
        } // if (currentLayer != lastLayer)
    }     // CheckForNewPuncture