π Stumbled here on accident? Start with the first part!
Welcome back to the 8th instalment in this series. This part is about importing an asset in form of a 3D model of a door that gets attached to an anchor.
βΉοΈ Remember - you can always run the code associated with this article and follow along using
npm start --part=8
Prerequisite
To be able to load model files in form of assets into a scene we first need to import the babylonjs model loader for glb/glTF
files.
import '@babylonjs/loaders/glTF';
The provided 3D model file consists of 3 layers. A Handle
, a Door
and a Door_frame
.
The loader itself add a parent node called __root__
to the whole model, therefore the 3 layers are stored as sub meshes to the __root__
.
enum DoorMeshes {
Handle = 'Handle',
Door = 'Door',
DoorFrame = 'Door_frame',
Container = '__root__',
}
To make things easier when loading parts on their own, we create an enum for the layer names.
Loading the model
addDoor(): void {
SceneLoader.Append("/models/", "door.glb", this._scene, ((scene: Scene) => {
this._handle = scene.getMeshByName(DoorMeshes.Handle);
this._door = scene.getMeshByName(DoorMeshes.Door);
this._doorFrame = scene.getMeshByName(DoorMeshes.DoorFrame);
this._doorContainer = scene.getMeshByName(DoorMeshes.Container);
const meshes = this._doorContainer!.getChildMeshes();
meshes.forEach((mesh) => {
this._shadowGenerator!.addShadowCaster(mesh);
mesh.receiveShadows = true;
});
this._handle!.isVisible = false;
this._door!.isVisible = false;
this._doorFrame!.isVisible = false;
}));
}
Next weβre going to add the addDoor
function to load the 3D model.
SceneLoader.Append
loads a model from a specific local file path into the the this._scene
.
Once the model is loaded a callback function is called. In the callback function each mesh is assigned to a variable making them easily accessible later on.
βοΈThe most important layer is the node layer which is assigned to this._doorContainer since this is going to be the one that is being attached to an anchor later on.
Then we loop through all the child meshes to:
add the mesh as a shadow caster to the
this._shadowGenerator
, allowing it to cast shadows to the scenesetting
receiveShadows
to true to enable the mesh to receive shadows from other objects in the scene
Finally we set each mesh to be invisible initially to be later explicitly make them visible again when attached to an anchor.
Adding the door to the scene
async createScene(): Promise<Scene> {
...
this.addDoor();
if (this._xrAnchors && this._xrAnchors.isCompatible()) {
this.observeAnchors();
this.handleControllerSelection();
}
return this._scene;
}
To be able for the scene to load the model, we add this.addDoor()
to the createScene
function.
Attaching the model to an anchor
addAnchorAtPosition(raycastHit: PickingInfo) {
this._xrAnchors!.addAnchorAtPositionAndRotationAsync(raycastHit.pickedPoint!).then((anchor) => {
const boxTransformNode = new TransformNode('boxTransformNode');
this._box!.parent = boxTransformNode;
this._box!.position = new Vector3(0, 1, .5);
this._box!.isVisible = true;
this._door!.isVisible = true;
this._doorFrame!.isVisible = true;
this._handle!.isVisible = true;
this._doorContainer!.position = raycastHit.pickedPoint!;
boxTransformNode.parent = this._doorContainer!;
anchor.attachedNode = this._doorContainer!;
anchor.attachedNode.position = raycastHit.pickedPoint!;
});
}
Since we already know how to attach a mesh to an anchor, we adjust our previous implementation for the this._box
to this._doorContainer
. Instead of attaching the this._box
directly to the anchor, we assign the this._doorContainer
as the parent to the box and assign the doorContainer
to anchor.attachedNode
. Important in this step is to make the model layers visible by setting isVisible
to true
.
Conclusion
In this 8th installment, we covered the process of importing and integrating a 3D door model with Babylon.js. We detailed loading the model, managing its components, and attaching it to an anchor. The steps taken demonstrate a straightforward approach to incorporating interactive elements in virtual environments, suggesting practical applications in web technology.
In the ninth and final part weβre going to implement some animations for the door.
Top comments (0)