/* Copyright (c) 2002-2012 Croteam Ltd. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // ModelerDoc.cpp : implementation of the CModelerDoc class // #include "stdafx.h" #include #include #include #include #include #ifdef _DEBUG #undef new #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CModelerDoc IMPLEMENT_DYNCREATE(CModelerDoc, CDocument) BEGIN_MESSAGE_MAP(CModelerDoc, CDocument) //{{AFX_MSG_MAP(CModelerDoc) ON_COMMAND(ID_FILE_ADD_TEXTURE, OnFileAddTexture) ON_UPDATE_COMMAND_UI(ID_FILE_ADD_TEXTURE, OnUpdateFileAddTexture) ON_COMMAND(ID_NEXT_SURFACE, OnNextSurface) ON_COMMAND(ID_PREV_SURFACE, OnPrevSurface) ON_COMMAND(ID_LINK_SURFACES, OnLinkSurfaces) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CModelerDoc construction/destruction CModelerDoc::CModelerDoc() { // Default clipboard variables used for storing copy/paste data m_f3ClipboardCenter = FLOAT3D( 0.0f, 0.0f, 0.0f); m_fClipboardZoom = FLOAT( 0.0f); m_f3ClipboardHPB = FLOAT3D( 0.0f, 0.0f, 0.0f); m_iCurrentMip = 0; } CModelerDoc::~CModelerDoc() { _pAnimStock->FreeUnused(); _pTextureStock->FreeUnused(); _pModelStock->FreeUnused(); _pSoundStock->FreeUnused(); } BOOL CModelerDoc::CreateModelFromScriptFile( CTFileName fnScrFileName, char *strError) { CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); try { CWaitCursor StartWaitCursor; CRect rectMainFrameSize; CRect rectProgress, rectProgressNew; pMainFrame->GetWindowRect( &rectMainFrameSize); pMainFrame->m_NewProgress.Create( IDD_NEW_PROGRESS, pMainFrame); pMainFrame->m_NewProgress.GetWindowRect( &rectProgress); rectProgressNew.left = rectMainFrameSize.Width()/2 - rectProgress.Width()/2; rectProgressNew.top = rectMainFrameSize.Height()/2 - rectProgress.Height()/2; rectProgressNew.right = rectProgressNew.left + rectProgress.Width(); rectProgressNew.bottom = rectProgressNew.top + rectProgress.Height(); pMainFrame->m_NewProgress.MoveWindow( rectProgressNew); pMainFrame->m_NewProgress.ShowWindow(SW_SHOW); m_emEditModel.LoadFromScript_t( fnScrFileName); } catch( char *err_str) { strcpy( strError, err_str); pMainFrame->m_NewProgress.DestroyWindow(); return FALSE; } pMainFrame->m_NewProgress.DestroyWindow(); m_bDocLoadedOk = TRUE; return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CModelerDoc serialization void CModelerDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { } else { } } ///////////////////////////////////////////////////////////////////////////// // CModelerDoc diagnostics #ifdef _DEBUG void CModelerDoc::AssertValid() const { CDocument::AssertValid(); } void CModelerDoc::Dump(CDumpContext& dc) const { CDocument::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CModelerDoc commands BOOL CModelerDoc::OnOpenDocument(LPCTSTR lpszPathName) { m_bDocLoadedOk = FALSE; CTFileName fnModelFile = CTString(CStringA(lpszPathName)); try { fnModelFile.RemoveApplicationPath_t(); } catch( char *err_str) { AfxMessageBox( CString(err_str)); return FALSE; } try { m_emEditModel.Load_t( fnModelFile); } catch( char *err_str) { CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); MessageBoxA(pMainFrame->m_hWnd, err_str, "Warning! Model load failed.", MB_OK|MB_ICONHAND|MB_SYSTEMMODAL); return FALSE; } INDEX ctLoadedModels=m_emEditModel.edm_aamAttachedModels.Count(); INDEX ctAttachmentPositions=m_emEditModel.edm_md.md_aampAttachedPosition.Count(); if(ctLoadedModelsExecute("FreeUnusedStock();"); SelectSurface( 0, TRUE); return TRUE; } BOOL CModelerDoc::OnSaveDocument(LPCTSTR lpszPathName) { CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); //return CDocument::OnSaveDocument(lpszPathName); CTFileName fnModelFile = CTString(CStringA(lpszPathName)); try { fnModelFile.RemoveApplicationPath_t(); } catch( char *err_str) { AfxMessageBox( CString(err_str)); return FALSE; } try { m_emEditModel.Save_t( fnModelFile); m_emEditModel.SaveMapping_t( fnModelFile.NoExt()+".map", 0); } catch( char *err_str) { MessageBoxA(pMainFrame->m_hWnd, err_str, "Warning! Model Save failed.", MB_OK|MB_ICONHAND|MB_SYSTEMMODAL); return FALSE; } SetModifiedFlag( FALSE); CModelerView *pModelerView = CModelerView::GetActiveView(); if( pModelerView != NULL) { pModelerView->SaveThumbnail(); } // reload attachments of all loaded models POSITION pos = theApp.m_pdtModelDocTemplate->GetFirstDocPosition(); while (pos!=NULL) { CModelerDoc *pmdCurrent = (CModelerDoc *)theApp.m_pdtModelDocTemplate->GetNextDoc(pos); if( pmdCurrent != this) { BOOL bUpdateAttachments = TRUE; // if document is modified if( pmdCurrent->IsModified()) { CTString strMessage; CTFileName fnDoc = CTString(CStringA(pmdCurrent->GetPathName())); strMessage.PrintF("Do you want to save model \"%s\" before reloading its attachments?", fnDoc.FileName() ); if( ::MessageBoxA( pMainFrame->m_hWnd, strMessage, "Warning !", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON1 | MB_TASKMODAL | MB_TOPMOST) != IDYES) { bUpdateAttachments = FALSE; } // save document else { pmdCurrent->OnSaveDocument(pmdCurrent->GetPathName()); } } if( bUpdateAttachments) { POSITION pos = pmdCurrent->GetFirstViewPosition(); while (pos != NULL) { CView* pView = GetNextView(pos); ((CModelerView *)pView)->m_ModelObject.AutoSetAttachments(); //CModelData *pmd = (CModelData *) ((CModelerView *)pView)->m_ModelObject.GetData(); //pmd->Reload(); } } } } return TRUE; } void CModelerDoc::OnIdle(void) { POSITION pos = GetFirstViewPosition(); while ( pos !=NULL) { CModelerView *pmvCurrent = (CModelerView *) GetNextView(pos); pmvCurrent->OnIdle(); } } // overridden from mfc to discard rendering precalculations void CModelerDoc::SetModifiedFlag( BOOL bModified /*= TRUE*/ ) { CDocument::SetModifiedFlag(bModified); } extern UINT APIENTRY ModelerFileRequesterHook( HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam); void CModelerDoc::OnFileAddTexture() { CModelerView *pModelerView = CModelerView::GetActiveView(); if( pModelerView == NULL) return; // call file requester for adding textures CDynamicArray afnTextures; CTFileName fnDocName = CTString(CStringA(GetPathName())); theApp.WriteProfileString( L"Scape", L"Add texture directory", CString(fnDocName.FileDir())); _EngineGUI.FileRequester( "Choose textures to add", FILTER_TEX FILTER_END, "Add texture directory", "Textures\\", fnDocName.FileName()+".tex", &afnTextures); MEX mexWidth, mexHeight; m_emEditModel.edm_md.GetTextureDimensions( mexWidth, mexHeight); // add selected textures FOREACHINDYNAMICARRAY( afnTextures, CTFileName, itTexture) { CTextureDataInfo *pNewTDI; // add texture CTFileName fnTexName = itTexture.Current(); try { pNewTDI =m_emEditModel.AddTexture_t( fnTexName, mexWidth, mexHeight); } catch( char *err_str) { pNewTDI = NULL; AfxMessageBox( CString(err_str)); } if( pNewTDI != NULL) { SetModifiedFlag(); pModelerView->m_ptdiTextureDataInfo = pNewTDI; // switch to texture mode pModelerView->OnRendUseTexture(); UpdateAllViews( NULL); } } } void CModelerDoc::OnUpdateFileAddTexture(CCmdUI* pCmdUI) { CModelerView *pModelerView = CModelerView::GetActiveView(); pCmdUI->Enable( pModelerView != NULL); } CTString CModelerDoc::GetModelDirectory( void) { CTFileName fnResult = CTFileName( CTString(CStringA(GetPathName()))).FileDir(); return CTString( fnResult); } CTString CModelerDoc::GetModelName( void) { CTFileName fnResult = CTFileName( CTString(CStringA(GetPathName()))).FileName(); return CTString( fnResult); } void CModelerDoc::SelectMipModel( INDEX iMipToSelect) { m_iCurrentMip = iMipToSelect; POSITION pos = GetFirstViewPosition(); while ( pos !=NULL) { CModelerView *pmvCurrent = (CModelerView *) GetNextView(pos); pmvCurrent->m_ModelObject.SetManualMipLevel( iMipToSelect); } SpreadSurfaceSelection(); theApp.m_chGlobal.MarkChanged(); } void CModelerDoc::ClearAttachments( void) { POSITION pos = GetFirstViewPosition(); while ( pos !=NULL) { CModelerView *pmvView = (CModelerView *) GetNextView(pos); pmvView->m_ModelObject.RemoveAllAttachmentModels(); } } void CModelerDoc::SetupAttachments( void) { POSITION pos = GetFirstViewPosition(); while ( pos !=NULL) { CModelerView *pmvView = (CModelerView *) GetNextView(pos); INDEX iAttachment = 0; FOREACHINDYNAMICARRAY( m_emEditModel.edm_aamAttachedModels, CAttachedModel, itam) { m_emEditModel.edm_aamAttachedModels.Lock(); CAttachedModel *pamAttachedModel = &m_emEditModel.edm_aamAttachedModels[ iAttachment]; if( pamAttachedModel->am_bVisible) { CAttachmentModelObject *pamo = pmvView->m_ModelObject.AddAttachmentModel( iAttachment); CModelData *pMD = (CModelData *) pamAttachedModel->am_moAttachedModel.GetData(); ASSERT(pMD != NULL); pamo->amo_moModelObject.SetData( pMD); pamo->amo_moModelObject.AutoSetTextures(); pamo->amo_moModelObject.AutoSetAttachments(); pamo->amo_moModelObject.StartAnim( itam->am_iAnimation); } m_emEditModel.edm_aamAttachedModels.Unlock(); iAttachment++; } } } void CModelerDoc::ClearSurfaceSelection(void) { ModelMipInfo &mmi = m_emEditModel.edm_md.md_MipInfos[ m_iCurrentMip]; for( INDEX iSurface=0; iSurface= mmi.mmpi_MappingSurfaces.Count()) return; if( bClearRest) ClearSurfaceSelection(); MappingSurface &ms = mmi.mmpi_MappingSurfaces[ iSurface]; ms.ms_ulRenderingFlags |= SRF_SELECTED; theApp.m_chGlobal.MarkChanged(); } void CModelerDoc::SelectNextSurface(void) { ModelMipInfo &mmi = m_emEditModel.edm_md.md_MipInfos[ m_iCurrentMip]; INDEX iFirstSelected = 1; for( INDEX iSurface=0; iSurface