UNPKG

@xeokit/xeokit-sdk

Version:

3D BIM IFC Viewer SDK for AEC engineering applications. Open Source JavaScript Toolkit based on pure WebGL for top performance, real-world coordinates and full double precision

129 lines (114 loc) 4.26 kB
import {utils} from '../../utils.js'; import {K3D} from '../../libs/k3d.js'; /** * @desc Loads {@link Geometry} from OBJ. * * ## Usage * * In the example below we'll create a {@link Mesh} with {@link MetallicMaterial} and {@link ReadableGeometry} loaded from OBJ. * * ````javascript * import {Viewer, Mesh, loadOBJGeometry, ReadableGeometry, * MetallicMaterial, Texture} from "xeokit-sdk.es.js"; * * const viewer = new Viewer({ * canvasId: "myCanvas" * }); * * viewer.scene.camera.eye = [0.57, 1.37, 1.14]; * viewer.scene.camera.look = [0.04, 0.58, 0.00]; * viewer.scene.camera.up = [-0.22, 0.84, -0.48]; * * loadOBJGeometry(viewer.scene, { * * src: "models/obj/fireHydrant/FireHydrantMesh.obj", * compressGeometry: false * * }).then(function (geometryCfg) { * * // Success * * new Mesh(viewer.scene, { * * geometry: new ReadableGeometry(viewer.scene, geometryCfg), * * material: new MetallicMaterial(viewer.scene, { * * baseColor: [1, 1, 1], * metallic: 1.0, * roughness: 1.0, * * baseColorMap: new Texture(viewer.scene, { * src: "models/obj/fireHydrant/fire_hydrant_Base_Color.png", * encoding: "sRGB" * }), * normalMap: new Texture(viewer.scene, { * src: "models/obj/fireHydrant/fire_hydrant_Normal_OpenGL.png" * }), * roughnessMap: new Texture(viewer.scene, { * src: "models/obj/fireHydrant/fire_hydrant_Roughness.png" * }), * metallicMap: new Texture(viewer.scene, { * src: "models/obj/fireHydrant/fire_hydrant_Metallic.png" * }), * occlusionMap: new Texture(viewer.scene, { * src: "models/obj/fireHydrant/fire_hydrant_Mixed_AO.png" * }), * * specularF0: 0.7 * }) * }); * }, function () { * // Error * }); * ```` * * @function loadOBJGeometry * @param {Scene} scene Scene we're loading the geometry for. * @param {*} [cfg] Configs, also added to the result object. * @param {String} [cfg.src] Path to OBJ file. * @returns {Object} Configuration to pass into a {@link Geometry} constructor, containing geometry arrays loaded from the OBJ file. */ function loadOBJGeometry(scene, cfg = {}) { return new Promise(function (resolve, reject) { if (!cfg.src) { console.error("loadOBJGeometry: Parameter expected: src"); reject(); } var spinner = scene.canvas.spinner; spinner.processes++; utils.loadArraybuffer(cfg.src, function (data) { if (!data.byteLength) { console.error("loadOBJGeometry: no data loaded"); spinner.processes--; reject(); } var m = K3D.parse.fromOBJ(data); // done ! // unwrap simply duplicates some values, so they can be indexed with indices [0,1,2,3 ... ] // In some rendering engines, you can have only one index value for vertices, UVs, normals ..., // so "unwrapping" is a simple solution. var positions = K3D.edit.unwrap(m.i_verts, m.c_verts, 3); var normals = K3D.edit.unwrap(m.i_norms, m.c_norms, 3); var uv = K3D.edit.unwrap(m.i_uvt, m.c_uvt, 2); var indices = new Int32Array(m.i_verts.length); for (var i = 0; i < m.i_verts.length; i++) { indices[i] = i; } spinner.processes--; resolve(utils.apply(cfg, { primitive: "triangles", positions: positions, normals: normals.length > 0 ? normals : null, autoNormals: normals.length === 0, uv: uv, indices: indices })); }, function (msg) { console.error("loadOBJGeometry: " + msg); spinner.processes--; reject(); }); }); } export {loadOBJGeometry};