-
Notifications
You must be signed in to change notification settings - Fork 48
/
ExtInstanceFeaturesDemo.ts
139 lines (113 loc) · 4.77 KB
/
ExtInstanceFeaturesDemo.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import { Accessor } from "@gltf-transform/core";
import { Document } from "@gltf-transform/core";
import { NodeIO } from "@gltf-transform/core";
import { EXTMeshGPUInstancing } from "@gltf-transform/extensions";
import { EXTInstanceFeatures } from "3d-tiles-tools";
import { InstanceFeaturesUtils } from "3d-tiles-tools";
function createMesh(document: Document) {
const root = document.getRoot();
const buffer = root.listBuffers()[0];
// prettier-ignore
const positions = [
0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
1.0, 1.0, 0.0,
];
const positionsAccessor = document.createAccessor();
positionsAccessor.setArray(new Float32Array(positions));
positionsAccessor.setType(Accessor.Type.VEC3);
positionsAccessor.setBuffer(buffer);
const indices = [0, 1, 2, 1, 3, 2];
const indicesAccessor = document.createAccessor();
indicesAccessor.setArray(new Uint16Array(indices));
indicesAccessor.setType(Accessor.Type.SCALAR);
indicesAccessor.setBuffer(buffer);
const primitive = document.createPrimitive();
primitive.setIndices(indicesAccessor);
primitive.setAttribute("POSITION", positionsAccessor);
const mesh = document.createMesh();
mesh.addPrimitive(primitive);
return mesh;
}
async function createExampleDocument(): Promise<Document> {
// Prepare the document with a single buffer and a single
// node with a single mesh in a single scene
const document = new Document();
const buffer = document.createBuffer();
const node = document.createNode();
const scene = document.createScene();
scene.addChild(node);
const mesh = createMesh(document);
node.setMesh(mesh);
// Create the EXT_mesh_gpu_instancing and the
// EXT_instance_features extension, and assign
// them to the document
const extMeshGPUInstancing = document.createExtension(EXTMeshGPUInstancing);
extMeshGPUInstancing.setRequired(true);
const extInstanceFeatures = document.createExtension(EXTInstanceFeatures);
// Create an accessor containing one ID for each instance
const ids = [12, 23, 34, 45];
const accessor = document.createAccessor();
accessor.setBuffer(buffer);
accessor.setType(Accessor.Type.SCALAR);
accessor.setArray(new Uint16Array(ids));
// Create an accessor containing the translations of the instances
// prettier-ignore
const translations = [
0.0, 0.0, 0.0,
2.0, 0.0, 0.0,
0.0, 2.0, 0.0,
2.0, 2.0, 0.0,
];
const translationsAccessor = document.createAccessor();
translationsAccessor.setArray(new Float32Array(translations));
translationsAccessor.setType(Accessor.Type.VEC3);
translationsAccessor.setBuffer(buffer);
// Create the EXT_mesh_gpu_instancing extension, set
// the translations and IDs of the instances, and
// assign the extension object to the node
const meshGpuInstancing = extMeshGPUInstancing.createInstancedMesh();
meshGpuInstancing.setAttribute("TRANSLATION", translationsAccessor);
const attributeNumber = 0;
meshGpuInstancing.setAttribute(`_FEATURE_ID_${attributeNumber}`, accessor);
node.setExtension("EXT_mesh_gpu_instancing", meshGpuInstancing);
// Create a `FeatureId` object. This object indicates that the IDs
// are stored in the attribute `_FEATURE_ID_${attributeNumber}`
const featureIdFromAttribute = extInstanceFeatures.createFeatureId();
featureIdFromAttribute.setFeatureCount(new Set(ids).size);
featureIdFromAttribute.setAttribute(attributeNumber);
// Create a `InstanceFeatures` object that contains the
// created `FeatureID` objects, and store it as an
// extension object in the `Node`
const instanceFeatures = extInstanceFeatures.createInstanceFeatures();
instanceFeatures.addFeatureId(featureIdFromAttribute);
node.setExtension("EXT_instance_features", instanceFeatures);
return document;
}
async function runCreationExample() {
const document = await createExampleDocument();
// Create an IO object and register the extensions
const io = new NodeIO();
io.registerExtensions([EXTMeshGPUInstancing]);
io.registerExtensions([EXTInstanceFeatures]);
// Write the document and print its JSON to the console
const written = await io.writeJSON(document);
console.log(JSON.stringify(written.json, null, 2));
}
async function runReadingExample() {
// Create the example document, write it into
// a GLB buffer, and read a new document from it
const inputDocument = await createExampleDocument();
const io = new NodeIO();
io.registerExtensions([EXTMeshGPUInstancing]);
io.registerExtensions([EXTInstanceFeatures]);
const glb = await io.writeBinary(inputDocument);
const document = await io.readBinary(glb);
// Print information about the feature IDs in the document:
const s = InstanceFeaturesUtils.createInstanceFeaturesInfoString(document);
console.log("Feature IDs:");
console.log(s);
}
runCreationExample();
runReadingExample();