public override void Draw(RenderContext renderContext, GameTime gameTime) { if (renderContext.layerPass != RenderContext.LayerPass.MAIN_PASS) { return; } if (Game1.RECORDING) { MoveShip(renderContext.graphicsDevice); } SphereVector unitPosition = new SphereVector(position.Normalized()); SphereVector up = unitPosition.WalkNorth(Math.PI / 2); SphereVector right = new SphereVector(up.Cross(unitPosition).Normalized()); double rotation = Math.Atan2(forward.Dot(-right), forward.Dot(up)); // we want up to be 0 and a positive rotation to be cw Matrixd shipWVP = CreateShipWVP(renderContext, rotation); foreach (ModelMesh mesh in GlobalContent.StartingShuttle.Meshes) { foreach (BasicEffect eff in mesh.Effects) { eff.EnableDefaultLighting(); eff.World = shipWVP.toMatrix(); eff.VertexColorEnabled = false; eff.Alpha = 1; } mesh.Draw(); } }
private void UpdateCameraRotation(Vector3d v1, Vector3d v2) { Vector3d center3 = To3D(new Vector3d(camera.cameraRotX, camera.cameraRotY, 0)); center3 = ApplyRotation(center3, v1, v2); LongLat longLat = new SphereVector(center3).ToLongLat(); camera.cameraRotX = longLat.X; camera.cameraRotY = longLat.Y; }
private void MoveShip1(GraphicsDevice graphicsDevice) { double rotationAccel = 0; double accel = AccelWithKeys(); Keyboard.GetState().AffectNumber(ref rotationAccel, Keys.Left, Keys.Right, Keys.A, Keys.D, 0.01); rotationSpeed = Math.Max(Math.Min(rotationSpeed + rotationAccel, 0.1), -0.1); rotationSpeed *= 0.9; // apply rotation SphereVector right = new SphereVector(forward.Cross(position).Normalized()); forward = forward.WalkTowards(right, rotationSpeed); // move forwards velocity += forward * accel * Math.Pow(0.5, zoom) * 20; position = new SphereVector((position + velocity).Normalized()); // flatten our forward/velocity against current position forward = new SphereVector(forward.Cross(position).Cross(-position).Normalized()); if (velocity.Length() > 0.0000000001) { double currentSpeed = velocity.Length(); //if (rotationSpeed != 0) currentSpeed *= velocity.Normalized().Dot(forward); double max = Math.Pow(0.5, zoom) * 0.2; double min = Math.Pow(0.5, zoom) * 0; currentSpeed = Math.Max(Math.Min(currentSpeed, max), min); velocity = (velocity.Cross(position).Cross(-position).Normalized() * 0.8 + forward * 0.2).Normalized() * currentSpeed; } else { velocity = velocity.Cross(position).Cross(-position); } // now update altitude ControlZoomWithKeys(); SphereVector unitPosition2 = new SphereVector(position.Normalized()); camera.cameraRotX = unitPosition2.ToLongLat().X; camera.cameraRotY = unitPosition2.ToLongLat().Y; camera.UpdateCamera(graphicsDevice); }
public double RotateWithMouse(GraphicsDevice graphicsDevice) { SphereVector unitPosition = new SphereVector(position.Normalized()); SphereVector up2 = unitPosition.WalkNorth(Math.PI / 2); SphereVector right2 = new SphereVector(up2.Cross(unitPosition).Normalized()); double screenSpaceRotation = Math.Atan2(-forward.Dot(up2), forward.Dot(right2)); // we want up to be 0 and a positive rotation to be cw Point mousePos = Mouse.GetState().Position; Vector2d mouseV = new Vector2d((mousePos.X / (double)graphicsDevice.Viewport.Width - 0.5) * graphicsDevice.Viewport.AspectRatio, mousePos.Y / (double)graphicsDevice.Viewport.Height - 0.5); double mouseRotation = Math.Atan2(mouseV.Y, mouseV.X); double diff1 = (mouseRotation + 4 * Math.PI - screenSpaceRotation) % (2 * Math.PI); double diff2 = (screenSpaceRotation + 4 * Math.PI - mouseRotation) % (2 * Math.PI); double rotationSpeed; if (diff1 < diff2) { return(diff1 / 10); } else { return(-diff2 / 10); } }
// have the mouse control everything private void MoveShip2(GraphicsDevice graphicsDevice) { double accel = AccelerateWithMouse(graphicsDevice); //double accel = AccelWithKeys(); rotationSpeed = RotateWithMouse(graphicsDevice); SphereVector right = new SphereVector(forward.Cross(position).Normalized()); forward = forward.WalkTowards(right, rotationSpeed); // move forwards velocity += forward * accel * Math.Pow(0.5, zoom) * 20; position = new SphereVector((position + velocity).Normalized()); // flatten our forward/velocity against current position forward = new SphereVector(forward.Cross(position).Cross(-position).Normalized()); if (velocity.Length() > 0.0000000001) { double currentSpeed = velocity.Length(); //if (rotationSpeed != 0) currentSpeed *= velocity.Normalized().Dot(forward); double max = Math.Pow(0.5, zoom) * 0.2; double min = Math.Pow(0.5, zoom) * 0; currentSpeed = Math.Max(Math.Min(currentSpeed, max), min); velocity = (velocity.Cross(position).Cross(-position).Normalized() * 0.8 + forward * 0.2).Normalized() * currentSpeed; } else { velocity = velocity.Cross(position).Cross(-position); } // now update altitude SphereVector unitPosition2 = new SphereVector(position.Normalized()); camera.cameraRotX = unitPosition2.ToLongLat().X; camera.cameraRotY = unitPosition2.ToLongLat().Y; BaseZoomOnSpeed(); //ControlZoomWithKeys(); camera.UpdateCamera(graphicsDevice); }
private void LoadDetailsFromSource(ISector sector) { BlobCollection blobs = OSMReader.GetAllBlobs(sector); foreach (var way in blobs.EnumerateWays(false)) { for (int i = 0; i < way.refs.Count; i++) { long ref1 = way.refs[i]; long ref2 = way.refs[(i + 1) % way.refs.Count]; if (ref1 == ref2) { continue; } Vector2d v1 = blobs.nodes[ref1]; Vector2d v2 = blobs.nodes[ref2]; LongLat longLat1 = new SphereVector(sector.ProjectToSphereCoordinates(v1)).ToLongLat(); LongLat longLat2 = new SphereVector(sector.ProjectToSphereCoordinates(v2)).ToLongLat(); // hmm, this logic will ignore edges that brush up exactly against the top or left of their sector (ex: nodes 6151473219, 6151473220 in way 146849673) // I have to compensate for this elswhere ISector sector1 = GetContainingSector(longLat1, 8); ISector sector2 = GetContainingSector(longLat2, 8); if (!sector1.Equals(sector2)) { var e = new EdgeInfo() { wayID = way.id, node1 = ref1, node2 = ref2, longLat1 = longLat1, longLat2 = longLat2 }; if (!edgeInfo.Contains(e)) { edgeInfo.Add(e); } List <int> wKeys = new List <int>(); List <int> wVals = new List <int>(); foreach (var pair in way.keyValues) { wKeys.Add(LoadIntoStringTable(pair.Key)); wVals.Add(LoadIntoStringTable(pair.Value)); } var w = new WayInfo() { id = way.id, keys = wKeys, values = wVals, startNode = way.refs.First(), endNode = way.refs.Last(), relations = new List <long>() }; if (!wayInfo.ContainsKey(w.id)) { wayInfo[w.id] = w; } } } } HashSet <long> extraWays = new HashSet <long>(); foreach (var relation in blobs.EnumerateRelations()) { foreach (var way in relation.memids) { extraWays.Add(way); if (wayInfo.ContainsKey(way) && !relationInfo.ContainsKey(relation.id)) { List <int> rKeys = new List <int>(); List <int> rVals = new List <int>(); List <int> rRoles = new List <int>(); foreach (var pair in relation.keyValues) { rKeys.Add(LoadIntoStringTable(pair.Key)); rVals.Add(LoadIntoStringTable(pair.Value)); } foreach (var role in relation.roleValues) { rRoles.Add(LoadIntoStringTable(role)); } var r = new RelationInfo() { id = relation.id, keys = rKeys, values = rVals, roleValues = rRoles, memids = relation.memids, types = relation.types }; relationInfo[r.id] = r; } } } foreach (var way in blobs.EnumerateWays(false)) { if (!extraWays.Contains(way.id)) { continue; } List <int> wKeys = new List <int>(); List <int> wVals = new List <int>(); foreach (var pair in way.keyValues) { wKeys.Add(LoadIntoStringTable(pair.Key)); wVals.Add(LoadIntoStringTable(pair.Value)); } var w = new WayInfo() { id = way.id, keys = wKeys, values = wVals, startNode = way.refs.First(), endNode = way.refs.Last() }; if (!wayInfo.ContainsKey(w.id)) { wayInfo[w.id] = w; } } }
private static int[,] ConvertHGTZIPsToShorts(ISector sector) { int BUFFER_SIZE = 10; var fileBytes = new List <KeyValuePair <string, byte[]> >(); int[,] shorts = new int[REZ, REZ]; var exists = new HashSet <string>(); var doesntexist = new HashSet <string>(); for (int x = 0; x < REZ; x++) { for (int y = 0; y < REZ; y++) { // for now, nearest-neighbor var longLat = new SphereVector(sector.ProjectToSphereCoordinates(new Vector2d((0.5 + x) / REZ, (0.5 + y) / REZ))).ToLongLat() * 180 / Math.PI; string filePath; double px, py; // ex: N00E017.SRTMGL1.hgt.zip (note, file name is the coordinate of bottom-left most point) // for some reason for dem, the file name is the coordinate of the top-left most point? if (longLat.Y < -60 || longLat.Y > 60) { int roundX = ((int)((longLat.X + 420) / 40)) * 40 - 420; int roundY = ((int)Math.Ceiling((longLat.Y + 510) / 50)) * 50 - 510; filePath = Path.Combine(@"C:\Users\Geoffrey Hart\Downloads\Source\STRMGL30", $"{(roundX > 0 ? "E" : "W")}{Math.Abs(roundX):D3}{(roundY > 0 ? "N" : "S")}{Math.Abs(roundY):D2}.SRTMGL30.dem.zip"); if (!exists.Contains(filePath) && !doesntexist.Contains(filePath)) { if (File.Exists(filePath)) { exists.Add(filePath); } else { doesntexist.Add(filePath); } } if (exists.Contains(filePath)) { px = (longLat.X - roundX) / 40; py = (1 - (roundY - longLat.Y) / 50); } else { continue; } } else { filePath = Path.Combine(@"C:\Users\Geoffrey Hart\Downloads\Source\STRMGL1", $"{(longLat.Y > 0 ? "N" : "S")}{(int)Math.Abs(Math.Floor(longLat.Y)):D2}{(longLat.X > 0 ? "E" : "W")}{(int)Math.Abs(Math.Floor(longLat.X)):D3}.SRTMGL1.hgt.zip"); if (!exists.Contains(filePath) && !doesntexist.Contains(filePath)) { if (File.Exists(filePath)) { exists.Add(filePath); } else { doesntexist.Add(filePath); } } if (exists.Contains(filePath)) { px = (longLat.X + 360) % 1; py = (longLat.Y + 360) % 1; } else { int roundX = ((int)((longLat.X + 420) / 40)) * 40 - 420; int roundY = ((int)Math.Ceiling((longLat.Y + 510) / 50)) * 50 - 510; filePath = Path.Combine(@"C:\Users\Geoffrey Hart\Downloads\Source\STRMGL30", $"{(roundX > 0 ? "E" : "W")}{Math.Abs(roundX):D3}{(roundY > 0 ? "N" : "S")}{Math.Abs(roundY):D2}.SRTMGL30.dem.zip"); px = (longLat.X - roundX) / 40; py = (1 - (roundY - longLat.Y) / 50); } } if (!fileBytes.Any(z => z.Key == filePath)) { if (fileBytes.Count == BUFFER_SIZE) { fileBytes.RemoveAt(0); } fileBytes.Add(new KeyValuePair <string, byte[]>(filePath, Compression.UnZipToBytes(filePath))); } var bytes = fileBytes.Where(z => z.Key == filePath).Single().Value; int W, H; if (filePath.Contains("hgt")) { int size = (int)Math.Sqrt(bytes.Length / 2); W = size; H = size; } else { W = 600 * 8; H = 750 * 8; } if (W * H * 2 != bytes.Length) { throw new NotImplementedException(); } shorts[x, y] = (int)Sample(bytes, px * (W - 1), (1 - py) * (H - 1), W, H); } } return(shorts); }