Load JSON file in babylon native

Good afternoon, I am trying to load a JSON file in a Babylon Javascript code that should then be loaded by a Babylon Native Android application. For some reason all I get is a black screen, but Android Studio does not seem to collaborate and does not give me any explicit error. I am for example trying to load this model from the playground (Babylon.js Playground), which works perfectly as it is but does not load if I create an independent JSON file and then refer to it through the app:/// or file:/// protocol. The same happens with this other model (Babylon.js Playground): it all loads perfectly but doesn’t work if I move the JSON code to an independent file (say, “sample.json”), save it in the Scripts folder and then refer to it like this

var gltf = “file:///Scripts/sample.json”

Thank you!

Pinging @Cedric for guidance

1 Like

Hi @fede17

Loading resources on Android works with app:// schema like in the playground sample:

Did you add the .json to the assets so it’s part of the .apk?
Once you’ve loaded the json with an xmlhttprequest, can you check you get a valid responsetext? You can check by logging the content.

Thank you @Cedric, I am sorry for the very late reply. Yes, I included the json file in the .apk, but I don’t why I cannot get any xmlHttpRequest to work.
This is my JS file with the xmlhttprequest. I load the Json via the http protocol, and I tried with the file and app protocol too. This same JS works perfectly if I add the necessary DOM depencies and run it on my local server, but the JSON does not seem to load on Babylon Native (I only see one single cube with no texture).

function CreateInputHandling(scene) {
var inputManager = new InputManager();
var priorX = inputManager.pointerX;
var priorY = inputManager.pointerY;
var x = 0;
var y = 0;
scene.onBeforeRenderObservable.add(function () {
    x = inputManager.pointerX;
    y = inputManager.pointerY;

    if (inputManager.isPointerDown) {
        scene.activeCamera.alpha += 0.01 * (priorX - x);
        scene.activeCamera.beta += 0.01 * (priorY - y);
    }

    priorX = x;
    priorY = y;
});
}

var createScene = function () {


// This creates a basic Babylon Scene object (non-mesh)
var scene = new BABYLON.Scene(engine);

// This creates and positions a free camera (non-mesh)
// Create a rotating camera
var camera = new BABYLON.ArcRotateCamera("Camera", 1.9, 5.0, 120, new BABYLON.Vector3(15, 15, 0), scene);

// Attach it to handle user inputs (keyboard, mouse, touch)
//camera.attachControl(canvas, false);

// This targets the camera to scene origin
camera.setTarget(BABYLON.Vector3.Zero());


// This creates a light, aiming 0,1,0 - to the sky (non-mesh)
var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);

// Default intensity is 1. Let's dim the light a small amount
light.intensity = 0.7;
var myColors = new Array(6);

var baseBlocks = [];

['mountain', 'hill', 'grass', 'water'].forEach(function (block) {
if( block == "mountain")
{
myColors[4] = new BABYLON.Color4(0,0,0,1);
} else if (block === "hill") {
myColors[4] = new BABYLON.Color4(1,1,0,1);
} else if (block === "water") {
myColors[4] = new BABYLON.Color4(0,1,0,1);
} else {
myColors[4] = new BABYLON.Color4(0,1,1,1);
}
var box = BABYLON.MeshBuilder.CreateBox("box", {height: 5, width:5, depth:5, faceColors: myColors}, scene);
box.enableEdgesRendering();
box.edgesWidth = 4.0;
box.edgesColor = new BABYLON.Color4(0, 0, 1, 1);

box.position.y = -1 * 5;
box.position.x = -1 * 5;
box.position.z = -1 * 5;
baseBlocks.push(box);
});


var gltf = "http://localhost/prova/try.json";
//var gltf = "file:///Scripts/try.json";
//var gltf = "app:///Scripts/try.json";
var xmlHttp = new XMLHttpRequest();

var arrayOfMeshes = [];

xmlHttp.onreadystatechange = function()
{
if (this.readyState == xmlHttp.DONE && this.status == 200)
{
    var out = JSON.parse(this.responseText);

mapBlocks = out.map;
mapBlocks.forEach(function (block) {
  if( block.type == "mountain")
  {
    var newClone = baseBlocks[0].clone();
  } else if (block.type === "hill") {
    var newClone = baseBlocks[1].clone();
  } else if (block.type === "water") {
    var newClone = baseBlocks[2].clone();
  } else {
    var newClone = baseBlocks[3].clone();
  }

    // Move the sphere upward 1/2 its height
  newClone.position.y = block.y * 5; //+ ( 5 * $y );
  newClone.position.x = block.x * 5;
  newClone.position.z = block.z * 5;
  newClone.enableEdgesRendering();
  newClone.edgesWidth = 1.0;
  newClone.edgesColor = new BABYLON.Color4(0, 0, 1, 1);
  arrayOfMeshes.push(newClone);
});


  var newMesh = BABYLON.Mesh.MergeMeshes(arrayOfMeshes);
    newMesh.enableEdgesRendering();
    newMesh.edgesWidth = 4.0;
    newMesh.edgesColor = new BABYLON.Color4(0, 0, 1, 1);}
};
        xmlHttp.open("GET", gltf, true);
        xmlHttp.send();


CreateInputHandling(scene);
return scene;

};

function getRandomInt(min, max) {
num = Math.random() * (max - min) + min;
return num;
}

In my Android Activity, I load the Scripts like this

mView.loadScript("app:///Scripts/JSON2.js");
mView.loadScript("app:///Scripts/playground_runner.js");

Thank you and sorry for bothering again.

if the json is part of your apk, then you can try:

var gltf = "app:///Local_Path_To_Assets_In_APK/try.json";

I guess the http doesn’t work because you didn’t forward tcp request from the device to the PC.
Also, you can try to do it by uploading the json to a public github repo and access it with github raw content.

Thanks @Cedric, nothing seems to be working at the moment, which is weird because I’ve always loaded different files (.png, .env, .gltf, etc.) via app and https protocols with no problem whatsoever. I’ve tried what you said (local path and github raw content) but I still cannot load JSON files. Again, the program works perfectly when I run the program on my local server rather than on Native. I will keep on trying and let you know, thank you.

1 Like

@Cedric I believe the problem could be related to the fact that if I declare

var gltf = “app:///Scripts/try.json”

or

var gltf = “https://raw.githubusercontent.com/.../try.json”

Babylon native simply reads it as a string rather than a “link” to an external resource, even though this problem does not occur when I run the same JS on the web and not on mobile. Could this be the problem? Do you have any suggestions on how to actually make Babylon Native read it as a JSON file?

I am working on a larger project where I need to load multiple JSON files, and I am trying to make these smaller models work in order to be able to tackle the real project step by step.

Is your JSON file using any encoding? like BOM

Sweet! Give me some hours to try to load it inside the Android playground …

1 Like

I cloned the repo, built for android and used this experience.js :

check lines 79 - 92
Everything worked fine.

1 Like

@Cedric thanks man, now the JSON2.js file is also loading the JSON. Thank you so much you are great!

1 Like