Skip to content

Fail to load GLB from File System - Might have a FIX #21

@leomav

Description

@leomav

Hi there,

I was trying to load a glb file from the storage of the application using the

  • type:fileSystemAppFolderGLB
  • type: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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions