mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 00:26:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			157 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			157 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include "navmeshtileview.hpp"
 | 
						|
#include "ref.hpp"
 | 
						|
 | 
						|
#include <DetourCommon.h>
 | 
						|
#include <DetourNavMesh.h>
 | 
						|
 | 
						|
#include <algorithm>
 | 
						|
#include <cassert>
 | 
						|
#include <stdexcept>
 | 
						|
#include <tuple>
 | 
						|
 | 
						|
inline bool operator==(const dtMeshHeader& lhs, const dtMeshHeader& rhs) noexcept
 | 
						|
{
 | 
						|
    const auto makeTuple = [] (const dtMeshHeader& v)
 | 
						|
    {
 | 
						|
        using DetourNavigator::ArrayRef;
 | 
						|
        return std::tuple(
 | 
						|
            v.x,
 | 
						|
            v.y,
 | 
						|
            v.layer,
 | 
						|
            v.userId,
 | 
						|
            v.polyCount,
 | 
						|
            v.vertCount,
 | 
						|
            v.maxLinkCount,
 | 
						|
            v.detailMeshCount,
 | 
						|
            v.detailVertCount,
 | 
						|
            v.detailTriCount,
 | 
						|
            v.bvNodeCount,
 | 
						|
            v.offMeshConCount,
 | 
						|
            v.offMeshBase,
 | 
						|
            v.walkableHeight,
 | 
						|
            v.walkableRadius,
 | 
						|
            v.walkableClimb,
 | 
						|
            v.detailVertCount,
 | 
						|
            ArrayRef(v.bmin),
 | 
						|
            ArrayRef(v.bmax),
 | 
						|
            v.bvQuantFactor
 | 
						|
        );
 | 
						|
    };
 | 
						|
    return makeTuple(lhs) == makeTuple(rhs);
 | 
						|
}
 | 
						|
 | 
						|
inline bool operator==(const dtPoly& lhs, const dtPoly& rhs) noexcept
 | 
						|
{
 | 
						|
    const auto makeTuple = [] (const dtPoly& v)
 | 
						|
    {
 | 
						|
        using DetourNavigator::ArrayRef;
 | 
						|
        return std::tuple(ArrayRef(v.verts), ArrayRef(v.neis), v.flags, v.vertCount, v.areaAndtype);
 | 
						|
    };
 | 
						|
    return makeTuple(lhs) == makeTuple(rhs);
 | 
						|
}
 | 
						|
 | 
						|
inline bool operator==(const dtPolyDetail& lhs, const dtPolyDetail& rhs) noexcept
 | 
						|
{
 | 
						|
    const auto makeTuple = [] (const dtPolyDetail& v)
 | 
						|
    {
 | 
						|
        return std::tuple(v.vertBase, v.triBase, v.vertCount, v.triCount);
 | 
						|
    };
 | 
						|
    return makeTuple(lhs) == makeTuple(rhs);
 | 
						|
}
 | 
						|
 | 
						|
inline bool operator==(const dtBVNode& lhs, const dtBVNode& rhs) noexcept
 | 
						|
{
 | 
						|
    const auto makeTuple = [] (const dtBVNode& v)
 | 
						|
    {
 | 
						|
        using DetourNavigator::ArrayRef;
 | 
						|
        return std::tuple(ArrayRef(v.bmin), ArrayRef(v.bmax), v.i);
 | 
						|
    };
 | 
						|
    return makeTuple(lhs) == makeTuple(rhs);
 | 
						|
}
 | 
						|
 | 
						|
inline bool operator==(const dtOffMeshConnection& lhs, const dtOffMeshConnection& rhs) noexcept
 | 
						|
{
 | 
						|
    const auto makeTuple = [] (const dtOffMeshConnection& v)
 | 
						|
    {
 | 
						|
        using DetourNavigator::ArrayRef;
 | 
						|
        return std::tuple(ArrayRef(v.pos), v.rad, v.poly, v.flags, v.side, v.userId);
 | 
						|
    };
 | 
						|
    return makeTuple(lhs) == makeTuple(rhs);
 | 
						|
}
 | 
						|
 | 
						|
namespace DetourNavigator
 | 
						|
{
 | 
						|
    NavMeshTileConstView asNavMeshTileConstView(const unsigned char* data)
 | 
						|
    {
 | 
						|
        const dtMeshHeader* header = reinterpret_cast<const dtMeshHeader*>(data);
 | 
						|
 | 
						|
        if (header->magic != DT_NAVMESH_MAGIC)
 | 
						|
            throw std::logic_error("Invalid navmesh magic");
 | 
						|
 | 
						|
        if (header->version != DT_NAVMESH_VERSION)
 | 
						|
            throw std::logic_error("Invalid navmesh version");
 | 
						|
 | 
						|
        // Similar code to https://github.com/recastnavigation/recastnavigation/blob/c5cbd53024c8a9d8d097a4371215e3342d2fdc87/Detour/Source/DetourNavMesh.cpp#L978-L996
 | 
						|
        const int headerSize = dtAlign4(sizeof(dtMeshHeader));
 | 
						|
        const int vertsSize = dtAlign4(sizeof(float) * 3 * header->vertCount);
 | 
						|
        const int polysSize = dtAlign4(sizeof(dtPoly) * header->polyCount);
 | 
						|
        const int linksSize = dtAlign4(sizeof(dtLink) * (header->maxLinkCount));
 | 
						|
        const int detailMeshesSize = dtAlign4(sizeof(dtPolyDetail) * header->detailMeshCount);
 | 
						|
        const int detailVertsSize = dtAlign4(sizeof(float) * 3 * header->detailVertCount);
 | 
						|
        const int detailTrisSize = dtAlign4(sizeof(unsigned char) * 4 * header->detailTriCount);
 | 
						|
        const int bvtreeSize = dtAlign4(sizeof(dtBVNode) * header->bvNodeCount);
 | 
						|
        const int offMeshLinksSize = dtAlign4(sizeof(dtOffMeshConnection) * header->offMeshConCount);
 | 
						|
 | 
						|
        const unsigned char* ptr = data + headerSize;
 | 
						|
 | 
						|
        NavMeshTileConstView view;
 | 
						|
 | 
						|
        view.mHeader = header;
 | 
						|
        view.mVerts = dtGetThenAdvanceBufferPointer<const float>(ptr, vertsSize);
 | 
						|
        view.mPolys = dtGetThenAdvanceBufferPointer<const dtPoly>(ptr, polysSize);
 | 
						|
        ptr += linksSize;
 | 
						|
        view.mDetailMeshes = dtGetThenAdvanceBufferPointer<const dtPolyDetail>(ptr, detailMeshesSize);
 | 
						|
        view.mDetailVerts = dtGetThenAdvanceBufferPointer<const float>(ptr, detailVertsSize);
 | 
						|
        view.mDetailTris = dtGetThenAdvanceBufferPointer<const unsigned char>(ptr, detailTrisSize);
 | 
						|
        view.mBvTree = dtGetThenAdvanceBufferPointer<const dtBVNode>(ptr, bvtreeSize);
 | 
						|
        view.mOffMeshCons = dtGetThenAdvanceBufferPointer<const dtOffMeshConnection>(ptr, offMeshLinksSize);
 | 
						|
 | 
						|
        return view;
 | 
						|
    }
 | 
						|
 | 
						|
    NavMeshTileConstView asNavMeshTileConstView(const dtMeshTile& tile)
 | 
						|
    {
 | 
						|
        NavMeshTileConstView view;
 | 
						|
 | 
						|
        view.mHeader = tile.header;
 | 
						|
        view.mPolys = tile.polys;
 | 
						|
        view.mVerts = tile.verts;
 | 
						|
        view.mDetailMeshes = tile.detailMeshes;
 | 
						|
        view.mDetailVerts = tile.detailVerts;
 | 
						|
        view.mDetailTris = tile.detailTris;
 | 
						|
        view.mBvTree = tile.bvTree;
 | 
						|
        view.mOffMeshCons = tile.offMeshCons;
 | 
						|
 | 
						|
        return view;
 | 
						|
    }
 | 
						|
 | 
						|
    bool operator==(const NavMeshTileConstView& lhs, const NavMeshTileConstView& rhs) noexcept
 | 
						|
    {
 | 
						|
        using DetourNavigator::Ref;
 | 
						|
        using DetourNavigator::Span;
 | 
						|
        const auto makeTuple = [] (const DetourNavigator::NavMeshTileConstView& v)
 | 
						|
        {
 | 
						|
            return std::tuple(
 | 
						|
                Ref(*v.mHeader),
 | 
						|
                Span(v.mPolys, v.mHeader->polyCount),
 | 
						|
                Span(v.mVerts, v.mHeader->vertCount),
 | 
						|
                Span(v.mDetailMeshes, v.mHeader->detailMeshCount),
 | 
						|
                Span(v.mDetailVerts, v.mHeader->detailVertCount),
 | 
						|
                Span(v.mDetailTris, v.mHeader->detailTriCount),
 | 
						|
                Span(v.mBvTree, v.mHeader->bvNodeCount),
 | 
						|
                Span(v.mOffMeshCons, v.mHeader->offMeshConCount)
 | 
						|
            );
 | 
						|
        };
 | 
						|
        return makeTuple(lhs) == makeTuple(rhs);
 | 
						|
    }
 | 
						|
}
 |