// // Since many functions call LatLon2screen, and only a few need multimap checks for display angle, // we separate functions to avoid slow downs. First used by CalculateScreenPositionsGroundline // void MapWindow::LatLon2ScreenMultimap(pointObj *ptin, POINT *ptout, const int n, const int skip) { static double lastangle = -1; static int cost=1024, sint=0; LKASSERT(Current_Multimap_TopZoom!=0); const double mDisplayAngle = Current_Multimap_TopAngle; if(mDisplayAngle != lastangle) { lastangle = mDisplayAngle; int deg = DEG_TO_INT(AngleLimit360(mDisplayAngle)); cost = ICOSTABLE[deg]; sint = ISINETABLE[deg]; } const int xxs = Current_Multimap_TopOrig.x*1024-512; const int yys = Current_Multimap_TopOrig.y*1024+512; const double mDrawScale = Current_Multimap_TopZoom; const double mPanLongitude = PanLongitude; const double mPanLatitude = PanLatitude; pointObj* p = ptin; const pointObj* ptend = ptin+n; while (p<ptend) { int Y = Real2Int((mPanLatitude-p->y)/mDrawScale); int X = Real2Int((mPanLongitude-p->x)*fastcosine(p->y)/mDrawScale); ptout->x = (xxs-X*cost + Y*sint)/1024; ptout->y = (Y*cost + X*sint + yys)/1024; ptout++; p+= skip; } }
void MapWindow::LatLon2Screen(const double &lon, const double &lat, POINT &sc) { int Y = Real2Int((PanLatitude-lat)*zoom.DrawScale()); int X = Real2Int((PanLongitude-lon)*fastcosine(lat)*zoom.DrawScale()); irotate(X, Y, DisplayAngle); sc.x = Orig_Screen.x - X; sc.y = Orig_Screen.y + Y; }
// JMW rounding further reduces data as required to speed up terrain // display on low zoom levels short RasterMap::GetField(const double &Latitude, const double &Longitude) { if(isMapLoaded()) { if (DirectFine) { return _GetFieldAtXY((int)(Longitude*fXroundingFine)-xlleft, xlltop- (int)(Latitude*fYroundingFine)); } else { #if (WINDOWSPC>0) unsigned int ix = Real2Int((Longitude-TerrainInfo.Left)*fXrounding)*Xrounding; unsigned int iy = Real2Int((TerrainInfo.Top-Latitude)*fYrounding)*Yrounding; #else unsigned int ix = ((int)((Longitude-TerrainInfo.Left)*fXrounding)) *Xrounding; unsigned int iy = ((int)((TerrainInfo.Top-Latitude)*fYrounding))*Yrounding; #endif return _GetFieldAtXY(ix<<8, iy<<8); } } else { return TERRAIN_INVALID; } }
///////////////////////////////////////////////////////////////////////////// // Rasterizaiton of an primtive in AABB // v=primtive vertices buffer address, nV=vertices count // nCidLimit=the max length of cell id buffer // pCid=cell id buffer address // nCid=number of rasterized cell id inline void COMap::RasterAABB(vertex* v, long nV, DWORD* pCid, long& nCid, const long nCidLimit) { long i,j,k; DWORD dwCell; vertex vmin, vmax; //AABB long xmin, ymin, zmin, xmax, ymax, zmax; // Rasterized AABB ScaleVector(v, TOMM, v); vmin.x=vmax.x=(*v).x; vmin.y=vmax.y=(*v).y; vmin.z=vmax.z=(*v).z; for(i=1;i<nV;i++) { vmin.x=__min(vmin.x, (*(v+i)).x); vmax.x=__max(vmax.x, (*(v+i)).x); vmin.y=__min(vmin.y, (*(v+i)).y); vmax.y=__max(vmax.y, (*(v+i)).y); vmin.z=__min(vmin.z, (*(v+i)).z); vmax.z=__max(vmax.z, (*(v+i)).z); } xmin=Real2Int(vmin.x)/m_dwR; xmax=Real2Int(vmax.x)/m_dwR; ymin=Real2Int(vmin.y)/m_dwR; ymax=Real2Int(vmax.y)/m_dwR; zmin=Real2Int(vmin.z)/m_dwR; zmax=Real2Int(vmax.z)/m_dwR; nCid=0; for(k=zmin;k<=zmax;k++) for(j=ymin;j<=ymax;j++) for(i=xmin;i<=xmax;i++) { if(nCid>=nCidLimit) { //TRACE("Cell id RASTER_SIZE overflows.\n"); } else{ dwCell=i+50+(j+50)*100+(k+50)*10000; // x, y, z [-500,500], Related to dwR. *(pCid+nCid++)=dwCell; } } }
inline DWORD COMap::Coor2dw(vertex& v) { //return (DWORD)(v.x/m_dwR+500)+(DWORD)(v.y/m_dwR+500)*1000+(DWORD)(v.z/m_dwR+500)*1000000; // [-500,500] return (Real2Int(v.x)/m_dwR+500+(Real2Int(v.y)/m_dwR+500)*1000+(Real2Int(v.z)/m_dwR+500)*1000000); // [-500,500] }