// ViewWindowInfo.cpp: implementation of the ViewWindowInfo class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MW4GameEd2.h" #include "ViewWindowInfo.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// ViewWindowInfo::ViewWindowInfo() { ClientArea=CSize(100,100); BitmapArea=CSize(256,256); ZoomFact.x=1.0f; ZoomFact.y=0.0f; ZoomFact.z=1.0f; Pan.x=50.0f; Pan.y=0.0f; Pan.z=50.0f; MapOrg.x=-50.0f; MapOrg.y=0.0f; MapOrg.z=-50.0f; MapSize.x=100.0f; MapSize.y=0.0f; MapSize.z=100.0f; CalcConstants(); } ViewWindowInfo::~ViewWindowInfo() { } void ViewWindowInfo::CalcConstants() { MapOrg.x=-MapSize.x*0.5f; MapOrg.z=-MapSize.z*0.5f; MapRatio=MapSize.z/MapSize.x; ViewSizeX=MapSize.x/ZoomFact.x; ViewSizeY=MapSize.z/ZoomFact.z; ClientRatio=((float)ClientArea.cx/(float)ClientArea.cy); if(ClientRatio>1) ViewSizeY/=ClientRatio; else ViewSizeX*=ClientRatio; HalfViewSizeX=ViewSizeX*0.5f; HalfViewSizeY=ViewSizeY*0.5f; SourcePixs_Per_MeterX=BitmapArea.cx/MapSize.x; SourcePixs_Per_MeterY=BitmapArea.cy/MapSize.z; DestPixs_Per_MeterX=ClientArea.cx/ViewSizeX; DestPixs_Per_MeterY=ClientArea.cy/ViewSizeY; MeterX_Per_DestPixs=1/DestPixs_Per_MeterX; MeterY_Per_DestPixs=1/DestPixs_Per_MeterY; DestPixs_Per_SourcePixsX=DestPixs_Per_MeterX/SourcePixs_Per_MeterX; DestPixs_Per_SourcePixsY=DestPixs_Per_MeterY/SourcePixs_Per_MeterY; } void ViewWindowInfo::SetClientArea(CSize &rct) { ClientArea=rct; if(ClientArea.cx==0) ClientArea.cx=1; if(ClientArea.cy==0) ClientArea.cy=1; CorrectViewBounds(); } void ViewWindowInfo::SetBitmapArea(CSize &rct) { BitmapArea=rct; CorrectViewBounds(); } void ViewWindowInfo::SetZoom(float zf) { ZoomFact.z=ZoomFact.x=zf; CorrectViewBounds(); } void ViewWindowInfo::SetPan(Point3D &pnt) { Pan=pnt; CorrectViewBounds(); } void ViewWindowInfo::OffsetPan(Point3D &pnt) { Pan+=pnt; CorrectViewBounds(); } void ViewWindowInfo::MultiplyZoom(float zf) { ZoomFact.x*=zf; ZoomFact.z*=zf; CorrectViewBounds(); } void ViewWindowInfo::SetViewLimits(Point3D min, Point3D max) { if(min.x>max.x) { Scalar tmp; tmp=min.x; min.x=max.x; max.x=tmp; } if(min.z>max.z) { Scalar tmp; tmp=min.z; min.z=max.z; max.z=tmp; } Verify((min.xy=max->y=0.0f; min->x=Pan.x-HalfViewSizeX; max->x=Pan.x+HalfViewSizeX; min->z=Pan.z-HalfViewSizeY; max->z=Pan.z+HalfViewSizeY; } bool ViewWindowInfo::GetBltRects(CRect *drct,CRect *srct) { float src_top,src_right,src_left,src_bottom; drct->left=0; drct->top=0; drct->right=ClientArea.cx; drct->bottom=ClientArea.cy; Point3D flip_pan; flip_pan.y=0.0f; flip_pan.x=MapSize.x-(Pan.x-MapOrg.x); flip_pan.z=MapSize.z-(Pan.z-MapOrg.z); //Calulate percise Source window src_left=(flip_pan.x-HalfViewSizeX)*SourcePixs_Per_MeterX; src_right=(flip_pan.x+HalfViewSizeX)*SourcePixs_Per_MeterX; src_top=(flip_pan.z-HalfViewSizeY)*SourcePixs_Per_MeterY; src_bottom=(flip_pan.z+HalfViewSizeY)*SourcePixs_Per_MeterY; //Truncate Source Window with overlap srct->left=(int)floor(src_left); srct->right=(int)ceil(src_right); srct->top=(int)floor(src_top); srct->bottom=(int)ceil(src_bottom); //Adjust Dest Window for overlap if(srct->Width()>1) { drct->left-=(int)((src_left-floor(src_left))*DestPixs_Per_SourcePixsX); drct->right+=(int)((ceil(src_right)-src_right)*DestPixs_Per_SourcePixsX); } if(srct->Height()>1) { drct->top-=(int)((src_top-floor(src_top))*DestPixs_Per_SourcePixsY); drct->bottom+=(int)((ceil(src_bottom)-src_bottom)*DestPixs_Per_SourcePixsY); } return (abs(srct->right-srct->left)<=1 || abs(srct->bottom-srct->top)<=1 ); } void ViewWindowInfo::SetPan(CPoint &pnt) { SetPan(ScreenToData(pnt)); } void ViewWindowInfo::OffsetPan(CSize &pnt) { //Reverser for no 180 flip //Pan.x+=(float)((pnt.cx)*MapSize.x)/(ClientArea.cx*ZoomFact.x); //Pan.z+=(float)((pnt.cy)*MapSize.z)/(ClientArea.cy*ZoomFact.z); Pan.x-=(float)((pnt.cx)*MapSize.x)/(ClientArea.cx*ZoomFact.x); Pan.z-=(float)((pnt.cy)*MapSize.z)/(ClientArea.cy*ZoomFact.z); CorrectViewBounds(); } void ViewWindowInfo::CorrectViewBounds() { if(ZoomFact.x<1.0f) ZoomFact.x=1.0f; if(ZoomFact.z<1.0f) ZoomFact.z=1.0f; CalcConstants(); float src_top,src_right,src_left,src_bottom; bool change; //Calulate percise Source window src_left=((Pan.x-MapOrg.x)-HalfViewSizeX)*SourcePixs_Per_MeterX; src_right=((Pan.x-MapOrg.x)+HalfViewSizeX)*SourcePixs_Per_MeterX; src_top=((Pan.z-MapOrg.z)-HalfViewSizeY)*SourcePixs_Per_MeterY; src_bottom=((Pan.z-MapOrg.z)+HalfViewSizeY)*SourcePixs_Per_MeterY; if(src_left<0) { Pan.x=HalfViewSizeX+MapOrg.x; change=true; } if(src_top<0) { Pan.z=HalfViewSizeY+MapOrg.z; change=true; } if(src_right>BitmapArea.cx) { Pan.x=((BitmapArea.cx)/SourcePixs_Per_MeterX)-HalfViewSizeX+MapOrg.x; change=true; } if(src_bottom>BitmapArea.cy) { Pan.z=((BitmapArea.cy)/SourcePixs_Per_MeterY)-HalfViewSizeY+MapOrg.z; change=true; } if(change) CalcConstants(); }