google-ar / sceneform-android-sdk

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

Using Sceneform for 3D rendering without AR #788

Open tigran-babajanyan opened 5 years ago

tigran-babajanyan commented 5 years ago

I use SceneView for 3d rendering instead of ArSceneView and ArFragment, It show my model but user unable to scale or rotate model. Is this the reason of my possible mistake or this is a common problem? Maybe I have to implement touch events myself ?

tonilsz commented 5 years ago

Is your model renderable of TransformableNode object?

tigran-babajanyan commented 5 years ago

@tonilsz I replaced it to TransformableNode, now gestures works, but that are the same gestures as for ArSeneview that ar not suitable for 3D, for example I cannot rotate model with one finger

tonilsz commented 5 years ago

Depending of the gestures you need, I suppose that you don't need to translate the object, you will want to rotate dragging and scale with a pinch gesture. So, you have two options:

1- Avoid to use transformable node and implement your own gestures, scales and rotations.

2- Continue using Transformable node for it's facilities, then you only have to remove the translation controller and implement a new rotation controller. You can try starting from a copy of TransformableNode for the gestures and the structure and take a look on RotationController for the rotation functionality.

Good luck ;)

tigran-babajanyan commented 5 years ago

@tonilsz I removed translation controller and added new rotation controller, now it rotating on dragging, thats fine. Now I have to make it rotate vertically(to see top side of model). I successed to rotate it vertically, but only around anchor (bottom side of model). Can you suggest any way to rotate it around it's middle side? Thanks a lot

chnouman commented 4 years ago

@tigran-babajanyan any success in veritcal rotation?

tigran-babajanyan commented 4 years ago

@chnouman finally we implemented all kind of rotations (vertical, horizontal) by transforming camera

chnouman commented 4 years ago

@tigran-babajanyan can you share something because I'm having an issue in vertical rotation.

chnouman commented 4 years ago

@tigran-babajanyan it will be a great favor for me.

tigran-babajanyan commented 4 years ago

@chnouman Use this as your node

import com.google.ar.sceneform.ux.TransformableNode
import com.google.ar.sceneform.ux.TransformationSystem

class DragTransformableNode(val radius: Float, transformationSystem: TransformationSystem) :
    TransformableNode(transformationSystem) {
    val dragRotationController = DragRotationController(
        this,
        transformationSystem.dragRecognizer
    )
}
import android.os.Handler
import com.google.ar.sceneform.Node
import com.google.ar.sceneform.math.Quaternion
import com.google.ar.sceneform.math.Vector3
import com.google.ar.sceneform.ux.BaseTransformationController
import com.google.ar.sceneform.ux.DragGesture
import com.google.ar.sceneform.ux.DragGestureRecognizer

class DragRotationController(
    private val transformableNode: DragTransformableNode,
    gestureRecognizer: DragGestureRecognizer
) :
    BaseTransformationController<DragGesture>(transformableNode, gestureRecognizer) {

    companion object {

        private const val initialLat = 26.15444376319647
        private const val initialLong = 18.995950736105442

        var lat: Double = initialLat
        var long: Double = initialLong
    }

    // Rate that the node rotates in degrees per degree of twisting.
    private var rotationRateDegrees = 0.1f

    public override fun canStartTransformation(gesture: DragGesture): Boolean {
        return transformableNode.isSelected
    }

    private fun getX(lat: Double, long: Double): Float {
        return (transformableNode.radius * Math.cos(Math.toRadians(lat)) * Math.sin(Math.toRadians(long))).toFloat()
    }

    private fun getY(lat: Double, long: Double): Float {
        return transformableNode.radius * Math.sin(Math.toRadians(lat)).toFloat()
    }

    private fun getZ(lat: Double, long: Double): Float {
        return (transformableNode.radius * Math.cos(Math.toRadians(lat)) * Math.cos(Math.toRadians(long))).toFloat()
    }

    override fun onActivated(node: Node?) {
        super.onActivated(node)
        Handler().postDelayed({
            transformCamera(lat, long)
        }, 0)
    }

    public override fun onContinueTransformation(gesture: DragGesture) {

        val rotationAmountY = gesture.delta.y * rotationRateDegrees
        val rotationAmountX = gesture.delta.x * rotationRateDegrees
        val deltaAngleY = rotationAmountY.toDouble()
        val deltaAngleX = rotationAmountX.toDouble()

        long -= deltaAngleX
        lat += deltaAngleY

        lat = Math.max(Math.min(lat, 90.0), 0.0)

        transformCamera(lat, long)
    }

    private fun transformCamera(lat: Double, long: Double) {
        val camera = transformableNode.scene?.camera

        var rot = Quaternion.eulerAngles(Vector3(0F, 0F, 0F))
        val pos = Vector3(getX(lat, long), getY(lat, long), getZ(lat, long))
        rot = Quaternion.multiply(rot, Quaternion(Vector3.up(), (long).toFloat()))
        rot = Quaternion.multiply(rot, Quaternion(Vector3.right(), (-lat).toFloat()))
        camera?.localRotation = rot
        camera?.localPosition = pos
    }

    fun resetInitialState() {
        transformCamera(initialLat, initialLong)
    }

    public override fun onEndTransformation(gesture: DragGesture) {}

}
chnouman commented 4 years ago

@tigran-babajanyan thank you so much let me give it a try.

tigran-babajanyan commented 4 years ago

@chnouman please play with radius parameter to see your model in correct scale

chnouman commented 4 years ago

@tigran-babajanyan sure thanks.

tigran-babajanyan commented 4 years ago

Yes I have put it above @chnouman

chnouman commented 4 years ago

@tigran-babajanyan this is reasonable approach but I'm unable to see the model from top and from back side of model. Can you share in which app you are using this so that I can try the ux.

chnouman commented 4 years ago

@tigran-babajanyan tweaking with radius worked thanks a lot man.

chnouman commented 4 years ago

@olancedev review this https://github.com/chnouman/SceneView.

chnouman commented 4 years ago

@olancedev what issue you are facing in that?

chnouman commented 4 years ago

@olancedev I have pushed a new commit check now.

chnouman commented 4 years ago

@olancedev cheers and don't forget to give credit to @tigran-babajanyan and his team.

chnouman commented 4 years ago

@olancedev can you please post it on Stackoverflow so that we can keep the threads small and explorable. I'll answer there.