Grids
Copying and pasting? We've got you covered! You can find the full source code of this tutorial here.
πΈοΈ Adding a fancy grid to our sceneβ
In this tutorial you'll learn how to add a fancy grid to your scene. It's super easy and will make your app look much more professional!
Grids are very common in 3D apps, and it's a great way to have a reference point for your users to navigate around, even when there are no visible objects around.
In this tutorial, we will import:
Three.js
to get some 3D entities for our app.@thatopen/components
to set up the barebone of our app.
import * as THREE from "three";
import Stats from "stats.js";
import * as OBC from "@thatopen/components";
import * as BUI from "@thatopen/ui";
π Setting up a simple sceneβ
We will start by creating a simple scene with a camera and a renderer. If you don't know how to set up a scene, you can check the Worlds tutorial.
const container = document.getElementById("container")!;
const components = new OBC.Components();
const worlds = components.get(OBC.Worlds);
const world = worlds.create<
OBC.SimpleScene,
OBC.SimpleCamera,
OBC.SimpleRenderer
>();
world.scene = new OBC.SimpleScene(components);
world.renderer = new OBC.SimpleRenderer(components, container);
world.camera = new OBC.SimpleCamera(components);
components.init();
const cube = new THREE.Mesh(
new THREE.BoxGeometry(),
new THREE.MeshBasicMaterial({ color: "red" }),
);
world.scene.three.add(cube);
We'll make the background of the scene transparent so that it looks good in our docs page, but you don't have to do that in your app!
world.scene.three.background = null;
π·οΈ Adding the grid to the worldβ
To add the grid to the world, we will use the Grids
component. Instead of instantiating it, we will get it directly from the components
object. Remember that all components are meant to be singletons. Then, we will call the create
method to add a grid to the scene.
const grids = components.get(OBC.Grids);
const grid = grids.create(world);
console.log(grid);
𧩠Adding some UIβ
We will use the @thatopen/ui
library to add some simple and cool UI elements to our app. First, we need to call the init
method of the BUI.Manager
class to initialize the library:
BUI.Manager.init();
Now we will create some UI elements and bind them to some of the controls of the clipper, like activation, visibility, size, color, etc. For more information about the UI library, you can check the specific documentation for it!
const panel = BUI.Component.create<BUI.PanelSection>(() => {
return BUI.html`
<bim-panel label="Grids Tutorial" class="options-menu">
<bim-panel-section collapsed label="Controls"">
<bim-checkbox label="Grid visible" checked
@change="${({ target }: { target: BUI.Checkbox }) => {
grid.config.visible = target.value;
}}">
</bim-checkbox>
<bim-color-input
label="Grid Color" color="#bbbbbb"
@input="${({ target }: { target: BUI.ColorInput }) => {
grid.config.color = new THREE.Color(target.color);
}}">
</bim-color-input>
<bim-number-input
slider step="0.1" label="Grid primary size" value="1" min="0" max="10"
@change="${({ target }: { target: BUI.NumberInput }) => {
grid.config.primarySize = target.value;
}}">
</bim-number-input>
<bim-number-input
slider step="0.1" label="Grid secondary size" value="10" min="0" max="20"
@change="${({ target }: { target: BUI.NumberInput }) => {
grid.config.secondarySize = target.value;
}}">
</bim-number-input>
</bim-panel-section>
</bim-panel>
`;
});
document.body.append(panel);
And we will make some logic that adds a button to the screen when the user is visiting our app from their phone, allowing to show or hide the menu. Otherwise, the menu would make the app unusable.
const button = BUI.Component.create<BUI.PanelSection>(() => {
return BUI.html`
<bim-button class="phone-menu-toggler" icon="solar:settings-bold"
@click="${() => {
if (panel.classList.contains("options-menu-visible")) {
panel.classList.remove("options-menu-visible");
} else {
panel.classList.add("options-menu-visible");
}
}}">
</bim-button>
`;
});
document.body.append(button);
β±οΈ Measuring the performance (optional)β
We'll use the Stats.js to measure the performance of our app. We will add it to the top left corner of the viewport. This way, we'll make sure that the memory consumption and the FPS of our app are under control.
const stats = new Stats();
stats.showPanel(2);
document.body.append(stats.dom);
stats.dom.style.left = "0px";
stats.dom.style.zIndex = "unset";
world.renderer.onBeforeUpdate.add(() => stats.begin());
world.renderer.onAfterUpdate.add(() => stats.end());
π Wrap upβ
Congratulations! You have created your first infinite grid in your 3D app. As you can see, it's super easy and it looks great!