effect.py (8911B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\util\effect.py 2 import logging 3 import math 4 import blue 5 import mathext 6 import uthread 7 log = logging.getLogger(__name__) 8 9 class UIEffects: 10 11 def StopBlink(self, sprite): 12 if not getattr(self, 'blink_running', False): 13 return 14 if not hasattr(self, 'remPending'): 15 self.remPending = [] 16 self.remPending.append(id(sprite)) 17 18 def BlinkSpriteA(self, sprite, a, time = 1000.0, maxCount = 10, passColor = 1, minA = 0.0, timeFunc = blue.os.GetWallclockTime): 19 if not hasattr(self, 'blinksA'): 20 self.blinksA = {} 21 key = id(sprite) 22 self.blinksA[key] = (sprite, 23 a, 24 minA, 25 time, 26 maxCount, 27 passColor, 28 timeFunc) 29 if key in getattr(self, 'remPending', []): 30 self.remPending.remove(key) 31 if not getattr(self, 'blink_running', False): 32 self.blink_running = True 33 uthread.new(self._BlinkThread).context = 'UIObject::effect._BlinkThread' 34 35 def BlinkSpriteRGB(self, sprite, r, g, b, time = 1000.0, maxCount = 10, passColor = 1, timeFunc = blue.os.GetWallclockTime): 36 if not hasattr(self, 'blinksRGB'): 37 self.blinksRGB = {} 38 key = id(sprite) 39 self.blinksRGB[key] = (sprite, 40 r, 41 g, 42 b, 43 time, 44 maxCount, 45 passColor, 46 timeFunc) 47 if key in getattr(self, 'remPending', []): 48 self.remPending.remove(key) 49 if not getattr(self, 'blink_running', False): 50 self.blink_running = True 51 uthread.new(self._BlinkThread).context = 'UIObject::effect._BlinkThread' 52 53 def _BlinkThread(self): 54 startTimes = {} 55 countsA = {} 56 countsRGB = {} 57 if not hasattr(self, 'blinksA'): 58 self.blinksA = {} 59 if not hasattr(self, 'blinksRGB'): 60 self.blinksRGB = {} 61 try: 62 while True: 63 if not self: 64 return 65 rem = [] 66 for key, each in self.blinksA.iteritems(): 67 sprite, a, minA, time, maxCount, passColor, timeFunc = each 68 if not sprite or sprite.destroyed: 69 rem.append(key) 70 continue 71 if passColor and getattr(sprite, 'tripass', None): 72 color = sprite.tripass.textureStage0.customColor 73 else: 74 color = sprite.color 75 if key in getattr(self, 'remPending', []): 76 rem.append(key) 77 color.a = minA or a 78 continue 79 now = timeFunc() 80 try: 81 diff = blue.os.TimeDiffInMs(now, startTimes[timeFunc]) 82 except KeyError: 83 startTimes[timeFunc] = now 84 diff = 0 85 86 pos = diff % time 87 if pos < time / 2.0: 88 ndt = min(pos / (time / 2.0), 1.0) 89 color.a = mathext.lerp(a, minA, ndt) 90 else: 91 ndt = min((pos - time / 2.0) / (time / 2.0), 1.0) 92 color.a = mathext.lerp(minA, a, ndt) 93 if key not in countsA: 94 countsA[key] = now 95 if maxCount and blue.os.TimeDiffInMs(countsA[key], now) / time > maxCount: 96 rem.append(key) 97 color.a = minA or a 98 if key in countsA: 99 del countsA[key] 100 101 for each in rem: 102 if each in self.blinksA: 103 del self.blinksA[each] 104 105 rem = [] 106 for key, each in self.blinksRGB.iteritems(): 107 sprite, r, g, b, time, maxCount, passColor, timeFunc = each 108 if not sprite or sprite.destroyed: 109 rem.append(key) 110 continue 111 if passColor and getattr(sprite, 'tripass', None): 112 color = sprite.tripass.textureStage0.customColor 113 else: 114 color = sprite.color 115 if key in getattr(self, 'remPending', []): 116 rem.append(key) 117 color.r = r 118 color.g = g 119 color.b = b 120 continue 121 now = timeFunc() 122 try: 123 diff = blue.os.TimeDiffInMs(now, startTimes[timeFunc]) 124 except KeyError: 125 startTimes[timeFunc] = now 126 diff = 0 127 128 pos = diff % time 129 if pos < time / 2.0: 130 ndt = min(pos / (time / 2.0), 1.0) 131 color.r = mathext.lerp(r, 0.0, ndt) 132 color.g = mathext.lerp(g, 0.0, ndt) 133 color.b = mathext.lerp(b, 0.0, ndt) 134 else: 135 ndt = min((pos - time / 2.0) / (time / 2.0), 1.0) 136 color.r = mathext.lerp(0.0, r, ndt) 137 color.g = mathext.lerp(0.0, g, ndt) 138 color.b = mathext.lerp(0.0, b, ndt) 139 if key not in countsRGB: 140 countsRGB[key] = now 141 if maxCount and blue.os.TimeDiffInMs(countsRGB[key], now) / time > maxCount: 142 rem.append(key) 143 color.r = r 144 color.g = g 145 color.b = b 146 if key in countsRGB: 147 del countsRGB[key] 148 149 for each in rem: 150 if each in self.blinksRGB: 151 del self.blinksRGB[each] 152 153 self.remPending = [] 154 if not len(self.blinksA) and not len(self.blinksRGB) or not self.blink_running: 155 self.blinksA = {} 156 self.blinksRGB = {} 157 self.blink_running = False 158 break 159 blue.pyos.synchro.Yield() 160 161 except Exception: 162 self.blink_running = False 163 log.exception() 164 165 def MorphUIMassSpringDamper(self, item, attrname = None, newVal = 1.0, newthread = 1, float = 1, minVal = -10000000000.0, maxVal = 10000000000.0, dampRatio = 0.11, frequency = 20.0, initSpeed = 0.0, maxTime = 1.0, callback = None, initVal = None, timeFunc = blue.os.GetWallclockTime): 166 if newthread: 167 return uthread.new(self._MorphUIMassSpringDamper, item, attrname, newVal, newthread, float, minVal, maxVal, dampRatio, frequency, initSpeed, maxTime, callback, initVal, timeFunc) 168 self._MorphUIMassSpringDamper(item, attrname, newVal, newthread, float, minVal, maxVal, dampRatio, frequency, initSpeed, maxTime, callback, initVal, timeFunc) 169 170 def _MorphUIMassSpringDamper(self, item, attrname, newVal, newthread, float, minVal, maxVal, dampRatio, frequency, initSpeed, maxTime, callback, initVal = None, timeFunc = blue.os.GetWallclockTime): 171 if initVal is None and attrname is not None: 172 initVal = getattr(item, attrname) 173 if initVal == newVal: 174 initVal += 1e-05 175 t0 = timeFunc() 176 xn = newVal - initVal 177 x0 = -xn 178 w0 = frequency 179 L = dampRatio 180 if math.fabs(L) >= 1.0: 181 L = 0.99 182 wd = w0 * math.sqrt(1.0 - L ** 2) 183 A = x0 184 v0 = initSpeed 185 B = (L * w0 * x0 + v0) / wd 186 t = 0.0 187 val = 0.0 188 stopCount = 0 189 while t < maxTime: 190 t = blue.os.TimeDiffInMs(t0, timeFunc()) / 1000.0 191 C = -L * w0 * t 192 val = math.exp(C) * (A * math.cos(wd * t) + B * math.sin(wd * t)) + xn 193 val = max(minVal - initVal, min(val, maxVal - initVal)) 194 if math.fabs(val + initVal - newVal) / math.fabs(initVal - newVal) < 0.02: 195 stopCount += 1 196 if stopCount >= 5: 197 break 198 setVal = val + initVal 199 if not float: 200 setVal = int(setVal) 201 if attrname and item: 202 setattr(item, attrname, setVal) 203 if callback: 204 callback(item, setVal) 205 blue.pyos.synchro.Yield() 206 if item and item.destroyed: 207 break 208 209 newVal = max(minVal, min(newVal, maxVal)) 210 if not float: 211 newVal = int(newVal) 212 if attrname and item: 213 setattr(item, attrname, newVal) 214 if callback: 215 if item and item.destroyed: 216 return 217 callback(item, newVal)