computeBounds top-level property
@param {BufferGeometry} geometry @param {GLTF.Primitive} primitiveDef @param {GLTFParser} parser
Implementation
Function computeBounds = (geometry, Map<String, dynamic> primitiveDef, GLTFParser parser) {
Map<String, dynamic> attributes = primitiveDef["attributes"];
var box = Box3(null, null);
if (attributes["POSITION"] != null) {
var accessor = parser.json["accessors"][attributes["POSITION"]];
var min = accessor["min"];
var max = accessor["max"];
// glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.
if (min != null && max != null) {
box.set(Vector3(min[0].toDouble(), min[1].toDouble(), min[2].toDouble()),
Vector3(max[0].toDouble(), max[1].toDouble(), max[2].toDouble()));
// todo normalized is bool ? int ?
if (accessor["normalized"] != null && accessor["normalized"] != false && accessor["normalized"] != 0) {
var boxScale = getNormalizedComponentScale(webGlComponentTypes[accessor.componentType]);
box.min.multiplyScalar(boxScale);
box.max.multiplyScalar(boxScale);
}
} else {
print('THREE.GLTFLoader: Missing min/max properties for accessor POSITION.');
return;
}
} else {
return;
}
var targets = primitiveDef["targets"];
if (targets != null) {
var maxDisplacement = Vector3.init();
var vector = Vector3.init();
for (var i = 0, il = targets.length; i < il; i++) {
var target = targets[i];
if (target["POSITION"] != null) {
var accessor = parser.json["accessors"][target["POSITION"]];
var min = accessor["min"];
var max = accessor["max"];
// glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.
if (min != null && max != null) {
// we need to get max of absolute components because target weight is [-1,1]
vector.setX(Math.max(Math.abs(min[0]).toDouble(), Math.abs(max[0])).toDouble());
vector.setY(Math.max(Math.abs(min[1]).toDouble(), Math.abs(max[1])).toDouble());
vector.setZ(Math.max(Math.abs(min[2]).toDouble(), Math.abs(max[2])).toDouble());
if (accessor["normalized"] == true) {
var boxScale = getNormalizedComponentScale(webGlComponentTypes[accessor.componentType]);
vector.multiplyScalar(boxScale);
}
// Note: this assumes that the sum of all weights is at most 1. This isn't quite correct - it's more conservative
// to assume that each target can have a max weight of 1. However, for some use cases - notably, when morph targets
// are used to implement key-frame animations and as such only two are active at a time - this results in very large
// boxes. So for now we make a box that's sometimes a touch too small but is hopefully mostly of reasonable size.
maxDisplacement.max(vector);
} else {
print('THREE.GLTFLoader: Missing min/max properties for accessor POSITION.');
}
}
}
// As per comment above this box isn't conservative, but has a reasonable size for a very large number of morph targets.
box.expandByVector(maxDisplacement);
}
geometry.boundingBox = box;
var sphere = Sphere(null, null);
box.getCenter(sphere.center);
sphere.radius = box.min.distanceTo(box.max) / 2;
geometry.boundingSphere = sphere;
};