skinrShipSceneContainerCamera.py (9457B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\camera\skinrShipSceneContainerCamera.py 2 import blue 3 import geo2 4 import math 5 from bisect import bisect_left 6 from carbonui import const as uiconst 7 from carbonui.uicore import uicore 8 from cosmetics.client.ships.skins.live_data import current_skin_design 9 from cosmetics.common.ships.skins.static_data.slot_name import PATTERN_SLOT_IDS, PATTERN_SLOT_ID_BY_PATTERN_MATERIAL_ID 10 from eve.client.script.ui.camera.baseCamera import Camera 11 from eve.client.script.ui.camera.sceneContainerCamera import SceneContainerCamera 12 from eve.client.script.ui.cosmetics.ship.pages.studio import studioSettings 13 from eve.client.script.ui.cosmetics.ship.pages.studio.studioSettings import pattern_rotation_follow_camera_setting 14 ROLL_SNAP_STEP = 15 15 16 class YawPitchCamera(Camera): 17 kOrbitSpeed = 10.0 18 kMinPitch = 0.001 19 kMaxPitch = math.pi - kMinPitch 20 21 22 class SkinrShipSceneContainerCamera(SceneContainerCamera): 23 kFovSpeed = 7.0 24 roll_snap_angles = [ x for x in range(-180, 180 + ROLL_SNAP_STEP, ROLL_SNAP_STEP) ] 25 roll_snap_delay = 50.0 26 roll_snap_timestamp = blue.os.GetSimTime() 27 28 def __init__(self): 29 SceneContainerCamera.__init__(self) 30 self.kFovSpeed = 5.0 31 self.cameraBasedProjectionThread = None 32 self.patternTwist = 0.0 33 self.model = None 34 self.currentModKeyOrbitalModeHorizontal = True 35 self.inputConsistencyCounter = 5.0 36 self.yaw_pitch_camera = YawPitchCamera() 37 self.yaw_pitch_camera.on_eye_position_changed.connect(self.on_yaw_pitch_camera_eye_position_changed) 38 self.yaw_pitch_camera.on_orbit_end.connect(self.on_yaw_pitch_camera_orbit_end) 39 uicore.event.RegisterForTriuiEvents(uiconst.UI_MOUSEDOWN, self.OnMouseDown) 40 studioSettings.pattern_rotation_follow_camera_setting.on_change.connect(self.on_pattern_rotation_follow_camera_setting) 41 42 def on_yaw_pitch_camera_orbit_end(self): 43 current_skin_design.add_to_undo_history() 44 45 def Update(self): 46 super(SkinrShipSceneContainerCamera, self).Update() 47 self.yaw_pitch_camera.Update() 48 49 def on_yaw_pitch_camera_eye_position_changed(self, value): 50 component_instance = self.get_pattern_component_instance() 51 if component_instance: 52 yaw_ratio = -self.yaw_pitch_camera.yaw / math.pi 53 pitch_ratio = 1.0 - 2 * (self.yaw_pitch_camera.pitch / math.pi) 54 component_instance.yaw = yaw_ratio 55 component_instance.pitch = pitch_ratio 56 57 def on_pattern_rotation_follow_camera_setting(self, value): 58 if value: 59 self.reset_pattern_uv_offset() 60 current_skin_design.add_to_undo_history() 61 62 def OnMouseDown(self, button, eventID, vKeyAndFlag, *args): 63 updatingPattern = uicore.uilib.Key(uiconst.VK_CONTROL) or pattern_rotation_follow_camera_setting.is_enabled() 64 activeWindow = uicore.registry.GetActive() 65 if updatingPattern and activeWindow is not None and len(vKeyAndFlag) > 0: 66 if activeWindow.name == 'ShipSKINRWindow': 67 if vKeyAndFlag[0] == uiconst.MOUSELEFT: 68 uicore.uilib.SetCursor(uiconst.UICURSOR_NONE) 69 uicore.event.RegisterForTriuiEvents(uiconst.UI_MOUSEUP, self.OnTestLeftMouseUp) 70 if vKeyAndFlag[0] == uiconst.MOUSERIGHT: 71 uicore.uilib.SetCursor(uiconst.UICURSOR_NONE) 72 uicore.event.RegisterForTriuiEvents(uiconst.UI_MOUSEUP, self.OnTestRightMouseUp) 73 return True 74 75 def OnTestRightMouseUp(self, obj, eventID, vk_flag): 76 vkey, flag = vk_flag 77 if vkey == uiconst.MOUSERIGHT: 78 if not uicore.uilib.leftbtn: 79 uicore.uilib.SetCursor(uiconst.UICURSOR_DEFAULT) 80 else: 81 return True 82 83 def OnTestLeftMouseUp(self, obj, eventID, vk_flag): 84 vkey, flag = vk_flag 85 if vkey == uiconst.MOUSELEFT: 86 if not uicore.uilib.rightbtn: 87 uicore.uilib.SetCursor(uiconst.UICURSOR_DEFAULT) 88 else: 89 return True 90 91 def reset_pattern_uv_offset(self): 92 component_instance = self.get_pattern_component_instance() 93 if component_instance: 94 component_instance.offset_u_ratio = component_instance.offset_v_ratio = 0.0 95 96 def SetZoom(self, proportion): 97 if not pattern_rotation_follow_camera_setting.is_enabled(): 98 direction = self.GetLookAtDirection() 99 distance = self.GetZoomDistanceByZoomProportion(proportion) 100 zoomVec = geo2.Vec3Scale(direction, distance) 101 self.SetEyePosition(geo2.Vec3Add(self.GetZoomToPoint(), zoomVec)) 102 103 def Orbit(self, dx = 0, dy = 0): 104 if uicore.uilib.Key(uiconst.VK_CONTROL): 105 self._modify_pattern_attributes(dx, dy) 106 else: 107 super(SkinrShipSceneContainerCamera, self).Orbit(dx, dy) 108 109 def _modify_pattern_attributes(self, dx, dy): 110 if uicore.uilib.rightbtn and not uicore.uilib.leftbtn: 111 self.modify_offset(dx, dy) 112 elif uicore.uilib.leftbtn and not uicore.uilib.rightbtn: 113 self.modify_yaw_pitch(dx, dy) 114 115 def modify_yaw_pitch(self, dx, dy): 116 if not self.yaw_pitch_camera.orbitUpdateThread: 117 component_instace = self.get_pattern_component_instance() 118 if component_instace: 119 self.yaw_pitch_camera.yaw = -component_instace.yaw * math.pi 120 self.yaw_pitch_camera.pitch = -math.pi * (component_instace.pitch - 1.0) / 2.0 121 k = 0.03 if uicore.uilib.Key(uiconst.VK_SHIFT) else 0.3 122 self.yaw_pitch_camera.Orbit(-k * dx, -2 * k * dy) 123 124 def modify_offset(self, dx, dy): 125 k = 0.01 if uicore.uilib.Key(uiconst.VK_SHIFT) else 0.1 126 if uicore.uilib.Key(uiconst.VK_MENU): 127 pass 128 else: 129 component_instance = self.get_pattern_component_instance() 130 if component_instance: 131 dx, dy = self._rotate_offset_to_face_camera(component_instance, dx, dy) 132 component_instance.offset_u_ratio += k * dx 133 component_instance.offset_v_ratio += k * dy 134 current_skin_design.add_to_undo_history_batch_up() 135 136 def _rotate_offset_to_face_camera(self, component_instance, dx, dy): 137 yaw = self.yaw + component_instance.yaw * math.pi 138 if component_instance.pitch > 0: 139 yaw *= -1 140 dx, _, dy = geo2.QuaternionTransformVector(geo2.QuaternionRotationSetYawPitchRoll(yaw, 0, 0), (dx, 0, -dy)) 141 return (dx, dy) 142 143 def _Update(self): 144 super(SkinrShipSceneContainerCamera, self)._Update() 145 if pattern_rotation_follow_camera_setting.is_enabled(): 146 yaw_ratio = -self.GetYaw() / math.pi 147 pitch_ratio = 1.0 - 2 * (self.GetPitch() / math.pi) 148 component_instance = self.get_pattern_component_instance() 149 if component_instance: 150 component_instance.yaw = yaw_ratio 151 component_instance.pitch = pitch_ratio 152 153 def Zoom(self, dz): 154 updatingPattern = uicore.uilib.Key(uiconst.VK_CONTROL) or pattern_rotation_follow_camera_setting.is_enabled() 155 if not updatingPattern: 156 return super(SceneContainerCamera, self).Zoom(dz) 157 component_instance = self.get_pattern_component_instance() 158 if not component_instance: 159 return 160 if uicore.uilib.rightbtn and uicore.uilib.leftbtn: 161 k = 0.01 if uicore.uilib.Key(uiconst.VK_SHIFT) else 0.1 162 component_instance.scaling_ratio += dz * k 163 current_skin_design.add_to_undo_history_batch_up() 164 elif uicore.uilib.Key(uiconst.VK_MENU): 165 component_instance.roll = self.get_roll_snap_value(component_instance.roll, dz) 166 current_skin_design.add_to_undo_history_batch_up() 167 else: 168 k = 0.01 if uicore.uilib.Key(uiconst.VK_SHIFT) else 0.1 169 component_instance.roll += dz * k 170 current_skin_design.add_to_undo_history_batch_up() 171 172 def get_roll_snap_value(self, current_value, dz): 173 now = blue.os.GetSimTime() 174 delta = blue.os.TimeDiffInMs(self.roll_snap_timestamp, now) 175 if delta < self.roll_snap_delay or dz == 0: 176 return current_value 177 self.roll_snap_timestamp = now 178 current_angle = current_value * 180 179 index = bisect_left(self.roll_snap_angles, current_angle) 180 if dz > 0: 181 if index == len(self.roll_snap_angles) - 1: 182 index = 1 183 else: 184 index += 1 185 elif index == 0: 186 index = len(self.roll_snap_angles) - 2 187 else: 188 index -= 1 189 return self.roll_snap_angles[index] / 180.0 190 191 def get_pattern_component_instance(self): 192 slot_id = current_skin_design.get_selected_slot_id() 193 slot_id = PATTERN_SLOT_ID_BY_PATTERN_MATERIAL_ID.get(slot_id, slot_id) 194 if slot_id in PATTERN_SLOT_IDS: 195 return current_skin_design.get().get_fitted_component_instance(slot_id) 196 197 def SetInnerBoundRadius(self, innerRadius): 198 maxSideLength = max(innerRadius) 199 paddingLength = 0.01 * maxSideLength + 5 200 padding = (paddingLength, paddingLength, paddingLength) 201 self.innerBoundRadius = geo2.Vec3Add(innerRadius, padding) 202 203 def SetModelCenter(self, modelCenter): 204 self._modelCenterOffset = modelCenter 205 self.SetAtPosition(self._modelCenterOffset)