Scaling a gltf model

I want to scale a gltf model I have . Here is the code I have :

<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>

	<script src="https://cdn.babylonjs.com/babylon.js"></script>
	<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
	<script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>
	<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>

	<style>
	#renderCanvas {
		width: 100%;
		height: 100%;
		touch-action: none;
	}
</style>
</head>
<body>
	<canvas id="renderCanvas" touch-action="none"></canvas>

	<script type="text/javascript">

		const canvas = document.getElementById("renderCanvas"); /*Get the canvas element*/ 
		const engine = new BABYLON.Engine(canvas, true); /*Generate the BABYLON 3D engine*/ 
		let render = true

		const createScene = function () {

			const scene = new BABYLON.Scene(engine);  

			const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 15, new BABYLON.Vector3(0, 0, 0));
			camera.attachControl(canvas, true);

			BABYLON.MeshBuilder.CreateBox("box",{})

			const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0));

			BABYLON.SceneLoader.Append("./city_scene_tokyo/", "scene.gltf", scene);

			return scene;
		};
		
		const scene = createScene(); /*Call the createScene function*/

		/* Register a render loop to repeatedly render the scene*/
		engine.runRenderLoop(function () {
			if (render) {
				scene.render();
			}
		});

		/*Watch for browser/canvas resize events*/
		window.addEventListener("resize", function () {
			engine.resize();
		});


	</script>
</body>
</html>

Here’s what I tried:

<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>

	<script src="https://cdn.babylonjs.com/babylon.js"></script>
	<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
	<script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>
	<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>

	<style>
	#renderCanvas {
		width: 100%;
		height: 100%;
		touch-action: none;
	}
</style>
</head>
<body>
	<canvas id="renderCanvas" touch-action="none"></canvas>

	<script type="text/javascript">

		const canvas = document.getElementById("renderCanvas"); /*Get the canvas element*/ 
		const engine = new BABYLON.Engine(canvas, true); /*Generate the BABYLON 3D engine*/ 
		let render = true

		/*Add your code here matching the playground format*/ 
		const createScene = function () {

			const scene = new BABYLON.Scene(engine);  

			const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 15, new BABYLON.Vector3(0, 0, 0));
			camera.attachControl(canvas, true);

			BABYLON.MeshBuilder.CreateBox("box",{})

			const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0));

			let city = BABYLON.SceneLoader.Append("./city_scene_tokyo/", "scene.gltf", scene);
                        city.scaling = new BABYLON.Vector3(0.1,0.1,0.1)

			return scene;
		};
		
		const scene = createScene(); /*Call the createScene function*/

		/* Register a render loop to repeatedly render the scene*/
		engine.runRenderLoop(function () {
			if (render) {
				scene.render();
			}
		});

		/*Watch for browser/canvas resize events*/
		window.addEventListener("resize", function () {
			engine.resize();
		});


	</script>
</body>
</html>

Hi!
I think you can scale down the model by scaling down meshes.
You can do this in the callback function of the SceneLoader.Append method like below.

BABYLON.SceneLoader.Append("./city_scene_tokyo/", "scene.gltf", scene, (meshes, _, skeletons) => {
  meshes.forEach((mesh) => {
    mesh.scaling = new BABYLON.Vector3(0.5, 0.5, 0.5)
  })
});

Thanks!
But what is _, skeletons?

The callback function has some parameters like meshes, particleSystems, skeletons and so on.
You can check these in the console like the code below.

BABYLON.SceneLoader.Append("./city_scene_tokyo/", "scene.gltf", scene, (...params) => {
  console.log(params)
});
1 Like

Thanks!

1 Like

@ynnek please consider creating your repro in the babylon playground next time :slight_smile: https://playground.babylonjs.com/

3 Likes

It’s not working . I tried it like you said ,

BABYLON.SceneLoader.Append("./city_scene_tokyo/", "scene.gltf", scene, (meshes, skeletons) => {
				meshes.forEach((mesh) => {
					mesh.scaling = new BABYLON.Vector3(0.1, 0.1, 0.1)
				})
		});

@user1 I don’t know your model’s data… So I can’t figure out the problem…
Check out the PG below where the scaling process works well!

https://playground.babylonjs.com/#92Y727#159

My model : City Scene Tokyo - Download Free 3D model by Sooi Cherchye (@sooi) [b25d23f] - Sketchfab

@user1 I don’t know if it is because of my working environment, but I can’t even load the file…
I double-checked with blender and also failed…

Ok , thanks for trying . I’ll see what I can do.

@user1 please please create a repro in the playground

1 Like

Please provide a playground, but if you want to scale the model, you don’t want to loop through all the meshes. That will scale multiple times (at least twice) since there is a root mesh that is the parent of everything. You should be able to scale the model by scaling just the root mesh, which is always mesh[0] returned by the loader.

2 Likes

But how do I load my own model in the playground?

@bghgary Thanks for correcting my mistake!

1 Like

This doc should help:

1 Like

I just tested the glTF loader and mesh[0] is not root.
There seems to be a mesh named ‘root’ and scale should be applied to this node.

I prepared a demo here:

Not sure if the specs changed or if this is a bug.

SceneLoader.Append returns a scene. If you want to get the loaded meshes, you need to call SceneLoader.ImportMesh.