Animation setup 3D Gaussian Splatting

Animation setup 3D Gaussian Splatting script details
Type
Typescript logo image
typescript
App Version
0.15.12
Visibility
public
Date Created
Jun 6, 2024, 6:11:17 AM
Last Edit Date
Jun 19, 2024, 9:30:59 PM

Script Details

The Code
const { occt } = bitbybit; enum cameraAnimationEnum { ellipse, spiral, line, }; let activeAnimation = cameraAnimationEnum.spiral; const start = async () => { const asset = await bitbybit.asset.getFile({ fileName: "plant.splat" }); const objectUrl = bitbybit.asset.createObjectURL({ file: asset }); const gs = await bitbybit.babylon.gaussianSplatting.create({ url: objectUrl }); createVase(); setupCameraAndAnimations(); } async function createVase() { const shapesToDelete = []; const cylinder = await occt.shapes.solid.createCylinder({ center: [0, 0, 0], direction: [0, 1, 0], height: 0.2, radius: 0.7, }); shapesToDelete.push(cylinder); const ngon = await occt.shapes.wire.createNGonWire({ nrCorners: 6, direction: [0, 1, 0], radius: 1, center: [0, 0, 0], }); shapesToDelete.push(ngon); const rotatedExtrude = await occt.operations.rotatedExtrude({ shape: ngon, angle: 90, height: 0.5, }); shapesToDelete.push(rotatedExtrude); const translatedExtrude = await occt.transforms.translate({ shape: rotatedExtrude, translation: [0, -0.4, 0], }); shapesToDelete.push(translatedExtrude); const vaseBase = await occt.booleans.difference({ shape: translatedExtrude, shapes: [cylinder], keepEdges: false, }); shapesToDelete.push(vaseBase); const vase = await occt.fillets.filletEdges({ shape: vaseBase, radius: 0.03, }); bitbybit.occt.deleteShapes({ shapes: shapesToDelete }); const drawOptions = new Bit.Inputs.Draw.DrawOcctShapeOptions(); drawOptions.edgeColour = "#000000"; drawOptions.edgeWidth = 0.1; drawOptions.faceColour = "#404040"; drawOptions.precision = 0.001; bitbybit.draw.drawAnyAsync({ entity: vase, options: drawOptions, }); } async function setupCameraAndAnimations() { let wire; if (activeAnimation === cameraAnimationEnum.ellipse) { wire = await occt.shapes.wire.createEllipseWire({ center: [0, 2, 0], radiusMinor: 4, radiusMajor: 5, direction: [1, 1, 0] }); } else if (activeAnimation === cameraAnimationEnum.line) { wire = await occt.shapes.wire.createLineWire({ start: [6, 2, 3], end: [-6, 2, 3], }); } else if (activeAnimation === cameraAnimationEnum.spiral) { const radius = 4; const step = 0.2; const ptsSpiralBase: Bit.Inputs.Base.Point3[] = [ [radius, 0, 0], [0, step * 1, radius], [-radius, step * 2, 0], [0, step * 3, -radius], [radius, step * 4, 0], [0, step * 5, radius], [-radius, step * 6, 0], [0, step * 7, -radius], [radius, step * 8, 0], [0, step * 9, radius], [-radius, step * 10, 0], [0, step * 11, -radius], ]; wire = await occt.shapes.wire.interpolatePoints({ points: ptsSpiralBase, periodic: false, tolerance: 0.01 }); } const points = await occt.shapes.wire.divideWireByEqualDistanceToPoints({ shape: wire, nrOfDivisions: 10000, removeStartPoint: false, removeEndPoint: true }); const ptsLooped = [...points, ...points.reverse()] const camera = bitbybit.babylon.scene.getActiveCamera() as BABYLON.ArcRotateCamera; camera.target = new BABYLON.Vector3(0, 0.5, 0); let index = 0; bitbybit.time.registerRenderFunction(() => { if (index < ptsLooped.length) { const pt = ptsLooped[index]; camera.setPosition(new BABYLON.Vector3(pt[0], pt[1], pt[2])) index++; } else { index = 0; } }); } start();