import {SceneModel} from '@xeokit/xeokit-sdk/src/viewer/scene/model/SceneModel.js'
SceneModel
Extends:
Direct Subclass:
Implements:
A high-performance model representation for efficient rendering and low memory usage.
Examples
Internally, SceneModel uses a combination of several different techniques to render and represent the different parts of a typical model. Each of the live examples at these links is designed to "unit test" one of these techniques, in isolation. If some bug occurs in SceneModel, we use these tests to debug, but they also serve to demonstrate how to use the capabilities of SceneModel programmatically.
- Loading building models into SceneModels
- Loading city models into SceneModels
- Loading LiDAR scans into SceneModels
- Loading CAD models into SceneModels
- SceneModel feature tests
Overview
While xeokit's standard scene graph is great for gizmos and medium-sized models, it doesn't scale up to millions of objects in terms of memory and rendering efficiency.
For huge models, we have the SceneModel
representation, which is optimized to pack large amounts of geometry into memory and render it efficiently using WebGL.
SceneModel
is the default model representation loaded by (at least) GLTFLoaderPlugin, XKTLoaderPlugin and WebIFCLoaderPlugin.
In this tutorial you'll learn how to use SceneModel
to create high-detail content programmatically. Ordinarily you'd be learning about SceneModel
if you were writing your own model loader plugins.
Contents
- SceneModel
- GPU-Resident Geometry
- Picking
- Example 1: Geometry Instancing
- Finalizing a SceneModel
- Finding Entities
- Example 2: Geometry Batching
- Classifying with Metadata
- Querying Metadata
- Metadata Structure
- RTC Coordinates
SceneModel
SceneModel
uses two rendering techniques internally:
- Geometry batching for unique geometries, combining those into a single WebGL geometry buffer, to render in one draw call, and
- geometry instancing for geometries that are shared by multiple meshes, rendering all instances of each shared geometry in one draw call.
These techniques come with certain limitations:
- Non-realistic rendering - while scene graphs can use xeokit's full set of material workflows,
SceneModel
uses simple Lambertian shading without textures. - Static transforms - transforms within a
SceneModel
are static and cannot be dynamically translated, rotated and scaled the way Nodes and Meshes in scene graphs can. - Immutable model representation - while scene graph Nodes and
Meshes can be dynamically plugged together,
SceneModel
is immutable, since it packs its geometries into buffers and instanced arrays.
SceneModel
's API allows us to exploit batching and instancing, while exposing its elements as
abstract Entity types.
Entity is the abstract base class for the various xeokit components that represent models, objects, or anonymous visible elements. An Entity has a unique ID and can be individually shown, hidden, selected, highlighted, ghosted, culled, picked and clipped, and has its own World-space boundary.
- A
SceneModel
is an Entity that represents a model. - A
SceneModel
represents each of its objects with an Entity. - Each Entity has one or more meshes that define its shape.
- Each mesh has either its own unique geometry, or shares a geometry with other meshes.
GPU-Resident Geometry
For a low memory footprint, SceneModel
stores its geometries in GPU memory only, compressed (quantized) as integers. Unfortunately, GPU-resident geometry is
not readable by JavaScript.
Example 1: Geometry Instancing
In the example below, we'll use a SceneModel
to build a simple table model using geometry instancing.
We'll start by adding a reusable box-shaped geometry to our SceneModel
.
Then, for each object in our model we'll add an Entity that has a mesh that instances our box geometry, transforming and coloring the instance.
import {Viewer, SceneModel} from "xeokit-sdk.es.js";
const viewer = new Viewer({
canvasId: "myCanvas",
transparent: true
});
viewer.scene.camera.eye = [-21.80, 4.01, 6.56];
viewer.scene.camera.look = [0, -5.75, 0];
viewer.scene.camera.up = [0.37, 0.91, -0.11];
// Build a SceneModel representing a table
// with four legs, using geometry instancing
const sceneModel = new SceneModel(viewer.scene, {
id: "table",
isModel: true, // <--- Registers SceneModel in viewer.scene.models
position: [0, 0, 0],
scale: [1, 1, 1],
rotation: [0, 0, 0]
});
// Create a reusable geometry within the SceneModel
// We'll instance this geometry by five meshes
sceneModel.createGeometry({
id: "myBoxGeometry",
// The primitive type - allowed values are "points", "lines" and "triangles".
// See the OpenGL/WebGL specification docs
// for how the coordinate arrays are supposed to be laid out.
primitive: "triangles",
// The vertices - eight for our cube, each
// one spanning three array elements for X,Y and Z
positions: [
1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, // v0-v1-v2-v3 front
1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, // v0-v3-v4-v1 right
1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, // v0-v1-v6-v1 top
-1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, // v1-v6-v7-v2 left
-1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, // v7-v4-v3-v2 bottom
1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1 // v4-v7-v6-v1 back
],
// Normal vectors, one for each vertex
normals: [
0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0-v1-v2-v3 front
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0-v3-v4-v5 right
0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0-v5-v6-v1 top
-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1-v6-v7-v2 left
0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, // v7-v4-v3-v2 bottom
0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1 // v4-v7-v6-v5 back
],
// Indices - these organise the positions and and normals
// into geometric primitives in accordance with the "primitive" parameter,
// in this case a set of three indices for each triangle.
//
// Note that each triangle is specified in counter-clockwise winding order.
//
indices: [
0, 1, 2, 0, 2, 3, // front
4, 5, 6, 4, 6, 7, // right
8, 9, 10, 8, 10, 11, // top
12, 13, 14, 12, 14, 15, // left
16, 17, 18, 16, 18, 19, // bottom
20, 21, 22, 20, 22, 23
]
});
// Red table leg
sceneModel.createMesh({
id: "redLegMesh",
geometryId: "myBoxGeometry",
position: [-4, -6, -4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [1, 0.3, 0.3]
});
sceneModel.createEntity({
id: "redLeg",
meshIds: ["redLegMesh"],
isObject: true // <---- Registers Entity by ID on viewer.scene.objects
});
// Green table leg
sceneModel.createMesh({
id: "greenLegMesh",
geometryId: "myBoxGeometry",
position: [4, -6, -4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [0.3, 1.0, 0.3]
});
sceneModel.createEntity({
id: "greenLeg",
meshIds: ["greenLegMesh"],
isObject: true // <---- Registers Entity by ID on viewer.scene.objects
});
// Blue table leg
sceneModel.createMesh({
id: "blueLegMesh",
geometryId: "myBoxGeometry",
position: [4, -6, 4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [0.3, 0.3, 1.0]
});
sceneModel.createEntity({
id: "blueLeg",
meshIds: ["blueLegMesh"],
isObject: true // <---- Registers Entity by ID on viewer.scene.objects
});
// Yellow table leg
sceneModel.createMesh({
id: "yellowLegMesh",
geometryId: "myBoxGeometry",
position: [-4, -6, 4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [1.0, 1.0, 0.0]
});
sceneModel.createEntity({
id: "yellowLeg",
meshIds: ["yellowLegMesh"],
isObject: true // <---- Registers Entity by ID on viewer.scene.objects
});
// Purple table top
sceneModel.createMesh({
id: "purpleTableTopMesh",
geometryId: "myBoxGeometry",
position: [0, -3, 0],
scale: [6, 0.5, 6],
rotation: [0, 0, 0],
color: [1.0, 0.3, 1.0]
});
sceneModel.createEntity({
id: "purpleTableTop",
meshIds: ["purpleTableTopMesh"],
isObject: true // <---- Registers Entity by ID on viewer.scene.objects
});
Finalizing a SceneModel
Before we can view and interact with our SceneModel
, we need to finalize it. Internally, this causes the SceneModel
to build the
vertex buffer objects (VBOs) that support our geometry instances. When using geometry batching (see next example),
this causes SceneModel
to build the VBOs that combine the batched geometries. Note that you can do both instancing and
batching within the same SceneModel
.
Once finalized, we can't add anything more to our SceneModel
.
SceneModel.finalize();
Finding Entities
As mentioned earlier, Entity is the abstract base class for components that represent models, objects, or just anonymous visible elements.
Since we created configured our SceneModel
with isModel: true
,
we're able to find it as an Entity by ID in viewer.scene.models
. Likewise, since
we configured each of its Entities with isObject: true
, we're able to
find them in viewer.scene.objects
.
// Get the whole table model Entity
const table = viewer.scene.models["table"];
// Get some leg object Entities
const redLeg = viewer.scene.objects["redLeg"];
const greenLeg = viewer.scene.objects["greenLeg"];
const blueLeg = viewer.scene.objects["blueLeg"];
Example 2: Geometry Batching
Let's once more use a SceneModel
to build the simple table model, this time exploiting geometry batching.
import {Viewer, SceneModel} from "xeokit-sdk.es.js";
const viewer = new Viewer({
canvasId: "myCanvas",
transparent: true
});
viewer.scene.camera.eye = [-21.80, 4.01, 6.56];
viewer.scene.camera.look = [0, -5.75, 0];
viewer.scene.camera.up = [0.37, 0.91, -0.11];
// Create a SceneModel representing a table with four legs, using geometry batching
const sceneModel = new SceneModel(viewer.scene, {
id: "table",
isModel: true, // <--- Registers SceneModel in viewer.scene.models
position: [0, 0, 0],
scale: [1, 1, 1],
rotation: [0, 0, 0]
});
// Red table leg
sceneModel.createMesh({
id: "redLegMesh",
// Geometry arrays are same as for the earlier batching example
primitive: "triangles",
positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
position: [-4, -6, -4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [1, 0.3, 0.3]
});
sceneModel.createEntity({
id: "redLeg",
meshIds: ["redLegMesh"],
isObject: true // <---- Registers Entity by ID on viewer.scene.objects
});
// Green table leg
sceneModel.createMesh({
id: "greenLegMesh",
primitive: "triangles",
primitive: "triangles",
positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
position: [4, -6, -4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [0.3, 1.0, 0.3]
});
sceneModel.createEntity({
id: "greenLeg",
meshIds: ["greenLegMesh"],
isObject: true // <---- Registers Entity by ID on viewer.scene.objects
});
// Blue table leg
sceneModel.createMesh({
id: "blueLegMesh",
primitive: "triangles",
positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
position: [4, -6, 4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [0.3, 0.3, 1.0]
});
sceneModel.createEntity({
id: "blueLeg",
meshIds: ["blueLegMesh"],
isObject: true // <---- Registers Entity by ID on viewer.scene.objects
});
// Yellow table leg object
sceneModel.createMesh({
id: "yellowLegMesh",
positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
position: [-4, -6, 4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [1.0, 1.0, 0.0]
});
sceneModel.createEntity({
id: "yellowLeg",
meshIds: ["yellowLegMesh"],
isObject: true // <---- Registers Entity by ID on viewer.scene.objects
});
// Purple table top
sceneModel.createMesh({
id: "purpleTableTopMesh",
positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
position: [0, -3, 0],
scale: [6, 0.5, 6],
rotation: [0, 0, 0],
color: [1.0, 0.3, 1.0]
});
sceneModel.createEntity({
id: "purpleTableTop",
meshIds: ["purpleTableTopMesh"],
isObject: true // <---- Registers Entity by ID on viewer.scene.objects
});
// Finalize the SceneModel.
SceneModel.finalize();
// Find BigModelNodes by their model and object IDs
// Get the whole table model
const table = viewer.scene.models["table"];
// Get some leg objects
const redLeg = viewer.scene.objects["redLeg"];
const greenLeg = viewer.scene.objects["greenLeg"];
const blueLeg = viewer.scene.objects["blueLeg"];
Classifying with Metadata
In the previous examples, we used SceneModel
to build
two versions of the same table model, to demonstrate geometry batching and geometry instancing.
We'll now classify our Entitys with metadata. This metadata will work the same for both our examples, since they create the exact same structure of Entitys to represent their models and objects. The abstract Entity type is, after all, intended to provide an abstract interface through which differently-implemented scene content can be accessed uniformly.
To create the metadata, we'll create a MetaModel for our model, with a MetaObject for each of it's objects. The MetaModel and MetaObjects get the same IDs as the Entitys that represent their model and objects within our scene.
const furnitureMetaModel = viewer.metaScene.createMetaModel("furniture", { // Creates a MetaModel in the MetaScene
"projectId": "myTableProject",
"revisionId": "V1.0",
"metaObjects": [
{ // Creates a MetaObject in the MetaModel
"id": "table",
"name": "Table", // Same ID as an object Entity
"type": "furniture", // Arbitrary type, could be IFC type
"properties": { // Arbitrary properties, could be IfcPropertySet
"cost": "200"
}
},
{
"id": "redLeg",
"name": "Red table Leg",
"type": "leg",
"parent": "table", // References first MetaObject as parent
"properties": {
"material": "wood"
}
},
{
"id": "greenLeg", // Node with corresponding id does not need to exist
"name": "Green table leg", // and MetaObject does not need to exist for Node with an id
"type": "leg",
"parent": "table",
"properties": {
"material": "wood"
}
},
{
"id": "blueLeg",
"name": "Blue table leg",
"type": "leg",
"parent": "table",
"properties": {
"material": "wood"
}
},
{
"id": "yellowLeg",
"name": "Yellow table leg",
"type": "leg",
"parent": "table",
"properties": {
"material": "wood"
}
},
{
"id": "tableTop",
"name": "Purple table top",
"type": "surface",
"parent": "table",
"properties": {
"material": "formica",
"width": "60",
"depth": "60",
"thickness": "5"
}
}
]
});
Querying Metadata
Having created and classified our model (either the instancing or batching example), we can now find the MetaModel and MetaObjects using the IDs of their corresponding Entitys.
const furnitureMetaModel = scene.metaScene.metaModels["furniture"];
const redLegMetaObject = scene.metaScene.metaObjects["redLeg"];
In the snippet below, we'll log metadata on each Entity we click on:
viewer.scene.input.on("mouseclicked", function (coords) {
const hit = viewer.scene.pick({
canvasPos: coords
});
if (hit) {
const entity = hit.entity;
const metaObject = viewer.metaScene.metaObjects[entity.id];
if (metaObject) {
console.log(JSON.stringify(metaObject.getJSON(), null, "\t"));
}
}
});
Metadata Structure
The MetaModel organizes its MetaObjects in a tree that describes their structural composition:
// Get metadata on the root object
const tableMetaObject = furnitureMetaModel.rootMetaObject;
// Get metadata on the leg objects
const redLegMetaObject = tableMetaObject.children[0];
const greenLegMetaObject = tableMetaObject.children[1];
const blueLegMetaObject = tableMetaObject.children[2];
const yellowLegMetaObject = tableMetaObject.children[3];
Given an Entity, we can find the object or model of which it is a part, or the objects that comprise it. We can also generate UI components from the metadata, such as the tree view demonstrated in this demo.
This hierarchy allows us to express the hierarchical structure of a model while representing it in
various ways in the 3D scene (such as with SceneModel
, which
has a non-hierarchical scene representation).
Note also that a MetaObject does not need to have a corresponding Entity and vice-versa.
RTC Coordinates for Double Precision
SceneModel
can emulate 64-bit precision on GPUs using relative-to-center (RTC) coordinates.
Consider a model that contains many small objects, but with such large spatial extents that 32 bits of GPU precision (accurate to ~7 digits) will not be sufficient to render all of the the objects without jittering.
To prevent jittering, we could spatially subdivide the objects into "tiles". Each tile would have a center position, and the positions of the objects within the tile would be relative to that center ("RTC coordinates").
While the center positions of the tiles would be 64-bit values, the object positions only need to be 32-bit.
Internally, when rendering an object with RTC coordinates, xeokit first temporarily translates the camera viewing matrix by the object's tile's RTC center, on the CPU, using 64-bit math.
Then xeokit loads the viewing matrix into its WebGL shaders, where math happens at 32-bit precision. Within the shaders, the matrix is effectively down-cast to 32-bit precision, and the object's 32-bit vertex positions are transformed by the matrix.
We see no jittering, because with RTC a detectable loss of GPU accuracy only starts happening to objects as they become very distant from the camera viewpoint, at which point they are too small to be discernible anyway.
RTC Coordinates with Geometry Instancing
To use RTC with SceneModel
geometry instancing, we specify an RTC center for the geometry via its origin
parameter. Then SceneModel
assumes that all meshes that instance that geometry are within the same RTC coordinate system, ie. the meshes position
and rotation
properties are assumed to be relative to the geometry's origin
.
For simplicity, our example's meshes all instance the same geometry. Therefore, our example model has only one RTC center.
Note that the axis-aligned World-space boundary (AABB) of our model is [ -6, -9, -6, 1000000006, -2.5, 1000000006]
.
const origin = [100000000, 0, 100000000];
sceneModel.createGeometry({
id: "box",
primitive: "triangles",
positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
});
sceneModel.createMesh({
id: "leg1",
geometryId: "box",
position: [-4, -6, -4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [1, 0.3, 0.3],
origin: origin
});
sceneModel.createEntity({
meshIds: ["leg1"],
isObject: true
});
sceneModel.createMesh({
id: "leg2",
geometryId: "box",
position: [4, -6, -4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [0.3, 1.0, 0.3],
origin: origin
});
sceneModel.createEntity({
meshIds: ["leg2"],
isObject: true
});
sceneModel.createMesh({
id: "leg3",
geometryId: "box",
position: [4, -6, 4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [0.3, 0.3, 1.0],
origin: origin
});
sceneModel.createEntity({
meshIds: ["leg3"],
isObject: true
});
sceneModel.createMesh({
id: "leg4",
geometryId: "box",
position: [-4, -6, 4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [1.0, 1.0, 0.0],
origin: origin
});
sceneModel.createEntity({
meshIds: ["leg4"],
isObject: true
});
sceneModel.createMesh({
id: "top",
geometryId: "box",
position: [0, -3, 0],
scale: [6, 0.5, 6],
rotation: [0, 0, 0],
color: [1.0, 0.3, 1.0],
origin: origin
});
sceneModel.createEntity({
meshIds: ["top"],
isObject: true
});
RTC Coordinates with Geometry Batching
To use RTC with SceneModel
geometry batching, we specify an RTC center (origin
) for each mesh. For performance, we try to have as many meshes share the same value for origin
as possible. Each mesh's positions
, position
and rotation
properties are assumed to be relative to origin
.
For simplicity, the meshes in our example all share the same RTC center.
The axis-aligned World-space boundary (AABB) of our model is [ -6, -9, -6, 1000000006, -2.5, 1000000006]
.
const origin = [100000000, 0, 100000000];
sceneModel.createMesh({
id: "leg1",
origin: origin, // This mesh's positions and transforms are relative to the RTC center
primitive: "triangles",
positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
position: [-4, -6, -4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [1, 0.3, 0.3]
});
sceneModel.createEntity({
meshIds: ["leg1"],
isObject: true
});
sceneModel.createMesh({
id: "leg2",
origin: origin, // This mesh's positions and transforms are relative to the RTC center
primitive: "triangles",
positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
position: [4, -6, -4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [0.3, 1.0, 0.3]
});
sceneModel.createEntity({
meshIds: ["leg2"],
isObject: true
});
sceneModel.createMesh({
id: "leg3",
origin: origin, // This mesh's positions and transforms are relative to the RTC center
primitive: "triangles",
positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
position: [4, -6, 4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [0.3, 0.3, 1.0]
});
sceneModel.createEntity({
meshIds: ["leg3"],
isObject: true
});
sceneModel.createMesh({
id: "leg4",
origin: origin, // This mesh's positions and transforms are relative to the RTC center
primitive: "triangles",
positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
position: [-4, -6, 4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [1.0, 1.0, 0.0]
});
sceneModel.createEntity({
meshIds: ["leg4"],
isObject: true
});
sceneModel.createMesh({
id: "top",
origin: origin, // This mesh's positions and transforms are relative to the RTC center
primitive: "triangles",
positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
position: [0, -3, 0],
scale: [6, 0.5, 6],
rotation: [0, 0, 0],
color: [1.0, 0.3, 1.0]
});
sceneModel.createEntity({
meshIds: ["top"],
isObject: true
});
Positioning at World-space coordinates
To position a SceneModel at given double-precision World coordinates, we can
configure the origin
of the SceneModel itself. The origin
is a double-precision
3D World-space position at which the SceneModel will be located.
Note that position
is a single-precision offset relative to origin
.
const origin = [100000000, 0, 100000000];
const sceneModel = new SceneModel(viewer.scene, {
id: "table",
isModel: true,
origin: origin, // Everything in this SceneModel is relative to this RTC center
position: [0, 0, 0],
scale: [1, 1, 1],
rotation: [0, 0, 0]
});
sceneModel.createGeometry({
id: "box",
primitive: "triangles",
positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
});
sceneModel.createMesh({
id: "leg1",
geometryId: "box",
position: [-4, -6, -4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [1, 0.3, 0.3]
});
sceneModel.createEntity({
meshIds: ["leg1"],
isObject: true
});
sceneModel.createMesh({
id: "leg2",
geometryId: "box",
position: [4, -6, -4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [0.3, 1.0, 0.3]
});
sceneModel.createEntity({
meshIds: ["leg2"],
isObject: true
});
sceneModel.createMesh({
id: "leg3",
geometryId: "box",
position: [4, -6, 4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [0.3, 0.3, 1.0]
});
sceneModel.createEntity({
meshIds: ["leg3"],
isObject: true
});
sceneModel.createMesh({
id: "leg4",
geometryId: "box",
position: [-4, -6, 4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [1.0, 1.0, 0.0]
});
sceneModel.createEntity({
meshIds: ["leg4"],
isObject: true
});
sceneModel.createMesh({
id: "top",
geometryId: "box",
position: [0, -3, 0],
scale: [6, 0.5, 6],
rotation: [0, 0, 0],
color: [1.0, 0.3, 1.0]
});
sceneModel.createEntity({
meshIds: ["top"],
isObject: true
});
Textures
Loading KTX2 Texture Files into a SceneModel
A SceneModel that is configured with a KTX2TextureTranscoder will allow us to load textures into it from KTX2 buffers or files.
In the example below, we'll create a Viewer, containing a SceneModel configured with a KTX2TextureTranscoder. We'll then programmatically create a simple object within the SceneModel, consisting of a single mesh with a texture loaded from a KTX2 file, which our SceneModel internally transcodes, using its KTX2TextureTranscoder. Note how we configure our KTX2TextureTranscoder with a path to the Basis Universal transcoder WASM module.
const viewer = new Viewer({
canvasId: "myCanvas",
transparent: true
});
viewer.scene.camera.eye = [-21.80, 4.01, 6.56];
viewer.scene.camera.look = [0, -5.75, 0];
viewer.scene.camera.up = [0.37, 0.91, -0.11];
const textureTranscoder = new KTX2TextureTranscoder({
viewer,
transcoderPath: "https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/" // <------ Path to BasisU transcoder module
});
const sceneModel = new SceneModel(viewer.scene, {
id: "myModel",
textureTranscoder // <<-------------------- Configure model with our transcoder
});
sceneModel.createTexture({
id: "myColorTexture",
src: "../assets/textures/compressed/sample_uastc_zstd.ktx2" // <<----- KTX2 texture asset
});
sceneModel.createTexture({
id: "myMetallicRoughnessTexture",
src: "../assets/textures/alpha/crosshatchAlphaMap.jpg" // <<----- JPEG texture asset
});
sceneModel.createTextureSet({
id: "myTextureSet",
colorTextureId: "myColorTexture",
metallicRoughnessTextureId: "myMetallicRoughnessTexture"
});
sceneModel.createMesh({
id: "myMesh",
textureSetId: "myTextureSet",
primitive: "triangles",
positions: [1, 1, 1, ...],
normals: [0, 0, 1, 0, ...],
uv: [1, 0, 0, ...],
indices: [0, 1, 2, ...],
});
sceneModel.createEntity({
id: "myEntity",
meshIds: ["myMesh"]
});
sceneModel.finalize();
Loading KTX2 Textures from ArrayBuffers into a SceneModel
A SceneModel that is configured with a KTX2TextureTranscoder will allow us to load textures into it from KTX2 ArrayBuffers.
In the example below, we'll create a Viewer, containing a SceneModel configured with a KTX2TextureTranscoder. We'll then programmatically create a simple object within the SceneModel, consisting of a single mesh with a texture loaded from a KTX2 ArrayBuffer, which our SceneModel internally transcodes, using its KTX2TextureTranscoder.
const viewer = new Viewer({
canvasId: "myCanvas",
transparent: true
});
viewer.scene.camera.eye = [-21.80, 4.01, 6.56];
viewer.scene.camera.look = [0, -5.75, 0];
viewer.scene.camera.up = [0.37, 0.91, -0.11];
const textureTranscoder = new KTX2TextureTranscoder({
viewer,
transcoderPath: "https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/" // <------ Path to BasisU transcoder module
});
const sceneModel = new SceneModel(viewer.scene, {
id: "myModel",
textureTranscoder // <<-------------------- Configure model with our transcoder
});
utils.loadArraybuffer("../assets/textures/compressed/sample_uastc_zstd.ktx2",(arrayBuffer) => {
sceneModel.createTexture({
id: "myColorTexture",
buffers: [arrayBuffer] // <<----- KTX2 texture asset
});
sceneModel.createTexture({
id: "myMetallicRoughnessTexture",
src: "../assets/textures/alpha/crosshatchAlphaMap.jpg" // <<----- JPEG texture asset
});
sceneModel.createTextureSet({
id: "myTextureSet",
colorTextureId: "myColorTexture",
metallicRoughnessTextureId: "myMetallicRoughnessTexture"
});
sceneModel.createMesh({
id: "myMesh",
textureSetId: "myTextureSet",
primitive: "triangles",
positions: [1, 1, 1, ...],
normals: [0, 0, 1, 0, ...],
uv: [1, 0, 0, ...],
indices: [0, 1, 2, ...],
});
sceneModel.createEntity({
id: "myEntity",
meshIds: ["myMesh"]
});
sceneModel.finalize();
});
Constructor Summary
Public Constructor | ||
public |
constructor(owner: Component, cfg: *) |
Member Summary
Public Members | ||
public get |
Gets the SceneModel's World-space 3D axis-aligned bounding box. Represented by a six-element Float64Array containing the min/max extents of the
axis-aligned volume, ie. |
|
public get |
Sets if backfaces are rendered for this SceneModel. |
|
public set |
Sets if backfaces are rendered for this SceneModel. |
|
public get |
Gets if this SceneModel casts a shadow. |
|
public set |
Sets if this SceneModel casts a shadow. |
|
public get |
Gets if SceneModelEntitys in this SceneModel are clippable. |
|
public set |
Sets if SceneModelEntitys in this SceneModel are clippable. |
|
public get |
Gets if this SceneModel is collidable. |
|
public set |
Sets if SceneModelEntitys in this SceneModel are collidable. |
|
public get |
Gets if color textures are enabled for this SceneModel. |
|
public get |
Gets the RGB colorize color for this SceneModel. |
|
public set |
Sets the RGB colorize color for this SceneModel. |
|
public get |
Gets if this SceneModel is culled from view. |
|
public set |
Sets if this SceneModel is culled from view. |
|
public get |
Configures the appearance of edges of SceneModelEntitys within this SceneModel. |
|
public get |
Gets if any SceneModelEntitys in this SceneModel have edges emphasised. |
|
public set |
Sets if all SceneModelEntitys in this SceneModel have edges emphasised. |
|
public get |
entityList: SceneModelEntity[]: * Gets the list of SceneModelEntitys within this SceneModel. |
|
public get |
Configures the appearance of highlighted SceneModelEntitys within this SceneModel. |
|
public get |
Gets if any SceneModelEntitys in this SceneModel are highlighted. |
|
public set |
Sets if all SceneModelEntitys in this SceneModel are highlighted. |
|
public get |
Returns true to indicate that SceneModel is implements Drawable. |
|
public get |
Returns true to indicate that SceneModel is an Entity. |
|
public get |
Returns |
|
public get |
Returns |
|
public get |
Returns true to indicate that this Component is a SceneModel. |
|
public |
layerList: *[] |
|
public set |
Sets the SceneModel's local modeling transform matrix. Default value is |
|
public get |
Gets the SceneModel's local modeling transform matrix. Default value is |
|
public get |
meshes: * | {}: * The SceneModelMeshes in this SceneModel. |
|
public |
|
|
public get |
The approximate number of line primitives in this SceneModel. |
|
public get |
The approximate number of point primitives in this SceneModel. |
|
public get |
The approximate number of triangle primitives in this SceneModel. |
|
public get |
objects: * | {}: * The SceneModelEntitys in this SceneModel. |
|
public get |
Gets this SceneModel's opacity factor. This is a factor in range |
|
public set |
Sets the opacity factor for this SceneModel. |
|
public get |
Gets the 3D World-space origin for this SceneModel. |
|
public get |
Gets if physically-based rendering (PBR) is enabled for this SceneModel. |
|
public get |
Gets if this SceneModel is pickable. |
|
public set |
Sets if SceneModelEntitys in this SceneModel are pickable. |
|
public set |
Sets the SceneModel's local translation. Default value is |
|
public get |
Gets the SceneModel's local translation. Default value is |
|
public set |
quaternion: Number[] Sets the SceneModel's local rotation quaternion. Default value is |
|
public get |
quaternion: Number[] Gets the SceneModel's local rotation quaternion. Default value is |
|
public get |
Sets if this SceneModel can have shadow cast upon it. |
|
public set |
Sets if this SceneModel can have shadow cast upon it. |
|
public |
renderOrder: * |
|
public set |
Sets the SceneModel's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis. Default value is |
|
public get |
Gets the SceneModel's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis. Default value is |
|
public get |
Gets the SceneModel's local modeling rotation transform matrix. |
|
public get |
Gets the conjugate of the SceneModel's local modeling rotation transform matrix. This is used for RTC view matrix management in renderers. |
|
public get |
Gets if Scalable Ambient Obscurance (SAO) will apply to this SceneModel. |
|
public set |
this set was deprecated.
Sets the SceneModel's local scale. Default value is |
|
public get |
this get was deprecated.
Gets the SceneModel's local scale. Default value is |
|
public get |
Gets if any SceneModelEntitys in this SceneModel are selected. |
|
public set |
Sets if all SceneModelEntitys in this SceneModel are selected. |
|
public get |
Configures the appearance of selected SceneModelEntitys within this SceneModel. |
|
public get |
textureSets: * | {}: * The SceneModelTextureSets in this SceneModel. |
|
public get |
textures: * | {}: * The SceneModelTextures in this SceneModel. |
|
public get |
transforms: * | {}: * The SceneModelTransforms in this SceneModel. |
|
public get |
Gets if any SceneModelEntitys in this SceneModel are visible. |
|
public set |
Sets if this SceneModel is visible. |
|
public get |
Gets the SceneModel's World matrix. |
|
public get |
Gets the SceneModel's World normal matrix. |
|
public get |
Configures the appearance of xrayed SceneModelEntitys within this SceneModel. |
|
public get |
Gets if any SceneModelEntitys in this SceneModel are xrayed. |
|
public set |
Sets if all SceneModelEntitys in this SceneModel are xrayed. |
Method Summary
Public Methods | ||
public |
createEntity(cfg: Object): SceneModelEntity Creates a SceneModelEntity within this SceneModel. |
|
public |
createGeometry(cfg: *): * Creates a reusable geometry within this SceneModel. |
|
public |
createMesh(cfg: object): SceneModelMesh Creates a new SceneModelMesh within this SceneModel. |
|
public |
createQuantizationRange(cfg: *) |
|
public |
createTexture(cfg: *): * Creates a texture within this SceneModel. |
|
public |
createTextureSet(cfg: *): SceneModelTransform Creates a texture set within this SceneModel. |
|
public |
createTransform(cfg: *): SceneModelTransform Creates a new SceneModelTransform within this SceneModel. |
|
public |
destroy() Destroys this SceneModel. |
|
public |
finalize() Finalizes this SceneModel. |
|
public |
Pre-renders all meshes that have been added, even if the SceneModel has not bee finalized yet. |
Inherited Summary
From class Component | ||
public get |
The Component that owns the lifecycle of this Component, if any. |
|
public |
True as soon as this Component has been destroyed |
|
public |
ID of this Component, unique within the Scene. |
|
public |
meta: * Arbitrary, user-defined metadata on this component. |
|
public |
The parent Scene that contains this Component. |
|
public |
The viewer that contains this Scene. |
|
public |
clear() Destroys all Components that are owned by this. |
|
public |
destroy() Destroys this component. |
|
public |
Logs an error for this component to the JavaScript console. |
|
public |
Fires an event on this component. |
|
public |
Returns true if there are any subscribers to the given event on this component. |
|
public |
Tests if this component is of the given type, or is a subclass of the given type. |
|
public |
Logs a console debugging message for this component. |
|
public |
Cancels an event subscription that was previously made with Component#on or Component#once. |
|
public |
Subscribes to an event on this component. |
|
public |
Subscribes to the next occurrence of the given event, then un-subscribes as soon as the event is subIdd. |
|
public |
scheduleTask(task: *) Schedule a task to perform on the next browser interval |
|
public |
Logs a warning for this component to the JavaScript console. |
Public Constructors
public constructor(owner: Component, cfg: *) source
Override:
Component#constructorParams:
Name | Type | Attribute | Description |
owner | Component | Owner component. When destroyed, the owner will destroy this component as well. |
|
cfg | * |
|
Configs |
cfg.id | String |
|
Optional ID, unique among all components in the parent scene, generated automatically when omitted. |
cfg.isModel | Boolean |
|
Specify |
cfg.origin | Number[] |
|
World-space double-precision 3D origin. |
cfg.position | Number[] |
|
Local, single-precision 3D position, relative to the origin parameter. |
cfg.scale | Number[] |
|
Local scale. |
cfg.rotation | Number[] |
|
Local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis. |
cfg.matrix | Number[] |
|
|
cfg.visible | Boolean |
|
Indicates if the SceneModel is initially visible. |
cfg.culled | Boolean |
|
Indicates if the SceneModel is initially culled from view. |
cfg.pickable | Boolean |
|
Indicates if the SceneModel is initially pickable. |
cfg.clippable | Boolean |
|
Indicates if the SceneModel is initially clippable. |
cfg.collidable | Boolean |
|
Indicates if the SceneModel is initially included in boundary calculations. |
cfg.xrayed | Boolean |
|
Indicates if the SceneModel is initially xrayed. |
cfg.highlighted | Boolean |
|
Indicates if the SceneModel is initially highlighted. |
cfg.selected | Boolean |
|
Indicates if the SceneModel is initially selected. |
cfg.edges | Boolean |
|
Indicates if the SceneModel's edges are initially emphasized. |
cfg.colorize | Number[] |
|
SceneModel's initial RGB colorize color, multiplies by the rendered fragment colors. |
cfg.opacity | Number |
|
SceneModel's initial opacity factor, multiplies by the rendered fragment alpha. |
cfg.backfaces | Number |
|
When we set this |
cfg.saoEnabled | Boolean |
|
Indicates if Scalable Ambient Obscurance (SAO) will apply to this SceneModel. SAO is configured by the Scene's SAO component. |
cfg.pbrEnabled | Boolean |
|
Indicates if physically-based rendering (PBR) will apply to the SceneModel when Scene#pbrEnabled is |
cfg.colorTextureEnabled | Boolean |
|
Indicates if base color textures will be rendered for the SceneModel when Scene#colorTextureEnabled is |
cfg.edgeThreshold | Number |
|
When xraying, highlighting, selecting or edging, this is the threshold angle between normals of adjacent triangles, below which their shared wireframe edge is not drawn. |
cfg.maxGeometryBatchSize | Number |
|
Maximum geometry batch size, as number of vertices. This is optionally supplied
to limit the size of the batched geometry arrays that SceneModel internally creates for batched geometries.
A lower value means less heap allocation/de-allocation while creating/loading batched geometries, but more draw calls and
slower rendering speed. A high value means larger heap allocation/de-allocation while creating/loading, but less draw calls
and faster rendering speed. It's recommended to keep this somewhere roughly between |
cfg.textureTranscoder | TextureTranscoder |
|
Transcoder that will be used internally by SceneModel#createTexture
to convert transcoded texture data. Only required when we'll be providing transcoded data
to SceneModel#createTexture. We assume that all transcoded texture data added to a |
cfg.dtxEnabled | Boolean |
|
When |
cfg.renderOrder | Number |
|
Specifies the rendering order for this SceneModel. This is used to control the order in which SceneModels are drawn when they have transparent objects, to give control over the order in which those objects are blended within the transparent render pass. |
Public Members
public get aabb: Number[] source
Gets the SceneModel's World-space 3D axis-aligned bounding box.
Represented by a six-element Float64Array containing the min/max extents of the
axis-aligned volume, ie. [xmin, ymin,zmin,xmax,ymax, zmax]
.
public get backfaces: Boolean source
Sets if backfaces are rendered for this SceneModel.
Default is false
.
public set backfaces: Boolean source
Sets if backfaces are rendered for this SceneModel.
Default is false
.
When we set this true
, then backfaces are always rendered for this SceneModel.
When we set this false
, then we allow the Viewer to decide whether to render backfaces. In this case,
the Viewer will:
- hide backfaces on watertight meshes,
- show backfaces on open meshes, and
- always show backfaces on meshes when we slice them open with SectionPlanes.
public get clippable: Boolean source
Gets if SceneModelEntitys in this SceneModel are clippable.
Clipping is done by the SectionPlanes in Scene#sectionPlanes.
public set clippable: Boolean source
Sets if SceneModelEntitys in this SceneModel are clippable.
Clipping is done by the SectionPlanes in Scene#sectionPlanes.
public get colorTextureEnabled: Boolean source
Gets if color textures are enabled for this SceneModel.
Only works when Scene#colorTextureEnabled is also true.
public get colorize: Number[] source
Gets the RGB colorize color for this SceneModel.
Each element of the color is in range [0..1]
.
public set colorize: Number[] source
Sets the RGB colorize color for this SceneModel.
Multiplies by rendered fragment colors.
Each element of the color is in range [0..1]
.
public get culled: Boolean source
Gets if this SceneModel is culled from view.
The SceneModel is only rendered when SceneModel#visible is true and SceneModel#culled is false.
public set culled: Boolean source
Sets if this SceneModel is culled from view.
The SceneModel is only rendered when SceneModel#visible is true and SceneModel#culled is false.
public get edgeMaterial: EdgeMaterial source
Configures the appearance of edges of SceneModelEntitys within this SceneModel.
This is the Scene#edgeMaterial.
public get edges: Boolean source
Gets if any SceneModelEntitys in this SceneModel have edges emphasised.
public set edges: Boolean source
Sets if all SceneModelEntitys in this SceneModel have edges emphasised.
public get entityList: SceneModelEntity[]: * source
Gets the list of SceneModelEntitys within this SceneModel.
public get highlightMaterial: EmphasisMaterial source
Configures the appearance of highlighted SceneModelEntitys within this SceneModel.
This is the Scene#highlightMaterial.
public get highlighted: Boolean source
Gets if any SceneModelEntitys in this SceneModel are highlighted.
public set highlighted: Boolean source
Sets if all SceneModelEntitys in this SceneModel are highlighted.
public get isDrawable: Boolean source
Returns true to indicate that SceneModel is implements Drawable.
public get isModel: Boolean source
Returns true
if this SceneModel represents a model.
When true
the SceneModel will be registered by SceneModel#id in
Scene#models and may also have a MetaObject with matching MetaObject#id.
public get isObject: Boolean source
Returns false
to indicate that SceneModel never represents an object.
public get isPerformanceModel: Boolean source
Returns true to indicate that this Component is a SceneModel.
public layerList: *[] source
public set matrix: Number[] source
Sets the SceneModel's local modeling transform matrix.
Default value is [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
.
public get matrix: Number[] source
Gets the SceneModel's local modeling transform matrix.
Default value is [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
.
public get meshes: * | {}: * source
The SceneModelMeshes in this SceneModel.
Each {@SceneModelMesh} is stored here against its SceneModelMesh.id.
Return:
* | {} |
public get numTriangles: Number source
The approximate number of triangle primitives in this SceneModel.
public get objects: * | {}: * source
The SceneModelEntitys in this SceneModel.
Each {#link SceneModelEntity} in this SceneModel that represents an object is stored here against its SceneModelTransform.id.
Return:
* | {} |
public get opacity: Number source
Gets this SceneModel's opacity factor.
This is a factor in range [0..1]
which multiplies by the rendered fragment alphas.
public set opacity: Number source
Sets the opacity factor for this SceneModel.
This is a factor in range [0..1]
which multiplies by the rendered fragment alphas.
public get origin: Float64Array source
Gets the 3D World-space origin for this SceneModel.
Each SceneModelMesh.origin, if supplied, is relative to this origin.
Default value is [0,0,0]
.
public get pbrEnabled: Boolean source
Gets if physically-based rendering (PBR) is enabled for this SceneModel.
Only works when Scene#pbrEnabled is also true.
public get pickable: Boolean source
Gets if this SceneModel is pickable.
Picking is done via calls to Scene#pick.
public set pickable: Boolean source
Sets if SceneModelEntitys in this SceneModel are pickable.
Picking is done via calls to Scene#pick.
public set position: Number[] source
Sets the SceneModel's local translation.
Default value is [0,0,0]
.
public get position: Number[] source
Gets the SceneModel's local translation.
Default value is [0,0,0]
.
public set quaternion: Number[] source
Sets the SceneModel's local rotation quaternion.
Default value is [0,0,0,1]
.
public get quaternion: Number[] source
Gets the SceneModel's local rotation quaternion.
Default value is [0,0,0,1]
.
public renderOrder: * source
public set rotation: Number[] source
Sets the SceneModel's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.
Default value is [0,0,0]
.
public get rotation: Number[] source
Gets the SceneModel's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.
Default value is [0,0,0]
.
public get rotationMatrix: Number[] source
Gets the SceneModel's local modeling rotation transform matrix.
public get rotationMatrixConjugate: Number[] source
Gets the conjugate of the SceneModel's local modeling rotation transform matrix.
This is used for RTC view matrix management in renderers.
public get saoEnabled: Boolean source
Gets if Scalable Ambient Obscurance (SAO) will apply to this SceneModel.
SAO is configured by the Scene's SAO component.
Only works when SAO#enabled is also true.
public set scale: Number[] source
Sets the SceneModel's local scale.
Default value is [1,1,1]
.
public get scale: Number[] source
Gets the SceneModel's local scale.
Default value is [1,1,1]
.
public get selectedMaterial: EmphasisMaterial source
Configures the appearance of selected SceneModelEntitys within this SceneModel.
This is the Scene#selectedMaterial.
public get textureSets: * | {}: * source
The SceneModelTextureSets in this SceneModel.
Each SceneModelTextureSet is stored here against its SceneModelTextureSet.id.
Return:
* | {} |
public get textures: * | {}: * source
The SceneModelTextures in this SceneModel.
- Each SceneModelTexture is created with SceneModel.createTexture.
- Each SceneModelTexture is stored here against its SceneModelTexture.id.
Return:
* | {} |
public get transforms: * | {}: * source
The SceneModelTransforms in this SceneModel.
Each {#link SceneModelTransform} is stored here against its SceneModelTransform.id.
Return:
* | {} |
public get visible: Boolean source
Gets if any SceneModelEntitys in this SceneModel are visible.
The SceneModel is only rendered when SceneModel#visible is true
and SceneModel#culled is false
.
public set visible: Boolean source
Sets if this SceneModel is visible.
The SceneModel is only rendered when SceneModel#visible is true
and SceneModel#culled is false
.
*
public get worldMatrix: Number[] source
Gets the SceneModel's World matrix.
Properties:
Name | Type | Attribute | Description |
worldMatrix | * |
public get xrayMaterial: EmphasisMaterial source
Configures the appearance of xrayed SceneModelEntitys within this SceneModel.
This is the Scene#xrayMaterial.
Public Methods
public createEntity(cfg: Object): SceneModelEntity source
Creates a SceneModelEntity within this SceneModel.
- Gives the SceneModelEntity one or more SceneModelMeshes previously created with SceneModel#createMesh. A SceneModelMesh can only belong to one SceneModelEntity, so you'll get an error if you try to reuse a mesh among multiple SceneModelEntitys.
- The SceneModelEntity can have a SceneModelTextureSet, previously created with SceneModel#createTextureSet. A SceneModelTextureSet can belong to multiple SceneModelEntitys.
- The SceneModelEntity can have a geometry, previously created with SceneModel#createTextureSet. A geometry is a "virtual component" and can belong to multiple SceneModelEntitys.
Params:
Name | Type | Attribute | Description |
cfg | Object | SceneModelEntity configuration. |
|
cfg.id | String | Optional ID for the new SceneModelEntity. Must not clash with any existing components within the Scene. |
|
cfg.meshIds | String[] | IDs of one or more meshes created previously with {@link SceneModel@createMesh}. |
|
cfg.isObject | Boolean |
|
Set |
cfg.visible | Boolean |
|
Indicates if the SceneModelEntity is initially visible. |
cfg.culled | Boolean |
|
Indicates if the SceneModelEntity is initially culled from view. |
cfg.pickable | Boolean |
|
Indicates if the SceneModelEntity is initially pickable. |
cfg.clippable | Boolean |
|
Indicates if the SceneModelEntity is initially clippable. |
cfg.collidable | Boolean |
|
Indicates if the SceneModelEntity is initially included in boundary calculations. |
cfg.castsShadow | Boolean |
|
Indicates if the SceneModelEntity initially casts shadows. |
cfg.receivesShadow | Boolean |
|
Indicates if the SceneModelEntity initially receives shadows. |
cfg.xrayed | Boolean |
|
Indicates if the SceneModelEntity is initially xrayed. XRayed appearance is configured by SceneModel#xrayMaterial. |
cfg.highlighted | Boolean |
|
Indicates if the SceneModelEntity is initially highlighted. Highlighted appearance is configured by SceneModel#highlightMaterial. |
cfg.selected | Boolean |
|
Indicates if the SceneModelEntity is initially selected. Selected appearance is configured by SceneModel#selectedMaterial. |
cfg.edges | Boolean |
|
Indicates if the SceneModelEntity's edges are initially emphasized. Edges appearance is configured by SceneModel#edgeMaterial. |
public createGeometry(cfg: *): * source
Creates a reusable geometry within this SceneModel.
We can then supply the geometry ID to SceneModel#createMesh when we want to create meshes that instance the geometry.
Params:
Name | Type | Attribute | Description |
cfg | * | Geometry properties. |
|
cfg.id | String | Number | Mandatory ID for the geometry, to refer to with SceneModel#createMesh. |
|
cfg.primitive | String | The primitive type. Accepted values are 'points', 'lines', 'triangles', 'solid' and 'surface'. |
|
cfg.positions | Number[] |
|
Flat array of uncompressed 3D vertex positions positions. Required for all primitive types. Overridden by |
cfg.positionsCompressed | Number[] |
|
Flat array of quantized 3D vertex positions. Overrides |
cfg.positionsDecodeMatrix | Number[] |
|
A 4x4 matrix for decompressing |
cfg.normals | Number[] |
|
Flat array of normal vectors. Only used with "triangles", "solid" and "surface" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals. |
cfg.normalsCompressed | Number[] |
|
Flat array of oct-encoded normal vectors. Overrides |
cfg.colors | Number[] |
|
Flat array of uncompressed RGBA vertex colors, as float values in range |
cfg.colorsCompressed | Number[] |
|
Flat array of compressed RGBA vertex colors, as unsigned short integers in range |
cfg.uv | Number[] |
|
Flat array of uncompressed vertex UV coordinates. Only used with "triangles", "solid" and "surface" primitives. Required for textured rendering. |
cfg.uvCompressed | Number[] |
|
Flat array of compressed vertex UV coordinates. Only used with "triangles", "solid" and "surface" primitives. Overrides |
cfg.uvDecodeMatrix | Number[] |
|
A 3x3 matrix for decompressing |
cfg.indices | Number[] |
|
Array of primitive connectivity indices. Not required for |
cfg.edgeIndices | Number[] |
|
Array of edge line indices. Used only with 'triangles', 'solid' and 'surface' primitives. Automatically generated internally if not supplied, using the optional |
Return:
* |
public createMesh(cfg: object): SceneModelMesh source
Creates a new SceneModelMesh within this SceneModel.
- It prepares and saves data for a SceneModelMesh SceneModel#meshes creation. SceneModelMesh will be created only once the SceneModelEntity (which references this particular SceneModelMesh) will be created.
- The SceneModelMesh can either define its own geometry or share it with other SceneModelMeshes. To define own geometry, provide the various geometry arrays to this method. To share a geometry, provide the ID of a geometry created earlier with SceneModel#createGeometry.
- If you accompany the arrays with an
origin
, thencreateMesh()
will assume that the geometrypositions
are in relative-to-center (RTC) coordinates, withorigin
being the origin of their RTC coordinate system.
Params:
Name | Type | Attribute | Description |
cfg | object | Object properties. |
|
cfg.id | String | Mandatory ID for the new mesh. Must not clash with any existing components within the Scene. |
|
cfg.textureSetId | String | Number |
|
ID of a SceneModelTextureSet previously created with SceneModel#createTextureSet. |
cfg.transformId | String | Number |
|
ID of a SceneModelTransform to instance, previously created with SceneModel#createTransform. Overrides all other transform parameters given to this method. |
cfg.geometryId | String | Number |
|
ID of a geometry to instance, previously created with SceneModel#createGeometry. Overrides all other geometry parameters given to this method. |
cfg.primitive | String | The primitive type. Accepted values are 'points', 'lines', 'triangles', 'solid' and 'surface'. |
|
cfg.positions | Number[] |
|
Flat array of uncompressed 3D vertex positions positions. Required for all primitive types. Overridden by |
cfg.positionsCompressed | Number[] |
|
Flat array of quantized 3D vertex positions. Overrides |
cfg.positionsDecodeMatrix | Number[] |
|
A 4x4 matrix for decompressing |
cfg.normals | Number[] |
|
Flat array of normal vectors. Only used with "triangles", "solid" and "surface" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals. |
cfg.normalsCompressed | Number[] |
|
Flat array of oct-encoded normal vectors. Overrides |
cfg.colors | Number[] |
|
Flat array of uncompressed RGBA vertex colors, as float values in range |
cfg.colorsCompressed | Number[] |
|
Flat array of compressed RGBA vertex colors, as unsigned short integers in range |
cfg.uv | Number[] |
|
Flat array of uncompressed vertex UV coordinates. Only used with "triangles", "solid" and "surface" primitives. Required for textured rendering. |
cfg.uvCompressed | Number[] |
|
Flat array of compressed vertex UV coordinates. Only used with "triangles", "solid" and "surface" primitives. Overrides |
cfg.uvDecodeMatrix | Number[] |
|
A 3x3 matrix for decompressing |
cfg.indices | Number[] |
|
Array of primitive connectivity indices. Not required for |
cfg.edgeIndices | Number[] |
|
Array of edge line indices. Used only with 'triangles', 'solid' and 'surface' primitives. Automatically generated internally if not supplied, using the optional |
cfg.origin | Number[] |
|
Optional geometry origin, relative to SceneModel#origin. When this is given, then |
cfg.position | Number[] |
|
Local 3D position of the mesh. Overridden by |
cfg.scale | Number[] |
|
Scale of the mesh. Overridden by |
cfg.rotation | Number[] |
|
Rotation of the mesh as Euler angles given in degrees, for each of the X, Y and Z axis. Overridden by |
cfg.quaternion | Number[] |
|
Rotation of the mesh as a quaternion. Overridden by |
cfg.matrix | Number[] |
|
Mesh modelling transform matrix. Overrides the |
cfg.color | Number[] |
|
RGB color in range |
cfg.opacity | Number |
|
Opacity in range |
cfg.metallic | Number |
|
Metallic factor in range |
cfg.roughness | Number |
|
Roughness factor in range |
public createQuantizationRange(cfg: *) source
Params:
Name | Type | Attribute | Description |
cfg | * |
public createTexture(cfg: *): * source
Creates a texture within this SceneModel.
We can then supply the texture ID to SceneModel#createTextureSet when we want to create texture sets that use the texture.
Params:
Name | Type | Attribute | Description |
cfg | * | Texture properties. |
|
cfg.id | String | Number | Mandatory ID for the texture, to refer to with SceneModel#createTextureSet. |
|
cfg.src | String |
|
Image file for the texture. Assumed to be transcoded if not having a recognized image file
extension (jpg, jpeg, png etc.). If transcoded, then assumes |
cfg.buffers | ArrayBuffer[] |
|
Transcoded texture data. Assumes |
cfg.image | HTMLImageElement |
|
HTML Image object to load into this texture. Overrides |
cfg.minFilter | Number |
|
How the texture is sampled when a texel covers less than one pixel. Supported values are LinearMipmapLinearFilter, LinearMipMapNearestFilter, NearestMipMapNearestFilter, NearestMipMapLinearFilter and LinearMipMapLinearFilter. |
cfg.magFilter | Number |
|
How the texture is sampled when a texel covers more than one pixel. Supported values are LinearFilter and NearestFilter. |
cfg.wrapS | Number |
|
Wrap parameter for texture coordinate S. Supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. |
cfg.wrapT | Number |
|
Wrap parameter for texture coordinate T. Supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping.. |
cfg.wrapR | Number |
|
Wrap parameter for texture coordinate R. Supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. |
cfg.flipY | Boolean |
|
Flips this Texture's source data along its vertical axis when |
cfg.encoding | Number |
|
Encoding format. Supported values are LinearEncoding and sRGBEncoding. |
Return:
* |
public createTextureSet(cfg: *): SceneModelTransform source
Creates a texture set within this SceneModel.
- Stores the new SceneModelTextureSet in SceneModel#textureSets.
A texture set is a collection of textures that can be shared among meshes. We can then supply the texture set ID to SceneModel#createMesh when we want to create meshes that use the texture set.
The textures can work as a texture atlas, where each mesh can have geometry UVs that index a different part of the textures. This allows us to minimize the number of textures in our models, which means faster rendering.
Params:
Name | Type | Attribute | Description |
cfg | * | Texture set properties. |
|
cfg.id | String | Number | Mandatory ID for the texture set, to refer to with SceneModel#createMesh. |
|
cfg.colorTextureId | * |
|
ID of RGBA base color texture, with color in RGB and alpha in A. |
cfg.metallicRoughnessTextureId | * |
|
ID of RGBA metal-roughness texture, with the metallic factor in R, and roughness factor in G. |
cfg.normalsTextureId | * |
|
ID of RGBA normal map texture, with normal map vectors in RGB. |
cfg.emissiveTextureId | * |
|
ID of RGBA emissive map texture, with emissive color in RGB. |
cfg.occlusionTextureId | * |
|
ID of RGBA occlusion map texture, with occlusion factor in R. |
public createTransform(cfg: *): SceneModelTransform source
Creates a new SceneModelTransform within this SceneModel.
- Stores the new SceneModelTransform in SceneModel#transforms.
- Can be connected into hierarchies
- Each SceneModelTransform can be used by unlimited SceneModelMeshes
Params:
Name | Type | Attribute | Description |
cfg | * | Transform creation parameters. |
|
cfg.id | String | Mandatory ID for the new transform. Must not clash with any existing components within the Scene. |
|
cfg.parentTransformId | String |
|
ID of a parent transform, previously created with SceneModel#createTextureSet. |
cfg.position | Number[] |
|
Local 3D position of the mesh. Overridden by |
cfg.scale | Number[] |
|
Scale of the transform. |
cfg.rotation | Number[] |
|
Rotation of the transform as Euler angles given in degrees, for each of the X, Y and Z axis. |
cfg.matrix | Number[] |
|
Modelling transform matrix. Overrides the |
public finalize() source
Finalizes this SceneModel.
Once finalized, you can't add anything more to this SceneModel.