def GetSolidAroundLine(line, radius): rad = math.pi * 2.0 / 3.0 triangle1 = [] triangle1.append((math.cos(0) * radius, math.sin(0) * radius, 0.0)) triangle1.append((math.cos(rad) * radius, math.sin(rad) * radius, 0.0)) triangle1.append( (math.cos(2 * rad) * radius, math.sin(2 * rad) * radius, 0.0)) dirOfLine = geo2.Vec3Normalize(geo2.Vec3Subtract(line[1], line[0])) if abs(geo2.Vec3Dot((0.0, 0.0, 1.0), dirOfLine)) != 1.0: rot = geo2.QuaternionRotationArc((0.0, 0.0, 1.0), dirOfLine) else: rot = geo2.QuaternionIdentity() rot = geo2.MatrixRotationQuaternion(rot) t1 = geo2.MatrixTranslation(*line[0]) t2 = geo2.MatrixTranslation(*line[1]) compA = geo2.MatrixMultiply(rot, t1) compB = geo2.MatrixMultiply(rot, t2) startTri = geo2.Vec3TransformCoordArray(triangle1, compA) endTri = geo2.Vec3TransformCoordArray(triangle1, compB) triangles = [ startTri[1], endTri[0], startTri[0], endTri[1], endTri[0], startTri[1], startTri[2], endTri[1], startTri[1], endTri[2], endTri[1], startTri[2], startTri[0], endTri[2], startTri[2], endTri[0], endTri[2], startTri[0] ] return triangles
def UpdateViewProjForLight(self, stepView, stepProj, light, effectValue): """ Renderstep callback to make sure the rendersteps that deal with view transform and projection, are still up to date with any changes to the lights. Works out the values for this light and then delegates to the individual MeshData instances. """ eye = light.position at = geo2.Add(eye, light.coneDirection) up = (0, 0, 1) if SkinSpotLightShadows.REUSE_ENGINE_MAPS: VP = light.GetViewProjMatrix() else: if effectValue: effectValue.value = (0, 0, 0, light.radius) viewmat = geo2.MatrixLookAtRH(eye, at, up) self.ComputeProjectionMatrix(stepProj.projection, light, viewmat) stepView.view.transform = viewmat VP1 = geo2.MatrixMultiply(viewmat, stepProj.projection.transform) VP = geo2.MatrixMultiply(VP1, self.uvAdjustMatrix) VPT = geo2.MatrixTranspose(VP) for meshData in self.meshes.itervalues(): meshData.updateParams(light, VPT)
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 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 GenGeometry(self): rotateMat = geo2.MatrixRotationZ(-math.pi / 2.0) transform = geo2.MatrixTranslation(0.0, 1.0, 0.0) transform = geo2.MatrixMultiply(transform, rotateMat) c_tris = geo2.Vec3TransformCoordArray(dungeonEditorToolGeometry.CONE_TRIS, transform) xTransAreaCone = dungeonEditorToolGeometry.area('x', dungeonEditorToolGeometry.RED) xTransAreaCone.AddToSolidSet(c_tris) xTransAreaAxis = dungeonEditorToolGeometry.area('x', dungeonEditorToolGeometry.RED) xTransAreaAxis.AddToLineSet([(0.0, 0.0, 0.0), (1.0, 0.0, 0.0)]) t = dungeonEditorToolGeometry.GetSolidAroundLine([(0.3, 0.0, 0.0), (1.0, 0.0, 0.0)], 0.08) xTransAreaAxis.AddToPickingSet(t) transform = geo2.MatrixTranslation(0.0, 1.0, 0.0) c_tris = geo2.Vec3TransformCoordArray(dungeonEditorToolGeometry.CONE_TRIS, transform) yTransAreaCone = dungeonEditorToolGeometry.area('y', dungeonEditorToolGeometry.GREEN) yTransAreaCone.AddToSolidSet(c_tris) yTransAreaAxis = dungeonEditorToolGeometry.area('y', dungeonEditorToolGeometry.GREEN) yTransAreaAxis.AddToLineSet([(0.0, 0.0, 0.0), (0.0, 1.0, 0.0)]) t = dungeonEditorToolGeometry.GetSolidAroundLine([(0.0, 0.3, 0.0), (0.0, 1.0, 0.0)], 0.08) yTransAreaAxis.AddToPickingSet(t) transform = geo2.MatrixTranslation(0.0, 1.0, 0.0) rotateMat = geo2.MatrixRotationX(math.pi / 2.0) transform = geo2.MatrixMultiply(transform, rotateMat) c_tris = geo2.Vec3TransformCoordArray(dungeonEditorToolGeometry.CONE_TRIS, transform) zTransAreaCone = dungeonEditorToolGeometry.area('z', dungeonEditorToolGeometry.BLUE) zTransAreaCone.AddToSolidSet(c_tris) zTransAreaAxis = dungeonEditorToolGeometry.area('z', dungeonEditorToolGeometry.BLUE) zTransAreaAxis.AddToLineSet([(0.0, 0.0, 0.0), (0.0, 0.0, 1.0)]) t = dungeonEditorToolGeometry.GetSolidAroundLine([(0.0, 0.0, 0.3), (0.0, 0.0, 1.0)], 0.08) zTransAreaAxis.AddToPickingSet(t) wTransAreaPlane = dungeonEditorToolGeometry.area('w', dungeonEditorToolGeometry.CYAN) wTransAreaPlane.AddToLineSet(dungeonEditorToolGeometry.CIRCLE_POINTS_QUART) wTransAreaPlane._lineset.viewOriented = True picking_tris = dungeonEditorToolGeometry.GenCircleTriangles(0.25) if not trinity.IsRightHanded(): picking_tris.reverse() wTransAreaPlane.AddToPickingSet(picking_tris) translationGeo = dungeonEditorToolGeometry.geometry(self.primitiveScene) translationGeo.AppendArea(wTransAreaPlane) translationGeo.AppendArea(xTransAreaCone) translationGeo.AppendArea(xTransAreaAxis) translationGeo.AppendArea(yTransAreaCone) translationGeo.AppendArea(yTransAreaAxis) translationGeo.AppendArea(zTransAreaCone) translationGeo.AppendArea(zTransAreaAxis) self.cones.append(xTransAreaCone) self.cones.append(yTransAreaCone) self.cones.append(zTransAreaCone) self.axes.append(xTransAreaAxis) self.axes.append(yTransAreaAxis) self.axes.append(zTransAreaAxis) return translationGeo
def ApplyParticleEffect(self, *args): if not sm.GetService('device').GetAppFeatureState('Interior.ParticlesEnabled', True): return True entityID, effectFilePath, boneName, duration, xOffset, yOffset, zOffset = args[:7] yawOffset, pitchOffset, rollOffset, ignoreTransform, effectStringID = args[7:] effectID = self._GetNextEffectID() zaction.AddPropertyForCurrentPythonProc({effectStringID: effectID}) translation = geo2.MatrixTranslation(xOffset, yOffset, zOffset) rotation = geo2.MatrixRotationYawPitchRoll(math.radians(yawOffset), math.radians(pitchOffset), math.radians(rollOffset)) offset = geo2.MatrixMultiply(rotation, translation) with self.activeParticlesSemaphore: trinityObject = trinity.Load(effectFilePath) entity = self.entityClient.FindEntityByID(entityID) scene = self.graphicClient.GetScene(entity.scene.sceneID) scene.AddDynamic(trinityObject) curveSet = None positionComponent = entity.GetComponent('position') if boneName or positionComponent: curveSet = trinity.TriCurveSet() scene.AddCurveSetToScene(curveSet) if boneName: paperDollComponent = entity.GetComponent('paperdoll') model = paperDollComponent.doll.avatar curve = trinity.Tr2BoneMatrixCurve() curve.skinnedObject = model curve.bone = boneName if not ignoreTransform: offset = geo2.MatrixMultiply(offset, trinityObject.transform) curve.transform = offset else: curve = GameWorld.PositionComponentCurve() curve.positionComponent = positionComponent curve.positionOffset = geo2.Vector(xOffset, yOffset, zOffset) curve.rotationOffset = geo2.QuaternionRotationSetYawPitchRoll(yawOffset, pitchOffset, rollOffset) bind = trinity.TriValueBinding() bind.destinationObject = trinityObject bind.destinationAttribute = 'transform' bind.sourceObject = curve bind.sourceAttribute = 'currentValue' curveSet.curves.append(curve) curveSet.bindings.append(bind) curveSet.Play() expireTime = blue.os.GetWallclockTime() + duration * const.MSEC effectData = util.KeyVal(effectID=effectID, entityID=entityID, effectFilePath=effectFilePath, expireTime=expireTime, offset=offset, trinityObject=trinityObject, sceneID=entity.scene.sceneID, curveSet=curveSet) self.activeParticleEffects[effectID] = effectData if duration > 0: self.timedParticleEffects.append(effectData) self.timedParticleEffects.sort(key=lambda entry: entry.expireTime) self.updateTaskletLock.set() self._ConnectEffectCurveSets(effectData, effectStringID) return True
def render_cb(dev): global START_TIME current = time.clock() m = geo2.MatrixRotationY((current - START_TIME) * rad_per_sec) trinity.SetViewTransform( geo2.MatrixMultiply(m, trinity.GetViewTransform())) START_TIME = current
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 GetTargetPlaneProjectionMatrix(self): trans = self.GetTranslation() adjusted_translation = ProjectPointTowardsFrontPlane(trans) rmat = geo2.MatrixRotationQuaternion(self.GetRotation()) rmat = geo2.MatrixTranspose(rmat) mat = geo2.MatrixTranslation(adjusted_translation.x, adjusted_translation.y, adjusted_translation.z) self.frontPlaneTranslation = geo2.MatrixMultiply(rmat, mat) return self.frontPlaneTranslation
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 UpdateViewProjForLight(self, stepView, stepProj, light, effectValue): eye = light.position at = geo2.Add(eye, light.coneDirection) up = (0, 0, 1) if SkinSpotLightShadows.REUSE_ENGINE_MAPS: VP = light.GetViewProjMatrix() else: if effectValue: effectValue.value = (0, 0, 0, light.radius) viewmat = geo2.MatrixLookAtRH(eye, at, up) self.ComputeProjectionMatrix(stepProj.projection, light, viewmat) stepView.view.transform = viewmat VP1 = geo2.MatrixMultiply(viewmat, stepProj.projection.transform) VP = geo2.MatrixMultiply(VP1, self.uvAdjustMatrix) VPT = geo2.MatrixTranspose(VP) for meshData in self.meshes.itervalues(): meshData.updateParams(light, VPT)
def _GetViewAndProjectionUsingProjectedBoundingBox( calculateProjectedBoundingBox, scene=None, boundingSphereRadius=None, boundingSphereCenter=None, boundingBoxMin=None, boundingBoxMax=None, cameraAngle=None): """ Fits an object in frame with view and projection matrices. We first do a rough fit using either the bounding sphere or bounding box. We then "zoom in" to the point where the projected bounding box fills 90% of the image. """ cameraAngle = cameraAngle or GETPHOTO_ANGLE if boundingSphereRadius: radius = boundingSphereRadius center = boundingSphereCenter if boundingSphereCenter else (0.0, 0.0, 0.0) else: center = geo2.Vec3Add(boundingBoxMin, boundingBoxMax) center = geo2.Vec3Scale(center, 0.5) radius = geo2.Vec3Length( geo2.Vec3Subtract(boundingBoxMax, boundingBoxMin)) dist = _SphericalFit(radius) viewEyeAtUp = _GetViewMatrixFromAngle(cameraAngle, center, dist) projTransform = geo2.MatrixPerspectiveFovRH(*GETPHOTO_PROJECTION) viewTransform = geo2.MatrixLookAtRH(*viewEyeAtUp) combinedTransform = viewTransform combinedTransform = geo2.MatrixMultiply(combinedTransform, projTransform) safeMin, safeMax = calculateProjectedBoundingBox(combinedTransform) deltaX = safeMax[0] - safeMin[0] deltaY = safeMax[1] - safeMin[1] scalingFactor = 0.9 * (2.0 / max(deltaX, deltaY)) try: if scene.backgroundEffect is not None: params = scene.backgroundEffect.Find(['trinity.Tr2FloatParameter']) for param in params: if param.name == 'ProjectionScaling': param.value = scalingFactor except AttributeError: pass offsetX = -1 * scalingFactor * (safeMin[0] + safeMax[0]) / 2.0 offsetY = -1 * scalingFactor * (safeMin[1] + safeMax[1]) / 2.0 scale = 1.0 / tan(GETPHOTO_FOV / 2.0) * scalingFactor zn = 1.0 zf = dist + radius * 2 t = zn * (1 - offsetY) / scale b = -t * (1 + offsetY) / (1 - offsetY) r = zn * (1 - offsetX) / scale l = -r * (1 + offsetX) / (1 - offsetX) projection = trinity.TriProjection() projection.PerspectiveOffCenter(l, r, b, t, zn, zf) view = trinity.TriView() view.SetLookAtPosition(*viewEyeAtUp) return (view, projection)
def AddToScene(self, entity, component): if component.trinityObject is None: component.trinityObject = trinity.Load(component.redFile) scene = self.graphicClient.GetScene(entity.scene.sceneID) if scene: scene.AddDynamic(component.trinityObject) positionComponent = entity.GetComponent('position') if positionComponent is not None and component.trinityObject is not None: component.trinityObject.transform = geo2.MatrixMultiply( geo2.MatrixRotationQuaternion(positionComponent.rotation), geo2.MatrixTranslation(positionComponent.position[0], positionComponent.position[1], positionComponent.position[2]))
def Update(self, transform): mat = geo2.MatrixMultiply(self.localTransform, transform) tmat = GeoToTri(mat) if len(self.lines) > 0: self.lineset.transform = tmat if len(self.triangles) > 0: self.solidset.transform = tmat if len(self.points) > 0: self.pointset.transform = tmat if self.bounds: try: self.bounds.Update(mat) except Exception as e: import traceback traceback.print_exc() sys.exc_clear()
def _GetViewAndProjectionUsingProjectedBoundingBox(self, CalculateProjectedBoundingBox, scene = None, boundingSphereRadius = None, boundingSphereCenter = None, boundingBoxMin = None, boundingBoxMax = None, cameraAngle = None): self.LogInfo('TakeSnapShotUsingBoundingBox') cameraAngle = cameraAngle or GETPHOTO_ANGLE if boundingSphereRadius: radius = boundingSphereRadius center = boundingSphereCenter if boundingSphereCenter else (0.0, 0.0, 0.0) elif boundingBoxMin and boundingBoxMax: boundingBoxMin = geo2.Vector(boundingBoxMin.x, boundingBoxMin.y, boundingBoxMin.z) boundingBoxMax = geo2.Vector(boundingBoxMax.x, boundingBoxMax.y, boundingBoxMax.z) center = (boundingBoxMin + boundingBoxMax) / 2.0 radius = geo2.Vec3Length(boundingBoxMax - boundingBoxMin) else: raise RuntimeError('Can not do a rough fit without either a bounding sphere or bounding box.') dist = self._SphericalFit(radius) viewEyeAtUp = self._GetViewMatrixFromAngle(cameraAngle, center, dist) projTransform = geo2.MatrixPerspectiveFovRH(*GETPHOTO_PROJECTION) viewTransform = geo2.MatrixLookAtRH(*viewEyeAtUp) combinedTransform = viewTransform combinedTransform = geo2.MatrixMultiply(combinedTransform, projTransform) safeMin, safeMax = CalculateProjectedBoundingBox(combinedTransform) deltaX = safeMax[0] - safeMin[0] deltaY = safeMax[1] - safeMin[1] scalingFactor = 0.9 * (2.0 / max(deltaX, deltaY)) try: if scene.backgroundEffect is not None: params = scene.backgroundEffect.Find(['trinity.TriFloatParameter', 'trinity.Tr2FloatParameter']) for param in params: if param.name == 'ProjectionScaling': param.value = scalingFactor except AttributeError: pass offsetX = -1 * scalingFactor * (safeMin[0] + safeMax[0]) / 2.0 offsetY = -1 * scalingFactor * (safeMin[1] + safeMax[1]) / 2.0 scale = 1.0 / tan(GETPHOTO_FOV / 2.0) * scalingFactor zn = 1.0 zf = dist + radius * 2 t = zn * (1 - offsetY) / scale b = -t * (1 + offsetY) / (1 - offsetY) r = zn * (1 - offsetX) / scale l = -r * (1 + offsetX) / (1 - offsetX) projection = trinity.TriProjection() projection.PerspectiveOffCenter(l, r, b, t, zn, zf) view = trinity.TriView() view.SetLookAtPosition(*viewEyeAtUp) return (view, projection)
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 UpdateTransform(self, transform): mat = geo2.MatrixMultiply(self.localTransform, transform) for each in iter(self.primitives): each.localTransform = mat
def ComputeProjectionMatrix(self, projection, light, viewmat): fov = light.coneAlphaOuter * 3.1415927 / 90.0 projection.PerspectiveFov(fov, 1.0, 0.1, light.radius) if not self.scene or not self.autoOptimizeFrustum: return model = None for dynamic in self.scene.dynamics: if dynamic.__typename__ == 'Tr2IntSkinnedObject': if model is not None: return model = dynamic if model is None: return VP = geo2.MatrixMultiply(viewmat, projection.transform) m = model.transform mm = ((m._11, m._12, m._13, m._14), (m._21, m._22, m._23, m._24), (m._31, m._32, m._33, m._34), (m._41, m._42, m._43, m._44)) obb = model.GetClippedWorldBoundingObb(mm) def getPoint(i): p = obb[3] x = obb[0] y = obb[1] z = obb[2] size = obb[4] p = geo2.Vec3Add(p, geo2.Vec3Scale(x, size[0] if i & 1 else -size[0])) p = geo2.Vec3Add(p, geo2.Vec3Scale(y, size[1] if i & 2 else -size[1])) p = geo2.Vec3Add(p, geo2.Vec3Scale(z, size[2] if i & 4 else -size[2])) return p maxx = -1.0 maxy = -1.0 minx = 1.0 miny = 1.0 pClip = [] for i in xrange(8): p = getPoint(i) pClip.append((p[0], p[1], p[2], 1)) pClip = geo2.Vec4TransformArray(pClip, VP) for pp in pClip: if pp[3] < 0.0001: continue pp = (pp[0] / pp[3], pp[1] / pp[3], pp[2] / pp[3]) minx = min(minx, pp[0]) miny = min(miny, pp[1]) maxx = max(maxx, pp[0]) maxy = max(maxy, pp[1]) def clip(x): if x < -1.0: return -1.0 if x > 1.0: return 1.0 return x minx = clip(minx) miny = clip(miny) maxx = clip(maxx) maxy = clip(maxy) if minx >= maxx or miny >= maxy: return scalex = 2.0 / (maxx - minx) scaley = 2.0 / (maxy - miny) biasx = (minx + maxx) / (minx - maxx) biasy = (miny + maxy) / (miny - maxy) bias = ((scalex, 0, 0, 0), (0, scaley, 0, 0), (0, 0, 1, 0), (biasx, biasy, 0, 1)) projM = geo2.MatrixMultiply(projection.transform, bias) projection.CustomProjection(projM)