Script: Physics Cruiser

Physics Cruiser picture
Type
Typescript logo indicatortypescript
Author
matas
Date Created
Nov 11, 2023, 9:07:42 AM
Last Edit Date
Apr 29, 2024, 7:42:19 AM

Project Information

This is a conceptual design of advanced spacecraft that shows off some of the new algorithms of the platform, such as splitting the wire into multiple pieces, selecting geometry by using boolean pattern matching, and adopting advanced lofting techniques.

View Full Project

Script Code

const scene = bitbybit.babylon.scene.getScene();

scene.activeCamera.position = new BABYLON.Vector3(-40, 10, -40)

const start = async () => {

    const files = [
        "alien-nebula-cruiser-1.glb",
        "alien-nebula-collision-body-1.glb",
    ]

    const gltfFiles = await Promise.all(files.map(fileName => bitbybit.asset.getFile({ fileName })));
    const meshes = await Promise.all(gltfFiles.map(assetFile => bitbybit.babylon.io.loadAssetIntoScene({ assetFile, hidden: true })));
    const meshSpaceship = meshes[0];
    meshSpaceship.position = new BABYLON.Vector3(0, 50, 0);

    const meshSpadceshipCollisionBody = meshes[1];
    const collisionBody = meshSpadceshipCollisionBody.getChildMeshes().find((m) => m.name.includes("surface")) as BABYLON.Mesh;
    collisionBody.position = new BABYLON.Vector3(0, 50, 0);
    collisionBody.isVisible = false;
    const groundMesh = await createBox();
    const groundCollisionMesh = groundMesh.getChildMeshes().find((m) => m.name.includes("surface")) as BABYLON.Mesh;

    bitbybit.babylon.scene.enablePhysics({ vector: [0, -9.81, 0] });

    const size = 20;
    const step = 20;
    for (let x = -size; x <= size; x += step) {
        for (let y = -size; y < size * 4; y += step) {
            for (let z = -size; z <= size; z += step) {
                const parentMesh = new BABYLON.Mesh(`${x}-${y}-${z}`, scene);
                meshSpaceship.getChildMeshes().forEach((mesh: BABYLON.Mesh) => {
                    if (mesh.name !== "__root__") {
                        const inst = mesh.createInstance(`${x}-${y}-${z}-instance`);
                        inst.parent = parentMesh;
                    }
                });

                parentMesh.position = new BABYLON.Vector3(x, y + (size * 2), z);
                const collisionBodyMesh = collisionBody.clone(`${x}-${y}-${z}-collision`);
                new BABYLON.PhysicsAggregate(parentMesh, BABYLON.PhysicsShapeType.MESH, { mesh: collisionBodyMesh, mass: 3.75, restitution: 0.75 }, scene);
            }
        }
    }

    new BABYLON.PhysicsAggregate(groundMesh, BABYLON.PhysicsShapeType.MESH, { mesh: groundCollisionMesh, mass: 0, restitution: 0.75 }, scene);
    meshSpaceship.getChildMeshes().forEach(m => m.isVisible = false);
    const lightOpt = new Bit.Inputs.BabylonScene.DirectionalLightDto();
    lightOpt.direction = [-100, -500, -100];
    lightOpt.shadowGeneratorMapSize = 2056;
    bitbybit.babylon.scene.drawDirectionalLight(lightOpt)
}

start();


async function createBox() {

    const box = await bitbybit.occt.shapes.solid.createBox({
        width: 100,
        length: 100,
        height: 30,
        center: [0, 13, 0],
    })

    const boxCutout = await bitbybit.occt.shapes.solid.createBox({
        width: 90,
        length: 90,
        height: 30,
        center: [0, 15, 0],
    })

    const diff = await bitbybit.occt.booleans.difference({
        shape: box,
        shapes: [boxCutout],
        keepEdges: false
    })

    const boxDrawOptions = new Bit.Inputs.Draw.DrawOcctShapeOptions();
    boxDrawOptions.precision = 0.1;
    boxDrawOptions.faceColour = "#ff00ff";
    const boxMesh = await bitbybit.draw.drawAnyAsync({
        entity: diff,
        options: boxDrawOptions
    })

    return boxMesh

}