Open mistrydarshan99 opened 6 years ago
A URI can point to a file or a content provider. It doesn't have to be an http URL.
Looking at the code here, file, android resource and http URI's are supported. We don't do content providers yet. I'm adding support for that for the next release.
@malik-at-work I think at least provide one method in sceneform assets library that accepts two parameters whether user download 3D model or not and download location of 3D model in file storage. So that we will not retrieve 3D model from a server every time.
@malik-at-work Hello If you don't mind could you clarify is it possible to get downloaded .sfb file url from ModelRenderable? E.g.
ModelRenderable.builder()
.setSource(this, Uri.parse("http://blabla/3dmodels/android/my_custom_model.sfb"))
.build()
.thenAccept(renderable -> {
this.renderable = renderable;
})
In accept callback I want to store fetched .sfb file into the local device storage and use this local stored .sfb file later instead of downloading it again from the server. Please advise.
I tried to load this model at runtime from Azure But it doesn't load. I followed the documentation.
How can we download to device then render in Sceneform?
@jonas-kgomo
You should download a file itself into device storage and use Callable<InputStream> inputStreamCreator
as a source for ModelRenderable:
https://developers.google.com/ar/reference/java/sceneform/reference/com/google/ar/sceneform/rendering/ModelRenderable.Builder
e.g. (kotlin)
ModelRenderable.builder()
.setSource(context, Callable<InputStream> {
return@Callable FileInputStream(%downloaded_file_absolute_ path_string%)
})
.build()
I am using Java, this doesn't render the model. It's not able to fetch the location from runtime :
File file = new File("file:///storage/emulated/0/Download/andy.sfb");
Callable callable = () -> {
InputStream inputStream = new FileInputStream(file);
return inputStream;
};
FutureTask task = new FutureTask<>(callable);
new Thread(task).start();
ModelRenderable.builder()
.setSource(this, callable)
.build()
.thenAccept(renderable -> andyRenderable = renderable)
.exceptionally(
throwable -> {
Toast toast =
Toast.makeText(this, "Unable to load andy renderable", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
return null;
});
arFragment.setOnTapArPlaneListener((HitResult hitResult, Plane plane, MotionEvent motionEvent) -> {
if (andyRenderable == null) {
return;
}
// Create the Anchor.
Anchor anchor = hitResult.createAnchor();
AnchorNode anchorNode = new AnchorNode(anchor);
anchorNode.setParent(arFragment.getArSceneView().getScene());
// Create the transformable andy and add it to the anchor.
TransformableNode andy = new TransformableNode(arFragment.getTransformationSystem());
andy.setParent(anchorNode);
andy.setRenderable(andyRenderable);
andy.select();
});
}
I have a button that downloads the model to device (internal storage),
public void addListenerOnButton() {
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse("https://companyname.blob.core.windows.net/models/andy.sfb");
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setTitle("model");
request.setDescription("downloading...");
request.allowScanningByMediaScanner();// if you want to be available from media players
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
Long reference = downloadManager.enqueue(request);
File filepath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "andy.sfb");
Toast.makeText(getApplicationContext(), "FilePath : " + filepath, Toast.LENGTH_LONG).show();
// this file is saved at : /storage/emulated/0/Download/andy.png
}
});
}
@jonas-kgomo I sent you a 100% working solution. I don't know what is wrong with your code; basically, there are plenty of reasons why your code does not render a model:
Moreover you don't need creatingFutureTask
and start it in a thread
, just pass the callable
object into setSource(...)
.
Also I recommend logging the exception message. Display toast with the hardcoded text message won't help you;
@artemtkachenko can you share with me the working solution thank you.
@artemtkachenko when we can expect running code?
In ARCore 1.5 documentation provide snippest to load 3D model runtime.
Instead of loading the 3D model at runtime, Can we download (.gltf) file in storage? Is there any method available in sceneform assets library to dowload .gltf file in storage?
Load 3D model every time is time consuming usecase for end user. User will not wait for long time in such usecase.