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

scanHologramHandler.py (8078B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\inflight\scannerFiles\scanHologramHandler.py
      2 import math
      3 import inventorycommon.const as invconst
      4 import evetypes
      5 from carbon.client.script.environment.AudioUtil import PlaySound
      6 from carbonui.uianimations import animations
      7 from eve.client.script.ui.inflight.scannerFiles.directionalScanUtil import GetScanRangeInMeters
      8 from eve.client.script.ui.shared.mapView.mapViewConst import SOLARSYSTEM_SCALE
      9 from evegraphics.utils import BuildSOFDNAFromTypeID
     10 import geo2
     11 import blue
     12 import uthread
     13 import trinity
     14 import dogma.const as dogmaconst
     15 from eve.client.script.environment.sofService import GetSofService
     16 from spacecomponents.common.helper import HasMineableComponent
     17 IGNORE_CATEOGORIES = (invconst.categoryStarbase,
     18  invconst.categoryAsteroid,
     19  invconst.categoryOrbital,
     20  invconst.categorySovereigntyStructure,
     21  invconst.categoryStation,
     22  invconst.categoryStructure)
     23 IGNORE_GROUPS = (invconst.groupStargate,)
     24 DURATION = 0.2
     25 THRESHOLD_LARGE = 2000
     26 THRESHOLD_SMALL = 240.0
     27 SIZE_SMALL = 1
     28 SIZE_MEDIUM = 2
     29 SIZE_LARGE = 3
     30 MAX_IN_GROUP = {SIZE_SMALL: 5,
     31  SIZE_MEDIUM: 3,
     32  SIZE_LARGE: 1}
     33 MAX_GROUPS = 3
     34 
     35 class ScanHologramHandler(object):
     36 
     37     def __init__(self, scene, camera):
     38         self.scene = scene
     39         self.camera = camera
     40         self.hologramModels = []
     41         self.dScanResultIDs = []
     42 
     43     def RenderHolograms(self, results, egoPos, direction):
     44         typeIDs = self.GetTypeIDsToDisplay(results)
     45         if not typeIDs:
     46             return
     47         self.CleanUpHolograms()
     48         typeIDs.sort(key=self.GetTypeRadius, reverse=True)
     49         typeIDGroups = self.GetTypeIDGroups(typeIDs)
     50         blue.synchro.SleepWallclock(500)
     51         for typeIDGroup in typeIDGroups:
     52             PlaySound('msg_newscan_directional_scan_hologram_appear_play')
     53             models = self.ConstructAndPositionModels(typeIDGroup, egoPos, direction)
     54             for i, typeID in enumerate(typeIDGroup):
     55                 model = models[i]
     56                 uthread.new(self.AnimEnterHologram, model, direction, duration=DURATION)
     57 
     58             blue.synchro.SleepWallclock(1000 * (DURATION + 0.3))
     59 
     60     def RenderHologram(self, typeID, egoPos, direction, duration = DURATION):
     61         if not self.IsValidTypeID(typeID):
     62             return
     63         typeIDGroup = [typeID]
     64         models = self.ConstructAndPositionModels(typeIDGroup, egoPos, direction)
     65         self.AnimAppear(direction, models[0], animPos=False)
     66 
     67     def HideHologram(self):
     68         self.CleanUpHolograms()
     69 
     70     def GetTypeIDGroups(self, typeIDs):
     71         ret = []
     72         j = 0
     73         currGroup = None
     74         currSize = None
     75         for typeID in typeIDs:
     76             if currGroup is None:
     77                 currGroup = []
     78                 radius = self.GetTypeRadius(typeID)
     79                 currSize = self.GetSize(radius)
     80             currGroup.append(typeID)
     81             if len(currGroup) == MAX_IN_GROUP[currSize]:
     82                 ret.append(currGroup)
     83                 currGroup = None
     84             if len(ret) == MAX_GROUPS:
     85                 break
     86 
     87         if currGroup:
     88             ret.append(currGroup)
     89         return ret
     90 
     91     def GetSize(self, radius):
     92         if radius > THRESHOLD_LARGE:
     93             return SIZE_LARGE
     94         elif radius > THRESHOLD_SMALL:
     95             return SIZE_MEDIUM
     96         else:
     97             return SIZE_SMALL
     98 
     99     def IsValidTypeID(self, typeID):
    100         if evetypes.GetCategoryID(typeID) in IGNORE_CATEOGORIES:
    101             return False
    102         if evetypes.GetGroupID(typeID) in IGNORE_GROUPS:
    103             return False
    104         if not BuildSOFDNAFromTypeID(typeID):
    105             return False
    106         if HasMineableComponent(typeID):
    107             return False
    108         return True
    109 
    110     def GetTypeIDsToDisplay(self, results):
    111         resultIDs = [ result.id for result in results ]
    112         typeIDs = [ result.typeID for result in results if self.IsNewResult(result) and self.IsValidTypeID(result.typeID) ]
    113         self.dScanResultIDs = resultIDs
    114         return typeIDs
    115 
    116     def IsNewResult(self, result):
    117         return result.id not in self.dScanResultIDs
    118 
    119     def GetTypeRadius(self, typeID):
    120         godma = sm.GetService('godma')
    121         return godma.GetTypeAttribute(typeID, dogmaconst.attributeRadius)
    122 
    123     def ConstructAndPositionModels(self, typeIDGroup, egoPos, direction):
    124         models = [ self.ConstructHologramModel(typeID) for typeID in typeIDGroup ]
    125         numModels = len(models)
    126         xDir = geo2.Vec3Normalize(geo2.Vec3Cross(direction, (0, 1, 0)))
    127         yDir = geo2.Vec3Normalize(geo2.Vec3Cross(direction, xDir))
    128         for i, model in enumerate(models):
    129             self.SetModelRotation(model, direction)
    130             pos = self.GetModelPosition(model, direction, i, numModels, xDir, yDir)
    131             model.translationCurve.value = geo2.Vec3Add(egoPos, pos)
    132 
    133         return models
    134 
    135     def GetModelPosition(self, model, direction, i, numModels, xDir, yDir):
    136         shipRadius = model.GetBoundingSphereRadius()
    137         shipRadius = max(shipRadius, 18)
    138         p0 = geo2.Vec3Scale(direction, 13 + shipRadius + GetScanRangeInMeters() * SOLARSYSTEM_SCALE)
    139         offset = self.GetPositionOffset(i, numModels, 10 + 0.8 * shipRadius, xDir, yDir)
    140         if offset:
    141             p0 = geo2.Vec3Add(p0, offset)
    142         return p0
    143 
    144     def GetPositionOffset(self, i, numModels, r, xDir, yDir):
    145         if numModels == 1:
    146             return None
    147         else:
    148             theta = float(i) / numModels * 2 * math.pi
    149             x = geo2.Vec3Scale(xDir, r * math.cos(theta))
    150             y = geo2.Vec3Scale(yDir, r * math.sin(theta))
    151             return geo2.Vec3Add(x, y)
    152 
    153     def AnimEnterHologram(self, model, direction, duration = 1.0):
    154         self.AnimAppear(direction, model)
    155         blue.synchro.SleepWallclock(duration * 1000)
    156         self.AnimDisappear(direction, model)
    157         self.RemoveHologram(model)
    158 
    159     def AnimAppear(self, direction, model, animPos = True):
    160         if animPos:
    161             animDiff = geo2.Vec3Scale(direction, 5.0)
    162             pos = geo2.Vec3Add(model.translationCurve.value, animDiff)
    163             animations.MorphVector3(model.translationCurve, 'value', pos, model.translationCurve.value, duration=0.1)
    164         animations.MorphScalar(model, 'modelScale', 0.0, model.modelScale, duration=0.05)
    165         for j in xrange(2):
    166             animations.MorphScalar(model, 'activationStrength', 2.0, 1.3, duration=0.15, sleep=True)
    167 
    168     def AnimDisappear(self, direction, model):
    169         animDiff = geo2.Vec3Scale(direction, 30.0)
    170         pos = geo2.Vec3Subtract(model.translationCurve.value, animDiff)
    171         duration = 0.15
    172         animations.MorphVector3(model.translationCurve, 'value', model.translationCurve.value, pos, duration=duration)
    173         animations.MorphScalar(model, 'modelScale', model.modelScale, 0.0, duration=duration)
    174         animations.MorphScalar(model, 'activationStrength', 2.0, 0.0, duration=duration, sleep=True)
    175 
    176     def ConstructHologramModel(self, typeID):
    177         dna = BuildSOFDNAFromTypeID(typeID)
    178         if dna:
    179             sof = GetSofService().spaceObjectFactory
    180             model = sof.BuildFromDNA(dna + ':variant?dscan_hologram:class?mobile')
    181             model.translationCurve = trinity.Tr2TranslationAdapter()
    182             model.modelScale = 3.5 / model.boundingSphereRadius ** 0.6
    183             model.rotationCurve = trinity.Tr2RotationAdapter()
    184             model.activationStrength = 0.0
    185             self.scene.objects.append(model)
    186             self.hologramModels.append(model)
    187             return model
    188 
    189     def SetModelRotation(self, model, direction):
    190         quat = geo2.QuaternionRotationArc((0, 0, -1), direction)
    191         yaw, pitch, _ = geo2.QuaternionRotationGetYawPitchRoll(quat)
    192         quat = geo2.QuaternionRotationSetYawPitchRoll(yaw, pitch, 0.0)
    193         model.rotationCurve.value = quat
    194 
    195     def CleanUpHolograms(self):
    196         for model in self.hologramModels:
    197             self.RemoveHologram(model)
    198 
    199         self.hologramModels = []
    200 
    201     def RemoveHologram(self, model):
    202         self.scene.objects.fremove(model)