google-ar / sceneform-android-sdk

Sceneform SDK for Android
https://developers.google.com/sceneform/develop/
Apache License 2.0
1.23k stars 603 forks source link

Is there a way to load models from server #35

Closed RavindraVirat closed 6 years ago

RavindraVirat commented 6 years ago

In Sceneform sample app we are loading models from model folder, in case I have more then 20 models assume for any shopping app then if I put all those models in asset folder, apk size will increase, so my question is can we load models means 'model related files like obj, mtl, png, sfa, sfb' from server and save to local then go for rendering.

dsternfeld7 commented 6 years ago

The generated sfb file contains all of the data for the model, so if you copy just the sfb file to a web server, you can then load the renderable via a url:

ModelRenderable.builder().setSource(this, Uri.parse("https://www.foo.com/bar.sfb")).build();

The download will automatically happen on a background thread.

Alternatively, you could write your own mechanism for downloading the .sfb files (zipped together or otherwise) and load them using a file:// URI or from an InputStream.

RavindraVirat commented 6 years ago

Thank you for reply.

In sceneform sample app I observed that the model is already configured in gradle file as below - sceneform.asset('sampledata/models/andy.obj', 'default', 'sampledata/models/andy.sfa', 'src/main/res/raw/Andy')

, in this case model is already available, so if I download the new model from server then how will I mention my newly downloaded file in gradle.

dsternfeld7 commented 6 years ago

You can use a gradle project (it doesn't need to be the same project as your application) to convert the raw assets (obj + mtl) into an sfb in advance and then store just the sfbs on your web server.

The sfbs you download from the web server do not need to be mentioned in your build.gradle. res/raw can only contain resources that are packaged with the apk.

When downloading an sfb, you can load the Renderable using a URL directly, save them in device storage and access them using a "file://" URI, or load them from an inputstream directly.

ldima commented 6 years ago

@dsternfeld7 I have got

Unable to load Renderable Unable to load Renderable registryId='file:///storage/emulated/0/Download/lion3.sfb' java.util.concurrent.CompletionException: java.io.FileNotFoundException: /storage/emulated/0/Download/lion3.sfb

File is exist. What does it mean?

RavindraVirat commented 6 years ago

If you pass Uri of the .sfb file to setSource() method , it is not working, giving IllegalArgumentException: Unable to parse url, MalformedURLException: unknown protocol: content.

I tried like this and its able to render - setSource(this, new Callable() { @Override public InputStream call() throws Exception { FileInputStream fileInputStream = null; try { fileInputStream = new FileInputStream(getFilePath()); } catch (FileNotFoundException e) { e.printStackTrace(); } return fileInputStream; } })

getFilePath() method will return path of the .sfb file.

ishaang10 commented 5 years ago

How to load a model from a file input stream ????

I downloaded the file from server using the download manager and its path is Content://downloads/all_download/190.
so if i can somehow get it in a filestream . then how can i load that model.

its the .sfb file.

artemtkachenko commented 5 years ago

@ishaang10 seems like this is what you are looking for

ModelRenderable.builder()
            .setSource(context, Callable<InputStream> {
                return@Callable FileInputStream(%downloaded_file_absolute_path_string%)
            })
            .build()

Nevertheless I am not sure that a content:// uri can be a source for downloaded_file_absolute_path_string. I suggest using a file:// uri instead. It works for sure.