/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains base collider class. * \file OPC_Collider.h * \author Pierre Terdiman * \date June, 2, 2001 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_COLLIDER_H__ #define __OPC_COLLIDER_H__ enum CollisionFlag { OPC_FIRST_CONTACT = (1<<0), //!< Report all contacts (false) or only first one (true) OPC_TEMPORAL_COHERENCE = (1<<1), //!< Use temporal coherence or not OPC_CONTACT = (1<<2), //!< Final contact status after a collision query OPC_TEMPORAL_HIT = (1<<3), //!< There has been an early exit due to temporal coherence OPC_NO_PRIMITIVE_TESTS = (1<<4), //!< Keep or discard primitive-bv tests in leaf nodes (volume-mesh queries) OPC_CONTACT_FOUND = OPC_FIRST_CONTACT | OPC_CONTACT, OPC_TEMPORAL_CONTACT = OPC_TEMPORAL_HIT | OPC_CONTACT, OPC_FORCE_DWORD = 0x7fffffff }; class OPCODE_API Collider { public: // Constructor / Destructor Collider(); virtual ~Collider(); // Collision report /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the last collision status after a collision query. * \return true if a collision occured */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL GetContactStatus() const { return mFlags & OPC_CONTACT; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the "first contact" mode. * \return true if "first contact" mode is on */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL FirstContactEnabled() const { return mFlags & OPC_FIRST_CONTACT; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Gets the temporal coherence mode. * \return true if temporal coherence is on */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL TemporalCoherenceEnabled() const { return mFlags & OPC_TEMPORAL_COHERENCE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks a first contact has already been found. * \return true if a first contact has been found and we can stop a query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL ContactFound() const { return (mFlags&OPC_CONTACT_FOUND)==OPC_CONTACT_FOUND; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks there's been an early exit due to temporal coherence; * \return true if a temporal hit has occured */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL TemporalHit() const { return mFlags & OPC_TEMPORAL_HIT; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks primitive tests are enabled; * \return true if primitive tests must be skipped */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL SkipPrimitiveTests() const { return mFlags & OPC_NO_PRIMITIVE_TESTS; } // Settings /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Reports all contacts (false) or first contact only (true) * \param flag [in] true for first contact, false for all contacts * \see SetTemporalCoherence(bool flag) * \see ValidateSettings() */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void SetFirstContact(bool flag) { if(flag) mFlags |= OPC_FIRST_CONTACT; else mFlags &= ~OPC_FIRST_CONTACT; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Enable/disable temporal coherence. * \param flag [in] true to enable temporal coherence, false to discard it * \see SetFirstContact(bool flag) * \see ValidateSettings() */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void SetTemporalCoherence(bool flag) { if(flag) mFlags |= OPC_TEMPORAL_COHERENCE; else mFlags &= ~OPC_TEMPORAL_COHERENCE; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Enable/disable primitive tests. * \param flag [in] true to enable primitive tests, false to discard them */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void SetPrimitiveTests(bool flag) { if(!flag) mFlags |= OPC_NO_PRIMITIVE_TESTS; else mFlags &= ~OPC_NO_PRIMITIVE_TESTS; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Validates current settings. You should call this method after all the settings / callbacks have been defined for a collider. * \return null if everything is ok, else a string describing the problem */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual const char* ValidateSettings() = 0; protected: udword mFlags; //!< Bit flags const BaseModel* mCurrentModel; //!< Current model for collision query (owner of touched faces) // User mesh interface const MeshInterface* mIMesh; //!< User-defined mesh interface // Internal methods /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Setups current collision model * \param model [in] current collision model * \return TRUE if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ BOOL Setup(const BaseModel* model) { // Keep track of current model mCurrentModel = model; if(!mCurrentModel) return FALSE; mIMesh = model->GetMeshInterface(); return mIMesh!=null; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Initializes a query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual inline_ void InitQuery() { mFlags &= ~OPC_TEMPORAL_CONTACT; } }; #endif // __OPC_COLLIDER_H__