isInFrustum() tests failing

Hi ,
I have a function to check if the mesh is in camera’s Frustum.

isMeshInFrustum(mesh: Mesh, scene: Scene): boolean {
let withinFrustum = false;
const frustumPlanes = Frustum.GetPlanes(scene.getTransformMatrix());
if (mesh && mesh.isInFrustum(frustumPlanes)) {
withinFrustum = true;
}
return withinFrustum;
}

q1)I am trying to create a jest test with nullEngine and creating scene and camera out of it.
const engine = new NullEngine();
const scene = new Scene(engine);
i created a cube behind the camera. no matter where the box is placed in the scene, the cube is always in Frustum.
but the above function works well in the actual code. when any mesh gets behind the camera, the above function returns false.

q2)const frustumPlanes = Frustum.GetPlanes(scene.getTransformMatrix());
Frustum.GetPlanes accepts transform immutable Matrix as argument… is there a way we can use projection or view matrices…
What is the difference between projection Matrix, Transform Matrix and view Matrix. how can they be used…

q3)when i create any mesh say a cube in my jest test file with nullEngine and scene…
const engine = new NullEngine();
const scene = new Scene(engine);
const myCamera = new PlayerCamera(cameraProperties);
myCamera.target = new Vector3(0, 0, 0);
const box1 = Mesh.CreateBox(“box1”, .1, scene);
box1.position = new Vector3(0, 0.5, 0);

why is this mesh always not active… isActiveMesh(box1) returns false…

In your tests you should call scene.render() to simulate what is happening in reality. This will warm up and compute all the required cached data like matrices values and such.

About the matrices this is a nice article speaking about them Model View Projection.

the third question will have the same answer than the first one.

@sebavan
Thank you very much for helping me out. is there a specific way to call scene.render() in test files…

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

and

scene.render();

doesnt work either…

You might be interested in looking at how validation tests are implemented for the Babylon.js repo: Babylon.js/validation.js at master · BabylonJS/Babylon.js (github.com)

Edit: above may not be relevant to you if you are just testing whether the mesh is in frustum

Is there any way you can share the relevant code with us so we can take a look?

1 Like

just want to test that function… isInFrustum(); below is simple test case…

const engine = new NullEngine();
const scene = new Scene(engine);
const myCamera = new Camera(cameraProperties);
myCamera.target = new Vector3(0, 0, 0);

const box1 = Mesh.CreateBox(“box1”, .1, scene);
box1.position = new Vector3(0, 0.5, 0);

const box2 = Mesh.CreateBox(“box2”, .1, scene);
box2.position = new Vector3(0,0.5,-20);

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

describe(‘isMeshInFrustum tests’, () => {

beforeEach(() => {
    jest.spyOn(console, 'error').mockImplementation();
});

it('we should get box is in Frustum', () => {        
    expect(isMeshInFrustum(box1, scene)).toBe(true);
});

it('we should get box2 is not in Frustum', () => {      
    expect(isMeshInFrustum(box2, scene)).toBe(false);
});  

});

you should not need engine.runRenderLoop(() => {… only scene.render();

1 Like

also would be great to have your camera properties so that @DarraghBurke can try to repro ?

1 Like

just creating a basic scene and basic cube mesh…and this function below… and write a simple test case with ArcRotateCamera…

isMeshInFrustum(mesh: Mesh, scene: Scene): boolean {
let withinFrustum = false;
const frustumPlanes = Frustum.GetPlanes(scene.getTransformMatrix());
if (mesh && mesh.isInFrustum(frustumPlanes)) {
withinFrustum = true;
}
return withinFrustum;
}

const engine = new NullEngine();
const scene = new Scene(engine);
const camera = new ArcRotateCamera();
camera.target = new Vector3(0, 0, 0);

const box1 = Mesh.CreateBox(“box1”, .1, scene);
box1.position = new Vector3(0, 0.5, 0);

const box2 = Mesh.CreateBox(“box2”, .1, scene);
box2.position = new Vector3(0,0.5, -20);

scene.render();

describe(‘isMeshInFrustum tests’, () => {

beforeEach(() => {
    jest.spyOn(console, 'error').mockImplementation();
});

it('we should get box is in Frustum', () => {        
    expect(isMeshInFrustum(box1, scene)).toBe(true);
});

it('we should get box2 is not in Frustum', () => {      
    expect(isMeshInFrustum(box2, scene)).toBe(false);
});  

});

1 Like

Your arc rotate camera is not correct here, you did not set it up fully.

this test is totally ok for me

describe("frustrum test", () => {
        const isMeshInFrustum = (mesh: BABYLON.Mesh, scene: BABYLON.Scene): boolean => {
            let withinFrustum = false;
            const frustumPlanes = BABYLON.Frustum.GetPlanes(scene.getTransformMatrix());
            if (mesh && mesh.isInFrustum(frustumPlanes)) {
                withinFrustum = true;
            }
            return withinFrustum;
        };

        it("should be in frustum", () => {
            const engine = new BABYLON.NullEngine();
            const scene = new BABYLON.Scene(engine);

            const camera = new BABYLON.ArcRotateCamera("camera1", 0, 0, 5, new BABYLON.Vector3(0, 0, 0), scene);
            camera.target = new BABYLON.Vector3(0, 0, 0);

            const box1 = BABYLON.Mesh.CreateBox('box1', .1, scene);
            box1.position = new BABYLON.Vector3(0, 0.5, 0);

            const box2 = BABYLON.Mesh.CreateBox('box2', .1, scene);
            box2.position = new BABYLON.Vector3(0, 0.5, -10);

            scene.render();

            expect(isMeshInFrustum(box1, scene)).to.be.true;
            expect(isMeshInFrustum(box2, scene)).to.be.false;
        });
    });
2 Likes