def update_line_position(posInfo): lineData = posInfo[2] lineID = lineData.lineID fromPosition = posInfo[0] if fromPosition is None: fromMapNode = GetNodeBySolarSystemID(lineData.fromSolarSystemID) fromPosition = fromMapNode.position posInfo[0] = fromPosition toPosition = posInfo[1] if toPosition is None: toMapNode = GetNodeBySolarSystemID(lineData.toSolarSystemID) toPosition = toMapNode.position posInfo[1] = toPosition if lineID in adjustLines: fromPosition = geo2.Vec3Add(fromPosition, adjustLines[lineID][0]) toPosition = geo2.Vec3Add(toPosition, adjustLines[lineID][2]) lineSet.ChangeLinePositionCrt(lineID, fromPosition, toPosition) if lineData.jumpType == JUMPBRIDGE_TYPE: linkVec = geo2.Vec3Subtract(toPosition, fromPosition) normLinkVec = geo2.Vec3Normalize(linkVec) rightVec = geo2.Vec3Cross(worldUp, normLinkVec) upVec = geo2.Vec3Cross(rightVec, normLinkVec) offsetVec = geo2.Vec3Scale(geo2.Vec3Normalize(upVec), geo2.Vec3Length(linkVec) * 1.0) midPos = geo2.Vec3Scale(geo2.Vec3Add(toPosition, fromPosition), 0.5) splinePos = geo2.Vec3Add(midPos, offsetVec) lineSet.ChangeLineIntermediateCrt(lineID, splinePos)
def _UpdateCameraNoiseOffset(self): if self.noiseScaleCurve: self.noiseScale = self.noiseScaleCurve.UpdateScalar( blue.os.GetSimTime()) if self.noiseScale == 0: return if self.noiseDampCurve: self.noiseDamp = self.noiseDampCurve.UpdateScalar( blue.os.GetSimTime()) dT = 1.0 / blue.os.fps ran = random.random() - 0.5 self._noiseX = (self._noiseX + self.noiseDamp * ran) / (1.0 + self.noiseDamp * dT) self._noiseX = max(-MAX_NOISE, min(self._noiseX, MAX_NOISE)) ran = random.random() - 0.5 self._noiseY = (self._noiseY + self.noiseDamp * ran) / (1.0 + self.noiseDamp * dT) self._noiseY = max(-MAX_NOISE, min(self._noiseY, MAX_NOISE)) noiseScale = self.GetZoomDistance() / 100.0 * self.noiseScale direction = self.GetLookAtDirection() vecX = geo2.Vec3Cross(direction, self._upDirection) vecY = geo2.Vec3Cross(direction, vecX) vecX = geo2.Vec3Scale(vecX, self._noiseX * noiseScale) vecY = geo2.Vec3Scale(vecY, self._noiseY * noiseScale) noiseOffset = geo2.Vec3Add(vecX, vecY) self._AddToAtOffset(noiseOffset)
def CreateViewMatrix(self): upVector = (0, 1, 0) xaxis = geo2.Vec3Normalize(geo2.Vec3Cross(upVector, self.direction)) yaxis = geo2.Vec3Cross(self.direction, xaxis) return ((xaxis[0], yaxis[0], self.direction[0], 0.0), (xaxis[1], yaxis[1], self.direction[1], 0.0), (xaxis[2], yaxis[2], self.direction[2], 0.0), (-geo2.Vec3Dot(xaxis, self.cameraPosition), -geo2.Vec3Dot(yaxis, self.cameraPosition), -geo2.Vec3Dot(self.direction, self.cameraPosition), 1.0))
def GetCorrectCameraXandYFactors(self, position, poi): cameraZ = geo2.Vec3Normalize(geo2.Subtract(position, poi)) cameraX = geo2.Vec3Cross(cameraZ, (0.0, 1.0, 0.0)) cameraY = geo2.Vec3Cross(cameraZ, cameraX) cameraMatrix = ((cameraX[0], cameraY[0], cameraZ[0], 0.0), (cameraX[1], cameraY[1], cameraZ[1], 0.0), (cameraX[2], cameraY[2], cameraZ[2], 0.0), (0.0, 0.0, 0.0, 1.0)) offset = geo2.Subtract(self.focus, poi) res = geo2.Vec3Transform(offset, cameraMatrix) return (res[0], res[1])
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 SetPitch(self, pitch): pitch = self.ClampPitch(pitch) axis = geo2.Vec3Cross(self.upDirection, self.GetLookAtDirection()) rotMat = geo2.MatrixRotationAxis(axis, pitch) vec = (0, self.GetZoomDistance(), 0) self._eyePosition = geo2.Vec3Add(self._atPosition, geo2.Vec3Transform(vec, rotMat))
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 SetModel(self, scale): graphic = cfg.invtypes.Get(self.pinKv.typeID).Graphic() self.model = None if graphic and graphic.graphicFile: graphicFile = str(graphic.graphicFile) graphicFile = graphicFile.replace(':/model', ':/dx9/model').replace( '.blue', '.red') self.model = trinity.Load(graphicFile) if not self.model or self.model.__bluetype__ != 'trinity.EveTransform': self.model = trinity.Load( 'res:/dx9/model/worldobject/Orbital/UI/Terrestrial/Command/CommT_T1/CommT_T1.red' ) if not self.model: return EXT = 1.026 self.model.scaling = (scale, scale, scale) self.model.sortValueMultiplier = 0.5 self.model.translation = (EXT * self.surfacePoint.x, EXT * self.surfacePoint.y, EXT * self.surfacePoint.z) plnSurfRotMat = geo2.MatrixRotationAxis( geo2.Vec3Cross( geo2.Vec3Normalize(self.surfacePoint.GetAsXYZTuple()), (0.0, 1.0, 0.0)), -math.acos( geo2.Vec3Dot( geo2.Vec3Normalize(self.surfacePoint.GetAsXYZTuple()), (0.0, 1.0, 0.0)))) rotQuat = geo2.QuaternionRotationMatrix(plnSurfRotMat) self.model.rotation = rotQuat self.model.name = '%s,%s' % (planetCommon.PINTYPE_NORMAL, self.pinKv.id) self.transform.children.append(self.model)
def AddExplosion(self, uniqueName, explosionGfxID, spreadOut): if uniqueName not in self.districts: self.logger.error('Could not find district %s for planet with id %s', str(uniqueName), str(self.itemID)) graphics = GetGraphic(explosionGfxID) if graphics is None: self.logger.error("Explosion graphicsID %s doesn't exist!", str(explosionGfxID)) return fx = trinity.Load(graphics.graphicFile) if fx is None: self.logger.error("Explosion %s doesn't exist!", str(graphics.graphicFile)) return if len(fx.curveSets) == 0: self.logger.error('Explosion %s has no curveSets! This is useless...', str(graphics.graphicFile)) return direction = self.districts[uniqueName].centerNormal rotMatrix1 = geo2.MatrixRotationAxis((direction[1], direction[2], direction[0]), random.random() * spreadOut * self.districts[uniqueName].pinRadius) rotMatrix2 = geo2.MatrixRotationAxis(direction, random.uniform(0, 2.0 * math.pi)) direction = geo2.Vec3TransformNormal(direction, rotMatrix1) direction = geo2.Vec3TransformNormal(direction, rotMatrix2) fx.translation = direction fx.scaling = (5000.0 / PLANET_SIZE_SCALE, 5000.0 / PLANET_SIZE_SCALE, 5000.0 / PLANET_SIZE_SCALE) v1 = geo2.Vec3Cross(geo2.Vec3Normalize(direction), (0.0, 1.0, 0.0)) alpha = -math.acos(geo2.Vec3Dot(geo2.Vec3Normalize(direction), (0.0, 1.0, 0.0))) fx.rotation = geo2.QuaternionRotationAxis(v1, alpha) duration = fx.curveSets[0].GetMaxCurveDuration() self.districtExplosions.children.append(fx) uthread.new(self._RemoveExplosionFromDistrict, fx, duration)
def OrbitUpdateThread(self): try: while True: if self.orbitTarget is None: break vLookAt = self.GetLookAtDirection() currPitch = self.GetAngleLookAtToUpDirection() self.eyePosition = geo2.Subtract(self.eyePosition, self.atPosition) yawLeft = self.orbitTarget[0] if yawLeft: yaw = self.kOrbitSpeed * yawLeft / blue.os.fps if math.fabs(yawLeft) < self.kOrbitStopAngle: yaw = yawLeft rotYaw = geo2.MatrixRotationAxis(self.upDirection, yaw) self.eyePosition = geo2.Vec3Transform(self.eyePosition, rotYaw) self.orbitTarget[0] -= yaw targetPitch = self.orbitTarget[1] pitchLeft = currPitch - targetPitch if pitchLeft: pitch = self.kOrbitSpeed * pitchLeft / blue.os.fps if math.fabs(pitchLeft) < self.kOrbitStopAngle: pitch = pitchLeft axis = geo2.Vec3Cross(vLookAt, self.upDirection) rotPitch = geo2.MatrixRotationAxis(axis, pitch) self.eyePosition = geo2.Vec3Transform(self.eyePosition, rotPitch) self.eyePosition = geo2.Add(self.eyePosition, self.atPosition) if not pitchLeft and not yawLeft: break blue.synchro.Yield() finally: self.orbitUpdateThread = None self.orbitTarget = None
def _SplitTriangle(self, v0, v1, v2, lines, cLines, hLines, sps, level): level -= 1 lc0 = self._GetLineCenterPoint(v0, v1) lc1 = self._GetLineCenterPoint(v1, v2) lc2 = self._GetLineCenterPoint(v2, v0) tc = self._GetTriangleCenterPoint(v0, v1, v2) if level > 0: self._SplitTriangle(v0, lc0, lc2, lines, cLines, hLines, sps, level) self._SplitTriangle(v1, lc1, lc0, lines, cLines, hLines, sps, level) self._SplitTriangle(v2, lc2, lc1, lines, cLines, hLines, sps, level) self._SplitTriangle(lc0, lc1, lc2, lines, cLines, hLines, sps, level) else: v = geo2.Vector vecC = v(*tc.GetAsXYZTuple()) vec0 = v(*v0.GetAsXYZTuple()) vec1 = v(*v0.GetAsXYZTuple()) vec2 = v(*v0.GetAsXYZTuple()) vec01 = v(*(v1.x - v0.x, v1.y - v0.y, v1.z - v0.z)) n0 = v(*geo2.Vec3Cross(vecC, vec01)) vec12 = v(*(v2.x - v1.x, v2.y - v1.y, v2.z - v1.z)) n1 = v(*geo2.Vec3Cross(vecC, vec12)) vec20 = v(*(v0.x - v2.x, v0.y - v2.y, v0.z - v2.z)) n2 = v(*geo2.Vec3Cross(vecC, vec20)) s = 0.16 sGap = 0.1 n0 = v(*(s * n0)) n1 = v(*(s * n1)) n2 = v(*(s * n2)) lp0 = SurfacePoint(*(vecC - n0)) lp1 = SurfacePoint(*(vecC - n1)) lp2 = SurfacePoint(*(vecC - n2)) lr0 = SurfacePoint(*(vecC - v(*(sGap * n0)))) lr1 = SurfacePoint(*(vecC - v(*(sGap * n1)))) lr2 = SurfacePoint(*(vecC - v(*(sGap * n2)))) lp0.SetRadius(1.0) lp1.SetRadius(1.0) lp2.SetRadius(1.0) lr0.SetRadius(1.0) lr1.SetRadius(1.0) lr2.SetRadius(1.0) lines.add((lr0, lp0)) lines.add((lr1, lp1)) lines.add((lr2, lp2))
def SetAxis(self, xaxis, zaxis): self.xaxis = xaxis self.zaxis = zaxis yaxis = geo2.Vec3Normalize(geo2.Vec3Cross(zaxis, xaxis)) self.rotation = geo2.QuaternionRotationMatrix((xaxis + (0,), yaxis + (0,), zaxis + (0,), (0, 0, 0, 1)))
def UpdateInSceneContainer(self): if not self.inSceneContainer: return self.UpdateInSceneContainerPosition() lookAtDir = self.GetLookAtDirection() pitch = math.acos(geo2.Vec3Dot(lookAtDir, (0, -1, 0))) rightDir = geo2.Vec3Cross(self.GetUpDirection(), lookAtDir) roll = math.acos(geo2.Vec3Dot(rightDir, (0, 1, 0))) self.inSceneContainer.Update(pitch, roll)
def _UpdateRotateOffset(self): if self._rotateOffset != (0.0, 0.0): yaw, pitch = self._rotateOffset rotMat = geo2.MatrixRotationAxis(self.upDirection, -yaw) eyeAtVec = geo2.Vec3Subtract(self._atPosition, self._eyePosition) vec = geo2.Vec3Transform(eyeAtVec, rotMat) axis = geo2.Vec3Normalize(geo2.Vec3Cross(vec, self.upDirection)) rotMat = geo2.MatrixRotationAxis(axis, -pitch) vec = geo2.Vec3Transform(vec, rotMat) offset = geo2.Vec3Subtract(vec, eyeAtVec) self._AddToAtOffset(offset)
def _UpdatePitch(self, currPitch, vLookAt): targetPitch = self.orbitTarget[1] pitchRemaining = currPitch - targetPitch if pitchRemaining: if math.fabs(pitchRemaining) < self.kOrbitStopAngle: pitch = pitchRemaining pitchRemaining = None else: pitch = pitchRemaining * self._GetOrbitSpeed() axis = geo2.Vec3Cross(vLookAt, self.upDirection) rotPitch = geo2.MatrixRotationAxis(axis, pitch) self.SetEyePosition(geo2.Vec3Transform(self._eyePosition, rotPitch)) return pitchRemaining
def _EnforceMaximumDinstance(self, headSurfacePoint, uiPin): SAFETYFACTOR = 0.99 ecuSurfacePoint = uiPin.surfacePoint distance = headSurfacePoint.GetDistanceToOther(ecuSurfacePoint) areaOfInfluence = uiPin.pin.GetAreaOfInfluence() if distance < areaOfInfluence * SAFETYFACTOR: return distance / areaOfInfluence ecuVector = ecuSurfacePoint.GetAsXYZTuple() v = headSurfacePoint.GetAsXYZTuple() normal = geo2.Vec3Cross(ecuVector, v) rotMat = geo2.MatrixRotationAxis(normal, areaOfInfluence * SAFETYFACTOR) newV = geo2.Multiply(rotMat, ecuVector) headSurfacePoint.SetXYZ(*newV[:3]) return 1.0
def PlaceProbeAtDefaultPosition(self, headID): OFFSET = 0.08 VEC_X = (-1, 0, 0) rotAngle = float(headID) / planetCommon.ECU_MAX_HEADS * 2 * math.pi ecuVector = self.planetUISvc.myPinManager.pinsByID[ self.pin.id].surfacePoint.GetAsXYZTuple() normal = geo2.Vec3Cross(ecuVector, VEC_X) normal = geo2.Vector(*normal) * OFFSET posVec = geo2.Vec3Subtract(ecuVector, normal) posVec = geo2.Vec3Normalize(posVec) rotMat = geo2.MatrixRotationAxis(ecuVector, rotAngle) posVec = geo2.Multiply(rotMat, posVec) surfacePoint = SurfacePoint(*posVec) self.planetUISvc.myPinManager.PlaceExtractionHead( self.pin.id, headID, surfacePoint, self.currentRadius) self.UpdateHeadPosition(headID, surfacePoint)
def Update(self): speedFactor = 0.2 diff = geo2.Vec3Subtract(self.pointOfInterest, self._pointOfInterestCurrent) diffLength = geo2.Vec3Length(diff) if diffLength > 0.001: self._pointOfInterestCurrent = geo2.Vec3Add(self._pointOfInterestCurrent, geo2.Vec3Scale(diff, speedFactor)) else: self._pointOfInterestCurrent = self.pointOfInterest if abs(self._yawSpeed) > 0.0001: yawChange = self._yawSpeed * speedFactor rotYaw = geo2.MatrixRotationAxis(self.upVector, yawChange) self._eyePositionCurrent = geo2.Vec3Transform(self._eyePositionCurrent, rotYaw) self._yawSpeed -= yawChange else: self._yawSpeed = 0.0 if abs(self._pitchSpeed) > 0.0001: pitchChange = self._pitchSpeed * speedFactor viewVectorNormalized = geo2.Vec3Normalize(self._eyePositionCurrent) axis = geo2.Vec3Cross(viewVectorNormalized, self.upVector) rotPitch = geo2.MatrixRotationAxis(axis, pitchChange) self._eyePositionCurrent = geo2.Vec3Transform(self._eyePositionCurrent, rotPitch) self._pitchSpeed -= pitchChange else: self._pitchSpeed = 0.0 if self._panSpeed: panDistance = geo2.Vec3Length(self._panSpeed) if panDistance > 0.001: toMove = geo2.Vec3Scale(self._panSpeed, 0.95) self.pointOfInterest = geo2.Add(self.pointOfInterest, toMove) self._panSpeed -= toMove else: self._panSpeed = None cameraDistance = self.GetZoomDistance() cameraDistanceDiff = self._translationFromPOI - cameraDistance if math.fabs(cameraDistanceDiff) > 0.001: usedDist = cameraDistanceDiff * 0.1 viewVectorNormalized = geo2.Vec3Normalize(self._eyePositionCurrent) newDistance = min(self.maxDistance, max(self.minDistance, cameraDistance + usedDist)) self._eyePositionCurrent = geo2.Vec3Scale(viewVectorNormalized, newDistance) self.translationFromParent = newDistance self.UpdateProjection() self.UpdateView() if self.callback: self.callback()
def _EnforceMaximumDinstance(self, headSurfacePoint, uiPin): """ If the distance between the points is greater than the maximum, we snap headSurfacePoint to the max distance circle and return 1.0. Otherwise, we return the current distance factor [0.0-1.0] """ SAFETYFACTOR = 0.99 ecuSurfacePoint = uiPin.surfacePoint distance = headSurfacePoint.GetDistanceToOther(ecuSurfacePoint) areaOfInfluence = uiPin.pin.GetAreaOfInfluence() if distance < areaOfInfluence * SAFETYFACTOR: return distance / areaOfInfluence ecuVector = ecuSurfacePoint.GetAsXYZTuple() v = headSurfacePoint.GetAsXYZTuple() normal = geo2.Vec3Cross(ecuVector, v) rotMat = geo2.MatrixRotationAxis(normal, areaOfInfluence * SAFETYFACTOR) newV = geo2.Multiply(rotMat, ecuVector) headSurfacePoint.SetXYZ(*newV[:3]) return 1.0
def UpdatePosition(self, cameraController): if self.state == _PATH_STATE_PICK_XZ: plane_center = self.anchorFunction.GetValue() ray_dir, ray_start = cameraController.GetPickVector() if ray_dir[1] == 0: return multiplier = (ray_start[1] - plane_center[1]) / -ray_dir[1] pick_position = geo2.Vec3Add(ray_start, geo2.Vec3Scale(ray_dir, multiplier)) pick_dir = geo2.Vec3Subtract(pick_position, plane_center) maxDistance = self.maxDistance + self.baseDistance if multiplier < 0: pick_dir = geo2.Vec3Normalize(geo2.Vec3Scale(pick_dir, -1)) pick_position = geo2.Vec3Add(plane_center, geo2.Vec3Scale(pick_dir, maxDistance)) pick_length = geo2.Vec3Length(pick_dir) if pick_length > maxDistance or self.fixedDistance: pick_dir = geo2.Vec3Normalize(pick_dir) pick_position = geo2.Vec3Add(plane_center, geo2.Vec3Scale(pick_dir, maxDistance)) self.planarFunction.SetOffsetWorldspace(pick_position) self.destinationFunction.SetOffsetWorldspace(pick_position) self._UpdateDistanceText() elif self.state == _PATH_STATE_PICK_Y: xz_position = self.planarFunction.GetValue() plane_center = self.anchorFunction.GetValue() xz_direction = geo2.Vec3Subtract(xz_position, plane_center) length = geo2.Vec3Length(xz_direction) xz_direction = geo2.Vec3Normalize(xz_direction) plane_dir = geo2.Vec3Cross(xz_direction, (0, 1, 0)) ray_dir, start = cameraController.GetPickVector() pick_position, sign = RayToPlaneIntersection(start, ray_dir, plane_center, plane_dir, returnSign=True) pick_dir = geo2.Vec3Normalize(geo2.Vec3Subtract(pick_position, plane_center)) pick_dir = geo2.Vec3Scale(pick_dir, sign) pick_position = geo2.Vec3Add(plane_center, geo2.Vec3Scale(pick_dir, length)) self.destinationFunction.SetOffsetWorldspace(pick_position) base_offset = geo2.Vec3Subtract(self.destinationFunction.GetValue(), self.anchorFunction.GetValue()) base_offset = geo2.Vec3Scale(geo2.Vec3Normalize(base_offset), self.baseDistance) self.offsetAnchorFunction.SetOffsetRelative(base_offset) if self.areaIndication is not None: self.areaIndication.Update()
def Update(self): pointOfInterestOverrideValue = self.GetPointOfInterestOverrideValue() if pointOfInterestOverrideValue is not None: self._pointOfInterest = pointOfInterestOverrideValue elif self.followMarker: followMarker = self.followMarker() if followMarker: markerPosition = followMarker.GetDisplayPosition() if markerPosition is not None: self._pointOfInterest = markerPosition speedFactor = 0.4 diff = geo2.Vec3Subtract(self._pointOfInterest, self._pointOfInterestCurrent) diffLength = geo2.Vec3Length(diff) if diffLength > 0.001: addVector = geo2.Vec3ScaleD(diff, speedFactor) newPosition = geo2.Vec3Add(self._pointOfInterestCurrent, addVector) if geo2.Vec3Equal(newPosition, self._pointOfInterestCurrent): newPosition = self._pointOfInterest self._pointOfInterestCurrent = newPosition else: self._pointOfInterestCurrent = self._pointOfInterest if abs(self._yawSpeed) > 0.0001: yawChange = self._yawSpeed * speedFactor rotYaw = geo2.MatrixRotationAxis(self.upVector, yawChange) self._eyePositionCurrent = geo2.Vec3Transform( self._eyePositionCurrent, rotYaw) currentPositionN = geo2.Vec3Normalize(self._eyePositionCurrent) self._eyePosition = geo2.Vec3Scale( currentPositionN, geo2.Vec3Length(self._eyePosition)) self._yawSpeed -= yawChange else: self._yawSpeed = 0.0 if abs(self._pitchSpeed) > 0.0001: pitchChange = self._pitchSpeed * speedFactor viewVectorNormalized = geo2.Vec3Normalize(self._eyePositionCurrent) axis = geo2.Vec3Cross(viewVectorNormalized, self.upVector) rotPitch = geo2.MatrixRotationAxis(axis, pitchChange) self._eyePositionCurrent = geo2.Vec3Transform( self._eyePositionCurrent, rotPitch) currentPositionN = geo2.Vec3NormalizeD(self._eyePositionCurrent) self._eyePosition = geo2.Vec3ScaleD( currentPositionN, geo2.Vec3Length(self._eyePosition)) self._pitchSpeed -= pitchChange else: self._pitchSpeed = 0.0 setCameraDistance = geo2.Vec3Length(self._eyePosition) currentCameraDistance = geo2.Vec3Length(self._eyePositionCurrent) cameraDistanceDiff = setCameraDistance - currentCameraDistance if math.fabs(cameraDistanceDiff) > 0.001: usedDist = cameraDistanceDiff * speedFactor * 0.5 viewVectorNormalized = geo2.Vec3NormalizeD( self._eyePositionCurrent) newDistance = min( self.maxDistance, max(self.minDistance, currentCameraDistance + usedDist)) self._eyePositionCurrent = geo2.Vec3ScaleD(viewVectorNormalized, newDistance) self.UpdateProjection() self.UpdateView() if self.callback: self.callback()