UNPKG

x3d-tidy

Version:

X3D Converter, Beautifier and Minimizer

98 lines (77 loc) 2.66 kB
"use strict"; const X3D = require ("x_ite-node"), Traverse = require ("x3d-traverse") (X3D); module .exports = function inferProfileAndComponents (scene) { const browser = scene .getBrowser (), usedComponents = getUsedComponents (scene), profileAndComponents = getProfileAndComponentsFromUsedComponents (browser, usedComponents); setProfile (scene, profileAndComponents .profile); setComponents (scene, profileAndComponents .components); } function getUsedComponents (scene) { const components = new Map (); for (const object of scene .traverse (Traverse .PROTO_DECLARATIONS | Traverse .PROTO_DECLARATION_BODY | Traverse .ROOT_NODES | Traverse .PROTOTYPE_INSTANCES)) { if (!(object instanceof X3D .SFNode)) continue; const node = object .getValue (), componentInfo = node .getComponentInfo (); if (components .get (componentInfo .name) ?? 0 < componentInfo .level) components .set (componentInfo .name, componentInfo .level); } return components; } function getProfileAndComponentsFromUsedComponents (browser, usedComponents) { const profiles = ["Interchange", "Interactive", "Immersive", "Full"] .map (name => { return { profile: browser .getProfile (name), components: new Map (usedComponents) }; }); profiles .forEach (({ profile, components }) => { for (const component of profile .components) { const level = components .get (component .name); if (level === undefined) continue; if (level > component .level) continue; components .delete (component .name); } }); const { object } = profiles .reduce ((min, object) => { const count = new Set ([ ... [... object .profile .components] .map (component => component .name), ... object .components .keys () ]) .size; return min .count < count ? min : { count, object, }; }, { count: Number .POSITIVE_INFINITY }); return { profile: object .profile, components: Array .from (object .components .keys ()) .sort () .map (name => browser .getComponent (name, object .components .get (name))), }; } function setProfile (scene, profile) { scene .setProfile (profile); } function setComponents (scene, components) { const oldComponents = Array .from (scene .getComponents ()); for (const component of oldComponents) scene .removeComponent (component .name); for (const component of components) scene .addComponent (component); }