NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

mapViewProbeHandlerStandalone.py (47657B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\mapView\mapViewProbeHandlerStandalone.py
      2 import itertools
      3 import math
      4 from collections import defaultdict
      5 import blue
      6 import geo2
      7 import carbonui.const as uiconst
      8 import trinity
      9 import uthread
     10 from carbon.client.script.environment.AudioUtil import PlaySound, SetSoundParameter
     11 from carbon.common.script.util.timerstuff import AutoTimer
     12 from carbonui.uicore import uicore
     13 from eve.client.script.ui.inflight.probeControl_MapView import BaseProbeControl, ProbeControl, BASE_PROBE_COLOR
     14 from eve.client.script.ui.shared.mapView import mapViewUtil
     15 from eve.client.script.ui.shared.mapView.mapViewConst import SOLARSYSTEM_SCALE, MARKERID_SCANRESULT, MARKERID_PROBE, MODIFY_POSITION, MODIFY_RANGE, MODIFY_SPREAD
     16 from eve.client.script.ui.shared.mapView.mapViewUtil import SolarSystemPosToMapPos, MapPosToSolarSystemPos
     17 from eve.client.script.ui.shared.mapView.markers.mapMarkerScanResult import MarkerScanResult
     18 from probescanning.const import probeStateIdle, probeStateInactive
     19 from probescanning.util import IsIntersecting
     20 RESULT_LINE_WIDTH = 4.5
     21 LINE_DASH_LENGTH = 4000.0
     22 DISTANCE_RING_RANGES = [1,
     23  2,
     24  4,
     25  8,
     26  16,
     27  32,
     28  64,
     29  128]
     30 MAX_DIST_RING_RANGE = DISTANCE_RING_RANGES[-1]
     31 r, g, b, a = BASE_PROBE_COLOR
     32 CENTROID_LINE_COLOR = (r * 0.3,
     33  g * 0.3,
     34  b * 0.3,
     35  1.0)
     36 CENTROID_LINE_WIDTH = 2.5
     37 WARP_LINE_COLOR = (r * 0.3,
     38  g * 0.3,
     39  b * 0.3,
     40  1.0)
     41 WARP_LINE_WIDTH = 2.0
     42 CIRCLE_COLOR_ANIM = (0.15,
     43  0.0,
     44  0.0,
     45  1.0)
     46 CIRCLE_COLOR_DESELECTED = (0.5,
     47  0.0,
     48  0.0,
     49  0.5)
     50 CIRCLE_COLOR_SELECTED = (1.0,
     51  0.0,
     52  0.0,
     53  0.7)
     54 INTERSECTION_ACTIVE = 0.6
     55 INTERSECTION_INACTIVE = 0.05
     56 AXIS_Y = geo2.Vector(0.0, 1.0, 0.0)
     57 AXIS_Z = geo2.Vector(0.0, 0.0, 1.0)
     58 FORMATION_CONTROL_ID = 'formationControl'
     59 
     60 class MapViewProbeHandlerStandalone(object):
     61     __notifyevents__ = ['OnProbeScanner_ProbeEntryMouseEnter',
     62      'OnProbeScanner_ProbeEntryMouseExit',
     63      'OnProbeScanner_ProbeEntryDblClick',
     64      'OnProbeScanner_FocusOnProbe',
     65      'OnProbeScanner_FocusOnResult',
     66      'OnProbeScanner_ScanResultMouseEnter',
     67      'OnProbeScanner_ScanResultMouseExit',
     68      'OnProbeAdded',
     69      'OnProbeRemoved',
     70      'OnProbeWarpStart',
     71      'OnProbeWarpEnd',
     72      'OnProbeStateUpdated',
     73      'OnProbeRangeUpdated',
     74      'OnProbePositionsUpdated',
     75      'OnSiteSelectionChanged',
     76      'OnSystemScanBegun',
     77      'OnSystemScanDone',
     78      'OnSystemScanFilterChanged',
     79      'OnScannerDisconnected',
     80      'OnRefreshScanResults']
     81     _keyState = None
     82     _editMode = MODIFY_POSITION
     83     _activeEditMode = None
     84     _filterResults = None
     85     highlightCursorData = None
     86 
     87     def __init__(self, systemMapHandler):
     88         self.systemMapHandler = systemMapHandler
     89         self.Cleanup()
     90         self.updatesScanHitsThread = None
     91         parentTransform = trinity.EveTransform()
     92         parentTransform.name = 'probes_%d' % systemMapHandler.solarsystemID
     93         self.parentTransform = parentTransform
     94         systemMapHandler.systemMapTransform.children.append(self.parentTransform)
     95         self.scanSvc = sm.GetService('scanSvc')
     96         sm.RegisterNotify(self)
     97         self.keyDownCookie = uicore.event.RegisterForTriuiEvents(uiconst.UI_KEYDOWN, self.OnGlobalKeyCallback)
     98         self.keyUpCookie = uicore.event.RegisterForTriuiEvents(uiconst.UI_KEYUP, self.OnGlobalKeyCallback)
     99         self.updateTick = AutoTimer(200, self.UpdateInputState)
    100         self.UpdateProbeSpheres()
    101         self.UpdateScanResult()
    102 
    103     def StopHandler(self):
    104         uicore.event.UnregisterForTriuiEvents(self.keyDownCookie)
    105         uicore.event.UnregisterForTriuiEvents(self.keyUpCookie)
    106         self.updateTick = None
    107         sm.UnregisterNotify(self)
    108         if self.updatesScanHitsThread:
    109             self.updatesScanHitsThread.kill()
    110             self.updatesScanHitsThread = None
    111         self.systemMapHandler.systemMapTransform.children.remove(self.parentTransform)
    112         self.systemMapHandler = None
    113 
    114     def Cleanup(self):
    115         if getattr(self, 'parentTransform', None):
    116             for each in self.parentTransform.children[:]:
    117                 self.parentTransform.children.remove(each)
    118 
    119         if self.systemMapHandler and self.systemMapHandler.markersHandler:
    120             resultMarkers = self.systemMapHandler.markersHandler.GetMarkersByType(MARKERID_SCANRESULT)
    121             for markerObject in resultMarkers:
    122                 self.systemMapHandler.markersHandler.RemoveMarker(markerObject.markerID)
    123 
    124         self.centerProbeControl = None
    125         self.probeIntersectionsByPair = {}
    126         self.centroidLines = None
    127         self.lastProbeIDs = None
    128         self.probeControlsByID = {}
    129         self.resultObjectsByID = {}
    130         self.lineIDsByID = defaultdict(list)
    131         self.resultMarkers = set()
    132 
    133     def UpdateInputState(self):
    134         self.CheckKeyState()
    135 
    136     def OnGlobalKeyCallback(self, wnd, eventID, param):
    137         vkey, flag = param
    138         if vkey not in (uiconst.VK_CONTROL, uiconst.VK_MENU, uiconst.VK_SHIFT):
    139             return True
    140         if eventID == uiconst.UI_KEYDOWN and flag & 1073741824:
    141             return True
    142         try:
    143             self.CheckKeyState()
    144         finally:
    145             return True
    146 
    147     def CheckKeyState(self):
    148         if not trinity.app.IsActive():
    149             return
    150         CTRL = uicore.uilib.Key(uiconst.VK_CONTROL)
    151         ALT = uicore.uilib.Key(uiconst.VK_MENU)
    152         SHIFT = uicore.uilib.Key(uiconst.VK_SHIFT)
    153         if CTRL:
    154             self._editMode = MODIFY_SPREAD
    155         elif ALT:
    156             self._editMode = MODIFY_RANGE
    157         else:
    158             self._editMode = MODIFY_POSITION
    159         keyState = (CTRL, ALT, SHIFT)
    160         if self._keyState != keyState:
    161             self._keyState = keyState
    162             self.UpdateProbeControlDisplay()
    163 
    164     def GetEditMode(self):
    165         return self._editMode
    166 
    167     def GetActiveEditMode(self):
    168         return self._activeEditMode
    169 
    170     def OnProbeWarpStart(self, probeID, fromPos, toPos, startTime, duration):
    171         PlaySound('msg_newscan_probe_travel_play')
    172         uthread.worker('MapViewProbeHandler::OnProbeWarpStart_Thread', self.OnProbeWarpStart_Thread, probeID, fromPos, toPos, startTime, duration)
    173 
    174     def OnProbeWarpStart_Thread(self, probeID, fromPos, toPos, startTime, duration):
    175         if not hasattr(self, 'probeRoutes'):
    176             self.probeRoutes = {}
    177         data = self.probeTracker.GetProbeData()
    178         if probeID not in data:
    179             return
    180         probe = data[probeID]
    181         lineSet = mapViewUtil.CreateLineSet()
    182         lineSet.name = 'probeRoute_' + str(probeID)
    183         lineID = lineSet.AddStraightLine(probe.pos, WARP_LINE_COLOR, probe.destination, WARP_LINE_COLOR, WARP_LINE_WIDTH)
    184         lineSet.ChangeLineAnimation(lineID, WARP_LINE_COLOR, -0.125, 10.0)
    185         lineSet.SubmitChanges()
    186         self.parentTransform.children.append(lineSet)
    187         self.probeRoutes[probeID] = lineSet
    188 
    189     def OnProbeWarpEnd(self, probeID):
    190         PlaySound('msg_newscan_probe_travel_stop')
    191         uthread.worker('MapViewProbeHandler::OnProbeWarpEnd_Thread', self.OnProbeWarpEnd_Thread, probeID)
    192 
    193     def OnProbeWarpEnd_Thread(self, probeID):
    194         if hasattr(self, 'probeRoutes') and probeID in self.probeRoutes:
    195             routeLineSet = self.probeRoutes[probeID]
    196             if routeLineSet in self.parentTransform.children:
    197                 self.parentTransform.children.remove(routeLineSet)
    198             del self.probeRoutes[probeID]
    199             scanSvc = sm.GetService('scanSvc')
    200             probes = scanSvc.GetProbeData()
    201             if probes and probeID in probes and self.systemMapHandler and self.systemMapHandler.markersHandler:
    202                 probe = probes[probeID]
    203                 markerID = (MARKERID_PROBE, probeID)
    204                 markerObject = self.systemMapHandler.markersHandler.GetMarkerByID(markerID)
    205                 if markerObject:
    206                     markerObject.UpdateMapPositionLocal(SolarSystemPosToMapPos(probe.destination), animate=True)
    207 
    208     def OnProbeAdded(self, probe):
    209         uthread.new(self._OnProbeAdded, probe)
    210 
    211     def _OnProbeAdded(self, probe):
    212         self.UpdateProbeSpheres()
    213 
    214     def OnProbeRemoved(self, probeID):
    215         uthread.new(self._OnProbeRemove, probeID)
    216 
    217     def _OnProbeRemove(self, probeID):
    218         self.UpdateProbeSpheres(animate=True)
    219 
    220     def OnSystemScanBegun(self):
    221         self.SetScanDronesState(1)
    222 
    223     def OnSystemScanDone(self):
    224         self.SetScanDronesState(0)
    225         self.SetResultFilter([])
    226         self.UpdateScanResult(animate=True)
    227 
    228     def OnSystemScanFilterChanged(self, *args):
    229         self.UpdateScanResult()
    230 
    231     def OnProbeStateUpdated(self, probeID, state):
    232         self.updateProbeSpheresTimer = AutoTimer(200, self.UpdateProbeSpheres)
    233 
    234     def OnProbeRangeUpdated(self, probeID, scanRange):
    235         probe = self.GetProbeControl(probeID)
    236         if probe:
    237             probe.SetRange(scanRange, animate=True)
    238 
    239     def OnScannerDisconnected(self):
    240         if self.systemMapHandler:
    241             self.UpdateProbeSpheres()
    242             self.UpdateScanResult(animate=True)
    243 
    244     def OnRefreshScanResults(self):
    245         self.UpdateProbeSpheres()
    246         self.UpdateScanResult(animate=True)
    247 
    248     def OnProbePositionsUpdated(self):
    249         self.UpdateProbeSpheres(animate=True)
    250 
    251     def OnProbeScanner_ProbeEntryMouseEnter(self, probeID):
    252         probeControl = self.GetProbeControl(probeID)
    253         if probeControl:
    254             probeControl.HighlightProbe()
    255 
    256     def OnProbeScanner_ProbeEntryMouseExit(self, probeID):
    257         probeControl = self.GetProbeControl(probeID)
    258         if probeControl:
    259             probeControl.StopHighlightProbe()
    260 
    261     def OnProbeScanner_ProbeEntryDblClick(self, result):
    262         markerID = (MARKERID_SCANRESULT, (result.id, 0))
    263         if not self.systemMapHandler.markersHandler:
    264             return
    265         marker = self.systemMapHandler.markersHandler.GetMarkerByID(markerID)
    266         if not marker:
    267             return
    268         self.systemMapHandler.mapView.SetSelectedMarker(marker)
    269 
    270     def OnProbeScanner_ScanResultMouseEnter(self, result):
    271         if not self.systemMapHandler.markersHandler:
    272             return
    273         if isinstance(result.data, (tuple, list)):
    274             if isinstance(result.data, list):
    275                 positions = result.data
    276             else:
    277                 positions = [result.data]
    278             markerIDs = [ (MARKERID_SCANRESULT, (result.id, i)) for i, position in enumerate(positions) ]
    279         else:
    280             markerIDs = [(MARKERID_SCANRESULT, result.id)]
    281         self.systemMapHandler.markersHandler.HilightMarkers(markerIDs)
    282         resultMarkers = self.systemMapHandler.markersHandler.GetMarkersByType(MARKERID_SCANRESULT)
    283         for markerObject in resultMarkers:
    284             markerObject.UpdateActiveAndHilightState()
    285 
    286     def OnProbeScanner_ScanResultMouseExit(self, result):
    287         if not self.systemMapHandler.markersHandler:
    288             return
    289         self.systemMapHandler.markersHandler.HilightMarkers([])
    290         resultMarkers = self.systemMapHandler.markersHandler.GetMarkersByType(MARKERID_SCANRESULT)
    291         for markerObject in resultMarkers:
    292             markerObject.UpdateActiveAndHilightState()
    293 
    294     def OnProbeScanner_FocusOnProbe(self, probeID, *args):
    295         self.FocusOnProbe(probeID)
    296 
    297     def OnProbeScanner_FocusOnResult(self, result, *args):
    298         if isinstance(result.data, float):
    299             self.systemMapHandler.markersHandler.mapView.SetCameraPointOfInterestSolarSystemPosition(self.systemMapHandler.solarsystemID, result.pos)
    300         elif isinstance(result.data, (tuple, list)):
    301             if isinstance(result.data, list):
    302                 positions = result.data
    303             else:
    304                 positions = [result.data]
    305             centerPosition = self.GetCenterPosition(positions)
    306             self.systemMapHandler.markersHandler.mapView.SetCameraPointOfInterestSolarSystemPosition(self.systemMapHandler.solarsystemID, centerPosition)
    307         else:
    308             self.systemMapHandler.markersHandler.mapView.SetCameraPointOfInterestSolarSystemPosition(self.systemMapHandler.solarsystemID, result.data.point)
    309 
    310     def UpdateProbeControlDisplay(self):
    311         editMode = self.GetActiveEditMode() or self.GetEditMode()
    312         SHIFT = uicore.uilib.Key(uiconst.VK_SHIFT)
    313         probesAvailable = self.HasAvailableProbes()
    314         if self.centerProbeControl:
    315             self.centerProbeControl.cursor.display = editMode == MODIFY_POSITION and not SHIFT and probesAvailable
    316         for probeID, probeControl in self.probeControlsByID.iteritems():
    317             if self.probeTracker.GetProbeState(probeID) != probeStateIdle:
    318                 probeControl.SetEditMode(MODIFY_POSITION)
    319                 self.RemoveCentroidLines()
    320                 continue
    321             probeControl.SetEditMode(editMode)
    322             if editMode in (MODIFY_SPREAD, MODIFY_RANGE):
    323                 self.ShowCentroidLines()
    324             else:
    325                 self.RemoveCentroidLines()
    326 
    327         if self.highlightCursorData:
    328             self.HighlightCursors(*self.highlightCursorData)
    329 
    330     def HasAvailableProbes(self):
    331         return self.probeTracker.HasAvailableProbes()
    332 
    333     def SetScanDronesState(self, value):
    334         for probe in self.probeControlsByID.values():
    335             probe.SetScanDronesState(value)
    336 
    337     def SetResultFilter(self, showResults, update = False):
    338         self._filterResults = showResults
    339         if update:
    340             self.UpdateScanResult()
    341 
    342     def UpdateScanResult(self, animate = False):
    343         if not self.systemMapHandler or self.systemMapHandler.solarsystemID != session.solarsystemid2:
    344             return
    345         if not self.systemMapHandler.markersHandler:
    346             return
    347         previousMarkerIDs = self.resultMarkers.copy()
    348         self.resultMarkers = set()
    349         previousSpheresAndCircles = self.resultObjectsByID.copy()
    350         self.resultObjectsByID = {}
    351         self.lineIDsByID = defaultdict(list)
    352         results, ignored, filtered, filteredAnomalies = self.scanSvc.GetResults()
    353         for result in results:
    354             if self._filterResults and result.id not in self._filterResults:
    355                 continue
    356             if result.id in previousSpheresAndCircles:
    357                 for obj in previousSpheresAndCircles[result.id]:
    358                     self.parentTransform.children.remove(obj)
    359 
    360                 del previousSpheresAndCircles[result.id]
    361             if isinstance(result.data, float):
    362                 self.CreateSphereResult(result, animate=animate)
    363             elif isinstance(result.data, (tuple, list)):
    364                 self.CreatePointResult(result, animate=animate)
    365             else:
    366                 self.CreateCircleResult(result, animate=animate)
    367 
    368         oldMarkerIDs = previousMarkerIDs.difference(self.resultMarkers)
    369         for each in oldMarkerIDs:
    370             self.systemMapHandler.markersHandler.RemoveMarker(each)
    371 
    372         previousSpheresAndCirclesIDs = set(previousSpheresAndCircles.keys())
    373         spheresAndCirclesIDs = set(self.resultObjectsByID.keys())
    374         oldSpheresAndCirclesIDs = previousSpheresAndCirclesIDs.difference(spheresAndCirclesIDs)
    375         for oldResultID in oldSpheresAndCirclesIDs:
    376             for obj in previousSpheresAndCircles[oldResultID]:
    377                 self.parentTransform.children.remove(obj)
    378 
    379         self.UpdateSelectedObjects()
    380 
    381     def OnSiteSelectionChanged(self):
    382         self.UpdateSelectedObjects()
    383 
    384     def UpdateSelectedObjects(self):
    385         for siteID, objects in self.resultObjectsByID.iteritems():
    386             for object in objects:
    387                 if object.name.startswith('scanResult_'):
    388                     isSelected = self.scanSvc.IsSiteSelected(siteID)
    389                     sphere = object.children[0]
    390                     self._SetSphereSelectedState(sphere, isSelected)
    391                 elif siteID in self.lineIDsByID:
    392                     lineIDs = self.lineIDsByID[siteID]
    393                     if self.scanSvc.IsSiteSelected(siteID):
    394                         color = CIRCLE_COLOR_SELECTED
    395                     else:
    396                         color = CIRCLE_COLOR_DESELECTED
    397                     for lineID in lineIDs:
    398                         object.ChangeLineColor(lineID, color, color)
    399 
    400                     object.SubmitChanges()
    401 
    402     def _SetSphereSelectedState(self, sphere, isSelected):
    403         sphere.children[0].children[0].mesh.additiveAreas[0].display = isSelected
    404         sphere.children[0].children[0].children[1].display = isSelected
    405         sphere.children[0].children[0].children[2].display = isSelected
    406         sphere.children[0].children[1].display = isSelected
    407 
    408     def UpdateProbeSpheres(self, animate = False):
    409         uthread.Lock('MapViewProbeHandler::UpdateProbeSpheres')
    410         try:
    411             bp = sm.GetService('michelle').GetBallpark()
    412             if not bp or session.shipid not in bp.balls:
    413                 self.Cleanup()
    414                 return
    415             probeData = self.probeTracker.GetProbeData()
    416             probeIDs = self.probeControlsByID.keys()[:]
    417             for probeID in probeIDs:
    418                 if probeID not in probeData or probeData[probeID].state == probeStateInactive:
    419                     probeControl = self.probeControlsByID[probeID]
    420                     probeControl.Remove(animate=animate)
    421                     del self.probeControlsByID[probeID]
    422 
    423             if probeData and self.centerProbeControl is None:
    424                 self.centerProbeControl = BaseProbeControl(FORMATION_CONTROL_ID, self.parentTransform)
    425                 uthread.new(self.UpdatProbeControlArrowsThread)
    426             for probeID, probe in probeData.items():
    427                 if probe.state == probeStateInactive:
    428                     continue
    429                 if probeID not in self.probeControlsByID:
    430                     probeControl = ProbeControl(probeID, probe, self.parentTransform)
    431                     self.probeControlsByID[probeID] = probeControl
    432                 else:
    433                     probeControl = self.probeControlsByID[probeID]
    434                 probeControl.SetRange(probe.scanRange, animate=animate)
    435                 probeControl.SetPosition(probe.destination, animate=animate)
    436 
    437             self.HighlightProbeIntersections()
    438             self.HighlightMarkersInProbeRange()
    439             self.UpdateProbeControlDisplay()
    440         finally:
    441             uthread.UnLock('MapViewProbeHandler::UpdateProbeSpheres')
    442             self.updateProbeSpheresTimer = None
    443 
    444         centerPosition = self.probeTracker.GetCenterOfActiveProbes()
    445         for probeID, probeControl in self.probeControlsByID.iteritems():
    446             probeControl.SetFormationCenter(centerPosition)
    447 
    448         if self.centerProbeControl:
    449             self.centerProbeControl.SetPosition(self.probeTracker.GetCenterOfActiveProbes(), animate=animate)
    450         if self.systemMapHandler:
    451             self.systemMapHandler.LoadProbeMarkers()
    452 
    453     def UpdatProbeControlArrowsThread(self):
    454         while self.centerProbeControl and self.systemMapHandler and self.systemMapHandler.markersHandler:
    455             camera = self.systemMapHandler.markersHandler.mapView.camera
    456             self.centerProbeControl.UpdateArrowOrientation(camera)
    457             self.centerProbeControl.UpdateArrowVisibility(camera)
    458             for probe in self.probeControlsByID.values():
    459                 probe.UpdateArrowOrientation(camera)
    460 
    461             blue.synchro.Yield()
    462 
    463     def HighlightCursors(self, activeProbeControl = None, axis = None):
    464         SHIFT = uicore.uilib.Key(uiconst.VK_SHIFT)
    465         self.highlightCursorData = (activeProbeControl, axis)
    466         if self.centerProbeControl:
    467             if self.centerProbeControl is activeProbeControl or not SHIFT and axis:
    468                 self.centerProbeControl.SetCursorState(self.centerProbeControl.STATE_ACTIVE, axis)
    469             else:
    470                 self.centerProbeControl.SetCursorState(self.centerProbeControl.STATE_IDLE, axis)
    471         for probeID, probeControl in self.probeControlsByID.iteritems():
    472             if self.probeTracker.GetProbeState(probeID) != probeStateIdle:
    473                 continue
    474             if not probeControl.IsVisible():
    475                 continue
    476             if activeProbeControl is None:
    477                 probeControl.SetCursorState(probeControl.STATE_IDLE, axis)
    478             elif probeControl is activeProbeControl or not SHIFT:
    479                 probeControl.SetCursorState(probeControl.STATE_ACTIVE, axis)
    480             else:
    481                 probeControl.SetCursorState(probeControl.STATE_IDLE, axis)
    482 
    483     def HighlightProbeIntersections(self, showAll = False):
    484         probeIDs = self.probeTracker.GetActiveProbes()
    485         probeIDs.sort()
    486         possiblePairs = [ pair for pair in itertools.combinations(probeIDs, 2) ]
    487         activePairs = []
    488         for pair in possiblePairs:
    489             id1, id2 = pair
    490             probe1 = self.GetProbeControl(id1)
    491             probe2 = self.GetProbeControl(id2)
    492             if not probe1 or not probe2:
    493                 self.RemoveIntersection(pair)
    494                 continue
    495             pos1 = probe1.GetPosition()
    496             radius1 = probe1.GetRange()
    497             pos2 = probe2.GetPosition()
    498             radius2 = probe2.GetRange()
    499             if (showAll or not self.probeTracker.IsInFormation()) and IsIntersecting(pos1, radius1, pos2, radius2):
    500                 if pair not in self.probeIntersectionsByPair:
    501                     intersection = ProbesIntersection(pair)
    502                     self.parentTransform.children.append(intersection.transform)
    503                     self.probeIntersectionsByPair[pair] = intersection
    504                 changed = self.SetIntersectionHighlight(pair, (pos1,
    505                  pos2,
    506                  radius1,
    507                  radius2))
    508                 if changed:
    509                     activePairs.append(pair)
    510             else:
    511                 self.RemoveIntersection(pair)
    512 
    513         for pair in self.probeIntersectionsByPair.keys():
    514             if pair not in possiblePairs:
    515                 self.RemoveIntersection(pair)
    516 
    517         if not getattr(self, 'fadeActiveIntersectionsTimers', {}):
    518             self.fadeActiveIntersectionsTimers = {}
    519         for each in activePairs:
    520             intersection = self.probeIntersectionsByPair.get(each)
    521             if intersection:
    522                 uicore.animations.MorphScalar(intersection, 'opacity', startVal=intersection.opacity, endVal=INTERSECTION_ACTIVE, duration=0.1)
    523                 self.fadeActiveIntersectionsTimers[each] = AutoTimer(500, self.FadeOutIntersection, each)
    524 
    525     def ComputeHighlightCircle(self, distance, pos1, pos2, rad1, rad2):
    526         if not distance:
    527             return None
    528         rad1_sq = rad1 ** 2
    529         rad2_sq = rad2 ** 2
    530         dist_sq = distance ** 2
    531         distToPoint = (rad1_sq - rad2_sq + dist_sq) / (2 * distance)
    532         radius_sq = rad1_sq - distToPoint ** 2
    533         if radius_sq < 0.0:
    534             return None
    535         radius = math.sqrt(radius_sq)
    536         normal = geo2.Vec3Normalize(pos2 - pos1)
    537         normal = geo2.Vector(*normal)
    538         point = pos1 + normal * distToPoint
    539         rotation = geo2.QuaternionRotationArc(AXIS_Z, normal)
    540         return (point, rotation, radius)
    541 
    542     def SetIntersectionHighlight(self, pair, config):
    543         intersection = self.probeIntersectionsByPair[pair]
    544         if repr(config) != repr(intersection.lastConfig):
    545             intersection.lastConfig = config
    546             intersection.opacity = INTERSECTION_ACTIVE
    547             pos1, pos2, radius1, radius2 = config
    548             newDistance = geo2.Vec3Length(geo2.Vec3Subtract(pos1, pos2))
    549             self.UpdateIntersection(pair, newDistance)
    550             return True
    551         return False
    552 
    553     def RemoveIntersection(self, pair):
    554         if pair in self.probeIntersectionsByPair:
    555             intersection = self.probeIntersectionsByPair[pair]
    556             if intersection.transform in self.parentTransform.children:
    557                 self.parentTransform.children.remove(intersection.transform)
    558             del self.probeIntersectionsByPair[pair]
    559         try:
    560             del self.fadeActiveIntersectionsTimers[pair]
    561         except:
    562             pass
    563 
    564     def UpdateIntersection(self, pair, distance):
    565         intersection = self.probeIntersectionsByPair[pair]
    566         data = self.ComputeHighlightCircle(distance, *intersection.lastConfig)
    567         if data:
    568             point, rotation, radius = data
    569             tr = intersection.transform
    570             tr.translation = point
    571             tr.rotation = rotation
    572             tr.scaling = (radius * 2.0, radius * 2.0, radius * 2.0)
    573             changed = True
    574         else:
    575             self.RemoveIntersection(pair)
    576             changed = False
    577         return changed
    578 
    579     def FadeOutIntersection(self, pairID):
    580         del self.fadeActiveIntersectionsTimers[pairID]
    581         intersection = self.probeIntersectionsByPair.get(pairID, None)
    582         if not intersection:
    583             return
    584         uicore.animations.MorphScalar(intersection, 'opacity', startVal=intersection.opacity, endVal=INTERSECTION_INACTIVE, duration=1.5)
    585 
    586     def ShowCentroidLines(self):
    587         if self.centroidLines is None:
    588             self.centroidLines = mapViewUtil.CreateLineSet()
    589             self.centroidLines.name = 'centroidLines'
    590             self.parentTransform.children.append(self.centroidLines)
    591         self.centroidLines.display = True
    592         probes = self.probeTracker.GetProbeData()
    593         probeIDs = [ probeID for probeID, probe in probes.iteritems() if probe.state == probeStateIdle ]
    594         if probeIDs:
    595             probeIDs.sort()
    596             update = self.lastProbeIDs == probeIDs
    597             if not update:
    598                 self.lastProbeIDs = probeIDs
    599                 self.centroidLines.ClearLines()
    600             centroid = geo2.Vector(0, 0, 0)
    601             probePositions = []
    602             scanRanges = []
    603             for probeID in probeIDs:
    604                 probeControl = self.GetProbeControl(probeID)
    605                 if probeControl:
    606                     p = probeControl.GetPosition()
    607                     centroid += p
    608                     probePositions.append((p.x, p.y, p.z))
    609                     scanRanges.append(probeControl.GetRange())
    610 
    611             editMode = self.GetActiveEditMode() or self.GetEditMode()
    612             centroid /= len(probeIDs)
    613             c = (centroid.x, centroid.y, centroid.z)
    614             for index, position in enumerate(probePositions):
    615                 startPosition = c
    616                 if editMode == MODIFY_RANGE:
    617                     v = geo2.Vec3Subtract(position, c)
    618                     l = geo2.Vec3Length(v)
    619                     vN = geo2.Vec3Normalize(v)
    620                     if uicore.uilib.Key(uiconst.VK_SHIFT):
    621                         startPosition = position
    622                     position = geo2.Vec3Add(c, geo2.Vec3Scale(vN, l + scanRanges[index]))
    623                 if update:
    624                     self.centroidLines.ChangeLinePositionCrt(index, startPosition, position)
    625                     self.centroidLines.ChangeLineAnimation(index, CENTROID_LINE_COLOR, -0.25, 10.0)
    626                 else:
    627                     self.centroidLines.AddStraightLine(startPosition, CENTROID_LINE_COLOR, position, CENTROID_LINE_COLOR, CENTROID_LINE_WIDTH)
    628 
    629             self.centroidLines.SubmitChanges()
    630 
    631     def RemoveCentroidLines(self):
    632         if self.centroidLines and self.centroidLines in self.parentTransform.children:
    633             self.parentTransform.children.remove(self.centroidLines)
    634         self.centroidLines = None
    635         self.centroidTimer = None
    636         self.lastProbeIDs = None
    637 
    638     @property
    639     def probeTracker(self):
    640         return self.scanSvc.GetProbeTracker()
    641 
    642     def GetProbeControl(self, probeID):
    643         if probeID == FORMATION_CONTROL_ID:
    644             return self.centerProbeControl
    645         else:
    646             return self.probeControlsByID.get(int(probeID), None)
    647 
    648     def GetProbeControls(self):
    649         return self.probeControlsByID
    650 
    651     def GetCenterPosition(self, positions):
    652         accPos = geo2.Vector((0, 0, 0))
    653         if not positions:
    654             return accPos
    655         for pos in positions:
    656             if isinstance(pos, (tuple, list)):
    657                 accPos += geo2.Vector(pos)
    658             else:
    659                 accPos += pos
    660 
    661         return geo2.Vec3Scale(accPos, 1.0 / len(positions))
    662 
    663     def GetWorldPositionCenterOfActiveProbes(self):
    664         probes = self.probeTracker.GetProbeData()
    665         return self.GetCenterPosition([ self.GetProbeControl(probeID).GetWorldPosition() for probeID, probe in probes.iteritems() if probe.state == probeStateIdle ])
    666 
    667     def InitProbeScaling(self, probeScenePosition, centerScenePosition, mousePositionInProbePlane, mousePositionInCenterPlane):
    668         self.initProbeScaleData = (probeScenePosition,
    669          centerScenePosition,
    670          mousePositionInProbePlane,
    671          mousePositionInCenterPlane)
    672         self._activeEditMode = MODIFY_RANGE
    673 
    674     def InitProbeMove(self, probeScenePosition, centerScenePosition, mousePositionInProbeAxisPlane, mousePositionInCenterAxisPlane):
    675         self.probeTracker.StartMoveMode()
    676         self.StartProbeMoveSound()
    677         self.initProbeMoveData = (probeScenePosition,
    678          centerScenePosition,
    679          mousePositionInProbeAxisPlane,
    680          mousePositionInCenterAxisPlane)
    681         self._activeEditMode = self.GetEditMode()
    682 
    683     def StartProbeMoveSound(self):
    684         if not self.updatesScanHitsThread:
    685             self.updatesScanHitsThread = uthread.new(self._UpdateScanHitsThread)
    686         self.UpdateScanHitsSoundParameter()
    687         PlaySound('msg_newscan_probe_move_scale_play')
    688 
    689     def _UpdateScanHitsThread(self):
    690         while True:
    691             self.UpdateScanHitsSoundParameter()
    692             blue.synchro.Yield()
    693 
    694     def UpdateScanHitsSoundParameter(self):
    695         maxHits = self.UpdateMaxScanHits()
    696         SetSoundParameter('msg_newscan_probe_move_scale_rtpc', maxHits)
    697 
    698     def UpdateMaxScanHits(self):
    699         probes = self.probeControlsByID.values()
    700         probes = [ (geo2.Vec3Scale(probe.GetPosition(), SOLARSYSTEM_SCALE), probe.GetRange() * SOLARSYSTEM_SCALE) for probe in probes ]
    701         resultMarkers = self.systemMapHandler.markersHandler.GetMarkersByType(MARKERID_SCANRESULT)
    702         if resultMarkers:
    703             return max((self._GetNumHitsForSite(probes, siteMarker) for siteMarker in resultMarkers))
    704         else:
    705             return 0
    706 
    707     def _GetNumHitsForSite(self, probes, siteMarker):
    708         return sum((self._IsSiteWithinProbeRange(probePos, probeRadius, siteMarker.position) for probePos, probeRadius in probes))
    709 
    710     def _IsSiteWithinProbeRange(self, probePos, probeRadius, sitePos):
    711         return geo2.Vec3Distance(probePos, sitePos) < probeRadius
    712 
    713     def StopProbeMoveSound(self):
    714         if self.updatesScanHitsThread:
    715             self.updatesScanHitsThread.kill()
    716             self.updatesScanHitsThread = None
    717         PlaySound('msg_newscan_probe_move_scale_stop')
    718 
    719     def RegisterProbeScale(self, probeControl):
    720         self.HighlightMarkersInProbeRange()
    721         probeControl.HideScanRanges()
    722         self.probeTracker.UnsetAsScaling()
    723         probeID = probeControl.uniqueID
    724         probe = self.probeTracker.GetProbe(probeID)
    725         currentSize = probe.scanRange
    726         desiredSize = self.probeControlsByID[probeID].GetRange()
    727         rangeStep, desiredSize = self.probeTracker.GetRangeStepForType(probe.typeID, desiredSize)
    728         if not uicore.uilib.Key(uiconst.VK_SHIFT):
    729             scale = desiredSize / currentSize
    730             self.probeTracker.ScaleAllProbes(scale)
    731         else:
    732             self.probeTracker.SetProbeRangeStep(probeID, rangeStep)
    733         self.probeTracker.PersistProbeFormation()
    734         self.probeTracker.PurgeBackupData()
    735         self.UpdateProbeSpheres()
    736         self.UpdateProbeControlDisplay()
    737         self._activeEditMode = None
    738         self.StopProbeMoveSound()
    739 
    740     def RegisterProbeMove(self, *args):
    741         probes = self.probeTracker.GetProbeData()
    742         for probeID, probe in probes.iteritems():
    743             if probe.state != probeStateIdle:
    744                 continue
    745             probeControl = self.GetProbeControl(probeID)
    746             if probeControl:
    747                 cachedPos = probes[probeID].destination
    748                 currentPos = probeControl.locator.translation
    749                 if geo2.Vec3DistanceD(cachedPos, currentPos):
    750                     self.probeTracker.SetProbeDestination(probeID, currentPos)
    751 
    752         self.probeTracker.PersistProbeFormation()
    753         self.probeTracker.PurgeBackupData()
    754         self.UpdateProbeSpheres()
    755         self.UpdateProbeControlDisplay()
    756         self.HighlightMarkersInProbeRange()
    757         self._activeEditMode = None
    758         self.StopProbeMoveSound()
    759 
    760     def ScaleProbe(self, probeControl, currentCursorPosInProbePlane, currentCursorPosInCenterPlane):
    761         probeScenePosition, centerScenePosition, mousePositionInProbePlane, mousePositionInCenterPlane = self.initProbeScaleData
    762         shift = uicore.uilib.Key(uiconst.VK_SHIFT)
    763         if shift:
    764             initDistance = geo2.Vec3Length(geo2.Vec3Subtract(probeScenePosition, mousePositionInProbePlane))
    765             distanceToFocusPoint = geo2.Vec3Length(geo2.Vec3Subtract(probeScenePosition, currentCursorPosInProbePlane))
    766             scale = distanceToFocusPoint / initDistance
    767             scaleOthers = 1.0
    768         else:
    769             initDistance = geo2.Vec3Length(geo2.Vec3Subtract(centerScenePosition, mousePositionInCenterPlane))
    770             distanceToFocusPoint = geo2.Vec3Length(geo2.Vec3Subtract(centerScenePosition, currentCursorPosInCenterPlane))
    771             scale = distanceToFocusPoint / initDistance
    772             scaleOthers = scale
    773         probeIDs = [ probeID for probeID in self.probeTracker.GetProbeData() ]
    774         probe = self.probeTracker.GetProbe(probeControl.uniqueID)
    775         probeControl.SetRange(probe.scanRange * scale)
    776         probesInfo = self.probeTracker.GetScaledProbesData(probeIDs, scaleOthers)
    777         positions = []
    778         for probeID, probePos, scanRange in probesInfo:
    779             _probeControl = self.probeControlsByID[probeID]
    780             if probeID != probeControl.uniqueID:
    781                 _probeControl.SetRange(scanRange)
    782             _probeControl.SetPosition(probePos)
    783             positions.append(probePos)
    784 
    785         if self.centerProbeControl:
    786             centerPosition = self.GetCenterPosition(positions)
    787             self.centerProbeControl.SetPosition(centerPosition)
    788         self.HighlightMarkersInProbeRange()
    789         self.HighlightCursors(probeControl)
    790         self.UpdateProbeControlDisplay()
    791 
    792     def MoveProbe(self, probeControl, moveAxis, currentCursorPosInProbeAxisPlane, currentCursorPosInCenterAxisPlane):
    793         alt = uicore.uilib.Key(uiconst.VK_MENU)
    794         shift = uicore.uilib.Key(uiconst.VK_SHIFT)
    795         probeIDs = [ probeID for probeID in self.probeTracker.GetProbeData() ]
    796         allPositionDiff = (0, 0, 0)
    797         probePositionDiff = (0, 0, 0)
    798         positionOverride = {}
    799         probesInfo = self.probeTracker.GetScaledProbesData(probeIDs, 1.0)
    800         probeScenePosition, centerScenePosition, mousePositionInProbeAxisPlane, mousePositionInCenterAxisPlane = self.initProbeMoveData
    801         if self._activeEditMode == MODIFY_SPREAD:
    802             initDistance = geo2.Vec3Length(geo2.Vec3Subtract(centerScenePosition, mousePositionInCenterAxisPlane))
    803             distanceToFocusPoint = geo2.Vec3Length(geo2.Vec3Subtract(centerScenePosition, currentCursorPosInCenterAxisPlane))
    804             scale = distanceToFocusPoint / initDistance
    805             if shift:
    806                 modProbesInfo = self.probeTracker.GetScaledProbesData([probeControl.uniqueID], scale)
    807                 positionOverride[probeControl.uniqueID] = modProbesInfo[0][1]
    808             else:
    809                 probesInfo = self.probeTracker.GetScaledProbesData(probeIDs, scale)
    810         elif self._activeEditMode == MODIFY_POSITION and currentCursorPosInProbeAxisPlane:
    811             initPosition = geo2.Vec3Subtract(probeScenePosition, mousePositionInProbeAxisPlane)
    812             currentPosition = geo2.Vec3Subtract(probeScenePosition, currentCursorPosInProbeAxisPlane)
    813             positionDiff = geo2.Vec3Scale(geo2.Vec3Subtract(initPosition, currentPosition), 1 / SOLARSYSTEM_SCALE)
    814             if shift:
    815                 probePositionDiff = self.ClampVector(positionDiff, moveAxis)
    816             else:
    817                 allPositionDiff = self.ClampVector(positionDiff, moveAxis)
    818         else:
    819             return
    820         positions = []
    821         for probeID, probePos, scanRange in probesInfo:
    822             _probeControl = self.probeControlsByID[probeID]
    823             newPosition = positionOverride.get(probeID, geo2.Vec3Add(probePos, allPositionDiff))
    824             if probeID == probeControl.uniqueID:
    825                 newPosition = geo2.Vec3Add(newPosition, probePositionDiff)
    826             _probeControl.SetPosition(newPosition)
    827             positions.append(newPosition)
    828 
    829         centerPosition = self.GetCenterPosition(positions)
    830         for probeID, probePos, scanRange in probesInfo:
    831             _probeControl = self.probeControlsByID[probeID]
    832             _probeControl.SetFormationCenter(centerPosition)
    833 
    834         if self.centerProbeControl:
    835             self.centerProbeControl.SetPosition(centerPosition)
    836         self.HighlightCursors(probeControl, moveAxis)
    837         if shift or self._activeEditMode == MODIFY_SPREAD:
    838             self.HighlightProbeIntersections(showAll=True)
    839         else:
    840             self.HighlightProbeIntersections()
    841         self.UpdateProbeControlDisplay()
    842 
    843     def ClampVector(self, vec, axis):
    844         if axis == 'xz':
    845             x, y, z = vec
    846             return (x, 0.0, z)
    847         if axis == 'xy':
    848             x, y, z = vec
    849             return (x, y, 0.0)
    850         if axis == 'yz':
    851             x, y, z = vec
    852             return (0.0, y, z)
    853         if axis == 'x':
    854             scaledDir = (1.0, 0.0, 0.0)
    855         elif axis == 'y':
    856             scaledDir = (0.0, 1.0, 0.0)
    857         elif axis == 'z':
    858             scaledDir = (0.0, 0.0, 1.0)
    859         dot = geo2.Vec3Dot(vec, scaledDir)
    860         scaledDir = geo2.Vec3Scale(scaledDir, dot)
    861         return scaledDir
    862 
    863     def CancelProbeMoveOrScaling(self, *args):
    864         self.RemoveCentroidLines()
    865         self.probeTracker.RestoreProbesFromBackup()
    866         self.UpdateProbeSpheres()
    867         for probeControl in self.probeControlsByID.itervalues():
    868             probeControl.HideScanRanges()
    869 
    870         self.HighlightMarkersInProbeRange()
    871         self._activeEditMode = None
    872         self.StopProbeMoveSound()
    873 
    874     def FocusOnProbe(self, probeID):
    875         try:
    876             probeID = int(probeID)
    877         except ValueError:
    878             focusPoint = self.probeTracker.GetCenterOfActiveProbes()
    879         else:
    880             focusPoint = self.probeTracker.GetProbe(probeID).destination
    881 
    882         self.systemMapHandler.markersHandler.mapView.SetCameraPointOfInterestSolarSystemPosition(self.systemMapHandler.solarsystemID, focusPoint)
    883 
    884     def CreateSphereResult(self, result, animate = False):
    885         sphereSize = result.data
    886         sphere = trinity.Load('res:/dx9/model/UI/scanbubblehitsphere.red')
    887         sphere.name = 'Result sphere'
    888         sphere.scaling = (sphereSize / 4, sphereSize / 4, sphereSize / 4)
    889         self._SetSphereSelectedState(sphere, False)
    890         locator = trinity.EveTransform()
    891         locator.name = 'scanResult_%s' % result.id
    892         locator.translation = result.pos
    893         locator.children.append(sphere)
    894         self.parentTransform.children.append(locator)
    895         if result.id not in self.resultObjectsByID:
    896             self.resultObjectsByID[result.id] = []
    897         self.resultObjectsByID[result.id].append(locator)
    898         markerID = (MARKERID_SCANRESULT, (result.id, 0))
    899         markerObject = self.systemMapHandler.markersHandler.GetMarkerByID(markerID)
    900         if markerObject:
    901             markerObject.UpdateResultData(result)
    902             markerObject.UpdateMapPositionLocal(SolarSystemPosToMapPos(result.pos), animate)
    903         else:
    904             self.systemMapHandler.markersHandler.AddSolarSystemBasedMarker(markerID, MarkerScanResult, resultData=result, solarSystemID=self.systemMapHandler.solarsystemID, mapPositionLocal=SolarSystemPosToMapPos(result.pos), mapPositionSolarSystem=self.systemMapHandler.position)
    905         self.resultMarkers.add(markerID)
    906 
    907     def CreateCircleResult(self, result, animate = False):
    908         self._DrawCircleResultLines(result)
    909         markerID = (MARKERID_SCANRESULT, (result.id, 0))
    910         markerObject = self.systemMapHandler.markersHandler.GetMarkerByID(markerID)
    911         if markerObject:
    912             markerObject.UpdateResultData(result)
    913             markerObject.UpdateMapPositionLocal(SolarSystemPosToMapPos(result.data.point), animate)
    914         else:
    915             self.systemMapHandler.markersHandler.AddSolarSystemBasedMarker(markerID, MarkerScanResult, resultData=result, solarSystemID=self.systemMapHandler.solarsystemID, mapPositionLocal=SolarSystemPosToMapPos(result.data.point), mapPositionSolarSystem=self.systemMapHandler.position)
    916         self.resultMarkers.add(markerID)
    917 
    918     def _DrawCircleResultLines(self, result):
    919         lineSet = mapViewUtil.CreateLineSet()
    920         self.parentTransform.children.append(lineSet)
    921         if result.id not in self.resultObjectsByID:
    922             self.resultObjectsByID[result.id] = []
    923         self.resultObjectsByID[result.id].append(lineSet)
    924         scale = 500.0
    925         lineSet.scaling = (scale, scale, scale)
    926         lineSet.translation = result.data.point
    927         lineSet.rotation = geo2.QuaternionRotationArc((0.0, 1.0, 0.0), result.data.normal)
    928         radius = result.data.radius / scale
    929         lineIDs = mapViewUtil.DrawCircle(lineSet, centerPosition=(0, 0, 0), radius=radius, startColor=CIRCLE_COLOR_ANIM, endColor=CIRCLE_COLOR_ANIM, lineWidth=RESULT_LINE_WIDTH * 0.85)
    930         length = math.pi * 2 * result.data.radius * SOLARSYSTEM_SCALE
    931         for lineID in lineIDs:
    932             lineSet.ChangeLineAnimation(lineID, CIRCLE_COLOR_ANIM, 0.05, LINE_DASH_LENGTH / length)
    933 
    934         self.lineIDsByID[result.id].extend(lineIDs)
    935         lineSet.SubmitChanges()
    936 
    937     def CreatePointResult(self, result, animate = False):
    938         isMultiplePoints = isinstance(result.data, list)
    939         if isMultiplePoints:
    940             positions = result.data
    941         else:
    942             positions = [result.data]
    943         for i, position in enumerate(positions):
    944             markerID = (MARKERID_SCANRESULT, (result.id, i))
    945             markerObject = self.systemMapHandler.markersHandler.GetMarkerByID(markerID)
    946             if markerObject:
    947                 markerObject.UpdateResultData(result)
    948                 markerObject.UpdateMapPositionLocal(SolarSystemPosToMapPos(position), animate)
    949             else:
    950                 self.systemMapHandler.markersHandler.AddSolarSystemBasedMarker(markerID, MarkerScanResult, resultData=result, solarSystemID=self.systemMapHandler.solarsystemID, mapPositionLocal=SolarSystemPosToMapPos(position), mapPositionSolarSystem=self.systemMapHandler.position)
    951             self.resultMarkers.add(markerID)
    952 
    953         if isMultiplePoints:
    954             self._DrawPointResultLines(result)
    955 
    956     def _DrawPointResultLines(self, result):
    957         lineSet = mapViewUtil.CreateLineSet()
    958         self.parentTransform.children.append(lineSet)
    959         if result.id not in self.resultObjectsByID:
    960             self.resultObjectsByID[result.id] = []
    961         self.resultObjectsByID[result.id].append(lineSet)
    962         p0 = result.data[0]
    963         p1 = result.data[1]
    964         length = geo2.Vec3Distance(p0, p1) * SOLARSYSTEM_SCALE
    965         lineID = lineSet.AddStraightLine(p0, CIRCLE_COLOR_ANIM, p1, CIRCLE_COLOR_ANIM, RESULT_LINE_WIDTH)
    966         self.lineIDsByID[result.id].append(lineID)
    967         lineSet.ChangeLineAnimation(lineID, CIRCLE_COLOR_ANIM, 0.05, LINE_DASH_LENGTH / length)
    968         lineSet.SubmitChanges()
    969 
    970     def HighlightProbeBorder(self, probeControl = None):
    971         probeControls = self.GetProbeControls()
    972         for _probeID, _probeControl in probeControls.iteritems():
    973             if probeControl and _probeControl is probeControl:
    974                 probeControl.HighlightBorder(True)
    975             else:
    976                 _probeControl.HighlightBorder(False)
    977 
    978     def HighlightMarkersInProbeRange(self):
    979         if getattr(self, 'lastHighlightItemsWithinProbeRange', None):
    980             timeDiff = blue.os.TimeDiffInMs(self.lastHighlightItemsWithinProbeRange, blue.os.GetWallclockTime())
    981             if timeDiff < 200.0:
    982                 return
    983         self.lastHighlightItemsWithinProbeRange = blue.os.GetWallclockTime()
    984         if self.systemMapHandler is None:
    985             return
    986         probeData = self.probeTracker.GetProbeData()
    987         validProbes = [ probeID for probeID, probe in probeData.iteritems() if probe.state != const.probeStateInactive ]
    988         markerID_position = {}
    989         solarsystemMarkerIDs = self.systemMapHandler.GetMarkerIDs()
    990         for markerID in solarsystemMarkerIDs:
    991             markerObject = self.systemMapHandler.markersHandler.GetMarkerByID(markerID)
    992             if markerObject:
    993                 solarSystemPosition = MapPosToSolarSystemPos(markerObject.mapPositionLocal)
    994                 markerID_position[markerID] = solarSystemPosition
    995 
    996         inRangeOfProbe = []
    997         probeControls = self.GetProbeControls()
    998         for probeID in validProbes:
    999             if probeID not in probeControls:
   1000                 continue
   1001             probeControl = probeControls[probeID]
   1002             pPos = probeControl.GetPosition()
   1003             pRange = probeControl.GetRange()
   1004             for markerID, position in markerID_position.items():
   1005                 if pRange > geo2.Vec3Length(geo2.Vec3Subtract(pPos, position)):
   1006                     inRangeOfProbe.append(markerID)
   1007                     markerID_position.pop(markerID, None)
   1008 
   1009             if not markerID_position:
   1010                 break
   1011 
   1012         for markerID in solarsystemMarkerIDs:
   1013             markerObject = self.systemMapHandler.markersHandler.GetMarkerByID(markerID)
   1014             if not markerObject or not hasattr(markerObject, 'SetInRangeIndicatorState'):
   1015                 continue
   1016             markerObject.SetInRangeIndicatorState(markerID in inRangeOfProbe)
   1017 
   1018 
   1019 class ProbesIntersection(object):
   1020     _opacity = 0.0
   1021     lastConfig = None
   1022 
   1023     def __init__(self, probePair):
   1024         eff = trinity.Tr2Effect()
   1025         eff.effectFilePath = 'res:/Graphics/Effect/Managed/Space/SpecialFX/TextureColor.fx'
   1026         sampler = list(eff.samplerOverrides.GetDefaultValue())
   1027         sampler[0] = 'DiffuseMapSampler'
   1028         sampler[1] = trinity.TRITADDRESS_CLAMP
   1029         sampler[2] = trinity.TRITADDRESS_CLAMP
   1030         eff.samplerOverrides.append(tuple(sampler))
   1031         diffuseColor = trinity.Tr2Vector4Parameter()
   1032         diffuseColor.name = 'DiffuseColor'
   1033         eff.parameters.append(diffuseColor)
   1034         self.diffuseColor = diffuseColor
   1035         diffuseMap = trinity.TriTextureParameter()
   1036         diffuseMap.name = 'DiffuseMap'
   1037         diffuseMap.resourcePath = 'res:/UI/Texture/classes/ProbeScanner/intersectionCircle.png'
   1038         eff.resources.append(diffuseMap)
   1039         mesha = trinity.Tr2MeshArea()
   1040         mesha.effect = eff
   1041         mesh = trinity.Tr2Mesh()
   1042         mesh.geometryResPath = 'res:/Model/Global/zsprite.gr2'
   1043         mesh.additiveAreas.append(mesha)
   1044         transform = trinity.EveTransform()
   1045         transform.scaling = (10000.0, 10000.0, 10000.0)
   1046         transform.mesh = mesh
   1047         self.transform = transform
   1048         self.opacity = INTERSECTION_INACTIVE
   1049 
   1050     @apply
   1051     def opacity():
   1052 
   1053         def fget(self):
   1054             return self._opacity
   1055 
   1056         def fset(self, value):
   1057             self._opacity = value
   1058             r, g, b, a = BASE_PROBE_COLOR
   1059             self.diffuseColor.value = (r * value,
   1060              g * value,
   1061              b * value,
   1062              1.0)
   1063 
   1064         return property(**locals())