text: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  /*
   *	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__
  