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)