//----------------------------------------------------------------------------- // Copyright (c) 2013 GarageGames, LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- #include "graphics/dgl.h" #include "console/consoleTypes.h" #include "io/bitStream.h" #include "Trigger.h" // Script bindings. #include "Trigger_ScriptBinding.h" // Debug Profiling. #include "debug/profiler.h" //------------------------------------------------------------------------------ IMPLEMENT_CONOBJECT(Trigger); //----------------------------------------------------------------------------- Trigger::Trigger() { // Setup some debug vector associations. VECTOR_SET_ASSOCIATION(mEnterColliders); VECTOR_SET_ASSOCIATION(mLeaveColliders); // Set default callbacks. mEnterCallback = true; mStayCallback = false; mLeaveCallback = true; // Use a static body by default. mBodyDefinition.type = b2_staticBody; // Gather contacts. mGatherContacts = true; } //----------------------------------------------------------------------------- bool Trigger::onAdd() { // Eventually, we'll need to deal with Server/Client functionality! // Call Parent. if(!Parent::onAdd()) return false; // Return Okay. return true; } //----------------------------------------------------------------------------- void Trigger::initPersistFields() { addProtectedField("EnterCallback", TypeBool, Offset(mEnterCallback, Trigger), &setEnterCallback, &defaultProtectedGetFn, &writeEnterCallback,""); addProtectedField("StayCallback", TypeBool, Offset(mStayCallback, Trigger), &setStayCallback, &defaultProtectedGetFn, &writeStayCallback, ""); addProtectedField("LeaveCallback", TypeBool, Offset(mLeaveCallback, Trigger), &setLeaveCallback, &defaultProtectedGetFn, &writeLeaveCallback, ""); Parent::initPersistFields(); } //----------------------------------------------------------------------------- void Trigger::preIntegrate(const F32 totalTime, const F32 elapsedTime, DebugStats *pDebugStats) { // Call Parent. Parent::preIntegrate(totalTime, elapsedTime, pDebugStats); // Clear Collider Callback Lists. mEnterColliders.clear(); mLeaveColliders.clear(); } //----------------------------------------------------------------------------- void Trigger::integrateObject( const F32 totalTime, const F32 elapsedTime, DebugStats *pDebugStats ) { // Call Parent. Parent::integrateObject(totalTime, elapsedTime, pDebugStats); // Debug Profiling. PROFILE_SCOPE(Trigger_IntegrateObject); // Perform "OnEnter" callback. if ( mEnterCallback && mEnterColliders.size() > 0 ) { // Debug Profiling. PROFILE_SCOPE(Trigger_OnEnterCallback); for ( collideCallbackType::iterator contactItr = mEnterColliders.begin(); contactItr != mEnterColliders.end(); ++contactItr ) { Con::executef(this, 2, "onEnter", (*contactItr)->getIdString()); } } // Fetch current contacts. const Scene::typeContactVector* pCurrentContacts = getCurrentContacts(); // Sanity! AssertFatal( pCurrentContacts != NULL, "Trigger::integrateObject() - Contacts not initialized correctly." ); // Perform "OnStay" callback. if ( mStayCallback && pCurrentContacts->size() > 0 ) { // Debug Profiling. PROFILE_SCOPE(Trigger_OnStayCallback); for ( Scene::typeContactVector::const_iterator contactItr = pCurrentContacts->begin(); contactItr != pCurrentContacts->end(); ++contactItr ) { // Fetch colliding object. SceneObject* pCollideWidth = contactItr->getCollideWith( this ); Con::executef(this, 2, "onStay", pCollideWidth->getIdString()); } } // Perform "OnLeave" callback. if ( mLeaveCallback && mLeaveColliders.size() > 0 ) { // Debug Profiling. PROFILE_SCOPE(Trigger_OnLeaveCallback); for ( collideCallbackType::iterator contactItr = mLeaveColliders.begin(); contactItr != mLeaveColliders.end(); ++contactItr ) { Con::executef(this, 2, "onLeave", (*contactItr)->getIdString()); } } } //----------------------------------------------------------------------------- void Trigger::onBeginCollision( const TickContact& tickContact ) { // Call parent. Parent::onBeginCollision( tickContact ); // Add to enter colliders. mEnterColliders.push_back( tickContact.getCollideWith( this ) ); } //----------------------------------------------------------------------------- void Trigger::onEndCollision( const TickContact& tickContact ) { // Call parent. Parent::onEndCollision( tickContact ); // Add to leave colliders. mLeaveColliders.push_back( tickContact.getCollideWith( this ) ); } //----------------------------------------------------------------------------- void Trigger::copyTo(SimObject* object) { Parent::copyTo(object); AssertFatal(dynamic_cast(object), "Trigger::copyTo() - Object is not the correct type."); Trigger* trigger = static_cast(object); trigger->mEnterCallback = mEnterCallback; trigger->mStayCallback = mStayCallback; trigger->mLeaveCallback = mLeaveCallback; }