Bitbybit For BabylonJS Developers

If you already use BabylonJS you can adapt bitbybit and it's CAD features in your web applications, games or 3D configurators. BabylonJS is amazing game engine that sits at the core of our technology stack.

Intermediate
Free
TypeScript
Image showing BabylonJS logo designed in 3D using TypeScript programming language

Havok Physics

Physics engine called Havok gives our users powerful simulation features, let's learn how to use it in Bitbybit.

In this tutorial video we learn how to use it in combination with our CAD algorithms. We will design a chain model shape, convert it to BabylonJS mesh and will simulate it's physical movement through Havok.

The Code

You can copy paste this code to Monaco TypeScript editor and it should work without problems even if you do not have an account.

const start = async () => { bitbybit.draw.drawGridMesh(new Bit.Inputs.Draw.SceneDrawGridMeshDto()); const resMeshes = await createPartMeshes(); bitbybit.babylon.scene.enablePhysics({ vector: [0, -9.81, 0] }); const times = 8; const step = 4.5; for (let i = 0; i <= times; i++) { const cloneVisual = resMeshes.visualMesh.clone(`clone-visual-${i}`); const cloneCollision = resMeshes.collisionMesh.clone(`clone-collision-${i}`); if (i % 2 === 0) { cloneVisual.rotateAround(new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(1, 0, 0), Math.PI / 2); } cloneVisual.position = new BABYLON.Vector3(i * step, 20, 0); cloneCollision.position = new BABYLON.Vector3(i * step, 20, 0); if (i === 0) { new BABYLON.PhysicsAggregate( cloneVisual, BABYLON.PhysicsShapeType.MESH, { mesh: cloneCollision, mass: 0, restitution: 0.75 } ); } else { new BABYLON.PhysicsAggregate( cloneVisual, BABYLON.PhysicsShapeType.MESH, { mesh: cloneCollision, mass: 0.5, restitution: 0.75 } ); } } resMeshes.visualMesh.getChildMeshes().forEach(m => m.isVisible = false); } start(); async function createPartMeshes() { const res = await createChainPartShape(); const visualOptions = new Bit.Inputs.Draw.DrawOcctShapeOptions(); visualOptions.precision = 0.02; const visualMesh = await bitbybit.draw.drawAnyAsync({ entity: res.visualShape, options: visualOptions, }); const collisionOptions = new Bit.Inputs.Draw.DrawOcctShapeOptions(); collisionOptions.drawEdges = false; collisionOptions.precision = 0.5; const collisionMeshRes = await bitbybit.draw.drawAnyAsync({ entity: res.collisionShape, options: collisionOptions }); const collisionMesh = collisionMeshRes.getChildMeshes()[0] as BABYLON.Mesh; collisionMesh.isVisible = false; return { visualMesh, collisionMesh }; } async function createChainPartShape() { const radiusOffset = 0.5; const radiusMinor = 1; const radiusMajor = 3; const radiusArray = [ { minor: radiusMinor, major: radiusMajor - radiusOffset }, { minor: radiusMinor + radiusOffset, major: radiusMajor + radiusOffset } ]; const ellipses = await Promise.all(radiusArray.map(r => { const ellipseOptions = new Bit.Inputs.OCCT.EllipseDto(); ellipseOptions.radiusMajor = r.major; ellipseOptions.radiusMinor = r.minor; ellipseOptions.direction = [0, 0, 1]; ellipseOptions.center = [0, 0, -radiusOffset / 2]; return bitbybit.occt.shapes.wire.createEllipseWire(ellipseOptions); })); const ellipseFace = await bitbybit.occt.operations.loft({ shapes: ellipses, makeSolid: false }); const collisionShape = await bitbybit.occt.operations.extrude({ shape: ellipseFace, direction: [0, 0, radiusOffset], }); const visualShape = await bitbybit.occt.fillets.filletEdges({ shape: collisionShape, radius: 0.1, }); return { visualShape, collisionShape }; }
< PreviousFinish >