// // Copyright (c) 2009-2010 Mikko Mononen memon@inside.org // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages // arising from the use of this software. // Permission is granted to anyone to use this software for any purpose, // including commercial applications, and to alter it and redistribute it // freely, subject to the following restrictions: // 1. The origin of this software must not be misrepresented; you must not // claim that you wrote the original software. If you use this software // in a product, an acknowledgment in the product documentation would be // appreciated but is not required. // 2. Altered source versions must be plainly marked as such, and must not be // misrepresented as being the original software. // 3. This notice may not be removed or altered from any source distribution. // #pragma once #include "PartitionedMesh.h" #include #include struct PartitionedMesh; class rcContext; struct duDebugDraw; static constexpr int MAX_CONVEXVOL_PTS = 12; struct ConvexVolume { float verts[MAX_CONVEXVOL_PTS * 3] = {}; int nverts = 0; float hmin = 0.0f; float hmax = 0.0f; int area = 0; }; struct BuildSettings { /// Cell size in world units float cellSize = 0; /// Cell height in world units float cellHeight = 0; /// Agent height in world units float agentHeight = 0; /// Agent radius in world units float agentRadius = 0; /// Agent max climb in world units float agentMaxClimb = 0; /// Agent max slope in degrees float agentMaxSlope = 0; /// Region minimum size in voxels. float regionMinSize = 0; /// Region merge size in voxels. regionMergeSize = sqrt(regionMergeArea) float regionMergeSize = 0; /// Edge max length in world units float edgeMaxLen = 0; /// Edge max error in voxels float edgeMaxError = 0; int vertsPerPoly = 0; /// Detail sample distance in voxels float detailSampleDist = 0; /// Detail sample max error in voxel heights. float detailSampleMaxError = 0; /// Partition type, see SamplePartitionType int partitionType = 0; /// Bounds of the area to mesh float navMeshBMin[3]{}; float navMeshBMax[3]{}; /// Size of the tiles in voxels float tileSize = 0; }; struct Mesh { std::vector verts; std::vector tris; std::vector normals; // face normals void reset() { verts.clear(); tris.clear(); normals.clear(); } [[nodiscard]] int getVertCount() const { return static_cast(verts.size()) / 3; } [[nodiscard]] int getTriCount() const { return static_cast(tris.size()) / 3; } void readFromObj(char* buf, size_t bufLen); }; class InputGeom { BuildSettings buildSettings; bool hasBuildSettings = false; public: std::string filename; Mesh mesh; float meshBoundsMin[3] = {}; float meshBoundsMax[3] = {}; PartitionedMesh partitionedMesh; /// @name Off-Mesh connections. ///@{ std::vector offmeshConnVerts; std::vector offmeshConnRadius; std::vector offmeshConnBidirectional; std::vector offmeshConnArea; std::vector offmeshConnFlags; std::vector offmeshConnId; ///@} std::vector convexVolumes; bool load(rcContext* ctx, const std::string& filepath); bool saveGeomSet(const BuildSettings* settings); /// Method to return static mesh data. [[nodiscard]] const float* getNavMeshBoundsMin() const { return hasBuildSettings ? buildSettings.navMeshBMin : meshBoundsMin; } [[nodiscard]] const float* getNavMeshBoundsMax() const { return hasBuildSettings ? buildSettings.navMeshBMax : meshBoundsMax; } [[nodiscard]] const BuildSettings* getBuildSettings() const { return hasBuildSettings ? &buildSettings : nullptr; } bool raycastMesh(float* src, float* dst, float& tmin) const; /// @name Off-Mesh connections. ///@{ void addOffMeshConnection(const float* startPos, const float* endPos, float radius, unsigned char bidirectional, unsigned char area, unsigned short flags); void deleteOffMeshConnection(int i); void drawOffMeshConnections(duDebugDraw* dd, bool highlight = false); ///@} /// @name Box Volumes. ///@{ void addConvexVolume(const float* verts, int nverts, float minh, float maxh, unsigned char area); void deleteConvexVolume(int i); void drawConvexVolumes(duDebugDraw* dd); ///@} private: bool loadMesh(rcContext* ctx, const std::string& filepath); bool loadGeomSet(rcContext* ctx, const std::string& filepath); bool loadGeomSet(rcContext* ctx, char* buffer, size_t bufferLen); void clearOffMeshConnections() { offmeshConnVerts.clear(); offmeshConnRadius.clear(); offmeshConnBidirectional.clear(); offmeshConnArea.clear(); offmeshConnFlags.clear(); offmeshConnId.clear(); } };