const scene = bitbybit.babylon.scene.getScene();
const wheelScale = 0.5;
const camera = scene.activeCamera as BABYLON.ArcRotateCamera;
camera.position = new BABYLON.Vector3(110, 10, 110);
camera.target = new BABYLON.Vector3(0, 30, 0);
const start = async () => {
const fileName = "alloy-wheel.glb";
bitbybit.babylon.scene.enablePhysics({
vector: [0, -9.81, 0]
});
const alloyWheelAssetFile = await bitbybit.asset.getFile({
fileName
});
const alloyWheelMesh = await bitbybit.babylon.io.loadAssetIntoScene({
assetFile: alloyWheelAssetFile,
hidden: false
});
alloyWheelMesh.getChildMeshes().forEach(m => m.isVisible = false);
const width = 40;
const pointsHorizontal = [
[-55, 55, -width / 2],
[-35, 50, -width / 2],
[-30, 50, -width / 2],
[0, 25, -width / 2],
[5, 20, -width / 2],
[10, 15, -width / 2],
[30, 10, -width / 2],
[50, 20, -width / 2],
] as Bit.Inputs.Base.Point3[];
const wireHorizontal = await bitbybit.occt.shapes.wire.interpolatePoints({
points: pointsHorizontal,
periodic: false,
tolerance: 0.1
});
const extrude = await bitbybit.occt.operations.extrude({
shape: wireHorizontal,
direction: [0, 0, width]
});
const thick = await bitbybit.occt.operations.makeThickSolidSimple({
shape: extrude,
offset: -2
});
const fillet = await bitbybit.occt.fillets.filletEdges({
shape: thick,
radius: 0.6
})
const optionsDrawSlide = new Bit.Inputs.Draw.DrawOcctShapeOptions();
optionsDrawSlide.faceColour = "#000055";
const filletShapeMesh = await bitbybit.draw.drawAnyAsync({
entity: fillet,
options: optionsDrawSlide
});
const thichMesh = filletShapeMesh.getChildMeshes().find(m => m.name.includes("surface")) as BABYLON.Mesh;
const groundMesh = await createBox();
const groundCollisionMesh = groundMesh.getChildMeshes().find((m) => m.name.includes("surface")) as BABYLON.Mesh;
for (let z = -width / 2 + 5; z < width / 2; z += 5) {
const alloyWheelInstanceParent = new BABYLON.Mesh(`${z}`);
const children = alloyWheelMesh.getChildren().filter(s => !s.name.includes("root"));
children.forEach((c: BABYLON.Mesh) => {
const inst = c.createInstance(c.name + "instance" + z);
inst.isVisible = true;
inst.receiveShadows = true;
inst.parent = alloyWheelInstanceParent;
})
alloyWheelInstanceParent.scaling = new BABYLON.Vector3(wheelScale, wheelScale, wheelScale);
alloyWheelInstanceParent.position = new BABYLON.Vector3(-50, 60, z);
new BABYLON.PhysicsAggregate(alloyWheelInstanceParent, BABYLON.PhysicsShapeType.CYLINDER, { pointA: new BABYLON.Vector3(0, 0, -4), pointB: new BABYLON.Vector3(0, 0, 0), friction: 1, radius: 7, mass: 20, restitution: 0.75 }, scene);
}
let timeoutIncrease = 5000;
const shadowGenerators = scene.metadata.shadowGenerators as BABYLON.ShadowGenerator[];
for (let y = 0; y <= 60; y += 20) {
setTimeout(() => {
for (let z = -width / 2 + 5; z < width / 2; z += 5) {
const alloyWheelInstanceParent = new BABYLON.Mesh(`${z}`);
const children = alloyWheelMesh.getChildren().filter(s => !s.name.includes("root"));
children.forEach((c: BABYLON.Mesh) => {
const inst = c.createInstance(c.name + "instance" + z);
inst.isVisible = true;
inst.receiveShadows = true;
inst.parent = alloyWheelInstanceParent;
shadowGenerators.forEach(sg => {
sg.addShadowCaster(inst);
})
})
alloyWheelInstanceParent.scaling = new BABYLON.Vector3(wheelScale, wheelScale, wheelScale);
alloyWheelInstanceParent.position = new BABYLON.Vector3(-50, 70 + y, z);
new BABYLON.PhysicsAggregate(alloyWheelInstanceParent, BABYLON.PhysicsShapeType.CYLINDER, { pointA: new BABYLON.Vector3(0, 0, -4), pointB: new BABYLON.Vector3(0, 0, 0), friction: 1, radius: 7, mass: 20, restitution: 0.75 }, scene);
}
}, timeoutIncrease);
timeoutIncrease += 5000;
}
new BABYLON.PhysicsAggregate(thichMesh, BABYLON.PhysicsShapeType.MESH, { mesh: thichMesh, mass: 0, restitution: 0.75, friction: 1 }, scene);
new BABYLON.PhysicsAggregate(groundMesh, BABYLON.PhysicsShapeType.MESH, { mesh: groundCollisionMesh, mass: 0, restitution: 0.75 }, scene);
const dirLightOptions = new Bit.Inputs.BabylonScene.DirectionalLightDto();
dirLightOptions.direction = [100, -100, 100];
dirLightOptions.intensity = 4;
dirLightOptions.shadowGeneratorMapSize = 2056;
bitbybit.babylon.scene.drawDirectionalLight(dirLightOptions);
const skyBox = new Bit.Inputs.BabylonScene.SkyboxDto();
skyBox.skybox = Bit.Inputs.Base.skyboxEnum.city;
skyBox.blur = 0.4;
skyBox.environmentIntensity = 0.3;
bitbybit.babylon.scene.enableSkybox(skyBox)
}
start();
async function createBox() {
const box = await bitbybit.occt.shapes.solid.createBox({
width: 250,
length: 250,
height: 70,
center: [0, 13, 0],
})
const boxCutout = await bitbybit.occt.shapes.solid.createBox({
width: 240,
length: 240,
height: 70,
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 = "#000033";
const boxMesh = await bitbybit.draw.drawAnyAsync({
entity: diff,
options: boxDrawOptions
})
return boxMesh
}