BetaBetaMari.cpp

Go to the documentation of this file.
00001 #include "BetabetaMari.h"
00002 #include "MercuryMath.h"
00003 #include "MercuryTheme.h"
00004 
00005 #define     MC_INPUTMAPPED      1       //convention: MESSAGE CODE
00006 #define     MC_INPUTUNMAPPED    2
00007 #define     MC_BETAJOIN         3
00008 
00009 //Register the BetaBetaMari with MercuryODE
00010 REGISTER_ODE_OBJECT_CLASS( BetaBetaMari );
00011 
00012 BetaBetaMari::~BetaBetaMari()
00013 {
00014 }
00015 
00016 void BetaBetaMari::Init()
00017 {
00018     MercuryODEObjectLoadable::Init();
00019 
00020     //load wav file name from metric.ini
00021 //  stick = SOUNDMAN->Load(THEME.GetMetricS(GetName(), "Stick"));
00022 //  AddObject(stick);
00023 
00024     //Set up initial ball's size
00025     fOldMariSize = 7;
00026     fMariSize = 7;      
00027 
00028     //Generate the ball itself, and attach it to the local space
00029     m_pSph = dCreateSphere( m_oSpace, SQRT( fMariSize ) + 1 );
00030     dGeomSetBody( m_pSph, m_oBody );
00031     dGeomSetData( m_pSph, this );
00032 
00033     //Don't allow auto disbale on the control object or it will never move
00034     if (m_oBody)
00035         dBodySetAutoDisableFlag (m_oBody, false);
00036 
00037     this->RegisterMessage( MC_BETAJOIN, "betabetamarijoin" );
00038 }
00039 
00040 void BetaBetaMari::Update( const float dTime )
00041 {
00042     //See if the mari grew
00043     if ( fOldMariSize != fMariSize )
00044     {
00045         dSpaceRemove( m_oSpace, m_pSph );   //Take out the old object
00046         fOldMariSize = fMariSize;
00047 
00048         //Generate the new ball collision object
00049         m_pSph = dCreateSphere( m_oSpace, SQRT( fMariSize )+1 );
00050         dGeomSetData( m_pSph, this );
00051         dGeomSetBody( m_pSph, m_oBody );
00052     }
00053 
00054     //Continue update cycle
00055     MercuryODEObjectLoadable::Update( dTime );
00056 }
00057 
00058 void BetaBetaMari::Message( int Message, PStack & data, const MString & name )
00059 {
00060     if (Message == MC_BETAJOIN)
00061     {
00062         MercuryODEObjectLoadable* pHit2 = (MercuryODEObjectLoadable*)data.PeekItem(5).GetValueV();
00063         MercuryODEWorld* pWorld = (MercuryODEWorld*)data.PeekItem(4).GetValueV();
00064         fMariSize += data.PeekItem().GetValueF();       //Increase the size of our mari
00065 
00066         MercuryPoint DX(data.PeekItem(3).GetValueF(),
00067                         data.PeekItem(2).GetValueF(),
00068                         data.PeekItem(1).GetValueF());
00069 
00070         //Get the position of the contact
00071         DX = DX - GetPosition();    //And find the relative position
00072 
00073         //Verify that we didn't get a bogus hit.
00074         if( (SQRT( fMariSize )+1) * 1.1 < DX.Magnitude() )
00075             return;
00076 
00077 //      stick->Play();
00078 
00079         //Begin dismantling the hit object
00080         dSpaceSetCleanup( pHit2->m_oSpace, 0 );
00081 
00082 //      LOG.Info( ssprintf( "Marisize: %f\n", fMariSize ) );
00083 
00084         for ( unsigned int i = 0; i < pHit2->m_vAllTransforms.size(); i++ )
00085         {
00086             dGeomID Tran = dCreateGeomTransform( m_oSpace );    //Create a new transformation
00087             dGeomSetData( Tran, this );                         //And set the data for all geoms
00088             dGeomSetData( pHit2->m_vAllTransforms[i], this );
00089             dGeomSetData( pHit2->m_vAllGeoms[i], this );
00090             dGeomTransformSetCleanup( Tran, 1 );                //Configure the cleanup mode
00091             dGeomSetBody( pHit2->m_vAllTransforms[i], 0 );      //Attach all geoms to _this_ body
00092             dGeomSetBody( pHit2->m_vAllGeoms[i], 0 );
00093             dGeomSetBody( Tran, m_oBody );
00094 
00095             const dReal * MAT = dBodyGetRotation( m_oBody );    //Find the current rotation
00096             
00097             dGeomTransformSetGeom( Tran, pHit2->m_vAllTransforms[i] );
00098             if ( dGeomGetSpace( pHit2->m_vAllTransforms[i] ) == m_oSpace )
00099                 dSpaceRemove( m_oSpace, pHit2->m_vAllTransforms[i] );
00100 
00101             //Multiply the matricies, to perform the rotation
00102             MercuryPoint DXO;
00103             DXO.x = DX.x * MAT[0] + DX.y * MAT[4] + DX.z * MAT[8];
00104             DXO.y = DX.x * MAT[1] + DX.y * MAT[5] + DX.z * MAT[9];
00105             DXO.z = DX.x * MAT[2] + DX.y * MAT[6] + DX.z * MAT[10];
00106             DX = DXO;
00107 
00108             //Set the position of the newly attached object
00109             dGeomSetPosition( pHit2->m_vAllTransforms[i], DX.x, DX.y,DX.z );
00110         }
00111 
00112         //Remove the newly attached object's old information
00113         pWorld->RemoveObject( pHit2, false );
00114 
00115         //Make it a child of _this_
00116         AddObject( pHit2, true );
00117 
00118         //Set its position, and other information
00119         pHit2->SetPosition(DX);
00120         pHit2->m_bBodied = false;
00121 
00122         //Destroy it's body information
00123         if (pHit2->m_oBody)
00124             dBodyDestroy( pHit2->m_oBody );
00125 
00126         //Clean out the old object
00127         pHit2->m_vAllGeoms.clear();
00128         pHit2->m_vAllTransforms.clear();
00129     }
00130 }
00131 
00132 bool BetaBetaMari::Collide( MercuryODEObject * pHit, dContact &pContact, MercuryODEWorld * pWorld )
00133 {
00134     //Typecast pHit (Since we only have Loadables)
00135     MercuryODEObjectLoadable * pHit2 = (MercuryODEObjectLoadable*)pHit; 
00136 
00137     if ( !pHit2->m_bBodied )        //Make sure what we are colliding with has a body, otherwise act normally
00138         return true;
00139     if ( pHit == this )             //If we're colliding with part of ourself, ignore.
00140         return false;
00141     if ( pHit->m_oBody == m_oBody ) //If the representation of our body is identical to that of another, ignore.
00142         return false;
00143 
00144     //See if any of the contacts are with the sphere itself, if so, do a normal collision
00145     if ( pContact.geom.g1 != m_pSph && pContact.geom.g2 != m_pSph )
00146         return true;
00147 
00148     //Find the size of the object we're hitting
00149     float fSizeHit = pHit->GetParameter( "Size" ).GetValueF();
00150 
00151     //Make sure we're allowed to suck it up
00152     if (  fSizeHit == 0 || fSizeHit > SQRT( fMariSize ) / 1.7 )
00153         return true;
00154 
00155     PStack data;
00156     data.PushItem(PSElement((void*)pHit));
00157     data.PushItem(PSElement((void*)pWorld));
00158     data.PushItem(pContact.geom.pos[0]);
00159     data.PushItem(pContact.geom.pos[1]);
00160     data.PushItem(pContact.geom.pos[2]);
00161     data.PushItem(PSElement(fSizeHit));
00162     MESSAGEMAN->PostSystemMessage("betabetamarijoin", data, 0);
00163 
00164     return false;
00165 }
00166 
00167 /*
00168  * (PD) 2006 Charles Lohr
00169  * No rights reserved.
00170  * 
00171  * All code inside of this document is hereby released into the
00172  * public domain.  It may be used for any purpose without limitation.
00173  *
00174  */

Hosted by SourceForge.net Logo