UNPKG

nativescript-ar

Version:

NativeScript Augmented Reality plugin. ARKit on iOS and (with the help of Sceneform) ARCore on Android.

321 lines (320 loc) 11.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var file_system_1 = require("tns-core-modules/file-system"); var utils = require("tns-core-modules/utils/utils"); var ARMaterialFactory = (function () { function ARMaterialFactory() { } ARMaterialFactory.applyMaterial = function (node, material) { if (typeof material === "string") { return new Promise(function (resolve, reject) { reject("not implemented"); }); } else if (material.constructor.name === "Color") { return ARMaterialFactory.applyColor(node, material.android) .catch(function (err) { return console.log("Error applying material: " + err); }); } else { return ARMaterialFactory.applyARMaterial(node, material) .catch(function (err) { return console.log("Error applying material: " + err); }); } }; ARMaterialFactory.applyColor = function (node, color) { return new Promise(function (resolve, reject) { com.google.ar.sceneform.rendering.MaterialFactory.makeOpaqueWithColor(utils.ad.getApplicationContext(), new com.google.ar.sceneform.rendering.Color(color)) .thenAccept(new java.util.function.Consumer({ accept: function (material) { var renderable = node.getRenderable(); if (renderable) { renderable.setMaterial(material); } resolve(); } })) .exceptionally(new java.util.function.Function({ apply: function (error) { return reject(error); } })); }); }; ARMaterialFactory.applyARMaterial = function (node, material) { return new Promise(function (resolve, reject) { android.os.AsyncTask.execute(new java.lang.Runnable({ run: function () { var gltf = blankGLTF(); var index = 0; if (material.diffuse) { if (material.diffuse.constructor.name === "Color") { addPbrMetallic(gltf, { "baseColorFactor": colorFrom(material.diffuse), }); } else { addTexture(gltf, material.diffuse, index); addPbrMetallic(gltf, { "baseColorTexture": { "index": index } }); gltf.materials[0]["extensions"] = { "KHR_materials_pbrSpecularGlossiness": { "diffuseTexture": { "index": index } } }; index++; } } if (material.normal) { if (material.normal.constructor.name === "Color") { } else { addTexture(gltf, material.normal, index); gltf.materials[0]["normalTexture"] = { "index": index }; index++; } } if (material.roughness) { if (material.roughness.constructor.name === "Color") { } else { addTexture(gltf, material.roughness, index); addPbrMetallic(gltf, { "metallicRoughnessTexture": { "index": index } }); index++; } } if (material.emission) { if (material.emission.constructor.name === "Color") { } else { addTexture(gltf, material.emission, index); gltf.materials[0]["emissiveFactor"] = [ 1.0, 1.0, 1.0 ]; gltf.materials[0]["emissiveTexture"] = { "index": index }; index++; } } var p = file_system_1.path.join(file_system_1.knownFolders.temp().path, "ar-" + (new Date()).getTime()); var tmp = file_system_1.Folder.fromPath(p); var file = tmp.getFile("model_source.gltf"); var modelPath = file.path; var promise = file.writeText(JSON.stringify(gltf, null, " ")) .then(function () { return copyAsset("material.bin", tmp.getFile("material.bin").path); }); gltf.images.forEach(function (image) { promise = promise.then(function () { return copyAsset(image.uri, tmp.getFile(image.uri).path) .catch(function (err) { return console.log("Failed to copy " + image.uri + " with error: " + err); }); }); }); promise.then(function () { var context = utils.ad.getApplicationContext(); var model = com.google.ar.sceneform.assets.RenderableSource.builder().setSource(context, android.net.Uri.parse(modelPath), com.google.ar.sceneform.assets.RenderableSource.SourceType.GLTF2).build(); com.google.ar.sceneform.rendering.ModelRenderable.builder() .setSource(context, model) .build() .thenAccept(new java.util.function.Consumer({ accept: function (renderable) { node.getRenderable().setMaterial(renderable.getMaterial()); } })) .exceptionally(new java.util.function.Function({ apply: function (error) { console.error("failed loading custom material: " + error); reject(error); } })); }).catch(function (err) { console.error("failed to load custom material"); console.log(err); reject(err); }); } })); }); }; return ARMaterialFactory; }()); exports.ARMaterialFactory = ARMaterialFactory; var getWrapMode = function (wrapMode) { if (wrapMode === "Mirror") { return 33648; } else if (wrapMode === "Clamp") { return 33071; } else if (wrapMode === "ClampToBorder") { return 33071; } else { return 10497; } }; var counter = 0; var copyAsset = function (asset, to) { return new Promise(function (resolve, reject) { var context = utils.ad.getApplicationContext(); var input = context.getAssets().open(asset); var out = new java.io.FileOutputStream(new java.io.File(to)); var buf = Array.create("byte", 1024); var len; while ((len = input.read(buf)) > 0) { out.write(buf, 0, len); } input.close(); out.close(); resolve(); }); }; var colorFrom = function (color) { var c = new com.google.ar.sceneform.rendering.Color(color.android); return [c.r, c.g, c.b, c.a]; }; var addPbrMetallic = function (gltf, property) { if (gltf.materials[0]["pbrMetallicRoughness"] === undefined) { gltf.materials[0]["pbrMetallicRoughness"] = {}; } Object.keys(property).forEach(function (key) { return gltf.materials[0]["pbrMetallicRoughness"][key] = property[key]; }); }; var addTexture = function (gltf, material, index) { var property = (typeof material === "string" ? { contents: material, wrapMode: "Repeat" } : material); gltf.images.push({ "uri": property.contents }); gltf.samplers.push({ "magFilter": 9729, "minFilter": 9987, "wrapT": getWrapMode(property.wrapMode), "wrapS": getWrapMode(property.wrapMode) }); gltf.textures.push({ "sampler": index, "source": index }); }; var blankGLTF = function () { return { "asset": { "version": "2.0", "generator": "Khronos glTF Blender I/O v0.9.53" }, "scene": 0, "scenes": [ { "nodes": [ 0 ], "name": "Scene" } ], "nodes": [ { "mesh": 0, "name": "Cube" } ], "images": [], "materials": [ { "name": "Material", "alphaMode": "BLEND" } ], "samplers": [], "textures": [], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 0, "NORMAL": 1, "TEXCOORD_0": 2 }, "material": 0, "indices": 3 } ], "name": "Cube" } ], "accessors": [ { "componentType": 5126, "count": 24, "type": "VEC3", "min": [ -1.0000003576278687, -1, -1.0000003576278687 ], "bufferView": 0, "max": [ 1.0000004768371582, 1, 1.0000005960464478 ] }, { "componentType": 5126, "bufferView": 1, "count": 24, "type": "VEC3" }, { "componentType": 5126, "bufferView": 2, "count": 24, "type": "VEC2" }, { "componentType": 5123, "bufferView": 3, "count": 36, "type": "SCALAR" } ], "bufferViews": [ { "byteLength": 288, "buffer": 0, "byteOffset": 0 }, { "byteLength": 288, "buffer": 0, "byteOffset": 288 }, { "byteLength": 192, "buffer": 0, "byteOffset": 576 }, { "byteLength": 72, "buffer": 0, "byteOffset": 768 } ], "buffers": [ { "byteLength": 840, "uri": "material.bin" } ] }; };