Uttam Kumar Nayak
Uttam Kumar Nayak

Reputation: 31

How to give material to the renderable instance of .glb file Sceneform ARCore

I had tried to give the material with colour after generating the ModelRenderable instance of .glb file, but its throwing the error "java.util.concurrent.CompletionException: java.lang.IllegalArgumentException: submeshIndex (0) is out of range. It must be less than the submeshCount (0)" but same thing working for the ModleRenderable instance of the .sfb , Please see the below code, i don't know how to handle this scenario.

ModelRenderable.builder()
                    .setSource(context, Uri.parse("redMarker.glb"))
                    .setIsFilamentGltf(true)
                    .build()
                    .thenAccept { renderable ->
                        pointy4Cursor = renderable
                    }
                    .exceptionally {
                        Log.e(TAG, "unable to load renderable pointy4Cursor  - " + it.toString())
                        val toast = Toast.makeText(context, "Unable to load renderable new model 6", Toast.LENGTH_LONG)
                        toast.setGravity(Gravity.CENTER, 0, 0)
                        toast.show()
                        null
                    },

 MaterialFactory.makeOpaqueWithColor(context, Color(context.getColor(R.color.colorSecondary)))
                    .thenAccept {
                        navaPink = it
                    }
                    .exceptionally {
                        Log.e(TAG, "unable to load material navaPink")
                        val toast = Toast.makeText(context, "Unable to load material", Toast.LENGTH_LONG)
                        toast.setGravity(Gravity.CENTER, 0, 0)
                        toast.show()
                        null
                    },

 pointy4Cursor.material = navaPink // It's throwing exception as define above. 

Please help

Upvotes: 0

Views: 1335

Answers (1)

nphi
nphi

Reputation: 45

I assume you are using Sceneform version 1.16 because of the possibility to load GLB models?

Your problem is a known issue as you see here, here or here.

A possible workaround here is to use the filamentAsset you can get in Sceneform 1.16. You can get it like this:

private void addModel (Anchor anchor, ModelRenderable modelRenderable){
            // Creating a AnchorNode with a specific anchor
            AnchorNode anchorNode = new AnchorNode(anchor);

            // attaching the anchorNode with the ArFragment
            anchorNode.setParent(arCam.getArSceneView().getScene());

            // attaching the anchorNode with the TransformableNode
            TransformableNode model = new TransformableNode(arCam.getTransformationSystem());
            model.setParent(anchorNode);

            // attaching the 3d model with the TransformableNode
            // that is already attached with the node
            model.setRenderable(modelRenderable);
            model.select();

            // Saving the object as filament asset
            // -> Possibility to run animations and change textures
            filamentAsset = model.getRenderableInstance().getFilamentAsset();
        }

The function can be invoked inside the ModelRenderable.builder() like:

ModelRenderable.builder()
                            .setSource(this, R.raw.avocado)
                            .setIsFilamentGltf(true)
                            .build()
                            .thenAccept(modelRenderable -> addModel(anchor, modelRenderable))
                            .exceptionally(throwable -> {
                                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                                builder.setMessage("Somthing is not right" + throwable.getMessage()).show();
                                return null;
                            });

When you saved the filamentAsset to a variable, you can access the MaterialInstances and set parameters:

public void changeMaterials () {
            MaterialInstance[] materialInstances = filamentAsset.getMaterialInstances();

            TextureSampler textureSampler = new TextureSampler();

            for (MaterialInstance materialInstance : materialInstances) {
                if (materialInstance.getName() == "example_name") {
                    materialInstance.setParameter("baseColorFactor", 0.3f, 0.5f, 0.7f); // Values for Red, Green and Blue
                }
            }
        }

Which values you can set you can see here.

I hope this solves your issues!

Upvotes: 1

Related Questions