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

minime.py (17141B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\minime.py
      2 import sys
      3 import ctypes
      4 import ctypes.wintypes
      5 import blue
      6 import geo2
      7 import time
      8 import logmodule
      9 try:
     10     import trinity
     11 except (ImportError, RuntimeError):
     12     pass
     13 
     14 WNDPROC = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_long, ctypes.c_int, ctypes.c_int, ctypes.c_int)
     15 
     16 def LOWORD(dword):
     17     return dword & 65535
     18 
     19 
     20 def HIWORD(dword):
     21     return dword >> 16
     22 
     23 
     24 hwnd = None
     25 wndclass = None
     26 OnKeyDown = None
     27 OnKeyUp = None
     28 OnChar = None
     29 OnMouse = None
     30 blueArgs = blue.pyos.GetArg()[1:]
     31 
     32 def GetMousePosition(lparam):
     33     x = LOWORD(lparam)
     34     y = HIWORD(lparam)
     35     return (x, y)
     36 
     37 
     38 def PostOnMouse(event, wParam, lParam):
     39     try:
     40         if OnMouse is not None and callable(OnMouse):
     41             x, y = GetMousePosition(lParam)
     42             if event == 'MOUSE_WHEEL':
     43                 OnMouse(event, (x, y, HIWORD(wParam)))
     44             else:
     45                 OnMouse(event, (x, y))
     46     except:
     47         import traceback
     48         traceback.print_exc()
     49 
     50 
     51 class Camera(object):
     52 
     53     def __init__(self, fov, front, back, asp):
     54         self.minZoomDistance = 0.05
     55         self.maxZoomDistance = 100000.0
     56         self.parentPos = (0.0, 0.0, 0.0)
     57         self.localViewMatrix = geo2.MatrixIdentity()
     58         self.view = trinity.TriView()
     59         self.view.transform = geo2.MatrixIdentity()
     60         self.projection = trinity.TriProjection()
     61         self.SetPerspective(fov, front, back, asp)
     62         self.SetPosition((0.0, 50.0, -100.0))
     63         self.Focus((0.0, 0.0, 0.0))
     64 
     65     def _SetViewMatrix(self, value):
     66         self.view.transform = value
     67 
     68     def _GetViewMatrix(self):
     69         return self.view.transform
     70 
     71     viewMatrix = property(_GetViewMatrix, _SetViewMatrix)
     72 
     73     def _GetProjectionMatrix(self):
     74         return self.projection.transform
     75 
     76     projectionMatrix = property(_GetProjectionMatrix)
     77 
     78     def SetPerspective(self, fov, front, back, asp):
     79         self.fieldOfView = fov
     80         self.frontClip = front
     81         self.backClip = back
     82         self.aspectRatio = asp
     83         self.projection.PerspectiveFov(self.fieldOfView, self.aspectRatio, self.frontClip, self.backClip)
     84 
     85     def Update(self):
     86         parentMat = geo2.MatrixTranslation(*self.parentPos)
     87         viewInv = geo2.MatrixInverse(self.localViewMatrix)
     88         newT = geo2.MatrixMultiply(viewInv, parentMat)
     89         self.viewMatrix = geo2.MatrixInverse(newT)
     90         trinity.SetViewTransform(self.viewMatrix)
     91         trinity.SetPerspectiveProjection(self.fieldOfView, self.frontClip, self.backClip, self.aspectRatio)
     92         self.projection.PerspectiveFov(self.fieldOfView, self.aspectRatio, self.frontClip, self.backClip)
     93 
     94     def SetParentPos(self, pos):
     95         self.parentPos = pos
     96 
     97     def Zoom(self, val):
     98         dev = trinity.device
     99         pos = self.GetPosition()
    100         target = self.GetPointOfInterest()
    101         view = geo2.Vec3Normalize(geo2.Subtract(pos, target))
    102         length = geo2.Vec3Length(geo2.Subtract(pos, target))
    103         nextPos = geo2.Vec3Add(pos, geo2.Vec3Scale(view, length * val))
    104         nextLength = geo2.Vec3Length(geo2.Vec3Subtract(nextPos, target))
    105         if nextLength < self.minZoomDistance:
    106             nextPos = geo2.Vec3Add(target, geo2.Vec3Scale(view, self.minZoomDistance))
    107         elif nextLength > self.maxZoomDistance:
    108             nextPos = geo2.Vec3Add(target, geo2.Vec3Scale(view, self.maxZoomDistance))
    109         self.SetPosition(nextPos)
    110 
    111     def Orbit(self, yaw, pitch):
    112         dev = trinity.device
    113         self.Focus(self.pointOfInterest)
    114         up = geo2.Vector(0.0, 1.0, 0.0)
    115         t = geo2.Vector(self.localViewMatrix[1][0], self.localViewMatrix[1][1], self.localViewMatrix[1][2])
    116         if geo2.Vec3Dot(t, up) <= 0.0:
    117             pitch = -pitch
    118             yaw = -yaw
    119         pos = self.GetPosition()
    120         target = self.pointOfInterest
    121         view = geo2.Subtract(pos, target)
    122         view = geo2.Vec3Normalize(view)
    123         right = geo2.Vec3Cross(view, up)
    124         mat = self.localViewMatrix
    125         ipmat = geo2.MatrixTranslation(-target[0], -target[1], -target[2])
    126         pmat = geo2.MatrixTranslation(target[0], target[1], target[2])
    127         mat = geo2.MatrixInverse(mat)
    128         yrotMat = geo2.MatrixRotationAxis(up, yaw)
    129         rrotMat = geo2.MatrixRotationAxis(right, pitch)
    130         yrotMat = geo2.MatrixMultiply(yrotMat, rrotMat)
    131         mat = geo2.MatrixMultiply(mat, ipmat)
    132         mat = geo2.MatrixMultiply(mat, yrotMat)
    133         mat = geo2.MatrixMultiply(mat, pmat)
    134         self._position = geo2.MatrixDecompose(mat)[2]
    135         mat = geo2.MatrixInverse(mat)
    136         self.localViewMatrix = mat
    137 
    138     def Focus(self, point, dist = -1.0):
    139         dev = trinity.device
    140         pos = self.GetPosition()
    141         up = (0.0, 1.0, 0.0)
    142         t = (self.localViewMatrix[1][0], self.localViewMatrix[1][1], self.localViewMatrix[1][2])
    143         if geo2.Vec3Dot(t, up) <= 0.0:
    144             up = (0.0, -1.0, 0.0)
    145         self.pointOfInterest = point
    146         self.localViewMatrix = geo2.MatrixLookAtRH(pos, point, up)
    147         if dist > 0.0:
    148             view = geo2.Vec3Subtract(pos, point)
    149             view = geo2.Vec3Normalize(view)
    150             self.SetPosition(geo2.Vec3Add(point, geo2.Vec3Scale(view, dist)))
    151 
    152     def Pan(self, diff):
    153         pos = self.GetPosition()
    154         self.SetPosition(geo2.Vec3Add(pos, diff))
    155         self.pointOfInterest = geo2.Vec3Add(self.pointOfInterest, diff)
    156 
    157     def SetPosition(self, pos):
    158         mat = geo2.MatrixInverse(self.localViewMatrix)
    159         mat = (mat[0],
    160          mat[1],
    161          mat[2],
    162          (pos[0],
    163           pos[1],
    164           pos[2],
    165           mat[3][3]))
    166         self.localViewMatrix = geo2.MatrixInverse(mat)
    167         self._position = pos
    168 
    169     def GetPosition(self):
    170         return self._position
    171 
    172     def GetPointOfInterest(self):
    173         return self.pointOfInterest
    174 
    175 
    176 CS_HREDRAW = 2
    177 CS_VREDRAW = 1
    178 NULL = 0
    179 IDI_APPLICATION = 32512
    180 IDC_ARROW = 32512
    181 WHITE_BRUSH = 0
    182 BLACK_BRUSH = 4
    183 WS_OVERLAPPEDWINDOW = 13565952
    184 CW_USEDEFAULT = -2147483648L
    185 SW_SHOWNORMAL = 1
    186 WM_PAINT = 15
    187 DT_SINGLELINE = 32
    188 DT_CENTER = 1
    189 DT_VCENTER = 4
    190 WM_DESTROY = 2
    191 GWL_STYLE = -16
    192 WS_POPUP = -2147483648L
    193 WS_SYSMENU = 524288
    194 WS_VISIBLE = 268435456
    195 WS_MINIMIZEBOX = 131072
    196 WS_CAPTION = 12582912
    197 WM_CLOSE = 16
    198 WM_QUIT = 18
    199 WM_SIZE = 5
    200 WM_SETCURSOR = 32
    201 WM_MOUSEFIRST = 512
    202 WM_MOUSEMOVE = 512
    203 WM_LBUTTONDOWN = 513
    204 WM_LBUTTONUP = 514
    205 WM_LBUTTONDBLCLK = 515
    206 WM_RBUTTONDOWN = 516
    207 WM_RBUTTONUP = 517
    208 WM_RBUTTONDBLCLK = 518
    209 WM_MBUTTONDOWN = 519
    210 WM_MBUTTONUP = 520
    211 WM_MBUTTONDBLCLK = 521
    212 WM_MOUSEWHEEL = 522
    213 WM_ACTIVATE = 6
    214 WM_SYSCOMMAND = 274
    215 WM_ERASEBKGND = 20
    216 SC_KEYMENU = 61696
    217 WA_ACTIVE = 1
    218 WA_CLICKACTIVE = 2
    219 WS_EX_TOPMOST = 8
    220 WS_EX_COMPOSITED = 33554432
    221 WM_KEYDOWN = 256
    222 WM_KEYUP = 257
    223 WM_CHAR = 258
    224 WM_NCLBUTTONDOWN = 161
    225 HTCAPTION = 2
    226 WS_THICKFRAME = 262144
    227 WS_SIZEBOX = WS_THICKFRAME
    228 VK_RETURN = 13
    229 VK_SHIFT = 16
    230 VK_CONTROL = 17
    231 VK_ESCAPE = 27
    232 VK_SPACE = 32
    233 VK_PRIOR = 33
    234 VK_NEXT = 34
    235 VK_END = 35
    236 VK_HOME = 36
    237 VK_LEFT = 37
    238 VK_UP = 38
    239 VK_RIGHT = 39
    240 VK_DOWN = 40
    241 VK_SELECT = 41
    242 VK_PRINT = 42
    243 VK_EXECUTE = 43
    244 VK_SNAPSHOT = 44
    245 VK_INSERT = 45
    246 VK_DELETE = 46
    247 VK_HELP = 47
    248 SWP_NOSIZE = 1
    249 SWP_NOMOVE = 2
    250 SWP_NOZORDER = 4
    251 WT_DEFAULT_FRAME = WS_OVERLAPPEDWINDOW
    252 WT_FRAME_NO_X = WS_POPUP | WS_SIZEBOX
    253 WT_NO_FRAME = WS_EX_TOPMOST | WS_POPUP
    254 uilib = None
    255 
    256 def SetWindowSize(w, h):
    257     dev = trinity.device
    258     hwnd = dev.GetWindow()
    259     ctypes.windll.user32.SetWindowPos(ctypes.c_int(hwnd), 0, 0, 0, w, h, SWP_NOZORDER | SWP_NOMOVE)
    260 
    261 
    262 def SetWindowPos(x, y):
    263     dev = trinity.device
    264     hwnd = dev.GetWindow()
    265     ctypes.windll.user32.SetWindowPos(ctypes.c_int(hwnd), 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE)
    266 
    267 
    268 def StartUI():
    269     global uilib
    270     from carbonui.uilib import Uilib
    271     uilib = Uilib()
    272 
    273 
    274 class WNDCLASS(ctypes.Structure):
    275     _fields_ = [('style', ctypes.c_uint),
    276      ('lpfnWndProc', WNDPROC),
    277      ('cbClsExtra', ctypes.c_int),
    278      ('cbWndExtra', ctypes.c_int),
    279      ('hInstance', ctypes.wintypes.HINSTANCE),
    280      ('hIcon', ctypes.wintypes.HICON),
    281      ('hCursor', ctypes.wintypes.HICON),
    282      ('hbrBackground', ctypes.wintypes.HBRUSH),
    283      ('lpszMenuName', ctypes.wintypes.LPCSTR),
    284      ('lpszClassName', ctypes.wintypes.LPCSTR)]
    285 
    286 
    287 class RECT(ctypes.Structure):
    288     _fields_ = [('left', ctypes.c_long),
    289      ('top', ctypes.c_long),
    290      ('right', ctypes.c_long),
    291      ('bottom', ctypes.c_long)]
    292 
    293 
    294 class PAINTSTRUCT(ctypes.Structure):
    295     _fields_ = [('hdc', ctypes.c_int),
    296      ('fErase', ctypes.c_int),
    297      ('rcPaint', RECT),
    298      ('fRestore', ctypes.c_int),
    299      ('fIncUpdate', ctypes.c_int),
    300      ('rgbReserved', ctypes.c_char * 32)]
    301 
    302 
    303 class MARGINS(ctypes.Structure):
    304     _fields_ = [('cxLeftWidth', ctypes.c_long),
    305      ('cxRightWidth', ctypes.c_long),
    306      ('cyTopHeight', ctypes.c_long),
    307      ('cyBottomHeight', ctypes.c_long)]
    308 
    309 
    310 class POINT(ctypes.Structure):
    311     _fields_ = [('x', ctypes.c_long), ('y', ctypes.c_long)]
    312 
    313 
    314 class MSG(ctypes.Structure):
    315     _fields_ = [('hwnd', ctypes.c_int),
    316      ('message', ctypes.c_uint),
    317      ('wParam', ctypes.c_int),
    318      ('lParam', ctypes.c_int),
    319      ('time', ctypes.c_int),
    320      ('pt', POINT)]
    321 
    322 
    323 def ErrorIfZero(handle):
    324     if handle == 0:
    325         raise ctypes.WinError()
    326     else:
    327         return handle
    328 
    329 
    330 def SetConstantYawRotation(rad_per_sec):
    331     global START_TIME
    332     START_TIME = time.clock()
    333 
    334     def render_cb():
    335         global START_TIME
    336         current = time.clock()
    337         m = geo2.MatrixRotationY((current - START_TIME) * rad_per_sec)
    338         trinity.SetViewTransform(geo2.MatrixMultiply(m, trinity.GetViewTransform()))
    339         START_TIME = current
    340 
    341     rj = trinity.CreateRenderJob('ConstantYawRotation')
    342     rj.PythonCB(render_cb)
    343     rj.ScheduleRecurring()
    344 
    345 
    346 def CreateWindow(fullscreen = False, size = None, windowType = WT_DEFAULT_FRAME, showWindow = True):
    347     global hwnd
    348     global wndclass
    349     CreateWindowEx = ctypes.windll.user32.CreateWindowExA
    350     CreateWindowEx.argtypes = [ctypes.wintypes.DWORD,
    351      ctypes.wintypes.LPCSTR,
    352      ctypes.wintypes.LPCSTR,
    353      ctypes.wintypes.DWORD,
    354      ctypes.c_int,
    355      ctypes.c_int,
    356      ctypes.c_int,
    357      ctypes.c_int,
    358      ctypes.wintypes.HWND,
    359      ctypes.wintypes.HMENU,
    360      ctypes.wintypes.HINSTANCE,
    361      ctypes.wintypes.LPVOID]
    362     CreateWindowEx.restype = ErrorIfZero
    363     wndclass = WNDCLASS()
    364     wndclass.style = CS_HREDRAW | CS_VREDRAW
    365     wndclass.lpfnWndProc = WNDPROC(WndProc)
    366     wndclass.cbClsExtra = wndclass.cbWndExtra = 0
    367     wndclass.hInstance = ctypes.windll.kernel32.GetModuleHandleA(ctypes.c_char_p(NULL))
    368     wndclass.hIcon = ctypes.windll.user32.LoadImageA(ctypes.c_void_p(NULL), ctypes.c_char_p(IDI_APPLICATION), ctypes.c_uint(1), ctypes.c_int64(10), ctypes.c_int64(10), ctypes.c_uint64(0))
    369     wndclass.hCursor = ctypes.windll.user32.LoadImageA(ctypes.c_void_p(NULL), ctypes.c_char_p(IDC_ARROW), ctypes.c_uint(2), ctypes.c_int64(10), ctypes.c_int64(10), ctypes.c_uint64(0))
    370     wndclass.hbrBackground = ctypes.windll.gdi32.GetStockObject(ctypes.c_int(BLACK_BRUSH))
    371     wndclass.lpszMenuName = None
    372     wndclass.lpszClassName = 'MainWin'
    373     if not ctypes.windll.user32.RegisterClassA(ctypes.byref(wndclass)):
    374         raise ctypes.WinError()
    375     if '/fullscreen' in blueArgs:
    376         fullscreen = True
    377     if fullscreen:
    378         dspmode = trinity.adapters.GetCurrentDisplayMode(trinity.adapters.DEFAULT_ADAPTER)
    379         if size is None:
    380             width = dspmode.width
    381             height = dspmode.height
    382         else:
    383             width, height = size
    384         hwnd = CreateWindowEx(0, wndclass.lpszClassName, 'MINI ME', WS_EX_TOPMOST | WS_POPUP, 0, 0, width, height, NULL, NULL, wndclass.hInstance, NULL)
    385     else:
    386         if size is None:
    387             width = CW_USEDEFAULT
    388             height = CW_USEDEFAULT
    389         else:
    390             width, height = size
    391         hwnd = CreateWindowEx(WS_EX_COMPOSITED, wndclass.lpszClassName, 'MINI ME', windowType, CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, wndclass.hInstance, NULL)
    392     if showWindow:
    393         ctypes.windll.user32.ShowWindow(ctypes.c_int(hwnd), ctypes.c_int(SW_SHOWNORMAL))
    394         ctypes.windll.user32.UpdateWindow(ctypes.c_int(hwnd))
    395     return hwnd
    396 
    397 
    398 def GetWindowSize(hwnd):
    399     rect = RECT()
    400     ctypes.windll.user32.GetClientRect(hwnd, ctypes.byref(rect))
    401     return (rect.right, rect.bottom)
    402 
    403 
    404 def CreateDevice(hwnd, fullscreen = False):
    405     if '/fullscreen' in blueArgs:
    406         fullscreen = True
    407     w, h = GetWindowSize(hwnd)
    408     if fullscreen:
    409         trinity.device.CreateFullScreenDevice(hwnd, w, h)
    410     else:
    411         trinity.device.CreateWindowedDevice(hwnd, w, h)
    412 
    413 
    414 def RunTestScript():
    415     try:
    416         for each in blueArgs:
    417             if each.startswith('/test_script'):
    418                 path = each.split('=')[1]
    419                 execfile(path, globals())
    420 
    421     except Exception as e:
    422         import traceback
    423         traceback.print_exc()
    424         logmodule.LogException()
    425         sys.exc_clear()
    426 
    427 
    428 def Main(postCreateCallback = None, fullscreen = False, size = None, windowType = WT_DEFAULT_FRAME):
    429     hwnd = CreateWindow(fullscreen, size, windowType)
    430     CreateDevice(hwnd, fullscreen)
    431     w, h = GetWindowSize(hwnd)
    432     asp = float(w) / float(h)
    433     trinity.SetPerspectiveProjection(1.57, 1.0, 1000.0, asp)
    434     if postCreateCallback and callable(postCreateCallback):
    435         postCreateCallback()
    436     MinimeMainLoop()
    437 
    438 
    439 def MinimeMainLoop():
    440     msg = MSG()
    441     pMsg = ctypes.pointer(msg)
    442     running = True
    443     TranslateMessage = ctypes.windll.user32.TranslateMessage
    444     DispatchMessageA = ctypes.windll.user32.DispatchMessageA
    445     PeekMessageA = ctypes.windll.user32.PeekMessageA
    446     while running:
    447         while PeekMessageA(pMsg, NULL, 0, 0, 1):
    448             if msg.message == WM_QUIT:
    449                 running = False
    450                 break
    451             TranslateMessage(pMsg)
    452             DispatchMessageA(pMsg)
    453 
    454         blue.os.Pump()
    455 
    456     ctypes.windll.user32.PostQuitMessage(0)
    457     return msg.wParam
    458 
    459 
    460 def WndProc(hwnd, message, wParam, lParam):
    461     dev = trinity.device
    462     if message == WM_DESTROY:
    463         blue.os.Terminate()
    464         return 0
    465     elif message == WM_CLOSE:
    466         blue.os.Terminate()
    467         return 0
    468     if message == WM_SIZE:
    469         if dev.GetWindow():
    470             rect = RECT()
    471             ctypes.windll.user32.GetClientRect(hwnd, ctypes.byref(rect))
    472             viewTrans = trinity.GetViewTransform()
    473             fov = trinity.GetFieldOfView()
    474             front = trinity.GetFrontClip()
    475             back = trinity.GetBackClip()
    476             w, h = rect.right, rect.bottom
    477             defaultBackBuffer = trinity.device.GetRenderContext().GetDefaultBackBuffer()
    478             if w == defaultBackBuffer.width and h == defaultBackBuffer.height:
    479                 return 0
    480             asp = float(w) / float(h)
    481             dev.ChangeBackBufferSize(w, h)
    482             trinity.SetPerspectiveProjection(fov, front, back, asp)
    483             trinity.SetViewTransform(viewTrans)
    484     elif message == WM_LBUTTONDOWN:
    485         rect = RECT()
    486         ctypes.windll.user32.GetClientRect(hwnd, ctypes.byref(rect))
    487         offset = POINT()
    488         ctypes.windll.user32.ClientToScreen(hwnd, ctypes.byref(offset))
    489         ctypes.windll.user32.OffsetRect(ctypes.byref(rect), offset.x, offset.y)
    490         ctypes.windll.user32.ClipCursor(ctypes.byref(rect))
    491         PostOnMouse('LEFT_BUTTON_DOWN', wParam, lParam)
    492     elif message == WM_LBUTTONUP:
    493         ctypes.windll.user32.ClipCursor(0)
    494         PostOnMouse('LEFT_BUTTON_UP', wParam, lParam)
    495     elif message == WM_LBUTTONDBLCLK:
    496         PostOnMouse('LEFT_BUTTON_DBLCLK', wParam, lParam)
    497     elif message == WM_RBUTTONUP:
    498         PostOnMouse('RIGHT_BUTTON_UP', wParam, lParam)
    499     elif message == WM_RBUTTONDOWN:
    500         PostOnMouse('RIGHT_BUTTON_DOWN', wParam, lParam)
    501     elif message == WM_RBUTTONDBLCLK:
    502         PostOnMouse('RIGHT_BUTTON_DBLCLK', wParam, lParam)
    503     elif message == WM_MBUTTONUP:
    504         PostOnMouse('MIDDLE_BUTTON_UP', wParam, lParam)
    505     elif message == WM_MBUTTONDOWN:
    506         PostOnMouse('MIDDLE_BUTTON_DOWN', wParam, lParam)
    507     elif message == WM_MBUTTONDBLCLK:
    508         PostOnMouse('MIDDLE_BUTTON_DBLCLK', wParam, lParam)
    509     elif message == WM_MOUSEMOVE:
    510         PostOnMouse('MOUSE_MOVE', wParam, lParam)
    511     elif message == WM_MOUSEWHEEL:
    512         PostOnMouse('MOUSE_WHEEL', wParam, lParam)
    513     elif message == WM_ACTIVATE:
    514         if not (wParam == WA_ACTIVE and wParam == WA_CLICKACTIVE):
    515             ctypes.windll.user32.ClipCursor(0)
    516     elif message == WM_SYSCOMMAND:
    517         if wParam == SC_KEYMENU:
    518             return 0
    519     else:
    520         if message == WM_ERASEBKGND:
    521             return 0
    522         if message == WM_KEYDOWN:
    523             if OnKeyDown is not None and callable(OnKeyDown):
    524                 OnKeyDown(wParam)
    525         elif message == WM_KEYUP:
    526             if OnKeyUp is not None and callable(OnKeyUp):
    527                 OnKeyUp(wParam)
    528         elif message == WM_CHAR:
    529             if OnChar is not None and callable(OnChar):
    530                 OnChar(wParam)
    531     if uilib is not None:
    532         return 0
    533     else:
    534         return ctypes.windll.user32.DefWindowProcA(ctypes.c_int(hwnd), ctypes.c_int(message), ctypes.c_int(wParam), ctypes.c_int(lParam))