All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.recast4j.detour.extras.jumplink.NavMeshGroundSampler Maven / Gradle / Ivy

The newest version!
package org.recast4j.detour.extras.jumplink;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

import org.recast4j.detour.MeshTile;
import org.recast4j.detour.NavMesh;
import org.recast4j.detour.NavMeshBuilder;
import org.recast4j.detour.NavMeshDataCreateParams;
import org.recast4j.detour.NavMeshQuery;
import org.recast4j.detour.Poly;
import org.recast4j.detour.QueryFilter;
import org.recast4j.detour.Result;
import org.recast4j.detour.Tupple2;
import org.recast4j.recast.RecastBuilder.RecastBuilderResult;

class NavMeshGroundSampler extends AbstractGroundSampler {

    private final QueryFilter filter = new NoOpFilter();

    private static class NoOpFilter implements QueryFilter {

        @Override
        public boolean passFilter(long ref, MeshTile tile, Poly poly) {
            return true;
        }

        @Override
        public float getCost(float[] pa, float[] pb, long prevRef, MeshTile prevTile, Poly prevPoly, long curRef,
                MeshTile curTile, Poly curPoly, long nextRef, MeshTile nextTile, Poly nextPoly) {
            return 0;
        }

    }

    @Override
    public void sample(JumpLinkBuilderConfig acfg, RecastBuilderResult result, EdgeSampler es) {
        NavMeshQuery navMeshQuery = createNavMesh(result, acfg.agentRadius, acfg.agentHeight, acfg.agentClimb);
        sampleGround(acfg, es, (pt, h) -> getNavMeshHeight(navMeshQuery, pt, acfg.cellSize, h));
    }

    private NavMeshQuery createNavMesh(RecastBuilderResult r, float agentRadius, float agentHeight, float agentClimb) {
        NavMeshDataCreateParams params = new NavMeshDataCreateParams();
        params.verts = r.getMesh().verts;
        params.vertCount = r.getMesh().nverts;
        params.polys = r.getMesh().polys;
        params.polyAreas = r.getMesh().areas;
        params.polyFlags = r.getMesh().flags;
        params.polyCount = r.getMesh().npolys;
        params.nvp = r.getMesh().nvp;
        params.detailMeshes = r.getMeshDetail().meshes;
        params.detailVerts = r.getMeshDetail().verts;
        params.detailVertsCount = r.getMeshDetail().nverts;
        params.detailTris = r.getMeshDetail().tris;
        params.detailTriCount = r.getMeshDetail().ntris;
        params.walkableRadius = agentRadius;
        params.walkableHeight = agentHeight;
        params.walkableClimb = agentClimb;
        params.bmin = r.getMesh().bmin;
        params.bmax = r.getMesh().bmax;
        params.cs = r.getMesh().cs;
        params.ch = r.getMesh().ch;
        params.buildBvTree = true;
        return new NavMeshQuery(new NavMesh(NavMeshBuilder.createNavMeshData(params), params.nvp, 0));
    }

    private Tupple2 getNavMeshHeight(NavMeshQuery navMeshQuery, float[] pt, float cs,
            float heightRange) {
        float[] halfExtents = new float[] { cs, heightRange, cs };
        float maxHeight = pt[1] + heightRange;
        AtomicBoolean found = new AtomicBoolean();
        AtomicReference minHeight = new AtomicReference<>(pt[1]);
        navMeshQuery.queryPolygons(pt, halfExtents, filter, (tile, poly, ref) -> {
            Result h = navMeshQuery.getPolyHeight(ref, pt);
            if (h.succeeded()) {
                float y = h.result;
                if (y > minHeight.get() && y < maxHeight) {
                    minHeight.set(y);
                    found.set(true);
                }
            }
        });
        if (found.get()) {
            return new Tupple2<>(true, minHeight.get());
        }
        return new Tupple2<>(false, pt[1]);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy