def GetWarpCollisions(self, ball): space = sm.GetService('space') planets = space.planetManager.planets destination = self.destination source = (ball.x, ball.y, ball.z) self.direction = geo2.Vec3SubtractD(destination, source) direction = self.direction warpDistance = geo2.Vec3LengthD(direction) normDirection = geo2.Vec3NormalizeD(direction) self.normDirection = normDirection ballpark = sm.GetService('michelle').GetBallpark() collisions = [] for planet in planets: planetBall = ballpark.GetBall(planet.id) if planetBall is None: log.LogWarn('Warping got a None planet ball.') continue planetRadius = planetBall.radius planetPosition = (planetBall.x, planetBall.y, planetBall.z) planetDir = geo2.Vec3SubtractD(planetPosition, source) if geo2.Vec3LengthSqD( self.direction) < geo2.Vec3LengthSqD(planetDir): continue effectiveRadius = self.CalcEffectiveRadius(normDirection, planetDir, planetRadius) if effectiveRadius is None: continue collisions.append((planetBall, effectiveRadius)) blue.pyos.BeNice() return collisions
def UpdatePosition(self, localPosition=None): if not self.model: self._LoadModel() if not len(self.model.children): return if not localPosition: localSystem = sm.StartService('map').GetItem(session.solarsystemid) localPosition = (localSystem.x, localSystem.y, localSystem.z) if not self.effectPosition: effectSystem = sm.StartService('map').GetItem(SUPERNOVA_SYSTEM_ID) self.effectPosition = (effectSystem.x, effectSystem.y, effectSystem.z) effect = self.model.children[0] direction = geo2.Vec3SubtractD(localPosition, self.effectPosition) direction = (direction[0], direction[1], -direction[2]) distance = geo2.Vec3LengthD(direction) / 1e+16 direction = geo2.Vec3Normalize(direction) if distance < self.nearDistance: scale = self.nearSize else: shift = (self.farSize * self.farDistance - self.nearSize * self.nearDistance) / (self.nearSize - self.farSize) baseSize = self.nearSize * (self.nearDistance + shift) scale = baseSize / (distance + shift) effect.scaling = (scale, scale, scale) effect.translation = geo2.Vec3Scale(direction, 15.0)
def AlignToPosition(self, position): ballpark = self.michelle.GetBallpark() myBall = self.michelle.GetBall(ballpark.ego) myPosition = (myBall.x, myBall.y, myBall.z) directionalVector = geo2.Vec3SubtractD(position, myPosition) rbp = self.michelle.GetRemotePark() rbp.CmdGotoDirection(directionalVector[0], directionalVector[1], directionalVector[2])
def Update(self): if not self.ball: return ballPos = GetBallPosition(self.ball) if self.ballPosLast: self.positionDiff = geo2.Vec3SubtractD(ballPos, self.ballPosLast) self.ballPosLast = ballPos
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 PanUpdateThread(self): try: while True: if self.panTarget is None: break if self._IsPanTargetOutOfBounds(): return distLeft = geo2.Vec3LengthD(self.panTarget) if distLeft == 0: break if distLeft < self.kPanStopDist: dist = 1.0 else: dist = min(1.0, self._GetPanSpeed() / blue.os.fps) toMove = geo2.Vec3ScaleD(self.panTarget, dist) self.SetEyePosition(geo2.Vec3Add(self._eyePosition, toMove)) self.SetAtPosition(geo2.Vec3Add(self._atPosition, toMove)) self.panTarget = geo2.Vec3SubtractD(self.panTarget, toMove) if dist == 1.0: break blue.synchro.Yield() finally: self.panUpdateThread = None self.panTarget = None
def UpdatePosition(self, localPosition=None): """ Updates the position and scale of the supernova. localPosition: An optional 3 tuple for the local position. If not passed in the session.solarsystemid is used to determine the position. """ if not self.model: self._LoadModel() if not localPosition: localSystem = sm.StartService('map').GetItem(session.solarsystemid) localPosition = (localSystem.x, localSystem.y, localSystem.z) if not self.effectPosition: effectSystem = sm.StartService('map').GetItem(SUPERNOVA_SYSTEM_ID) self.effectPosition = (effectSystem.x, effectSystem.y, effectSystem.z) effect = self.model.children[0] direction = geo2.Vec3SubtractD(localPosition, self.effectPosition) direction = (direction[0], direction[1], -direction[2]) distance = geo2.Vec3LengthD(direction) / 1e+16 direction = geo2.Vec3Normalize(direction) if distance < self.nearDistance: scale = self.nearSize else: shift = (self.farSize * self.farDistance - self.nearSize * self.nearDistance) / (self.nearSize - self.farSize) baseSize = self.nearSize * (self.nearDistance + shift) scale = baseSize / (distance + shift) effect.scaling = (scale, scale, scale) effect.translation = geo2.Vec3Scale(direction, 15.0)
def Update(self): if not self.ball: return (0, 0, 0) atPosLast = self.atPosition if self.GetItemID() == self.camera.ego: self.atPosition = (0, 0, 0) else: self.atPosition = GetBallPosition(self.ball) self.atPositionDiff = geo2.Vec3SubtractD(self.atPosition, atPosLast)
def Update(self, center, range, closestPoints, width): self.AddLinesToScene() self.ClearLines() d0 = geo2.Vec3SubtractD(center, closestPoints[0]) d1 = geo2.Vec3SubtractD(center, closestPoints[1]) up = geo2.Vec3NormalizeD(geo2.Vec3CrossD(d1, d0)) dir = geo2.Vec3NormalizeD(d0) pFar = geo2.Vec3AddD(center, geo2.Vec3ScaleD(dir, range)) pNear = geo2.Vec3AddD(center, geo2.Vec3ScaleD(dir, -range)) perp = geo2.Vec3NormalizeD(geo2.Vec3CrossD(dir, up)) pRight = geo2.Vec3AddD(center, geo2.Vec3ScaleD(perp, range)) pLeft = geo2.Vec3AddD(center, geo2.Vec3ScaleD(perp, -range)) width *= LINE_WIDTH self.lineSet.AddSpheredLineCrt(pFar, DEFAULT_COLOR, pRight, DEFAULT_COLOR, center, width) self.lineSet.AddSpheredLineCrt(pRight, DEFAULT_COLOR, pNear, DEFAULT_COLOR, center, width) self.lineSet.AddSpheredLineCrt(pNear, DEFAULT_COLOR, pLeft, DEFAULT_COLOR, center, width) self.lineSet.AddSpheredLineCrt(pLeft, DEFAULT_COLOR, pFar, DEFAULT_COLOR, center, width) self.lineSet.SubmitChanges()
def GetRayAndPointFromScreen(self): x = float(uicore.uilib.x) y = float(uicore.uilib.y) data = self.GetCameraMatrixes() start = geo2.Vec3Unproject((x, y, 0.0), *data) end = geo2.Vec3Unproject((x, y, 100000.0), *data) ray = geo2.Vec3SubtractD(end, start) ray = geo2.Vector(*ray) start = geo2.Vector(*start) return (ray, start)
def MakeOrbitRing(self, drawPoints, alpha): if self.settings.mode == 'Orbit': if self.orbitDrawer is None: self.orbitDrawer = OrbitRangeDrawer() m = sm.GetService('michelle') bp = m.GetBallpark() myPos = bp.GetCurrentEgoPos()[:3] targetBall = bp.GetBall(self.settings.targetID) targetPos = geo2.Vec3SubtractD((targetBall.x, targetBall.y, targetBall.z), myPos) closestPoints = [drawPoints[-2][0], drawPoints[-1][0]] totalRange = self.settings.range + bp.GetBall(bp.ego).radius + targetBall.radius self.orbitDrawer.Update(targetPos, totalRange, closestPoints, self.animationPos * alpha)
def GetDrawDataFromPoints(self, points): drawPoints = [] ballPos = self.ballpark.GetCurrentEgoPos()[:3] for i, p in enumerate(points): percent = float(i) / len(points) width = self.GetWidthForPointFraction(percent) pos = p[:3] if ballPos is not None: pos = geo2.Vec3SubtractD(pos, ballPos) drawPoints.append((pos, width)) return drawPoints
def _FindClosestBallDir(self, constgrp): bp = self.sm.StartService('michelle').GetBallpark() dist = 1e+100 closestID = None for ballID, slimItem in bp.slimItems.iteritems(): if slimItem.groupID == constgrp: test = bp.DistanceBetween(self.id, ballID) if test < dist: dist = test closestID = ballID if closestID is None: return (1.0, 0.0, 0.0) ball = bp.GetBall(closestID) direction = geo2.Vec3SubtractD((self.x, self.y, self.z), (ball.x, ball.y, ball.z)) return direction
def GetDrawDataFromPoints(self, points): """ Converts a set of data points into the drawable points - ie, converts a list of: (x, y, z) to a list of: ((x, y, z), width) """ drawPoints = [] ballPos = self.ballpark.GetCurrentEgoPos()[:3] for i, p in enumerate(points): percent = float(i) / len(points) width = self.GetWidthForPointFraction(percent) pos = p[:3] if ballPos is not None: pos = geo2.Vec3SubtractD(pos, ballPos) drawPoints.append((pos, width)) return drawPoints
def AddGfxResult(self, siteData, myPos): if self.suppressGfxReasons: return if not self.sensorSuiteService.siteController.IsSiteVisible(siteData): return if siteData.signalStrength >= 1.0: return if siteData.targetID in self.gfxActiveSensorResults: return direction = geo2.Vec3SubtractD(siteData.position, myPos) distToSite = geo2.Vec3LengthD(direction) deviation = siteData.deviation * 0.5 a = min(distToSite, deviation) b = max(distToSite, deviation) tanA = a / b angle = math.atan(tanA) normalizedDir = geo2.Vec3NormalizeD(direction) self.AddGfxResultToScene(siteData.targetID, normalizedDir, angle)
def __UpdateCompass(self): bp = self.michelle.GetBallpark() if bp is None: return camera = self.GetCamera() camRotation = geo2.QuaternionRotationGetYawPitchRoll( camera.rotationAroundParent) yaw, pitch, roll = camRotation cx, cy, cz = geo2.QuaternionTransformVector( camera.rotationAroundParent, (0, 0, -1.0)) camLengthInPlane = geo2.Vec2Length((cx, cz)) camAngle = math.atan2(cy, camLengthInPlane) self.compassTransform.rotation = -yaw + math.pi myPos = bp.GetCurrentEgoPos() if self.lastPose: lastCamRot, lastPos = self.lastPose isNewCamRotation = not AreVectorsEqual(lastCamRot, camRotation, 0.05) isNewPosition = not AreVectorsEqual(lastPos, myPos, 0.5) isNewPose = isNewPosition or isNewCamRotation else: isNewPosition = True isNewPose = True for siteID, indicator in self.siteIndicatorsBySiteID.iteritems(): if indicator.isNew or isNewPose: toSiteVec = geo2.Vec3SubtractD(indicator.data.position, myPos) toSiteVec = geo2.Vec3NormalizeD(toSiteVec) if indicator.isNew or isNewPosition: angle = math.atan2(-toSiteVec[2], toSiteVec[0]) indicator.SetRotation(angle + MATH_PI_2) sx, sy, sz = toSiteVec siteLengthInPlane = geo2.Vec2Length((sx, sz)) siteAngle = math.atan2(sy, siteLengthInPlane) inclinationAngle = siteAngle - camAngle verticalAngle = min(inclinationAngle, MATH_PI_2) indicator.SetInclination(verticalAngle) indicator.isNew = False self.lastPose = (camRotation, myPos)
def _UpdateCursor(self): if self.currentCursor: self.cursors[self.currentCursor].Show() while self.currentCursor and self.cursors[ self.currentCursor].IsShown(): playerClientBall = self.GetPlayerClientBall() selectionCenter = geo2.VectorD(self.GetSelectionCenter()) playerPosition = geo2.VectorD(playerClientBall.x, playerClientBall.y, playerClientBall.z) toolPosition = geo2.Vec3SubtractD(selectionCenter, playerPosition) self.cursors[self.currentCursor].Rotate( self.GetSelectionRotation()) self.cursors[self.currentCursor].Translate(toolPosition) self.cursors[self.currentCursor].UpdatePrimitives() keyDown = uicore.uilib.Key if keyDown(uiconst.VK_MENU): if keyDown(uiconst.VK_W): self.SetCursor('Translation') if keyDown(uiconst.VK_E): self.SetCursor('Rotation') if keyDown(uiconst.VK_R): self.SetCursor('Scaling') blue.synchro.Yield()