📄 boidswinmenu.cpp
字号:
/* 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 + -