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

📄 chmaze.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			}
			else
			{
				userShadingPref = GetSettings()->GetRenderQuality();
			}
			m_RC.SetShadingPref(userShadingPref);
			

			R3dClearBuffers( m_RC.GetRC(),
								R3D_CI_DRAW_BUFFER | R3D_CI_ZBUFFER );
			G3dClearStack( m_RC.GetGC() );
											/* Turn off texturing except when
												we encounter one; then do it at
												draw prim time */

			R3dSetState( m_RC.GetRC(), R3D_STA_DISABLES, R3D_SE_TEXTURING );
			R3dSetState( m_RC.GetRC(), R3D_STA_TEX_ID, (Dword_t)(0) );
			R3dSetState( m_RC.GetRC(), R3D_STA_DISABLES, R3D_SE_MODULATION );
			G3dSetState( m_RC.GetGC(), G3DL_TEXTURE_MOD, &off );



			//ChQvState	state( this );

			TRACE( "Drawing the tree\r\n" );

			#if !defined(CH_VRML_VIEWER) && !defined(CH_VRML_PLUGIN )
			// TODO
			m_pMainInfo->StartFrameTime();
			#else
			StartFrameTime();
			#endif

	    	if (m_pRoot)
	    	{
				if(m_RC.Draw())
				{
					POINT	ptCursor;

					GetCursorPos( &ptCursor );
					ScreenToClient( &ptCursor );
					IsAnchor(ptCursor.x, ptCursor.y);		// update the status line
				}
			}

			#if !defined(CH_VRML_VIEWER) && !defined(CH_VRML_PLUGIN )
			m_pMainInfo->EndFrameTime();
			#else
			EndFrameTime();
			#endif
			R3dSwapBuffers( m_RC.GetRC(), 0 );
		}
	}
	#else
	#endif	// defined( CH_USE_3DR )

	if (IsInMouseMove())
	{
		DrawMouseMoveCrosshair( pDC );
		DrawMouseMoveVector( pDC );
	}
    										/* Release the DC if it was one
    											we created */
    if (0 == pDC)
    {
    	ReleaseDC( pUseDC );
	}
}


// Render the scene to the off-screen buffer
// pClipRect defaults to 0
void ChMazeWnd::Render(CRect* pClipRect)
{
}


bool ChMazeWnd::NotifyPaletteChange( UINT uMsg, CWnd* pFocusWnd )
{
	bool boolIsProcessed = false;

	if (IsCurrent())
	{
		switch( uMsg )
		{
			case WM_PALETTECHANGED:
			{
				OnPaletteChanged( pFocusWnd );

				//SendMessage(WM_PALETTECHANGED, WORD(pFocusWnd->GetSafeHwnd( )));
				break;
			}
			case WM_QUERYNEWPALETTE:
			{
											/* 3DR is apparently hooking the
												window with the DC passed to
												CreateRC to get this message */

				boolIsProcessed = true;
				SendMessage( WM_QUERYNEWPALETTE );
				GetRenderContext()->SetDirty();
				InvalidateRect( 0, false );
				break;
			}
		}
	}

	return boolIsProcessed;
}

void ChMazeWnd::AdjustLight(string strCmd, int iLight, float fLevel)
{
	ChQvState state(this, strCmd, iLight, fLevel);
    if(m_pRoot) m_pRoot->traverse(&state);
	GetRenderContext()->SetDirty();
	InvalidateRect(0, false);
}


void ChMazeWnd::DoNodeCommand(string& strCmd, string &strNodeVRML )
{
	// Build a new tree

	string strVRML = EncapsulateVRML(strNodeVRML);

	// make the vrml thing

	char *buf = strVRML.GetBuffer(1);
	istrstream is(buf);
	bool boolSuccess = false;
	QvDB::init();

    ChQvInput	in;
	in.setFilePointer(&is);
    QvNode	*root;

    if (QvDB::read(&in, root) && root != 0)
	{
		boolSuccess = true;
	}
    else
    {
		return ;
    }

	string strSubCmd;
	string strKey;

	ChQvState state(this, strCmd, strSubCmd, strKey, strNodeVRML, root);
    if(m_pRoot) m_pRoot->traverse(&state);
 	ChQvState defstate(this, strCmd, strSubCmd, strKey, strNodeVRML, root);
	// used to walk the default root here, but now camera is handled elsewhere
	delete root;
	GetRenderContext()->SetDirty();
	InvalidateRect(0, false);
}

bool ChMazeWnd::CheckForTrailingJunk(QvInput &in ) //, FILE *f)
{
	char ch;

	in.get( ch );

	#if 0
	while( ch  != EOF)
	{
		if(!isspace(ch))
		{
			//Trailing junk
			if(ch == '#')
			{
				while( ch  != EOF && ch != '\n' && ch != '\r') in.get(ch);	// ignore comments				
			}
			else
			{
				QvReadError::post(&in, "Trailing characters after toplevel node. (Only one toplevel node allowed.)");
				return true;
			}

		}
		else
		{
			in.get( ch );
		}
	}
	#endif	// Allow just about anything
	return false;
}

bool ChMazeWnd::LoadScene( const string &strURL, const string &strFilename, chparam data )
{

	if ( m_hParseThreadEvent == 0 && GetRenderContext()->IsThreaded() )
	{	// Create the thread event
		m_hParseThreadEvent = ::CreateEvent( 0, false, false, 0 );
		ASSERT( m_hParseThreadEvent );
		::InitializeCriticalSection( &m_syncParser );
	}

	// cancel all parse threads before we start a new thread
	AbortParsing();
	// Reset the event
	::ResetEvent( GetEndParseEvent() );

	
	ChParseInfo * pParseInfo = new ChParseInfo( this, strURL, strFilename );
	ASSERT( pParseInfo );

	pParseInfo->SetUserData2((void*)data);

	// Add it to my list of parse threads running
	AddParseInfo( pParseInfo );

	if ( !pParseInfo->ParseVrmlFile( ChParseInfo::typeScene ))
	{   // failed to initialize
		m_parseThreadList.RemoveTail( );

		delete pParseInfo;
	}

	return true;

}

bool ChMazeWnd::LoadWWWInline( const string &strURL, const string &strFilename, 
											QvWWWInline *pInlineNode )
{
	
	ChParseInfo * pParseInfo = new ChParseInfo( this, strURL, strFilename );
	ASSERT( pParseInfo );

	pParseInfo->SetUserData( pInlineNode );

	((ChQvWWWInlineRenderData*)(pInlineNode->GetRenderData()))->SetParseInfo(pParseInfo); // starting to parse
	// Serialize this
	// Add it to my list of parse threads running
	AddParseInfo( pParseInfo );

	if ( !pParseInfo->ParseVrmlFile( ChParseInfo::typeWWWInline ))
	{   // failed to initialize
		RemoveParseInfo( pParseInfo );

		delete pParseInfo;
	}

	return true;

}



#define CAMERA_CLASS	"QvPerspectiveCamera"
#define CAMERA_CLASS_ORTHO	"QvOrthographicCamera"

ChMazeWnd* ChMazeWnd::SetScene( QvNode *root )
{
	m_pRoot = root;
						/* Get the global hints from the
							tree */
	SetGlobalHints();
	SetupTreeDefaults();

	// Reset the navigators
	for(int j = 0; j < viewerModeCount; j++)
	{
		if(m_pNavigators[j])
		{
			m_pNavigators[j]->SetState(ChVrmlStateTransition::s_start);
		}
	}

	#if !defined(CH_VRML_VIEWER) && !defined(CH_VRML_PLUGIN )
	GetMainInfo()->GetCore()->AbortRequests( false, 
								GetMainInfo()->GetStream() );
	#else
	GetHTTPConn()->AbortRequests( false, GetHTTPConn()->GetStreamMgr() );
	#endif

	// Set the node count to zero
	GetRenderContext()->ResetScene();
						// Delete the old instance tree, and
						// make a new one

	ChQvBuildState bldIt(this);
	m_pRoot->traverse(&bldIt);

	// TODO !!	   fix this for trivial trees
	GetRenderContext()->SetRoot((ChQvInstance*)(bldIt.GetCurrentParent()));

		 // Compute bounds on instance tree
	
	if (!m_pBounds) m_pBounds = new ChQvBounds;
	//m_pBounds->Apply(m_pRoot, this);
	m_pBounds->Apply(GetRenderContext()->GetRoot(), GetRenderContext());

	// Set the initial camera
	ChQvQuery cameraQuery( this, CAMERA_CLASS, ChQvQuery::byClassName );
	cameraQuery.Apply( m_pRoot );
								// Try to get the camera node
	QvPerspectiveCamera* pCameraNode = (QvPerspectiveCamera*)cameraQuery.GetNode();

	if(!pCameraNode)
	{
		// No perspective camera, maybe an ortho one?
		ChQvQuery cameraQuery( this, CAMERA_CLASS_ORTHO, ChQvQuery::byClassName );
		cameraQuery.Apply( m_pRoot );
								// Try to get the camera node
		pCameraNode = (QvPerspectiveCamera*)cameraQuery.GetNode();
	}
	if(pCameraNode)
	{
		GetRenderContext()->SetCurrentCamera(pCameraNode);
		//GetRenderContext()->SetCurrentCamera(pCameraNode);	  // ????????
	}
	#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
	else
	{
		GetRenderContext()->SetCurrentCamera();
	}
	#endif


	GetCameraControl()->Init();
	#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))

	GetRenderContext()->StartConstruction();	// Start the actual scene building
												// in reality lab - done in 
												// another thread
	#endif
	if (!m_uiTickTimer)
	{
											// Start the timer
		m_uiTickTimer = SetTimer( moveTimerID+1, moveTimerDuration, 0 );
	}

	GetRenderContext()->SetDirty();
	Invalidate(false);

	OnLoadComplete();	// Call the UI or whoever to tell it we're loaded

	return this;
}

void ChMazeWnd::Spawn(const string & strURL)
{
	ChQvSpawnState state(this, strURL);
    if(m_pRoot) m_pRoot->traverse(&state);
	return;
}




#if defined(CH_USE_3DR)
void ChMazeWnd::AddAnchor(ChQvAnchorSensor *pAnchor)
{
	pAnchor->SetID(m_anchors.GetCount());
	m_anchors.AddTail(pAnchor);
}
#elif (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
// no need to
#else
#pragma message("Not adding/clearing anchors")
#endif

void ChMazeWnd::ClearAnchors()
{
#if defined(CH_USE_3DR)
	ChQvAnchorSensor *pAnchor;
	while(!m_anchors.IsEmpty())
	{
		pAnchor = m_anchors.RemoveHead();
		delete pAnchor;
	}
#endif
}

/*----------------------------------------------------------------------------
	ChMazeWnd Pueblo helper functions
----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
	ChMazeWnd static functions
----------------------------------------------------------------------------*/

string ChMazeWnd::EncapsulateVRML( string strNodeVRML )
{
	string	strBuf( "#VRML V1.0 ascii\n " );

	//strBuf += " Separator {");
	strBuf += strNodeVRML;
	//strBuf += " }";

	return strBuf;
}


/*----------------------------------------------------------------------------
	ChMazeWnd diagnostics
----------------------------------------------------------------------------*/

#if defined( _DEBUG )

void ChMazeWnd::AssertValid() const
{
	ChGraphicView::AssertValid();
}

void ChMazeWnd::Dump( CDumpContext& dc ) const
{
	ChGraphicView::Dump( dc );
}

#endif	// defined( _DEBUG )


/*----------------------------------------------------------------------------
	ChMazeWnd protected methods
----------------------------------------------------------------------------*/

bool ChMazeWnd::NewBackground( ChDib* pDIB )
{											/* Create a new buffer and
												palette to match a new
												background DIB */
    return true;
}


bool ChMazeWnd::IsAnchor( int iX, int iY, pChQvAnchorSensor &pHitAnchor )
{
	bool boolIsAnchor = false;
#if defined(CH_USE_3DR)
	if(!GetScene()) return false;
											/* X and Y are in window
												coordinates */
	G3dSetActiveStack(GetGC(), G3DT_CAM_CLIP);
	G3dPushTransform(GetGC());
	G3dSetActiveStack(GetGC(), G3DT_MODEL);
	G3dPushTransform(GetGC());
	
	// Now do the hittest on each anchor in the list. If -any- get a hit, we choose the closest.
    if (!m_anchors.IsEmpty())
    {
		float	fNearZ;
		ChQvAnchorSensor *pAnchor, *pNearAnchor = 0;

		ChPosition pos = m_anchors.GetHeadPosition();
	    while (pos) {
	        pAnchor = m_anchors.GetNext(pos);
			float fZ;
			if( pAnchor->HitTest(GetGC(), iX, iY, fZ))
			{
				if(!pNearAnchor || fZ > fNearZ)
				{
					fNearZ = fZ;
					pNearAnchor = pAnchor;
				}
			}
	    }
		if (pNearAnchor)
		{
			boolIsAnchor = true;
			QvWWWAnchor	*pAnchorNode = pNearAnchor->GetAnchorNode();
			string hint;
			pNearAnchor->GetHint(hint);

			OnHotSpot(0, hint);

			m_boolIsHintDisplayed = true;
			pHitAnchor = pNearAnchor;  
			m_hCursor = m_hAnchorCursor;
			::SetCursor(m_hAnchorCursor);
		}
		else
		{
			if(m_boolIsHintDisplayed)
			{
				string hint;

				OnHotSpot(0, hint);

				m_boolIsHintDisplayed = false;
				HCURSOR hCurs = m_hCursor = HCURSOR(GetClassLong(GetSafeHwnd(), GCL_HCURSOR));
				::SetCursor(hCurs);
			}
		}
	}


	G3dSetActiveStack(GetGC(), G3DT_CAM_CLIP);
	G3dPopTransform(GetGC());
	G3dSetActiveStack(GetGC(), G3DT_MODEL);
	G3dPopTransform(GetGC());
#elif (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
	{
		// Hand it to RC; it has scene data
		GetRenderContext()->LockScene();
		boolIsAnchor = GetRenderContext()->IsAnchor(iX, iY, pHitAnchor);
		if(boolIsAnchor)
		{	
			string hint;
			pHitAnchor->GetHint(hint);

			OnHotSpot(0, hint);

			m_boolIsHintDisplayed = true;
			m_hCursor = m_hAnchorCursor;
			::SetCursor(m_hAnchorCursor);
		}
		else if(m_boolIsHintDisplayed)
		{
			string hint;

			OnHotSpot(0, hint);

			m_boolIsHintDisplayed = false;
			HCURSOR hCurs = m_hCursor = HCURSOR(GetClassLong(GetSafeHwnd(), GCL_HCURSOR));
			::SetCursor(hCurs);
		}
		GetRenderContext()->UnlockScene();
	}				

#else
#pragma message("Not testing anchors")
#endif

	
	return boolIsAnchor;
}

void ChMazeWnd::WriteStatus( UINT uMsgID )
{
	// iMessage should be > 0 for all valid messages and 0 to remove
	// any progress message. If you want to define any new message,
	// add it to the list in ChMaze.h


	// The status messages could be generated by worker threads, so
	// we post the message to the thread that created this window and
	// retrive the message and let the virtual functions to the work
	PostMessage( WM_VRML_PROGRESS, 	uMsgID );
}

void ChMazeWnd::OnHotSpot( chparam userData,
								const string& strDocURL  )
{
	#if !defined(CH_VRML_VIEWER) && !defined(CH_VRML_PLUGIN )
	GetMainInfo()->WriteStatus(strDocURL);
	#else
	#endif
}

void ChMazeWnd::StartAnchor( int iX, int iY )
{
#if defined(CH_USE_3DR)
											/* We can't be in both mouse move
												and anchor states */
	ChQvAnchorSensor		*pAnchor;

	ASSERT( !IsInMouseMove() );
	IsAnchor(iX, iY, pAnchor);			
											// Save the current anchor by   
											// making a copy of the sensor  
	m_pAnchor = new ChQvAnchorSensor(0);
	*m_pAnchor = *pAnchor;												 
	m_boolInMouseAnchor = true;
#elif (defined(CH_USE_RLAB) || defined(CH_USE_D3D))											 
											/* We can't be in both mouse move
												and anchor states */
	ChQvAnchorSensor		*pAnchor;

	ASSERT( !IsInMouseMove() );
	IsAnchor(iX, iY, pAnchor);			
											// Don't make a copy for rlab  
	m_pAnchor = pAnchor;												 
	m_boolInMouseAnchor = true;											 
#else
#pragma message("Not starting anchors")
#endif
}


void ChMazeWnd::UpdateAnchor( int iX, int iY )
{
	IsAnchor(iX, iY);		// update the status line
}


void ChMazeWnd::EndAnchor( int iX, int iY )
{
#if defined(CH_USE_3DR) || defined(CH_USE_RLAB) || defined(CH_USE_D3D)
	ChQvAnchorSensor		*pAnchor;

								// get the anchor currently under mouse, if any
								// and test to see if it's the one that started us
	if(IsAnchor(iX, iY, pAnchor) && pAnchor /*&& *pAnchor == *m_pAnchor*/)	   // jwd - changed to use click
	{
		//WriteStatus("Request Initiated");		// just for debugging
															// Tell my info who will tell the pane mgr
															// It's their job to notify

		string command;

		command = pAnchor->GetCommand();
		if(!command.IsEmpty())
		{
			#if !defined(CH_VRML_VIEWER) && !defined(CH_VRML_PLUGIN )
			GetMainInfo()->NotifyAnchor(command);
			#else
			GetURL(command, 0, GetCurrentURL());

⌨️ 快捷键说明

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