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

📄 boidswinmenu.cpp

📁 3D的Boids效果演示源程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*	Filename:		BoidsWinMenu.cpp
	Author:			Robert Platt
	Creation date:	15/06/1999
	Modified:		08/02/2004
	Version:		0.54
	Description:	Implementation file for the boids main window class.
*/


#include "BoidsConfig.h"


// Message handler to load in a configuration.
afx_msg void BoidsWin::OnLoad( )
{
	// Set the multitasking flag.
	appIdle = false;

	// Restart the rendering thread if stopped.
	threadEnabled = true;

	if ( threadFinished == true )
	{
		threadFinished = false;
		ptrD3DThread = AfxBeginThread( d3dThread, this,
											THREAD_PRIORITY_NORMAL );
	}


	// Create an MFC file dialog.
	CFileDialog fileDialog( TRUE, NULL, NULL, NULL,
						"Configuration Files (*.ini)|*.ini|" );

	// Activate the dialog.
	if ( fileDialog.DoModal( ) == IDCANCEL )
	{
		return;  // Abort if cancel is pressed.
	}

	// Extract the chosen filename.
	CString fileName = fileDialog.GetFileName( );

	// Make a new configuration object.
	BoidsConfig config;

	// Load data from stored configuration file.
	config.loadConfig( fileName );

	// Adjust the number of flyers.
	int num = config.getNFlyers( );
	// If there is more in the config than active.
	if ( num > numFlyers )
	{
		// Reduce the number to be changed accordingly.
		num = numFlyers;
	}
	else
	{
		// Reduce the number of active to match the config.
		requiredFlyers = num;
	}

	// Declare a Flyer structure, to use for extraction of the data.
	Flyer flr;
	// Get a copy of the configuration object's vector.
	vector< Flyer * > fConfigs = config.getFConfigs( );
	// Iterate through all the active flyers.
	for ( int number = 0; number < num; number++ )
	{
		flr = *fConfigs[ number ];  // Get a pointer to a flyer.

		// Set the state of the relevant flyer.
		flyers[ number ] -> setPosition( flr.xPos, flr.yPos, flr.zPos );
		flyers[ number ] -> setVelocity( flr.speed,
										flr.hHeading, flr.vHeading );
		flyers[ number ] -> setReqVelocity( flr.reqSpeed,
										flr.reqHHeading, flr.reqVHeading );
	}


	// Stop the rendering thread when done.
	threadEnabled = false;


	return;
}


// Message handler to save the configuration.
afx_msg void BoidsWin::OnSave( )
{
	// Set the multitasking flag.
	appIdle = false;

	// Restart the rendering thread if stopped.
	threadEnabled = true;

	if ( threadFinished == true )
	{
		threadFinished = false;
		ptrD3DThread = AfxBeginThread( d3dThread, this,
										THREAD_PRIORITY_NORMAL );
	}


	// Make a data structure to pass to the configuration object.
	// A vector of pointers to a Flyer structure.
	vector< Flyer * > f;
	Flyer *fPtr;

	// Iterate through all the active flyers.
	for ( int number = 0; number < numFlyers; number++ )
	{
		// Make a new Flyer structure in memory;
		fPtr = new Flyer( );

		// Declare some temporary local variables.
		D3DVALUE x, y, z;
		D3DVALUE hH, vH;
		D3DVALUE reqHH, reqVH;
		D3DVALUE s, reqS;

		// Get the data from the flyer.
		flyers[ number ] -> getPosition( &x, &y, &z );
		flyers[ number ] -> getVelocity( &s, &hH, &vH );
		flyers[ number ] -> getReqVelocity( &reqS, &reqHH, &reqVH );

		// Fill the structure with the flyers data.
		fPtr -> xPos = (int)x;
		fPtr -> yPos = (int)y;
		fPtr -> zPos = (int)z;
		fPtr -> hHeading = (int)hH;
		fPtr -> vHeading = (int)vH;
		fPtr -> reqHHeading = (int)reqHH;
		fPtr -> reqVHeading = (int)reqVH;
		fPtr -> speed = (int)s;
		fPtr -> reqSpeed = (int)reqS;

		// Add a pointer to the Flyer structure to the vector.
		f.push_back( fPtr );
	}

	// Create a new config object with the data structure.
	// Pass the vector using call by reference.
	BoidsConfig config( f );

	// Create an MFC file dialog.
	CFileDialog fileDialog( FALSE, NULL, NULL, NULL,
						"Configuration Files (*.ini)|*.ini|" );

	// Activate the dialog.
	if ( fileDialog.DoModal( ) == IDCANCEL )
	{
		return;  // Abort if cancel is pressed.
	}

	// Extract the chosen filename.
	CString fileName = fileDialog.GetFileName( );

	// Append '.ini' to the end of the filename, if needed.
	if ( fileName.Right( 4 ) != ".ini" )
	{
		fileName += ".ini";
	}

	config.saveConfig( fileName );  // Save the configuration to disk.

	
	// Stop the rendering thread when done.
	threadEnabled = false;


	return;
}


// Message handler for the button that stops the simulation.
afx_msg void BoidsWin::OnStartStop( )
{
	static clock_t begin, end;

	// Toggle the start/stop button.
	if ( stopped )  // If the start button is pressed.
	{
		stopped = false;  // Unset the stopped flag.
		btnStop.SetWindowText( "Stop" );  // Toggle button text.
		end = clock( );  // End mesuring the stop time.
		stopTime += end - begin;  // Update the stop time.
	}
	else  // If the stop button is pressed.
	{
		stopped = true;  // Set the stopped flag.
		btnStop.SetWindowText( "Start" );  // Toggle button text.
		begin = clock( );  // Begin to measure the stop time.
		runTime = clock( ) - stopTime;  // Generate the time when stopped.
	}

	SetFocus( );  // Set the focus back to the main window.
}


// Menu driven command to exit the application.
afx_msg void BoidsWin::OnExit( )
{
	// Close the window and terminate the application.
	SendMessage( WM_CLOSE );
}


// Position the camera to give a birds eye view.
afx_msg void BoidsWin::OnCameraAbove( )
{
	// Remove the camera from a boid, if it is on one.
	if ( cameraOnBoid == true )
	{
		scene -> AddChild( camera );
		cameraOnBoid = false;
	}

	cameraView = CAM_ABOVE;
	positionCamera( );
}


// Attach the camera to the first boid in the vector.
afx_msg void BoidsWin::OnCameraBoid( )
{
	// First check to see that there is a boid operational.
	if ( numFlyers > 0 )
	{
		cameraView = CAM_BOID;
		positionCamera( );
	}
}


// Position the camera to face north.
afx_msg void BoidsWin::OnCameraNorth( )
{
	// Remove the camera from a boid, if it is on one.
	if ( cameraOnBoid == true )
	{
		scene -> AddChild( camera );
		cameraOnBoid = false;
	}

	cameraView = CAM_NORTH;
	positionCamera( );
}


// Position the camera to face east.
afx_msg void BoidsWin::OnCameraEast( )
{
	// Remove the camera from a boid, if it is on one.
	if ( cameraOnBoid == true )
	{
		scene -> AddChild( camera );
		cameraOnBoid = false;
	}

	cameraView = CAM_EAST;
	positionCamera( );
}


// Position the camera to face south.
afx_msg void BoidsWin::OnCameraSouth( )
{
	// Remove the camera from a boid, if it is on one.
	if ( cameraOnBoid == true )
	{
		scene -> AddChild( camera );
		cameraOnBoid = false;
	}

	cameraView = CAM_SOUTH;
	positionCamera( );
}


// Position the camera to face west.
afx_msg void BoidsWin::OnCameraWest( )
{
	// Remove the camera from a boid, if it is on one.
	if ( cameraOnBoid == true )
	{
		scene -> AddChild( camera );
		cameraOnBoid = false;
	}

	cameraView = CAM_WEST;
	positionCamera( );
}


// Update the checkmark on the window's menu item.
afx_msg void BoidsWin::OnUpdateCameraAbove( CCmdUI *ptrCmdUI )
{
	ptrCmdUI -> SetCheck( cameraView == CAM_ABOVE );
}


// Update the checkmark on the window's menu item.
afx_msg void BoidsWin::OnUpdateCameraBoid( CCmdUI *ptrCmdUI )
{
	ptrCmdUI -> SetCheck( cameraView == CAM_BOID );
}


// Update the checkmark on the window's menu item.
afx_msg void BoidsWin::OnUpdateCameraNorth( CCmdUI *ptrCmdUI )
{
	ptrCmdUI -> SetCheck( cameraView == CAM_NORTH );
}


// Update the checkmark on the window's menu item.
afx_msg void BoidsWin::OnUpdateCameraEast( CCmdUI *ptrCmdUI )
{
	ptrCmdUI -> SetCheck( cameraView == CAM_EAST );
}


// Update the checkmark on the window's menu item.
afx_msg void BoidsWin::OnUpdateCameraSouth( CCmdUI *ptrCmdUI )
{
	ptrCmdUI -> SetCheck( cameraView == CAM_SOUTH );
}


// Update the checkmark on the window's menu item.
afx_msg void BoidsWin::OnUpdateCameraWest( CCmdUI *ptrCmdUI )
{
	ptrCmdUI -> SetCheck( cameraView == CAM_WEST );
}


// Increase the position of the camera.
afx_msg void BoidsWin::OnIncCameraPos( )
{
	// Increase the position of the slider.
	int num = sliderCam.GetPos( );
	sliderCam.SetPos( num += POSITION_SLIDER_SPEED );

	// Call the Horizontal Scroll Bar update handler.
	OnHScroll( 3, num, (CScrollBar *)&sliderCam );
}


// Decrease the position of the camera.
afx_msg void BoidsWin::OnDecCameraPos( )
{
	// Decrease the position of the slider.
	int num = sliderCam.GetPos( );
	sliderCam.SetPos( num -= POSITION_SLIDER_SPEED );

	// Call the Horizontal Scroll Bar update handler.
	OnHScroll( 3, num, (CScrollBar *)&sliderCam );
}


// Increase the rotation of the camera.
afx_msg void BoidsWin::OnIncCameraRot( )
{
	// Increase the position of the slider by one unit.
	int num = sliderCam2.GetPos( );

	num += ROTATION_SLIDER_SPEED;

	// Make the slider smoothly wrap around.
	if ( num > sliderCam2.GetRangeMax( ) )
	{
		int overlap = num - sliderCam2.GetRangeMax( );
		num = sliderCam2.GetRangeMin( ) + overlap;
	}

	sliderCam2.SetPos( num );

	// Call the Horizontal Scroll Bar update handler.
	OnHScroll( 4, num, (CScrollBar *)&sliderCam2 );
}


// Decrease the rotation of the camera.
afx_msg void BoidsWin::OnDecCameraRot( )
{
	// Decrease the position of the slider by one unit.
	int num = sliderCam2.GetPos( );

	num -= ROTATION_SLIDER_SPEED;

	// Make the slider smoothly wrap around.
	if ( num < sliderCam2.GetRangeMin( ) )
	{
		int overlap = sliderCam2.GetRangeMin( ) - num;
		num = sliderCam2.GetRangeMax( ) - overlap;
	}

	sliderCam2.SetPos( num );

	// Call the Horizontal Scroll Bar update handler.
	OnHScroll( 4, num, (CScrollBar *)&sliderCam2 );
}


// Message handler for the button that centres the camera.
afx_msg void BoidsWin::OnCentre( )
{
	// Centre the camera angle slider.
	sliderCam2.SetPos( 180 );
	// Update the window's data member.
	cameraPosition2 = sliderCam2.GetPos( );
	// Update the camera.
	positionCamera( );

	SetFocus( );  // Set the focus back to the main window.
}


// Menu driven command to set the rendering style to wireframe.
afx_msg void BoidsWin::OnWireFrame( )
{
	renderStyle = D3DRMRENDER_WIREFRAME;
	device -> SetQuality( renderStyle );
}


// Menu driven command to set the rendering style to unlit flat.
afx_msg void BoidsWin::OnUnlitFlat( )
{
	renderStyle = D3DRMRENDER_UNLITFLAT;
	device -> SetQuality( renderStyle );
}


// Menu driven command to set the rendering style to flat shaded.
afx_msg void BoidsWin::OnFlat( )
{
	renderStyle = D3DRMRENDER_FLAT;
	device -> SetQuality( renderStyle );
}


// Menu driven command to set the rendering style to Gouraud.
afx_msg void BoidsWin::OnGouraud( )
{
	renderStyle = D3DRMRENDER_GOURAUD;
	device -> SetQuality( renderStyle );
}


// Add a flyer to the scene by interacting with the slider control.
afx_msg void BoidsWin::OnAddFlyer( )
{
	// Also move the slider to the correct position.
	requiredFlyers++;

	if ( requiredFlyers > MAXIMUM_NUM_FLYERS )
	{
		requiredFlyers = MAXIMUM_NUM_FLYERS;
	}

	sliderNum.SetPos( requiredFlyers );
}


// Remove a flyer from the scene by interacting with the slider control.
afx_msg void BoidsWin::OnRemoveFlyer( )
{
	if ( requiredFlyers > 0 )
	{
		requiredFlyers--;
	}
}


// Increase the size of the flyers.
afx_msg void BoidsWin::OnIncFlyerSize( )
{
	// Increase the position of the slider.
	int num = sliderSize.GetPos( );
	sliderSize.SetPos( num += FLYER_SIZE_SLIDER_SPEED );

	// Call the Horizontal Scroll Bar update handler.
	OnHScroll( 2, num, (CScrollBar *)&sliderSize );
}


// Decrease the size of the flyers.
afx_msg void BoidsWin::OnDecFlyerSize( )
{
	// Decrease the position of the slider.
	int num = sliderSize.GetPos( );
	sliderSize.SetPos( num -= FLYER_SIZE_SLIDER_SPEED );

	// Call the Horizontal Scroll Bar update handler.
	OnHScroll( 2, num, (CScrollBar *)&sliderSize );
}


// Menu driven command to change boids to tetrahedrons.
afx_msg void BoidsWin::OnTetra( )
{
	// Abort change if mesh is already in use.
	if ( flyerMesh == IDR_MESH_TETRA )
	{
		return;
	}


	// Set the window's data member.
	flyerMesh = IDR_MESH_TETRA;

	// Set the mesh counter back to zero.
	flyerMeshesChanged = 0;
}


// Menu driven command to change boids to small birds.
afx_msg void BoidsWin::OnBird( )
{
	// Abort change if mesh is already in use.
	if ( flyerMesh == IDR_MESH_BIRD )
	{
		return;
	}


	// Set the window's data member.
	flyerMesh = IDR_MESH_BIRD;

	// Set the mesh counter back to zero.
	flyerMeshesChanged = 0;
}

⌨️ 快捷键说明

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