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
JavaScript
;
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"
}
]
};
};