From 81bb6873f1c0291fecbf6e429ad15ac3db66a4c0 Mon Sep 17 00:00:00 2001 From: Aki Date: Tue, 12 Mar 2024 22:07:03 +0100 Subject: Legal notices updated Rename contrib -> third-party intendes to express the origin and purpose of that part of the code better. I plan to readd contrib/ again but with more in-project things like bash-completions, dev workflow scripts etc. --- third-party/Opcode/OPC_RayCollider.h | 225 +++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 third-party/Opcode/OPC_RayCollider.h (limited to 'third-party/Opcode/OPC_RayCollider.h') diff --git a/third-party/Opcode/OPC_RayCollider.h b/third-party/Opcode/OPC_RayCollider.h new file mode 100644 index 0000000..393bc5f --- /dev/null +++ b/third-party/Opcode/OPC_RayCollider.h @@ -0,0 +1,225 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a ray collider. + * \file OPC_RayCollider.h + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_RAYCOLLIDER_H__ +#define __OPC_RAYCOLLIDER_H__ + + class OPCODE_API CollisionFace + { + public: + //! Constructor + inline_ CollisionFace() {} + //! Destructor + inline_ ~CollisionFace() {} + + udword mFaceID; //!< Index of touched face + float mDistance; //!< Distance from collider to hitpoint + float mU, mV; //!< Impact barycentric coordinates + }; + + class OPCODE_API CollisionFaces : private Container + { + public: + //! Constructor + CollisionFaces() {} + //! Destructor + ~CollisionFaces() {} + + inline_ udword GetNbFaces() const { return GetNbEntries()>>2; } + inline_ const CollisionFace* GetFaces() const { return (const CollisionFace*)GetEntries(); } + + inline_ void Reset() { Container::Reset(); } + + inline_ void AddFace(const CollisionFace& face) { Add(face.mFaceID).Add(face.mDistance).Add(face.mU).Add(face.mV); } + }; + +#ifdef OPC_RAYHIT_CALLBACK + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * User-callback, called by OPCODE to record a hit. + * \param hit [in] current hit + * \param user_data [in] user-defined data from SetCallback() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + typedef void (*HitCallback) (const CollisionFace& hit, void* user_data); +#endif + + class OPCODE_API RayCollider : public Collider + { + public: + // Constructor / Destructor + 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); + // + bool Collide(const Ray& world_ray, const AABBTree* tree, Container& box_indices); + // Settings + +#ifndef OPC_RAYHIT_CALLBACK + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * 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; } +#endif + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * 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) { mMaxDist = max_dist; } + +#ifdef OPC_RAYHIT_CALLBACK + inline_ void SetHitCallback(HitCallback cb) { mHitCallback = cb; } + inline_ void SetUserData(void* user_data) { mUserData = user_data; } +#else + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * 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; } +#endif + // 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 { 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 { 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(); + + protected: + // Ray in local space + IcePoint mOrigin; //!< Ray origin + IcePoint mDir; //!< Ray direction (normalized) + IcePoint mFDir; //!< fabsf(mDir) + IcePoint mData, mData2; + // Stabbed faces + CollisionFace mStabbedFace; //!< Current stabbed face +#ifdef OPC_RAYHIT_CALLBACK + HitCallback mHitCallback; //!< Callback used to record a hit + void* mUserData; //!< User-defined data +#else + CollisionFaces* mStabbedFaces; //!< List of stabbed faces +#endif + // 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 + IcePoint mCenterCoeff; + IcePoint mExtentsCoeff; + // Settings + float mMaxDist; //!< Valid segment on the ray +#ifndef OPC_RAYHIT_CALLBACK + bool mClosestHit; //!< Report closest hit only +#endif + bool mCulling; //!< Stab culled faces or not + // Internal methods + void _SegmentStab(const AABBCollisionNode* node); + void _SegmentStab(const AABBNoLeafNode* node); + void _SegmentStab(const AABBQuantizedNode* node); + void _SegmentStab(const AABBQuantizedNoLeafNode* node); + void _SegmentStab(const AABBTreeNode* node, Container& box_indices); + void _RayStab(const AABBCollisionNode* node); + void _RayStab(const AABBNoLeafNode* node); + void _RayStab(const AABBQuantizedNode* node); + void _RayStab(const AABBQuantizedNoLeafNode* node); + void _RayStab(const AABBTreeNode* node, Container& box_indices); + // Overlap tests + inline_ BOOL RayAABBOverlap(const IcePoint& center, const IcePoint& extents); + inline_ BOOL SegmentAABBOverlap(const IcePoint& center, const IcePoint& extents); + inline_ BOOL RayTriOverlap(const IcePoint& vert0, const IcePoint& vert1, const IcePoint& vert2); + // Init methods + BOOL InitQuery(const Ray& world_ray, const Matrix4x4* world=null, udword* face_id=null); + }; + +#endif // __OPC_RAYCOLLIDER_H__ -- cgit v1.1