Trampoline

Trampoline script details
Author
matas
Type
Typescript logo image
typescript
App Version
0.15.9
Visibility
public
Date Created
Nov 12, 2023, 3:21:38 PM
Last Edit Date
Apr 29, 2024, 7:45:12 AM

Script Details

The Code
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 }