-
Notifications
You must be signed in to change notification settings - Fork 36
Fail to load GLB from File System - Might have a FIX #21
Description
Hi there,
I was trying to load a glb file from the storage of the application using the
type:fileSystemAppFolderGLBtype:fileSystemAppFolderGLTF2
but i kept getting a FileNotFoundException.
I think I found a solution, which I will lay out here.
I looked into the code, inside the ArView.kt file and located the buildModelNode function that gets called in order to build our mode node.
ArView.kt:
(/android/src/main/kotlin/com.uhg0.ar_flutter_plugin_2/ArView.kt)
private suspend fun buildModelNode(nodeData: Map<String, Any>): ModelNode? {
var fileLocation = nodeData["uri"] as? String ?: return null
when (nodeData["type"] as Int) {
0 -> { // GLTF2 Model from Flutter asset folder
// Get path to given Flutter asset
val loader = FlutterInjector.instance().flutterLoader()
fileLocation = loader.getLookupKeyForAsset(fileLocation)
}
1 -> { // GLB Model from the web
fileLocation = fileLocation
}
2 -> { // fileSystemAppFolderGLB
fileLocation = fileLocation
}
3 -> { //fileSystemAppFolderGLTF2
val documentsPath = viewContext.getApplicationInfo().dataDir
val fileLocation = documentsPath + "/app_flutter/" + nodeData["uri"] as String
// --> HERE in the fileLocation declaration lies the issue
}
else -> {
return null
}
}
if (fileLocation == null) {
return null
}
// ...First thing I checked was the case of fileSystemAppFolderGLTF2. In that case I saw that the fileLocation property is redeclared
// ...
3 -> { //fileSystemAppFolderGLTF2
val documentsPath = viewContext.getApplicationInfo().dataDir
val fileLocation = documentsPath + "/app_flutter/" + nodeData["uri"] as String
}I changed it to
// ...
3 -> { //fileSystemAppFolderGLTF2
val documentsPath = viewContext.getApplicationInfo().dataDir
// val fileLocation = documentsPath + "/app_flutter/" + nodeData["uri"] as String
fileLocation = documentsPath + "/app_flutter/" + nodeData["uri"] as String
}I still couldn't make it work, so I dug more and found that the the loadFileBuffer function from sceneview-android package waits for a sepcific prefix in order to read files inside the app's storage, specifically file://.
For example:
file://data/user/0/com.example.my_app_name/app_flutter/test.glb
instead of just:
/data/user/0/com.example.my_app_name/app_flutter/test.glb.
So I updated the code snippet again to look like this:
// ...
3 -> { //fileSystemAppFolderGLTF2
val documentsPath = viewContext.getApplicationInfo().dataDir
fileLocation = "file://" + documentsPath + "/app_flutter/" + nodeData["uri"] as String
}And it worked, the model appeared!
Then I checked out the fileSystemAppFolderGLB case. I see that in that case the fileLocation does not change
2 -> { //fileSystemAppFolderGLB
fileLocation = fileSystem
}I don't know why.
So i did the same thing with the GLTF2 case and again it worked
2 -> { //fileSystemAppFolderGLB
val documentsPath = viewContext.getApplicationInfo().dataDir
fileLocation = "file://" + documentsPath + "/app_flutter/" + nodeData["uri"] as String
}I guess this is my fix, do you find it viable?
If yes I can open a PR.