// NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #ifndef NL_COLLISION_SURFACE_TEMP_H #define NL_COLLISION_SURFACE_TEMP_H #include "nel/misc/types_nl.h" #include "edge_collide.h" #include "collision_desc.h" namespace NLPACS { // *************************************************************************** /** * Temp collision data used during tryMove(). * \author Lionel Berenguier * \author Nevrax France * \date 2001 */ class CEdgeCollideNode : public CEdgeCollide { public: /// Next edgeCollideNode in the CCollisionSurfaceTemp allocator. 0xFFFFFFFF if none. uint32 Next; public: CEdgeCollideNode() { Next= 0xFFFFFFFF; } }; // *************************************************************************** /** * Temp collision data used during tryMove(). * \author Lionel Berenguier * \author Nevrax France * \date 2001 */ class CCollisionChain { public: /// First edgeCollideNode in the CCollisionSurfaceTemp allocator. 0xFFFFFFFF if none. This is a List of edgeCollide. uint32 FirstEdgeCollide; /// The Left/Right surface next this chain. CSurfaceIdent LeftSurface, RightSurface; /// the id in the local retriever which generate this chain (temp). uint16 ChainId; /// In the algorithm, this chain has been tested??? bool Tested; /// If the chain is an exterior edge bool ExteriorEdge; public: CCollisionChain() { FirstEdgeCollide= 0xFFFFFFFF; Tested= false; ExteriorEdge = false; } /// test if 2 CCollisionChain have same surface neighbors. bool sameSurfacesThan(const CCollisionChain &o) const { return (LeftSurface==o.LeftSurface && RightSurface==o.RightSurface) || (LeftSurface==o.RightSurface && RightSurface==o.LeftSurface); } /// test if Left or Right == surf. bool hasSurface(const CSurfaceIdent &surf) const { return LeftSurface==surf || RightSurface==surf; } /// Return Left if surf==Right, else return Right. const CSurfaceIdent &getOtherSurface(const CSurfaceIdent &surf) const { if(RightSurface==surf) return LeftSurface; else return RightSurface; } }; // *************************************************************************** /** * Temp collision data used during tryMove(). * \author Lionel Berenguier * \author Nevrax France * \date 2001 */ class CEdgeChainEntry { public: /// The id of the ordered chain. uint16 OChainId; /// the first edge of the ordered chain, found in this quad. uint16 EdgeStart; /// the end edge of the ordered chain, found in this quad. "end edge" is lastEdge+1: numEdges= end-start. uint16 EdgeEnd; }; // *************************************************************************** /** * Temp collision data used for exterior mesh collision detection. * \author Benjamin Legros * \author Nevrax France * \date 2001 */ class CExteriorEdgeEntry { public: /// The id of the edge. uint16 EdgeId; /// The id of the interior chain id uint16 ChainId; /// The interior and exterior surfaces along this edge CSurfaceIdent Interior, Exterior; void serial(NLMISC::IStream &f) { f.serial(EdgeId, ChainId, Interior, Exterior); } }; // *************************************************************************** /** * Description of the contact of a collision against a chain. * * \author Lionel Berenguier * \author Nevrax France * \date 2001 */ class CMoveSurfaceDesc { public: /// This is the 128 bits rational float, when the movement reach this surface. CRational64 ContactTime; /// To which chain we have collided. CSurfaceIdent LeftSurface, RightSurface; /// Is it an interface between exterior and interior bool ExteriorEdge; /// true if Dot product between EdgeCollide Norm and Movement is >=0. bool MovementSens; /// Chain Id of the exterior edge uint16 ChainId; public: CMoveSurfaceDesc() : ExteriorEdge(false) {} CMoveSurfaceDesc(CRational64 t, CSurfaceIdent left, CSurfaceIdent right) : ContactTime(t), LeftSurface(left), RightSurface(right), ExteriorEdge(false) {} bool operator<(const CMoveSurfaceDesc &o) const { return ContactTime TExteriorEdgeIndex; // typedef std::pair TSurfaceLUTEntry; class CDistanceSurface { public: uint16 Surface; uint16 Instance; float Distance; bool FoundCloseEdge; CDistanceSurface() {} CDistanceSurface(float distance, uint16 surface, uint16 instance, bool foundCloseEdge) : Surface(surface), Instance(instance), Distance(distance), FoundCloseEdge(foundCloseEdge) {} bool operator () (const CDistanceSurface &a, const CDistanceSurface &b) const { return a.Distance < b.Distance; } }; class CSurfaceLUTEntry { public: bool IsPossible; bool FoundCloseEdge; bool OnVerticalEdge; uint8 Counter; void reset() { IsPossible = false; FoundCloseEdge = false; Counter = 0; } }; public: /// For CChainQuad::selectEdges(). uint16 OChainLUT[65536]; std::vector EdgeChainEntries; std::vector ExteriorEdgeIndexes; /// Array of possible near surfaces // TSurfaceLUTEntry SurfaceLUT[65536]; CSurfaceLUTEntry SurfaceLUT[65536]; uint8 OutCounter; std::vector PossibleSurfaces; std::vector SortedSurfaces; /// Array of near Collision Chains. std::vector CollisionChains; /// result of testMovementWithCollisionChains(). std::vector MoveDescs; /// result of testRotWithCollisionChains(). std::vector RotDescs; /// Result of collision testMove(). TCollisionSurfaceDescVector CollisionDescs; /// CGlobalRetriever instance possibly colliding movement. std::vector CollisionInstances; /// For testMove/doMove, prec settings. CSurfaceIdent PrecStartSurface; NLMISC::CVector PrecStartPos; NLMISC::CVector PrecDeltaPos; bool PrecValid; public: /// Constructor CCollisionSurfaceTemp(); /// \name Access to EdgeCollideNode // @{ void resetEdgeCollideNodes(); /// return first Id. uint32 allocEdgeCollideNode(uint32 size=1); CEdgeCollideNode &getEdgeCollideNode(uint32 id); // @} // void incSurface(sint32 surf) { if (surf >= 0) { if (!SurfaceLUT[surf].IsPossible) PossibleSurfaces.push_back((uint16)surf); SurfaceLUT[surf].IsPossible = true; ++SurfaceLUT[surf].Counter; } else { ++OutCounter; } } // void decSurface(sint32 surf) { if (surf >= 0) { if (!SurfaceLUT[surf].IsPossible) PossibleSurfaces.push_back((uint16)surf); SurfaceLUT[surf].IsPossible = true; --SurfaceLUT[surf].Counter; } else { --OutCounter; } } private: /// Allocator of EdgeCollideNode. std::vector _EdgeCollideNodes; }; } // NLPACS #endif // NL_COLLISION_SURFACE_TEMP_H /* End of collision_surface_temp.h */