Issue with earcut import

Hi,

I am trying to extrude a polygone using a (x,z) path . I tested the thing in a typescript project evrything was working fine . When I tried to do the same in Javascript project, earcut keep throughing me :
Uncaught TypeError: this.bjsEarcut is not a function

But i try it in the playground it works fine :

Here’s my earcut version :

"node_modules/earcut": {
            "version": "3.0.1",
            "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.1.tgz",
            "integrity": "sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw=="
        },

Herei’s my js code :

import * as BABYLON from '@babylonjs/core';
import * as earcut from "earcut";



// Also make it available globally just in case
window.earcut = earcut;

window.scene = undefined;
document.addEventListener("DOMContentLoaded", function () {
    const canvas3d = document.getElementById('canvas3d');
    if (!canvas3d) {
        console.error("Canvas element with ID 'canvas3d' not found!");
        return;
    }

    const engine = new BABYLON.Engine(canvas3d, true);
    window.scene = new BABYLON.Scene(engine);
    scene.clearColor = new BABYLON.Color3(0.9, 0.9, 0.9); // Light green
    // Create camera
    const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 3, 10, BABYLON.Vector3.Zero(), scene);
    camera.attachControl(canvas3d, true);

    // Lighting setup
    const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
    light.intensity = 0.7;
    
    const dirLight = new BABYLON.DirectionalLight("dirLight", new BABYLON.Vector3(0, -1, 1), scene);
    dirLight.intensity = 0.5;

    // Optional: Handle clicks to change texture
    function handleCanvasClick() {
        // Dispose of the old texture to prevent memory leaks
        window.createSlap([
            {x:-2,y:-2},
            {x:2,y:-2},
            {x:2,y:2},
            {x:-2,y:-2},
        ],0,0.2);
        
    }

    canvas3d.addEventListener('click', function(event) {
        console.log('Canvas clicked!');
        handleCanvasClick();
    });

    engine.runRenderLoop(() => {
        scene.render();
    });

    window.addEventListener("resize", () => {
        engine.resize();
    });
});

window.createSlap = function(points, y, height) {
    
    
    // Create the extruded polygon with a hole
    const slapGroundObject = BABYLON.MeshBuilder.ExtrudePolygon(
        "slapGround", 
        {
            shape: points,
            depth: height,
            sideOrientation: BABYLON.Mesh.DOUBLESIDE,
            updatable: true
        }, 
        scene
    );
    
    // Add materials
    const material = new BABYLON.StandardMaterial("material", scene);
    material.diffuseColor = new BABYLON.Color3(0.4, 0.6, 0.9);
    material.backFaceCulling = false;
    slapGroundObject.material = material;
    
    return scene;
}

Thanks in advance.

If you prefer not to use the global variable for earcut, then you should inject the earcut dependency in your builder. Based on your earcut import, you should do something like this:

 const slapGroundObject = BABYLON.MeshBuilder.ExtrudePolygon(
        "slapGround", 
        {
            shape: points,
            depth: height,
            sideOrientation: BABYLON.Mesh.DOUBLESIDE,
            updatable: true
        }, 
        scene,
        earcut.default
    );

Otherwise, if you are using a module bundler, you can provide it directly from its configuration. You can learn how to do from here:

1 Like

Thanks @SimoneDev

actually its working ,but i had to run npm run watch as well to refresh the output.

Regards.

3 Likes