// RenderViewport.cpp : implementation filefov // #include "stdafx.h" #include "RenderViewport.h" #include "DisplaySettings.h" #include "EditTool.h" #include "CryEditDoc.h" #include "GameEngine.h" #include "Objects\ObjectManager.h" #include "Objects\BaseObject.h" #include "Objects\CameraObject.h" #include "VegetationMap.h" #include "ViewManager.h" #include "ProcessInfo.h" #include "Settings.h" #include #include "IPhysics.h" #include #include #include #include ".\renderviewport.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif IMPLEMENT_DYNCREATE(CRenderViewport,CViewport) ///////////////////////////////////////////////////////////////////////////// // CRenderViewport CRenderViewport::CRenderViewport() { m_camera.Init( 800,600,gSettings.viewports.fDefaultFov ); m_camera.SetZMin( 0.1f ); m_camera.SetZMax( 10000.0f ); m_camera.SetPos( Vec3d(1000,1000,60) ); m_camera.SetAngle( Vec3d(0,0,0) ); m_camera.Update(); GetIEditor()->GetSystem()->SetViewCamera(m_camera); m_bRenderContextCreated = false; m_bInRotateMode = false; m_bInMoveMode = false; m_bWireframe = GetIEditor()->GetDisplaySettings()->GetDisplayMode() == DISPLAYMODE_WIREFRAME; m_bDisplayLabels = GetIEditor()->GetDisplaySettings()->IsDisplayLabels(); //for (int i = 0; i < 255; i++) //GetAsyncKeyState( i ); m_cameraObjectId = GUID_NULL; m_moveSpeed = 1; m_bSequenceCamera = false; m_bRMouseDown = false; m_bUpdating = false; m_nPresedKeyState = 0; } CRenderViewport::~CRenderViewport() { } BEGIN_MESSAGE_MAP(CRenderViewport, CViewport) //{{AFX_MSG_MAP(CRenderViewport) ON_WM_CREATE() ON_WM_SIZE() ON_WM_ERASEBKGND() ON_WM_PAINT() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_MBUTTONDOWN() ON_WM_MBUTTONUP() ON_WM_MOUSEMOVE() ON_WM_RBUTTONDOWN() ON_WM_RBUTTONUP() ON_WM_MOUSEWHEEL() ON_WM_KEYDOWN() //}}AFX_MSG_MAP ON_WM_SETCURSOR() ON_WM_DESTROY() ON_COMMAND(ID_SWITCHCAMERA_DEFAULTCAMERA, OnSwitchcameraDefaultcamera) ON_COMMAND(ID_SWITCHCAMERA_SEQUENCECAMERA, OnSwitchcameraSequencecamera) ON_COMMAND(ID_SWITCHCAMERA_SELECTEDCAMERA, OnSwitchcameraSelectedcamera) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CRenderViewport message handlers int CRenderViewport::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CViewport::OnCreate(lpCreateStruct) == -1) return -1; m_renderer = GetIEditor()->GetRenderer(); if (!m_renderer) { // Create renderer. m_renderer = GetIEditor()->GetSystem()->CreateRenderer( false,AfxGetInstanceHandle(),GetSafeHwnd() ); SetViewerPos( Vec3d(1000,1000,100) ); //CSystem::Instance()->SetCurrentRenderer( m_renderer ); } m_engine = GetIEditor()->Get3DEngine(); assert( m_engine ); m_pAnimationSystem = GetIEditor()->GetSystem()->GetIAnimationSystem(); CreateRenderContext(); return 0; } void CRenderViewport::OnSize(UINT nType, int cx, int cy) { CViewport::OnSize(nType, cx, cy); if(!cx || !cy) return; GetClientRect( m_rcClient ); m_viewSize.cx = cx; m_viewSize.cy = cy; } BOOL CRenderViewport::OnEraseBkgnd(CDC* pDC) { CGameEngine *ge = GetIEditor()->GetGameEngine(); if (ge && ge->IsLevelLoaded()) { return TRUE; } return FALSE; } void CRenderViewport::OnPaint() { // TODO: Add your message handler code here // Do not call CViewport::OnPaint() for painting messages CGameEngine *ge = GetIEditor()->GetGameEngine(); if (ge && ge->IsLevelLoaded()) { CViewport::OnPaint(); Update(); } else { CPaintDC dc(this); // device context for painting CRect rc; GetClientRect(rc); dc.FillRect( rc,CBrush::FromHandle((HBRUSH)GetStockObject(GRAY_BRUSH)) ); } } void CRenderViewport::OnLButtonDown(UINT nFlags, CPoint point) { if (GetIEditor()->IsInGameMode()) return; // Convert point to position on terrain. if (!m_renderer) return; // TODO: Add your message handler code here and/or call default CViewport::OnLButtonDown(nFlags, point); } void CRenderViewport::OnLButtonUp(UINT nFlags, CPoint point) { if (GetIEditor()->IsInGameMode()) return; // Convert point to position on terrain. if (!m_renderer) return; // TODO: Add your message handler code here and/or call default CViewport::OnLButtonUp(nFlags, point); } void CRenderViewport::OnRButtonDown(UINT nFlags, CPoint point) { m_bRMouseDown = true; if (GetIEditor()->IsInGameMode()) return; if (GetIEditor()->GetEditTool()) { GetIEditor()->GetEditTool()->MouseCallback( this,eMouseRDown,point,nFlags ); } CViewport::OnRButtonDown(nFlags, point); m_bInRotateMode = true; m_mousePos = point; CaptureMouse(); } void CRenderViewport::OnRButtonUp(UINT nFlags, CPoint point) { m_bRMouseDown = false; if (GetIEditor()->IsInGameMode()) return; CViewport::OnRButtonUp(nFlags, point); m_bInRotateMode = false; ReleaseMouse(); ////////////////////////////////////////////////////////////////////////// // To update object cursor. ////////////////////////////////////////////////////////////////////////// // Track mouse movements. ObjectHitInfo hitInfo(this,point); HitTest( point,hitInfo ); SetObjectCursor(hitInfo.object,true); // Update viewports after done with rotating. GetIEditor()->UpdateViews(eUpdateObjects); } void CRenderViewport::OnMButtonDown(UINT nFlags, CPoint point) { if (GetIEditor()->IsInGameMode()) return; if (!(nFlags & MK_CONTROL) && !(nFlags & MK_SHIFT)) { m_bInMoveMode = true; m_mousePos = point; CaptureMouse(); } CViewport::OnMButtonDown(nFlags, point); } void CRenderViewport::OnMButtonUp(UINT nFlags, CPoint point) { if (GetIEditor()->IsInGameMode()) return; m_bInMoveMode = false; m_mousePos = point; ReleaseMouse(); // Update viewports after done with moving viewport. GetIEditor()->UpdateViews(eUpdateObjects); CViewport::OnMButtonUp(nFlags, point); } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::OnMouseMove(UINT nFlags, CPoint point) { if (GetIEditor()->IsInGameMode()) return; SetObjectCursor(0); if(!m_nPresedKeyState) m_nPresedKeyState = 1; if (point == m_mousePos) { CViewport::OnMouseMove(nFlags, point); return; } float speedScale = 1; speedScale *= gSettings.cameraMoveSpeed; if (nFlags & MK_CONTROL) { speedScale *= gSettings.cameraFastMoveSpeed; } if (m_bInRotateMode && m_bInMoveMode) { // Zoom. Matrix44 m = m_camera.GetVCMatrixD3D9(); //Vec3d xdir(m[0][0],m[1][0],m[2][0]); Vec3d xdir(0,0,0); //xdir.Normalize(); Vec3d zdir(m[0][2],m[1][2],m[2][2]); zdir.Normalize(); //m_camera.SetPos( m_camera.GetPos() + ydir*(m_mousePos.y-point.y),xdir*(m_mousePos.x-point.x) ); Vec3d pos = GetViewerPos(); pos = pos + 0.1f*xdir*(point.x-m_mousePos.x)*speedScale + 0.2f*zdir*(m_mousePos.y-point.y)*speedScale; SetViewerPos( pos ); // GetIEditor()->MoveViewer(0.1f*xdir*(point.x-m_mousePos.x) + 0.2f*zdir*(m_mousePos.y-point.y)); CPoint pnt = m_mousePos; ClientToScreen( &pnt ); SetCursorPos( pnt.x,pnt.y ); return; } else if (m_bInRotateMode) { // Look Vec3d angles( point.y-m_mousePos.y,0,-point.x+m_mousePos.x ); SetViewerAngles( GetViewerAngles() + angles*0.2f ); CPoint pnt = m_mousePos; ClientToScreen( &pnt ); SetCursorPos( pnt.x,pnt.y ); return; } else if (m_bInMoveMode) { // Slide. Matrix44 m = m_camera.GetVCMatrixD3D9(); Vec3d xdir(m[0][0],m[1][0],m[2][0]); Vec3d ydir(m[0][1],m[1][1],m[2][1]); xdir.Normalize(); ydir.Normalize(); //m_camera.SetPos( m_camera.GetPos() + ydir*(m_mousePos.y-point.y),xdir*(m_mousePos.x-point.x) ); Vec3d pos = GetViewerPos(); pos += 0.1f*xdir*(point.x-m_mousePos.x)*speedScale + 0.1f*ydir*(m_mousePos.y-point.y)*speedScale; SetViewerPos( pos ); // GetIEditor()->MoveViewer(0.1f*xdir*(point.x-m_mousePos.x) + 0.1f*ydir*(m_mousePos.y-point.y)); CPoint pnt = m_mousePos; ClientToScreen( &pnt ); SetCursorPos( pnt.x,pnt.y ); return; } CViewport::OnMouseMove(nFlags, point); } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::Update() { if (!m_renderer || !m_engine) return; if (GetIEditor()->IsInGameMode()) return; if (!IsWindowVisible()) return; if (!GetIEditor()->GetDocument()->IsDocumentReady()) return; CGameEngine *ge = GetIEditor()->GetGameEngine(); if (!ge || !ge->IsLevelLoaded()) return; // Prevents rendering recursion due to recursive Paint messages. if (m_bUpdating) return; m_bUpdating = true; FUNCTION_PROFILER( GetIEditor()->GetSystem(),PROFILE_EDITOR ); // Render if (!m_bRenderContextCreated) { if (!CreateRenderContext()) return; } m_renderer->SetCurrentContext( m_hWnd ); m_renderer->SetClearColor( Vec3(1,0,0) ); m_renderer->BeginFrame(); m_renderer->ChangeViewport(0,0,m_rcClient.right,m_rcClient.bottom); OnRender(); // Print results. GetIEditor()->GetSystem()->GetITimer()->MeasureTime((LPCSTR)(-1)); // Render all kind of system statistical data. GetIEditor()->GetSystem()->RenderStatistics(); m_renderer->FlushTextMessages(); m_renderer->Update(); GetIEditor()->GetRenderer()->MakeCurrent(); if (GetFocus() == this) ProcessKeys(); CViewport::Update(); m_bUpdating = false; } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::SetCameraObject( CBaseObject *cameraObject ) { if (cameraObject) { m_cameraObjectId = cameraObject->GetId(); if (GetParent()) { GetParent()->SetWindowText( cameraObject->GetName() ); GetParent()->Invalidate(); } GetViewManager()->SetCameraObjectId( m_cameraObjectId ); } else { // Switch to normal view. m_cameraObjectId = GUID_NULL; if (GetParent()) { GetParent()->SetWindowText( GetName() ); GetParent()->Invalidate(); } GetViewManager()->SetCameraObjectId( m_cameraObjectId ); } } ////////////////////////////////////////////////////////////////////////// CBaseObject* CRenderViewport::GetCameraObject() const { CBaseObject *cameraObject = 0; if (m_bSequenceCamera) { m_cameraObjectId = GetViewManager()->GetCameraObjectId(); } if (m_cameraObjectId != GUID_NULL) { // Find camera object from id. cameraObject = GetIEditor()->GetObjectManager()->FindObject(m_cameraObjectId); } return cameraObject; } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::OnRender() { FUNCTION_PROFILER( GetIEditor()->GetSystem(),PROFILE_EDITOR ); //float proj = (float)rc.bottom/(float)rc.right; //if (proj > 1) proj = 1; //m_camera.Init( rc.right,rc.bottom,3.14f/2.0f,10000.0f,proj ); //m_camera.Init( 800,600,3.14f/2.0f,10000.0f,proj ); CBaseObject *cameraObject = GetCameraObject(); if (cameraObject) { // Find camera object // This is a camera object. float fov = gSettings.viewports.fDefaultFov; if (cameraObject->IsKindOf(RUNTIME_CLASS(CCameraObject))) { CCameraObject *camObj = (CCameraObject*)cameraObject; fov = camObj->GetFOV(); //m_camera.SetFov(fov); } else { //m_camera.SetFov(m_stdFOV); } /* int screenW = m_rcClient.right - m_rcClient.left; int screenH = m_rcClient.bottom - m_rcClient.top; float fAspect = gSettings.viewports.fDefaultAspectRatio; int w = screenH/fAspect; int h = screenH; //int sx = (screenW - w)/2; int sx = 0; //m_renderer->ChangeViewport( sx,0,w,h ); //float proj = (float)h/(float)w; */ int w = m_rcClient.right - m_rcClient.left; int h = m_rcClient.bottom - m_rcClient.top; float fAspectRatio = (float)h/(float)w; if (fAspectRatio > 1.2f) fAspectRatio = 1.2f; m_camera.Init( w,h,fov,m_camera.GetZMax(),fAspectRatio ); } else { // Normal camera. m_cameraObjectId = GUID_NULL; //m_camera.SetFov(m_stdFOV); int w = m_rcClient.right - m_rcClient.left; int h = m_rcClient.bottom - m_rcClient.top; //m_renderer->ChangeViewport( 0,0,w,h ); float fAspectRatio = (float)h/(float)w; if (fAspectRatio > 1.2f) fAspectRatio = 1.2f; m_camera.Init( w,h,gSettings.viewports.fDefaultFov,m_camera.GetZMax(),fAspectRatio ); } m_camera.SetPos( GetViewerPos() ); m_camera.SetAngle( GetViewerAngles() ); m_camera.Update(); GetIEditor()->GetSystem()->SetViewCamera(m_camera); m_engine->SetCamera(m_camera); if (GetIEditor()->GetDisplaySettings()->GetDisplayMode() == DISPLAYMODE_WIREFRAME) m_renderer->SetPolygonMode(R_WIREFRAME_MODE); else m_renderer->SetPolygonMode(R_SOLID_MODE); m_engine->Update(); m_engine->Draw(); // Draw engine stats IConsole * console = GetIEditor()->GetSystem()->GetIConsole(); ICVar * pDispInfoCVar = console->GetCVar("r_DisplayInfo"); if (pDispInfoCVar && pDispInfoCVar->GetIVal()) { // Draw 3dengine stats and get last text cursor position float nTextPosX=101-20, nTextPosY=-2, nTextStepY=3; m_engine->DisplayInfo(nTextPosX, nTextPosY, nTextStepY); } //m_engine->SetRenderCallback( 0,0 ); m_renderer->EF_StartEf(); m_renderer->ResetToDefault(); m_renderer->SelectTMU(0); m_renderer->EnableTMU(false); ////////////////////////////////////////////////////////////////////////// // Setup two infinite lights for helpers drawing. ////////////////////////////////////////////////////////////////////////// CDLight light[2]; light[0].m_Origin = m_camera.GetPos(); light[0].m_Color.Set(1,1,1,1); light[0].m_SpecColor.Set(1,1,1,1); light[0].m_fRadius = 1000000; light[0].m_fStartRadius = 0; light[0].m_fEndRadius = 1000000; light[0].m_Flags |= DLF_DIRECTIONAL; m_renderer->EF_ADDDlight( &light[0] ); light[1].m_Origin = Vec3(100000,100000,100000); light[1].m_Color.Set(1,1,1,1); light[1].m_SpecColor.Set(1,1,1,1); light[1].m_fRadius = 1000000; light[1].m_fStartRadius = 0; light[1].m_fEndRadius = 1000000; light[1].m_Flags |= DLF_DIRECTIONAL; m_renderer->EF_ADDDlight( &light[1] ); ////////////////////////////////////////////////////////////////////////// RenderAll(); m_engine->SetupDistanceFog(); m_renderer->EF_EndEf3D(SHDF_SORT | SHDF_ALLOWHDR); m_renderer->EF_ClearLightsList(); ////////////////////////////////////////////////////////////////////////// // Draw 2D helpers. ////////////////////////////////////////////////////////////////////////// m_renderer->Set2DMode( true,m_rcClient.right,m_rcClient.bottom ); ////////////////////////////////////////////////////////////////////////// // Draw selected rectangle. ////////////////////////////////////////////////////////////////////////// if (!m_selectedRect.IsRectEmpty()) { //m_renderer->EnableBlend(true); //m_renderer->SetBlendMode(); m_renderer->SetState(GS_DEPTHWRITE | GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA); m_renderer->SetMaterialColor( 1,1,1,0.4f ); //CPoint p1 = ViewToWorld(m_selectedRect. CPoint p1 = CPoint( m_selectedRect.left,m_selectedRect.top ); CPoint p2 = CPoint( m_selectedRect.right,m_selectedRect.bottom ); m_renderer->DrawLine( Vec3(p1.x,p1.y,0),Vec3(p2.x,p1.y,0) ); m_renderer->DrawLine( Vec3(p1.x,p2.y,0),Vec3(p2.x,p2.y,0) ); m_renderer->DrawLine( Vec3(p1.x,p1.y,0),Vec3(p1.x,p2.y,0) ); m_renderer->DrawLine( Vec3(p2.x,p1.y,0),Vec3(p2.x,p2.y,0) ); } // Draw Axis arrow in lower right corner. if (!IsAVIRecording()) { DrawAxis(); } // Display cursor string. RenderCursorString(); if (gSettings.viewports.bShowSafeFrame) RenderSafeFrame(); m_renderer->Set2DMode( false,m_rcClient.right,m_rcClient.bottom ); } static IRenderer *g_pRenderer; static void g_DrawLine(float *v1,float *v2) { Vec3d V1, V2; //V1.Set(v1); //V2.Set(v2); V1.Set(v1[0],v1[1],v1[2]); V2.Set(v2[0],v2[1],v2[2]); g_pRenderer->DrawLine(V1,V2); } void CRenderViewport::RenderAll() { m_renderer->ResetToDefault(); // Draw all objects. DisplayContext dctx; dctx.settings = GetIEditor()->GetDisplaySettings(); dctx.view = this; dctx.renderer = m_renderer; dctx.engine = m_engine; dctx.box.min=Vec3d( -100000,-100000,-100000 ); dctx.box.max=Vec3d( 100000,100000,100000 ); dctx.camera = &m_camera; if (!dctx.settings->IsDisplayLabels()) { dctx.flags |= DISPLAY_HIDENAMES; } if (dctx.settings->IsDisplayLinks()) { dctx.flags |= DISPLAY_LINKS; } if (m_bDegradateQuality) { dctx.flags |= DISPLAY_DEGRADATED; } if (dctx.settings->GetRenderFlags() & RENDER_FLAG_BBOX) { dctx.flags |= DISPLAY_BBOX; } dctx.flags |= DISPLAY_TRACKS; dctx.flags |= DISPLAY_TRACKTICKS; if (GetIEditor()->GetReferenceCoordSys() == COORDS_WORLD) { dctx.flags |= DISPLAY_WORLDSPACEAXIS; } //dctx.renderer->SetBlendMode(); //dctx.renderer->EnableBlend(true); dctx.SetState( GS_DEPTHWRITE|GS_BLSRC_SRCALPHA|GS_BLDST_ONEMINUSSRCALPHA ); GetIEditor()->GetObjectManager()->Display( dctx ); //dctx.renderer->EnableBlend(false); //dctx.renderer->SetState(GS_DEPTHWRITE); BBox box; GetIEditor()->GetSelectedRegion( box ); if (!IsEquivalent(box.min,box.max,0)) RenderTerrainGrid( box.min.x,box.min.y,box.max.x,box.max.y ); //RenderMarker(); g_pRenderer = m_renderer; IPhysicalWorld *physWorld = GetIEditor()->GetSystem()->GetIPhysicalWorld(); if (physWorld) physWorld->DrawPhysicsHelperInformation(g_DrawLine); IAISystem *aiSystem = GetIEditor()->GetSystem()->GetAISystem(); if (aiSystem) aiSystem->DebugDraw(m_renderer); if (dctx.settings->GetDebugFlags() & DBG_MEMINFO) { ProcessMemInfo mi; CProcessInfo::QueryMemInfo( mi ); int MB = 1024*1024; CString str; str.Format( "WorkingSet=%dMb, PageFile=%dMb, PageFaults=%d",mi.WorkingSet/MB,mi.PagefileUsage/MB,mi.PageFaultCount ); m_renderer->TextToScreenColor( 1,1,1,0,0,1,str ); } // Display editing tool. if (GetIEditor()->GetEditTool()) { GetIEditor()->GetEditTool()->Display( dctx ); } /* // Draw Construction plane. { m_renderer->EnableBlend(true); m_renderer->SetBlendMode(); m_renderer->SetCullMode(R_CULL_NONE); Vec3 p = m_constructionOriginalMatrix.GetTranslationOLD(); Vec3 n = m_constructionPlane.n; Vec3 dir = Vec3( 1,0,0 ); Vec3 u = (dir.Cross(n)).GetNormalized(); Vec3 v = (u.Cross(n)).GetNormalized(); dctx.SetColor( 1,0,1,0.2f ); float s = 4; dctx.DrawQuad( p, p+u*s,p+u*s+v*s,p+v*s ); dctx.SetColor( 0,0,1,1 ); dctx.DrawLine( p, p+u*s ); dctx.DrawLine( p+u*s,p+u*s+v*s ); dctx.DrawLine( p+u*s+v*s,p+v*s ); dctx.DrawLine( p,p+v*s ); } */ } ////////////////////////////////////////////////////////////////////////// namespace { inline Vec3 NegY( const Vec3 &v,float y ) { return Vec3(v.x,y-v.y,v.z); } } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::DrawAxis() { float colx[4] = {1,0,0,1};// Red float coly[4] = {0,1,0,1};// Green float colz[4] = {0,0,1,1};// Blue float colw[4] = {1,1,1,1};// White int size = 25; Vec3 pos( 25,25,0 ); Vec3 x(size,0,0); Vec3 y(0,size,0); Vec3 z(0,0,size); float height = m_rcClient.Height(); Vec3 hvec(height,height,height); Matrix44 camMatrix = m_camera.GetVCMatrixD3D9(); // camMatrix.Invert(); //CHANGED_BY_IVO //x = camMatrix.TransformVector(x); //y = camMatrix.TransformVector(y); //z = camMatrix.TransformVector(z); x = GetTransposed44(camMatrix)*(x); y = GetTransposed44(camMatrix)*(y); z = GetTransposed44(camMatrix)*(z); //m_renderer->EnableDepthTest(false); //m_renderer->EnableDepthWrites(false); m_renderer->SetState(GS_NODEPTHTEST); m_renderer->SetCullMode( R_CULL_DISABLE ); Vec3 src = NegY(pos,height); Vec3 trgx = NegY(pos+x,height); Vec3 trgy = NegY(pos+y,height); Vec3 trgz = NegY(pos+z,height); m_renderer->SetMaterialColor( colx[0],colx[1],colx[2],colx[3] ); m_renderer->DrawLine( src,trgx ); m_renderer->SetMaterialColor( coly[0],coly[1],coly[2],coly[3] ); m_renderer->DrawLine( src,trgy ); m_renderer->SetMaterialColor( colz[0],colz[1],colz[2],colz[3] ); m_renderer->DrawLine( src,trgz ); m_renderer->Draw2dLabel( trgx.x,trgx.y,1.1f,colw,true,"x" ); m_renderer->Draw2dLabel( trgy.x,trgy.y,1.1f,colw,true,"y" ); m_renderer->Draw2dLabel( trgz.x,trgz.y,1.1f,colw,true,"z" ); m_renderer->SetState(GS_DEPTHWRITE); //m_renderer->EnableDepthTest(true); //m_renderer->EnableDepthWrites(true); } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::RenderCursorString() { if (m_cursorStr.IsEmpty()) return; CPoint point; GetCursorPos( &point ); ScreenToClient( &point ); // float d = GetViewerPos().Distance(pos) * 0.02; // Display hit object name. float col[4] = { 1,1,1,1 }; m_renderer->Draw2dLabel( point.x+12,point.y+4,1.2f,col,false,"%s",(const char*)m_cursorStr ); } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::RenderSafeFrame() { m_renderer->SetState(GS_BLSRC_SRCALPHA|GS_BLDST_ONEMINUSSRCALPHA|GS_NODEPTHTEST); int screenW = m_rcClient.right - m_rcClient.left; int screenH = m_rcClient.bottom - m_rcClient.top; float fAspect = gSettings.viewports.fDefaultAspectRatio; int w = screenH/fAspect; int h = screenH; int sx = (screenW - w)/2; //float proj = (float)h/(float)w; m_renderer->SetMaterialColor( 0,1,1,0.5f ); // cyan m_renderer->DrawLine( Vec3(sx,0,0),Vec3(sx+w,0,0) ); m_renderer->DrawLine( Vec3(sx,1,0),Vec3(sx+w,1,0) ); m_renderer->DrawLine( Vec3(sx,h-2,0),Vec3(sx+w,h-2,0) ); m_renderer->DrawLine( Vec3(sx,h-1,0),Vec3(sx+w,h-1,0) ); m_renderer->DrawLine( Vec3(sx,0,0),Vec3(sx,h,0) ); m_renderer->DrawLine( Vec3(sx-1,0,0),Vec3(sx-1,h,0) ); m_renderer->DrawLine( Vec3(sx+w,0,0),Vec3(sx+w,h,0) ); m_renderer->DrawLine( Vec3(sx+w+1,0,0),Vec3(sx+w+1,h,0) ); } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::RenderMarker() { /* Vec3 p = GetIEditor()->GetMarkerPosition(); float verts[4][5]; memset( verts,0,sizeof(verts) ); float dist = (p - m_camera.GetPos()).Length(); float size = 0.5f; float offset = 0.1f; float x = p.x; float y = p.y; verts[0][0] = x-size; verts[0][1] = y-size; verts[0][2] = GetIEditor()->GetTerrainElevation( x-size,y-size ) + offset; verts[1][0] = x+size; verts[1][1] = y-size; verts[1][2] = GetIEditor()->GetTerrainElevation( x+size,y-size ) + offset; verts[3][0] = x+size; verts[3][1] = y+size; verts[3][2] = GetIEditor()->GetTerrainElevation( x+size,y+size ) + offset; verts[2][0] = x-size; verts[2][1] = y+size; verts[2][2] = GetIEditor()->GetTerrainElevation( x-size,y+size ) + offset; m_renderer->SetMaterialColor( 1,0,0.8f,0.6f ); m_renderer->SetBlendMode(); m_renderer->EnableBlend( true ); m_renderer->DrawTriStrip(&(CVertexBuffer(verts,VERTEX_FORMAT_P3F_TEX2F)),4); m_renderer->SetMaterialColor( 1,1,0,0.6f ); m_renderer->DrawBall( p,size*0.8f ); m_renderer->ResetToDefault(); */ } inline bool SortCameraObjectsByName( CCameraObject *pObject1,CCameraObject *pObject2 ) { return stricmp(pObject1->GetName(),pObject2->GetName()) < 0; } void CRenderViewport::OnTitleMenu( CMenu &menu ) { m_bWireframe = GetIEditor()->GetDisplaySettings()->GetDisplayMode() == DISPLAYMODE_WIREFRAME; m_bDisplayLabels = GetIEditor()->GetDisplaySettings()->IsDisplayLabels(); menu.AppendMenu( MF_STRING|(m_bWireframe)?MF_CHECKED:MF_UNCHECKED,1,"Wireframe" ); menu.AppendMenu( MF_STRING|(m_bDisplayLabels)?MF_CHECKED:MF_UNCHECKED,2,"Labels" ); menu.AppendMenu( MF_STRING|(gSettings.viewports.bShowSafeFrame)?MF_CHECKED:MF_UNCHECKED,3,"Show Safe Frame" ); // Add Cameras. std::vector objects; ((CObjectManager*)GetIEditor()->GetObjectManager())->GetCameras( objects ); if (!objects.empty()) { std::sort( objects.begin(),objects.end(),SortCameraObjectsByName ); menu.AppendMenu( MF_SEPARATOR,0,"" ); menu.AppendMenu( MF_STRING|(m_cameraObjectId == GUID_NULL && !m_bSequenceCamera)?MF_CHECKED:MF_UNCHECKED,1000,"Default Camera" ); menu.AppendMenu( MF_STRING|(m_bSequenceCamera)?MF_CHECKED:MF_UNCHECKED,1001,"Sequence Camera" ); menu.AppendMenu( MF_SEPARATOR,0,"" ); static CMenu subMenu; if (subMenu.m_hMenu) subMenu.DestroyMenu(); subMenu.CreatePopupMenu(); menu.AppendMenu( MF_POPUP,(UINT_PTR)subMenu.GetSafeHmenu(),"Camera" ); for (int i = 0; i < objects.size(); i++) { int state = (m_cameraObjectId == objects[i]->GetId() && !m_bSequenceCamera)?MF_CHECKED:MF_UNCHECKED; subMenu.AppendMenu( MF_STRING|state,1002+i,objects[i]->GetName() ); } } } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::OnTitleMenuCommand( int id ) { if (id >= 1000 && id < 2000) { if (id == 1000) { m_bSequenceCamera = false; SetCameraObject(0); } else if (id == 1001) { m_bSequenceCamera = true; SetCameraObject(0); } else { m_bSequenceCamera = false; // Switch to Camera Object. std::vector objects; ((CObjectManager*)GetIEditor()->GetObjectManager())->GetCameras( objects ); std::sort( objects.begin(),objects.end(),SortCameraObjectsByName ); int index = id - 1002; if (index < objects.size()) { SetCameraObject( objects[index] ); } } } switch (id) { case 1: m_bWireframe = !m_bWireframe; if (m_bWireframe) GetIEditor()->GetDisplaySettings()->SetDisplayMode( DISPLAYMODE_WIREFRAME ); else GetIEditor()->GetDisplaySettings()->SetDisplayMode( DISPLAYMODE_SOLID ); break; case 2: m_bDisplayLabels = !m_bDisplayLabels; GetIEditor()->GetDisplaySettings()->DisplayLabels( m_bDisplayLabels ); break; case 3: gSettings.viewports.bShowSafeFrame = !gSettings.viewports.bShowSafeFrame; break; } } ////////////////////////////////////////////////////////////////////////// BOOL CRenderViewport::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) { if (GetIEditor()->IsInGameMode()) return FALSE; // TODO: Add your message handler code here and/or call default Matrix44 m = m_camera.GetVCMatrixD3D9(); Vec3d zdir(m[0][2],m[1][2],m[2][2]); zdir.Normalize(); Vec3d pos = GetViewerPos(); pos += 0.2f*zdir*(zDelta); SetViewerPos( pos ); // GetIEditor()->MoveViewer(0.2f*zdir*(zDelta)); return CViewport::OnMouseWheel(nFlags, zDelta, pt); } void CRenderViewport::SetCamera( const CCamera &camera ) { m_camera = camera; SetViewerPos( m_camera.GetPos() ); SetViewerAngles( m_camera.GetAngles() ); } Vec3 CRenderViewport::GetViewerPos() const { CBaseObject *cameraObject = GetCameraObject(); if (!cameraObject) return GetIEditor()->GetViewerPos(); else { return cameraObject->GetWorldPos(); } } Vec3 CRenderViewport::GetViewerAngles() const { CBaseObject *cameraObject = GetCameraObject(); if (!cameraObject) return GetIEditor()->GetViewerAngles(); else { Matrix44 tm = cameraObject->GetWorldTM(); tm.NoScale(); //CHANGED_BY_IVO //Quat quat(tm); //Quat quat = CovertMatToQuat( GetTransposed44(tm) ); Quat quat = Quat( GetTransposed44(tm) ); return RAD2DEG(Ang3::GetAnglesXYZ(Matrix33(quat))); } } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::SetViewerPos( const Vec3 &pos ) { Vec3 p = pos; // If no collision flag set do not check for terrain elevation. if ((GetIEditor()->GetDisplaySettings()->GetSettings()&SETTINGS_NOCOLLISION) == 0) { float z = GetIEditor()->GetTerrainElevation( p.x,p.y ); if (p.z < z+1) p.z = z+1; } CBaseObject *cameraObject = GetCameraObject(); if (!cameraObject) { GetIEditor()->SetViewerPos( p ); } else { if(!m_nPresedKeyState || m_nPresedKeyState==1) { CUndo undo("Move Camera"); Matrix44 tm = cameraObject->GetWorldTM(); tm.SetTranslationOLD(pos); cameraObject->SetWorldTM( tm ); } else { Matrix44 tm = cameraObject->GetWorldTM(); tm.SetTranslationOLD(pos); cameraObject->SetWorldTM( tm ); } } if(m_nPresedKeyState==1) m_nPresedKeyState=2; UpdateConstrPlane(); } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::SetViewerAngles( const Vec3 &angles ) { CBaseObject *cameraObject = GetCameraObject(); if (!cameraObject) { GetIEditor()->SetViewerAngles( angles ); } else { if(!m_nPresedKeyState || m_nPresedKeyState==1) { CUndo undo("Turn Camera"); Matrix44 tm; tm.SetIdentity(); //tm.RotateMatrix_fix( angles ); tm=Matrix44::CreateRotationZYX(-angles*gf_DEGTORAD)*tm; //NOTE: angles in radians and negated Vec3 pos = cameraObject->GetWorldTM().GetTranslationOLD(); tm.SetTranslationOLD(pos); cameraObject->SetWorldTM( tm ); } else { Matrix44 tm; tm.SetIdentity(); //tm.RotateMatrix_fix( angles ); tm=Matrix44::CreateRotationZYX(-angles*gf_DEGTORAD)*tm; //NOTE: angles in radians and negated Vec3 pos = cameraObject->GetWorldTM().GetTranslationOLD(); tm.SetTranslationOLD(pos); cameraObject->SetWorldTM( tm ); } } if(m_nPresedKeyState==1) m_nPresedKeyState=2; UpdateConstrPlane(); } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::RenderTerrainGrid( float x1,float y1,float x2,float y2 ) { if (!m_engine) return; float x,y; struct_VERTEX_FORMAT_P3F_TEX2F verts[4]; memset( verts,0,sizeof(verts) ); float step = MAX( y2-y1,x2-x1 ); if (step < 0.1) return; step = step / 100.0f; //if (step > 2) step = 2; //x1 = (((int)x1)/2)*2; //y1 = (((int)y1)/2)*2; //x2 = (((int)x2)/2)*2; //y2 = (((int)y2)/2)*2; m_renderer->SetMaterialColor( 1,1,1,1 ); float z1 = m_engine->GetTerrainElevation( x1,y1 ); float z2 = m_engine->GetTerrainElevation( x2,y2 ); float z3 = m_engine->GetTerrainElevation( x2,y1 ); float z4 = m_engine->GetTerrainElevation( x1,y2 ); m_renderer->DrawLine( Vec3(x1,y1,z1),Vec3(x1,y1,z1+0.5) ); m_renderer->DrawLine( Vec3(x2,y2,z2),Vec3(x2,y2,z2+0.5) ); m_renderer->DrawLine( Vec3(x2,y1,z3),Vec3(x2,y1,z3+0.5) ); m_renderer->DrawLine( Vec3(x1,y2,z4),Vec3(x1,y2,z4+0.5) ); m_renderer->SetMaterialColor( 1,0,0,0.5 ); m_renderer->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST); //m_renderer->SetBlendMode(); //m_renderer->EnableBlend( true ); //m_renderer->EnableDepthTest( false ); float offset = 0.01f; for (y = y1; y < y2+step; y += step) { for (x = x1; x < x2+step; x += step) { verts[0].xyz.x = x; verts[0].xyz.y = y; verts[0].xyz.z = m_engine->GetTerrainElevation( x,y ) + offset; verts[1].xyz.x = x+step; verts[1].xyz.y = y; verts[1].xyz.z = m_engine->GetTerrainElevation( x+step,y ) + offset; verts[3].xyz.x = x+step; verts[3].xyz.y = y+step; verts[3].xyz.z = m_engine->GetTerrainElevation( x+step,y+step ) + offset; verts[2].xyz.x = x; verts[2].xyz.y = y+step; verts[2].xyz.z = m_engine->GetTerrainElevation( x,y+step ) + offset; //m_renderer->DrawLine( Vec3d(x,y,z),Vec3d(x+step,y,z) ); //m_renderer->DrawLine( Vec3d(x,y,z),Vec3d(x,y+step,z) ); /* float //m_renderer->DrawLine( Vec3d(x,y,z),Vec3d(x+step,y,z) ); //m_renderer->DrawLine( Vec3d(x,y,z),Vec3d(x,y+step,z) ); m_renderer->DrawQuad( x+step*0.5f,y+step*0.5f,(z1+z2+z3+z4)/4 ); float data[] = { -dx+x, dy+y,-object_Scale4+z, 0, 0, // 1,1,1,alpha,//NOTE: totaly stupid dx+x,-dy+y,-object_Scale4+z, 0, 0, // 1,1,1,alpha, -dx+x, dy+y, object_Scale4+z, -1, 1, // 1,1,1,alpha, dx+x,-dy+y, object_Scale4+z, 0, 1, // 1,1,1,alpha, }; GetRenderer()->SetMaterialColor(1,1,1,alpha); GetRenderer()->SetTexture(tid); */ m_renderer->DrawTriStrip(&(CVertexBuffer(verts,VERTEX_FORMAT_P3F_TEX2F)),4); } } Vec3 p1,p2; // Draw yellow border lines. m_renderer->SetMaterialColor( 1,1,0,1 ); for (y = y1; y < y2+step; y += step) { p1.x = x1; p1.y = y; p1.z = m_engine->GetTerrainElevation( p1.x,p1.y ) + offset; p2.x = x1; p2.y = y+step; p2.z = m_engine->GetTerrainElevation( p2.x,p2.y ) + offset; m_renderer->DrawLine( p1,p2 ); p1.x = x2+step; p1.y = y; p1.z = m_engine->GetTerrainElevation( p1.x,p1.y ) + offset; p2.x = x2+step; p2.y = y+step; p2.z = m_engine->GetTerrainElevation( p2.x,p2.y ) + offset; m_renderer->DrawLine( p1,p2 ); } for (x = x1; x < x2+step; x += step) { p1.x = x; p1.y = y1; p1.z = m_engine->GetTerrainElevation( p1.x,p1.y ) + offset; p2.x = x+step; p2.y = y1; p2.z = m_engine->GetTerrainElevation( p2.x,p2.y ) + offset; m_renderer->DrawLine( p1,p2 ); p1.x = x; p1.y = y2+step; p1.z = m_engine->GetTerrainElevation( p1.x,p1.y ) + offset; p2.x = x+step; p2.y = y2+step; p2.z = m_engine->GetTerrainElevation( p2.x,p2.y ) + offset; m_renderer->DrawLine( p1,p2 ); } //m_renderer->EnableDepthTest(true); m_renderer->SetState(GS_DEPTHWRITE); m_renderer->ResetToDefault(); } void CRenderViewport::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { /* m_camera.Update(); Matrix m = m_camera.GetMatrix(); Vec3d zdir(m[0][2],m[1][2],m[2][2]); zdir.Normalize(); Vec3d xdir(m[0][0],m[1][0],m[2][0]); xdir.Normalize(); //m_camera.SetPos( m_camera.GetPos() + ydir*(m_mousePos.y-point.y),xdir*(m_mousePos.x-point.x) ); Vec3d pos = GetViewerPos(); if (nChar == VK_UP) { // move forward pos = pos - 0.5f*zdir; SetViewerPos( pos ); } if (nChar == VK_DOWN) { // move backward pos = pos + 0.5f*zdir; SetViewerPos( pos ); } if (nChar == VK_LEFT) { // move left pos = pos - 0.5f*xdir; SetViewerPos( pos ); } if (nChar == VK_RIGHT) { // move right pos = pos + 0.5f*xdir; SetViewerPos( pos ); } */ CViewport::OnKeyDown(nChar, nRepCnt, nFlags); } void CRenderViewport::ProcessKeys() { if (GetFocus() != this) return; m_camera.Update(); Matrix44 m = m_camera.GetVCMatrixD3D9(); Vec3d zdir(m[0][2],m[1][2],m[2][2]); zdir.Normalize(); Vec3d xdir(m[0][0],m[1][0],m[2][0]); xdir.Normalize(); //m_camera.SetPos( m_camera.GetPos() + ydir*(m_mousePos.y-point.y),xdir*(m_mousePos.x-point.x) ); Vec3d pos = GetViewerPos(); IConsole * console = GetIEditor()->GetSystem()->GetIConsole(); float speedScale = 60.0f * GetIEditor()->GetSystem()->GetITimer()->GetFrameTime(); if (speedScale > 20) speedScale = 20; speedScale *= gSettings.cameraMoveSpeed; if (CheckVirtualKey(VK_SHIFT)) { speedScale *= gSettings.cameraFastMoveSpeed; } bool bCtrl = CheckVirtualKey(VK_LCONTROL) || CheckVirtualKey(VK_RCONTROL); //bool bAlt = GetAsyncKeyState(VK_LALT) || GetAsyncKeyState(VK_RCONTROL); if (bCtrl) return; bool bIsPressedSome = false; if (CheckVirtualKey(VK_UP) || CheckVirtualKey('W')) { // move forward bIsPressedSome = true; if(!m_nPresedKeyState) m_nPresedKeyState = 1; pos = pos - speedScale*m_moveSpeed*zdir; SetViewerPos( pos ); //GetIEditor()->MoveViewer(-speedScale*m_moveSpeed*zdir); } if (CheckVirtualKey(VK_DOWN) || CheckVirtualKey('S')) { // move backward bIsPressedSome = true; if(!m_nPresedKeyState) m_nPresedKeyState = 1; pos = pos + speedScale*m_moveSpeed*zdir; SetViewerPos( pos ); //GetIEditor()->MoveViewer(speedScale*m_moveSpeed*zdir); } if (CheckVirtualKey(VK_LEFT) || CheckVirtualKey('A')) { // move left bIsPressedSome = true; if(!m_nPresedKeyState) m_nPresedKeyState = 1; pos = pos - speedScale*m_moveSpeed*xdir; SetViewerPos( pos ); //GetIEditor()->MoveViewer(-speedScale*m_moveSpeed*xdir); } if (CheckVirtualKey(VK_RIGHT) || CheckVirtualKey('D')) { // move right bIsPressedSome = true; if(!m_nPresedKeyState) m_nPresedKeyState = 1; pos = pos + speedScale*m_moveSpeed*xdir; SetViewerPos( pos ); //GetIEditor()->MoveViewer(speedScale*m_moveSpeed*xdir); } if (CheckVirtualKey(VK_RBUTTON)) { bIsPressedSome = true; } if(!bIsPressedSome) m_nPresedKeyState=0; } ////////////////////////////////////////////////////////////////////////// CPoint CRenderViewport::WorldToView( Vec3 wp ) { CPoint p; float x,y,z; m_renderer->ProjectToScreen( wp.x,wp.y,wp.z,&x,&y,&z ); p.x = (x / 100) * m_rcClient.Width(); p.y = (y / 100) * m_rcClient.Height(); return p; } ////////////////////////////////////////////////////////////////////////// Vec3 CRenderViewport::ViewToWorld( CPoint vp,bool *collideWithTerrain,bool onlyTerrain ) { if (!m_renderer) return Vec3(0,0,0); m_renderer->SetCurrentContext( m_hWnd ); CRect rc = m_rcClient; //m_renderer->ChangeViewport( 0,0,rc.right-rc.left,rc.bottom-rc.top ); Vec3 pos0,pos1; float wx,wy,wz; m_renderer->UnProjectFromScreen( vp.x,rc.bottom-vp.y,0,&wx,&wy,&wz ); if (!_finite(wx) || !_finite(wy) || !_finite(wz)) return Vec3(0,0,0); pos0( wx,wy,wz ); m_renderer->UnProjectFromScreen( vp.x,rc.bottom-vp.y,1,&wx,&wy,&wz ); if (!_finite(wx) || !_finite(wy) || !_finite(wz)) return Vec3(0,0,0); pos1( wx,wy,wz ); Vec3 v = (pos1-pos0); v = GetNormalized(v); v = v*2000.0f; if (!_finite(v.x) || !_finite(v.y) || !_finite(v.z)) return Vec3(0,0,0); /* GetIEditor()->GetSystem()->GetILog()->Log( "x:%f, y%f, z:%f",v.x,v.y,v.z ); */ Vec3 colp(0,0,0); IPhysicalWorld *world = GetIEditor()->GetSystem()->GetIPhysicalWorld(); if (!world) return colp; vectorf vPos(pos0.x,pos0.y,pos0.z); vectorf vDir(v.x,v.y,v.z); int objTypes = ent_terrain; if (!onlyTerrain && !GetIEditor()->IsTerrainAxisIgnoreObjects()) objTypes |= ent_static; int flags = rwi_stop_at_pierceable|rwi_ignore_terrain_holes; //flags = 31; ray_hit hit; hit.pCollider = 0; int col = world->RayWorldIntersection( vPos,vDir,objTypes,flags,&hit,1 ); bool hitTerrain = hit.bTerrain; if (hit.dist > 0 && !hit.bTerrain && hit.pCollider != 0) { // Check if we collided with collision entity of selected object. bool bCollidedWithSelection = false; CSelectionGroup *sel = GetIEditor()->GetSelection(); for (int i = 0; i < sel->GetCount(); i++) { if (sel->GetObject(i)->GetCollisionEntity() == hit.pCollider) { bCollidedWithSelection = true; break; } } if (bCollidedWithSelection) { // Repeat collision test, but skip selected collider. col = world->RayWorldIntersection( vPos,vDir,objTypes,flags,&hit,1,hit.pCollider ); /* pe_status_pos statusPos; hit.pCollider->GetStatus( &statusPos ); Vec3 size = statusPos.BBox[1] - statusPos.BBox[0]; if (size.Length() < 20) { // We collided small static object, ignore it, and collide only with terrain. objTypes = ent_terrain; col = world->RayWorldIntersection( vPos,vDir,objTypes,flags,&hit,1 ); hitTerrain = true; } */ } } if (collideWithTerrain) *collideWithTerrain = hitTerrain; if (hit.dist > 0) { if (hit.pCollider != 0 && !hit.bTerrain) { //pe_status_pos statusPos; //hit.pCollider->GetStatus( &statusPos ); //BBox box( statusPos.BBox[0],statusPos.BBox[1] ); } colp = hit.pt; if (hitTerrain) { colp.z = m_engine->GetTerrainElevation( colp.x,colp.y ); } } return colp; } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::ViewToWorldRay( CPoint vp,Vec3 &raySrc,Vec3 &rayDir ) { if (!m_renderer) return; CRect rc = m_rcClient; m_renderer->SetCurrentContext( m_hWnd ); //m_renderer->ChangeViewport( 0,0,rc.right-rc.left,rc.bottom-rc.top ); Vec3 pos0,pos1; float wx,wy,wz; m_renderer->UnProjectFromScreen( vp.x,rc.bottom-vp.y,0,&wx,&wy,&wz ); if (!_finite(wx) || !_finite(wy) || !_finite(wz)) return; if (fabs(wx) > 1000000 || fabs(wy) > 1000000 || fabs(wz) > 1000000) return; pos0( wx,wy,wz ); m_renderer->UnProjectFromScreen( vp.x,rc.bottom-vp.y,1,&wx,&wy,&wz ); if (!_finite(wx) || !_finite(wy) || !_finite(wz)) return; if (fabs(wx) > 1000000 || fabs(wy) > 1000000 || fabs(wz) > 1000000) return; pos1( wx,wy,wz ); Vec3 v = (pos1-pos0); v = GetNormalized(v); raySrc = pos0; rayDir = v; } ////////////////////////////////////////////////////////////////////////// float CRenderViewport::GetScreenScaleFactor( const Vec3 &worldPoint ) { float dist = GetDistance( m_camera.GetPos(), worldPoint ); if (dist < m_camera.GetZMin()) dist = m_camera.GetZMin(); return dist; } BOOL CRenderViewport::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { if (m_hCurrCursor == NULL && !m_cursorStr.IsEmpty()) { m_cursorStr = ""; // Display cursor string. } return CViewport::OnSetCursor(pWnd, nHitTest, message); } void CRenderViewport::OnDestroy() { DestroyRenderContext(); CViewport::OnDestroy(); } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::DrawTextLabel( DisplayContext &dc,const Vec3& pos,float size,const CFColor& color,const char *text ) { float col[4] = { color.r,color.g,color.b,color.a }; m_renderer->DrawLabelEx( pos,size,col,true,true,text ); } ////////////////////////////////////////////////////////////////////////// bool CRenderViewport::HitTest( CPoint point,ObjectHitInfo &hitInfo,int flags ) { hitInfo.camera = &m_camera; return CViewport::HitTest( point,hitInfo,flags ); } ////////////////////////////////////////////////////////////////////////// bool CRenderViewport::IsBoundsVisible( const BBox &box ) const { // If at least part of bbox is visible then its visible. return m_camera.IsAABBVisibleFast( AABB(box.min,box.max) ); } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::CenterOnSelection() { if (!GetIEditor()->GetSelection()->IsEmpty()) { CSelectionGroup *sel = GetIEditor()->GetSelection(); BBox bounds = sel->GetBounds(); Vec3 selPos = sel->GetCenter(); float size = GetLength(bounds.max - bounds.min); Vec3 pos = selPos; pos += Vec3(0,size*2,size); //pos.z = GetIEditor()->GetTerrainElevation(pos.x,pos.y)+5; GetIEditor()->SetViewerPos( pos ); Vec3 dir = GetNormalized(selPos - pos); dir=ConvertVectorToCameraAngles(dir); GetIEditor()->SetViewerAngles( dir ); } } ////////////////////////////////////////////////////////////////////////// bool CRenderViewport::CreateRenderContext() { // Create context. if (m_renderer && !m_bRenderContextCreated) { m_bRenderContextCreated = true; m_renderer->CreateContext( m_hWnd ); // Make main context current. m_renderer->MakeCurrent(); return true; } return false; } ////////////////////////////////////////////////////////////////////////// void CRenderViewport::DestroyRenderContext() { // Destroy render context. if (m_renderer && m_bRenderContextCreated) { // Do not delete primary context. if (m_hWnd != m_renderer->GetHWND()) m_renderer->DeleteContext(m_hWnd); m_bRenderContextCreated = false; } } void CRenderViewport::OnSwitchcameraDefaultcamera() { m_bSequenceCamera = false; SetCameraObject(0); } void CRenderViewport::OnSwitchcameraSequencecamera() { m_bSequenceCamera = true; SetCameraObject(0); } void CRenderViewport::OnSwitchcameraSelectedcamera() { CBaseObject *pObject = GetIEditor()->GetSelectedObject(); if (pObject && pObject->IsKindOf(RUNTIME_CLASS(CCameraObject))) SetCameraObject( pObject ); }