def Orbit(self, yaw, pitch): dev = trinity.device self.Focus(self.pointOfInterest) up = geo2.Vector(0.0, 1.0, 0.0) t = geo2.Vector(self.localViewMatrix[1][0], self.localViewMatrix[1][1], self.localViewMatrix[1][2]) if geo2.Vec3Dot(t, up) <= 0.0: pitch = -pitch yaw = -yaw pos = self.GetPosition() target = self.pointOfInterest view = geo2.Subtract(pos, target) view = geo2.Vec3Normalize(view) right = geo2.Vec3Cross(view, up) mat = self.localViewMatrix ipmat = geo2.MatrixTranslation(-target[0], -target[1], -target[2]) pmat = geo2.MatrixTranslation(target[0], target[1], target[2]) mat = geo2.MatrixInverse(mat) yrotMat = geo2.MatrixRotationAxis(up, yaw) rrotMat = geo2.MatrixRotationAxis(right, pitch) yrotMat = geo2.MatrixMultiply(yrotMat, rrotMat) mat = geo2.MatrixMultiply(mat, ipmat) mat = geo2.MatrixMultiply(mat, yrotMat) mat = geo2.MatrixMultiply(mat, pmat) self._position = geo2.MatrixDecompose(mat)[2] mat = geo2.MatrixInverse(mat) self.localViewMatrix = mat
def GetRayAndPointFromUI(self, x, y, projection2view=None, view2world=None): viewport = self.viewport mx = x - viewport.x my = y - viewport.y w = viewport.width h = viewport.height fx = float(mx * 2) / w - 1.0 fy = float(my * 2) / h - 1.0 fy *= -1 projection2view = projection2view or geo2.MatrixInverse( self.projectionMatrix.transform) view2world = view2world or geo2.MatrixInverse( self.viewMatrix.transform) rayStart = (fx, fy, 0.0) rayStart = geo2.Vec3TransformCoord(rayStart, projection2view) rayStart = geo2.Vec3TransformCoord(rayStart, view2world) rayEnd = (fx, fy, 1.0) rayEnd = geo2.Vec3TransformCoord(rayEnd, projection2view) rayEnd = geo2.Vec3TransformCoord(rayEnd, view2world) rayDir = geo2.Vec3SubtractD(rayEnd, rayStart) return (geo2.Vec3NormalizeD(rayDir), rayStart)
def Update(self): parentMat = geo2.MatrixTranslation(*self.parentPos) viewInv = geo2.MatrixInverse(self.localViewMatrix) newT = geo2.MatrixMultiply(viewInv, parentMat) self.viewMatrix = geo2.MatrixInverse(newT) trinity.SetViewTransform(self.viewMatrix) trinity.SetPerspectiveProjection(self.fieldOfView, self.frontClip, self.backClip, self.aspectRatio) self.projection.PerspectiveFov(self.fieldOfView, self.aspectRatio, self.frontClip, self.backClip)
def SetPosition(self, pos): """ Set the position of the camera in world coordinates """ mat = geo2.MatrixInverse(self.localViewMatrix) mat = (mat[0], mat[1], mat[2], (pos[0], pos[1], pos[2], mat[3][3])) self.localViewMatrix = geo2.MatrixInverse(mat) self._position = pos
def CameraFacingMatrix(objtransform): viewMat = trinity.GetViewTransform() objInv = geo2.MatrixInverse(objtransform) viewInv = geo2.MatrixInverse(viewMat) viewInv = geo2.MatrixMultiply(viewInv, objInv) rmat = geo2.MatrixRotationX(math.pi * 0.5) rmat = geo2.MatrixMultiply(rmat, viewInv) rmat = (rmat[0], rmat[1], rmat[2], (0.0, 0.0, 0.0, rmat[3][3])) return rmat
def SetPosition(self, pos): mat = geo2.MatrixInverse(self.localViewMatrix) mat = (mat[0], mat[1], mat[2], (pos[0], pos[1], pos[2], mat[3][3])) self.localViewMatrix = geo2.MatrixInverse(mat) self._position = pos
def _PrimeForCameraPanning(self): projection2view = geo2.MatrixInverse(self.mapView.camera.projectionMatrix.transform) view2world = geo2.MatrixInverse(self.mapView.camera.viewMatrix.transform) x, y = ScaleDpi(uicore.uilib.x), ScaleDpi(uicore.uilib.y) ray, start = self.mapView.camera.GetRayAndPointFromUI(x, y, projection2view, view2world) targetPlaneNormal = self.mapView.camera.GetViewVector() initPointOfInterest = self.mapView.camera._pointOfInterestCurrent initRayToPlaneIntersection = RayToPlaneIntersection(start, ray, initPointOfInterest, targetPlaneNormal) return (initRayToPlaneIntersection, initPointOfInterest, targetPlaneNormal, projection2view, view2world)
def _TransformAxis(self, v): viewMat = trinity.GetViewTransform() viewVec = geo2.Vector(viewMat[0][2], viewMat[1][2], viewMat[2][2]) pos = self.GetTranslation() start = self.startPlanePos - pos start = geo2.Vec3Normalize(start) end = self.endPlanePos - pos end = geo2.Vec3Normalize(end) q = geo2.QuaternionIdentity() dot = geo2.Vec3Dot(start, end) if 1.0 - dot < 1e-05: return q dnormal = geo2.Vec3Cross(start, end) if self.activeManipAxis == 'w': worldInv = geo2.MatrixInverse(self.worldTranslation) axis = geo2.Vec3TransformNormal(viewVec, worldInv) axis = geo2.Vector(*axis) rdot = geo2.Vec3Dot(axis, viewVec) ddot = geo2.Vec3Dot(dnormal, axis) if ddot < 0.0 and rdot > 0.0: axis = -axis elif ddot > 0.0 and rdot < 0.0: axis = -axis elif self.activeManipAxis == 'ww': curP = self._Hemisphere(self.curX, self.curY) preP = self._Hemisphere(self.preX, self.preY) viewInverse = geo2.MatrixInverse(viewMat) norm = geo2.Vec3Cross(preP, curP) worldInv = geo2.MatrixInverse(self.worldTranslation) axis = geo2.Vec3TransformNormal(norm, worldInv) axis = geo2.Vec3TransformNormal(axis, viewInverse) dot = geo2.Vec3Dot(curP, preP) else: axis = self.axis[self.activeManipAxis] if geo2.Vec3Dot(dnormal, axis) < 0.0: axis = -axis if self.activeManipAxis == 'x' and self.worldTranslation[0][ 0] < 0.0 or self.activeManipAxis == 'y' and self.worldTranslation[ 1][1] < 0.0 or self.activeManipAxis == 'z' and self.worldTranslation[ 2][2] < 0.0: axis = -axis self.startPlanePos = self.endPlanePos if dot < -1: dot = -1 elif dot > 1: dot = 1 q = geo2.QuaternionRotationAxis(axis, math.acos(dot)) q = geo2.QuaternionNormalize(q) return q
def _GetModelStartTransformAndSpeed(self, muzzleID, moduleIdx): if not self.model: self.LogError('Missile::_GetModelStart with no model') return (None, None) now = blue.os.GetSimTime() q = self.model.rotationCurve.GetQuaternionAt(now) v = self.model.translationCurve.GetVectorAt(now) missileBallWorldTransform = geo2.MatrixAffineTransformation(1.0, (0.0, 0.0, 0.0), (q.x, q.y, q.z, q.w), (v.x, v.y, v.z)) sourceShipBallWorldTransform = missileBallWorldTransform firingPosWorldTransform = missileBallWorldTransform sourceShipBallSpeed = (0.0, 0.0, 0.0) sourceTurretSet = self._GetModelTurret(moduleIdx) sourceShipBall = self.globalsGlob.GetTargetBall(self.sourceShipID) if sourceShipBall is not None: q = sourceShipBall.GetQuaternionAt(now) v = sourceShipBall.GetVectorAt(now) sourceShipBallWorldTransform = geo2.MatrixAffineTransformation(1.0, (0.0, 0.0, 0.0), (q.x, q.y, q.z, q.w), (v.x, v.y, v.z)) s = sourceShipBall.GetVectorDotAt(now) sourceShipBallSpeed = (s.x, s.y, s.z) if sourceTurretSet is not None and len(sourceTurretSet.turretSets) > 0: gfxTS = sourceTurretSet.turretSets[0] firingPosWorldTransform = gfxTS.GetFiringBoneWorldTransform(gfxTS.currentCyclingFiresPos + muzzleID) invMissileBallWorldTransform = geo2.MatrixInverse(missileBallWorldTransform) startTransform = geo2.MatrixMultiply(firingPosWorldTransform, invMissileBallWorldTransform) startSpeed = geo2.Vec3TransformNormal(sourceShipBallSpeed, invMissileBallWorldTransform) return (startTransform, startSpeed)
def GetSafeSpotTransformMatrix(self): rotQuat = geo2.QuaternionRotationSetYawPitchRoll( self.GetSafeSpotYaw(), 0, 0) rotMatrix = geo2.MatrixRotationQuaternion(rotQuat) rotMatrix = geo2.MatrixInverse(rotMatrix) transMatrix = geo2.MatrixTranslation(*self.GetSafeSpotPosition()) return geo2.MatrixMultiply(rotMatrix, transMatrix)
def _TransformAxis(self, v): if self.activeManipAxis != 'w': ret = geo2.Vector(*v) worldTransInv = geo2.MatrixInverse(self.worldTranslation) v = geo2.Vec3TransformNormal(v, worldTransInv) t = self.GetTranslation() self.Translate(t + v) return ret return v
def SetupFakeAudioTransformLocation(self, shipPosition): self.fakeAudioTransform.translationCurve = trinity.TriVectorCurve() viewTransformOffset = geo2.MatrixTransformation( (0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 1.0), (1.0, 1.0, 1.0), (0.0, 0.0, 0.0), self.sceneRotation, self.sceneTranslation) viewTransformInverse = geo2.MatrixInverse(viewTransformOffset) newAudioEmitterPosition = geo2.Vec3TransformCoord( shipPosition, viewTransformInverse) self.fakeAudioTransform.translationCurve.value = newAudioEmitterPosition distance = geo2.Vec3Distance((0, 0, 0), newAudioEmitterPosition) gallenteHangarBaseline = 561.28692627 audioScaleFactor = distance / gallenteHangarBaseline self.generalAudioEntity.SetAttenuationScalingFactor(audioScaleFactor)
def PickObject(self, obj, rayOrigin, rayDirection, areaName = None): if obj.placeableRes is None: return model = obj.placeableRes.visualModel if model is None: return pickingGeometry = None pickingMesh = None pickingArea = None pickingCount = None for mesh in model.meshes: for area in mesh.transparentAreas: if areaName is None or area.name == areaName: pickingGeometry = mesh.geometry pickingMesh = mesh.meshIndex pickingArea = area.index pickingCount = area.count break for area in mesh.opaquePrepassAreas: if areaName is None or area.name == areaName: pickingGeometry = mesh.geometry pickingMesh = mesh.meshIndex pickingArea = area.index pickingCount = area.count break if pickingGeometry is not None: world = ((obj.transform._11, obj.transform._12, obj.transform._13, obj.transform._14), (obj.transform._21, obj.transform._22, obj.transform._23, obj.transform._24), (obj.transform._31, obj.transform._32, obj.transform._33, obj.transform._34), (obj.transform._41, obj.transform._42, obj.transform._43, obj.transform._44)) worldInv = geo2.MatrixInverse(world) origin = geo2.Vec3Transform(rayOrigin, worldInv) direction = geo2.Vec3TransformNormal(rayDirection, worldInv) for area in range(pickingCount): result = pickingGeometry.GetRayAreaIntersection(origin, direction, pickingMesh, pickingArea + area, trinity.TriGeometryCollisionResultFlags.ANY) if result is not None: return result
def _GetModelStartTransformAndSpeed(self, muzzleID, moduleIdx): """Returns a tuple of the missile model's start transform and the starting speed. Does a lot of complex logic that only works in a full client environment. Override it to provide a constant transform and speed. :returns: transform, speed. Use an identity matrix for transform to start the missile at the destinyball's origin. Returns None, None if the values cannot be calculated (because self.model is None). """ if not self.model: self.LogError('Missile::_GetModelStart with no model') return (None, None) now = blue.os.GetSimTime() q = self.model.rotationCurve.GetQuaternionAt(now) v = self.model.translationCurve.GetVectorAt(now) missileBallWorldTransform = geo2.MatrixAffineTransformation( 1.0, (0.0, 0.0, 0.0), (q.x, q.y, q.z, q.w), (v.x, v.y, v.z)) sourceShipBallWorldTransform = missileBallWorldTransform firingPosWorldTransform = missileBallWorldTransform sourceShipBallSpeed = (0.0, 0.0, 0.0) sourceTurretSet = self._GetModelTurret(moduleIdx) sourceShipBall = self.globalsGlob.GetTargetBall(self.sourceShipID) if sourceShipBall is not None: q = sourceShipBall.GetQuaternionAt(now) v = sourceShipBall.GetVectorAt(now) sourceShipBallWorldTransform = geo2.MatrixAffineTransformation( 1.0, (0.0, 0.0, 0.0), (q.x, q.y, q.z, q.w), (v.x, v.y, v.z)) s = sourceShipBall.GetVectorDotAt(now) sourceShipBallSpeed = (s.x, s.y, s.z) if sourceTurretSet is not None and len( sourceTurretSet.turretSets) > 0: gfxTS = sourceTurretSet.turretSets[0] firingPosWorldTransform = gfxTS.GetFiringBoneWorldTransform( gfxTS.currentCyclingFiresPos + muzzleID) invMissileBallWorldTransform = geo2.MatrixInverse( missileBallWorldTransform) startTransform = geo2.MatrixMultiply(firingPosWorldTransform, invMissileBallWorldTransform) startSpeed = geo2.Vec3TransformNormal(sourceShipBallSpeed, invMissileBallWorldTransform) return (startTransform, startSpeed)
def _UpdateCameraAnimation(self, alignToParent=False, alignTargets=None, loop=False, clipName=None, parent=None): def FindParametersInPostFx(): blurScaleH = None blurScaleV = None blurFade = None exposure = None rj = self.GetRenderJob() if rj: for step in rj.steps: if step.name == 'RJ_POSTPROCESSING': if step.job: for jobStep in step.job.steps: if jobStep.name == 'PostProcess Blur': for fx in jobStep.PostProcess.stages: for param in fx.parameters: if param.name == 'ScalingFactor': if fx.name == 'Gaussian Horizontal Blur': blurScaleH = param if fx.name == 'Gaussianl Vertical Blur': blurScaleV = param if fx.name == '4x Up Filter and Add': blurFade = param if jobStep.name == 'PostProcess Exposure': for fx in jobStep.PostProcess.stages: for param in fx.parameters: if param.name == 'ScalingFactor': if fx.name == '4x Up Filter and Add': exposure = param return (blurScaleH, blurScaleV, blurFade, exposure) transformTrack = None shakeSequencer = None duration = 0.0 curveSetName = 'AnimatedCamera' scene = sm.GetService('sceneManager').GetRegisteredScene('default') viewStep, proj = self.GetViewAndProjection() camera = viewStep.camera for cset in scene.curveSets: if cset.name == curveSetName: transformTrack = cset.curves[0] if len(cset.curves) > 1: shakeSequencer = cset.curves[1] duration = transformTrack.duration - 1 / 10.0 oldFov = camera.fieldOfView ppJob.AddPostProcess('Blur', 'res:/fisfx/postprocess/blur.red') ppJob.AddPostProcess('Exposure', 'res:/fisfx/postprocess/exposure.red') blurScaleH, blurScaleV, blurFade, exposure = FindParametersInPostFx() ballpark = sm.GetService('michelle').GetBallpark() ball = ballpark.GetBall(session.shipid) if parent: ball = parent.translationCurve if alignTargets: ball = alignTargets[0] if viewStep: viewStep.view = trinity.TriView() startTime = blue.os.GetSimTime() if loop: endTime = startTime + 36000000000L else: endTime = startTime + duration * 10000000 time = startTime globalSceneScale = 4.0 / 30.0 * ball.model.boundingSphereRadius lastWorldPos = None lastWorldRot = None while time < endTime and not self.resetCamera and not self.interrupt: time = blue.os.GetSimTime() weight1 = 0.0 weight2 = 0.0 if self.vectorTracks: currentTime = trinity.device.animationTime for cvt in self.vectorTracks: if cvt == 'targetWeight1' or cvt == 'targetWeight2': vecTrack = self.vectorTracks[cvt] if cvt == 'targetWeight1': weight1 = vecTrack.value else: weight2 = vecTrack.value if viewStep: trans = geo2.MatrixTranslation( transformTrack.translation[0] * globalSceneScale, transformTrack.translation[1] * globalSceneScale, transformTrack.translation[2] * globalSceneScale) rot = geo2.MatrixRotationQuaternion(transformTrack.rotation) comp = geo2.MatrixMultiply(rot, trans) if alignToParent: if not ball.model and lastWorldPos: translation = lastWorldPos rotation = lastWorldRot else: rotation = ball.GetQuaternionAt(time) translation = ball.model.worldPosition lastWorldPos = translation lastWorldRot = rotation transOffset = geo2.MatrixTranslation( translation[0], translation[1], translation[2]) rotOffset = geo2.MatrixRotationQuaternion( (rotation.x, rotation.y, rotation.z, rotation.w)) comp = geo2.MatrixMultiply(comp, rotOffset) comp = geo2.MatrixMultiply(comp, transOffset) if alignTargets: t1 = alignTargets[0].model.worldPosition t2 = alignTargets[1].model.worldPosition if True: sphereOffset = alignTargets[ 1].model.boundingSphereCenter qr = alignTargets[ 1].model.rotationCurve.GetQuaternionAt(time) quatRotation = (qr.x, qr.y, qr.z, qr.w) correctedOffset = geo2.QuaternionTransformVector( quatRotation, sphereOffset) t2 = geo2.Vec3Add(t2, correctedOffset) rot = geo2.MatrixLookAtRH(t2, t1, (0.0, 1.0, 0.0)) rot = geo2.MatrixInverse(rot) rot = (rot[0], rot[1], rot[2], (t1[0], t1[1], t1[2], 1.0)) comp = geo2.MatrixMultiply(comp, rot) if weight1 > 0.0001: shake = shakeSequencer.value pos = (comp[3][0], comp[3][1], comp[3][2]) targetPos = (t2[0] + shake.x, t2[1] + shake.y, t2[2] + shake.z) lookat = geo2.MatrixLookAtRH(pos, targetPos, (0.0, 1.0, 0.0)) lookat = geo2.MatrixInverse(lookat) qlookat = geo2.QuaternionRotationMatrix(lookat) qorig = geo2.QuaternionRotationMatrix(comp) qresult = geo2.Lerp(qorig, qlookat, weight1) mresult = geo2.MatrixRotationQuaternion(qresult) comp = (mresult[0], mresult[1], mresult[2], comp[3]) if viewStep.view: viewStep.view.transform = geo2.MatrixInverse(comp) if self.vectorTracks: currentTime = trinity.device.animationTime for cvt in self.vectorTracks: if cvt == 'fov': vecTrack = self.vectorTracks['fov'] fovValue = vecTrack.value camera.fieldOfView = fovValue proj.projection.PerspectiveFov( fovValue, trinity.device.width / float(trinity.device.height), camera.frontClip, camera.backClip) if cvt == 'blur': vecTrack = self.vectorTracks['blur'] blurValue = vecTrack.value if blurScaleH and blurScaleV and blurFade: blurScaleH.value = blurValue blurScaleV.value = blurValue if blurValue > 0.01: blurFade.value = 1.0 else: blurFade.value = 0.0 if cvt == 'exposure': vecTrack = self.vectorTracks['exposure'] exposureValue = vecTrack.value if exposure: exposure.value = exposureValue if 'fov' not in self.vectorTracks: camera.fieldOfView = oldFov proj.projection.PerspectiveFov( oldFov, trinity.device.width / float(trinity.device.height), camera.frontClip, camera.backClip) blue.synchro.Yield() if exposure and blurFade: exposure.value = 0.0 blurFade.value = 0.0 if viewStep: viewStep.view = None camera.fieldOfView = oldFov if not self.interrupt: if not camera.fieldOfView == 1.0: self.LogWarn('Warning: Camera fov not 1, correcting...') camera.fieldOfView = 1.0 proj.projection = camera.projectionMatrix self.playingClip = False if self.continuousType and not self.interrupt and not self.resetCamera: self.interrupt = False self.UpdateContinuous() self.resetCamera = False self.interrupt = False if clipName: self.LogInfo('Camera clip done:', clipName)
def GetViewVector(self): t = geo2.MatrixInverse(self.viewMatrix.transform) ret = geo2.Vec3NormalizeD((t[2][0], t[2][1], t[2][2])) return ret