-
Notifications
You must be signed in to change notification settings - Fork 293
Importing Models
xeokit-sdk can load multiple models from a variety of source formats into the same 3D scene. xeokit represents a 3D scene as a scene graph, which is hierarchy of Nodes in which Meshes are the drawable elements at the leaves. When we use one of xeokit's Viewer plugins to load a model, we create a sub-graph of Nodes and Meshes within the scene graph that represents the model.
See also:
- Scene Graphs - generic details on scene graphs
- Scene Metadata - classifying scene content with metadata
- Viewer Plugins - list of available viewer plugins
- Example
- Finding Models and Objects by ID
- Destroying a model
- Replacing Model Materials with LambertMaterials
In the example below, we'll use a GLTFLoaderPlugin to load the Schependomlaan house model and a OBJLoaderPlugin to load a model of a car.
We'll also use a Node to contain them in a simple scene graph, scaled down a bit, and we'll add a Mesh to represent the green ground plane.
The ground plane Mesh gets a plane-shaped Geometry created by a buildPlaneGeometry builder function.
Click the image below for a live demo.
import {Viewer} from "../src/viewer/Viewer.js";
import {Node} from "../src/scene/nodes/Node.js";
import {OBJLoaderPlugin} from "../src/viewer/plugins/OBJLoaderPlugin/OBJLoaderPlugin.js";
import {GLTFLoaderPlugin} from "../src/viewer/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.js";
import {Mesh} from "../src/scene/mesh/Mesh.js";
import {buildPlaneGeometry} from "../src/scene/geometry/builders/buildPlaneGeometry.js";
import {ReadableGeometry} from "../src/scene/geometry/ReadableGeometry.js";
import {PhongMaterial} from "../src/scene/materials/PhongMaterial.js";
const viewer = new Viewer({
canvasId: "myCanvas"
});
const objLoader = new OBJLoaderPlugin(viewer);
const gltfLoader = new GLTFLoaderPlugin(viewer);
new Node(viewer.scene, {
scale: [.5, .5, .5], // Scale the whole scene down a bit
children: [
// Car
objLoader.load({
id: "myCarModel",
src: "./models/obj/sportsCar/sportsCar.obj",
position: [-5, -1, 0],
}),
// House
gltfLoader.load({
id: "myHouseModel",
src: "./models/gltf/schependomlaan/scene.gltf",
rotation: [0, 50, 0],
edges: true
}),
// Ground plane
new Mesh(viewer.scene, {
geometry: buildPlaneGeometry(ReadableGeometry, viewer.scene, {
xSize: 500,
zSize: 500
}),
material: new PhongMaterial(viewer.scene, {
diffuse: [0.4, 1.0, 0.4],
backfaces: true
}),
position: [0, -1.0, 0],
pickable: false,
collidable: false
})
]
});
GLTFLoaderPlugin and OBJLoaderPlugin each created a tree of Nodes within the Viewer's Scene to represent the models they loaded.
In each tree, the root Node has isModel:true
to indicate that it represents a model, while each of their sub-Nodes has isObject:true
to indicate that it represents an object.
Consequently, the root Nodes get registered in viewer.scene.models
, while the object Nodes get registered in viewer.scene.objects
.
We can get them by ID like this:
const carModel = viewer.scene.model["myCarModel"];
const houseModel = viewer.scene.model["myHouseModel"];
const carWheelObject = viewer.scene.objects["3yjlObltnCpO3ehdiY7mcZ"];
const houseWindowObject = viewer.scene.objects["3yjlObltnCpO3ehdiY7mcZ"];
To destroy a model, just destroy its Node:
carModel.destroy();
When models have many objects, and we only care about what they represent in terms of structure, we can optionally replace their materials with LambertMaterials as we load them, in order to save memory and render them more efficiently.
Below is portion of the example again, this time with materials replaced by LambertMaterials.
See Material Workflows for more info on materials.
import {Viewer} from "../src/viewer/Viewer.js";
import {Node} from "../src/scene/nodes/Node.js";
import {OBJLoaderPlugin} from "../src/viewer/plugins/OBJLoaderPlugin/OBJLoaderPlugin.js";
import {GLTFLoaderPlugin} from "../src/viewer/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.js";
const viewer = new Viewer({
canvasId: "myCanvas"
});
const objLoader = new OBJLoaderPlugin(viewer);
const gltfLoader = new GLTFLoaderPlugin(viewer);
new Node(viewer.scene, {
scale: [.5, .5, .5], // Scale the whole scene down a bit
children: [
// Car
objLoader.load({
id: "myCarModel",
src: "./models/obj/sportsCar/sportsCar.obj",
position: [-5, -1, 0],
lambertMaterial: true // <<--- Replace materials with LambertMaterial
}),
// House
gltfLoader.load({
id: "myHouseModel",
src: "./models/gltf/schependomlaan/scene.gltf",
rotation: [0, 50, 0],
edges: true,
lambertMaterial: true // <<--- Replace materials with LambertMaterial
})
]
});