public Vector3 ScreenToWorldPoint(Vector2 screenPos) { double screenX = screenPos.x; double screenY = screenPos.y; double screenZ = MapFunction.GetCameraHeight(mMapZoomLevel); Matrix4x4 pMatrix = mMapCamera.projectionMatrix; //反齐次除法,求出裁剪空间坐标 double px = screenX / Screen.width; px = (px - 0.5f) * 2f; double py = screenY / Screen.height; py = (py - 0.5f) * 2f; double pz = (-screenZ - pMatrix.m23) / pMatrix.m22; double pw = screenZ; px *= pw; py *= pw; //裁剪空间到相机空间 Matrix4x4 pInverseMatrix = mMapCamera.projectionMatrix.inverse; double vx = (pInverseMatrix.m00 * px + pInverseMatrix.m01 * py + pInverseMatrix.m02 * pz + pInverseMatrix.m03 * pw); double vy = (pInverseMatrix.m10 * px + pInverseMatrix.m11 * py + pInverseMatrix.m12 * pz + pInverseMatrix.m13 * pw); double vz = (pInverseMatrix.m20 * px + pInverseMatrix.m21 * py + pInverseMatrix.m22 * pz + pInverseMatrix.m23 * pw); //观察空间到世界空间 Matrix4x4 vInverseMatrix = mMapCamera.worldToCameraMatrix.inverse; double x = (vInverseMatrix.m00 * vx + vInverseMatrix.m01 * vy + vInverseMatrix.m02 * vz + vInverseMatrix.m03 * 1); double y = (vInverseMatrix.m10 * vx + vInverseMatrix.m11 * vy + vInverseMatrix.m12 * vz + vInverseMatrix.m13 * 1); double z = (vInverseMatrix.m20 * vx + vInverseMatrix.m21 * vy + vInverseMatrix.m22 * vz + vInverseMatrix.m23 * 1); return(new Vector3((float)(x), (float)(y), (float)(z))); }
/// <summary> /// 渲染地图 /// </summary> public void DoRender() { //相机坐标 Vector3 centerPos = LngLat2WorldPos(mCenterLngLat); //相机高度 Vector3 heightVec = new Vector3(0, (float)MapFunction.GetCameraHeight(mMapZoomLevel), 0); Vector3 cameraPos = centerPos + heightVec; mMapCamera.transform.position = cameraPos; //计算相机范围 Vector3 leftDownWorldPos = ScreenToWorldPoint(new Vector3(-0.1f * Screen.width, -0.1f * Screen.height, heightVec.y)); Vector3 rightUpWorldPos = ScreenToWorldPoint(new Vector3(1.1f * Screen.width, 1.1f * Screen.height, heightVec.y)); TileData leftDownTile = WorldPos2TileData(leftDownWorldPos); TileData rightUpTile = WorldPos2TileData(rightUpWorldPos); List <TileData> allTileDatas = new List <TileData>(); for (int i = leftDownTile.tile.x; i <= rightUpTile.tile.x; i++) { for (int k = leftDownTile.tile.y; k <= rightUpTile.tile.y; k++) { allTileDatas.Add(new TileData((int)mMapZoomLevel, i, k)); } } //中心Tile TileData centerTileData = WorldPos2TileData(centerPos); //按照距离排序,距离近的优先加载 allTileDatas.Sort((tileData1, tileData2) => { double distance1 = centerTileData.Distance(tileData1); double distance2 = centerTileData.Distance(tileData2); if (distance1.DoubleIsEqual(distance2)) { return(0); } return(distance1 < distance2 ? -1 : 1); }); for (int i = 0; i < allTileDatas.Count; i++) { MapTile mapTile = GetMapTile(allTileDatas[i]); mapTile.transform.position = TileData2WorldPos(allTileDatas[i]); } //清理距离远的Tile if (0 < allTileDatas.Count) { TileData maxDisTile = allTileDatas[allTileDatas.Count - 1]; double maxDistance = maxDisTile.Distance(centerTileData); ClearMapTile(centerTileData, maxDistance); } }