⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 geneditview.cpp

📁 3D游戏场景编辑器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************************/
/*  GenEditView.cpp                                                                      */
/*                                                                                      */
/*  Author:       Jim Mischel, Ken Baird, Jeff Lomax, John Moore                        */
/*  Description:  MFC view stuff...  Alot of the editor UI functionality is here        */
/*                                                                                      */
/*  The contents of this file are subject to the Genesis3D Public License               */
/*  Version 1.01 (the "License"); you may not use this file except in                   */
/*  compliance with the License. You may obtain a copy of the License at                */
/*  http://www.genesis3d.com                                                            */
/*                                                                                      */
/*  Software distributed under the License is distributed on an "AS IS"                 */
/*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
/*  the License for the specific language governing rights and limitations              */
/*  under the License.                                                                  */
/*                                                                                      */
/*  The Original Code is Genesis3D, released March 25, 1999.                            */
/*Genesis3D Version 1.1 released November 15, 1999                            */
/*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
/*                                                                                      */
/*  Modified by Tom Morris for GenEdit-Classic ver. 0.58, April 23, 2001				*/
/****************************************************************************************/
#include "stdafx.h"
#include "Globals.h"
#include "KeyEditDlg.h"
#include "GenEditView.h"
#include <assert.h>
#include "units.h"
#include "face.h"
#include "ram.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define AXIS_X	0x1
#define AXIS_Y	0x2
#define AXIS_Z	0x4

#define MAX_PIXEL_DRAG_START_DIST (12.0f)

int CGenEditView::mCY_DRAG = 2 ;
int CGenEditView::mCX_DRAG = 2 ;

IMPLEMENT_DYNCREATE(CGenEditView, CView)

BEGIN_MESSAGE_MAP(CGenEditView, CView)
	ON_MESSAGE(WM_USER_COMPILE_MSG, OnCompileMessage)
	ON_MESSAGE(WM_USER_COMPILE_ERR, OnCompileError)
	ON_MESSAGE(WM_USER_COMPILE_DONE, OnCompileDone)
	//{{AFX_MSG_MAP(CGenEditView)
	ON_WM_SIZE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_COMMAND(ID_TOOLS_CAMERA, OnToolsCamera)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_CAMERA, OnUpdateToolsCamera)
	ON_WM_RBUTTONDOWN()
	ON_WM_RBUTTONUP()
	ON_COMMAND(ID_AXIS_X, OnAxisX)
	ON_UPDATE_COMMAND_UI(ID_AXIS_X, OnUpdateAxisX)
	ON_COMMAND(ID_AXIS_Y, OnAxisY)
	ON_UPDATE_COMMAND_UI(ID_AXIS_Y, OnUpdateAxisY)
	ON_COMMAND(ID_AXIS_Z, OnAxisZ)
	ON_UPDATE_COMMAND_UI(ID_AXIS_Z, OnUpdateAxisZ)
	ON_COMMAND(ID_TOOLS_BRUSH_MOVEROTATEBRUSH, OnToolsBrushMoverotatebrush)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_BRUSH_MOVEROTATEBRUSH, OnUpdateToolsBrushMoverotatebrush)
	ON_COMMAND(ID_TOOLS_BRUSH_SCALEBRUSH, OnToolsBrushScalebrush)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_BRUSH_SCALEBRUSH, OnUpdateToolsBrushScalebrush)
	ON_COMMAND(ID_TOOLS_BRUSH_SHOWBRUSH, OnToolsBrushShowbrush)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_BRUSH_SHOWBRUSH, OnUpdateToolsBrushShowbrush)
	ON_WM_ERASEBKGND()
	ON_COMMAND(ID_TOOLS_BRUSH_SHEARBRUSH, OnToolsBrushShearbrush)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_BRUSH_SHEARBRUSH, OnUpdateToolsBrushShearbrush)
	ON_UPDATE_COMMAND_UI(ID_GROUPS_MAKENEWGROUP, OnUpdateBrushGroupsMakenewgroup)
	ON_UPDATE_COMMAND_UI(ID_BRUSH_GROUPS_ADDTOGROUP, OnUpdateBrushGroupsAddtogroup)
	ON_COMMAND(ID_TOOLS_BRUSH_ROTATE90, OnToolsBrushRotate45)
	ON_COMMAND(ID_TOOLS_BRUSH_MOVESELECTEDBRUSHES, OnToolsBrushMoveselectedbrushes)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_BRUSH_MOVESELECTEDBRUSHES, OnUpdateToolsBrushMoveselectedbrushes)
	ON_COMMAND(ID_TOOLS_TEMPLATE, OnToolsTemplate)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_TEMPLATE, OnUpdateToolsTemplate)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_BRUSH_ROTATE90, OnUpdateToolsBrushRotate45)
	ON_COMMAND(ID_BRUSH_REMOVESELECTEDFROMGROUP, OnBrushRemoveselectedfromgroup)
	ON_UPDATE_COMMAND_UI(ID_BRUSH_REMOVESELECTEDFROMGROUP, OnUpdateBrushRemoveselectedfromgroup)
	ON_COMMAND(ID_BRUSH_GROUPS_ADDTOGROUP, OnBrushGroupsAddtogroup)
	ON_COMMAND(ID_DESELECTALL, OnDeselectall)
	ON_UPDATE_COMMAND_UI(ID_DESELECTALL, OnUpdateDeselectall)
	ON_COMMAND(ID_SELECTALL, OnSelectall)
	ON_UPDATE_COMMAND_UI(ID_SELECTALL, OnUpdateSelectall)
	ON_COMMAND(ID_TOOLS_SCALEWORLD, OnToolsScaleworld)
	ON_COMMAND(ID_TOOLS_BRUSH_MAKENEWEST, OnToolsBrushMakenewest)
	ON_COMMAND(ID_TOOLS_SETTEXTURESCALE, OnToolsSettexturescale)
	ON_COMMAND(ID_TOOLS_NEXTBRUSH, OnToolsNextbrush)
	ON_COMMAND(ID_TOOLS_PREVBRUSH, OnToolsPrevbrush)
	ON_COMMAND(ID_TOOLS_ADDTOLEVEL, OnToolsAddtolevel)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_ADDTOLEVEL, OnUpdateToolsAddtolevel)
	ON_COMMAND(ID_VIEW_ZOOMIN, OnViewZoomin)
	ON_UPDATE_COMMAND_UI(ID_VIEW_ZOOMIN, OnUpdateViewZoomin)
	ON_COMMAND(ID_VIEW_ZOOMOUT, OnViewZoomout)
	ON_UPDATE_COMMAND_UI(ID_VIEW_ZOOMOUT, OnUpdateViewZoomout)
	ON_COMMAND(ID_CENTERTHING, OnCenterthing)
	ON_UPDATE_COMMAND_UI(ID_CENTERTHING, OnUpdateCenterthing)
	ON_WM_CONTEXTMENU()
	ON_COMMAND(ID_TOOLS_BRUSH_ROTATEBRUSH, OnToolsBrushRotatebrush)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_BRUSH_ROTATEBRUSH, OnUpdateToolsBrushRotatebrush)
	ON_WM_MBUTTONUP()
	ON_WM_MOUSEWHEEL()	//	posthoot
	ON_WM_MBUTTONDOWN()	//	posthoot
	ON_WM_MBUTTONUP()	//posthoot
	ON_COMMAND(IDC_BTN_REBUILD_COMMAND, OnButtonRebuildShow)//	post 0.57
	ON_COMMAND(IDC_BTN_REBUILD_HIDE, OnButtonRebuildHide)//	post 0.57
	ON_BN_CLICKED(IDC_BTN_VIEW_REBUILD, OnButtonRebuild)//	post 0.57

	//}}AFX_MSG_MAP
	ON_COMMAND_RANGE( ID_VIEW_3DWIREFRAME, ID_VIEW_TEXTUREVIEW, OnViewType)
	ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_3DWIREFRAME, ID_VIEW_TEXTUREVIEW, OnViewTypeCmdUi)
END_MESSAGE_MAP()


#define SIDE_LEFT 1
#define SIDE_RIGHT 2
#define SIDE_TOP 4
#define SIDE_BOTTOM 8


//	post 0.57	notifies user of need to rebuild
//	see pDoc::SelectRay for origin of message
void CGenEditView::OnButtonRebuildShow()
{
	if (mViewType == ID_VIEW_TEXTUREVIEW)
	{
	if (m_btnRebuild)
	{
		if (!m_btnRebuild.IsWindowVisible())
		{
			m_btnRebuild.ShowWindow(SW_SHOW);
			CGenEditDoc *pDoc = GetDocument();
			pDoc->PlayResource("SND_QUICKBEEP");
		}
	}
	}
}

//	post 0.57	notifies user of need to rebuild
//	see pDoc::OngbspnoWater for origin of message
void CGenEditView::OnButtonRebuildHide()
{
	if (mViewType == ID_VIEW_TEXTUREVIEW)
	{
		if (m_btnRebuild)
		{
			if (m_btnRebuild.IsWindowVisible())
			{
				m_btnRebuild.ShowWindow(SW_HIDE);
			}
		}
	}
}


//	post 0.57
void CGenEditView::OnButtonRebuild()
{
	if (mViewType == ID_VIEW_TEXTUREVIEW)
	{
		CGenEditDoc *pDoc = GetDocument ();
		pDoc->UpdateAllViews( UAV_ALL3DVIEWS | REBUILD_QUICK, NULL, TRUE ); //post 0.57

		if (m_btnRebuild.IsWindowVisible())
		{
			m_btnRebuild.ShowWindow(SW_HIDE);
		}
		CGlobals::g_iRebuildClickCount = 0;
	}
}



void CGenEditView::OnUpdateCenterthing(CCmdUI* pCmdUI) 
{
	CGenEditDoc *pDoc = GetDocument ();

	if ((pDoc->mModeTool == ID_TOOLS_TEMPLATE) &&
	    ((mViewType == ID_VIEW_TOPVIEW) || (mViewType == ID_VIEW_SIDEVIEW) || (mViewType == ID_VIEW_FRONTVIEW)))
	{
		pCmdUI->Enable (TRUE);
	}
	else
	{
		pCmdUI->Enable (FALSE);
	}
}

// Center the template brush or entity in the selected view.
// Doesn't work for 3d views...
void CGenEditView::OnCenterthing()
{
	CGenEditDoc *pDoc = GetDocument ();
	// only works on templates
	if ((pDoc->mModeTool != ID_TOOLS_TEMPLATE) ||
	    ((mViewType != ID_VIEW_TOPVIEW) && (mViewType != ID_VIEW_SIDEVIEW) && (mViewType != ID_VIEW_FRONTVIEW)))
	{
		return;
	}

	geVec3d NewWorldPos = Render_GetViewCenter (VCam);

	// Get the current thing's position...
	geVec3d CurrentThingPos;

	if (pDoc->TempEnt)
	{
		CurrentThingPos = pDoc->mRegularEntity.mOrigin;
	}
	else
	{
		if (pDoc->CurBrush == NULL)
		{
			return;
		}
		Brush_Center (pDoc->CurBrush, &CurrentThingPos);
	}

	// Compute delta required to get thing to NewWorldPos.
	// One dimension won't be changed (i.e. in the top view, the Y won't be modified)
	geVec3d MoveDelta;

	geVec3d_Subtract (&NewWorldPos, &CurrentThingPos, &MoveDelta);

	switch (mViewType)
	{
		case ID_VIEW_TOPVIEW :
			MoveDelta.Y = 0.0f;
			break;

		case ID_VIEW_SIDEVIEW :
			MoveDelta.X = 0.0f;
			break;

		case ID_VIEW_FRONTVIEW :
			MoveDelta.Z = 0.0f;
			break;

		default :
			// don't do nothin!
			assert (0);
	}

	// We've computed the delta, so move the thing...
	pDoc->MoveTemplateBrush (&MoveDelta);

	//	Be very careful when speccing flags for UpdateAllViews()
	//	The wrong flags at the wrong time will totally screw things up
	pDoc->UpdateAllViews( UAV_ALL3DVIEWS, NULL );
}

static geBoolean IsKeyDown (int Key)
{
	int KeyState;

	KeyState = ::GetAsyncKeyState (Key);
	return (KeyState & 0x8000);
}

// Prevent axis movement.  View space clipping.
void CGenEditView::LockAxisView (int *dx, int *dy)
{
	CGenEditDoc *pDoc = GetDocument ();
	int mLockAxis = pDoc->GetLockAxis ();

	switch (mViewType)
	{
		case ID_VIEW_TOPVIEW :
			if (mLockAxis & AXIS_X) *dx = 0;
			if (mLockAxis & AXIS_Z) *dy = 0;
			break;

		case ID_VIEW_SIDEVIEW :
			if (mLockAxis & AXIS_X) *dx = 0;
			if (mLockAxis & AXIS_Y) *dy = 0;
			break;
			
		case ID_VIEW_FRONTVIEW :
			if (mLockAxis & AXIS_Z) *dx = 0;
			if (mLockAxis & AXIS_Y) *dy = 0;
			break;
	}
}

// Prevent axis movement.  World space clipping.
void CGenEditView::LockAxis( geVec3d * pWP )
{
	int mLockAxis ;
	CGenEditDoc* pDoc = GetDocument();

	mLockAxis = pDoc->GetLockAxis() ;

	if( mLockAxis & AXIS_X )	pWP->X = 0.0f ;
	if( mLockAxis & AXIS_Y )	pWP->Y = 0.0f ;
	if( mLockAxis & AXIS_Z )	pWP->Z = 0.0f ;
}/* CGenEditView::LockAxis */

void CGenEditView::OnToolsBrushRotate45()
{
	geVec3d	rp;

	static int i_reminder;	//	so this messagebox only shows up once

	CGenEditDoc* pDoc = GetDocument();
		//	post 0.57
	CString message = _T("If you choose this control while the Textured View is active,\n");
			message += _T("rotation will NOT occur.\n\n");
			message += _T("In order to get rotation in the view of your choice,\n");
			message += _T("make sure your view is active (highlighted).\n\n");
			message += _T("We recommend that you use the menu item for this control\n");
			message += _T("on the right-click context menu while in the view of your choice.");

	geVec3d_Clear (&rp);
	switch (mViewType)
	{
	case ID_VIEW_TEXTUREVIEW:	//	post 0.57
		if (i_reminder <1)		//	deliver the reminder once
		{
			AfxMessageBox(message);
			i_reminder++;
		}
		break;
		case ID_VIEW_TOPVIEW:	//	if textured view is highlighted, rotation will occur
			rp.Y = -(M_PI/4.0f);//	in the topo view
			break;
		case ID_VIEW_FRONTVIEW :
			rp.Z = -(M_PI/4.0f);
			break;
		case ID_VIEW_SIDEVIEW:
			rp.X = (M_PI/4.0f);
			break;
		default :
			return;
	}

	if(GetModeTool()!=ID_GENERALSELECT)
	{
		pDoc->RotateTemplateBrush(&rp);
		pDoc->UpdateSelected();	// calls UpdateMainControls()
		//	Be very careful when speccing flags for UpdateAllViews()
		//	The wrong flags at the wrong time will totally screw things up
		pDoc->UpdateAllViews(UAV_ALL3DVIEWS, NULL);
	}
	else
	{
		pDoc->RotateSelectedBrushesDirect (&rp);
		//	Be very careful when speccing flags for UpdateAllViews()
		//	The wrong flags at the wrong time will totally screw things up
		//	Make sure REBUILD_QUICK is absolutely necessary.
		pDoc->UpdateAllViews(UAV_ALL3DVIEWS | REBUILD_QUICK, NULL);
	}

	//	post 0.57	send a message to display the Rebuild button on the textured view
	int ModeTool = GetModeTool ();
	int AdjustMode = GetAdjustMode ();
	if ((ModeTool == ID_GENERALSELECT) && (AdjustMode == ADJUST_MODE_BRUSH))
	{
		if(!Level_RebuildBspAlways(pDoc->pLevel))	
		{
			pDoc->mpMainFrame->SendMessageToDescendants(WM_COMMAND, IDC_BTN_REBUILD_COMMAND);
			CGlobals::g_iRebuildClickCount = 0;
		}
	}
}


int CGenEditView::GetCursorBoxPos (const POINT *ptMousePos)
{
	CGenEditDoc *pDoc;
	const Box3d *pBrushBox;
	POINT ptMin, ptMax;
	int dx, dy;
	int x, y;
	int horiz, vert;
	int lookup[4] = {1, 2, 2, 3};

	/*
	  Split the box up into 3 sections vertically and 3 horizontally.
	  The center sections are 1/2 the width and height, and the end sections are
	  each 1/4 of width and height.

	  What we're creating is:

			0	   1       2        3	  4
				------------------------
				|     |          |     |
			5	|  6  |    7     |  8  |  9
				------------------------
				|     |          |     |
				|     |          |     | 
		   10	|  11 |   12     |  13 |  14
				|     |          |     |
				------------------------
				|     |          |     | 
		   15	|  16 |   17     |  18 |  19
				------------------------
		   20      21	  22	    23	  24
	  
	  Then we determine which of the sections the cursor is closest to,
	  and return that index.
	*/

	pDoc = GetDocument ();

	pBrushBox = Brush_GetBoundingBox (pDoc->CurBrush);

	// obtain screen coordinates for bounding box min and max points
	ptMin = Render_OrthoWorldToView (VCam, &pBrushBox->Min);
	ptMax = Render_OrthoWorldToView (VCam, &pBrushBox->Max);

	// make sure the min and max points are correct...
	if (ptMin.x > ptMax.x)
	{
		int temp;

		temp = ptMin.x;
		ptMin.x = ptMax.x;
		ptMax.x = temp;
	}
	if (ptMin.y > ptMax.y)
	{
		int temp;

		temp = ptMin.y;
		ptMin.y = ptMax.y;
		ptMax.y = temp;
	}

	// compute horizontal first
	x = ptMousePos->x - ptMin.x;
	dx = (ptMax.x - ptMin.x);
	if (dx == 0) horiz = 0; else horiz = (4*x) / dx;
	if (horiz < 0) horiz = 0;
	else if (horiz > 3) horiz = 4;
	else horiz = lookup[horiz];

	// and vertical
	y = ptMousePos->y - ptMin.y;
	dy = (ptMax.y - ptMin.y);
	if (dy == 0) vert = 0; else vert = (4*y)/dy;
	if (vert < 0) vert = 0;
	else if (vert > 3) vert = 3;
	else vert = lookup[vert];

	// return index...
	return (vert * 5) + horiz;
}

void CGenEditView::SetEditCursor (int Tool, const POINT *pMousePos)
{
	//for sizing stuff
	static const char *SizeCursors[25]=
	{
		IDC_SIZENWSE,	IDC_SIZENWSE,	IDC_SIZENS,		IDC_SIZENESW,	IDC_SIZENESW,
		IDC_SIZENWSE,	IDC_SIZENWSE,	IDC_SIZENS,		IDC_SIZENESW,	IDC_SIZENESW,	
		IDC_SIZEWE,		IDC_SIZEWE,		IDC_NO,			IDC_SIZEWE,		IDC_SIZEWE,
		IDC_SIZENESW,	IDC_SIZENESW,	IDC_SIZENS,		IDC_SIZENWSE,	IDC_SIZENWSE,
		IDC_SIZENESW,	IDC_SIZENESW,	IDC_SIZENS,		IDC_SIZENWSE,	IDC_SIZENWSE
	};

	static const char *ShearCursors[25]=
	{
		IDC_NO,			IDC_SIZEWE,		IDC_SIZEWE,		IDC_SIZEWE,		IDC_NO,
		IDC_SIZENS,		IDC_NO,			IDC_SIZEWE,		IDC_NO,			IDC_SIZENS,
		IDC_SIZENS,		IDC_SIZENS,		IDC_NO,			IDC_SIZENS,		IDC_SIZENS,
		IDC_SIZENS,		IDC_NO,			IDC_SIZEWE,		IDC_NO,			IDC_SIZENS,
		IDC_NO,			IDC_SIZEWE,		IDC_SIZEWE,		IDC_SIZEWE,		IDC_NO
	};

	const char *WhichCursor = NULL;
	int CursorIndex;

	assert ((Tool == ID_TOOLS_BRUSH_SCALEBRUSH) || (Tool == ID_TOOLS_BRUSH_SHEARBRUSH));

	// Determine where the cursor is on the box surrounding the selected brush,
	// and set the appropriate cursor.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -