Engine::Engine(PlayerInfo &player)
	: player(player)
{
	// Start the thread for doing calculations.
	calcThread = thread(&Engine::ThreadEntryPoint, this);
	
	if(!player.IsLoaded() || !player.GetSystem())
		return;
	
	// Preload any landscapes for this system.
	for(const StellarObject &object : player.GetSystem()->Objects())
		if(object.GetPlanet())
			GameData::Preload(object.GetPlanet()->Landscape());
	
	// Figure out what planet the player is landed on, if any.
	const StellarObject *object = player.GetStellarObject();
	if(object)
		center = object->Position();
	
	// Now we know the player's current position. Draw the planets.
	draw[calcTickTock].SetCenter(center);
	radar[calcTickTock].SetCenter(center);
	for(const StellarObject &object : player.GetSystem()->Objects())
		if(object.HasSprite())
		{
			draw[calcTickTock].Add(object);
			
			double r = max(2., object.Radius() * .03 + .5);
			radar[calcTickTock].Add(RadarType(object), object.Position(), r, r - 1.);
		}
	
	// Add all neighboring systems to the radar.
	const Ship *flagship = player.Flagship();
	const System *targetSystem = flagship ? flagship->GetTargetSystem() : nullptr;
	const vector<const System *> &links = (flagship && flagship->Attributes().Get("jump drive")) ?
		player.GetSystem()->Neighbors() : player.GetSystem()->Links();
	for(const System *system : links)
		radar[calcTickTock].AddPointer(
			(system == targetSystem) ? Radar::SPECIAL : Radar::INACTIVE,
			system->Position() - player.GetSystem()->Position());
}