basicCamera.py (7312B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\camera\basicCamera.py 2 import blue 3 import math 4 import geo2 5 import trinity 6 from carbon.common.lib.const import SEC 7 from carbon.common.script.util import mathCommon 8 9 class BasicCamera(object): 10 11 def __init__(self): 12 self.direction = (math.pi / 4.0, math.pi / 4.0, math.pi / 4.0) 13 self.cameraPosition = (0, 0, 0) 14 self.viewMatrix = trinity.TriView() 15 self.baseViewMatrix = trinity.TriView() 16 self.projectionMatrix = trinity.TriProjection() 17 self.fieldOfView = 1.0 18 self.frontClip = 0.1 19 self.backClip = 1000.0 20 self.yaw, self.pitch = self.GetYawPitch() 21 self.desiredDeltaX = 0 22 self.desiredDeltaY = 0 23 self.controlEnabled = True 24 self.cameraBehaviors = [] 25 self.lastUpdateTime = blue.os.GetWallclockTime() 26 27 def Reset(self): 28 pass 29 30 def ResetLayer(self): 31 pass 32 33 def SetTrinityMatrixObjects(self, viewMatrix, projectionMatrix): 34 self.viewMatrix = viewMatrix 35 self.projectionMatrix = projectionMatrix 36 37 def SetControlEnabled(self, boolEnable): 38 self.controlEnabled = boolEnable 39 40 def IsControlEnabled(self): 41 return self.controlEnabled 42 43 def SetDesiredMouseDelta(self, desiredDeltaX, desiredDeltaY): 44 self.desiredDeltaX = desiredDeltaX 45 self.desiredDeltaY = desiredDeltaY 46 47 def AdjustYaw(self, delta): 48 if not self.controlEnabled: 49 return 50 self.yaw += delta 51 self.CalcCameraDirection() 52 53 def AdjustPitch(self, delta): 54 if not self.controlEnabled: 55 return 56 if self.pitch + delta < math.pi and self.pitch + delta > 0.01: 57 self.pitch += delta 58 else: 59 if self.pitch + delta < 0.01: 60 self.pitch = 0.01 61 if self.pitch + delta > math.pi: 62 self.pitch = math.pi 63 self.CalcCameraDirection() 64 65 def SetPitch(self, pitch): 66 self.pitch = pitch 67 self.CalcCameraDirection() 68 69 def SetYaw(self, yaw): 70 self.yaw = yaw 71 self.CalcCameraDirection() 72 73 def Deactivate(self): 74 pass 75 76 def CalcCameraDirection(self): 77 if trinity.IsRightHanded(): 78 self.direction = (math.sin(self.pitch) * math.cos(self.yaw), -math.cos(self.pitch), math.sin(self.pitch) * math.sin(self.yaw)) 79 else: 80 self.direction = (-math.sin(self.pitch) * math.cos(self.yaw), math.cos(self.pitch), -math.sin(self.pitch) * math.sin(self.yaw)) 81 82 def GetPosition(self): 83 return self.cameraPosition 84 85 def GetYawPitch(self): 86 rotMatrix = geo2.MatrixTranspose(self.viewMatrix.transform) 87 quat = geo2.QuaternionRotationMatrix(rotMatrix) 88 yaw, pitch, roll = geo2.QuaternionRotationGetYawPitchRoll(quat) 89 yaw = math.pi / 2 - yaw 90 pitch = math.pi / 2 - pitch 91 return (yaw, pitch) 92 93 def SetPosition(self, position): 94 self.cameraPosition = position 95 96 def UpdateProjectionMatrix(self): 97 aspectRatio = float(trinity.device.viewport.width) / float(trinity.device.viewport.height) 98 self.projectionMatrix.PerspectiveFov(self.fieldOfView, aspectRatio, self.frontClip, self.backClip) 99 100 def SetFieldOfView(self, fov): 101 self.fieldOfView = fov 102 self.UpdateProjectionMatrix() 103 104 def CreateViewMatrix(self): 105 upVector = (0, 1, 0) 106 xaxis = geo2.Vec3Normalize(geo2.Vec3Cross(upVector, self.direction)) 107 yaxis = geo2.Vec3Cross(self.direction, xaxis) 108 return ((xaxis[0], 109 yaxis[0], 110 self.direction[0], 111 0.0), 112 (xaxis[1], 113 yaxis[1], 114 self.direction[1], 115 0.0), 116 (xaxis[2], 117 yaxis[2], 118 self.direction[2], 119 0.0), 120 (-geo2.Vec3Dot(xaxis, self.cameraPosition), 121 -geo2.Vec3Dot(yaxis, self.cameraPosition), 122 -geo2.Vec3Dot(self.direction, self.cameraPosition), 123 1.0)) 124 125 def Update(self): 126 now = blue.os.GetWallclockTime() 127 frameTime = float(now - self.lastUpdateTime) / SEC 128 for priority, behavior in self.cameraBehaviors: 129 behavior.ProcessCameraUpdate(self, now, frameTime) 130 131 self.lastUpdateTime = now 132 self.viewMatrix.transform = self.CreateViewMatrix() 133 self.baseViewMatrix.transform = self.CreateViewMatrix() 134 135 def AddBehavior(self, behavior, priority = 100): 136 self.cameraBehaviors.append((priority, behavior)) 137 self.cameraBehaviors.sort() 138 behavior.OnBehaviorAdded(self) 139 140 def RemoveBehavior(self, behavior): 141 toRemove = None 142 for priority, myBehavior in self.cameraBehaviors: 143 if myBehavior == behavior: 144 toRemove = (priority, myBehavior) 145 break 146 147 if toRemove is not None: 148 self.cameraBehaviors.remove(toRemove) 149 150 def GetBehavior(self, behaviorType): 151 for priority, behavior in self.cameraBehaviors: 152 if type(behavior) is behaviorType: 153 return behavior 154 155 def PerformPick(self, x, y, ignoreEntID = -1): 156 raise NotImplementedError('PerformPick must be implemented on derived camera classes') 157 158 def GetRay(self, x, y): 159 app = trinity.app 160 aspect = float(app.width) / app.height 161 fovTan = math.tan(self.fieldOfView * 0.5) 162 dx = fovTan * (2.0 * x / app.width - 1.0) * aspect 163 dy = fovTan * (1.0 - 2.0 * y / app.height) 164 if trinity.IsRightHanded(): 165 startPoint = trinity.TriVector(self.frontClip * dx, self.frontClip * dy, -self.frontClip) 166 endPoint = trinity.TriVector(self.backClip * dx, self.backClip * dy, -self.backClip) 167 else: 168 startPoint = trinity.TriVector(self.frontClip * dx, self.frontClip * dy, self.frontClip) 169 endPoint = trinity.TriVector(self.backClip * dx, self.backClip * dy, self.backClip) 170 invViewMatrix = mathCommon.ConvertTupleToTriMatrix(self.viewMatrix.transform) 171 invViewMatrix.Inverse() 172 startPoint.TransformCoord(invViewMatrix) 173 endPoint.TransformCoord(invViewMatrix) 174 startPoint = (startPoint.x, startPoint.y, startPoint.z) 175 endPoint = (endPoint.x, endPoint.y, endPoint.z) 176 return (startPoint, endPoint) 177 178 def ProjectPoint(self, point): 179 viewport = (trinity.device.viewport.x, 180 trinity.device.viewport.y, 181 trinity.device.viewport.width, 182 trinity.device.viewport.height, 183 trinity.device.viewport.minZ, 184 trinity.device.viewport.maxZ) 185 return geo2.Vec3Project(point, viewport, self.projectionMatrix.transform, self.viewMatrix.transform, geo2.MatrixIdentity()) 186 187 def IsPointInViewport(self, point): 188 point2D = self.ProjectPoint(point) 189 if point2D[0] < trinity.device.viewport.x or point2D[0] > trinity.device.viewport.x + trinity.device.viewport.width or point2D[1] < trinity.device.viewport.y or point2D[1] > trinity.device.viewport.y + trinity.device.viewport.height or point2D[2] < trinity.device.viewport.minZ or point2D[2] > trinity.device.viewport.maxZ: 190 return False 191 return True 192 193 def ResetBehaviors(self): 194 for prio, behavior in self.cameraBehaviors: 195 behavior.Reset()