-
Notifications
You must be signed in to change notification settings - Fork 229
/
gltf_utils.js
85 lines (70 loc) · 2.23 KB
/
gltf_utils.js
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
import { vec3 } from 'gl-matrix';
import { jsToGl } from './utils.js';
function getSceneExtents(gltf, sceneIndex, outMin, outMax)
{
for (const i of [0, 1, 2])
{
outMin[i] = Number.POSITIVE_INFINITY;
outMax[i] = Number.NEGATIVE_INFINITY;
}
const scene = gltf.scenes[sceneIndex];
let nodeIndices = scene.nodes.slice();
while(nodeIndices.length > 0)
{
const node = gltf.nodes[nodeIndices.pop()];
nodeIndices = nodeIndices.concat(node.children);
if (node.mesh === undefined)
{
continue;
}
const mesh = gltf.meshes[node.mesh];
if (mesh.primitives === undefined)
{
continue;
}
for (const primitive of mesh.primitives)
{
const attribute = primitive.glAttributes.find(a => a.attribute == "POSITION");
if (attribute === undefined)
{
continue;
}
const accessor = gltf.accessors[attribute.accessor];
const assetMin = vec3.create();
const assetMax = vec3.create();
getExtentsFromAccessor(accessor, node.worldTransform, assetMin, assetMax);
for (const i of [0, 1, 2])
{
outMin[i] = Math.min(outMin[i], assetMin[i]);
outMax[i] = Math.max(outMax[i], assetMax[i]);
}
}
}
}
function getExtentsFromAccessor(accessor, worldTransform, outMin, outMax)
{
const boxMin = vec3.create();
let min = jsToGl(accessor.min);
if (accessor.normalized){
vec3.normalize(min, min);
}
vec3.transformMat4(boxMin, min, worldTransform);
const boxMax = vec3.create();
let max = jsToGl(accessor.max);
if (accessor.normalized){
vec3.normalize(max, max);
}
vec3.transformMat4(boxMax, max, worldTransform);
const center = vec3.create();
vec3.add(center, boxMax, boxMin);
vec3.scale(center, center, 0.5);
const centerToSurface = vec3.create();
vec3.sub(centerToSurface, boxMax, center);
const radius = vec3.length(centerToSurface);
for (const i of [0, 1, 2])
{
outMin[i] = center[i] - radius;
outMax[i] = center[i] + radius;
}
}
export { getSceneExtents };