Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FootprintSelectionVisualizer not displaying footprint #30

Closed
kelvinwatson opened this issue Mar 3, 2022 · 17 comments
Closed

FootprintSelectionVisualizer not displaying footprint #30

kelvinwatson opened this issue Mar 3, 2022 · 17 comments

Comments

@kelvinwatson
Copy link

kelvinwatson commented Mar 3, 2022

I'm trying to set a foot print shadow but I'm not seeing one when I try to add a FootprintSelectionVisualizer.

Am I missing a step?

    private fun onModelLoaded(modelRenderable: ModelRenderable) {

        val footprintSelectionVisualizer = FootprintSelectionVisualizer().apply {
            footprintRenderable = modelRenderable // this doesn't seem to do anything
        }
        val transformationSystem = TransformationSystem(context.resources.displayMetrics, footprintSelectionVisualizer)

        val node = DragTransformableNode(1f, transformationSystem).also {
            it.renderable = modelRenderable
            scene.addChild(it)
            it.select()
        }

        scene.addOnPeekTouchListener { hitTestResult: HitTestResult?, motionEvent: MotionEvent? ->
            transformationSystem.onTouch(hitTestResult, motionEvent)
        }

    }
@ThomasGorisse
Copy link
Contributor

ThomasGorisse commented Mar 3, 2022

Sorry about that, we didn't moved the old Sceneform TransformationSystem to SceneView yet (even if it might be totally functional). Just to let you know, it will be much easier to use and directly accessible at the Node level when moved to SceneView.

Here is your answer:

Since the FootprintSelectionVisualizer.footprintNode is private your better move is to override the SelectionVisualizer based on what is done in the FootprintSelectionVisualizer but cleaner:

class NodeSelectionVisualizer(val selectorNode: Node) : SelectionVisualizer {

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

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

(It would be great if you could make a Pull Request with this code)

And to manage the shadows:

val modelNode = ModelNode()
modelNode.loadModelAsync(
    context = requireContext(),
    glbFileLocation = "NodeSelector.glb",
    coroutineScope = lifecycleScope,
    autoAnimate = true,
    autoScale = true,
    centerOrigin = Position(0.0f)
) { instance: RenderableInstance ->
    instance.isShadowCaster = true
    instance.isShadowReceiver = true
}
val transformationSystem = TransformationSystem(requireContext().resources.displayMetrics, NodeSelectionVisualizer(modelNode))

You then just have 2 choice depending on your usage case:

  • Pass your Activity/Fragment lifecycleScope to the loadModelAsync() function in order to preload the model at at least the Activity/Fragment created state
  • Use coroutineScope = null to load the model when the ModelNode is first attached/first applySelectionVisual to its parent. In this case, the SceneView lifecycle will be use so it's also safe to have an http glb file and the loading will cancel on the view detached and the model resource will also be released when the SceneView is destroyed.

@ThomasGorisse
Copy link
Contributor

@kelvinwatson
Copy link
Author

Thanks @ThomasGorisse. I've tried the above recommendations but still not seeing any footprint on the model.

@kelvinwatson
Copy link
Author

kelvinwatson commented Mar 11, 2022

I guess maybe I wasn't very clear about what I needed. I actually need a shadow below the model. I guess what I need is a plane or surface underneath the model and make the model the shadow caster?

@kelvinwatson
Copy link
Author

kelvinwatson commented Mar 11, 2022

I created a ViewRenderable to go underneath the model, but it doesn't seem to result in any shadow being cast on the viewRenderable.

class ShadowSelectionVisualizer : SelectionVisualizer {
        private val footprintNode: Node = Node()

        fun setFootprintRenderable(viewRenderable: ViewRenderable) {
            val copyRenderable = viewRenderable.makeCopy()
            copyRenderable.verticalAlignment = ViewRenderable.VerticalAlignment.CENTER
            val rotation1: Quaternion = Quaternion.axisAngle(Vector3(1.0f, 0.0f, 0.0f), 90f)
            footprintNode.renderable = copyRenderable
            footprintNode.localRotation = rotation1
        }

        override fun applySelectionVisual(node: BaseTransformableNode) {
            if (node.collisionShape is Box) {
                val box: Box = node.collisionShape as Box
                val vector3: Vector3 = box.size
                (footprintNode.renderable as ViewRenderable).sizer = ViewSizer {
                    val bound = if (vector3.x > vector3.z) vector3.x else vector3.z
                    Vector3(bound, bound, 0.0f)
                }
                footprintNode.setParent(node)
            }
        }

        override fun removeSelectionVisual(node: BaseTransformableNode?) {
            footprintNode.setParent(null)
        }
    }

threeDimensionalModel.isShadowCaster = true

val selectionVisualizer = ShadowSelectionVisualizer()
val transformationSystem = TransformationSystem(resources.displayMetrics, selectionVisualizer)

 ViewRenderable.builder()
            .setView(
                context, R.layout.shadow_receiver
            )
            .setRegistryId("someId.glb")
            .build()
            .thenAccept { viewRenderable: ViewRenderable ->
                // If the selection visualizer already has a footprint renderable, then it was set to
                // something custom. Don't override the custom visual.
                viewRenderable.isShadowCaster = false
                viewRenderable.isShadowReceiver = true
                selectionVisualizer.setFootprintRenderable(viewRenderable)
            }

@ThomasGorisse
Copy link
Contributor

@grassydragon @RGregat Any idea?

@RGregat
Copy link
Contributor

RGregat commented Mar 12, 2022

@kelvinwatson you want to get something like this ?
image

I quickly created a default plane in Blender and exported it as a glb file.
plane.zip

I also disabled the PlaneRender to not act as a shadow receiver

...
sceneView = view.findViewById<ArSceneView?>(R.id.sceneView).apply {
            planeRenderer.isVisible = false
            planeRenderer.isEnabled = false
            lightEstimationMode = LightEstimationMode.DISABLED
...

planeNode = ArModelNode()
planeNode.loadModelAsync(context = requireContext(),
   coroutineScope = lifecycleScope,
   glbFileLocation = "models/plane.glb",
   onLoaded = {
       it.isShadowCaster = false
       it.isShadowReceiver = true
})

Is that close to what you want achieve?

@kelvinwatson
Copy link
Author

kelvinwatson commented Mar 13, 2022 via email

@kelvinwatson
Copy link
Author

kelvinwatson commented Mar 15, 2022

Actually what we really want to achieve is this. A faded/gray shadow that disappears when you rotate it upwards/downwards

Sorry about the bad quality of the gif.

@ThomasGorisse
Copy link
Contributor

Do you have the source code and model files of your sample?

@kelvinwatson
Copy link
Author

kelvinwatson commented Mar 15, 2022

@ThomasGorisse I'm currently actually using the archived SceneForm library in my code. Unfortunately I am unable to share the model since it is company owned.

class MySceneView : SceneView {
    fun onModelRenderable( threeDimensionalModel:ModelRenderable) {
        threeDimensionalModel.isShadowCaster = true
        //        threeDimensionalModel.isShadowReceiver=true


        val resources = context.resources

        val selectionVisualizer = FootprintSelectionVisualizer()
        val transformationSystem = TransformationSystem(resources.displayMetrics, selectionVisualizer)


        ModelRenderable.builder()
            .setSource(
                context,
                RenderableSource.Builder().setSource(context, Uri.parse("models/sceneform_footprint.glb"), RenderableSource.SourceType.GLB)
                    .setScale(3f)
                    .build()
            )
            .setRegistryId("models/sceneform_footprint.glb")
            .build()
            .thenAccept { renderable: ModelRenderable ->
                
                renderable.isShadowCaster = false
                renderable.isShadowReceiver = true
                selectionVisualizer.setFootprintRenderable(renderable)
            }


        val node = DragTransformableNode(1f, transformationSystem, ::onRotation).also {
            // required min and max scale so as not to shrink model below 1f during pinch
            it.scaleController.minScale = 1f
            it.scaleController.maxScale = 2f
            it.renderable = threeDimensionalModel

            scene.addChild(it)
//            it.select()

//            val myLight: Light = Light.builder(Light.Type.FOCUSED_SPOTLIGHT)
//                .setColor(com.google.ar.sceneform.rendering.Color(android.graphics.Color.RED))
//                .setShadowCastingEnabled(true)
//                .build()
//
//             it.light=myLight

            scene.sunlight?.light?.intensity = 1000f
//            scene.sunlight?.light?.color = com.google.ar.sceneform.rendering.Color(android.graphics.Color.GREEN)

        }

The above gives me something like this:

@ThomasGorisse
Copy link
Contributor

Sorry, I won't be able to help you on the archived version.
You will have to move to SceneView

@kelvinwatson
Copy link
Author

kelvinwatson commented Mar 19, 2022

Hi @ThomasGorisse. Filament says here that it supports Percentage Closer Soft Shadow (PCSS) and Variance Shadow Mapping (VSM) which sounds like what I need (for a blurry/soft shadow). Do you know how I could access those shadow rendering techniques through your SceneView?

@kelvinwatson
Copy link
Author

Just checked with Romain Guy. He says View.setShadowType and View.setVsmShadowOptions are the ways to access the VSM shadow in filament.

@grassydragon
Copy link
Contributor

I'm closing this issue since it is related to Sceneform and a solution for soft shadows has been found.

@kelvinwatson
Copy link
Author

kelvinwatson commented May 24, 2022 via email

@grassydragon
Copy link
Contributor

Can you reference the solution that was found for soft shadows?

I've thought this is it:

Just checked with Romain Guy. He says View.setShadowType and View.setVsmShadowOptions are the ways to access the VSM shadow in filament.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants