mirror of
git://opensimulator.org/git/opensim-libs
synced 2026-08-14 00:58:00 +00:00
a few more changes to ubode ( STILL BAD ON LINUX )
This commit is contained in:
@@ -20,133 +20,133 @@
|
||||
#ifndef __OPC_BASEMODEL_H__
|
||||
#define __OPC_BASEMODEL_H__
|
||||
|
||||
//! Model creation structure
|
||||
struct OPCODE_API OPCODECREATE
|
||||
{
|
||||
//! Constructor
|
||||
OPCODECREATE();
|
||||
//! Model creation structure
|
||||
struct OPCODE_API OPCODECREATE
|
||||
{
|
||||
//! Constructor
|
||||
OPCODECREATE();
|
||||
|
||||
MeshInterface* mIMesh; //!< Mesh interface (access to triangles & vertices) (*)
|
||||
BuildSettings mSettings; //!< Builder's settings
|
||||
bool mKeepOriginal; //!< true => keep a copy of the original tree (debug purpose)
|
||||
bool mCanRemap; //!< true => allows OPCODE to reorganize client arrays
|
||||
MeshInterface* mIMesh; //!< Mesh interface (access to triangles & vertices) (*)
|
||||
BuildSettings mSettings; //!< Builder's settings
|
||||
bool mKeepOriginal; //!< true => keep a copy of the original tree (debug purpose)
|
||||
bool mCanRemap; //!< true => allows OPCODE to reorganize client arrays
|
||||
|
||||
// (*) This pointer is saved internally and used by OPCODE until collision structures are released,
|
||||
// so beware of the object's lifetime.
|
||||
};
|
||||
// (*) This pointer is saved internally and used by OPCODE until collision structures are released,
|
||||
// so beware of the object's lifetime.
|
||||
};
|
||||
|
||||
enum ModelFlag
|
||||
{
|
||||
OPC_SINGLE_NODE = (1<<2) //!< Special case for 1-node models
|
||||
};
|
||||
enum ModelFlag
|
||||
{
|
||||
OPC_SINGLE_NODE = (1 << 2) //!< Special case for 1-node models
|
||||
};
|
||||
|
||||
class OPCODE_API BaseModel
|
||||
{
|
||||
public:
|
||||
// Constructor/Destructor
|
||||
BaseModel();
|
||||
virtual ~BaseModel();
|
||||
class OPCODE_API BaseModel
|
||||
{
|
||||
public:
|
||||
// Constructor/Destructor
|
||||
BaseModel();
|
||||
virtual ~BaseModel();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Builds a collision model.
|
||||
* \param create [in] model creation structure
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual bool Build(const OPCODECREATE& create) = 0;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Builds a collision model.
|
||||
* \param create [in] model creation structure
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual bool Build(const OPCODECREATE& create) = 0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the number of bytes used by the tree.
|
||||
* \return amount of bytes used
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual udword GetUsedBytes() const = 0;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the number of bytes used by the tree.
|
||||
* \return amount of bytes used
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual udword GetUsedBytes() const = 0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Refits the collision model. This can be used to handle dynamic meshes. Usage is:
|
||||
* 1. modify your mesh vertices (keep the topology constant!)
|
||||
* 2. refit the tree (call this method)
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual bool Refit();
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Refits the collision model. This can be used to handle dynamic meshes. Usage is:
|
||||
* 1. modify your mesh vertices (keep the topology constant!)
|
||||
* 2. refit the tree (call this method)
|
||||
* \return true if success
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual bool Refit();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the source tree.
|
||||
* \return generic tree
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ const AABBTree* GetSourceTree() const { return mSource; }
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the source tree.
|
||||
* \return generic tree
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ const AABBTree* GetSourceTree() const { return mSource; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the tree.
|
||||
* \return the collision tree
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ const AABBOptimizedTree* GetTree() const { return mTree; }
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the tree.
|
||||
* \return the collision tree
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ const AABBOptimizedTree* GetTree() const { return mTree; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the tree.
|
||||
* \return the collision tree
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ AABBOptimizedTree* GetTree() { return mTree; }
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the tree.
|
||||
* \return the collision tree
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ AABBOptimizedTree* GetTree() { return mTree; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the number of nodes in the tree.
|
||||
* Should be 2*N-1 for normal trees and N-1 for optimized ones.
|
||||
* \return number of nodes
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ udword GetNbNodes() const { return mTree->GetNbNodes(); }
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the number of nodes in the tree.
|
||||
* Should be 2*N-1 for normal trees and N-1 for optimized ones.
|
||||
* \return number of nodes
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ udword GetNbNodes() const { return mTree->GetNbNodes(); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks whether the model has a single node or not. This special case must be handled separately.
|
||||
* \return true if the model has only 1 node
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL HasSingleNode() const { return mModelCode & OPC_SINGLE_NODE; }
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks whether the model has a single node or not. This special case must be handled separately.
|
||||
* \return true if the model has only 1 node
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL HasSingleNode() const { return mModelCode & OPC_SINGLE_NODE; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the model's code.
|
||||
* \return model's code
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ udword GetModelCode() const { return mModelCode; }
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the model's code.
|
||||
* \return model's code
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ udword GetModelCode() const { return mModelCode; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the mesh interface.
|
||||
* \return mesh interface
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ const MeshInterface* GetMeshInterface() const { return mIMesh; }
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Gets the mesh interface.
|
||||
* \return mesh interface
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ const MeshInterface* GetMeshInterface() const { return mIMesh; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Sets the mesh interface.
|
||||
* \param imesh [in] mesh interface
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void SetMeshInterface(const MeshInterface* imesh) { mIMesh = imesh; }
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Sets the mesh interface.
|
||||
* \param imesh [in] mesh interface
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void SetMeshInterface(const MeshInterface* imesh) { mIMesh = imesh; }
|
||||
|
||||
protected:
|
||||
const MeshInterface* mIMesh; //!< User-defined mesh interface
|
||||
udword mModelCode; //!< Model code = combination of ModelFlag(s)
|
||||
AABBTree* mSource; //!< Original source tree
|
||||
AABBOptimizedTree* mTree; //!< Optimized tree owned by the model
|
||||
// Internal methods
|
||||
void ReleaseBase();
|
||||
bool CreateTree();
|
||||
};
|
||||
protected:
|
||||
const MeshInterface* mIMesh; //!< User-defined mesh interface
|
||||
udword mModelCode; //!< Model code = combination of ModelFlag(s)
|
||||
AABBTree* mSource; //!< Original source tree
|
||||
AABBOptimizedTree* mTree; //!< Optimized tree owned by the model
|
||||
// Internal methods
|
||||
void ReleaseBase();
|
||||
bool CreateTree();
|
||||
};
|
||||
|
||||
#endif //__OPC_BASEMODEL_H__
|
||||
|
||||
@@ -20,157 +20,155 @@
|
||||
#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)
|
||||
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_CONTACT_FOUND = OPC_FIRST_CONTACT | OPC_CONTACT,
|
||||
OPC_TEMPORAL_CONTACT = OPC_TEMPORAL_HIT | OPC_CONTACT,
|
||||
|
||||
OPC_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
OPC_FORCE_DWORD = 0x7fffffff
|
||||
};
|
||||
|
||||
class OPCODE_API Collider
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
Collider();
|
||||
virtual ~Collider();
|
||||
class OPCODE_API Collider
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
Collider();
|
||||
virtual ~Collider();
|
||||
|
||||
// Collision report
|
||||
// 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 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 "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; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 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 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 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; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
// Settings
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 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 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;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 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;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
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
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 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;
|
||||
// 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;
|
||||
|
||||
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
|
||||
mIMesh = model->GetMeshInterface();
|
||||
return mIMesh != null;
|
||||
}
|
||||
|
||||
// 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; }
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Initializes a query
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual inline_ void InitQuery() { mFlags &= ~OPC_TEMPORAL_CONTACT; }
|
||||
};
|
||||
|
||||
#endif // __OPC_COLLIDER_H__
|
||||
|
||||
@@ -41,79 +41,71 @@ ODE_PURE_INLINE bool avxBoxesOverlap(const dReal* acenter, const dReal* bcenter
|
||||
}
|
||||
#endif
|
||||
|
||||
class OPCODE_API CollisionAABB
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ CollisionAABB() {}
|
||||
//! Constructor
|
||||
inline_ CollisionAABB(const AABB& b) { b.GetCenter(mCenter); b.GetExtents(mExtents); }
|
||||
//! Destructor
|
||||
inline_ ~CollisionAABB() {}
|
||||
class OPCODE_API CollisionAABB
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ CollisionAABB() {}
|
||||
//! Constructor
|
||||
inline_ CollisionAABB(const AABB& b) { b.GetCenter(mCenter); b.GetExtents(mExtents); }
|
||||
//! Destructor
|
||||
inline_ ~CollisionAABB() {}
|
||||
|
||||
//! Get min point of the box
|
||||
inline_ void GetMin(Point& min) const { min = mCenter - mExtents; }
|
||||
//! Get max point of the box
|
||||
inline_ void GetMax(Point& max) const { max = mCenter + mExtents; }
|
||||
//! Get min point of the box
|
||||
inline_ void GetMin(Point& min) const { min = mCenter - mExtents; }
|
||||
//! Get max point of the box
|
||||
inline_ void GetMax(Point& max) const { max = mCenter + mExtents; }
|
||||
|
||||
//! Get component of the box's min point along a given axis
|
||||
inline_ float GetMin(udword axis) const { return mCenter[axis] - mExtents[axis]; }
|
||||
//! Get component of the box's max point along a given axis
|
||||
inline_ float GetMax(udword axis) const { return mCenter[axis] + mExtents[axis]; }
|
||||
//! Get component of the box's min point along a given axis
|
||||
inline_ float GetMin(udword axis) const { return mCenter[axis] - mExtents[axis]; }
|
||||
//! Get component of the box's max point along a given axis
|
||||
inline_ float GetMax(udword axis) const { return mCenter[axis] + mExtents[axis]; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Setups an AABB from min & max vectors.
|
||||
* \param min [in] the min point
|
||||
* \param max [in] the max point
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void SetMinMax(const Point& min, const Point& max) { mCenter = (max + min)*0.5f; mExtents = (max - min)*0.5f; }
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Setups an AABB from min & max vectors.
|
||||
* \param min [in] the min point
|
||||
* \param max [in] the max point
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void SetMinMax(const Point& min, const Point& max)
|
||||
{
|
||||
mCenter = (max + min)*0.5f;
|
||||
mExtents = (max - min)*0.5f;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks a box is inside another box.
|
||||
* \param box [in] the other box
|
||||
* \return true if current box is inside input box
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL IsInside(const CollisionAABB& box) const
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Checks a box is inside another box.
|
||||
* \param box [in] the other box
|
||||
* \return true if current box is inside input box
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ BOOL IsInside(const CollisionAABB& box) const
|
||||
{
|
||||
#if defined (__AVX__)
|
||||
return avxBoxesOverlap(&(box.mCenter.x), &(mCenter.x), &(box.mExtents.x), &(mExtents.x));
|
||||
return avxBoxesOverlap(&(box.mCenter.x), &(mCenter.x), &(box.mExtents.x), &(mExtents.x));
|
||||
#else
|
||||
if(box.GetMin(0)>GetMin(0)) return FALSE;
|
||||
if(box.GetMin(1)>GetMin(1)) return FALSE;
|
||||
if(box.GetMin(2)>GetMin(2)) return FALSE;
|
||||
if(box.GetMax(0)<GetMax(0)) return FALSE;
|
||||
if(box.GetMax(1)<GetMax(1)) return FALSE;
|
||||
if(box.GetMax(2)<GetMax(2)) return FALSE;
|
||||
return TRUE;
|
||||
if (box.GetMin(0) > GetMin(0)) return FALSE;
|
||||
if (box.GetMin(1) > GetMin(1)) return FALSE;
|
||||
if (box.GetMin(2) > GetMin(2)) return FALSE;
|
||||
if (box.GetMax(0) < GetMax(0)) return FALSE;
|
||||
if (box.GetMax(1) < GetMax(1)) return FALSE;
|
||||
if (box.GetMax(2) < GetMax(2)) return FALSE;
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Point mCenter; //!< Box center
|
||||
Point mExtents; //!< Box extents
|
||||
};
|
||||
Point mCenter; //!< Box center
|
||||
Point mExtents; //!< Box extents
|
||||
};
|
||||
|
||||
class OPCODE_API QuantizedAABB
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ QuantizedAABB() {}
|
||||
//! Destructor
|
||||
inline_ ~QuantizedAABB() {}
|
||||
|
||||
sword mCenter[3]; //!< Quantized center
|
||||
uword mExtents[3]; //!< Quantized extents
|
||||
};
|
||||
|
||||
//! Quickly rotates & translates a vector
|
||||
inline_ void TransformPoint(Point& dest, const Point& source, const Matrix3x3& rot, const Point& trans)
|
||||
{
|
||||
dest.x = trans.x + source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0];
|
||||
dest.y = trans.y + source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1];
|
||||
dest.z = trans.z + source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2];
|
||||
}
|
||||
//! Quickly rotates & translates a vector
|
||||
inline_ void TransformPoint(Point& dest, const Point& source, const Matrix3x3& rot, const Point& trans)
|
||||
{
|
||||
dest.x = trans.x + source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0];
|
||||
dest.y = trans.y + source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1];
|
||||
dest.z = trans.z + source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2];
|
||||
}
|
||||
|
||||
#endif //__OPC_COMMON_H__
|
||||
|
||||
@@ -83,22 +83,6 @@
|
||||
// good strategy.
|
||||
};
|
||||
|
||||
class OPCODE_API AABBQuantizedNode
|
||||
{
|
||||
IMPLEMENT_IMPLICIT_NODE(AABBQuantizedNode, QuantizedAABB)
|
||||
|
||||
inline_ uword GetSize() const
|
||||
{
|
||||
const uword* Bits = mAABB.mExtents;
|
||||
uword Max = Bits[0];
|
||||
if(Bits[1]>Max) Max = Bits[1];
|
||||
if(Bits[2]>Max) Max = Bits[2];
|
||||
return Max;
|
||||
}
|
||||
// NB: for quantized nodes I don't feel like computing a square-magnitude with integers all
|
||||
// over the place.......!
|
||||
};
|
||||
|
||||
class OPCODE_API AABBNoLeafNode
|
||||
{
|
||||
IMPLEMENT_NOLEAF_NODE(AABBNoLeafNode, CollisionAABB)
|
||||
|
||||
@@ -20,211 +20,207 @@
|
||||
#ifndef __OPC_RAYCOLLIDER_H__
|
||||
#define __OPC_RAYCOLLIDER_H__
|
||||
|
||||
class OPCODE_API CollisionFace
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline_ CollisionFace() {}
|
||||
//! Destructor
|
||||
inline_ ~CollisionFace() {}
|
||||
class OPCODE_API CollisionFace
|
||||
{
|
||||
public:
|
||||
inline_ CollisionFace() {}
|
||||
inline_ ~CollisionFace() {}
|
||||
|
||||
udword mFaceID; //!< Index of touched face
|
||||
float mDistance; //!< Distance from collider to hitpoint
|
||||
float mU, mV; //!< Impact barycentric coordinates
|
||||
};
|
||||
udword mFaceID; //!< Index of touched face
|
||||
float mDistance; //!< Distance from collider to hitpoint
|
||||
float mU, mV; //!< Impact barycentric coordinates
|
||||
};
|
||||
|
||||
class OPCODE_API CollisionFaces : public Container
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
CollisionFaces() {}
|
||||
//! Destructor
|
||||
~CollisionFaces() {}
|
||||
class OPCODE_API CollisionFaces : public Container
|
||||
{
|
||||
public:
|
||||
inline_ CollisionFaces() {}
|
||||
inline_ ~CollisionFaces() {}
|
||||
|
||||
inline_ udword GetNbFaces() const
|
||||
inline_ udword GetNbFaces()
|
||||
{
|
||||
return GetNbEntries() >> 2;
|
||||
}
|
||||
inline_ const CollisionFace* GetFaces() const
|
||||
inline_ CollisionFace* GetFaces()
|
||||
{
|
||||
return (const CollisionFace*)GetEntries();
|
||||
return (CollisionFace*)GetEntries();
|
||||
}
|
||||
|
||||
inline_ void Reset()
|
||||
inline_ void Reset()
|
||||
{
|
||||
Container::Reset();
|
||||
}
|
||||
|
||||
inline_ void AddFace(const CollisionFace& face)
|
||||
inline_ void AddFace(CollisionFace& face)
|
||||
{
|
||||
Add(face.mFaceID).Add(face.mDistance).Add(face.mU).Add(face.mV);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class OPCODE_API RayCollider : public Collider
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
class OPCODE_API RayCollider : public Collider
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
RayCollider();
|
||||
virtual ~RayCollider();
|
||||
virtual ~RayCollider();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Generic stabbing query for generic OPCODE models. After the call, access the results:
|
||||
* - with GetContactStatus()
|
||||
* - in the user-provided destination array
|
||||
*
|
||||
* \param world_ray [in] stabbing ray in world space
|
||||
* \param model [in] Opcode model to collide with
|
||||
* \param world [in] model's world matrix, or null
|
||||
* \param cache [in] a possibly cached face index, or null
|
||||
* \return true if success
|
||||
* \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Collide(const Ray& world_ray, const Model& model, const Matrix4x4* world=null, udword* cache=null);
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Generic stabbing query for generic OPCODE models. After the call, access the results:
|
||||
* - with GetContactStatus()
|
||||
* - in the user-provided destination array
|
||||
*
|
||||
* \param world_ray [in] stabbing ray in world space
|
||||
* \param model [in] Opcode model to collide with
|
||||
* \param world [in] model's world matrix, or null
|
||||
* \param cache [in] a possibly cached face index, or null
|
||||
* \return true if success
|
||||
* \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool Collide(const Ray& world_ray, const Model& model, const Matrix4x4* world = null, udword* cache = null);
|
||||
//
|
||||
bool Collide(const Ray& world_ray, const AABBTree* tree, Container& box_indices);
|
||||
// Settings
|
||||
// Settings
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Settings: enable or disable "closest hit" mode.
|
||||
* \param flag [in] true to report closest hit only
|
||||
* \see SetCulling(bool flag)
|
||||
* \see SetMaxDist(float max_dist)
|
||||
* \see SetDestination(StabbedFaces* sf)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void SetClosestHit(bool flag)
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Settings: enable or disable "closest hit" mode.
|
||||
* \param flag [in] true to report closest hit only
|
||||
* \see SetCulling(bool flag)
|
||||
* \see SetMaxDist(float max_dist)
|
||||
* \see SetDestination(StabbedFaces* sf)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void SetClosestHit(bool flag)
|
||||
{
|
||||
mClosestHit = flag;
|
||||
mClosestHit = flag;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Settings: enable or disable backface culling.
|
||||
* \param flag [in] true to enable backface culling
|
||||
* \see SetClosestHit(bool flag)
|
||||
* \see SetMaxDist(float max_dist)
|
||||
* \see SetDestination(StabbedFaces* sf)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void SetCulling(bool flag)
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Settings: enable or disable backface culling.
|
||||
* \param flag [in] true to enable backface culling
|
||||
* \see SetClosestHit(bool flag)
|
||||
* \see SetMaxDist(float max_dist)
|
||||
* \see SetDestination(StabbedFaces* sf)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void SetCulling(bool flag)
|
||||
{
|
||||
mCulling = flag;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Settings: sets the higher distance bound.
|
||||
* \param max_dist [in] higher distance bound. Default = maximal value, for ray queries (else segment)
|
||||
* \see SetClosestHit(bool flag)
|
||||
* \see SetCulling(bool flag)
|
||||
* \see SetDestination(StabbedFaces* sf)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void SetMaxDist(float max_dist = MAX_FLOAT)
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Settings: sets the higher distance bound.
|
||||
* \param max_dist [in] higher distance bound. Default = maximal value, for ray queries (else segment)
|
||||
* \see SetClosestHit(bool flag)
|
||||
* \see SetCulling(bool flag)
|
||||
* \see SetDestination(StabbedFaces* sf)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void SetMaxDist(float max_dist = MAX_FLOAT)
|
||||
{
|
||||
mMaxDist = max_dist;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Settings: sets the destination array for stabbed faces.
|
||||
* \param cf [in] destination array, filled during queries
|
||||
* \see SetClosestHit(bool flag)
|
||||
* \see SetCulling(bool flag)
|
||||
* \see SetMaxDist(float max_dist)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void SetDestination(CollisionFaces* cf)
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Settings: sets the destination array for stabbed faces.
|
||||
* \param cf [in] destination array, filled during queries
|
||||
* \see SetClosestHit(bool flag)
|
||||
* \see SetCulling(bool flag)
|
||||
* \see SetMaxDist(float max_dist)
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ void SetDestination(CollisionFaces* cf)
|
||||
{
|
||||
mStabbedFaces = cf;
|
||||
}
|
||||
// Stats
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Stats: gets the number of Ray-BV overlap tests after a collision query.
|
||||
* \see GetNbRayPrimTests()
|
||||
* \see GetNbIntersections()
|
||||
* \return the number of Ray-BV tests performed during last query
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ udword GetNbRayBVTests() const
|
||||
// Stats
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Stats: gets the number of Ray-BV overlap tests after a collision query.
|
||||
* \see GetNbRayPrimTests()
|
||||
* \see GetNbIntersections()
|
||||
* \return the number of Ray-BV tests performed during last query
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ udword GetNbRayBVTests() const
|
||||
{
|
||||
return mNbRayBVTests;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Stats: gets the number of Ray-Triangle overlap tests after a collision query.
|
||||
* \see GetNbRayBVTests()
|
||||
* \see GetNbIntersections()
|
||||
* \return the number of Ray-Triangle tests performed during last query
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ udword GetNbRayPrimTests() const
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Stats: gets the number of Ray-Triangle overlap tests after a collision query.
|
||||
* \see GetNbRayBVTests()
|
||||
* \see GetNbIntersections()
|
||||
* \return the number of Ray-Triangle tests performed during last query
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ udword GetNbRayPrimTests() const
|
||||
{
|
||||
return mNbRayPrimTests;
|
||||
}
|
||||
|
||||
// In-out test
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Stats: gets the number of intersection found after a collision query. Can be used for in/out tests.
|
||||
* \see GetNbRayBVTests()
|
||||
* \see GetNbRayPrimTests()
|
||||
* \return the number of valid intersections during last query
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ udword GetNbIntersections() const
|
||||
// In-out test
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Stats: gets the number of intersection found after a collision query. Can be used for in/out tests.
|
||||
* \see GetNbRayBVTests()
|
||||
* \see GetNbRayPrimTests()
|
||||
* \return the number of valid intersections during last query
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline_ udword GetNbIntersections() const
|
||||
{
|
||||
return mNbIntersections;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider.
|
||||
* \return null if everything is ok, else a string describing the problem
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
override(Collider) const char* ValidateSettings();
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider.
|
||||
* \return null if everything is ok, else a string describing the problem
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
override(Collider) const char* ValidateSettings();
|
||||
|
||||
protected:
|
||||
// Ray in local space
|
||||
Point mOrigin; //!< Ray origin
|
||||
Point mDir; //!< Ray direction (normalized)
|
||||
Point mFDir; //!< fabsf(mDir)
|
||||
Point mData, mData2;
|
||||
// Stabbed faces
|
||||
CollisionFace mStabbedFace; //!< Current stabbed face
|
||||
CollisionFaces* mStabbedFaces; //!< List of stabbed faces
|
||||
bool mClosestHit; //!< Report closest hit only
|
||||
// Stats
|
||||
udword mNbRayBVTests; //!< Number of Ray-BV tests
|
||||
udword mNbRayPrimTests; //!< Number of Ray-Primitive tests
|
||||
// In-out test
|
||||
udword mNbIntersections; //!< Number of valid intersections
|
||||
// Dequantization coeffs
|
||||
Point mCenterCoeff;
|
||||
Point mExtentsCoeff;
|
||||
// Settings
|
||||
float mMaxDist; //!< Valid segment on the ray
|
||||
protected:
|
||||
// Ray in local space
|
||||
Point mOrigin; //!< Ray origin
|
||||
Point mDir; //!< Ray direction (normalized)
|
||||
Point mFDir; //!< fabsf(mDir)
|
||||
Point mData, mData2;
|
||||
// Stabbed faces
|
||||
CollisionFace mStabbedFace; //!< Current stabbed face
|
||||
CollisionFaces* mStabbedFaces; //!< List of stabbed faces
|
||||
bool mClosestHit; //!< Report closest hit only
|
||||
// Stats
|
||||
udword mNbRayBVTests; //!< Number of Ray-BV tests
|
||||
udword mNbRayPrimTests; //!< Number of Ray-Primitive tests
|
||||
// In-out test
|
||||
udword mNbIntersections; //!< Number of valid intersections
|
||||
// Dequantization coeffs
|
||||
Point mCenterCoeff;
|
||||
Point mExtentsCoeff;
|
||||
// Settings
|
||||
float mMaxDist; //!< Valid segment on the ray
|
||||
bool mCulling; //!< Stab culled faces or not
|
||||
// Internal methods
|
||||
void _SegmentStab(const AABBCollisionNode* node);
|
||||
void _SegmentStab(const AABBNoLeafNode* node);
|
||||
void _SegmentStab(const AABBTreeNode* node, Container& box_indices);
|
||||
void _RayStab(const AABBCollisionNode* node);
|
||||
void _RayStab(const AABBNoLeafNode* node);
|
||||
void _RayStab(const AABBTreeNode* node, Container& box_indices);
|
||||
// Overlap tests
|
||||
inline_ BOOL RayAABBOverlap(const Point& center, const Point& extents);
|
||||
inline_ BOOL SegmentAABBOverlap(const Point& center, const Point& extents);
|
||||
inline_ BOOL RayTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2);
|
||||
// Init methods
|
||||
BOOL InitQuery(const Ray& world_ray, const Matrix4x4* world=null, udword* face_id=null);
|
||||
};
|
||||
// Internal methods
|
||||
void _SegmentStab(const AABBCollisionNode* node);
|
||||
void _SegmentStab(const AABBNoLeafNode* node);
|
||||
void _SegmentStab(const AABBTreeNode* node, Container& box_indices);
|
||||
void _RayStab(const AABBCollisionNode* node);
|
||||
void _RayStab(const AABBNoLeafNode* node);
|
||||
void _RayStab(const AABBTreeNode* node, Container& box_indices);
|
||||
// Overlap tests
|
||||
inline_ BOOL RayAABBOverlap(const Point& center, const Point& extents);
|
||||
inline_ BOOL SegmentAABBOverlap(const Point& center, const Point& extents);
|
||||
inline_ BOOL RayTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2);
|
||||
// Init methods
|
||||
BOOL InitQuery(const Ray& world_ray, const Matrix4x4* world = null, udword* face_id = null);
|
||||
};
|
||||
|
||||
#endif // __OPC_RAYCOLLIDER_H__
|
||||
|
||||
Reference in New Issue
Block a user