ARCore Android:单个SurfaceView能否加载多对象并单独旋转指定对象?
Absolutely, both of these are totally feasible in ARCore for Android—let’s walk through how this works and how to implement it:
1. Loading Multiple Virtual Objects on a Single SurfaceView
ARCore’s rendering pipeline is built to support this out of the box. The SurfaceView (or the more commonly used ArSceneView wrapper in Sceneform) acts as your rendering canvas, and you just need to manage and draw each virtual object independently within the render loop.
- If you’re using Sceneform (Google’s high-level AR library), this is super straightforward: each virtual object is represented by a
Nodewith an attachedRenderable. You can add as manyNodeinstances as needed to theArSceneView’s scene—each will render on the same SurfaceView as long as they’re part of the scene graph. - For raw OpenGL implementations, you’ll maintain a list of objects, each with their own model matrix (storing position, rotation, scale). In your
onDrawFramemethod, loop through this list, apply each object’s matrix to the shader, and draw the object mesh one by one.
2. Rotating a Single Object While Others Stay Still
This all comes down to isolating the transform properties of each object. Every virtual object should have its own independent pose (position/rotation/scale) state—when you want to modify one, you only update that object’s state, leaving others untouched.
Example with Sceneform (Kotlin)
Here’s a quick snippet to show how to add two objects and rotate just one when tapped:
// Initialize your ArSceneView val arSceneView = findViewById<ArSceneView>(R.id.ar_scene_view) // Create and add first object (red cube) val cubeNode = Node().apply { setParent(arSceneView.scene) localPosition = Vector3(0f, 0f, -1f) // 1m in front of camera renderable = ShapeFactory.makeCube( Vector3(0.1f, 0.1f, 0.1f), Vector3.zero(), MaterialFactory.makeOpaqueWithColor(this@MainActivity, Color.RED) ) } // Create and add second object (blue sphere) val sphereNode = Node().apply { setParent(arSceneView.scene) localPosition = Vector3(0.5f, 0f, -1f) // 0.5m right of the cube renderable = ShapeFactory.makeSphere( 0.05f, Vector3.zero(), MaterialFactory.makeOpaqueWithColor(this@MainActivity, Color.BLUE) ) } // Rotate only the cube when tapped cubeNode.setOnTapListener { _, _ -> // Rotate 90 degrees around the Y-axis cubeNode.localRotation = cubeNode.localRotation * Quaternion.axisAngle(Vector3(0f, 1f, 0f), 90f) }
Key Concept
The core idea is that each object’s transform (rotation in this case) is stored separately. When you update the rotation of cubeNode, the sphereNode’s rotation (and position) stays unchanged because it’s managed in its own Node instance. For OpenGL, you’d modify only the target object’s model matrix rotation component instead of touching others.
To make this interactive (like rotating via touch gestures), use Android’s GestureDetector to track finger movements, map those movements to rotation angles, and apply the change only to the selected object (you’ll need a hit-test to determine which object the user tapped).
内容的提问来源于stack exchange,提问作者Shubham Sejpal

