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