Renderer/src/main/java/electrosphere/server/pathfinding/NavMeshConstructor.java
austin ccb532f4f7
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
navmesh bugfix
2025-04-24 19:03:43 -04:00

167 lines
5.7 KiB
Java

package electrosphere.server.pathfinding;
import org.recast4j.detour.MeshData;
import org.recast4j.detour.NavMeshBuilder;
import org.recast4j.detour.NavMeshDataCreateParams;
import org.recast4j.recast.AreaModification;
import org.recast4j.recast.PolyMesh;
import org.recast4j.recast.PolyMeshDetail;
import org.recast4j.recast.RecastBuilder;
import org.recast4j.recast.RecastBuilder.RecastBuilderResult;
import org.recast4j.recast.RecastConstants.PartitionType;
import org.recast4j.recast.RecastBuilderConfig;
import org.recast4j.recast.RecastConfig;
import org.recast4j.recast.geom.SingleTrimeshInputGeomProvider;
import electrosphere.client.terrain.data.TerrainChunkData;
/**
* Constructor methods for nav meshes
*/
public class NavMeshConstructor {
/**
* Size of a recast cell
*/
static final float RECAST_CELL_SIZE = 1.0f;
/**
* Height of a recast cell
*/
static final float RECAST_CELL_HEIGHT = 1.0f;
/**
* Size of a recast agent
*/
static final float RECAST_AGENT_SIZE = 1.0f;
/**
* Height of a recast agent
*/
static final float RECAST_AGENT_HEIGHT = 1.0f;
/**
* Maximum height a recast agent can climb
*/
static final float RECAST_AGENT_MAX_CLIMB = 0.1f;
/**
* Maximum slope a recast agent can handle
*/
static final float RECAST_AGENT_MAX_SLOPE = 0.4f;
/**
* Minimum size of a recast region
*/
static final int RECAST_MIN_REGION_SIZE = 1;
/**
* Merge size of a recast region
*/
static final int RECAST_REGION_MERGE_SIZE = 1;
static final float RECAST_REGION_EDGE_MAX_LEN = 1.0f;
static final float RECAST_REGION_EDGE_MAX_ERROR = 1.0f;
static final int RECAST_VERTS_PER_POLY = 3;
static final float RECAST_DETAIL_SAMPLE_DIST = 0.1f;
static final float RECAST_DETAIL_SAMPLE_MAX_ERROR = 0.1f;
/**
* Constructs a navmesh
* @param terrainChunk The terrain chunk
* @return the MeshData
*/
public static MeshData constructNavmesh(TerrainChunkData terrainChunkData){
MeshData rVal = null;
try {
RecastConfig recastConfig = new RecastConfig(
PartitionType.WATERSHED,
RECAST_CELL_SIZE,
RECAST_CELL_HEIGHT,
RECAST_AGENT_HEIGHT,
RECAST_AGENT_SIZE,
RECAST_AGENT_MAX_CLIMB,
RECAST_AGENT_MAX_SLOPE,
RECAST_MIN_REGION_SIZE,
RECAST_REGION_MERGE_SIZE,
RECAST_REGION_EDGE_MAX_LEN,
RECAST_REGION_EDGE_MAX_ERROR,
RECAST_VERTS_PER_POLY,
RECAST_DETAIL_SAMPLE_DIST,
RECAST_DETAIL_SAMPLE_MAX_ERROR,
new AreaModification(0)
);
SingleTrimeshInputGeomProvider geomProvider = new SingleTrimeshInputGeomProvider(terrainChunkData.getVertices(), terrainChunkData.getFaceElements());
RecastBuilderConfig recastBuilderConfig = new RecastBuilderConfig(recastConfig, geomProvider.getMeshBoundsMin(), geomProvider.getMeshBoundsMax());
RecastBuilder recastBuilder = new RecastBuilder();
RecastBuilderResult recastBuilderResult = recastBuilder.build(geomProvider, recastBuilderConfig);
PolyMesh polyMesh = recastBuilderResult.getMesh();
for(int i = 0; i < polyMesh.npolys; i++){
polyMesh.flags[i] = 1;
}
//set params
NavMeshDataCreateParams params = new NavMeshDataCreateParams();
params.verts = polyMesh.verts;
params.vertCount = polyMesh.nverts;
params.polys = polyMesh.polys;
params.polyAreas = polyMesh.areas;
params.polyFlags = polyMesh.flags;
params.polyCount = polyMesh.npolys;
params.nvp = polyMesh.nvp;
params.walkableHeight = RECAST_AGENT_HEIGHT;
params.walkableRadius = RECAST_AGENT_SIZE;
params.walkableClimb = RECAST_AGENT_MAX_CLIMB;
params.bmin = polyMesh.bmin;
params.bmax = polyMesh.bmax;
params.cs = RECAST_CELL_SIZE;
params.ch = RECAST_CELL_HEIGHT;
params.buildBvTree = true;
PolyMeshDetail polyMeshDetail = recastBuilderResult.getMeshDetail();
if(polyMeshDetail != null){
params.detailMeshes = polyMeshDetail.meshes;
params.detailVerts = polyMeshDetail.verts;
params.detailVertsCount = polyMeshDetail.nverts;
params.detailTris = polyMeshDetail.tris;
params.detailTriCount = polyMeshDetail.ntris;
}
// params.offMeshConVerts = new float[6];
// params.offMeshConVerts[0] = 0.1f;
// params.offMeshConVerts[1] = 0.2f;
// params.offMeshConVerts[2] = 0.3f;
// params.offMeshConVerts[3] = 0.4f;
// params.offMeshConVerts[4] = 0.5f;
// params.offMeshConVerts[5] = 0.6f;
// params.offMeshConRad = new float[1];
// params.offMeshConRad[0] = 0.1f;
// params.offMeshConDir = new int[1];
// params.offMeshConDir[0] = 1;
// params.offMeshConAreas = new int[1];
// params.offMeshConAreas[0] = 2;
// params.offMeshConFlags = new int[1];
// params.offMeshConFlags[0] = 12;
// params.offMeshConUserID = new int[1];
// params.offMeshConUserID[0] = 0x4567;
// params.offMeshConCount = 1;
//actually build
rVal = NavMeshBuilder.createNavMeshData(params);
} catch (Exception e){
e.printStackTrace();
}
return rVal;
}
}