Babylon JS Day 19
Today I worked on importing a golf club model and attaching it to a VR controller as a child object. I started off by setting up an AssetsManager
for the scene, then importing a model. I’m using the blue club from the Minigolf Kit from Kenney game assets. I’m really starting to like the AssetsManager
feature. It seems like I can count on anything loaded this way to be ready and available to other parts of the scene by the time the scene is done loading.
// Import assets
var assetsManager = new BABYLON.AssetsManager(scene);
const path = "../assets/models/";
assetsManager.addMeshTask("mesh task", "", path, "club_blue.glb").onSuccess = function (task) {
globalClub = task.loadedMeshes[0];
globalClub.position = new BABYLON.Vector3(0, 1, 2);
globalClub.name = "club";
};
assetsManager.load();
After loading the mesh in the mesh task, I assign it to a global variable so I can get a reference to it later. I’m sure there is a better way to do this, but this works for now.
Attaching the golf club to the controller was a lot harder than I thought it would be. I started by referring to the playground that I mentioned yesterday. First, I needed to swap out the box mesh with the club that I imported, hence the global variable mentioned above. Then I used a reference to the motion controller called mesh
as the parent object for the club. Getting the club positioned and rotated relative to the controller was the hard part. The rotate method was confusing me. It took me a while to realize that this method wanted radians and I was entering degrees…
The order of the rotation and translations was also important. When the club is attached to the parent mesh, I set its rotation to match the parent (controller), then rotate around the X axis, then rotate around the Y axis. Finally, move the club “down” the Y axis just a bit.
// WebXRDefaultExperience
const xr = await scene.createDefaultXRExperienceAsync({
floorMeshes: [ground]
});
xr.pointerSelection.detach();
xr.input.onControllerAddedObservable.add((inputSource) => {
inputSource.onMotionControllerInitObservable.add((motionController) => {
motionController.onModelLoadedObservable.add((mc) => {
let mesh = inputSource.grip;
if (motionController.handedness[0] !== "l") {
globalClub.setParent(mesh);
globalClub.position = BABYLON.Vector3.ZeroReadOnly;
globalClub.rotation = mesh.rotation;
globalClub.rotate(BABYLON.Axis.X, 1.57079, BABYLON.Space.LOCAL);
globalClub.rotate(BABYLON.Axis.Y, 3.14159, BABYLON.Space.LOCAL);
globalClub.locallyTranslate(new BABYLON.Vector3(0, -0.1, 0));
}
});
});
});