// 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_RETRIEVER_INSTANCE_H #define NL_RETRIEVER_INSTANCE_H #include #include "nel/misc/types_nl.h" #include "nel/misc/vector.h" #include "nel/misc/vectord.h" #include "nel/misc/vector_2f.h" #include "nel/misc/file.h" #include "nel/misc/aabbox.h" #include "local_retriever.h" #include "edge_quad.h" namespace NLPACS { class CCollisionSurfaceTemp; /// Precision of Snap. 1/1024 meter. If you change this, CEdgeCollide::testPointMove() won't work. const float SnapPrecision= 1024; /** * An instance of a local retriever. * It defines a physical/geographic zone of landscape. * \author Benjamin Legros * \author Nevrax France * \date 2001 */ class CRetrieverInstance { public: /** * A neighbor link */ class CLink { public: uint16 Instance; uint16 BorderChainId; uint16 ChainId; uint16 SurfaceId; CLink() { reset(); } void reset() { Instance = 0xFFFF; BorderChainId = 0xFFFF; ChainId = 0xFFFF; SurfaceId = 0xFFFF; } void serial(NLMISC::IStream &f) { f.serial(Instance, BorderChainId, ChainId, SurfaceId); } }; protected: friend class CGlobalRetriever; /** * The link to another node * \author Benjamin Legros * \author Nevrax France * \date 2001 */ struct CAStarNodeAccess { sint32 InstanceId; uint16 NodeId; uint16 ThroughChain; CAStarNodeAccess() :InstanceId(-1), NodeId(0xffff), ThroughChain(0xffff) {} bool operator == (const CAStarNodeAccess &node) const { return InstanceId == node.InstanceId && NodeId == node.NodeId; } bool operator != (const CAStarNodeAccess &node) const { return InstanceId != node.InstanceId || NodeId != node.NodeId; } }; /** * The information bound to the surfaces nodes. * \author Benjamin Legros * \author Nevrax France * \date 2001 */ struct CAStarNodeInfo { /// The position of this node. NLMISC::CVector2f Position; /// The cost to this node. float Cost; float F; /// The parent link. CAStarNodeAccess Parent; }; /// std::vector _NodesInformation; protected: /// The id of this instance. sint32 _InstanceId; /// The id of the retrievable surface pattern. sint32 _RetrieverId; /// The type of the instance (see CLocalRetriever::_Type) CLocalRetriever::EType _Type; /// @name Instance displacement. // @{ uint8 _Orientation; NLMISC::CVector _Origin; /// The BBox of the instance. NLMISC::CAABBox _BBox; // @} /// @name Instance linkage. // @{ /// The instance ids of the neighbors. std::vector _Neighbors; /// The neighbor chains on the border. std::vector _BorderChainLinks; // @} /// @name Interior instance coolision management. // @{ /** The edges of the exterior collision mesh, stored in a quad grid. The edges are stored in the instance rather than in the local retriever. */ CEdgeQuad _ExteriorEdgeQuad; // @} public: /// Default constructor. CRetrieverInstance(); /// Resets the instance. This doesn't affect any neighboring instances... void reset(); /// Resets links to the given instance. This doesn't affect any neighbor. void resetLinks(uint32 id); /// Resets links of the instance. This doesn't affect any neighboring instances... void resetLinks(); /// Returns the id of this instance. sint32 getInstanceId() const { return _InstanceId; } /// Returns the id of the retriever associated to this instance. sint32 getRetrieverId() const { return _RetrieverId; } /// Returns the orientation of the instance in relation to the retriever. uint8 getOrientation() const { return _Orientation; } /// Returns the origin translation of this instance. NLMISC::CVector getOrigin() const { return _Origin; } /// Returns the type of the instance CLocalRetriever::EType getType() const { return _Type; } /// Gets the neighbors. std::vector getNeighbors() const { return _Neighbors; } /// Gets the id of the neighbor on the edge. sint32 getNeighbor(uint n) const { return _Neighbors[n]; } /// Gets the ids of the neighbor chains on the given edge. const std::vector &getBorderChainLinks() const { return _BorderChainLinks; } /// Gets the id of the nth neighbor chain on the given edge. CLink getBorderChainLink(uint n) const { return _BorderChainLinks[n]; } /// Resets border chains links void resetBorderChainLinks(const std::vector &links); /// Forces border chain link void forceBorderChainLink(uint border, uint frontInstance, uint frontBorder, uint frontChain, uint frontSurface) { if (border >= _BorderChainLinks.size()) { nlwarning("forceBorderChainLink(): couldn't force border %d on instance %d, doesn't exist!", border, _InstanceId); return; } if (_BorderChainLinks[border].Instance != 0xffff || _BorderChainLinks[border].BorderChainId != 0xffff || _BorderChainLinks[border].ChainId != 0xffff || _BorderChainLinks[border].SurfaceId != 0xffff) { nlwarning("forceBorderChainLink(): forces border %d on instance %d whereas link is initialised yet, incoherences may appear!", border, _InstanceId); } _BorderChainLinks[border].Instance = uint16(frontInstance); _BorderChainLinks[border].BorderChainId = uint16(frontBorder); _BorderChainLinks[border].ChainId = uint16(frontChain); _BorderChainLinks[border].SurfaceId = uint16(frontSurface); } /// Returns the number of the edge on the instance corresponding to the edge on the retriever. uint8 getInstanceEdge(uint8 retrieverEdge) const { return (retrieverEdge+_Orientation)%4; } /// Returns the number of the edge on the retriever corresponding to the edge on the instance. uint8 getRetrieverEdge(uint8 instanceEdge) const { return (instanceEdge+4-_Orientation)%4; } /// Returns the bbox of the instance (using the translation and orientation of the retriever) const NLMISC::CAABBox &getBBox() const { return _BBox; } /// Inits the instance (after a serial for instance.) void init(const CLocalRetriever &retriever); /** Inits the edgequad (only for Interior instances, and only after all the landscape * instances have been built. */ void initEdgeQuad(CGlobalRetriever &gr); /// link the edge quad of the interior with the the landscape instances void linkEdgeQuad(CGlobalRetriever &gr); /// Builds the instance. void make(sint32 instanceId, sint32 retrieverId, const CLocalRetriever &retriever, uint8 orientation, const NLMISC::CVector &origin); /// Links the instance to a given neighbor on the given edge. void link(CRetrieverInstance &neighbor, const std::vector &retrievers); /// Unlinks the instance. The neighbor instance are AFFECTED. void unlink(std::vector &instances); /** * Retrieves the position in the instance from an estimated position. * WARNING: the estimated position is a GLOBAL position, and the returned position * is a LOCAL position (to the retriever). */ // CLocalRetriever::CLocalPosition retrievePosition(const NLMISC::CVector &estimated, const CLocalRetriever &retriever, CCollisionSurfaceTemp &cst) const; void retrievePosition(const NLMISC::CVector &estimated, const CLocalRetriever &retriever, CCollisionSurfaceTemp &cst, bool sortByDistance=true) const; /** * Retrieves the position in the instance from an estimated position (double instead.) * WARNING: the estimated position is a GLOBAL position, and the returned position * is a LOCAL position (to the retriever). */ void retrievePosition(const NLMISC::CVectorD &estimated, const CLocalRetriever &retriever, CCollisionSurfaceTemp &cst, bool sortByDistance=true) const; /** * Retrieves the position in the instance from an estimated position (double instead.) * WARNING: the estimated position is a GLOBAL position, and the returned position * is a LOCAL position (to the retriever). */ //void retrieveAccuratePosition(const NLMISC::CVectorD &estimated, const CLocalRetriever &retriever, CCollisionSurfaceTemp &cst, ) const; /// For the interior instances, snaps the point to the ground. void snapToInteriorGround(ULocalPosition &position, const CLocalRetriever &retriever) const; /// void snap(ULocalPosition &position, const CLocalRetriever &retriever) const; /// Serialises this CRetrieverInstance. void serial(NLMISC::IStream &f); /// Computes the position in the local axis of the retriever from a global position. NLMISC::CVector getLocalPosition(const NLMISC::CVector &globalPosition) const; /// Computes the position in the local axis of the retriever from a global position. NLMISC::CVector getLocalPosition(const NLMISC::CVectorD &globalPosition) const; /// Computes the position in the global axis from a local position (in the retriever axis). NLMISC::CVector getGlobalPosition(const NLMISC::CVector &localPosition) const; /// Computes the position (as double) in the global axis from a local position (in the retriever axis). NLMISC::CVectorD getDoubleGlobalPosition(const NLMISC::CVector &localPosition) const; /// Returns the bbox of the instance. // NLMISC::CAABBox getBBox() { return _BBox; } /// \name Vector Snapping. // @{ /** Snap a vector at 1mm (1/1024). v must be a local position (ie range from -80 to +240). * Doing this, we are sure we have precision of 9+10 bits, which is enough for 24 bits float precision. * NB: z is not snapped. */ static void snapVector(CVector &v) { v.x= (float)floor(v.x*SnapPrecision)/SnapPrecision; v.y= (float)floor(v.y*SnapPrecision)/SnapPrecision; } /** Snap a vector at 1mm (1/1024). v must be a local position (ie range from -80 to +240). * Doing this, we are sure we have precision of 9+10 bits, which is enough for 24 bits float precision. */ static void snapVector(CVector2f &v) { v.x= (float)floor(v.x*SnapPrecision)/SnapPrecision; v.y= (float)floor(v.y*SnapPrecision)/SnapPrecision; } // @} /// \name Collision part // @{ /** Test for collisions with the exterior mesh of an interior instance. This only works for interior instances !! see also testCollision() in CLocalRetriever */ void testExteriorCollision(CCollisionSurfaceTemp &cst, const NLMISC::CAABBox &bboxMoveLocal, const NLMISC::CVector2f &transBase, const CLocalRetriever &localRetriever) const; // @} }; }; // NLPACS #endif // NL_RETRIEVER_INSTANCE_H /* End of retriever_instance.h */