@@ -112,7 +112,7 @@ public static string[] GetAllChannelAnnotationData()
112112 private const float maxRoll = 180f ;
113113
114114 // Brain surface position
115- private bool probeInBrain ;
115+ private bool _probeInBrain ;
116116 private Vector3 _brainSurfaceCoordT ;
117117 private Vector3 _brainSurfaceWorldU ;
118118 private Vector3 _brainSurfaceWorldT ;
@@ -370,7 +370,7 @@ public void UpdateName()
370370 else
371371 {
372372 // Check if this probe is in the brain
373- name = probeInBrain ? $ "{ _probeUIManagers [ 0 ] . MaxArea } -{ UUID [ ..8 ] } " : UUID [ ..8 ] ;
373+ name = _probeInBrain ? $ "{ _probeUIManagers [ 0 ] . MaxArea } -{ UUID [ ..8 ] } " : UUID [ ..8 ] ;
374374 }
375375 }
376376
@@ -734,40 +734,7 @@ public void ResizeProbePanel(int newPxHeight)
734734 UIUpdateEvent . Invoke ( ) ;
735735 }
736736
737- #region Brain surface coordinate
738-
739- /// <summary>
740- /// Check whether the probe is in the brain.
741- /// If it is, calculate the brain surface coordinate by iterating up the probe until you leave the brain.
742- /// </summary>
743- public void UpdateSurfacePosition ( )
744- {
745- // note: the backward axis on the probe is the probe's "up" axis
746- ( Vector3 tipCoordWorld , _ , _ , Vector3 tipForwardWorldU ) = _probeController . GetTipWorldU ( ) ;
747-
748- Vector3 surfaceIdxCoordU = FindSurfaceIdxCoordinate ( BrainAtlasManager . ActiveReferenceAtlas . World2AtlasIdx ( tipCoordWorld ) ,
749- BrainAtlasManager . ActiveReferenceAtlas . World2Atlas_Vector ( - tipForwardWorldU ) ) ;
750-
751- if ( float . IsNaN ( surfaceIdxCoordU . x ) )
752- {
753- // not in the brain
754- probeInBrain = false ;
755- _brainSurfaceWorldU = new Vector3 ( float . NaN , float . NaN , float . NaN ) ;
756- _brainSurfaceWorldT = new Vector3 ( float . NaN , float . NaN , float . NaN ) ;
757- _brainSurfaceCoordT = new Vector3 ( float . NaN , float . NaN , float . NaN ) ;
758- }
759- else
760- {
761- // in the brain
762- probeInBrain = true ;
763- // get the surface coordinate in un-transformed world space
764- _brainSurfaceWorldU = BrainAtlasManager . ActiveReferenceAtlas . AtlasIdx2World ( surfaceIdxCoordU ) ;
765- // go back into transformed space, only using the reference coordinate for the entry coordinate (not the transform coordinate)
766- _brainSurfaceWorldT = BrainAtlasManager . WorldU2WorldT ( _brainSurfaceWorldU , false ) ;
767- _brainSurfaceCoordT = ProbeController . Insertion . World2T ( _brainSurfaceWorldU ) ;
768- }
769- }
770-
737+ #region Brain surface coordinate
771738
772739 public ( Vector3 surfaceCoordinateT , float depthT ) GetSurfaceCoordinateT ( )
773740 {
@@ -781,42 +748,85 @@ public Vector3 GetSurfaceCoordinateWorldT()
781748
782749 public bool IsProbeInBrain ( )
783750 {
784- return probeInBrain ;
751+ return _probeInBrain ;
785752 }
786-
753+
787754 /// <summary>
788755 /// Move probe to brain surface
789756 /// </summary>
790757 public void DropProbeToBrainSurface ( )
791758 {
792- if ( probeInBrain )
759+ if ( _probeInBrain )
793760 {
794761 _probeController . SetProbePosition ( _brainSurfaceCoordT ) ;
795762 }
796763 else
797764 {
798- // We need to calculate the surface coordinate ourselves
799- var tipExtensionDirection =
800- ManipulatorBehaviorController . IsSetToDropToSurfaceWithDepth ? _probeController . GetTipWorldU ( ) . tipUpWorldU : Vector3 . up ;
801-
802- var brainSurfaceCoordinate = FindSurfaceIdxCoordinate (
803- BrainAtlasManager . ActiveReferenceAtlas . World2AtlasIdx ( _probeController . GetTipWorldU ( ) . tipCoordWorldU - tipExtensionDirection * 5 ) ,
804- BrainAtlasManager . ActiveReferenceAtlas . World2Atlas_Vector ( tipExtensionDirection ) ) ;
765+ ( Vector3 entryCoordAtlasIdx , _ ) = CalculateEntryCoordinate ( ! ManipulatorBehaviorController . IsSetToDropToSurfaceWithDepth ) ;
805766
806- if ( float . IsNaN ( brainSurfaceCoordinate . x ) )
767+ if ( float . IsNaN ( entryCoordAtlasIdx . x ) )
807768 {
808769 Debug . LogWarning ( "Could not find brain surface! Canceling set brain offset." ) ;
809770 return ;
810771 }
811772
812- var brainSurfaceToTransformed =
813- _probeController . Insertion . World2T (
814- BrainAtlasManager . ActiveReferenceAtlas . AtlasIdx2World ( brainSurfaceCoordinate ) ) ;
773+ var entryCoordAtlasT = BrainAtlasManager . ActiveAtlasTransform . U2T (
774+ BrainAtlasManager . ActiveReferenceAtlas . Idx2Atlas ( entryCoordAtlasIdx ) ) ;
815775
816- _probeController . SetProbePosition ( brainSurfaceToTransformed ) ;
776+ _probeController . SetProbePosition ( entryCoordAtlasT ) ;
817777 }
818778 }
819779
780+ /// <summary>
781+ /// Check whether the probe is in the brain.
782+ /// If it is, calculate the brain surface coordinate by iterating up the probe until you leave the brain.
783+ /// </summary>
784+ public void UpdateSurfacePosition ( )
785+ {
786+ ( Vector3 entryCoordAtlasIdx , bool probeInBrain ) = CalculateEntryCoordinate ( ) ;
787+ _probeInBrain = probeInBrain ;
788+
789+ if ( ! _probeInBrain )
790+ {
791+ _brainSurfaceWorldU = new Vector3 ( float . NaN , float . NaN , float . NaN ) ;
792+ _brainSurfaceWorldT = new Vector3 ( float . NaN , float . NaN , float . NaN ) ;
793+ _brainSurfaceCoordT = new Vector3 ( float . NaN , float . NaN , float . NaN ) ;
794+ }
795+ else
796+ {
797+ // get the surface coordinate in un-transformed world space
798+ _brainSurfaceWorldU = BrainAtlasManager . ActiveReferenceAtlas . AtlasIdx2World ( entryCoordAtlasIdx ) ;
799+ // go back into transformed space, only using the reference coordinate for the entry coordinate (not the transform coordinate)
800+ _brainSurfaceWorldT = BrainAtlasManager . WorldU2WorldT ( _brainSurfaceWorldU , false ) ;
801+
802+ _brainSurfaceCoordT = BrainAtlasManager . ActiveAtlasTransform . U2T (
803+ BrainAtlasManager . ActiveReferenceAtlas . World2Atlas ( _brainSurfaceWorldU , true ) ) ;
804+ }
805+ }
806+
807+ /// <summary>
808+ /// Calculate the entry coordinate on the brain surface, returns coordIdx
809+ /// </summary>
810+ /// <param name="calculateOutside"></param>
811+ /// <param name="useDV"></param>
812+ /// <returns>(entryCoordAtlasIdx, probeInBrain)</returns>
813+ public ( Vector3 entryCoordAtlasIdx , bool probeInBrain ) CalculateEntryCoordinate ( bool useDV = false )
814+ {
815+ // note: the backward axis on the probe is the probe's "up" axis
816+ ( Vector3 tipCoordWorldU , _ , _ , Vector3 tipForwardWorldU ) = _probeController . GetTipWorldU ( ) ;
817+
818+ Vector3 tipAtlasIdxU = BrainAtlasManager . ActiveReferenceAtlas . World2AtlasIdx ( tipCoordWorldU ) ;
819+ Vector3 downDir = useDV ? Vector3 . down : tipForwardWorldU ;
820+
821+ // Check if we're in the brain
822+ bool probeInBrain = BrainAtlasManager . ActiveReferenceAtlas . GetAnnotationIdx ( tipAtlasIdxU ) > 0 ;
823+
824+ Vector3 entryCoordAtlasIdx = FindEntryIdxCoordinate ( probeInBrain ? tipAtlasIdxU : tipAtlasIdxU + downDir * 5000f / BrainAtlasManager . ActiveReferenceAtlas . Resolution . x ,
825+ BrainAtlasManager . ActiveReferenceAtlas . World2Atlas_Vector ( downDir ) ) ;
826+
827+ return ( entryCoordAtlasIdx , probeInBrain ) ;
828+ }
829+
820830 /// <summary>
821831 /// Use the annotation dataset to discover whether there is a surface coordinate by going *down* from a point searchDistance
822832 /// *above* the startPos
@@ -826,25 +836,44 @@ public void DropProbeToBrainSurface()
826836 /// to enter first to discover the surface coordinate.
827837 /// </summary>
828838 /// <param name="bottomIdxCoordU">coordinate to go down to</param>
829- /// <param name="upVector "></param>
839+ /// <param name="downVector "></param>
830840 /// <returns></returns>
831- public Vector3 FindSurfaceIdxCoordinate ( Vector3 bottomIdxCoordU , Vector3 upVector )
841+ public Vector3 FindEntryIdxCoordinate ( Vector3 bottomIdxCoordU , Vector3 downVector )
832842 {
833843 // search from 10000 um above the top idx
844+ Debug . Log ( downVector ) ;
834845 float searchDistance = 10000 / BrainAtlasManager . ActiveReferenceAtlas . Resolution . z ;
835- // We'll start at a point that is pretty far above the brain surface
836- // note that search distance is in 25um units, so this is actually 10000 um up (i.e. the top of the probe)
837- Vector3 topSearchIdxCoordU = bottomIdxCoordU + upVector * searchDistance ;
846+ Vector3 topSearchIdxCoordU = bottomIdxCoordU - downVector * searchDistance ;
838847
839848 // If by chance we are inside the brain, go farther
840849 if ( BrainAtlasManager . ActiveReferenceAtlas . GetAnnotationIdx ( topSearchIdxCoordU ) > 0 )
841- topSearchIdxCoordU = bottomIdxCoordU + upVector * searchDistance * 2f ;
850+ topSearchIdxCoordU = bottomIdxCoordU - downVector * searchDistance * 2f ;
842851
843- for ( float perc = 0 ; perc <= 1f ; perc += 0.0005f )
852+ // We're going to speed this up by doing two searches: first a fast search to get into the brain, then a slow search to accurately
853+ // get the surface coordinate
854+ float finalPerc = - 1f ;
855+ for ( float perc = 0 ; perc <= 1f ; perc += 0.01f )
844856 {
845857 Vector3 point = Vector3 . Lerp ( topSearchIdxCoordU , bottomIdxCoordU , perc ) ;
846858 if ( BrainAtlasManager . ActiveReferenceAtlas . GetAnnotationIdx ( point ) > 0 )
847- return point ;
859+ {
860+ Debug . Log ( point ) ;
861+ finalPerc = perc ;
862+ break ;
863+ }
864+ }
865+
866+ if ( finalPerc > - 1f )
867+ {
868+ for ( float perc = finalPerc ; perc >= 0f ; perc -= 0.0001f )
869+ {
870+ Vector3 point = Vector3 . Lerp ( topSearchIdxCoordU , bottomIdxCoordU , perc ) ;
871+ if ( BrainAtlasManager . ActiveReferenceAtlas . GetAnnotationIdx ( point ) <= 0 )
872+ {
873+ Debug . Log ( point ) ;
874+ return point ;
875+ }
876+ }
848877 }
849878
850879 // If you got here it means you *never* entered and then exited the brain
0 commit comments