/* 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. */ // ModelerView.cpp : implementation of the CModelerView class // #include "stdafx.h" #include #ifdef _DEBUG #undef new #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CModelerView extern UINT APIENTRY ModelerFileRequesterHook( HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam); static TIME tmSwapBuffers = 0; static FLOAT _bSoundPlayed = FALSE; #define MIN_MODEL_DISTANCE 3 #define MAX_MODEL_DISTANCE -200 IMPLEMENT_DYNCREATE(CModelerView, CView) BEGIN_MESSAGE_MAP(CModelerView, CView) //{{AFX_MSG_MAP(CModelerView) ON_WM_DESTROY() ON_WM_MOUSEMOVE() ON_WM_LBUTTONDOWN() ON_COMMAND(ID_ANIM_PLAY, OnAnimPlay) ON_COMMAND(ID_ANIM_PREVANIM, OnAnimPrevAnim) ON_COMMAND(ID_ANIM_NEXTANIM, OnAnimNextAnim) ON_COMMAND(ID_ANIM_NEXTFRAME, OnAnimNextFrame) ON_COMMAND(ID_ANIM_PREVFRAME, OnAnimPrevFrame) ON_WM_RBUTTONDOWN() ON_UPDATE_COMMAND_UI(ID_ANIM_PLAY, OnUpdateAnimPlay) ON_UPDATE_COMMAND_UI(ID_ANIM_NEXTFRAME, OnUpdateAnimNextframe) ON_UPDATE_COMMAND_UI(ID_ANIM_PREVFRAME, OnUpdateAnimPrevframe) ON_COMMAND(ID_ANIM_CHOOSE, OnAnimChoose) ON_COMMAND(ID_ANIM_MIP_PRECIZE, OnAnimMipPrecize) ON_COMMAND(ID_ANIM_MIP_ROUGH, OnAnimMipRough) ON_UPDATE_COMMAND_UI(ID_ANIM_MIP_PRECIZE, OnUpdateAnimMipPrecize) ON_UPDATE_COMMAND_UI(ID_ANIM_MIP_ROUGH, OnUpdateAnimMipRough) ON_COMMAND(ID_OPT_AUTO_MIP_MODELING, OnOptAutoMipModeling) ON_UPDATE_COMMAND_UI(ID_OPT_AUTO_MIP_MODELING, OnUpdateOptAutoMipModeling) ON_COMMAND(ID_ANIM_ROTATION, OnAnimRotation) ON_UPDATE_COMMAND_UI(ID_ANIM_ROTATION, OnUpdateAnimRotation) ON_WM_LBUTTONUP() ON_WM_RBUTTONUP() ON_WM_SIZE() ON_WM_CONTEXTMENU() ON_COMMAND(ID_PREFS_CHANGE_INK, OnPrefsChangeInk) ON_COMMAND(ID_PREFS_CHANGE_PAPER, OnPrefsChangePaper) ON_COMMAND(ID_FILE_REMOVE_TEXTURE, OnFileRemoveTexture) ON_COMMAND(ID_SCRIPT_OPEN, OnScriptOpen) ON_COMMAND(ID_SCRIPT_UPDATE_ANIMATIONS, OnScriptUpdateAnimations) ON_COMMAND(ID_SCRIPT_UPDATE_MIPMODELS, OnScriptUpdateMipmodels) ON_COMMAND(ID_LIGHT_ON, OnLightOn) ON_COMMAND(ID_LIGHT_COLOR, OnLightColor) ON_UPDATE_COMMAND_UI(ID_LIGHT_ON, OnUpdateLightOn) ON_COMMAND(ID_REND_BBOX_ALL, OnRendBboxAll) ON_COMMAND(ID_REND_BBOX_FRAME, OnRendBboxFrame) ON_COMMAND(ID_REND_WIRE_ONOFF, OnRendWireOnoff) ON_COMMAND(ID_REND_HIDDEN_LINES, OnRendHiddenLines) ON_COMMAND(ID_REND_NO_TEXTURE, OnRendNoTexture) ON_COMMAND(ID_REND_ON_COLORS, OnRendOnColors) ON_COMMAND(ID_REND_OFF_COLORS, OnRendOffColors) ON_COMMAND(ID_REND_SURFACE_COLORS, OnRendSurfaceColors) ON_COMMAND(ID_REND_WHITE_TEXTURE, OnRendWhiteTexture) ON_COMMAND(ID_REND_USE_TEXTURE, OnRendUseTexture) ON_UPDATE_COMMAND_UI(ID_LIGHT_COLOR, OnUpdateLightColor) ON_UPDATE_COMMAND_UI(ID_MAPPING_ON, OnUpdateMappingOn) ON_UPDATE_COMMAND_UI(ID_SCRIPT_OPEN, OnUpdateScriptOpen) ON_UPDATE_COMMAND_UI(ID_SCRIPT_UPDATE_ANIMATIONS, OnUpdateScriptUpdateAnimations) ON_UPDATE_COMMAND_UI(ID_SCRIPT_UPDATE_MIPMODELS, OnUpdateScriptUpdateMipmodels) ON_UPDATE_COMMAND_UI(ID_ANIM_NEXTANIM, OnUpdateAnimNextanim) ON_UPDATE_COMMAND_UI(ID_ANIM_PREVANIM, OnUpdateAnimPrevanim) ON_UPDATE_COMMAND_UI(ID_ANIM_CHOOSE, OnUpdateAnimChoose) ON_UPDATE_COMMAND_UI(ID_FILE_REMOVE_TEXTURE, OnUpdateFileRemoveTexture) ON_COMMAND(ID_MAGNIFY_LESS, OnMagnifyLess) ON_COMMAND(ID_MAGNIFY_MORE, OnMagnifyMore) ON_COMMAND(ID_WINDOW_FIT, OnWindowFit) ON_COMMAND(ID_WINDOW_CENTER, OnWindowCenter) ON_WM_KEYDOWN() ON_WM_KEYUP() ON_COMMAND(ID_BACKGROUND_TEXTURE, OnBackgroundTexture) ON_UPDATE_COMMAND_UI(ID_REND_HIDDEN_LINES, OnUpdateRendHiddenLines) ON_UPDATE_COMMAND_UI(ID_REND_WIRE_ONOFF, OnUpdateRendWireOnoff) ON_UPDATE_COMMAND_UI(ID_REND_NO_TEXTURE, OnUpdateRendNoTexture) ON_UPDATE_COMMAND_UI(ID_REND_WHITE_TEXTURE, OnUpdateRendWhiteTexture) ON_UPDATE_COMMAND_UI(ID_REND_SURFACE_COLORS, OnUpdateRendSurfaceColors) ON_UPDATE_COMMAND_UI(ID_REND_ON_COLORS, OnUpdateRendOnColors) ON_UPDATE_COMMAND_UI(ID_REND_OFF_COLORS, OnUpdateRendOffColors) ON_UPDATE_COMMAND_UI(ID_REND_USE_TEXTURE, OnUpdateRendUseTexture) ON_UPDATE_COMMAND_UI(ID_REND_BBOX_ALL, OnUpdateRendBboxAll) ON_UPDATE_COMMAND_UI(ID_REND_BBOX_FRAME, OnUpdateRendBboxFrame) ON_COMMAND(ID_TAKE_SCREEN_SHOOT, OnTakeScreenShoot) ON_WM_KILLFOCUS() ON_COMMAND(ID_BACKG_PICTURE, OnBackgPicture) ON_COMMAND(ID_BACKG_COLOR, OnBackgColor) ON_COMMAND(ID_REND_FLOOR, OnRendFloor) ON_UPDATE_COMMAND_UI(ID_REND_FLOOR, OnUpdateRendFloor) ON_COMMAND(ID_STAINS_INSERT, OnStainsInsert) ON_COMMAND(ID_STAINS_DELETE, OnStainsDelete) ON_UPDATE_COMMAND_UI(ID_STAINS_DELETE, OnUpdateStainsDelete) ON_COMMAND(ID_STAINS_PREVIOUS_STAIN, OnStainsPreviousStain) ON_COMMAND(ID_STAINS_NEXT_STAIN, OnStainsNextStain) ON_UPDATE_COMMAND_UI(ID_STAINS_INSERT, OnUpdateStainsInsert) ON_UPDATE_COMMAND_UI(ID_STAINS_NEXT_STAIN, OnUpdateStainsNextStain) ON_UPDATE_COMMAND_UI(ID_STAINS_PREVIOUS_STAIN, OnUpdateStainsPreviousStain) ON_COMMAND(ID_SHADOW_WORSE, OnShadowWorse) ON_COMMAND(ID_SHADOW_BETTER, OnShadowBetter) ON_WM_LBUTTONDBLCLK() ON_COMMAND(ID_SAVE_THUMBNAIL, OnSaveThumbnail) ON_UPDATE_COMMAND_UI(ID_SAVE_THUMBNAIL, OnUpdateSaveThumbnail) ON_COMMAND(ID_RESTART_ANIMATIONS, OnRestartAnimations) ON_COMMAND(ID_FRAME_RATE, OnFrameRate) ON_UPDATE_COMMAND_UI(ID_FRAME_RATE, OnUpdateFrameRate) ON_COMMAND(ID_HEADING, OnHeading) ON_COMMAND(ID_PITCH, OnPitch) ON_COMMAND(ID_BANKING, OnBanking) ON_UPDATE_COMMAND_UI(ID_COLLISION_BOX, OnUpdateCollisionBox) ON_COMMAND(ID_COLLISION_BOX, OnCollisionBox) ON_COMMAND(ID_RESET_VIEWER, OnResetViewer) ON_UPDATE_COMMAND_UI(ID_RESET_VIEWER, OnUpdateResetViewer) ON_COMMAND(ID_DOLLY_VIEWER, OnDollyViewer) ON_UPDATE_COMMAND_UI(ID_DOLLY_VIEWER, OnUpdateDollyViewer) ON_COMMAND(ID_DOLLY_LIGHT, OnDollyLight) ON_UPDATE_COMMAND_UI(ID_DOLLY_LIGHT, OnUpdateDollyLight) ON_COMMAND(ID_DOLLY_LIGHT_COLOR, OnDollyLightColor) ON_UPDATE_COMMAND_UI(ID_DOLLY_LIGHT_COLOR, OnUpdateDollyLightColor) ON_COMMAND(ID_NEXT_TEXTURE, OnNextTexture) ON_UPDATE_COMMAND_UI(ID_NEXT_TEXTURE, OnUpdateNextTexture) ON_COMMAND(ID_PREVIOUS_TEXTURE, OnPreviousTexture) ON_UPDATE_COMMAND_UI(ID_PREVIOUS_TEXTURE, OnUpdatePreviousTexture) ON_COMMAND(ID_RECREATE_TEXTURE, OnRecreateTexture) ON_UPDATE_COMMAND_UI(ID_RECREATE_TEXTURE, OnUpdateRecreateTexture) ON_COMMAND(ID_CREATE_MIP_MODELS, OnCreateMipModels) ON_COMMAND(ID_PICK_VERTEX, OnPickVertex) ON_UPDATE_COMMAND_UI(ID_PICK_VERTEX, OnUpdatePickVertex) ON_COMMAND(ID_DOLLY_MIP_MODELING, OnDollyMipModeling) ON_UPDATE_COMMAND_UI(ID_DOLLY_MIP_MODELING, OnUpdateDollyMipModeling) ON_COMMAND(ID_ANIM_PLAY_ONCE, OnAnimPlayOnce) ON_UPDATE_COMMAND_UI(ID_ANIM_PLAY_ONCE, OnUpdateAnimPlayOnce) ON_COMMAND(ID_TILE_TEXTURE, OnTileTexture) ON_UPDATE_COMMAND_UI(ID_TILE_TEXTURE, OnUpdateTileTexture) ON_COMMAND(ID_ADD_REFLECTION_TEXTURE, OnAddReflectionTexture) ON_COMMAND(ID_ADD_SPECULAR, OnAddSpecular) ON_COMMAND(ID_REMOVE_REFLECTION, OnRemoveReflection) ON_UPDATE_COMMAND_UI(ID_REMOVE_REFLECTION, OnUpdateRemoveReflection) ON_COMMAND(ID_REMOVE_SPECULAR, OnRemoveSpecular) ON_UPDATE_COMMAND_UI(ID_REMOVE_SPECULAR, OnUpdateRemoveSpecular) ON_COMMAND(ID_ADD_BUMP_TEXTURE, OnAddBumpTexture) ON_COMMAND(ID_REMOVE_BUMP_MAP, OnRemoveBumpMap) ON_UPDATE_COMMAND_UI(ID_REMOVE_BUMP_MAP, OnUpdateRemoveBumpMap) ON_COMMAND(ID_MAPPING_ON, OnMappingOn) ON_COMMAND(ID_SKIN_TEXTURE, OnSkinTexture) ON_UPDATE_COMMAND_UI(ID_SKIN_TEXTURE, OnUpdateSkinTexture) ON_WM_RBUTTONDBLCLK() ON_COMMAND(ID_SURFACE_NUMBERS, OnSurfaceNumbers) ON_UPDATE_COMMAND_UI(ID_SURFACE_NUMBERS, OnUpdateSurfaceNumbers) ON_COMMAND(ID_EXPORT_SURFACES, OnExportSurfaces) ON_COMMAND(ID_PREVIOUS_BCG_TEXTURE, OnPreviousBcgTexture) ON_COMMAND(ID_NEXT_BCG_TEXTURE, OnNextBcgTexture) ON_UPDATE_COMMAND_UI(ID_PREVIOUS_BCG_TEXTURE, OnUpdatePreviousBcgTexture) ON_UPDATE_COMMAND_UI(ID_NEXT_BCG_TEXTURE, OnUpdateNextBcgTexture) ON_COMMAND(ID_WINDOW_TOGGLEMAX, OnWindowTogglemax) ON_COMMAND(ID_EXPORT_FOR_SKINING, OnExportForSkining) ON_COMMAND(ID_RENDER_SURFACES_IN_COLORS, OnRenderSurfacesInColors) ON_UPDATE_COMMAND_UI(ID_RENDER_SURFACES_IN_COLORS, OnUpdateRenderSurfacesInColors) ON_COMMAND(ID_VIEW_AXIS, OnViewAxis) ON_UPDATE_COMMAND_UI(ID_VIEW_AXIS, OnUpdateViewAxis) ON_COMMAND(ID_VIEW_INFO, OnViewInfo) ON_COMMAND(ID_LIST_ANIMATIONS, OnListAnimations) ON_UPDATE_COMMAND_UI(ID_LIST_ANIMATIONS, OnUpdateListAnimations) ON_COMMAND(ID_CHANGE_AMBIENT, OnChangeAmbient) ON_UPDATE_COMMAND_UI(ID_CHANGE_AMBIENT, OnUpdateChangeAmbient) ON_COMMAND(ID_TOGGLE_ALL_SURFACES, OnToggleAllSurfaces) ON_UPDATE_COMMAND_UI(ID_TOGGLE_ALL_SURFACES, OnUpdateToggleAllSurfaces) ON_COMMAND(ID_KEY_A, OnKeyA) ON_COMMAND(ID_KEY_T, OnKeyT) ON_COMMAND(ID_ANIM_FIRST, OnAnimFirst) ON_UPDATE_COMMAND_UI(ID_ANIM_FIRST, OnUpdateAnimFirst) ON_COMMAND(ID_ANIM_LAST, OnAnimLast) ON_UPDATE_COMMAND_UI(ID_ANIM_LAST, OnUpdateAnimLast) ON_COMMAND(ID_TOGGLE_MEASURE_VTX, OnToggleMeasureVtx) ON_UPDATE_COMMAND_UI(ID_TOGGLE_MEASURE_VTX, OnUpdateToggleMeasureVtx) ON_COMMAND(ID_FIRST_FRAME, OnFirstFrame) ON_COMMAND(ID_LAST_FRAME, OnLastFrame) //}}AFX_MSG_MAP // Standard printing commands //ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) //ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) //ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CModelerView construction/destruction CModelerView::CModelerView() { m_bViewMeasureVertex = FALSE; m_vViewMeasureVertex = FLOAT3D(0,0,0); m_atAxisType = AT_NONE; m_pmtvClosestVertex = NULL; m_bTileMappingBCG = FALSE; m_bAnyKeyPressed = FALSE; m_pDrawPort = NULL; m_pViewPort = NULL; m_InputAction = IA_NONE; m_fTargetDistance = 2.0f; m_fDollySpeedMipModeling = 2.0f; CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); CModelerView *pModelerView = DYNAMIC_DOWNCAST(CModelerView, pMainFrame->GetActiveFrame()->GetActiveView()); // If view allready exists, copy preferences if( (pModelerView != NULL) && (theApp.m_Preferences.ap_CopyExistingWindowPrefs) ) { m_bPrintSurfaceNumbers = pModelerView->m_bPrintSurfaceNumbers; m_bRenderMappingInSurfaceColors = pModelerView->m_bRenderMappingInSurfaceColors; m_bFrameRate = pModelerView->m_bFrameRate; m_AutoRotating = pModelerView->m_AutoRotating; m_iChoosedColor = pModelerView->m_iChoosedColor; m_bOnColorMode = pModelerView->m_bOnColorMode; m_IsWinBcgTexture = pModelerView->m_IsWinBcgTexture; m_FloorOn = pModelerView->m_FloorOn; m_bDollyViewer = pModelerView->m_bDollyViewer; m_bDollyMipModeling = pModelerView->m_bDollyMipModeling; m_bDollyLight = pModelerView->m_bDollyLight; m_bDollyLightColor = pModelerView->m_bDollyLightColor; m_fnBcgTexture = pModelerView->m_fnBcgTexture; m_PaperColor = pModelerView->m_PaperColor; m_InkColor = pModelerView->m_InkColor; m_ptdiTextureDataInfo = pModelerView->m_ptdiTextureDataInfo; m_LightModeOn = pModelerView->m_LightModeOn; m_bMappingMode = pModelerView->m_bMappingMode; m_bCollisionMode = pModelerView->m_bCollisionMode; m_IsMappingBcgTexture = pModelerView->m_IsMappingBcgTexture; m_fCurrentMipFactor = pModelerView->m_fCurrentMipFactor; m_iCurrentFrame = pModelerView->m_iCurrentFrame; m_LightColor = pModelerView->m_LightColor; m_colAmbientColor = pModelerView->m_colAmbientColor; m_plLightPlacement = pModelerView->m_plLightPlacement; m_plModelPlacement = pModelerView->m_plModelPlacement; m_vTarget = pModelerView->m_vTarget; m_fTargetDistance = pModelerView->m_fTargetDistance; m_angViewerOrientation = pModelerView->m_angViewerOrientation; m_RenderPrefs.SetRenderType( pModelerView->m_RenderPrefs.GetRenderType()); m_iActivePatchBitIndex = pModelerView->m_iActivePatchBitIndex; m_offx = pModelerView->m_offx; m_offy = pModelerView->m_offy; m_MagnifyFactor = pModelerView->m_MagnifyFactor; m_LightDistance = pModelerView->m_LightDistance; m_ShowAllSurfaces = pModelerView->m_ShowAllSurfaces; m_fFOW = pModelerView->m_fFOW; } else { m_bPrintSurfaceNumbers = FALSE; m_bRenderMappingInSurfaceColors = FALSE; m_bFrameRate = FALSE; m_AutoRotating = FALSE; m_iChoosedColor = 0; m_bOnColorMode = TRUE; m_IsWinBcgTexture = theApp.m_Preferences.ap_bIsBcgVisibleByDefault; m_FloorOn = theApp.m_Preferences.ap_bIsFloorVisibleByDefault; m_bDollyViewer = FALSE; m_bDollyMipModeling = FALSE; m_bDollyLight = FALSE; m_bDollyLightColor = FALSE; m_fnBcgTexture = theApp.m_Preferences.ap_DefaultWinBcgTexture; m_PaperColor = 0x98c0a0; m_InkColor = 0; m_ptdiTextureDataInfo = (CTextureDataInfo *) -1; m_LightModeOn = FALSE; m_bMappingMode = FALSE; m_bCollisionMode = FALSE; m_IsMappingBcgTexture = TRUE; m_fCurrentMipFactor = 0.0f; m_iCurrentFrame = 0; m_LightColor = 0xBFBFBF00; m_plLightPlacement.pl_PositionVector = FLOAT3D( 0.0f, 0.0f, 0.0f); // center m_plLightPlacement.pl_OrientationAngle(1) = AngleDeg( 45.0f); // heading m_plLightPlacement.pl_OrientationAngle(2) = AngleDeg( -45.0f); // pitch m_plLightPlacement.pl_OrientationAngle(3) = AngleDeg( 0.0f); // banking m_RenderPrefs.SetRenderType( RT_TEXTURE); m_RenderPrefs.SetShadowQuality( 0); m_offx = 0; m_offy = 0; m_MagnifyFactor = 0.25f; m_LightDistance = 3.5f; m_colAmbientColor = theApp.m_Preferences.ap_colDefaultAmbientColor; FLOAT fHeading = theApp.m_Preferences.ap_fDefaultHeading; FLOAT fPitch = theApp.m_Preferences.ap_fDefaultPitch; FLOAT fBanking = theApp.m_Preferences.ap_fDefaultBanking; m_fFOW = theApp.m_Preferences.ap_fDefaultFOW; m_plModelPlacement.pl_PositionVector = FLOAT3D(0.0f,0.0f,0.0f); m_plModelPlacement.pl_OrientationAngle = ANGLE3D(AngleDeg(fHeading), AngleDeg(fPitch),AngleDeg(fBanking)); m_ShowAllSurfaces = TRUE; } if( theApp.m_Preferences.ap_SetDefaultColors) { m_PaperColor = CLRF_CLR( theApp.m_Preferences.ap_DefaultPaperColor); m_InkColor = CLRF_CLR( theApp.m_Preferences.ap_DefaultInkColor); } } CModelerView::~CModelerView() { // destroy canvas that is currently used if (m_pViewPort!=NULL) { _pGfx->DestroyWindowCanvas(m_pViewPort); } } void CModelerView::ResetViewerPosition(void) { CModelerDoc* pDoc = GetDocument(); // only now we can obtain model data and set initial viewer position // get model data CModelData *pMD = &pDoc->m_emEditModel.edm_md; // obtain bounding box of all frames FLOATaabbox3D MaxBB; pMD->GetAllFramesBBox( MaxBB); // initial distance is same as of all frames's bbox diagonal vector FLOAT fModelInitialDistance = MaxBB.Size().Length(); // set initial target m_vTarget = MaxBB.Center(); // set initial target distance m_fTargetDistance = fModelInitialDistance; // set default orientation m_angViewerOrientation = ANGLE3D(AngleDeg(-10.0f),AngleDeg(-30.0f),0); } ///////////////////////////////////////////////////////////////////////////// // Routine tries to find BOOL CModelerView::AssureValidTDI() { if(m_ptdiTextureDataInfo == NULL) return FALSE; CModelerDoc* pDoc = GetDocument(); BOOL bValidTex = FALSE; FOREACHINLIST( CTextureDataInfo, tdi_ListNode, pDoc->m_emEditModel.edm_WorkingSkins, it) { if( &it.Current() == m_ptdiTextureDataInfo) { bValidTex = TRUE; break; } } if( (bValidTex == FALSE) && (!pDoc->m_emEditModel.edm_WorkingSkins.IsEmpty()) ) { m_ptdiTextureDataInfo = LIST_HEAD( pDoc->m_emEditModel.edm_WorkingSkins, CTextureDataInfo, tdi_ListNode); bValidTex = TRUE; } if( !bValidTex) { m_ptdiTextureDataInfo = NULL; } return bValidTex; } ///////////////////////////////////////////////////////////////////////////// // CModelerView drawing void CModelerView::SetProjectionData( CPerspectiveProjection3D &prProjection, CDrawPort *pDP) { prProjection.FOVL() = AngleDeg(m_fFOW); prProjection.ScreenBBoxL() = FLOATaabbox2D( FLOAT2D(0.0f,0.0f), FLOAT2D((float)pDP->GetWidth(), (float)pDP->GetHeight())); prProjection.AspectRatioL() = 1.0f; prProjection.FrontClipDistanceL() = 0.05f; prProjection.ViewerPlacementL().pl_PositionVector = m_vTarget; prProjection.ViewerPlacementL().pl_OrientationAngle = m_angViewerOrientation; prProjection.Prepare(); prProjection.ViewerPlacementL().Translate_OwnSystem(FLOAT3D( 0.0f, 0.0f, m_fTargetDistance)); } FLOAT CModelerView::GetModelToViewerDistance(void) { CPlacement3D plViewer = CPlacement3D( m_vTarget, m_angViewerOrientation); plViewer.Translate_OwnSystem(FLOAT3D( 0.0f, 0.0f, m_fTargetDistance)); FLOAT3D vDistance = plViewer.pl_PositionVector-m_plModelPlacement.pl_PositionVector; return vDistance.Length(); } void CModelerView::ClearBcg( COLOR color, CDrawPort *pDrawPort) { // delete bcg or fill it with texture CTextureObject *ptoValid = (CTextureObject *) theApp.GetValidBcgTexture( m_fnBcgTexture); if( (m_IsWinBcgTexture) && ( ptoValid != NULL) ) { PIXaabbox2D screenBox; screenBox = PIXaabbox2D( PIX2D(0,0), PIX2D(pDrawPort->GetWidth(), pDrawPort->GetHeight()) ); pDrawPort->PutTexture( ptoValid, screenBox); } else { pDrawPort->Fill(color | CT_OPAQUE); } } static BOOL TimeIsBefore(TIME tmTime, TIME tmMark, TIME tmWrap) { BOOL bBefore = FALSE; TIME tmDelta = tmTime-tmMark; if (Abs(tmDelta)0) { bBefore = !bBefore; } return bBefore; } /* * Draw a line for arrow drawing. */ static inline void DrawLine(CDrawPort &dp, const FLOAT2D &vPoint0, const FLOAT2D &vPoint1, COLOR color, ULONG ulLineType) { PIX x0 = (PIX)vPoint0(1); PIX x1 = (PIX)vPoint1(1); PIX y0 = (PIX)vPoint0(2); PIX y1 = (PIX)vPoint1(2); dp.DrawLine(x0, y0, x1, y1, color, ulLineType); } /* * Draw an arrow for debugging edge directions. */ static inline void DrawArrow(CDrawPort &dp, PIX i0, PIX j0, PIX i1, PIX j1, COLOR color, ULONG ulLineType) { FLOAT2D vPoint0 = FLOAT2D((FLOAT)i0, (FLOAT)j0); FLOAT2D vPoint1 = FLOAT2D((FLOAT)i1, (FLOAT)j1); FLOAT2D vDelta = vPoint1-vPoint0; FLOAT fDelta = vDelta.Length(); FLOAT2D vArrowLen, vArrowWidth; if (fDelta>0.01) { vArrowLen = vDelta/fDelta*FLOAT(10.0); vArrowWidth = vDelta/fDelta*FLOAT(2.0); } else { vArrowWidth = vArrowLen = FLOAT2D(0.0f, 0.0f); } Swap(vArrowWidth(1), vArrowWidth(2)); DrawLine(dp, vPoint0, vPoint1, color, ulLineType); DrawLine(dp, vPoint1-vArrowLen+vArrowWidth, vPoint1, color, ulLineType); DrawLine(dp, vPoint1-vArrowLen-vArrowWidth, vPoint1, color, ulLineType); } INDEX _iTextLine = 0; void CModelerView::DrawArrowAndTypeText(CPerspectiveProjection3D &prProjection, const FLOAT3D &v0, const FLOAT3D &v1, COLOR colColor, CTString strText) { m_pDrawPort->SetFont( theApp.m_pfntFont); // get transformed end vertices FLOAT3D tv0, tv1; prProjection.PreClip(v0, tv0); prProjection.PreClip(v1, tv1); // clip the edge line FLOAT3D vClipped0 = tv0; FLOAT3D vClipped1 = tv1; ULONG ulClipFlags = prProjection.ClipLine(vClipped0, vClipped1); // if the edge remains after clipping to front plane if (ulClipFlags != LCF_EDGEREMOVED) { // project the vertices FLOAT3D v3d0, v3d1; prProjection.PostClip(vClipped0, v3d0); prProjection.PostClip(vClipped1, v3d1); // make 2d vertices FLOAT2D v2d0, v2d1; v2d0(1) = v3d0(1); v2d0(2) = v3d0(2); v2d1(1) = v3d1(1); v2d1(2) = v3d1(2); if( (Abs(v2d1(1)-v2d0(1)) > 8) || (Abs(v2d1(2)-v2d0(2)) > 8) ) { // draw arrow-headed line between vertices DrawArrow( *m_pDrawPort, (PIX)v2d0(1), (PIX)v2d0(2), (PIX)v2d1(1), (PIX)v2d1(2), colColor, _FULL_); // type text over line if( strText != "") { m_pDrawPort->SetFont( theApp.m_pfntFont); m_pDrawPort->PutTextCXY( strText, v2d1(1)-8, v2d1(2)-16); } } } } void CModelerView::RenderAxis( CPerspectiveProjection3D &prProjection, CPlacement3D &pl, FLOAT fSize) { // get rotation matrix FLOATmatrix3D mRot; MakeRotationMatrixFast( mRot, pl.pl_OrientationAngle); // get axis defining vertices FLOAT3D vCenter = pl.pl_PositionVector; FLOAT3D vX = FLOAT3D( fSize, 0.0f, 0.0f); FLOAT3D vY = FLOAT3D( 0.0f, fSize, 0.0f); FLOAT3D vZ = FLOAT3D( 0.0f, 0.0f, fSize); FLOAT3D vRotX = vCenter+vX*mRot; FLOAT3D vRotY = vCenter+vY*mRot; FLOAT3D vRotZ = vCenter-vZ*mRot; // project vertices and render axis arrows DrawArrowAndTypeText( prProjection, vCenter, vRotX, C_RED|CT_OPAQUE, "X"); DrawArrowAndTypeText( prProjection, vCenter, vRotY, C_RED|CT_OPAQUE, "Y"); DrawArrowAndTypeText( prProjection, vCenter, vRotZ, C_RED|CT_OPAQUE, "-Z"); } CStaticStackArray _armRenderModels; void CModelerView::RenderAxisOfAllAttachments(CPerspectiveProjection3D &prProjection, CPlacement3D &plParent, CModelObject &mo) { // create render model structure of parent CRenderModel *prmParent = &_armRenderModels.Push(); CAnyProjection3D apr; apr = prProjection; BeginModelRenderingView(apr, m_pDrawPort); prmParent->SetObjectPlacement( plParent); mo.SetupModelRendering(*prmParent); EndModelRenderingView(); // for each attachment on this model object FOREACHINLIST( CAttachmentModelObject, amo_lnInMain, mo.mo_lhAttachments, itamo) { // create new render model structure itamo->amo_prm = &_armRenderModels.Push(); // obtain attachment's data mo.CreateAttachment(*prmParent, *itamo); // create placement of attachment (child) ANGLE3D a3dAnglesChild; DecomposeRotationMatrix(a3dAnglesChild, itamo->amo_prm->rm_mObjectRotation); CPlacement3D plChild = CPlacement3D( itamo->amo_prm->rm_vObjectPosition, a3dAnglesChild); // recurse RenderAxisOfAllAttachments( prProjection, plChild, itamo->amo_moModelObject); // don't render non-initialized attachments CModelData *pmd = (CModelData *) itamo->amo_moModelObject.GetData(); if( pmd == NULL) continue; // obtain bounding box of attachment FLOATaabbox3D box; pmd->GetAllFramesBBox( box); FLOAT fSize = Clamp(box.Size().Length()/6.0f, 0.125f, 10.0f); RenderAxis( prProjection, plChild, fSize); } // all done _armRenderModels.PopAll(); } void CModelerView::RenderView( CDrawPort *pDrawPort) { CMainFrame* pmf = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); FLOATplane3D plFloorPlane; CModelerDoc* pDoc = GetDocument(); CModelData *pMD = &pDoc->m_emEditModel.edm_md; CTextureData *pTD, *pOldTD; INDEX i; // set effect textures (if they exist in edit model) try { if( m_ModelObject.mo_toReflection.GetName() != pDoc->m_emEditModel.edm_fnReflectionTexture) m_ModelObject.mo_toReflection.SetData_t( pDoc->m_emEditModel.edm_fnReflectionTexture); } catch (char *strError) { (void) strError;} try { if( m_ModelObject.mo_toSpecular.GetName() != pDoc->m_emEditModel.edm_fnSpecularTexture) m_ModelObject.mo_toSpecular.SetData_t( pDoc->m_emEditModel.edm_fnSpecularTexture); } catch (char *strError) { (void) strError;} try { if( m_ModelObject.mo_toBump.GetName() != pDoc->m_emEditModel.edm_fnBumpTexture) m_ModelObject.mo_toBump.SetData_t( pDoc->m_emEditModel.edm_fnBumpTexture); } catch (char *strError) { (void) strError;} // Calculate light position in absolute sytem CModelInfo MI; FLOATaabbox3D MaxBB; if( m_ModelObject.GetData() == NULL) return; m_ModelObject.GetModelInfo( MI); // info describing our model (not light) for( i=0; itdi_TextureData; if( pTD != m_ModelObject.mo_toTexture.GetData()) { m_ModelObject.mo_toTexture.SetData( pTD); } } else { m_ModelObject.mo_toTexture.SetData( NULL); ULONG CurrentTextureType = m_RenderPrefs.GetRenderType(); // no need to revert to white-texture mode, renderer with handle NULL texture just fine // if( CurrentTextureType&RT_TEXTURE) // m_RenderPrefs.SetTextureType( RT_WHITE_TEXTURE); // } } MEX mexWidth, mexHeight; mexWidth = m_ModelObject.GetWidth(); mexHeight = m_ModelObject.GetHeight(); FLOAT3D FloorVtx1 = FLOAT3D( -6.0f, 0.0f, -6.0f); FLOAT3D FloorVtx2 = FLOAT3D( -6.0f, 0.0f, 6.0f); FLOAT3D FloorVtx3 = FLOAT3D( 6.0f, 0.0f, 6.0f); FLOAT3D FloorVtx4 = FLOAT3D( 6.0f, 0.0f, -6.0f); // make floor plane from three of floor's vertices plFloorPlane = FLOATplane3D( FloorVtx1, FloorVtx2, FloorVtx3); pDrawPort->FillZBuffer( ZBUF_BACK); ClearBcg( CLR_CLRF( m_PaperColor), pDrawPort); if( !m_bMappingMode) { // get current frame for info window m_iCurrentFrame = m_ModelObject.GetFrame(); INDEX iAnim = m_ModelObject.GetAnim(); CAttachedSound &asSound = pDoc->m_emEditModel.edm_aasAttachedSounds[iAnim]; TIME tmAnimLen = m_ModelObject.GetAnimLength(iAnim); TIME tmPassed = m_ModelObject.GetPassedTime(); BOOL bNowIsBeforeDelay = TimeIsBefore(tmPassed, asSound.as_fDelay, tmAnimLen); if(bNowIsBeforeDelay) _bSoundPlayed = FALSE; if( (asSound.as_fnAttachedSound != "") && (asSound.as_bPlaying) ) { if( !_bSoundPlayed && !bNowIsBeforeDelay ) { try { pDoc->m_soSoundObject.Stop(); pDoc->m_soSoundObject.SetVolume( SL_VOLUME_MAX, SL_VOLUME_MAX); if( asSound.as_bLooping) pDoc->m_soSoundObject.Play_t( asSound.as_fnAttachedSound, SOF_LOOP); else pDoc->m_soSoundObject.Play_t( asSound.as_fnAttachedSound, 0); _bSoundPlayed = TRUE; } catch( char *strError) { (void) strError; //WarningMessage( strError); } } } // make perspective projection for lamp rendering CPerspectiveProjection3D prPerspectiveProjection; if( m_FloorOn) { // floor model and its texture must be valid ASSERT( theApp.m_pFloorModelObject != NULL); ASSERT( theApp.m_ptdFloorTexture != NULL); // initialize projection SetProjectionData( prPerspectiveProjection, pDrawPort); // set floor box's stretch factor theApp.m_pFloorModelObject->mo_Stretch = FLOAT3D( 1.0f, 1.0f, 1.0f); // set texture rendering mode and phong shading _mrpModelRenderPrefs.SetRenderType( RT_TEXTURE|RT_SHADING_PHONG); // render floor model // prepare render model structure CRenderModel rmRenderModel; CAnyProjection3D apr; apr = prPerspectiveProjection; BeginModelRenderingView(apr, pDrawPort); // set light placement rmRenderModel.rm_vLightDirection = -plLightPlacement.pl_PositionVector; // set color of light rmRenderModel.rm_colLight = m_LightColor; rmRenderModel.rm_colAmbient = m_colAmbientColor; // set floor's placement and orientation rmRenderModel.SetObjectPlacement( CPlacement3D(ANGLE3D( 0, 0, 0), FLOAT3D( 0.0f, 0.0f, 0.0f))); // render floor theApp.m_pFloorModelObject->SetupModelRendering(rmRenderModel); theApp.m_pFloorModelObject->RenderModel(rmRenderModel); EndModelRenderingView(); } // set current color rendering preferences m_RenderPrefs.SetInkColor( CLR_CLRF( m_InkColor)); m_RenderPrefs.SetPaperColor( CLR_CLRF( m_PaperColor)); // copy local (view's) rendering preferences over global model rendering preferences _mrpModelRenderPrefs = m_RenderPrefs; // set projection data SetProjectionData( prPerspectiveProjection, pDrawPort); // prepare render model structure CRenderModel rmRenderModel; CAnyProjection3D apr; apr = prPerspectiveProjection; BeginModelRenderingView(apr, pDrawPort); // set light placement rmRenderModel.rm_vLightDirection = m_plModelPlacement.pl_PositionVector - plLightPlacement.pl_PositionVector; // set color of light rmRenderModel.rm_colLight = m_LightColor; rmRenderModel.rm_colAmbient = m_colAmbientColor; // obtain translation speed value CString csSpeed; pmf->m_ctrlZSpeed.GetWindowText( csSpeed); CTString strSpeed = CStringA(csSpeed); FLOAT fSpeed; BOOL bSpeedValid = strSpeed.ScanF( "%g", &fSpeed); // obtain loop value CString csLoop; pmf->m_ctrlZLoop.GetWindowText( csLoop); CTString strLoop = CStringA(csLoop); INDEX iLoop; BOOL bLoopValid = strLoop.ScanF( "%d", &iLoop); // simulate translation along z-axis CPlacement3D plTranslated = m_plModelPlacement; if( bLoopValid && bSpeedValid && fSpeed!=0 && iLoop>0 && !m_ModelObject.IsPaused()) { TIME tmPassed = _pTimer->CurrentTick() - m_ModelObject.ao_tmAnimStart; TIME tmDuration = m_ModelObject.GetCurrentAnimLength(); if( tmPassed>tmDuration*iLoop) { tmPassed = 0; m_ModelObject.ResetAnim(); } plTranslated.pl_PositionVector(3) += -fSpeed*(tmPassed-tmDuration); } // set position of document's model rmRenderModel.SetObjectPlacement(plTranslated); // initialize rendering of document's model m_ModelObject.SetupModelRendering( rmRenderModel); // get current mip factor m_fCurrentMipFactor = rmRenderModel.rm_fMipFactor; // if model is visible if( m_ModelObject.IsModelVisible( m_fCurrentMipFactor) || (m_InputAction == IA_MIP_RANGING)) { // if floor is on if( m_FloorOn) { // render shadow of document's model m_ModelObject.RenderShadow( rmRenderModel, plLightPlacement, 20.0f, 0.0f, 1.0f, plFloorPlane); } // render document's model m_ModelObject.RenderModel( rmRenderModel); } // get current mip model pDoc->m_iCurrentMip = m_ModelObject.mo_iLastRenderMipLevel; EndModelRenderingView(); // if lamp mode is on or allways see lamp flag is set on and if lamp model exist if( (m_LightModeOn || theApp.m_Preferences.ap_AllwaysSeeLamp) && (theApp.m_pLampModelData != NULL)) { // set projection data SetProjectionData( prPerspectiveProjection, pDrawPort); // set light beam's surface color same as current light color theApp.m_LampModelObject->SetSurfaceColor( 0, 2, m_LightColor | CT_OPAQUE); // set these modele rendering preferences: surface colors, no shadows, no bounding boxes _mrpModelRenderPrefs.SetRenderType( RT_TEXTURE|RT_SHADING_PHONG); _mrpModelRenderPrefs.SetShadowQuality( 0); _mrpModelRenderPrefs.BBoxFrameShow(FALSE); _mrpModelRenderPrefs.BBoxAllShow(FALSE); _mrpModelRenderPrefs.SetInkColor( 0x55000000); // prepare render model structure CRenderModel rmRenderModel; CAnyProjection3D apr; apr = prPerspectiveProjection; BeginModelRenderingView(apr, pDrawPort); // set color of shading light rmRenderModel.rm_colLight = C_WHITE|CT_OPAQUE; rmRenderModel.rm_colAmbient = C_dGRAY|CT_OPAQUE; // set shading light placement rmRenderModel.rm_vLightDirection = FLOAT3D( 1.0f, 1.0f, 1.0f); // set placement of lamp model rmRenderModel.SetObjectPlacement(plLightPlacement); // render lamp rendering theApp.m_LampModelObject->SetupModelRendering(rmRenderModel); theApp.m_LampModelObject->RenderModel(rmRenderModel); EndModelRenderingView(); } // test if we are in collision mode if( m_bCollisionMode) { // collision box model and its texture must be valid ASSERT( theApp.m_pCollisionBoxModelObject != NULL); ASSERT( theApp.m_ptdCollisionBoxTexture != NULL); // initialize projection SetProjectionData( prPerspectiveProjection, pDrawPort); FLOAT3D vMin = pDoc->m_emEditModel.GetCollisionBoxMin(); FLOAT3D vMax = pDoc->m_emEditModel.GetCollisionBoxMax(); // get collision bounding box FLOATaabbox3D bbCollision( vMin,vMax); // set collision box's stretch factor theApp.m_pCollisionBoxModelObject->mo_Stretch = bbCollision.Size(); // set wire and hiden lines along with texture rendering mode and shiny shading _mrpModelRenderPrefs.SetRenderType( RT_WIRE_ON|RT_HIDDEN_LINES|RT_TEXTURE|RT_SHADING_PHONG); // render collision box // obtain collision box offset vector CPlacement3D plRotatedCollisionBoxOffset = CPlacement3D( bbCollision.Center(), ANGLE3D( 0,0,0)); // convert collision box center into model coordinate system plRotatedCollisionBoxOffset.RelativeToAbsolute( m_plModelPlacement); // prepare render model structure CRenderModel rmRenderModel; // set converted collision box's placement rmRenderModel.SetObjectPlacement(plRotatedCollisionBoxOffset); CAnyProjection3D apr; apr = prPerspectiveProjection; BeginModelRenderingView(apr, pDrawPort); // set placement of shading light rmRenderModel.rm_vLightDirection = m_plModelPlacement.pl_PositionVector-plLightPlacement.pl_PositionVector; // set color of shading light rmRenderModel.rm_colLight = m_LightColor; rmRenderModel.rm_colAmbient = m_colAmbientColor; // render collision box model theApp.m_pCollisionBoxModelObject->SetupModelRendering(rmRenderModel); theApp.m_pCollisionBoxModelObject->RenderModel(rmRenderModel); EndModelRenderingView(); } if( m_bViewMeasureVertex) { // prepare the projection CPerspectiveProjection3D prProjection; SetProjectionData( prProjection, pDrawPort); prProjection.ObjectPlacementL() = CPlacement3D(FLOAT3D(0,0,0), ANGLE3D(0,0,0)); prProjection.Prepare(); FLOAT3D v3D; prProjection.ProjectCoordinate(m_vViewMeasureVertex, v3D); // convert y coordinate from mathemathical representation into screen one v3D(2) = pDrawPort->GetHeight()- v3D(2); FLOAT2D v2D; v2D(1)=v3D(1); v2D(2)=v3D(2); DrawLine(*pDrawPort, v2D-FLOAT2D(5,0), v2D+FLOAT2D(5,0), C_RED|CT_OPAQUE, _FULL_); DrawLine(*pDrawPort, v2D-FLOAT2D(0,5), v2D+FLOAT2D(0,5), C_RED|CT_OPAQUE, _FULL_); } // if we should render axis if( m_atAxisType != AT_NONE) { // prepare the projection CPerspectiveProjection3D prProjection; SetProjectionData( prProjection, pDrawPort); prProjection.ObjectPlacementL() = CPlacement3D(FLOAT3D(0,0,0), ANGLE3D(0,0,0)); prProjection.Prepare(); // see if we should render only axis of main model { FLOATaabbox3D box; pMD->GetAllFramesBBox( box); CPlacement3D pl = plTranslated; FLOAT fSize = Clamp(box.Size().Length()/6.0f, 0.5f, 10.0f); RenderAxis( prProjection, pl, fSize); } if( m_atAxisType == AT_ALL) { // render recursivly all attachments and their attachments,... RenderAxisOfAllAttachments( prProjection, plTranslated, m_ModelObject); _armRenderModels.PopAll(); } _iTextLine = 0; } } // mapping mode else { MEX mexWidth, mexHeight; // pick up model's texture dimensions mexWidth = m_ModelObject.GetWidth(); mexHeight = m_ModelObject.GetHeight(); PIX pixRight = (PIX) (mexWidth * m_MagnifyFactor); PIX pixDown = (PIX) (mexHeight * m_MagnifyFactor); ClearBcg( theApp.m_Preferences.ap_MappingWinBcgColor, pDrawPort); // set position of texture on screen PIXaabbox2D boxScreen( PIX2D(-m_offx, -m_offy),PIX2D(-m_offx + pixRight, -m_offy + pixDown)); // set no valid texture mode CTextureData *pTD = NULL; CTextureData *pOldTD; pOldTD = (CTextureData *) m_ModelObject.mo_toTexture.GetData(); // try to get model's exsiting texture if( AssureValidTDI()) { pTD = m_ptdiTextureDataInfo->tdi_TextureData; if(pTD != m_ModelObject.mo_toTexture.GetData()) { m_ModelObject.mo_toTexture.SetData( pTD); } } // if there are no textures in this model else { m_ModelObject.mo_toTexture.SetData( NULL); } if( (m_IsMappingBcgTexture) && (pTD != NULL) ) { if( !m_bTileMappingBCG) { MEXaabbox2D boxTexture(MEX2D(0,0), MEX2D(mexWidth-1, mexHeight-1)); pDrawPort->PutTexture(&m_ModelObject.mo_toTexture, boxScreen, boxTexture); } else { PIX pixSizeI = pDrawPort->GetWidth(); PIX pixSizeJ = pDrawPort->GetHeight(); MEXaabbox2D boxTexture(MEX2D(0,0), MEX2D(mexWidth-1, mexHeight-1)); PIX pixDI = boxScreen.Size()(1); MEX mexDU = boxTexture.Size()(1); FLOAT fMexOverPix = mexDU/FLOAT(pixDI); MEX mexU0 = MEX(-boxScreen.Min()(1)*fMexOverPix); MEX mexV0 = MEX(-boxScreen.Min()(2)*fMexOverPix); MEX mexU1 = MEX(mexU0+pixSizeI*fMexOverPix); MEX mexV1 = MEX(mexV0+pixSizeJ*fMexOverPix); pDrawPort->PutTexture( &m_ModelObject.mo_toTexture, PIXaabbox2D(PIX2D(0,0), PIX2D( pixSizeI, pixSizeJ)), MEXaabbox2D(MEX2D( mexU0, mexV0), MEX2D( mexU1, mexV1))); } } else { pDrawPort->Fill( boxScreen.Min() (1), boxScreen.Min() (2), boxScreen.Size()(1), boxScreen.Size()(2), theApp.m_Preferences.ap_MappingPaperColor | CT_OPAQUE); } // render patches CModelData *pMD = &pDoc->m_emEditModel.edm_md; ModelMipInfo *pMMI = &pMD->md_MipInfos[ pDoc->m_iCurrentMip]; // if pathes are not hidden for this mip model if( pMMI->mmpi_ulFlags & MM_PATCHES_VISIBLE) { INDEX iExistingPatch=0; // for each possible patch for( INDEX iMaskBit=0; iMaskBitmd_mpPatches[iMaskBit].mp_toTexture.GetData(); // if current patch exists and is turned on if( (ptdPatch != NULL) && (m_ModelObject.GetPatchesMask() & ((1UL) << iMaskBit)) ) { MEX mexPatchU = pMD->md_mpPatches[iMaskBit].mp_mexPosition(1); MEX mexPatchV = pMD->md_mpPatches[iMaskBit].mp_mexPosition(2); PIX pixPatchUMin = (PIX) (mexPatchU * m_MagnifyFactor - m_offx); PIX pixPatchVMin = (PIX) (mexPatchV * m_MagnifyFactor - m_offy); PIX pixPatchUMax = (PIX) ((mexPatchU+ptdPatch->GetWidth()*pMD->md_mpPatches[iMaskBit].mp_fStretch) * m_MagnifyFactor - m_offx); PIX pixPatchVMax = (PIX) ((mexPatchV+ptdPatch->GetHeight()*pMD->md_mpPatches[iMaskBit].mp_fStretch) * m_MagnifyFactor - m_offy); PIXaabbox2D screenBox = PIXaabbox2D( PIX2D(pixPatchUMin, pixPatchVMin),PIX2D(pixPatchUMax, pixPatchVMax)); pDrawPort->PutTexture( &pMD->md_mpPatches[iMaskBit].mp_toTexture, screenBox); } } } // draw unselected surfaces ModelMipInfo &mmi = pDoc->m_emEditModel.edm_md.md_MipInfos[ pDoc->m_iCurrentMip]; if( m_bRenderMappingInSurfaceColors) { for( INDEX iSurface=0; iSurfacem_emEditModel.DrawFilledSurface( pDrawPort, pDoc->m_iCurrentMip, iSurface, m_MagnifyFactor, m_offx, m_offy, ms.ms_colColor, ms.ms_colColor); } } if( m_ShowAllSurfaces) { for( INDEX iSurface=0; iSurfacem_emEditModel.DrawWireSurface( pDrawPort, pDoc->m_iCurrentMip, iSurface, m_MagnifyFactor, m_offx, m_offy, theApp.m_Preferences.ap_MappingInactiveSurfaceColor, theApp.m_Preferences.ap_MappingInactiveSurfaceColor); } } // draw selected surfaces for( INDEX iSurface=0; iSurfacem_emEditModel.DrawWireSurface( pDrawPort, pDoc->m_iCurrentMip, iSurface, m_MagnifyFactor, m_offx, m_offy, theApp.m_Preferences.ap_MappingActiveSurfaceColor, C_RED); } // if we should print surface numbers if( m_bPrintSurfaceNumbers) { pDoc->m_emEditModel.PrintSurfaceNumbers( pDrawPort, theApp.m_pfntFont, pDoc->m_iCurrentMip, m_MagnifyFactor, m_offx, m_offy, C_BLACK); } } } void CModelerView::OnDraw(CDC* pDC) { CModelerDoc* pDoc = GetDocument(); CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); ASSERT_VALID(pDoc); // ARGH!! I hate these two lines, very, very bad coding but can You do it better? if( !pDoc->m_bDocLoadedOk) return; // render view if drawport is valid if( m_pDrawPort!=NULL && m_pDrawPort->Lock()) { CTimerValue tvStart = _pTimer->GetHighPrecisionTimer(); RenderView( m_pDrawPort); m_udViewPicture.MarkUpdated(); CTimerValue tvStop = _pTimer->GetHighPrecisionTimer(); TIME tmDelta = (tvStop-tvStart).GetSeconds() +tmSwapBuffers; // should we print frame rate? if( m_bFrameRate) { // prepare string about things that impact to currently rendered picture CTString strFPS, strReport; STAT_Report( strReport); STAT_Reset(); // adjust and set font m_pDrawPort->SetFont( _pfdConsoleFont); m_pDrawPort->SetTextScaling( 1.0f); // put filter PIX pixDPHeight = m_pDrawPort->GetHeight(); m_pDrawPort->Fill( 0,0, 150,pixDPHeight, C_BLACK|128, C_BLACK|0, C_BLACK|192, C_BLACK|0); // printout statistics strFPS.PrintF( " %3.0f FPS (%2.0f ms)\n----------------\n", 1.0f/tmDelta, tmDelta*1000.0f); m_pDrawPort->PutText( strFPS, 0, 5, C_lCYAN|CT_OPAQUE); m_pDrawPort->PutText( strReport, 4, 30, C_GREEN|CT_OPAQUE); } m_pDrawPort->Unlock(); // swap if there is a valid viewport if( m_pViewPort!=NULL) { tvStart = _pTimer->GetHighPrecisionTimer(); m_pViewPort->SwapBuffers(); tvStop = _pTimer->GetHighPrecisionTimer(); tmSwapBuffers = (tvStop-tvStart).GetSeconds(); } } // no draw port ? else { // just fill window CRect rectFillArea; pDC->GetWindow()->GetClientRect(rectFillArea); pDC->FillSolidRect( rectFillArea, GetSysColor( COLOR_APPWORKSPACE)); } // get active view CModelerView *pActiveView = DYNAMIC_DOWNCAST(CModelerView, pMainFrame->GetActiveFrame()->GetActiveView()); if( pActiveView == this) { INDEX iSurface = pDoc->GetOnlySelectedSurface(); if( iSurface != -1) { // line of text char achrLine[ 256]; achrLine[ 0] = 0; // prepare pane text line sprintf( achrLine, "%s", pDoc->m_emEditModel.GetSurfaceName( pDoc->m_iCurrentMip, iSurface)); // print active surface pMainFrame->m_wndStatusBar.SetPaneText( ACTIVE_SURFACE_PANE, CString(achrLine)); } } _pSound->UpdateSounds(); } ///////////////////////////////////////////////////////////////////////////// // CModelerView printing BOOL CModelerView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CModelerView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CModelerView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CModelerView diagnostics #ifdef _DEBUG void CModelerView::AssertValid() const { CView::AssertValid(); } void CModelerView::Dump(CDumpContext& dc) const { CView::Dump(dc); } CModelerDoc* CModelerView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CModelerDoc))); return (CModelerDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CModelerView message handlers void CModelerView::OnInitialUpdate() { CView::OnInitialUpdate(); // at this time, m_hWnd is valid, so we do canvas initialization here _pGfx->CreateWindowCanvas(m_hWnd, &m_pViewPort, &m_pDrawPort); CModelerDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); m_ModelObject.SetData( &pDoc->m_emEditModel.edm_md); m_ModelObject.SetAnim( 0); m_iActivePatchBitIndex = 0; pDoc->m_emEditModel.GetFirstValidPatchIndex( m_iActivePatchBitIndex); if( !pDoc->m_emEditModel.edm_WorkingSkins.IsEmpty()) { m_ptdiTextureDataInfo = LIST_HEAD( pDoc->m_emEditModel.edm_WorkingSkins, CTextureDataInfo, tdi_ListNode); } // set default viewer position ResetViewerPosition(); pDoc->ClearAttachments(); pDoc->SetupAttachments(); } void CModelerView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); // if window canvas is valid, resize it if( m_pViewPort!=NULL) m_pViewPort->Resize(); theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnDestroy() { CView::OnDestroy(); } //-------------------------------------------------------------------------------------------- void CModelerView::OnMouseMove(UINT nFlags, CPoint point) { // line of text char achrLine[ 256]; achrLine[ 0] = 0; CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); pMainFrame->EnableSound(); m_MousePosition = point; CModelerDoc *pDoc = (CModelerDoc *) GetDocument(); CPoint offset = point - m_MouseDownLocation; FLOAT fDistance = -m_fTargetDistance; CPlacement3D plViewer; plViewer.pl_PositionVector = m_vTarget; plViewer.pl_OrientationAngle = m_angViewerOrientation; // moving offsets need small amounts FLOAT dx = 0.001f * offset.x * fDistance; FLOAT dy = 0.001f * offset.y * fDistance; FLOAT dz = 0.01f * offset.y * fDistance; // angles need lot for rotation ANGLE dAngleX = AngleDeg( -0.5f * offset.x); ANGLE dAngleY = AngleDeg( -0.5f * offset.y); /* ANGLE dAngleX = AngleDeg( 0.5f * offset.x * fDistance); ANGLE dAngleY = AngleDeg( 0.5f * offset.y * fDistance); */ switch( m_InputAction) { case IA_MOVING_MEASURE_VERTEX: { CPlacement3D plMeasureVtx = CPlacement3D(m_vViewMeasureVertex, ANGLE3D(0,0,0)); plMeasureVtx.AbsoluteToRelative( plViewer); plMeasureVtx.Translate_AbsoluteSystem( FLOAT3D( -dx, dy, 0.0f)); plMeasureVtx.RelativeToAbsolute( plViewer); m_vViewMeasureVertex = plMeasureVtx.pl_PositionVector; //m_vTarget = m_vViewMeasureVertex; break; } case IA_MOVING_MODEL: { // project the placement to the viewer's system m_plModelPlacement.AbsoluteToRelative( plViewer); // translate it m_plModelPlacement.Translate_AbsoluteSystem( FLOAT3D( -dx, dy, 0.0f)); // project the placement back from viewer's system m_plModelPlacement.RelativeToAbsolute( plViewer); theApp.m_chPlacement.MarkChanged(); break; } case IA_MOVING_VIEWER: { CPlacement3D plTarget; plTarget.pl_PositionVector = m_vTarget; plTarget.pl_OrientationAngle = m_angViewerOrientation; // project the placement to the viewer's system plTarget.AbsoluteToRelative( plViewer); // translate it plTarget.Translate_AbsoluteSystem( FLOAT3D( dx, -dy, 0.0f)); // project the placement back from viewer's system plTarget.RelativeToAbsolute( plViewer); m_vTarget = plTarget.pl_PositionVector; theApp.m_chPlacement.MarkChanged(); break; } case IA_ZOOMING_MODEL: { CPlacement3D plNew = m_plModelPlacement; // project the placement to the viewer's system plNew.AbsoluteToRelative( plViewer); // translate it plNew.Translate_AbsoluteSystem( FLOAT3D( -dx, 0.0f, -dz)); // project the placement back from viewer's system plNew.RelativeToAbsolute( plViewer); m_plModelPlacement = plNew; theApp.m_chPlacement.MarkChanged(); break; } case IA_ZOOMING_MEASURE_VERTEX: { CPlacement3D plMeasureVtx = CPlacement3D(m_vViewMeasureVertex, ANGLE3D(0,0,0)); plMeasureVtx.AbsoluteToRelative( plViewer); plMeasureVtx.Translate_AbsoluteSystem( FLOAT3D( -dx, 0.0f, -dz)); plMeasureVtx.RelativeToAbsolute( plViewer); m_vViewMeasureVertex = plMeasureVtx.pl_PositionVector; //m_vTarget = m_vViewMeasureVertex; break; } case IA_ZOOMING_VIEWER: { // move target away m_fTargetDistance += dz; // now apply left/right movement CPlacement3D plTarget; plTarget.pl_PositionVector = m_vTarget; plTarget.pl_OrientationAngle = m_angViewerOrientation; // project the placement to the viewer's system plTarget.AbsoluteToRelative( plViewer); // translate it plTarget.Translate_AbsoluteSystem( FLOAT3D( dx, 0.0f, 0.0f)); // project the placement back from viewer's system plTarget.RelativeToAbsolute( plViewer); m_vTarget = plTarget.pl_PositionVector; // update view theApp.m_chPlacement.MarkChanged(); break; } case IA_MIP_RANGING: { // can't come closer, only traveling away is allowed if( offset.y > 0) { break; } m_fTargetDistance += dz; // update view theApp.m_chGlobal.MarkChanged(); break; } case IA_ZOOMING_LIGHT: { float fNewDistance = m_LightDistance - dz; if( fNewDistance > 0.2f) { m_LightDistance = fNewDistance; } theApp.m_chPlacement.MarkChanged(); break; } case IA_ROTATING_MODEL: { // project the placement to the viewer's system m_plModelPlacement.AbsoluteToRelative( plViewer); // rotate it m_plModelPlacement.Rotate_TrackBall( ANGLE3D( -dAngleX, -dAngleY, 0)); // project the placement back from viewer's system m_plModelPlacement.RelativeToAbsolute( plViewer); theApp.m_chPlacement.MarkChanged(); break; } case IA_ROTATING_VIEWER: { // initialize viewer's orientation CPlacement3D plOrientation; plOrientation.pl_PositionVector = FLOAT3D( 0.0f, 0.0f, 0.0f); plOrientation.pl_OrientationAngle = m_angViewerOrientation; // project the placement to the viewer's system plOrientation.AbsoluteToRelative( plViewer); // rotate it plOrientation.Rotate_TrackBall( ANGLE3D( dAngleX, dAngleY, 0)); // project the placement back from viewer's system plOrientation.RelativeToAbsolute( plViewer); // copy it back to viewer m_angViewerOrientation = plOrientation.pl_OrientationAngle; // update view theApp.m_chPlacement.MarkChanged(); break; } case IA_ROTATING_LIGHT: { // project the placement to the viewer's system m_plLightPlacement.AbsoluteToRelative( plViewer); // rotate it m_plLightPlacement.Rotate_TrackBall( ANGLE3D( -dAngleX/2, -dAngleY/2, 0)); // project the placement back from viewer's system m_plLightPlacement.RelativeToAbsolute( plViewer); theApp.m_chPlacement.MarkChanged(); break; } case IA_MOVING_MAPPING: { PIX new_offx = m_offx - offset.x; PIX new_offy = m_offy - offset.y; m_offx = new_offx; m_offy = new_offy; theApp.m_chPlacement.MarkChanged(); break; } case IA_MOVING_PATCH: { pDoc->m_emEditModel.MovePatchRelative( m_iActivePatchBitIndex, MEX2D( (MEX)(offset.x/m_MagnifyFactor), (MEX)(offset.y/m_MagnifyFactor))); pDoc->UpdateAllViews( NULL); pDoc->m_emEditModel.edm_md.md_bPreparedForRendering = FALSE; pDoc->SetModifiedFlag(); break; } case IA_ZOOMING_PATCH: { CModelPatch &mp = pDoc->m_emEditModel.edm_md.md_mpPatches[ m_iActivePatchBitIndex]; FLOAT fNewStretch = mp.mp_fStretch + offset.y * m_MagnifyFactor/150.0f; pDoc->m_emEditModel.SetPatchStretch(m_iActivePatchBitIndex, fNewStretch); pDoc->m_emEditModel.edm_md.md_bPreparedForRendering = FALSE; theApp.m_bRefreshPatchPalette = TRUE; pDoc->UpdateAllViews( NULL); pDoc->SetModifiedFlag(); break; } case IA_ZOOMING_MAPPING: { float NewMagnifyFactor = m_MagnifyFactor + offset.y * m_MagnifyFactor/150.0f; if( (NewMagnifyFactor > 1/32768.0f) && (NewMagnifyFactor < 8.0f) ) { MEX mexWidth, mexHeight; mexWidth = m_ModelObject.GetWidth(); mexHeight = m_ModelObject.GetHeight(); PIX pixOldWidth = (PIX) (mexWidth * m_MagnifyFactor); PIX pixOldHeight = (PIX) (mexHeight * m_MagnifyFactor); PIX pixNewWidth = (PIX) (mexWidth * NewMagnifyFactor); PIX pixNewHeight = (PIX) (mexHeight * NewMagnifyFactor); PIX pixDPWidth = m_pDrawPort->GetWidth(); PIX pixDPHeight = m_pDrawPort->GetHeight(); FLOAT fMagnifyDelta = NewMagnifyFactor/m_MagnifyFactor; PIX pixDCX = pixDPWidth/2 + m_offx; PIX pixDCY = pixDPHeight/2 + m_offy; m_offx = -(pixDPWidth/2 - pixDCX*fMagnifyDelta); m_offy = -(pixDPHeight/2 - pixDCY*fMagnifyDelta); m_MagnifyFactor = NewMagnifyFactor; theApp.m_chPlacement.MarkChanged(); } break; } default: { } } HWND hwndUnderMouse = ::WindowFromPoint( point); HWND hwndInfo = NULL; if( pMainFrame->m_pInfoFrame != NULL) hwndInfo = pMainFrame->m_pInfoFrame->m_hWnd; if( (m_hWnd != ::GetActiveWindow()) && ( hwndInfo != hwndUnderMouse) ) { SetActiveWindow(); SetFocus(); GetParentFrame()->SetActiveView( this); pMainFrame->MDIActivate(GetParentFrame()); } m_MouseDownLocation = point; } void CModelerView::MagnifyMapping(CPoint point, FLOAT fMagnification) { PIX pixDPWidth = m_pDrawPort->GetWidth(); PIX pixDPHeight = m_pDrawPort->GetHeight(); if( fMagnification > 1.0f) { // center clicked point m_offx += point.x - pixDPWidth/2; m_offy += point.y - pixDPHeight/2; } // correct offset for zoom PIX pixDCX = pixDPWidth/2 + m_offx; PIX pixDCY = pixDPHeight/2 + m_offy; m_offx = -(pixDPWidth/2 - pixDCX*fMagnification); m_offy = -(pixDPHeight/2 - pixDCY*fMagnification); m_MagnifyFactor *= fMagnification; theApp.m_chPlacement.MarkChanged(); Invalidate( FALSE); if( fMagnification > 1.0f) { // center cursor CPoint ptCenter; ptCenter.x = pixDPWidth/2; ptCenter.y = pixDPHeight/2; ClientToScreen( &ptCenter); SetCursorPos(ptCenter.x, ptCenter.y); } } void CModelerView::FastZoomIn( CPoint point) { if( m_bMappingMode) { MagnifyMapping(point, 2.0f); } else { OnMagnifyMore(); } } void CModelerView::FastZoomOut() { if( m_bMappingMode) { MagnifyMapping( CPoint(0,0), 0.5f); } else { OnMagnifyLess(); } } //-------------------------------------------------------------------------------------------- void CModelerView::OnLButtonDown(UINT nFlags, CPoint point) { CModelerDoc *pDoc = (CModelerDoc *) GetDocument(); BOOL bSpace = (GetKeyState( ' ') & 128) != 0; BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0; BOOL bCtrl = nFlags & MK_CONTROL; BOOL bShift = nFlags & MK_SHIFT; BOOL bLMB = nFlags & MK_LBUTTON; BOOL bRMB = nFlags & MK_RBUTTON; m_InputAction = IA_NONE; // ctrl+space+XMB is used for 2x zooming if( bCtrl && bSpace) { FastZoomIn( point); return; } // in mapping mode if( m_bMappingMode) { // LMB+space is used for mapping moving if( bSpace) { m_InputAction = IA_MOVING_MAPPING; } // Ctrl is used for moving patch else if( bCtrl) { m_InputAction = IA_MOVING_PATCH; } } // model view mode else { // shift operations control light if( bShift && bRMB) { m_InputAction = IA_ROTATING_LIGHT; } // alt colorizes surface else if( bAlt) { CPerspectiveProjection3D prProjection; SetProjectionData( prProjection, m_pDrawPort); // set position of document's model prProjection.ObjectPlacementL() = m_plModelPlacement; m_ModelObject.ColorizePolygon( m_pDrawPort, &prProjection, point.x, point.y, m_iChoosedColor, m_bOnColorMode); pDoc->m_emEditModel.edm_md.md_bPreparedForRendering = FALSE; pDoc->SetModifiedFlag(); Invalidate( FALSE); } // control operations are used for changing model placement else if( bCtrl) { if(m_bViewMeasureVertex) { m_InputAction = IA_MOVING_MEASURE_VERTEX; } else { m_InputAction = IA_MOVING_MODEL; } } // space operations are used for changing viewer placement else if( bSpace && bRMB ) { m_InputAction = IA_ROTATING_VIEWER; } else if( bSpace) { m_InputAction = IA_MOVING_VIEWER; } } m_MouseDownLocation = point; CView::OnLButtonDown(nFlags, point); } //-------------------------------------------------------------------------------------------- void CModelerView::OnRButtonDown(UINT nFlags, CPoint point) { CModelerDoc *pDoc = (CModelerDoc *) GetDocument(); BOOL bSpace = (GetKeyState( ' ') & 128) != 0; BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0; BOOL bCtrl = nFlags & MK_CONTROL; BOOL bShift = nFlags & MK_SHIFT; BOOL bLMB = nFlags & MK_LBUTTON; m_InputAction = IA_NONE; // ctrl+space+XMB is used for 2x zooming if( bCtrl && bSpace) { FastZoomOut(); return; } // if mapping mode if( m_bMappingMode) { // RMB + space is used for zooming mapping if( bSpace) { m_InputAction = IA_ZOOMING_MAPPING; } else if( bCtrl) { // Ctrl is used for zooming patch m_InputAction = IA_ZOOMING_PATCH; } else { m_InputAction = IA_CONTEXT_MENU; } } // model view mode else { // ctrl+shift start mip ranging if( bCtrl && bShift) { m_InputAction = IA_MIP_RANGING; // We will turn auto-mip modeling off but before that we have to set current auto mip // model as activ one (because of possible mip-modeling off situation) m_ModelObject.AutoMipModelingOn(); pDoc->SelectMipModel( m_ModelObject.GetMipModel( m_fCurrentMipFactor)); m_ModelObject.AutoMipModelingOff(); m_ModelObject.SetManualMipLevel( pDoc->m_iCurrentMip); // find center of all frames bbox FLOATaabbox3D MaxBB; m_ModelObject.GetAllFramesBBox( MaxBB); // look at the origin of model m_vTarget = m_plModelPlacement.pl_PositionVector; // move view up for half of model's max bbox m_vTarget(2) += MaxBB.Center()(2); // prepare projection to get viewer's placement CPerspectiveProjection3D prProjection; SetProjectionData( prProjection, m_pDrawPort); // update view Invalidate( FALSE); } // shift operations control light else if( bShift && bLMB) { m_InputAction = IA_ROTATING_LIGHT; } else if( bShift) { m_InputAction = IA_ZOOMING_LIGHT; } // space operaties with viewer position else if( bSpace && bLMB) { m_InputAction = IA_ROTATING_VIEWER; } else if( bSpace) { m_InputAction = IA_ZOOMING_VIEWER; } // ctrl operaties with model position else if( bCtrl && bLMB) { m_InputAction = IA_ROTATING_MODEL; } else if( bCtrl) { if(m_bViewMeasureVertex) { m_InputAction = IA_ZOOMING_MEASURE_VERTEX; } else { m_InputAction = IA_ZOOMING_MODEL; } } else { m_InputAction = IA_CONTEXT_MENU; } } m_MouseDownLocation = point; CView::OnRButtonDown(nFlags, point); } //-------------------------------------------------------------------------------------------- void CModelerView::OnLButtonUp(UINT nFlags, CPoint point) { CModelerDoc *pDoc = (CModelerDoc *) GetDocument(); m_pmtvClosestVertex = NULL; m_InputAction = IA_NONE; CView::OnLButtonUp(nFlags, point); } //-------------------------------------------------------------------------------------------- void CModelerView::OnRButtonUp(UINT nFlags, CPoint point) { CModelerDoc *pDoc = (CModelerDoc *) GetDocument(); if( m_InputAction == IA_MIP_RANGING) { pDoc->SetModifiedFlag(); // prepare the projection CPerspectiveProjection3D prProjection; SetProjectionData( prProjection, m_pDrawPort); prProjection.Prepare(); // set current mip factor as switch factor for current mip model m_ModelObject.SetMipSwitchFactor( pDoc->m_iCurrentMip, m_fCurrentMipFactor); CModelData *pMD = (CModelData *) m_ModelObject.GetData(); // spread switch factors of rougher mip models proportionally up to maximum // default factor pMD->SpreadMipSwitchFactors( pDoc->m_iCurrentMip + 1, m_fCurrentMipFactor); m_ModelObject.AutoMipModelingOn(); theApp.m_chGlobal.MarkChanged(); // update info page CDlgInfoFrame *pInfoFrame = ((CMainFrame *)( theApp.m_pMainWnd))->m_pInfoFrame; if( pInfoFrame == NULL) return; CDlgInfoPgMip *pDlgMip = &pInfoFrame->m_pInfoSheet->m_PgInfoMip; if( !::IsWindow(pDlgMip->m_hWnd)) return; pDlgMip->UpdateData( FALSE); } CView::OnRButtonUp(nFlags, point); } //-------------------------------------------------------------------------------------------- // restart animation for all attachments recursivly void PlayAnimForAllAttachments( CModelObject &mo, ULONG ulFlags) { FOREACHINLIST( CAttachmentModelObject, amo_lnInMain, mo.mo_lhAttachments, itamo) { PlayAnimForAllAttachments( itamo->amo_moModelObject, ulFlags); mo.ResetAnim(); mo.PlayAnim( mo.GetAnim(), ulFlags); } } void PauseAnimForAllAttachments( CModelObject &mo) { FOREACHINLIST( CAttachmentModelObject, amo_lnInMain, mo.mo_lhAttachments, itamo) { PauseAnimForAllAttachments( itamo->amo_moModelObject); mo.PauseAnim(); } } void CModelerView::OnAnimNextAnim() { m_ModelObject.NextAnim(); if( m_ModelObject.IsPaused()) { m_ModelObject.ao_tmAnimStart = 0; } } void CModelerView::OnAnimPrevAnim() { m_ModelObject.PrevAnim(); if( m_ModelObject.IsPaused()) { m_ModelObject.ao_tmAnimStart = 0; } } void CModelerView::OnAnimPlay() { if( m_ModelObject.IsPaused()) { m_ModelObject.PlayAnim( m_ModelObject.GetAnim(), AOF_LOOPING|AOF_NORESTART); PlayAnimForAllAttachments( m_ModelObject, AOF_LOOPING|AOF_NORESTART); } else { m_ModelObject.PauseAnim(); PauseAnimForAllAttachments( m_ModelObject); } } void CModelerView::OnFirstFrame() { if( !m_ModelObject.IsPaused()) { m_ModelObject.PauseAnim(); } m_ModelObject.FirstFrame(); } void CModelerView::OnLastFrame() { if( !m_ModelObject.IsPaused()) { m_ModelObject.PauseAnim(); } m_ModelObject.LastFrame(); } void CModelerView::OnAnimNextFrame() { if( !m_ModelObject.IsPaused()) { m_ModelObject.PauseAnim(); } m_ModelObject.NextFrame(); } void CModelerView::OnAnimPrevFrame() { if( !m_ModelObject.IsPaused()) { m_ModelObject.PauseAnim(); } m_ModelObject.PrevFrame(); } void CModelerView::OnUpdateAnimPlay(CCmdUI* pCmdUI) { if( m_bMappingMode) pCmdUI->Enable( FALSE); else if (m_ModelObject.IsPaused()) { pCmdUI->SetCheck(0); } else { pCmdUI->SetCheck(1); } } void CModelerView::OnRestartAnimations() { // get current animation index INDEX iMdlCurrentAnim = m_ModelObject.GetAnim(); // restart model's animation m_ModelObject.StartAnim( iMdlCurrentAnim); // retrieve current model's texture CTextureData *pTD = (CTextureData *) m_ModelObject.mo_toTexture.GetData(); // if model has texture if( pTD != NULL) { // get model's texture animation index INDEX iTexCurrentAnim = m_ModelObject.mo_toTexture.GetAnim(); // restart model's texture's animation m_ModelObject.mo_toTexture.StartAnim( iTexCurrentAnim); } } void CModelerView::OnUpdateAnimNextframe(CCmdUI* pCmdUI) { if( m_bMappingMode) pCmdUI->Enable( FALSE); else pCmdUI->Enable(TRUE); } void CModelerView::OnUpdateAnimPrevframe(CCmdUI* pCmdUI) { if( m_bMappingMode) pCmdUI->Enable( FALSE); else pCmdUI->Enable(TRUE); } void CModelerView::OnIdle(void) { if( m_AutoRotating) { TIME timeNow = _pTimer->GetRealTimeTick(); TIME tmDelta = timeNow-m_timeLastTick; m_plModelPlacement.pl_OrientationAngle( 1) -= AngleDeg(160.0f*tmDelta); theApp.m_chPlacement.MarkChanged(); m_timeLastTick = timeNow; } FLOAT fTimeVar1 = ((FLOAT)_pTimer->GetRealTimeTick()) / 1.5f; FLOAT fTimeVar2 = ((FLOAT)_pTimer->GetRealTimeTick()) * 0.8f; FLOAT fTimeVar3 = ((FLOAT)_pTimer->GetRealTimeTick()) * 1.8f; if( m_bDollyViewer) { m_fTargetDistance += (FLOAT)sin( fTimeVar1)/10; m_angViewerOrientation(1) += AngleDeg( 10.0f); m_angViewerOrientation(2) = AngleDeg( DegAngle(m_angViewerOrientation(2)) + (FLOAT)sin(fTimeVar1)/2.0f); theApp.m_chPlacement.MarkChanged(); } if( m_bDollyMipModeling) { if( m_fTargetDistance >= 100.0f) { m_fDollySpeedMipModeling = -2.0f; } else if( m_fTargetDistance <= 3.0f) { m_fDollySpeedMipModeling = 2.0f; } FLOAT fCorrector = 0.0f; if( m_fTargetDistance<20.0f) { FLOAT fAbsDistance = Abs(m_fTargetDistance); fCorrector = (22.5f-fAbsDistance)/20.0f; } m_fTargetDistance += m_fDollySpeedMipModeling-m_fDollySpeedMipModeling*fCorrector; theApp.m_chPlacement.MarkChanged(); } if( m_bDollyLight) { m_plLightPlacement.pl_OrientationAngle(1) += AngleDeg( 6.0f); m_plLightPlacement.pl_OrientationAngle(2) = AngleDeg( DegAngle(m_plLightPlacement.pl_OrientationAngle(2)) + (FLOAT)sin(fTimeVar3)*4.0f); theApp.m_chPlacement.MarkChanged(); } if( m_bDollyLightColor) { UBYTE ubRed = 128+((BYTE)(sin( fTimeVar1)*127)); UBYTE ubGreen = 128+((BYTE)(sin( fTimeVar2)*127)); UBYTE ubBlue = 128+((BYTE)(sin( fTimeVar3)*127)); m_LightColor = ((ULONG)ubRed)<<24 | ((ULONG)ubGreen)<<16 | ((ULONG)ubBlue)<<8; theApp.m_chPlacement.MarkChanged(); } BOOL bUpdate = !( m_ModelObject.IsPaused() && m_ModelObject.IsUpToDate(m_udViewPicture) && theApp.m_chGlobal.IsUpToDate(m_udViewPicture) && theApp.m_chPlacement.IsUpToDate(m_udViewPicture) && (m_ModelObject.GetPatchesMask() == 0) ); CTextureData *pTD = (CTextureData *) m_ModelObject.mo_toTexture.GetData(); if( (pTD != NULL) && (pTD->td_ctFrames > 1) ) bUpdate = TRUE; if( bUpdate) { Invalidate( FALSE); } } void CModelerView::OnAnimChoose() { CDChooseAnim dlg( &m_ModelObject); dlg.DoModal(); Invalidate( FALSE); } void CModelerView::OnAnimMipPrecize() { CModelerDoc* pDoc = GetDocument(); m_ModelObject.PrevManualMipLevel(); pDoc->SelectMipModel( m_ModelObject.GetMipModel( m_fCurrentMipFactor)); theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnAnimMipRough() { CModelerDoc* pDoc = GetDocument(); m_ModelObject.NextManualMipLevel(); pDoc->SelectMipModel( m_ModelObject.GetMipModel( m_fCurrentMipFactor)); //pDoc->SelectMipModel( pDoc->m_iCurrentMip); theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnUpdateAnimMipPrecize(CCmdUI* pCmdUI) { if( m_ModelObject.IsAutoMipModeling()) pCmdUI->Enable(FALSE); else pCmdUI->Enable(TRUE); } void CModelerView::OnUpdateAnimMipRough(CCmdUI* pCmdUI) { if( m_ModelObject.IsAutoMipModeling()) pCmdUI->Enable(FALSE); else pCmdUI->Enable(TRUE); } void CModelerView::OnOptAutoMipModeling() { if( m_ModelObject.IsAutoMipModeling()) m_ModelObject.AutoMipModelingOff(); else m_ModelObject.AutoMipModelingOn(); theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnUpdateOptAutoMipModeling(CCmdUI* pCmdUI) { if( m_bMappingMode) pCmdUI->Enable( FALSE); else pCmdUI->Enable( TRUE); pCmdUI->SetCheck( m_ModelObject.IsAutoMipModeling()); } void CModelerView::OnAnimRotation() { m_timeLastTick = _pTimer->GetRealTimeTick(); m_AutoRotating = !m_AutoRotating; } void CModelerView::OnUpdateAnimRotation(CCmdUI* pCmdUI) { if( m_bMappingMode) pCmdUI->Enable( FALSE); pCmdUI->SetCheck( m_AutoRotating); } CModelerView *CModelerView::GetActiveView(void) { CModelerView *res; CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); res = DYNAMIC_DOWNCAST(CModelerView, pMainFrame->GetActiveFrame()->GetActiveView()); if( (res != NULL) && (res->m_bMappingMode) ) return NULL; return res; } CModelerView *CModelerView::GetActiveMappingView(void) { CModelerView *res; CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); res = DYNAMIC_DOWNCAST(CModelerView, pMainFrame->GetActiveFrame()->GetActiveView()); if( (res != NULL) && (res->m_bMappingMode) ) return res; return NULL; } CModelerView *CModelerView::GetActiveMappingNormalView(void) { CModelerView *pModelerView = GetActiveView(); if( pModelerView == NULL) return GetActiveMappingView(); return pModelerView; } void CModelerView::OnContextMenu(CWnd* pWnd, CPoint point) { CMenu menu; if( m_bMappingMode) { if( (m_InputAction == IA_CONTEXT_MENU) && (menu.LoadMenu(IDR_MAPPING_VIEW_POPUP))) { CMenu* pPopup = menu.GetSubMenu(0); ASSERT(pPopup != NULL); pPopup->TrackPopupMenu(TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_LEFTALIGN, point.x, point.y, this); } } else { if( (m_InputAction == IA_CONTEXT_MENU) && (menu.LoadMenu(IDR_MODEL_VIEW_POPUP))) { CMenu* pPopup = menu.GetSubMenu(0); ASSERT(pPopup != NULL); if( m_RenderPrefs.BBoxFrameVisible()) pPopup->CheckMenuItem(ID_REND_BBOX_FRAME, MF_CHECKED); if( m_RenderPrefs.BBoxAllVisible()) pPopup->CheckMenuItem(ID_REND_BBOX_ALL, MF_CHECKED); if( m_RenderPrefs.WireOn()) pPopup->CheckMenuItem(ID_REND_WIRE_ONOFF, MF_CHECKED); if( m_RenderPrefs.HiddenLines()) pPopup->CheckMenuItem(ID_REND_HIDDEN_LINES, MF_CHECKED); ULONG rtRenderType = m_RenderPrefs.GetRenderType(); if( (rtRenderType & RT_NO_POLYGON_FILL) != 0) pPopup->CheckMenuItem( ID_REND_NO_TEXTURE, MF_CHECKED); if( (rtRenderType & RT_WHITE_TEXTURE) != 0) pPopup->CheckMenuItem( ID_REND_WHITE_TEXTURE, MF_CHECKED); if( (rtRenderType & RT_SURFACE_COLORS) != 0) pPopup->CheckMenuItem( ID_REND_SURFACE_COLORS, MF_CHECKED); if( (rtRenderType & RT_ON_COLORS) != 0) pPopup->CheckMenuItem( ID_REND_ON_COLORS, MF_CHECKED); if( (rtRenderType & RT_OFF_COLORS) != 0) pPopup->CheckMenuItem( ID_REND_OFF_COLORS, MF_CHECKED); if( (rtRenderType & RT_TEXTURE) != 0) pPopup->CheckMenuItem( ID_REND_USE_TEXTURE, MF_CHECKED); if( (rtRenderType & RT_SHADING_NONE) != 0) pPopup->CheckMenuItem( ID_REND_SHADING_NONE, MF_CHECKED); if( (rtRenderType & RT_SHADING_LAMBERT) != 0) pPopup->CheckMenuItem( ID_REND_SHADING_LAMBERT, MF_CHECKED); if( (rtRenderType & RT_SHADING_PHONG) != 0) pPopup->CheckMenuItem( ID_REND_PHONG, MF_CHECKED); pPopup->TrackPopupMenu(TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_LEFTALIGN, point.x, point.y, this); } } m_InputAction = IA_NONE; } BOOL MyChooseColor( COLORREF &clrNewColor, CWnd &wndOwner) { COLORREF MyCustColors[ 16]; CHOOSECOLOR ccInit; ASSERT( &wndOwner != NULL); MyCustColors[ 0] = CLRF_CLR(C_BLACK); MyCustColors[ 1] = CLRF_CLR(C_WHITE); MyCustColors[ 2] = CLRF_CLR(C_dGRAY); MyCustColors[ 3] = CLRF_CLR(C_GRAY); MyCustColors[ 4] = CLRF_CLR(C_lGRAY); MyCustColors[ 5] = CLRF_CLR(C_dRED); MyCustColors[ 6] = CLRF_CLR(C_dGREEN); MyCustColors[ 7] = CLRF_CLR(C_dBLUE); MyCustColors[ 8] = CLRF_CLR(C_dCYAN); MyCustColors[ 9] = CLRF_CLR(C_dMAGENTA); MyCustColors[10] = CLRF_CLR(C_dYELLOW); MyCustColors[11] = CLRF_CLR(C_dORANGE); MyCustColors[12] = CLRF_CLR(C_dBROWN); MyCustColors[13] = CLRF_CLR(C_dPINK); MyCustColors[14] = CLRF_CLR(C_lORANGE); MyCustColors[15] = CLRF_CLR(C_lBROWN); memset(&ccInit, 0, sizeof(CHOOSECOLOR)); ccInit.lStructSize = sizeof(CHOOSECOLOR); ccInit.Flags = CC_RGBINIT | CC_FULLOPEN; ccInit.rgbResult = clrNewColor; ccInit.lpCustColors = &MyCustColors[ 0]; ccInit.hwndOwner = wndOwner.m_hWnd; if( !ChooseColor( &ccInit)) return FALSE; clrNewColor = ccInit.rgbResult; return TRUE; } void CModelerView::OnPrefsChangeInk() { if( MyChooseColor( m_InkColor, *GetParent())) { Invalidate( FALSE); } } void CModelerView::OnPrefsChangePaper() { if( MyChooseColor( m_PaperColor, *GetParent())) { Invalidate( FALSE); } } void CModelerView::OnFileRemoveTexture() { // remove curently selected skin texture CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); CModelerDoc *pDoc = (CModelerDoc *) GetDocument(); ASSERT( pDoc->m_emEditModel.edm_WorkingSkins.Count() != 0); CTextureDataInfo *ptdiSelected = NULL; INDEX iCurSel = pMainFrame->m_SkinComboBox.GetCurSel(); INDEX iIter = 0; FOREACHINLIST( CTextureDataInfo, tdi_ListNode, pDoc->m_emEditModel.edm_WorkingSkins, it) { if( iCurSel == iIter) { ptdiSelected = &it.Current(); break; } iIter++; } _pTextureStock->Release( ptdiSelected->tdi_TextureData); ptdiSelected->tdi_ListNode.Remove(); delete ptdiSelected; Invalidate( FALSE); } void CModelerView::OnScriptOpen() { CModelerDoc *pDoc = (CModelerDoc *) GetDocument(); CTFileName fnDocName = CTString(CStringA(pDoc->GetPathName())); AfxGetApp()->OpenDocumentFile( CString(fnDocName.FileDir() + fnDocName.FileName() + ".scr")); } void CModelerView::OnScriptUpdateAnimations() { UpdateAnimations(); } BOOL CModelerView::UpdateAnimations(void) { CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); CModelerDoc *pDoc = (CModelerDoc *) GetDocument(); CTFileName fnModelName = CTString(CStringA(pDoc->GetPathName())); CTFileName fnScriptName = fnModelName.FileDir() + fnModelName.FileName() + ".scr"; pDoc->OnSaveDocument( pDoc->GetPathName()); try { fnScriptName.RemoveApplicationPath_t(); pMainFrame->m_NewProgress.Create( IDD_NEW_PROGRESS, pMainFrame); pMainFrame->m_NewProgress.CenterWindow(); pMainFrame->m_NewProgress.ShowWindow(SW_SHOW); pDoc->m_emEditModel.UpdateAnimations_t( fnScriptName); } catch( char *str_err) { pMainFrame->m_NewProgress.DestroyWindow(); pDoc->OnCloseDocument(); // explicit delete on error AfxMessageBox( CString(str_err)); return FALSE; } pMainFrame->m_NewProgress.DestroyWindow(); pDoc->m_emEditModel.edm_md.md_bPreparedForRendering = FALSE; pDoc->SetModifiedFlag(); pMainFrame->m_AnimComboBox.m_pvLastUpdatedView = NULL; theApp.m_chGlobal.MarkChanged(); return TRUE; } void CModelerView::OnScriptUpdateMipmodels() { CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); CModelerDoc *pDoc = (CModelerDoc *) GetDocument(); CTFileName fnModelName = CTString(CStringA(pDoc->GetPathName())); CTFileName fnScriptName = fnModelName.FileDir() + fnModelName.FileName() + ".scr"; if( ::MessageBoxA( this->m_hWnd, "Updating mip-models will discard current mip-model mapping " "and colorizing data. Are you sure that you want that?", "Warning !", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON1| MB_SYSTEMMODAL | MB_TOPMOST) == IDYES) { try { fnScriptName.RemoveApplicationPath_t(); pMainFrame->m_NewProgress.Create( IDD_NEW_PROGRESS, pMainFrame); pMainFrame->m_NewProgress.CenterWindow(); pMainFrame->m_NewProgress.ShowWindow(SW_SHOW); pDoc->m_emEditModel.UpdateMipModels_t( fnScriptName); } catch( char *str_err) { AfxMessageBox( CString(str_err)); } } pMainFrame->m_NewProgress.DestroyWindow(); pDoc->m_emEditModel.edm_md.md_bPreparedForRendering = FALSE; pDoc->SetModifiedFlag(); theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnLightOn() { if( !m_bMappingMode) { m_LightModeOn = !m_LightModeOn; Invalidate( FALSE); } } void CModelerView::OnLightColor() { COLORREF TmpColor = CLRF_CLR( m_LightColor); if( MyChooseColor( TmpColor, *GetParent())) { m_LightColor = CLR_CLRF( TmpColor); Invalidate( FALSE); } } void CModelerView::OnUpdateLightOn(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); pCmdUI->SetCheck( m_LightModeOn); } void CModelerView::OnUpdateLightColor(CCmdUI* pCmdUI) { if( m_bMappingMode) pCmdUI->Enable( FALSE); } void CModelerView::OnRendBboxAll() { m_RenderPrefs.BBoxAllShow( !m_RenderPrefs.BBoxAllVisible()); GetDocument()->UpdateAllViews( NULL); } void CModelerView::OnRendBboxFrame() { m_RenderPrefs.BBoxFrameShow( !m_RenderPrefs.BBoxFrameVisible()); GetDocument()->UpdateAllViews( NULL); } void CModelerView::OnRendWireOnoff() { m_RenderPrefs.SetWire( !m_RenderPrefs.WireOn()); GetDocument()->UpdateAllViews( NULL); } void CModelerView::OnRendHiddenLines() { m_RenderPrefs.SetHiddenLines( !m_RenderPrefs.HiddenLines()); GetDocument()->UpdateAllViews( NULL); } void CModelerView::OnRendNoTexture() { m_RenderPrefs.SetTextureType( RT_NO_POLYGON_FILL); GetDocument()->UpdateAllViews( NULL); } void CModelerView::OnRendOnColors() { m_RenderPrefs.SetTextureType( RT_ON_COLORS); GetDocument()->UpdateAllViews( NULL); } void CModelerView::OnRendOffColors() { m_RenderPrefs.SetTextureType( RT_OFF_COLORS); GetDocument()->UpdateAllViews( NULL); } void CModelerView::OnRendSurfaceColors() { m_RenderPrefs.SetTextureType( RT_SURFACE_COLORS); GetDocument()->UpdateAllViews( NULL); } void CModelerView::OnRendWhiteTexture() { m_RenderPrefs.SetTextureType( RT_WHITE_TEXTURE); GetDocument()->UpdateAllViews( NULL); } void CModelerView::OnRendUseTexture() { m_RenderPrefs.SetTextureType( RT_TEXTURE); GetDocument()->UpdateAllViews( NULL); } void CModelerView::OnMappingOn() { // if we are going into mapping mode if( !m_bMappingMode) { // remember auto mip modeling flag m_bAutoMipModelingBeforeMapping = m_ModelObject.IsAutoMipModeling(); // turn off auto mip modeling m_ModelObject.AutoMipModelingOff(); } else { // restore auto mip modeling flag if( m_bAutoMipModelingBeforeMapping) m_ModelObject.AutoMipModelingOn(); else m_ModelObject.AutoMipModelingOff(); } m_bMappingMode = !m_bMappingMode; Invalidate( FALSE); } void CModelerView::OnUpdateMappingOn(CCmdUI* pCmdUI) { pCmdUI->SetCheck( m_bMappingMode); } void CModelerView::OnUpdateScriptOpen(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); } void CModelerView::OnUpdateScriptUpdateAnimations(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); } void CModelerView::OnUpdateScriptUpdateMipmodels(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); } void CModelerView::OnUpdateAnimNextanim(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); } void CModelerView::OnUpdateAnimPrevanim(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); } void CModelerView::OnUpdateAnimChoose(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); } void CModelerView::OnUpdateFileRemoveTexture(CCmdUI* pCmdUI) { CModelerDoc *pDoc = (CModelerDoc *) GetDocument(); INDEX ctSkins = pDoc->m_emEditModel.edm_WorkingSkins.Count(); pCmdUI->Enable( !m_bMappingMode && (ctSkins!=0) ); } void CModelerView::OnMagnifyLess() { BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0; if( m_bMappingMode) { if( m_MagnifyFactor > 1.0/16384.0) { m_MagnifyFactor /= 2.0f; if( bAlt) { OnWindowFit(); } } } else if( m_fTargetDistance < 65535.0f) { m_fTargetDistance *= 2.0f; } theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnMagnifyMore() { BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0; if( m_bMappingMode) { if(m_MagnifyFactor < 4) { m_MagnifyFactor *= 2.0f; if( bAlt) { OnWindowFit(); } } } else if( m_fTargetDistance > 1.0f) { m_fTargetDistance /= 2.0f; } theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnWindowFit() { if( m_bMappingMode && !GetParent()->IsZoomed()) { MEX mexWidth, mexHeight; mexWidth = m_ModelObject.GetWidth(); mexHeight = m_ModelObject.GetHeight(); PIX pixLeft = -m_offx; PIX pixUp = -m_offy; PIX pixWidth = (PIX) (mexWidth * m_MagnifyFactor); PIX pixHeight = (PIX) (mexHeight * m_MagnifyFactor); CRect rectClient; CRect rectNewPos; CWnd *pWnd = GetParent(); // view's window pWnd->GetParent()->GetClientRect( rectClient); // size of whole working area window pWnd->GetWindowRect( rectNewPos); // size of view's window pWnd->GetParent()->ScreenToClient( rectNewPos); // view's window size relative to working area rectNewPos.left += pixLeft; if( rectNewPos.left < 0) rectNewPos.left = 0; m_offx = 0; rectNewPos.top += pixUp; if( rectNewPos.top < 0) rectNewPos.top = 0; m_offy = 0; rectNewPos.right = rectNewPos.left + pixWidth + 12; if( rectNewPos.right > rectClient.right) rectNewPos.right = rectClient.right; rectNewPos.bottom = rectNewPos.top + pixHeight + 31; if( rectNewPos.bottom > rectClient.bottom) rectNewPos.bottom = rectClient.bottom; pWnd->MoveWindow( rectNewPos, TRUE); theApp.m_chGlobal.MarkChanged(); } } void CModelerView::OnWindowCenter() { if( m_bMappingMode) { MEX mexWidth, mexHeight; mexWidth = m_ModelObject.GetWidth(); mexHeight = m_ModelObject.GetHeight(); PIX pixRight = (PIX) (mexWidth * m_MagnifyFactor); PIX pixDown = (PIX) (mexHeight * m_MagnifyFactor); PIX WinW, WinH; WinW = m_pDrawPort->GetWidth(); WinH = m_pDrawPort->GetHeight(); m_offx = -( WinW - pixRight)/2; m_offy = -( WinH - pixDown)/2; theApp.m_chGlobal.MarkChanged(); } else { OnCollisionBox(); } } void CModelerView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { CView::OnKeyDown(nChar, nRepCnt, nFlags); } void CModelerView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { if( m_InputAction != IA_MIP_RANGING) { m_InputAction = IA_NONE; } CView::OnKeyUp(nChar, nRepCnt, nFlags); } void CModelerView::OnListAnimations() { CDChooseAnim dlg( &m_ModelObject); dlg.DoModal(); Invalidate(FALSE); } void CModelerView::OnUpdateListAnimations(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); } void CModelerView::OnUpdateSkinTexture(CCmdUI* pCmdUI) { pCmdUI->Enable( m_bMappingMode); } void CModelerView::OnSkinTexture() { m_IsMappingBcgTexture = !m_IsMappingBcgTexture; } void CModelerView::OnBackgroundTexture() { m_IsWinBcgTexture = !m_IsWinBcgTexture; Invalidate(FALSE); } void CModelerView::OnUpdateRendHiddenLines(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); pCmdUI->SetCheck( m_RenderPrefs.HiddenLines()); } void CModelerView::OnUpdateRendWireOnoff(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); pCmdUI->SetCheck( m_RenderPrefs.WireOn()); } void CModelerView::OnUpdateRendNoTexture(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); pCmdUI->SetCheck( (m_RenderPrefs.GetRenderType() & RT_NO_POLYGON_FILL) != 0); } void CModelerView::OnUpdateRendWhiteTexture(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); pCmdUI->SetCheck( (m_RenderPrefs.GetRenderType() & RT_WHITE_TEXTURE) != 0); } void CModelerView::OnUpdateRendSurfaceColors(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); pCmdUI->SetCheck( (m_RenderPrefs.GetRenderType() & RT_SURFACE_COLORS) != 0); } void CModelerView::OnUpdateRendOnColors(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); pCmdUI->SetCheck( (m_RenderPrefs.GetRenderType() & RT_ON_COLORS) != 0); } void CModelerView::OnUpdateRendOffColors(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); pCmdUI->SetCheck( (m_RenderPrefs.GetRenderType() & RT_OFF_COLORS) != 0); } void CModelerView::OnUpdateRendUseTexture(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); pCmdUI->SetCheck( (m_RenderPrefs.GetRenderType() & RT_TEXTURE) != 0); } void CModelerView::OnUpdateRendBboxAll(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); pCmdUI->SetCheck( m_RenderPrefs.BBoxAllVisible() ); } void CModelerView::OnUpdateRendBboxFrame(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); pCmdUI->SetCheck( m_RenderPrefs.BBoxFrameVisible() ); } void CModelerView::OnTakeScreenShoot() { // redraw view if( m_pDrawPort->Lock()) { RenderView( m_pDrawPort); m_pDrawPort->Unlock(); } m_pViewPort->SwapBuffers(); // grab screen creating image info CImageInfo iiImageInfo; m_pDrawPort->GrabScreen( iiImageInfo, 1); CTFileName fnSSFileName = _EngineGUI.FileRequester( "Select name for screen shot", FILTER_TGA FILTER_END, "Take screen shoots directory", "ScreenShots\\", "", NULL, FALSE); if( fnSSFileName == "") return; CWaitCursor StartWaitCursor; CDlgPleaseWait dlg( "Please wait while saving screen shoot:", fnSSFileName); dlg.Create( IDD_PLEASE_WAIT); dlg.CenterWindow(); dlg.RedrawWindow(); // try to try { // save image info into file iiImageInfo.SaveTGA_t( fnSSFileName); } catch(char *strError) { AfxMessageBox(CString(strError)); } dlg.DestroyWindow(); } /* * Get the pointer to the main frame object of this application */ CMainFrame *CModelerView::GetMainFrame() { // get the MDIChildFrame of this window CChildFrame *pfrChild = (CChildFrame *)this->GetParentFrame(); ASSERT(pfrChild!=NULL); // get the MDIFrameWnd CMainFrame *pfrMain = (CMainFrame *)pfrChild->GetParentFrame(); ASSERT(pfrMain!=NULL); return pfrMain; } void CModelerView::OnKillFocus(CWnd* pNewWnd) { CView::OnKillFocus(pNewWnd); } void CModelerView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) { theApp.m_chGlobal.MarkChanged(); CView::OnActivateView(bActivate, pActivateView, pDeactiveView); } void CModelerView::OnBackgPicture() { m_IsWinBcgTexture = TRUE; Invalidate( FALSE); } void CModelerView::OnBackgColor() { m_IsWinBcgTexture = FALSE; Invalidate( FALSE); } void CModelerView::OnRendFloor() { m_FloorOn = !m_FloorOn; Invalidate( FALSE); } void CModelerView::OnUpdateRendFloor(CCmdUI* pCmdUI) { if( !m_bMappingMode) { if( theApp.m_pFloorModelObject != NULL) { // set floor mode check (press in button) pCmdUI->SetCheck( m_FloorOn); // enable tool bar's button pCmdUI->Enable( TRUE); // don't disable it again return; } } // gray collision mode command pCmdUI->Enable( FALSE); } void CModelerView::OnStainsInsert() { CModelerDoc* pDoc = GetDocument(); CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); CWorkingPatch *pWP = NULL; int iSelected = pMainFrame->m_StainsComboBox.GetCurSel(); if( iSelected != CB_ERR) { INDEX iCt = 0; FOREACHINLIST( CWorkingPatch, wp_ListNode, theApp.m_WorkingPatches, it) { if( iCt == iSelected) { pWP = &it.Current(); } iCt ++; } } ASSERT(pWP != NULL); CTextureData *pTD = pWP->wp_TextureData; CModelData *pMD = (CModelData *) m_ModelObject.GetData(); MEX mexWidth, mexHeight; pMD->GetTextureDimensions( mexWidth, mexHeight); INDEX iMaskBit; // if patch adding is not succesefull if( !pDoc->m_emEditModel.EditAddPatch( pWP->wp_FileName, MEX2D( mexWidth/2-pTD->GetWidth()/2, mexHeight/2-pTD->GetHeight()/2), iMaskBit) ) { WarningMessage("Unable to add patch"); return; } m_iActivePatchBitIndex = iMaskBit; m_ModelObject.ShowPatch( iMaskBit); pDoc->m_emEditModel.edm_md.md_bPreparedForRendering = FALSE; pDoc->SetModifiedFlag(); Invalidate( FALSE); if( pMainFrame->m_dlgPatchesPalette != NULL) { pMainFrame->m_dlgPatchesPalette->UpdateData( FALSE); pMainFrame->m_dlgPatchesPalette->Invalidate(FALSE); } } void CModelerView::OnStainsDelete() { CModelerDoc* pDoc = GetDocument(); POSITION pos = pDoc->GetFirstViewPosition(); while (pos != NULL) { CView *pView = pDoc->GetNextView( pos); if( DYNAMIC_DOWNCAST(CModelerView, pView) != NULL) { CModelerView* pModelerView = (CModelerView *) pView; pModelerView->m_ModelObject.HidePatch( m_iActivePatchBitIndex); } } pDoc->m_emEditModel.EditRemovePatch( m_iActivePatchBitIndex); INDEX iRemovedPatch = m_iActivePatchBitIndex; pDoc->m_emEditModel.GetFirstValidPatchIndex( m_iActivePatchBitIndex); pDoc->m_emEditModel.edm_md.md_bPreparedForRendering = FALSE; pDoc->SetModifiedFlag(); // for all views in this document, // select first patch that exists if deleted patch has been selected pos = pDoc->GetFirstViewPosition(); while (pos != NULL) { CView *pView = pDoc->GetNextView( pos); if( DYNAMIC_DOWNCAST(CModelerView, pView) != NULL) { CModelerView* pModelerView = (CModelerView *) pView; if( pModelerView->m_iActivePatchBitIndex == iRemovedPatch) { pModelerView->m_iActivePatchBitIndex = m_iActivePatchBitIndex; } } } CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); if( pMainFrame->m_dlgPatchesPalette != NULL) { pMainFrame->m_dlgPatchesPalette->UpdateData( FALSE); pMainFrame->m_dlgPatchesPalette->Invalidate(FALSE); } } void CModelerView::OnUpdateStainsInsert(CCmdUI* pCmdUI) { pCmdUI->Enable( !theApp.m_WorkingPatches.IsEmpty()); } void CModelerView::OnUpdateStainsDelete(CCmdUI* pCmdUI) { CModelerDoc* pDoc = GetDocument(); pCmdUI->Enable( pDoc->m_emEditModel.CountPatches() != 0); } void CModelerView::OnStainsPreviousStain() { CModelerDoc* pDoc = GetDocument(); pDoc->m_emEditModel.GetPreviousValidPatchIndex( m_iActivePatchBitIndex); CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); if( pMainFrame->m_dlgPatchesPalette != NULL) { pMainFrame->m_dlgPatchesPalette->UpdateData( FALSE); pMainFrame->m_dlgPatchesPalette->Invalidate(FALSE); } } void CModelerView::OnStainsNextStain() { CModelerDoc* pDoc = GetDocument(); pDoc->m_emEditModel.GetNextValidPatchIndex( m_iActivePatchBitIndex); CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); if( pMainFrame->m_dlgPatchesPalette != NULL) { pMainFrame->m_dlgPatchesPalette->UpdateData( FALSE); pMainFrame->m_dlgPatchesPalette->Invalidate(FALSE); } } void CModelerView::OnUpdateStainsNextStain(CCmdUI* pCmdUI) { CModelerDoc* pDoc = GetDocument(); pCmdUI->Enable( pDoc->m_emEditModel.CountPatches() > 1); } void CModelerView::OnUpdateStainsPreviousStain(CCmdUI* pCmdUI) { CModelerDoc* pDoc = GetDocument(); pCmdUI->Enable( pDoc->m_emEditModel.CountPatches() > 1); } void CModelerView::OnShadowWorse() { m_RenderPrefs.DesreaseShadowQuality(); Invalidate( FALSE); } void CModelerView::OnShadowBetter() { m_RenderPrefs.IncreaseShadowQuality(); Invalidate( FALSE); } void CModelerView::OnFallDown() { if( m_bMappingMode) { m_offx = 0; m_offy = 0; //m_MagnifyFactor = 1.0f; } else { m_vViewMeasureVertex = FLOAT3D(0,0,0); m_plModelPlacement.pl_PositionVector(1) = 0.0f; m_plModelPlacement.pl_PositionVector(2) = 0.0f; m_plModelPlacement.pl_PositionVector(3) = 0.0f; FLOAT fHeading = theApp.m_Preferences.ap_fDefaultHeading; FLOAT fPitch = theApp.m_Preferences.ap_fDefaultPitch; FLOAT fBanking = theApp.m_Preferences.ap_fDefaultBanking; m_plModelPlacement.pl_OrientationAngle = ANGLE3D(AngleDeg(fHeading), AngleDeg(fPitch),AngleDeg(fBanking)); } theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnLButtonDblClk(UINT nFlags, CPoint point) { BOOL bSpace = (GetKeyState( ' ') & 128) != 0; BOOL bCtrl = nFlags & MK_CONTROL; // ctrl+space+XMB is used for 2x zooming if( bCtrl && bSpace) { FastZoomIn( point); } if( m_bMappingMode) { PIX pixDPWidth = m_pDrawPort->GetWidth(); PIX pixDPHeight = m_pDrawPort->GetHeight(); m_offx += point.x - pixDPWidth/2; m_offy += point.y - pixDPHeight/2; } Invalidate( FALSE); CView::OnLButtonDblClk(nFlags, point); } void CModelerView::OnRButtonDblClk(UINT nFlags, CPoint point) { BOOL bSpace = (GetKeyState( ' ') & 128) != 0; BOOL bCtrl = nFlags & MK_CONTROL; // ctrl+space+XMB is used for 2x zooming if( bCtrl && bSpace) { FastZoomOut(); } CView::OnRButtonDblClk(nFlags, point); } void CModelerView::OnKeyA() { if( m_bMappingMode) { OnToggleAllSurfaces(); } else { OnChangeAmbient(); } } void CModelerView::OnUpdateSaveThumbnail(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); } void CModelerView::OnSaveThumbnail() { CModelerDoc* pDoc = GetDocument(); FillThumbnailSettings( pDoc->m_emEditModel.edm_tsThumbnailSettings); // mark that thumbnail settings have been set pDoc->m_emEditModel.edm_tsThumbnailSettings.ts_bSet = TRUE; SaveThumbnail(); STATUS_LINE_MESSAGE( L"Thumbnail saved."); } void CModelerView::SaveThumbnail() { CDrawPort *pDrawPort; CImageInfo iiImageInfo; CTextureData TD; CAnimData AD; CModelerDoc* pDoc = GetDocument(); // store current thumbnail settings CThumbnailSettings tsCurrent; FillThumbnailSettings( tsCurrent); // if we have precalculated thumbnail settings if( pDoc->m_emEditModel.edm_tsThumbnailSettings.ts_bSet) { // apply them ApplyThumbnailSettings( pDoc->m_emEditModel.edm_tsThumbnailSettings); } _pGfx->CreateWorkCanvas( 128, 128, &pDrawPort); if( pDrawPort != NULL) { INDEX iCurrentMip = m_ModelObject.GetManualMipLevel(); m_ModelObject.SetManualMipLevel(0); BOOL bAutoMipModeling = m_ModelObject.IsAutoMipModeling(); m_ModelObject.AutoMipModelingOff(); if( pDrawPort->Lock()) { BOOL bCollisionModeBefore = m_bCollisionMode; BOOL bMappingOnBefore = m_bMappingMode; m_bCollisionMode = FALSE; m_bMappingMode = FALSE; RenderView( pDrawPort); m_bCollisionMode = bCollisionModeBefore; m_bMappingMode = bMappingOnBefore; pDrawPort->Unlock(); } CTFileName fnDocName = CTString(CStringA(GetDocument()->GetPathName())); CTFileName fnThumbnail = fnDocName.FileDir() + fnDocName.FileName() + ".tbn"; pDrawPort->GrabScreen( iiImageInfo); // try to try { fnThumbnail.RemoveApplicationPath_t(); // create texture TD.Create_t( &iiImageInfo, 128, MAX_MEX_LOG2, FALSE); // save the thumbnail CTFileStream File; File.Create_t( fnThumbnail); TD.Write_t( &File); File.Close(); } // if failed catch (char *strError) { // report error AfxMessageBox(CString(strError)); } m_ModelObject.SetManualMipLevel( iCurrentMip); if( bAutoMipModeling) { m_ModelObject.AutoMipModelingOn(); } _pGfx->DestroyWorkCanvas( pDrawPort); } // restore current view settings ApplyThumbnailSettings( tsCurrent); } void CModelerView::OnFrameRate() { m_bFrameRate = !m_bFrameRate; Invalidate( FALSE); } void CModelerView::OnUpdateFrameRate(CCmdUI* pCmdUI) { pCmdUI->SetCheck( m_bFrameRate); } void CModelerView::OnHeading() { m_plModelPlacement.pl_OrientationAngle( 1) += AngleDeg( 90.0f); theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnPitch() { m_plModelPlacement.pl_OrientationAngle( 2) += AngleDeg( 90.0f); theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnBanking() { m_plModelPlacement.pl_OrientationAngle( 3) += AngleDeg( 90.0f); theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnUpdateCollisionBox(CCmdUI* pCmdUI) { if( !m_bMappingMode) { if( theApp.m_pCollisionBoxModelObject != NULL) { // set collision mode check (press in button) pCmdUI->SetCheck( m_bCollisionMode); // enable tool bar's button pCmdUI->Enable( TRUE); // don't disable it again return; } } // gray collision mode command pCmdUI->Enable( FALSE); } void CModelerView::OnCollisionBox() { if( theApp.m_pCollisionBoxModelObject != NULL) { m_bCollisionMode = !m_bCollisionMode; Invalidate( FALSE); } } void CModelerView::OnResetViewer() { if( m_bMappingMode) { m_offx = 0; m_offy = 0; m_MagnifyFactor = 1.0f; } else { ResetViewerPosition(); OnFallDown(); } theApp.m_chGlobal.MarkChanged(); Invalidate( FALSE); } void CModelerView::OnUpdateResetViewer(CCmdUI* pCmdUI) { pCmdUI->Enable( TRUE); } void CModelerView::OnDollyViewer() { m_bDollyViewer = !m_bDollyViewer; Invalidate( FALSE); } void CModelerView::OnUpdateDollyViewer(CCmdUI* pCmdUI) { pCmdUI->SetCheck( m_bDollyViewer); pCmdUI->Enable( !m_bMappingMode); } void CModelerView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { // just invalidate the whole window area Invalidate(FALSE); } void CModelerView::OnDollyLight() { m_bDollyLight = !m_bDollyLight; Invalidate( FALSE); } void CModelerView::OnUpdateDollyLight(CCmdUI* pCmdUI) { pCmdUI->SetCheck( m_bDollyLight); pCmdUI->Enable( !m_bMappingMode); } void CModelerView::OnDollyLightColor() { m_bDollyLightColor = !m_bDollyLightColor; Invalidate( FALSE); } void CModelerView::OnUpdateDollyLightColor(CCmdUI* pCmdUI) { pCmdUI->SetCheck( m_bDollyLightColor); pCmdUI->Enable( !m_bMappingMode); } BOOL CModelerView::PreTranslateMessage(MSG* pMsg) { // translate message first BOOL bResult = CView::PreTranslateMessage(pMsg); CModelerView *pModelerView = CModelerView::GetActiveMappingNormalView(); if(pModelerView != this) return bResult; CModelerDoc* pDoc = GetDocument(); // get key statuses BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0; BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0; BOOL bControl = (GetKeyState( VK_CONTROL)&0x8000) != 0; BOOL bSpace = (GetKeyState( VK_SPACE)&0x8000) != 0; // get mouse button statuses BOOL bLMB = (GetKeyState( VK_LBUTTON)&0x8000) != 0; BOOL bRMB = (GetKeyState( VK_RBUTTON)&0x8000) != 0; if( (pMsg->message==WM_KEYDOWN) || bShift || bControl || bSpace || bLMB || bRMB ) { m_bAnyKeyPressed = TRUE; } else if(pMsg->message==WM_KEYUP) { m_bAnyKeyPressed = FALSE; } CDlgPgInfoAttachingPlacement *pAttPg = theApp.m_pPgAttachingPlacement; BOOL bAttachmentExists = (pAttPg!=NULL) && (pAttPg->GetCurrentAttachingPlacement() != -1); BOOL bViewHasFocus = (this == CWnd::GetFocus()); // see if we are picking vertices to define axis if( bViewHasFocus && bAttachmentExists && (pMsg->message==WM_KEYDOWN) && (( pMsg->wParam=='1') || ( pMsg->wParam=='2') || ( pMsg->wParam=='3')) ) { FLOAT3D vClosestVertex; INDEX iClosestVertex = GetClosestVertex( vClosestVertex); if( iClosestVertex != -1) { if( pMsg->wParam=='1') pAttPg->SetPlacementReferenceVertex(iClosestVertex, -1, -1); if( pMsg->wParam=='2') pAttPg->SetPlacementReferenceVertex(-1, iClosestVertex, -1); if( pMsg->wParam=='3') pAttPg->SetPlacementReferenceVertex(-1, -1, iClosestVertex); } } if( m_bViewMeasureVertex) { CTString strStatusLine; CPlacement3D plMeasureVtx = CPlacement3D(m_vViewMeasureVertex, ANGLE3D(0,0,0)); plMeasureVtx.AbsoluteToRelative( m_plModelPlacement); FLOAT3D vDelta = plMeasureVtx.pl_PositionVector; strStatusLine.PrintF("Measure vertex offset: %g, %g, %g", vDelta(1), vDelta(2), vDelta(3)); STATUS_LINE_MESSAGE( CString(strStatusLine)); } // if we caught key or button down message else if( (pMsg->message==WM_SYSKEYDOWN) || (pMsg->message==WM_KEYDOWN) || (pMsg->message==WM_KEYUP) || (pMsg->message==WM_LBUTTONDOWN) || (pMsg->message==WM_RBUTTONDOWN) || (pMsg->message==WM_LBUTTONUP) || (pMsg->message==WM_RBUTTONUP) || (bShift || bAlt || bControl || bSpace || bLMB || bRMB) ) { // in mapping mode if( m_bMappingMode) { // nothing if( !bShift && !bAlt && !bControl && !bSpace && !bLMB && !bRMB) { STATUS_LINE_MESSAGE( L"Try: Space, Ctrl+Space"); } // space else if( !bShift && !bAlt && !bControl && bSpace && !bLMB && !bRMB) { STATUS_LINE_MESSAGE( L"Move with LMB, zoom with RMB, center with LMBx2. Try: Ctrl+Space"); } // ctrl+space else if( !bShift && !bAlt && bControl && bSpace && !bLMB && !bRMB) { STATUS_LINE_MESSAGE( L"LMB zooms in, RMB zooms out"); } } // model view mode else { // nothing if( !bShift && !bAlt && !bControl && !bSpace && !bLMB && !bRMB) { // nothing pressed STATUS_LINE_MESSAGE( L"Try: Space, Ctrl+Space, Ctrl, Shift"); } // space else if( !bShift && !bAlt && !bControl && bSpace && !bLMB && !bRMB && !m_bMappingMode) { STATUS_LINE_MESSAGE( L"LMB moves, RMB zoomes, LMB+RMB rotates viewer. Try: Ctrl+Space"); } // ctrl+space else if( !bShift && !bAlt && bControl && bSpace && !bLMB && !bRMB && !m_bMappingMode) { STATUS_LINE_MESSAGE( L"LMB zooms in, RMB zoomes out"); } // ctrl else if( !bShift && !bAlt && bControl && !bSpace && !bLMB && !bRMB && !m_bMappingMode) { STATUS_LINE_MESSAGE( L"LMB moves, RMB zoomes, LMB+RMB rotates model"); } // shift else if( bShift && !bAlt && !bControl && !bSpace && !bLMB && !bRMB && !m_bMappingMode) { STATUS_LINE_MESSAGE( L"RMB zoomes, LMB+RMB rotates light"); } } } return bResult; } void CModelerView::OnNextTexture() { CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); // get curently selected combo member int iCurrentlySelected = pMainFrame->m_SkinComboBox.GetCurSel(); int iComboMembersCt = pMainFrame->m_SkinComboBox.GetCount(); // if next combo member can't be selected if( (iCurrentlySelected+1) >= iComboMembersCt) { return; } // select next combo member pMainFrame->m_SkinComboBox.SetCurSel( iCurrentlySelected+1); // set new texture ptr for active view m_ptdiTextureDataInfo = (CTextureDataInfo *) pMainFrame->m_SkinComboBox.GetItemDataPtr( iCurrentlySelected+1); // redraw view Invalidate( FALSE); } void CModelerView::OnUpdateNextTexture(CCmdUI* pCmdUI) { CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); // get curently selected combo member int iCurrentlySelected = pMainFrame->m_SkinComboBox.GetCurSel(); int iComboMembersCt = pMainFrame->m_SkinComboBox.GetCount(); // if next combo member can't be selected pCmdUI->Enable( (iCurrentlySelected+1) < iComboMembersCt); } void CModelerView::OnPreviousTexture() { CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); // get curently selected combo member int iCurrentlySelected = pMainFrame->m_SkinComboBox.GetCurSel(); // if next combo member can't be selected if( (iCurrentlySelected == 0) || (iCurrentlySelected==CB_ERR) ) { return; } // select next combo member pMainFrame->m_SkinComboBox.SetCurSel( iCurrentlySelected-1); // set new texture ptr for active view m_ptdiTextureDataInfo = (CTextureDataInfo *) pMainFrame->m_SkinComboBox.GetItemDataPtr( iCurrentlySelected-1); // redraw view Invalidate( FALSE); } void CModelerView::OnUpdatePreviousTexture(CCmdUI* pCmdUI) { CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); // get curently selected combo member int iCurrentlySelected = pMainFrame->m_SkinComboBox.GetCurSel(); // if previous combo member can't be selected pCmdUI->Enable( (iCurrentlySelected != 0) && (iCurrentlySelected!=CB_ERR) ); } void CModelerView::OnRecreateTexture() { // there must be valid texture ASSERT( AssureValidTDI()); CTextureData *pTD = m_ptdiTextureDataInfo->tdi_TextureData; CTFileName fnTextureName = pTD->GetName(); // call (re)create texture dialog _EngineGUI.CreateTexture( fnTextureName); // try to CTextureData *ptdTextureToReload; try { // obtain texture ptdTextureToReload = _pTextureStock->Obtain_t( fnTextureName); } catch ( char *err_str) { AfxMessageBox( CString(err_str)); return; } // reload the texture ptdTextureToReload->Reload(); // release the texture _pTextureStock->Release( ptdTextureToReload); CModelerDoc* pDoc = GetDocument(); pDoc->UpdateAllViews( NULL); } void CModelerView::OnUpdateRecreateTexture(CCmdUI* pCmdUI) { if( AssureValidTDI()) { pCmdUI->Enable( TRUE); } else { pCmdUI->Enable( FALSE); } } #define EQUAL_SUB_STR( str) (strnicmp( achrLine, str, strlen(str)) == 0) void CModelerView::OnCreateMipModels() { CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); CObject3D objRestFrame, objMipSourceFrame; CListHead FrameNamesList; CTFileName fnFrameFileName; char achrLine[ 128]; char achrBasePath[ PATH_MAX] = ""; char achrRestFrame[ PATH_MAX] = ""; char achrRestFrameFullPath[ PATH_MAX] = ""; CModelerDoc* pDoc = GetDocument(); CTFileName fnModelName = CTString(CStringA(pDoc->GetPathName())); CTFileName fnScriptName = fnModelName.FileDir() + fnModelName.FileName() + ".scr"; try { fnScriptName.RemoveApplicationPath_t(); // open script file CTFileStream File; File.Open_t( fnScriptName); FLOATmatrix3D mStretch; mStretch.Diagonal(1.0f); try { FOREVER { do { File.GetLine_t(achrLine, 128); } while( (strlen( achrLine)== 0) || (achrLine[0]==';')); if( EQUAL_SUB_STR( "DIRECTORY")) { _strupr( achrLine); sscanf( achrLine, "DIRECTORY %s", achrBasePath); if( achrBasePath[ strlen( achrBasePath) - 1] != '\\') strcat( achrBasePath,"\\"); } else if( EQUAL_SUB_STR( "MIP_MODELS")) { File.GetLine_t(achrLine, 128); _strupr( achrLine); sscanf( achrLine, "%s", achrRestFrame); sprintf( achrRestFrameFullPath, "%s%s", achrBasePath, achrRestFrame); } else if( EQUAL_SUB_STR( "SIZE")) { _strupr( achrLine); FLOAT fStretch = 1.0f; sscanf( achrLine, "SIZE %g", &fStretch); mStretch *= fStretch; } else if( EQUAL_SUB_STR( "TRANSFORM")) { _strupr( achrLine); FLOATmatrix3D mTran; mTran.Diagonal(1.0f); sscanf( achrLine, "TRANSFORM %g %g %g %g %g %g %g %g %g", &mTran(1,1), &mTran(1,2), &mTran(1,3), &mTran(2,1), &mTran(2,2), &mTran(2,3), &mTran(3,1), &mTran(3,2), &mTran(3,3)); mStretch *= mTran; } else if( EQUAL_SUB_STR( "ANIM_START")) { pDoc->m_emEditModel.edm_md.LoadFromScript_t( &File, &FrameNamesList); // extract file name of last rendered frame INDEX iFrame = 0; FOREACHINLIST( CFileNameNode, cfnn_Node, FrameNamesList, itFrameName) { if( m_iCurrentFrame == iFrame) { fnFrameFileName = CTString(itFrameName->cfnn_FileName); break; } iFrame++; } // clear list of frames FORDELETELIST( CFileNameNode, cfnn_Node, FrameNamesList, litDel) delete &litDel.Current(); } } } catch( char *pstrError) { (void) pstrError; } // if frame name is extracted properly if( fnFrameFileName != "") { // load rest frame objRestFrame.LoadAny3DFormat_t( CTString(achrRestFrameFullPath), mStretch); // load mip source frame objMipSourceFrame.LoadAny3DFormat_t( fnFrameFileName, mStretch); // show progres dialog 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); CDlgAutoMipModeling dlgAutoMipModeling; if( (dlgAutoMipModeling.DoModal() != IDOK) || (dlgAutoMipModeling.m_iVerticesToRemove<=0) || (dlgAutoMipModeling.m_iSurfacePreservingFactor<1) || (dlgAutoMipModeling.m_iSurfacePreservingFactor>99) ) { pMainFrame->m_NewProgress.DestroyWindow(); return; } // create mip models pDoc->m_emEditModel.CreateMipModels_t( objRestFrame, objMipSourceFrame, dlgAutoMipModeling.m_iVerticesToRemove, dlgAutoMipModeling.m_iSurfacePreservingFactor); // copy mapping from main mip model pDoc->m_emEditModel.SaveMapping_t( CTString("Temp\\ForAutoMipMapping.map"), 0); // paste mapping over all smaller mip models INDEX iMipModel=1; for( ; iMipModelm_emEditModel.edm_md.md_MipCt; iMipModel++) { pDoc->m_emEditModel.LoadMapping_t( CTString("Temp\\ForAutoMipMapping.map"), iMipModel); } for( INDEX iSurface=1; iSurfacem_emEditModel.edm_md.md_MipInfos[0].mmpi_MappingSurfaces.Count(); iSurface++) { // get rendering flags from main mip model for current surface ULONG ulRenderFlags; enum SurfaceShadingType sstShading; enum SurfaceTranslucencyType sttTranslucency; m_ModelObject.GetSurfaceRenderFlags( 0, iSurface, sstShading, sttTranslucency, ulRenderFlags); // get color of surface UBYTE ubSurfaceTransparency = (UBYTE) (m_ModelObject.GetSurfaceColor( 0, iSurface) & CT_OPAQUE); for( iMipModel=1; iMipModelm_emEditModel.edm_md.md_MipCt; iMipModel++) { // set render flags m_ModelObject.SetSurfaceRenderFlags( iMipModel, iSurface, sstShading, sttTranslucency, ulRenderFlags); COLOR colSurfaceColor = m_ModelObject.GetSurfaceColor( iMipModel, iSurface); // set remembered transparency colSurfaceColor = (colSurfaceColor & 0xFFFFFF00) | ubSurfaceTransparency; // set new surface color m_ModelObject.SetSurfaceColor( iMipModel, iSurface, colSurfaceColor); } } // destroy progres window pMainFrame->m_NewProgress.DestroyWindow(); } } catch( char *pStrError) { // destroy progress window pMainFrame->m_NewProgress.DestroyWindow(); AfxMessageBox( CString(pStrError)); } pDoc->SelectMipModel( 0); pDoc->SelectSurface( 0, TRUE); m_ModelObject.SetManualMipLevel( 0); theApp.m_chGlobal.MarkChanged(); pDoc->UpdateAllViews( NULL); pDoc->m_emEditModel.edm_md.md_bPreparedForRendering = FALSE; pDoc->SetModifiedFlag(); } void CModelerView::OnUpdatePickVertex(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); } INDEX CModelerView::GetClosestVertex(FLOAT3D &vClosestVertex) { CPerspectiveProjection3D prProjection; SetProjectionData( prProjection, m_pDrawPort); // set position of document's model prProjection.ObjectPlacementL() = m_plModelPlacement; return m_ModelObject.PickVertexIndex( m_pDrawPort, &prProjection, m_MousePosition.x, m_MousePosition.y, vClosestVertex); } void CModelerView::OnPickVertex() { FLOAT3D vClosestVertex; INDEX iClosestVertex = GetClosestVertex( vClosestVertex); if( iClosestVertex != -1) { char achrLine[ 256]; sprintf( achrLine, "Vertex index = %d (%g, %g, %g)", iClosestVertex, vClosestVertex(1), vClosestVertex(2), vClosestVertex(3)); CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); pMainFrame->m_wndStatusBar.SetPaneText( CLOSEST_SURFACE_PANE, CString(achrLine)); } } void CModelerView::OnDollyMipModeling() { m_bDollyMipModeling = !m_bDollyMipModeling; } void CModelerView::OnUpdateDollyMipModeling(CCmdUI* pCmdUI) { pCmdUI->SetCheck( m_bDollyMipModeling!=0); } void CModelerView::OnAnimPlayOnce() { if( m_ModelObject.IsPaused()) m_ModelObject.ContinueAnim(); m_ModelObject.ResetAnim(); m_ModelObject.PlayAnim( m_ModelObject.GetAnim(), AOF_NORESTART); PlayAnimForAllAttachments( m_ModelObject, AOF_NORESTART); } void CModelerView::OnUpdateAnimPlayOnce(CCmdUI* pCmdUI) { if( m_bMappingMode) pCmdUI->Enable( FALSE); } void CModelerView::FillThumbnailSettings( CThumbnailSettings &tsToReceive) { tsToReceive.ts_plLightPlacement = m_plLightPlacement; tsToReceive.ts_plModelPlacement = m_plModelPlacement; tsToReceive.ts_fTargetDistance = m_fTargetDistance; tsToReceive.ts_vTarget = m_vTarget; tsToReceive.ts_angViewerOrientation = m_angViewerOrientation; tsToReceive.ts_LightDistance = m_LightDistance; tsToReceive.ts_LightColor = m_LightColor; tsToReceive.ts_colAmbientColor = m_colAmbientColor; tsToReceive.ts_PaperColor = m_PaperColor; tsToReceive.ts_InkColor = m_InkColor; tsToReceive.ts_IsWinBcgTexture = m_IsWinBcgTexture; tsToReceive.ts_WinBcgTextureName = m_fnBcgTexture; tsToReceive.ts_RenderPrefs = m_RenderPrefs; } void CModelerView::ApplyThumbnailSettings( CThumbnailSettings &tsToApply) { m_plLightPlacement = tsToApply.ts_plLightPlacement; m_plModelPlacement = tsToApply.ts_plModelPlacement; m_fTargetDistance = tsToApply.ts_fTargetDistance; m_vTarget = tsToApply.ts_vTarget; m_angViewerOrientation = tsToApply.ts_angViewerOrientation; m_LightDistance = tsToApply.ts_LightDistance; m_LightColor = tsToApply.ts_LightColor; m_colAmbientColor = tsToApply.ts_colAmbientColor; m_PaperColor = tsToApply.ts_PaperColor; m_InkColor = tsToApply.ts_InkColor; m_IsWinBcgTexture = tsToApply.ts_IsWinBcgTexture; m_fnBcgTexture = tsToApply.ts_WinBcgTextureName; m_RenderPrefs = tsToApply.ts_RenderPrefs; } void CModelerView::OnTileTexture() { m_bTileMappingBCG = !m_bTileMappingBCG; GetDocument()->UpdateAllViews( NULL); } void CModelerView::OnUpdateTileTexture(CCmdUI* pCmdUI) { pCmdUI->SetCheck( m_bTileMappingBCG); } void CModelerView::OnAddReflectionTexture() { CTFileName fnChoosedFile = _EngineGUI.FileRequester( "Select reflection texture", FILTER_TEX FILTER_ALL FILTER_END, "Reflection textures directory", "Textures\\"); if( fnChoosedFile == "") return; try { m_ModelObject.mo_toReflection.SetData_t( fnChoosedFile); GetDocument()->m_emEditModel.edm_fnReflectionTexture = fnChoosedFile; } catch( char *strError) { WarningMessage( strError); } theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnAddSpecular() { CTFileName fnChoosedFile = _EngineGUI.FileRequester( "Select specular texture", FILTER_TEX FILTER_ALL FILTER_END, "Specularity textures directory", "Textures\\"); if( fnChoosedFile == "") return; try { m_ModelObject.mo_toSpecular.SetData_t( fnChoosedFile); GetDocument()->m_emEditModel.edm_fnSpecularTexture = fnChoosedFile; } catch( char *strError) { WarningMessage( strError); } theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnAddBumpTexture() { CTFileName fnChoosedFile = _EngineGUI.FileRequester( "Select bump texture", FILTER_TEX FILTER_ALL FILTER_END, "Bump textures directory", "Textures\\"); if( fnChoosedFile == "") return; try { m_ModelObject.mo_toBump.SetData_t( fnChoosedFile); GetDocument()->m_emEditModel.edm_fnBumpTexture = fnChoosedFile; } catch( char *strError) { WarningMessage( strError); } theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnRemoveReflection() { try { m_ModelObject.mo_toReflection.SetData_t( CTString("")); GetDocument()->m_emEditModel.edm_fnReflectionTexture = CTString(""); } catch( char *strError) { (void) strError;} theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnRemoveSpecular() { try { m_ModelObject.mo_toSpecular.SetData_t( CTString("")); GetDocument()->m_emEditModel.edm_fnSpecularTexture = CTString(""); } catch( char *strError) { (void) strError;} theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnRemoveBumpMap() { try { m_ModelObject.mo_toBump.SetData_t( CTString("")); GetDocument()->m_emEditModel.edm_fnBumpTexture = CTString(""); } catch( char *strError) { (void) strError;} theApp.m_chGlobal.MarkChanged(); } void CModelerView::OnUpdateRemoveReflection(CCmdUI* pCmdUI) { pCmdUI->Enable( m_ModelObject.mo_toReflection.GetData() != NULL); } void CModelerView::OnUpdateRemoveSpecular(CCmdUI* pCmdUI) { pCmdUI->Enable( m_ModelObject.mo_toSpecular.GetData() != NULL); } void CModelerView::OnUpdateRemoveBumpMap(CCmdUI* pCmdUI) { pCmdUI->Enable( m_ModelObject.mo_toBump.GetData() != NULL); } void CModelerView::OnSurfaceNumbers() { m_bPrintSurfaceNumbers = !m_bPrintSurfaceNumbers; } void CModelerView::OnUpdateSurfaceNumbers(CCmdUI* pCmdUI) { if( !m_bMappingMode) { pCmdUI->Enable( FALSE); } else if( m_bPrintSurfaceNumbers) { pCmdUI->SetCheck(1); } else { pCmdUI->SetCheck( 0); } } void CModelerView::OnExportSurfaces() { CTFileName fnExportFileName = _EngineGUI.FileRequester( "Select export file name", FILTER_TXT FILTER_END, "Open model directory", "Models\\", "", NULL, FALSE); if( fnExportFileName == "") return; CModelerDoc* pDoc = GetDocument(); pDoc->m_emEditModel.ExportSurfaceNumbersAndNames( fnExportFileName); } void CModelerView::OnPreviousBcgTexture() { m_fnBcgTexture = theApp.NextPrevBcgTexture( m_fnBcgTexture, -1); Invalidate( FALSE); } void CModelerView::OnUpdatePreviousBcgTexture(CCmdUI* pCmdUI) { if( theApp.m_WorkingTextures.Count() > 1) { pCmdUI->Enable(TRUE); } else { pCmdUI->Enable(FALSE); } } void CModelerView::OnNextBcgTexture() { m_fnBcgTexture = theApp.NextPrevBcgTexture( m_fnBcgTexture, 1); Invalidate( FALSE); } void CModelerView::OnUpdateNextBcgTexture(CCmdUI* pCmdUI) { if( theApp.m_WorkingTextures.Count() > 1) { pCmdUI->Enable(TRUE); } else { pCmdUI->Enable(FALSE); } } void CModelerView::OnWindowTogglemax() { CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); pMainFrame->OnWindowTogglemax(); } void CModelerView::OnExportForSkining() { CModelerDoc* pDoc = GetDocument(); CTFileName fnDocName = CTString(CStringA(pDoc->GetPathName())); CTFileName fnDirectory = fnDocName.FileDir(); CTFileName fnDefaultSelected = fnDocName.FileName()+CTString(".tga"); try { fnDirectory.RemoveApplicationPath_t(); } catch( char *str_err) { AfxMessageBox( CString(str_err)); return; } // note: NULL given instead of profile string name, to avoid using last directory CTFileName fnExportName = _EngineGUI.FileRequester( "Select name to export mapping", "Pictures (*.tga)\0*.tga\0" FILTER_END, NULL, fnDirectory, fnDefaultSelected, NULL, FALSE); if( fnExportName == "") return; CTFileName fnFullPath = _fnmApplicationPath+fnExportName; if( GetFileAttributesA( fnFullPath) != -1) { CTString strMsg; strMsg.PrintF( "File \"%s\" already exist. Do you want to replace it?", fnFullPath); if( ::MessageBoxA( this->m_hWnd, strMsg, "Warning !", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON1| MB_SYSTEMMODAL | MB_TOPMOST) != IDYES) { return; } } CDlgExportForSkinning dlg( fnExportName); if( dlg.DoModal() != IDOK) return; COLOR colPaper = dlg.m_ctrlPaperColor.GetColor(); COLOR colWire = dlg.m_ctrlWireColor.GetColor(); // calculate exporting picture width and height PIX pixWidth = dlg.m_iTextureWidth; FLOAT fWHRatio = FLOAT(pDoc->m_emEditModel.edm_md.md_Width)/pDoc->m_emEditModel.edm_md.md_Height; PIX pixHeight = PIX( pixWidth/fWHRatio); CDrawPort *pdp; _pGfx->CreateWorkCanvas( pixWidth, pixHeight, &pdp); if( pdp == NULL) return; if( !pdp->Lock()) return; // clear bcg pdp->Fill(colPaper|CT_OPAQUE); MEX mexWidth, mexHeight; mexWidth = m_ModelObject.GetWidth(); mexHeight = m_ModelObject.GetHeight(); FLOAT fMagnifyFit = FLOAT(pixWidth)/mexWidth; ModelMipInfo &mmi = pDoc->m_emEditModel.edm_md.md_MipInfos[ 0]; for( INDEX iSurface=0; iSurfacem_emEditModel.DrawFilledSurface( pdp, 0, iSurface, fMagnifyFit, 0, 0, ms.ms_colColor, ms.ms_colColor); } // render wire frame if( dlg.m_bWireFrame) { pDoc->m_emEditModel.DrawWireSurface( pdp, 0, iSurface, fMagnifyFit, 0, 0, colWire, colWire); } } // if we should print surface numbers if( dlg.m_bSurfaceNumbers) { pDoc->m_emEditModel.PrintSurfaceNumbers( pdp, theApp.m_pfntFont, 0, fMagnifyFit, 0, 0, colWire); pDoc->m_emEditModel.ExportSurfaceNumbersAndNames( fnExportName.FileDir()+fnExportName.FileName()+".txt"); } pdp->Unlock(); // grab draw port ti image info CImageInfo iiImageInfo; pdp->GrabScreen( iiImageInfo); // save picture try { iiImageInfo.SaveTGA_t( fnExportName); } catch (char *strError) { AfxMessageBox(CString(strError)); } _pGfx->DestroyWorkCanvas( pdp); } void CModelerView::OnRenderSurfacesInColors() { m_bRenderMappingInSurfaceColors = !m_bRenderMappingInSurfaceColors; Invalidate( FALSE); } void CModelerView::OnUpdateRenderSurfacesInColors(CCmdUI* pCmdUI) { pCmdUI->SetCheck( m_bRenderMappingInSurfaceColors); pCmdUI->Enable( m_bMappingMode); } void CModelerView::OnViewAxis() { if ( m_atAxisType == AT_NONE) m_atAxisType = AT_MAIN; else if( m_atAxisType == AT_MAIN) m_atAxisType = AT_ALL; else if( m_atAxisType == AT_ALL ) m_atAxisType = AT_NONE; Invalidate( FALSE); } void CModelerView::OnUpdateViewAxis(CCmdUI* pCmdUI) { CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); UINT nIDView, nStyleView; int iViewImage; pMainFrame->m_RenderControlBar.GetButtonInfo( 13, nIDView, nStyleView, iViewImage); // if no axis at all if( m_atAxisType == AT_NONE) { pMainFrame->m_RenderControlBar.SetButtonInfo( 13, nIDView, nStyleView, 13); pCmdUI->SetCheck( FALSE); } // if only axis of main model are visible else if( m_atAxisType == AT_MAIN) { pMainFrame->m_RenderControlBar.SetButtonInfo( 13, nIDView, nStyleView, 14); pCmdUI->SetCheck( TRUE); } // if all axis are visible else if( m_atAxisType == AT_ALL) { pMainFrame->m_RenderControlBar.SetButtonInfo( 13, nIDView, nStyleView, 15); pCmdUI->SetCheck( TRUE); } } void CModelerView::OnViewInfo() { CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd()); pMainFrame->ToggleInfoWindow(); } void CModelerView::OnChangeAmbient() { COLORREF clrfAmbient = CLRF_CLR( m_colAmbientColor); if( MyChooseColor( clrfAmbient, *GetParent())) { m_colAmbientColor = CLR_CLRF( clrfAmbient); Invalidate( FALSE); } } void CModelerView::OnUpdateChangeAmbient(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); GetDocument()->UpdateAllViews( NULL); } void CModelerView::OnToggleAllSurfaces() { m_ShowAllSurfaces = !m_ShowAllSurfaces; GetDocument()->UpdateAllViews( NULL); } void CModelerView::OnUpdateToggleAllSurfaces(CCmdUI* pCmdUI) { pCmdUI->Enable( m_bMappingMode); GetDocument()->UpdateAllViews( NULL); } void CModelerView::OnKeyT() { if( m_bMappingMode) { OnTileTexture(); } else { OnRendUseTexture(); } } void CModelerView::OnAnimFirst() { m_ModelObject.StartAnim( 0); } void CModelerView::OnAnimLast() { m_ModelObject.StartAnim( m_ModelObject.GetAnimsCt()-1); } void CModelerView::OnUpdateAnimFirst(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); } void CModelerView::OnUpdateAnimLast(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); } void CModelerView::OnToggleMeasureVtx() { if( m_bViewMeasureVertex) { CPlacement3D plMeasureVtx = CPlacement3D(m_vViewMeasureVertex, ANGLE3D(0,0,0)); plMeasureVtx.AbsoluteToRelative( m_plModelPlacement); FLOAT3D vDelta = plMeasureVtx.pl_PositionVector; // save closest vertex coordinates into file CTString strCoords; strCoords.PrintF( "(%gf, %gf, %gf)",vDelta(1), vDelta(2), vDelta(3)); try { strCoords.Save_t(CTString("temp\\VertexCoords.txt")); } catch( char *strError) { WarningMessage( strError); } } m_bViewMeasureVertex = !m_bViewMeasureVertex; //m_vTarget = m_vViewMeasureVertex; Invalidate( FALSE); } void CModelerView::OnUpdateToggleMeasureVtx(CCmdUI* pCmdUI) { pCmdUI->Enable( !m_bMappingMode); pCmdUI->SetCheck( m_bViewMeasureVertex); }