Recast is not defined?

Coming back o this -

Recast is compiled to both UMD and ES6, and both versions are available in the recast-detour package.

The right way to consume it is this:

import Recast from "recast-detour";
import { RecastJSPlugin } from "@babylonjs/core/Navigation/Plugins/recastJSPlugin";
// ... further imports

const recast = await Recast();
const navigationPlugin = new RecastJSPlugin(recast);
// this file can be downloaded from our repo, or taken from the next code sections in this message
navigationPlugin.setWorkerURL("./navMeshWorker.js");

You then continue with the standard implementation.

An example can be found here - babylonjs-webpack-es6/src/scenes/navigationMeshRecast.ts at master · RaananW/babylonjs-webpack-es6 (github.com)

Note that it is important that if you target es6 and up you will need to consume the packages as es6 packages. Depending on your build system, you will need to configure your builder correctly.

The file that will be passed to the worker (navMeshWorker) is this:

importScripts("https://cdn.babylonjs.com/recast.js");

onmessage = function(messageEvent) {
    // get message datas
    const meshData = messageEvent.data;
    const positions = meshData[0];
    const offset = meshData[1];
    const indices = meshData[2];
    const indicesLength = meshData[3];
    const parameters = meshData[4];

    // initialize Recast
    Recast().then((recast) => {
        // build rc config from parameters
        const rc = new recast.rcConfig();
        rc.cs = parameters.cs;
        rc.ch = parameters.ch;
        rc.borderSize = parameters.borderSize ? parameters.borderSize : 0;
        rc.tileSize = parameters.tileSize ? parameters.tileSize : 0;
        rc.walkableSlopeAngle = parameters.walkableSlopeAngle;
        rc.walkableHeight = parameters.walkableHeight;
        rc.walkableClimb = parameters.walkableClimb;
        rc.walkableRadius = parameters.walkableRadius;
        rc.maxEdgeLen = parameters.maxEdgeLen;
        rc.maxSimplificationError = parameters.maxSimplificationError;
        rc.minRegionArea = parameters.minRegionArea;
        rc.mergeRegionArea = parameters.mergeRegionArea;
        rc.maxVertsPerPoly = parameters.maxVertsPerPoly;
        rc.detailSampleDist = parameters.detailSampleDist;
        rc.detailSampleMaxError = parameters.detailSampleMaxError;

        // create navmesh and build it from message datas
        const navMesh = new recast.NavMesh();
        navMesh.build(positions, offset, indices, indicesLength, rc);

        // get recast uint8array
        const navmeshData = navMesh.getNavmeshData();
        const arrView = new Uint8Array(recast.HEAPU8.buffer, navmeshData.dataPointer, navmeshData.size);
        const ret = new Uint8Array(navmeshData.size);
        ret.set(arrView);
        navMesh.freeNavmeshData(navmeshData);

        // job done, returns the result
        postMessage(ret);
    });
}
1 Like

It works for me:

if you use Vite just add in your vite config plugin

plugins: [
      {
        name: 'fix-recast',
        transform(code, id) {
          if (id.includes('recast-detour.js')) {
            return code.replace(`this["Recast"]`, 'window["Recast"]');
          }
        }
      },
    ]
4 Likes

Thanks! Yes, this is a long standing emscripten issue with es6. Different ways of דolving this, this is one of them

2 Likes