|
|
//-----------------------------------------------------------------------------
// File: pipe.cpp
//
// Desc: Pipe base class stuff
//
// Copyright (c) 1994-2000 Microsoft Corporation
//-----------------------------------------------------------------------------
#include "stdafx.h"
//-----------------------------------------------------------------------------
// Name: PIPE constructor
// Desc:
//-----------------------------------------------------------------------------
PIPE::PIPE( STATE *state ) { m_pState = state; m_pWorldMatrixStack = m_pState->m_pWorldMatrixStack; m_radius = m_pState->m_radius;
// default direction choosing is random
m_chooseDirMethod = CHOOSE_DIR_RANDOM_WEIGHTED; m_chooseStartPosMethod = CHOOSE_STARTPOS_RANDOM; m_weightStraight = 1; }
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
PIPE::~PIPE() { }
//-----------------------------------------------------------------------------
// Name: ChooseMaterial
// Desc:
//-----------------------------------------------------------------------------
void PIPE::ChooseMaterial( ) { if( m_pState->m_bUseTexture ) m_pMat = RandomTexMaterial(); else m_pMat = RandomTeaMaterial(); }
//-----------------------------------------------------------------------------
// Name: SetChooseDirectionMethod
// Desc:
//-----------------------------------------------------------------------------
void PIPE::SetChooseDirectionMethod( int method ) { m_chooseDirMethod = method; }
//-----------------------------------------------------------------------------
// Name: ChooseNewDirection
// Desc: Call direction-finding function based on current method
// This is a generic entry point that is used by some pipe types
//-----------------------------------------------------------------------------
int PIPE::ChooseNewDirection() { NODE_ARRAY* nodes = m_pState->m_nodes; int bestDirs[NUM_DIRS], nBestDirs;
// figger out which fn to call
switch( m_chooseDirMethod ) { case CHOOSE_DIR_CHASE: if( nBestDirs = GetBestDirsForChase( bestDirs ) ) return nodes->ChoosePreferredDirection( &m_curPos, m_lastDir, bestDirs, nBestDirs ); // else lead pipe must have died, so fall thru:
case CHOOSE_DIR_RANDOM_WEIGHTED : default: return nodes->ChooseRandomDirection( &m_curPos, m_lastDir, m_weightStraight ); } }
//-----------------------------------------------------------------------------
// Name: GetBestDirsForChase
// Desc: Find the best directions to take to close in on the lead pipe in chase mode.
//
// mf: ? but want to use similar scheme for turning flex pipes !! (later)
//-----------------------------------------------------------------------------
int PIPE::GetBestDirsForChase( int *bestDirs ) { // Figure out best dirs to close in on leadPos
//mf: will have to 'protect' leadPos with GetLeadPos() for multi-threading
IPOINT3D* leadPos = &m_pState->m_pLeadPipe->m_curPos; IPOINT3D delta; int numDirs = 0;
delta.x = leadPos->x - m_curPos.x; delta.y = leadPos->y - m_curPos.y; delta.z = leadPos->z - m_curPos.z;
if( delta.x ) { numDirs++; *bestDirs++ = delta.x > 0 ? PLUS_X : MINUS_X; }
if( delta.y ) { numDirs++; *bestDirs++ = delta.y > 0 ? PLUS_Y : MINUS_Y; }
if( delta.z ) { numDirs++; *bestDirs++ = delta.z > 0 ? PLUS_Z : MINUS_Z; }
// It should be impossible for numDirs = 0 (all deltas = 0), as this
// means curPos = leadPos
return numDirs; }
//-----------------------------------------------------------------------------
// Name: SetChooseStartPosMethod
// Desc:
//-----------------------------------------------------------------------------
void PIPE::SetChooseStartPosMethod( int method ) { m_chooseStartPosMethod = method; }
//-----------------------------------------------------------------------------
// Name: PIPE::SetStartPos
// Desc: - Find an empty node to start the pipe on
//-----------------------------------------------------------------------------
BOOL PIPE::SetStartPos() { NODE_ARRAY* nodes = m_pState->m_nodes;
switch( m_chooseStartPosMethod ) { case CHOOSE_STARTPOS_RANDOM: default: if( !nodes->FindRandomEmptyNode( &m_curPos ) ) { return FALSE; } return TRUE; case CHOOSE_STARTPOS_FURTHEST: // find node furthest away from curPos
IPOINT3D refPos, numNodes; nodes->GetNodeCount( &numNodes ); refPos.x = (m_curPos.x >= (numNodes.x / 2)) ? 0 : numNodes.x - 1; refPos.y = (m_curPos.y >= (numNodes.y / 2)) ? 0 : numNodes.y - 1; refPos.z = (m_curPos.z >= (numNodes.z / 2)) ? 0 : numNodes.z - 1;
if( !nodes->TakeClosestEmptyNode( &m_curPos, &refPos ) ) { return FALSE; } return TRUE; } }
//-----------------------------------------------------------------------------
// Name: PIPE::IsStuck
// Desc:
//-----------------------------------------------------------------------------
BOOL PIPE::IsStuck() { return m_status == PIPE_STUCK; }
//-----------------------------------------------------------------------------
// Name: PIPE::TranslateToCurrentPosition
// Desc:
//-----------------------------------------------------------------------------
void PIPE::TranslateToCurrentPosition() { IPOINT3D numNodes;
float divSize = m_pState->m_view.m_divSize;
// this requires knowing the size of the node array
m_pState->m_nodes->GetNodeCount( &numNodes );
m_pWorldMatrixStack->TranslateLocal( (m_curPos.x - (numNodes.x - 1)/2.0f )*divSize, (m_curPos.y - (numNodes.y - 1)/2.0f )*divSize, (m_curPos.z - (numNodes.z - 1)/2.0f )*divSize );
}
//-----------------------------------------------------------------------------
// Name: UpdateCurrentPosition
// Desc: Increment current position according to direction taken
//-----------------------------------------------------------------------------
void PIPE::UpdateCurrentPosition( int newDir ) { switch( newDir ) { case PLUS_X: m_curPos.x += 1; break; case MINUS_X: m_curPos.x -= 1; break; case PLUS_Y: m_curPos.y += 1; break; case MINUS_Y: m_curPos.y -= 1; break; case PLUS_Z: m_curPos.z += 1; break; case MINUS_Z: m_curPos.z -= 1; break; } }
//-----------------------------------------------------------------------------
// Name: align_plusz
// Desc: - Aligns the z axis along specified direction
// - Used for all types of pipes
//-----------------------------------------------------------------------------
void PIPE::align_plusz( int newDir ) { static D3DXVECTOR3 xAxis = D3DXVECTOR3(1.0f,0.0f,0.0f); static D3DXVECTOR3 yAxis = D3DXVECTOR3(0.0f,1.0f,0.0f);
// align +z along new direction
switch( newDir ) { case PLUS_X: m_pWorldMatrixStack->RotateAxisLocal( &yAxis, PI/2.0f ); break; case MINUS_X: m_pWorldMatrixStack->RotateAxisLocal( &yAxis, -PI/2.0f ); break; case PLUS_Y: m_pWorldMatrixStack->RotateAxisLocal( &xAxis, -PI/2.0f ); break; case MINUS_Y: m_pWorldMatrixStack->RotateAxisLocal( &xAxis, PI/2.0f ); break; case PLUS_Z: m_pWorldMatrixStack->RotateAxisLocal( &yAxis, 0.0f ); break; case MINUS_Z: m_pWorldMatrixStack->RotateAxisLocal( &yAxis, PI ); break;
} }
//-----------------------------------------------------------------------------
// Name:
// Desc: this array tells you which way the notch will be once you make
// a turn
// format: notchTurn[oldDir][newDir][notchVec]
//-----------------------------------------------------------------------------
int notchTurn[NUM_DIRS][NUM_DIRS][NUM_DIRS] = { // oldDir = +x
iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, MINUS_X,PLUS_X, PLUS_Z, MINUS_Z, iXX, iXX, PLUS_X, MINUS_X,PLUS_Z, MINUS_Z, iXX, iXX, PLUS_Y, MINUS_Y,MINUS_X,PLUS_X, iXX, iXX, PLUS_Y, MINUS_Y,PLUS_X, MINUS_X, // oldDir = -x
iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, PLUS_X, MINUS_X,PLUS_Z, MINUS_Z, iXX, iXX, MINUS_X,PLUS_X, PLUS_Z, MINUS_Z, iXX, iXX, PLUS_Y, MINUS_Y,PLUS_X, MINUS_X, iXX, iXX, PLUS_Y, MINUS_Y,MINUS_X,PLUS_X,
// oldDir = +y
MINUS_Y,PLUS_Y, iXX, iXX, PLUS_Z, MINUS_Z, PLUS_Y, MINUS_Y,iXX, iXX, PLUS_Z, MINUS_Z, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, PLUS_X, MINUS_X,iXX, iXX, MINUS_Y,PLUS_Y, PLUS_X, MINUS_X,iXX, iXX, PLUS_Y, MINUS_Y, // oldDir = -y
PLUS_Y, MINUS_Y,iXX, iXX, PLUS_Z, MINUS_Z, MINUS_Y,PLUS_Y, iXX, iXX, PLUS_Z, MINUS_Z, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, PLUS_X, MINUS_X,iXX, iXX, PLUS_Y, MINUS_Y, PLUS_X, MINUS_X,iXX, iXX, MINUS_Y,PLUS_Y,
// oldDir = +z
MINUS_Z,PLUS_Z, PLUS_Y, MINUS_Y,iXX, iXX, PLUS_Z, MINUS_Z,PLUS_Y, MINUS_Y,iXX, iXX, PLUS_X, MINUS_X,MINUS_Z,PLUS_Z, iXX, iXX, PLUS_X, MINUS_X,PLUS_Z, MINUS_Z,iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, // oldDir = -z
PLUS_Z, MINUS_Z,PLUS_Y, MINUS_Y,iXX, iXX, MINUS_Z,PLUS_Z, PLUS_Y, MINUS_Y,iXX, iXX, PLUS_X, MINUS_X,PLUS_Z, MINUS_Z,iXX, iXX, PLUS_X, MINUS_X,MINUS_Z,PLUS_Z, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX, iXX };
|