/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * OPCODE - Optimized Collision Detection * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains a mesh interface. * \file OPC_MeshInterface.h * \author Pierre Terdiman * \date November, 27, 2002 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Include Guard #ifndef __OPC_MESHINTERFACE_H__ #define __OPC_MESHINTERFACE_H__ struct VertexPointers { const IcePoint* Vertex[3]; bool BackfaceCulling(const IcePoint& source) { const IcePoint& p0 = *Vertex[0]; const IcePoint& p1 = *Vertex[1]; const IcePoint& p2 = *Vertex[2]; // Compute normal direction IcePoint Normal = (p2 - p1)^(p0 - p1); // Backface culling return (Normal | (source - p0)) >= 0.0f; } }; #ifdef OPC_USE_CALLBACKS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * User-callback, called by OPCODE to request vertices from the app. * \param triangle_index [in] face index for which the system is requesting the vertices * \param triangle [out] triangle's vertices (must be provided by the user) * \param user_data [in] user-defined data from SetCallback() */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// typedef void (*RequestCallback) (udword triangle_index, VertexPointers& triangle, void* user_data); #endif class OPCODE_API MeshInterface { public: // Constructor / Destructor MeshInterface(); ~MeshInterface(); // Common settings inline_ udword GetNbTriangles() const { return mNbTris; } inline_ udword GetNbVertices() const { return mNbVerts; } inline_ void SetNbTriangles(udword nb) { mNbTris = nb; } inline_ void SetNbVertices(udword nb) { mNbVerts = nb; } #ifdef OPC_USE_CALLBACKS // Callback settings /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Callback control: setups object callback. Must provide triangle-vertices for a given triangle index. * \param callback [in] user-defined callback * \param user_data [in] user-defined data * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool SetCallback(RequestCallback callback, void* user_data); inline_ void* GetUserData() const { return mUserData; } inline_ RequestCallback GetCallback() const { return mObjCallback; } #else // Pointers settings /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Pointers control: setups object pointers. Must provide access to faces and vertices for a given object. * \param tris [in] pointer to triangles * \param verts [in] pointer to vertices * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool SetPointers(const IndexedTriangle* tris, const IcePoint* verts); inline_ const IndexedTriangle* GetTris() const { return mTris; } inline_ const IcePoint* GetVerts() const { return mVerts; } #ifdef OPC_USE_STRIDE // Strides settings /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Strides control * \param tri_stride [in] size of a triangle in bytes. The first sizeof(IndexedTriangle) bytes are used to get vertex indices. * \param vertex_stride [in] size of a vertex in bytes. The first sizeof(IcePoint) bytes are used to get vertex position. * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool SetStrides(udword tri_stride=sizeof(IndexedTriangle), udword vertex_stride=sizeof(IcePoint)); inline_ udword GetTriStride() const { return mTriStride; } inline_ udword GetVertexStride() const { return mVertexStride; } #endif #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Fetches a triangle given a triangle index. * \param vp [out] required triangle's vertex pointers * \param index [in] triangle index */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ void GetTriangle(VertexPointers& vp, udword index) const { #ifdef OPC_USE_CALLBACKS (mObjCallback)(index, vp, mUserData); #else #ifdef OPC_USE_STRIDE const IndexedTriangle* T = (const IndexedTriangle*)(((ubyte*)mTris) + index * mTriStride); vp.Vertex[0] = (const IcePoint*)(((ubyte*)mVerts) + T->mVRef[0] * mVertexStride); vp.Vertex[1] = (const IcePoint*)(((ubyte*)mVerts) + T->mVRef[1] * mVertexStride); vp.Vertex[2] = (const IcePoint*)(((ubyte*)mVerts) + T->mVRef[2] * mVertexStride); #else const IndexedTriangle* T = &mTris[index]; vp.Vertex[0] = &mVerts[T->mVRef[0]]; vp.Vertex[1] = &mVerts[T->mVRef[1]]; vp.Vertex[2] = &mVerts[T->mVRef[2]]; #endif #endif } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Remaps client's mesh according to a permutation. * \param nb_indices [in] number of indices in the permutation (will be checked against number of triangles) * \param permutation [in] list of triangle indices * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline_ bool RemapClient(udword nb_indices, const udword* permutation) const; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the mesh interface is valid, i.e. things have been setup correctly. * \return true if valid */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool IsValid() const; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Checks the mesh itself is valid. * Currently we only look for degenerate faces. * \return number of degenerate faces */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// udword CheckTopology() const; private: udword mNbTris; //!< Number of triangles in the input model udword mNbVerts; //!< Number of vertices in the input model #ifdef OPC_USE_CALLBACKS // User callback void* mUserData; //!< User-defined data sent to callback RequestCallback mObjCallback; //!< Object callback #else // User pointers const IndexedTriangle* mTris; //!< Array of indexed triangles const IcePoint* mVerts; //!< Array of vertices #ifdef OPC_USE_STRIDE udword mTriStride; //!< Possible triangle stride in bytes [Opcode 1.3] udword mVertexStride; //!< Possible vertex stride in bytes [Opcode 1.3] #endif #endif }; #endif //__OPC_MESHINTERFACE_H__