UNPKG

babylonjs-fbx-loader

Version:
152 lines 7.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FBXMaterial = void 0; const path_1 = require("path"); const core_1 = require("@babylonjs/core"); class FBXMaterial { /** * Parses all available materials in the FBX file. * @param runtime defines the reference to the current FBX runtime. */ static ParseMaterials(runtime) { var _a, _b, _c; const videos = this._ParseVideos(runtime.scene, runtime.objects, runtime.rootUrl, runtime.writeTextures); const textures = this._ParseTextures(runtime.objects, runtime.connections, videos); const materials = runtime.objects.nodes('Material'); for (const m of materials) { const id = m.prop(0, 'number'); const name = m.prop(1, 'string'); const material = new core_1.StandardMaterial(name, runtime.scene); material.id = id.toString(); runtime.result.materials.push(material); const properties = (_b = (_a = m.node('Properties70')) === null || _a === void 0 ? void 0 : _a.nodes('P')) !== null && _b !== void 0 ? _b : []; properties.forEach((p) => { const type = p.prop(0, 'string'); switch (type) { case 'Diffuse': case 'DiffuseColor': material.diffuseColor = new core_1.Color3(p.prop(4, 'number'), p.prop(5, 'number'), p.prop(6, 'number')); break; case 'Specular': case 'SpecularColor': material.specularColor = new core_1.Color3(p.prop(4, 'number'), p.prop(5, 'number'), p.prop(6, 'number')); break; case 'Ambient': case 'AmbientColor': material.ambientColor = new core_1.Color3(p.prop(4, 'number'), p.prop(5, 'number'), p.prop(6, 'number')); break; case 'Emissive': case 'EmissiveColor': material.emissiveColor = new core_1.Color3(p.prop(4, 'number'), p.prop(5, 'number'), p.prop(6, 'number')); break; } }); const relationships = runtime.connections.get(id); (_c = relationships === null || relationships === void 0 ? void 0 : relationships.children) === null || _c === void 0 ? void 0 : _c.forEach((c) => { const texture = textures[c.id]; if (!texture) { return; } const type = c.relationship; switch (type) { case 'DiffuseColor': case 'Maya|TEX_color_map': material.diffuseTexture = texture; break; case 'Bump': case 'NormalMap': case 'Maya|TEX_normal_map': material.bumpTexture = texture; break; case 'SpecularColor': material.specularTexture = texture; break; case 'Maya|TEX_ao_map': material.ambientTexture = texture; break; } }); runtime.cachedMaterials[id] = material; } } /** * Configures all the given textures. */ static _ParseTextures(objects, connections, videos) { var _a, _b, _c, _d, _e, _f; const result = {}; const textures = objects.nodes('Texture'); for (const t of textures) { const id = t.prop(0, 'number'); const videoId = (_b = (_a = connections.get(id)) === null || _a === void 0 ? void 0 : _a.children[0]) === null || _b === void 0 ? void 0 : _b.id; if (videoId === undefined) { continue; } const video = videos[videoId]; if (!video) { continue; } result[id] = video; // Configure texture const modelUVTranslation = t.node('ModelUVTranslation'); if (modelUVTranslation) { video.uOffset = (_c = modelUVTranslation.prop(0, 'number')) !== null && _c !== void 0 ? _c : 0; video.vOffset = (_d = modelUVTranslation.prop(1, 'number')) !== null && _d !== void 0 ? _d : 0; } const modelUVScaling = t.node('ModelUVScaling'); if (modelUVScaling) { video.uScale = (_e = modelUVScaling.prop(0, 'number')) !== null && _e !== void 0 ? _e : 1; video.vScale = (_f = modelUVScaling.prop(1, 'number')) !== null && _f !== void 0 ? _f : 1; } } return result; } /** * Parses all the available Video FBX nodes and returns the created textures dictionary. */ static _ParseVideos(scene, objects, rootUrl, writeTextures) { var _a, _b, _c, _d, _e, _f; const videos = objects.nodes('Video'); const result = {}; for (const v of videos) { let filePath = (_b = (_a = v.node('RelativeFilename')) === null || _a === void 0 ? void 0 : _a.prop(0, 'string')) !== null && _b !== void 0 ? _b : (_c = v.node('Filename')) === null || _c === void 0 ? void 0 : _c.prop(0, 'string'); if (!filePath) { continue; } filePath = filePath.replace(/\\/g, '/'); const extension = (0, path_1.extname)(filePath).toLowerCase(); if (this._SupportedTextureTypes.indexOf(extension) === -1) { continue; } const id = v.prop(0, 'number'); const useMipMap = (_e = (_d = v.node('UseMipMap')) === null || _d === void 0 ? void 0 : _d.prop(0)) !== null && _e !== void 0 ? _e : 0; const fileName = (0, path_1.basename)(filePath); let fileUrl = (0, path_1.join)(rootUrl, fileName); const content = (_f = v.node('Content')) === null || _f === void 0 ? void 0 : _f.prop(0); if (!Buffer.isBuffer(content)) { continue; } if (!content.length) { continue; } if (content.length) { if (writeTextures) { console.log('UNHANDLED: Write texture for video node'); //@TODO: understand what this is for. //writeFileSync(fileUrl, Buffer.from(content), { encoding: 'binary' }) } else { // FIX: @see https://github.com/Benjythebee/babylonjs-fbx-loader/issues/1 fileUrl = 'data:application/octet-stream;base64,'; fileUrl += Buffer.from(content).toString('base64'); } } const texture = new core_1.Texture(fileUrl, scene, !useMipMap, undefined, undefined, undefined); result[id] = texture; } return result; } } exports.FBXMaterial = FBXMaterial; FBXMaterial._SupportedTextureTypes = ['.png', '.jpg', '.jpeg', '.bmp']; //# sourceMappingURL=material.js.map