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

📄 boidsflyer.cpp

📁 3D的Boids效果演示源程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*	Filename:		BoidsFlyer.cpp
	Author:			Robert Platt
	Creation date:	22/07/1999
	Modified:		13/05/2000
	Version:		0.54
	Description:	Implementation file for the boids flyer class.
*/


#include "BoidsWin.h"


// Constructor for the flyer class.
BoidsFlyer::BoidsFlyer( )
{
	// Initialise the COM interface pointers.
	meshFrame = NULL;
	meshBuilder = NULL;
	leftWingFrame = NULL;
	rightWingFrame = NULL;
	builderLeftWing = NULL;
	builderRightWing = NULL;

	// Initialise the flyer's position and velocity.
	x = y = z = 0.0;
	speed = STARTING_SPEED;
	hHeading = 0.0;
	vHeading = 0.0;
	reqSpeed = STARTING_SPEED;
	reqHHeading = 0.0;
	reqVHeading = 0.0;

	startTime = clock( );  // Start the flyer's motion timer.
}


// Destructor for the flyer class.
BoidsFlyer::~BoidsFlyer( )
{
	// Release the flyers COM interfaces gracefully.
	// If the boid has wings, release them first.
	if ( leftWingFrame )
	{
		leftWingFrame -> DeleteVisual( builderLeftWing );
		rightWingFrame -> DeleteVisual( builderRightWing );
		builderLeftWing -> Release( );
		builderRightWing -> Release( );
		builderLeftWing = NULL;
		builderRightWing = NULL;
		meshFrame -> DeleteChild( leftWingFrame );
		meshFrame -> DeleteChild( rightWingFrame );
		leftWingFrame -> Release( );
		rightWingFrame -> Release( );
		leftWingFrame = NULL;
		rightWingFrame = NULL;
	}

	meshFrame -> DeleteMoveCallback( callBack, this );
	scene -> DeleteChild( meshFrame );

	if ( meshFrame )
	{
		meshFrame -> Release( );
		meshFrame = NULL;
	}

	if ( meshBuilder )
	{
		meshBuilder -> Release( );
		meshBuilder = NULL;
	}
}


void BoidsFlyer::build( CFrameWnd *win, LPDIRECT3DRM d, LPDIRECT3DRMFRAME s )
{
	window = win;
	d3drm = d;  // Store two pointers to the D3D interfaces inside the flyer.
	scene = s;  // This helps to keep future calls to the flyer concise.

	// Create the meshbuilder interface.
	d3drm -> CreateMeshBuilder( &meshBuilder );
	// Load a mesh object with the meshbuilder.
	D3DRMLOADRESOURCE resource;  // Declare a structure for the resource info.
	resource.hModule = NULL;  // Reference to module containing the resource.
	// Retrieve the shape of the flyer mesh from the main window.
	resource.lpName = MAKEINTRESOURCE( static_cast< BoidsWin * >
										( window ) -> getFlyerMesh( ) );
	resource.lpType = "MESH";  // State the type of the resource.
	// Load the mesh from the internal binary resource.
	meshBuilder -> Load( &resource, NULL,
							D3DRMLOAD_FROMRESOURCE, NULL, NULL );

	// Kept for possible future use or reference.
//	meshBuilder -> Load( OBJECT_FILENAME, NULL,
//							D3DRMLOAD_FROMFILE, NULL, NULL );

	// Set the colour of the main mesh.
	colour = static_cast< BoidsWin * >( window ) -> getFlyerColour( );
	meshBuilder -> SetColor( colour );

	// Create the mesh frame interface and add the mesh to it.
	d3drm -> CreateFrame( scene, &meshFrame );
	meshFrame -> AddVisual( meshBuilder );
	meshFrame -> AddMoveCallback( callBack, this );

	getSize( );  // Initialise the boid's size data member.

	// If the selected mesh is the animated one, add the wings to it.
	if ( static_cast< BoidsWin * >( window ) ->
									getFlyerMesh( ) == IDR_MESH_BIRDBODY )
	{
		// Add the left wing to the birds body.
		d3drm -> CreateMeshBuilder( &builderLeftWing );
		resource.lpName = MAKEINTRESOURCE( IDR_MESH_LEFTWING );
		builderLeftWing -> Load( &resource, NULL,
								D3DRMLOAD_FROMRESOURCE, NULL, NULL );
		d3drm -> CreateFrame( meshFrame, &leftWingFrame );
		leftWingFrame -> AddVisual( builderLeftWing );
		builderLeftWing -> SetColor( colour );

		// Add the right wing to the birds body.
		d3drm -> CreateMeshBuilder( &builderRightWing );
		resource.lpName = MAKEINTRESOURCE( IDR_MESH_RIGHTWING );
		builderRightWing -> Load( &resource, NULL,
								D3DRMLOAD_FROMRESOURCE, NULL, NULL );
		d3drm -> CreateFrame( meshFrame, &rightWingFrame );
		rightWingFrame -> AddVisual( builderRightWing );
		builderRightWing -> SetColor( colour );
	}
}


// Set rotation function for the flyer.
void BoidsFlyer::setRotation( D3DVALUE x, D3DVALUE y,
								D3DVALUE z, D3DVALUE magnitude )
{
	// Call the D3DRM set rotation function.
	meshFrame -> SetRotation( scene, x, y, z, magnitude );
}


// Get the position of the flyer.
void BoidsFlyer::getPosition( D3DVALUE *xPos, D3DVALUE *yPos, D3DVALUE *zPos )
{
	*xPos = x;
	*yPos = y;
	*zPos = z;
}


// Set the position of the flyer.
void BoidsFlyer::setPosition( D3DVALUE newX, D3DVALUE newY, D3DVALUE newZ )
{
	x = D3DVALUE( newX );
	y = D3DVALUE( newY );
	z = D3DVALUE( newZ );
	meshFrame -> SetPosition( scene, x, y, z );
}


// Get the velocity components of the flyer.
void BoidsFlyer::getVelocity( D3DVALUE *sp, D3DVALUE *horiz, D3DVALUE *vert )
{
	// Set the required velocity components.
	*sp = speed;
	*horiz = hHeading;
	*vert = vHeading;
}


// Set the velocity components of the flyer.
void BoidsFlyer::setVelocity( D3DVALUE sp, D3DVALUE horiz, D3DVALUE vert )
{
	// Set the required velocity components.
	speed = sp;
	hHeading = horiz;
	vHeading = vert;
}


// Get the required velocity of the flyer.
void BoidsFlyer::getReqVelocity( D3DVALUE *sp,
						D3DVALUE *horiz, D3DVALUE *vert )
{
	// Set the required velocity components.
	*sp = reqSpeed;
	*horiz = reqHHeading;
	*vert = reqVHeading;
}


// Set the required velocity of the flyer.
void BoidsFlyer::setReqVelocity( D3DVALUE sp, D3DVALUE horiz, D3DVALUE vert )
{
	// Set the required velocity components.
	reqSpeed = sp;
	reqHHeading = horiz;
	reqVHeading = vert;
}


// Set the speed of the flyer.
void BoidsFlyer::setReqSpeed( D3DVALUE sp )
{
	// Set the flyer's required speed.
	reqSpeed = sp;
}


// Retrieve the size of the boid & also update the boid's size data member.
D3DVALUE BoidsFlyer::getSize( )
{
	// First calculate the current size of the flyer.
	D3DRMBOX box;
	meshBuilder -> GetBox( &box );
	D3DVALUE sizex = box.max.x - box.min.x;
	D3DVALUE sizey = box.max.y - box.min.y;
	D3DVALUE sizez = box.max.z - box.min.z;
	// Find the average of the flyer's three dimensions.
	size = ( sizex + sizey + sizez ) / 3.0;

	return size;
}


// Scale the size of an flyer to a particular size.
void BoidsFlyer::setSize( double newSize )
{
	// Update the current size of the flyer.
	getSize( );

	// Calculate the scale factor required for the new size.
	D3DVALUE scalefactor;
	scalefactor = D3DVALUE( newSize / size );
	// Scale the flyer to the new size.
	meshBuilder -> Scale( scalefactor, scalefactor, scalefactor );

	// If the flying boid mesh is the animated one.
	if ( leftWingFrame )
	{
		// Also scale the left wing by the same amount.
		builderLeftWing -> Scale( scalefactor, scalefactor, scalefactor );

		// Also scale the right wing by the same amount.
		builderRightWing -> Scale( scalefactor, scalefactor, scalefactor );
	}

	// Update to the new size of the flyer.
	getSize( );
}


// Set the colour of the flyer.
void BoidsFlyer::setColour( D3DCOLOR col )
{
	colour = col;  // Set the data member of the boid.

	// Set the colour of the main mesh.
	meshBuilder -> SetColor( colour );

	// If the flying boid mesh is the animated one.
	if ( leftWingFrame )
	{
		// Also set the colour of the left wing.
		builderLeftWing -> SetColor( colour );

		// Also set the colour of the right wing.
		builderRightWing -> SetColor( colour );
	}
}


// Reload the flyer's mesh.
void BoidsFlyer::updateMesh( )
{
	// If the boid has wings, release them first.
	if ( leftWingFrame )
	{
		leftWingFrame -> DeleteVisual( builderLeftWing );
		rightWingFrame -> DeleteVisual( builderRightWing );
		builderLeftWing -> Release( );
		builderRightWing -> Release( );
		builderLeftWing = NULL;
		builderRightWing = NULL;
		meshFrame -> DeleteChild( leftWingFrame );
		meshFrame -> DeleteChild( rightWingFrame );
		leftWingFrame -> Release( );
		rightWingFrame -> Release( );
		leftWingFrame = NULL;
		rightWingFrame = NULL;
	}

	// First remove the previous meshbuilder from the boid's frame.
	meshFrame -> DeleteVisual( meshBuilder );
	meshBuilder -> Release( );  // Release the meshbuilder.
	meshBuilder = NULL;  // Release the meshbuilder.

	// Create a new meshbuilder.
	d3drm -> CreateMeshBuilder( &meshBuilder );

	// Load a new mesh from a resource with the new meshbuilder.
	D3DRMLOADRESOURCE resource;  // Declare a structure for the resource info.
	resource.hModule = NULL;  // Reference to module containing the resource.
	resource.lpName = MAKEINTRESOURCE( static_cast< BoidsWin * >
											( window ) -> getFlyerMesh( ) );
	resource.lpType = "MESH";
	meshBuilder -> Load( &resource, NULL,
					D3DRMLOAD_FROMRESOURCE, NULL, NULL );

	// Set the colour of the mesh to pure white.
	meshBuilder -> SetColor( colour );

	// Add the new meshbuilder to the boid's frame.
	meshFrame -> AddVisual( meshBuilder );

	// If the selected mesh is the animated one.
	if ( static_cast< BoidsWin * >( window ) -> getFlyerMesh( )
												== IDR_MESH_BIRDBODY )
	{
		// Add the left wing to the birds body.
		d3drm -> CreateMeshBuilder( &builderLeftWing );
		resource.lpName = MAKEINTRESOURCE( IDR_MESH_LEFTWING );
		builderLeftWing -> Load( &resource, NULL,
									D3DRMLOAD_FROMRESOURCE, NULL, NULL );
		d3drm -> CreateFrame( meshFrame, &leftWingFrame );
		leftWingFrame -> AddVisual( builderLeftWing );
		builderLeftWing -> SetColor( colour );

		// Add the right wing to the birds body.
		d3drm -> CreateMeshBuilder( &builderRightWing );
		resource.lpName = MAKEINTRESOURCE( IDR_MESH_RIGHTWING );
		builderRightWing -> Load( &resource, NULL,
									D3DRMLOAD_FROMRESOURCE, NULL, NULL );
		d3drm -> CreateFrame( meshFrame, &rightWingFrame );
		rightWingFrame -> AddVisual( builderRightWing );
		builderRightWing -> SetColor( colour );
	}
}


// Static callback function to move the flyer.
void BoidsFlyer::callBack( LPDIRECT3DRMFRAME meshframe,
										void *arg, D3DVALUE delta )
{
	// Use the provided pointer argument to -
	// - call a specific flyer's member functions.
	BoidsFlyer *boidsFlyer = static_cast< BoidsFlyer * >( arg );

	boidsFlyer -> directToBoid( );
	boidsFlyer -> velocityMatching( );
	boidsFlyer -> collisionAvoidance( );
	boidsFlyer -> landscapeAvoidance( );
	boidsFlyer -> moveObject( );
}


// Function that directs a boid to another boid in it's field of vision.
void BoidsFlyer::directToBoid( )
{
	BoidsWin *win = static_cast< BoidsWin * >( window );

	// Only perform direct to boid if the flag is set.
	if ( win -> getFlockFormingActive( ) == false )

⌨️ 快捷键说明

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