📄 chmaze.cpp
字号:
/*----------------------------------------------------------------------------
_ _ _
/\ | | | (_)
/ \ _ __ __| |_ __ ___ _ __ ___ ___ __| |_ __ _
/ /\ \ | '_ \ / _` | '__/ _ \| '_ ` _ \ / _ \/ _` | |/ _` |
/ ____ \| | | | (_| | | | (_) | | | | | | __/ (_| | | (_| |
/_/ \_\_| |_|\__,_|_| \___/|_| |_| |_|\___|\__,_|_|\__,_|
The contents of this file are subject to the Andromedia Public
License Version 1.0 (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.andromedia.com/APL/
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 Pueblo client code, released November 4, 1998.
The Initial Developer of the Original Code is Andromedia Incorporated.
Portions created by Andromedia are Copyright (C) 1998 Andromedia
Incorporated. All Rights Reserved.
Andromedia Incorporated 415.365.6700
818 Mission Street - 2nd Floor 415.365.6701 fax
San Francisco, CA 94103
Contributor(s):
--------------------------------------------------------------------------
Chaco team: Dan Greening, Glenn Crocker, Jim Doubek,
Coyote Lussier, Pritham Shetty.
Wrote and designed original codebase.
------------------------------------------------------------------------------
Implementation for the ChGraphicMaze class, which is used to display VRML.
----------------------------------------------------------------------------*/
// $Header: /home/cvs/chaco/modules/client/msw/ChGraphx/ChMaze.cpp,v 2.148 1996/09/20 20:46:20 jimd Exp $
#include "grheader.h"
#if !defined(CH_VRML_VIEWER) && !defined(CH_VRML_PLUGIN ) && !defined( CH_PUEBLO_PLUGIN )
#include "resource.h"
#else
#include "vwrres.h"
#endif
#include <ChReg.h>
#include <ChURLMap.h>
#if !defined(CH_VRML_VIEWER) && !defined(CH_VRML_PLUGIN )
#include <ChCore.h>
#include "ChGrMod.h"
#endif
#include <ChHTTP.h>
#include <ChUtil.h>
#include <QvNode.h>
#include <QvState.h>
#include <QvReadError.h>
#include <QvChildList.h>
#include <fstream.h>
#include <strstrea.h>
#include "ChMaze.h"
#include "ChMazCam.h"
#include "CvHitTst.h"
#include "ChQvPars.h"
#include "ChGrStrm.h"
#include "ChRenderData.h"
#include "ChMazDep.h"
// Change to real one when ready for scout version
#if defined(CH_VRML_EVENTS) && !defined( CH_VRML_PLUGIN )
#include "ChStubBrowser.h"
#endif
#include "ChVrmlTransition.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define NOT_IMPLEMENTED TRACE2("Function not implemented, file %s: line %s.", __FILE__, __LINE__)
/*----------------------------------------------------------------------------
Key map constants
----------------------------------------------------------------------------*/
#define ACTION_FORWARD "Forward"
#define ACTION_BACKWARD "Backward"
#define ACTION_LEFT "Left"
#define ACTION_RIGHT "Right"
#define ACTION_UP "Up"
#define ACTION_DOWN "Down"
#define ACTION_TURN_LEFT "Turn left"
#define ACTION_TURN_RIGHT "Turn right"
#define ACTION_TURN_UP "Turn up"
#define ACTION_TURN_DOWN "Turn down"
#define ACTION_ROLL_LEFT "Roll left"
#define ACTION_ROLL_RIGHT "Roll right"
#define ACTION_GO_FASTER "Faster"
#define ACTION_GO_SLOWER "Slower"
#define ACTION_WALK "Walk Mode"
#define ACTION_FLY "Fly Mode"
#define ACTION_EXAMINE "Examine Mode"
#define ACTION_BRIGHTER "Brighter"
#define ACTION_DIMMER "Dimmer"
#define ACTION_NEXT_CAMERA "Next Camera"
#define ACTION_PREV_CAMERA "Prev Camera"
#define ACTION_RESET_CAMERA "Reset Camera"
#define KEY_WALK 'W'
#define KEY_FLY 'F'
#define KEY_EXAMINE 'E'
#define KEY_BRIGHTER 'B'
#define KEY_DIMMER 'D'
#define KEY_RESET_CAMERA VK_HOME
#define ACTION_MOD_SHIFT (1L << 0)
#define ACTION_MOD_CONTROL (1L << 1)
const int defStepsPerWorld = 100;
const int defMoveAmount = 10; // obsolete
const float defUserSpeed = 1;
const float minUserSpeed = .1;
const float maxUserSpeed = 10.;
int ChMazeWnd::m_iObjectCount = 0;
/*----------------------------------------------------------------------------
Action enum
----------------------------------------------------------------------------*/
typedef enum { walkMode = 1, flyMode, examineMode, beBrighter, beDimmer,
goNextCamera, goPrevCamera, goFaster, goSlower, resetCamera } KeyAction;
/*----------------------------------------------------------------------------
ChMazeWnd class
----------------------------------------------------------------------------*/
#if defined(CH_VRML_VIEWER)
#undef new
IMPLEMENT_DYNCREATE( ChMazeWnd, ChGraphicView )
#endif
#if defined(CH_VRML_VIEWER) || defined(CH_VRML_PLUGIN )
ChMazeWnd::ChMazeWnd() :
m_pHttpConn( 0 ),
m_pSettings( 0 ),
ChGraphicView(),
m_pGraphicStream(0),
#else
ChMazeWnd::ChMazeWnd( ChMazeMainInfo *pInfo, ChVrmlSettings *pSettings ) :
ChGraphicView( pInfo ),
m_pSettings(pSettings),
#endif
m_pRoot( 0 ),
m_pCameraControl( 0 ),
m_pBounds(0),
m_fUserSpeedFactor(defUserSpeed),
m_boolInMouseAnchor( false ),
m_boolInMouseMove( false ),
m_boolMoving(false),
m_sCrosshairHalfWidth( 20 ),
m_sCrosshairHalfHeight( 20 ),
m_pageCount (0),
m_uiMoveTimer( 0 ),
m_uiTickTimer( 0 ),
m_pAnchor( 0 ),
m_hParseThreadEvent( 0 ),
m_boolMouseMove(false),
#if defined(CH_VRML_EVENTS) && !defined( CH_VRML_PLUGIN )
m_pVrmlBrowser(0),
#endif
m_pScoutMenu( 0 ),
m_hCameraMenu(0)
{
m_iObjectCount++; // Total number of maze objects
m_pCameraControl = new ChMazeCameraControl( this );
m_keyMap.AddItem( KEY_WALK, ACTION_MOD_CONTROL, ACTION_WALK, walkMode );
m_keyMap.AddItem( KEY_FLY, ACTION_MOD_CONTROL, ACTION_FLY, flyMode );
m_keyMap.AddItem( KEY_EXAMINE, ACTION_MOD_CONTROL, ACTION_EXAMINE, examineMode );
m_keyMap.AddItem( KEY_BRIGHTER, ACTION_MOD_CONTROL, ACTION_BRIGHTER, beBrighter );
m_keyMap.AddItem( KEY_DIMMER, ACTION_MOD_CONTROL, ACTION_DIMMER, beDimmer );
m_keyMap.AddItem( VK_ADD, 0, ACTION_GO_FASTER, goFaster );
m_keyMap.AddItem( VK_SUBTRACT, 0, ACTION_GO_SLOWER, goSlower );
m_keyMap.AddItem( VK_NEXT, 0, ACTION_NEXT_CAMERA, goNextCamera );
m_keyMap.AddItem( VK_PRIOR, 0, ACTION_PREV_CAMERA, goPrevCamera );
m_keyMap.AddItem( KEY_RESET_CAMERA, 0, ACTION_RESET_CAMERA, resetCamera );
#if !defined(CH_VRML_VIEWER) && !defined(CH_VRML_PLUGIN ) && !defined(CH_PUEBLO_PLUGIN )
if ( ChUtil::GetSystemType() == CH_SYS_WIN32S ||
ChUtil::GetSystemType() == CH_SYS_WIN3X )
{
m_hAnchorCursor = ::LoadCursor( ChGraphicsDLL.hModule,
MAKEINTRESOURCE( IDC_HANDMONO ));
}
else
{
m_hAnchorCursor = ::LoadCursor( ChGraphicsDLL.hModule,
MAKEINTRESOURCE( IDC_PICKER ));
}
#else
#if defined(CH_VRML_VIEWER)
if ( ChUtil::GetSystemType() == CH_SYS_WIN32S ||
ChUtil::GetSystemType() == CH_SYS_WIN3X )
{
m_hAnchorCursor = ::LoadCursor( AfxGetResourceHandle(),
MAKEINTRESOURCE( IDC_HANDMONO ));
}
else
{
m_hAnchorCursor = ::LoadCursor( AfxGetResourceHandle(),
MAKEINTRESOURCE( IDC_PICKER ));
}
#else
if ( ChUtil::GetSystemType() == CH_SYS_WIN32S ||
ChUtil::GetSystemType() == CH_SYS_WIN3X )
{
m_hAnchorCursor = ::LoadCursor( AfxGetInstanceHandle(),
MAKEINTRESOURCE( IDC_HANDMONO ));
}
else
{
m_hAnchorCursor = ::LoadCursor( AfxGetInstanceHandle(),
MAKEINTRESOURCE( IDC_PICKER ));
}
#endif
#endif
m_hCursor = ::LoadCursor( NULL, IDC_ARROW );
m_pNavigators[walk] = new ChVrmlWalkSTM(this);
m_pNavigators[fly] = new ChVrmlFlySTM(this);
m_pNavigators[examine] = new ChVrmlExaminerSTM(this);
}
ChMazeWnd::~ChMazeWnd()
{
m_iObjectCount--; // Total number of Maze objects
delete m_pNavigators[walk];
delete m_pNavigators[fly];
delete m_pNavigators[examine];
if ( m_pScoutMenu )
{
delete m_pScoutMenu;
}
if (0 != m_pCameraControl)
{
delete m_pCameraControl;
}
ClearAnchors();
delete m_pBounds;
m_pBounds = 0;
if( m_hParseThreadEvent )
{
::CloseHandle( m_hParseThreadEvent );
m_hParseThreadEvent = 0;
::DeleteCriticalSection( &m_syncParser );
}
#if defined(CH_VRML_EVENTS) && !defined( CH_VRML_PLUGIN )
delete m_pVrmlBrowser;
#endif
// Cleanup HTTP Stream
#if defined(CH_VRML_VIEWER) || defined(CH_VRML_PLUGIN )
GetHTTPConn()->SetStreamMgr(m_pGraphicStream->GetNextStreamMgr());
delete m_pGraphicStream;
#endif
}
#if defined(CH_VRML_VIEWER) || defined(CH_VRML_PLUGIN )
void ChMazeWnd::InitMazeView( ChHTTPConn *httpConn, ChVrmlSettings *pSettings )
{
m_pHttpConn = httpConn;
m_pSettings = pSettings;
m_pGraphicStream = new ChGraphicStreamManager( GetHTTPConn()->GetStreamMgr() );
ASSERT( m_pGraphicStream );
GetHTTPConn()->SetStreamMgr( m_pGraphicStream );
}
#endif
// Added by VSP : Cleanup QV on exit
void ChMazeWnd::TermMazeWnd()
{
if ( 0 == m_iObjectCount )
{
QvDB::term();
}
}
BEGIN_MESSAGE_MAP(ChMazeWnd, ChGraphicView)
//{{AFX_MSG_MAP(ChMazeWnd)
ON_WM_SIZE()
ON_WM_CHAR()
ON_WM_LBUTTONDBLCLK()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
ON_WM_RBUTTONDBLCLK()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
ON_WM_DESTROY()
ON_WM_TIMER()
ON_WM_SETCURSOR()
ON_WM_PAINT()
ON_COMMAND(IDM_CAMERA_NEXT, OnCameraNext)
ON_COMMAND(IDM_CAMERA_PREV, OnCameraPrev)
ON_COMMAND(ID_OPT_RESET_SPEED, OnOptResetSpeed)
ON_COMMAND(IDM_OPTIMIZE_BETTER, OnOptimizeBetter)
ON_COMMAND(IDM_OPTIMIZE_FASTER, OnOptimizeFaster)
ON_WM_PALETTECHANGED()
ON_WM_QUERYNEWPALETTE()
ON_COMMAND(IDM_COLLISION_CHECKING, OnCollisionChecking)
//}}AFX_MSG_MAP
ON_WM_SYSKEYDOWN()
ON_WM_SYSKEYUP()
ON_MESSAGE( WM_VRML_PREF_CHANGE, OnPrefChange )
ON_MESSAGE( WM_VRML_PROGRESS, OnProgressMsg )
ON_MESSAGE( WM_VRML_PARSE_ERROR, OnParseError)
ON_MESSAGE( WM_VRML_PARSE_DONE, OnParseComplete )
ON_MESSAGE( WM_VRML_LOAD_TEXTURE, OnLoadTexture )
ON_MESSAGE( WM_VRML_EVENT, OnVrmlEvent )
ON_MESSAGE( WM_VRML_ACTIVATE, OnActivateWnd )
ON_MESSAGE( WM_VRML_MAZE_ERROR, OnMazeError)
ON_COMMAND(ID_OPT_HEADLIGHT_SWITCH, OnHeadlightSwitch)
ON_COMMAND(ID_VIEW_RESET_CAMERA, OnResetCamera)
ON_COMMAND(IDM_BRIGHTEN, OnBrighten)
ON_COMMAND(IDM_DIMMER, OnDimmer)
ON_COMMAND(IDM_EXAMINE, OnExamine)
ON_COMMAND(IDM_FLY, OnFly)
ON_COMMAND(IDM_WALK, OnWalk)
ON_WM_INITMENUPOPUP()
ON_COMMAND_RANGE(IDM_CAMERA_FIRST, IDM_CAMERA_LAST, OnCameraMenuCommand)
ON_UPDATE_COMMAND_UI_RANGE(IDM_CAMERA_FIRST, IDM_CAMERA_LAST, OnCameraMenuUpdateCommand)
END_MESSAGE_MAP()
/*----------------------------------------------------------------------------
ChMazeWnd drawing
----------------------------------------------------------------------------*/
void ChMazeWnd::OnInitialUpdate()
{
ChGraphicView::OnInitialUpdate();
#if !defined(CH_VRML_VIEWER) && !defined(CH_VRML_PLUGIN )
CSize sizeTotal;
// TODO: calculate the total size of this view MAKE THE BARS GO AWAY _ HACK
sizeTotal.cx = sizeTotal.cy = 1;
SetScrollSizes(sizeTotal);
#endif
}
#if 0
bool ChMazeWnd::LoadBackground( const string & strURL )
{
if (!m_dibBkgnd.Load((char *)(LPCTSTR(strURL)))) {
return false;
}
// Create a new buffer
// and palette
// m_spriteList.m_NotifyObj.SetView(this);
NewBackground(&m_dibBkgnd);
return true;
}
#endif
void ChMazeWnd::OnPaletteChanged(CWnd* pFocusWnd)
{
/* See if the change was caused by
us and ignore it if so */
if (pFocusWnd != this)
{
#if 0
//OnQueryNewPalette(); // ????????????????????????
#else
{ /* Prevent background technicolor.
3dr takes care of foreground
querynewpalette */
CDC* pDC = GetDC();
UINT u = pDC->RealizePalette();
ReleaseDC( pDC );
GetRenderContext()->SetDirty();
InvalidateRect( 0, false ); // Repaint the lot
}
#endif
}
}
// Note: Windows actually ignores the return value.
BOOL ChMazeWnd::OnQueryNewPalette()
{
//R3dApplyNewPalette( m_RC.GetRC());
return false; // Say we did nothing.
// We are going active so realize our palette.
//if (m_pPal)
{
CDC* pdc = GetDC();
//CPalette* poldpal = pdc->SelectPalette(m_pPal, false);
UINT u = pdc->RealizePalette(); // ??????????????????????
ReleaseDC(pdc);
if (u != 0) {
// Some colors changed so we need to do a repaint.
return true; // Say we did something.
}
}
GetRenderContext()->SetDirty();
InvalidateRect(0, false); // Repaint the lot. not fast, but better than technicolor
return false; // Say we did nothing.
}
bool ChMazeWnd::Create( const CRect& rtView, CWnd* pParent, DWORD dwStyle,
UINT uiID )
{
bool boolSuccess;
boolSuccess = ChGraphicView::Create( rtView, pParent, dwStyle, uiID );
if (boolSuccess)
{
/* set up our 3dr rc and gc; assumes we have CS_OWNDC*/
SetupContexts();
}
return boolSuccess;
}
void ChMazeWnd::SetupContexts()
{
if(!m_RC.GetRC())
{
m_RC.Init( this, GetDC() );
}
}
void ChMazeWnd::SetGlobalHints()
{
ChQvGlobalSearchState state( this );
SetupContexts();
m_pRoot->traverse( &state );
m_fAspect = state.GetAspect();
m_backGroundColor = state.GetBackground();
m_boolLightOn = state.GetLightOn();
#if 0
m_sceneViewerMode = state.GetViewerMode();
m_sceneCollisionMode = state.GetCollisionMode();
#endif
if(state.GetViewerMode() != none) // will be invalid if not spec'd in file
{
GetSettings()->SetViewerMode(state.GetViewerMode());
}
if(state.GetCollisionMode() != invalidCollisionMode)
{
GetSettings()->SetCollisionMode(state.GetCollisionMode());
}
if(!m_boolLightOn && !IsHeadlightOn()) SetHeadlight(true); // Force headlight on if no scene light
}
void ChMazeWnd::SetupTreeDefaults()
{
SetupContexts();
GetRenderContext()->NewDefaultCamera()->SetCurrentCamera();
}
void ChMazeWnd::Draw( CDC* pDC, RECT* pRect )
{
CDC* pUseDC;
#if defined( CH_USE_3DR )
if(!m_RC.IsDirty()) return;
CRect rcDraw;
SetupContexts();
ClearAnchors();
/* Make sure we have what we need
to do a paint */
if (!m_pRoot)
{
return;
}
#endif
/* See if a DC was supplied, and
get one if not */
if (pDC)
{
pUseDC = pDC;
}
else
{
pUseDC = GetDC();
#if !defined( CH_VRML_PLUGIN )
ChViewBaseClass::OnPrepareDC( pUseDC ); // jwd
#endif
}
#if defined( CH_USE_3DR )
/* See if a clip rect was supplied,
and use the client area if not */
if (pRect)
{
rcDraw = *pRect; // this is in logicals; jwd
}
else
{
GetClientRect( rcDraw );
pUseDC->DPtoLP( LPRECT( rcDraw ) ); // fixed scrolling bug; jwd
}
pUseDC->RealizePalette(); // ???
{
CRect rcClient;
GetClientRect( rcClient );
if ((rcClient.bottom > 1) && (rcClient.right > 1))
{
// make 3dr contexts for our dc
// this is all moved to create
//m_hRC = R3dCreateRC((DWORD)(pDC->GetSafeHdc()), R3D_RI_DOUBLE_BUFFER /*R3D_RI_DEFAULT*/);
//R3dSetState( m_hRC, R3D_STA_ENABLES, R3D_SE_Z_BUFFERING);
//R3dSetState( m_hRC, R3D_STA_DISABLES, R3D_SE_CLIPPING);
//m_hGC = G3dCreateGC( m_hRC);
Fixed32_t on = 1;
Fixed32_t off = 0;
ChShadingLevel userShadingPref;
G3dSetState( m_RC.GetGC(), G3DL_FRONT_CCW, &off);
// Init the rendering context or whatever
G3dSetWindowSize(m_RC.GetGC(), Float_t(rcClient.right), Float_t(rcClient.bottom));
R3dSetState( m_RC.GetRC(), R3D_STA_BG_COLOR, GetBackgroundColorL()); // use the hint
// Set the shading appropriately
if (IsMoving())
{
userShadingPref = GetSettings()->GetMoveRenderQuality();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -