sceneform-android icon indicating copy to clipboard operation
sceneform-android copied to clipboard

How to create custom ring renderable such as the selection visualizer one?

Open fukalhan opened this issue 3 years ago • 10 comments

Hi, in our app, we would like to add resizeable selection visualizer according to the size of the current model renderable being selected. I've tried to add FootprintSelectionVisualizer with our custom renderable which size is changed according to the current model and it works fine, but we would like to have the default ring renderable as the visualizer, but I'm just not capable of replicating that renderable, the best I've got is setting the cylinder shaped renderable with zero height, which makes this filled circle shape, but we would like to have the ring with transparent insides. Is there any way how to replicate this renderable? Thank you

fukalhan avatar Feb 07 '22 12:02 fukalhan

If I understood your issue correctly, a ViewRenderable might be a possible solution. See this discussion: https://github.com/SceneView/sceneform-android/discussions/300#discussioncomment-2087242 Instead of a Rectangle use something like this

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <size android:height="40dp" android:width="40dp"/>
    <stroke
        android:width="1dp"
        android:color="#FFFFFF" />
</shape>

Probably you have to implement your own SelectionVisualizer

RGregat avatar Feb 07 '22 13:02 RGregat

You can also call this https://github.com/SceneView/sceneform-android/blob/ecaa67a59a999d39ff1def0f24fbdbc009090387/ux/src/main/java/com/google/ar/sceneform/ux/FootprintSelectionVisualizer.java#L34 and use a the glb of your choice.

Feel free to use the cursor.blend from sceneview-android as a starting point for your node selector.

Define the shape you want inside Blender and apply the same material as the linked model. Mostly for the color values which must be applied as diffuse if you don't want to come back here telling that your model seems dark. Using the baseColor your node selector will act as a "real"/"augmented" object. So if you're not using your app on a very sunny environment, the baseColor white will not be a "pure"/"non AR" white as it will be inflenced by the lights. emissiveColor is what you have to use if you want your model to be augmented but with a environment light independent material.

ThomasGorisse avatar Feb 07 '22 16:02 ThomasGorisse

Context

  • Dark environment
  • baseColor = White
  • emissiveColor = White

Result

  • Emission Strength = 0 image

  • Emission Strength = 0.5 image

  • Emission Strength = 1.0 image

ThomasGorisse avatar Feb 07 '22 16:02 ThomasGorisse

More samples with roughness = 1.0

  • Emission Strength = 0.0 image

  • Emission Strength = 1.0 image

ThomasGorisse avatar Feb 07 '22 16:02 ThomasGorisse

You can also call this

https://github.com/SceneView/sceneform-android/blob/ecaa67a59a999d39ff1def0f24fbdbc009090387/ux/src/main/java/com/google/ar/sceneform/ux/FootprintSelectionVisualizer.java#L34

and use a the glb of your choice. Feel free to use the cursor.blend from sceneview-android as a starting point for your node selector.

Define the shape you want inside Blender and apply the same material as the linked model. Mostly for the color values which must be applied as diffuse if you don't want to come back here telling that your model seems dark. Using the baseColor your node selector will act as a "real"/"augmented" object. So if you're not using your app on a very sunny environment, the baseColor white will not be a "pure"/"non AR" white as it will be inflenced by the lights. emissiveColor is what you have to use if you want your model to be augmented but with a environment light independent material.

Thank you for your answer, but if I understand correctly there is no way how to change the model renderable size in scene dynamically according to the current model selected, when it's supposed to serve as the selection visualizer. The RGregat's solution seems much more suitable, but the FootprintSelectionVisualizer takes only ModelRenderable as selection visualizer, so I will have to implement my own selection visualizer probably.

fukalhan avatar Feb 08 '22 17:02 fukalhan

It's true that the FootprintSelectionVisualizer node is private so you can't scale it directly. https://github.com/SceneView/sceneform-android/blob/ecaa67a59a999d39ff1def0f24fbdbc009090387/ux/src/main/java/com/google/ar/sceneform/ux/FootprintSelectionVisualizer.java#L27 But you can also just copy paste this https://github.com/SceneView/sceneform-android/blob/ecaa67a59a999d39ff1def0f24fbdbc009090387/ux/src/main/java/com/google/ar/sceneform/ux/FootprintSelectionVisualizer.java#L22-L55

And adjust your model scale by modifying the node scale.

ThomasGorisse avatar Feb 08 '22 17:02 ThomasGorisse

#300 (comment)

I've made my custom selection visualizer which sets view renderable as the selected node renderable, but it doesn't work with view renderable, it isn't displayed. But when I change the view renderable to model renderable implementatition, it shows the selection visualizer, so maybe I'm doing something wrong with the view renderable that I'm unaware of?

Here is my custom selection visualizer, which works fine if I replace the view renderable with model renderable

class CustomSelectionVisualizer(context: Context): SelectionVisualizer {
    private val selectionNode = Node()

    init {
        ViewRenderable.builder()
            .setView(context, R.drawable.selection_visualizer)
            .build()
            .thenAccept {
                it.isShadowCaster = false
                it.isShadowReceiver = false
                it.collisionShape = null
                selectionNode.renderable = it
            }
    }

    override fun applySelectionVisual(node: BaseTransformableNode?) {
        selectionNode.parent = node
    }

    override fun removeSelectionVisual(node: BaseTransformableNode?) {
        selectionNode.parent = null
    }
}

Here is the drawable I use for the view renderable

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <size android:height="250dp" android:width="250dp"/>
    <stroke
        android:width="10dp"
        android:color="@color/black" />
</shape>

fukalhan avatar Feb 08 '22 19:02 fukalhan

Oh ok, I found why it doesn't work, there's error inflating the given view from given source.

fukalhan avatar Feb 08 '22 19:02 fukalhan

setView takes a view res not drawable.

ThomasGorisse avatar Feb 08 '22 20:02 ThomasGorisse

I've managed to set the view to the ViewRenderable, but it displays weirdly as a square view mirroring the background. image

image

I guess it is expected behaviour according to the google docs. https://developers.google.com/sceneform/develop/create-renderables#create_from_android_widgets

The ViewRenderable should behave as a flat card in the scene displaying some view, so I'm not sure if the selection visualizer would even work with the ViewRenderable as @RGregat suggests, but it seemed like a good solution for my problem since I need to adjust the visualizer renderable size dynamically. Do you have any suggestions for this problem?

fukalhan avatar Feb 09 '22 11:02 fukalhan

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. Thank you for your contributions.

github-actions[bot] avatar Aug 17 '23 05:08 github-actions[bot]

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.

github-actions[bot] avatar Aug 25 '23 05:08 github-actions[bot]