#include "3DObject.h" #include "OrderTable.h" void CDrawableObject::draw( COrderTableHeader& h) { ; } long& CCord::x( ) { return m_x ; } long& CCord::y( ) { return m_y ; } long& CCord::z( ) { return m_z ; } const long& CCord::x( ) const { return m_x ; } const long& CCord::y( ) const { return m_y ; } const long& CCord::z( ) const { return m_z ; } CCord::CCord( long xx /* = 0 */, long yy /* = 0 */, long zz /* = 0 */) { x( ) = xx ; y( ) = yy ; z( ) = zz ; } CCord& CCord::operator +=( const CCord& c ) { x( )+=c.x( ) ; y( )+=c.y( ) ; z( )+= c.z( ) ; return *this ; } CCord& CCord::operator -=( const CCord& c ) { x( )-=c.x( ) ; y( )-=y( ) ; z( )-= c.z( ) ; return *this ; } CCord& CCord::operator+( const CCord& c ) { return *this += c ; } CCord& CCord::operator-( const CCord& c ) { return *this -= c ; } bool CCord::operator==( const CCord& c ) const { return x( ) == c.x( ) && y( ) == c.y( ) && z( ) == c.z( ) ; } bool CCord::operator <( const CCord& c ) const { return x( ) < c.x( ) && y( ) < c.y( ) && z( ) < c.z( ) ; } bool CCord::operator >( const CCord& c ) const { return x( ) > c.x( ) && y( ) > c.y( ) && z( ) > c.z( ) ; } bool CCord::operator !=( const CCord& c ) const { return ! ( *this == c ) ; } CLight::CLight( long lNumber /* = 0 */ ) { m_lNumber = lNumber ; color( 255,255,255) ; } /* static */ void CLight::fog ( ) { GsSetLightMode( lightFog ) ; } //static void CLight::normal( ) { GsSetLightMode( lightNormal ) ; } //static void CLight::ambient( long r, long g, long b ) { GsSetAmbient ( r , g , b ) ; } long& CLight::number( ) { return m_lNumber ; } const long& CLight::number( ) const { return m_lNumber ; } void CLight::position( const CCord& c ) { vx = c.x( ) ; vy = c.y( ) ; vz = c.z( ) ; } void CLight::color( u_char rr, u_char gg, u_char bb ) { r = rr ; g = gg ; b = bb; } void CLight::on( ) { GsSetFlatLight( number( ), this ) ; } CLight& CLight::operator--( ) { --r; --g; --b ; on( ) ; } CLight& CLight::operator++( ) { ++r; ++g; ++b ; on( ) ; } C3DObject::C3DObject( ) { vx = vy = vz = 0 ; m_startVector.vx = 0; m_startVector.vy = 0; m_startVector.vz = ONE; } inline void C3DObject::invalidate( ) { // setting the gsObjectCoord.flg to 0 indicates it is to be // drawn flg = 0; } inline const char* C3DObject::name( ) const { return m_pstrName ; } void C3DObject::position( const long lX , const long lY , const long lZ ) { coord.t[2] += lZ ; coord.t[1] += lY ; coord.t[0] += lX ; invalidate( ) ; } void C3DObject::position( const CCord& c ) { position( c.x( ) , c.y( ), c.z( ) ) ; } inline const u_long C3DObject::model( ) const { return m_lModel ; } void C3DObject::name( const char* cpstrName ) { m_pstrName = (char*)cpstrName ; // will change this when a CString class arrives } void C3DObject::model( const u_long lModelAddress ) { m_lModel = lModelAddress ; u_long* pModel = (u_long*) model( ) ; //increment the pointer to past the model id. (weird huh?) // map tmd data to its actual address GsMapModelingData( pModel + MODEL_MAP_OFFSET ) ; // increment pointer twice more - to point to top of model data (beats me!) // and link the model (tmd) with the players object handler GsLinkObject4( ( u_long ) ( pModel + MODEL_DATA_OFFSET ) , this,//&thePlayer->gsObjectHandler, 0 ) ; } void C3DObject::initCords( ) { // initialise the players coordinate system - set to be that of the //world GsInitCoordinate2( WORLD, ( GsCOORDINATE2* ) this ) ; // Assign the coordinates of the object model to the Object Handler coord2 = (GsCOORDINATE2*)this;//&thePlayer->gsObjectCoord; } // This function deals with setting up matrices needed for rendering // and sends the object to the ordering table so it is drawn void C3DObject::draw( COrderTableHeader& header ) { MATRIX tmpls, tmplw; GsDOBJ2* tmpPtr; // Set The Local World/Screen MATRIX GsGetLws( coord2, &tmplw, &tmpls ) ; GsSetLightMatrix( &tmplw ) ; GsSetLsMatrix( &tmpls ) ; tmpPtr = (GsDOBJ2*) this ; // Send Object To Ordering Table GsSortObject4( tmpPtr, &header , 4,//14 - ORDERING_TABLE_LENGTH, ( u_long* ) getScratchAddr( 0 ) ) ; } void C3DObject::advance( int nSpeed ) { // Moves the model nD units in the direction of its rotation vector MATRIX matTmp; SVECTOR startVector; SVECTOR currentDirection; // if nD = 0 there is no movement and we need to avois the // main body of the function which will cause a divide by zero error if( nSpeed ) { // set up original vector, pointing down the positive z axis startVector = m_startVector ; // RotMatrix sets up the matrix coefficients for rotation RotMatrix( (SVECTOR*)this ,//rotateVector, &matTmp ) ; // multiply startVector by mattmp and put the result in currentDirection // which is the vector defining the direction the player is pointing ApplyMatrixSV( &matTmp, &startVector, ¤tDirection); // currentDirection components have a maximum value of 4096 so we // scale nD to 4096 /nD then when we add the amount of // translation we divide by nD. This ensures that we will translate // the number of units originally specified by nD // nD = 4096 /nD ; coord.t[0] +=(currentDirection.vx * nSpeed ) / 4096; coord.t[1] +=(currentDirection.vy * nSpeed ) / 4096; coord.t[2] +=(currentDirection.vz * nSpeed ) / 4096; // Because It Has Changed, 0 Means that we will redraw it invalidate( ) ; } //if speed } void C3DObject::rotate( int x, int y, int z ) { MATRIX matTmp; // Reset the coord system to the identity matrix coord.m[0][0]=coord.m[1][1]=coord.m[2][2]=ONE; coord.m[0][1]=coord.m[0][2]=coord.m[1][0]=coord.m[1][2]=coord.m[2][0]=coord.m[2][1]=0; // Add the new rotation factors into the players rotation vector // and then set them to the remainder of division by ONE (4096) vx = (vx+x)%ONE; vy = (vy+y)%ONE; vz = (vz+z)%ONE; // RotMatrix sets up the matrix coefficients for rotation RotMatrix( ( SVECTOR* ) this, &matTmp ) ; // Concatenate the existing objects matrix with the rotation matrix MulMatrix0( &coord, &matTmp, &coord ) ; // set the flag to redraw the object invalidate( ) ; } CView::CView( ) { ; } void CView::projection( const CCord& c ) { // Set the eye position or center of projection vpx = c.x( ) ; vpy = c.y( ) ; vpz = c.z( ) ; } void CView::reference( const CCord& c ) { // Set the look at position vrx = c.x( ) ; vry = c.y( ) ; vrz = c.z( ) ; } void CView::distance( int n ) { // This is the distance between the eye // and the imaginary projection screen GsSetProjection( n ) ; } void CView::parent( _GsCOORDINATE2* pParent ) { super = pParent; } void CView::twist( int n ) { // Set which way is up rz =- n ; } bool CView::set( ) { // Activate view return GsSetRefView2( this ) ? true : false ; }