You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android及ARCore中如何隐藏渲染3D模型的特定子节点?

Hey there! I've worked with ARCore on Android quite a bit, so let's walk through how to hide specific child nodes of a 3D model—including replicating that ARKit-style "find by name" functionality you're looking for. Here's what you need to know, broken down by the most common ARCore rendering frameworks:

1. Using Sceneform (Legacy but Widely Adopted)

Sceneform was the go-to for ARCore model rendering for a long time, and it makes node management straightforward. Here's how to find a child node by name and hide it:

Step 1: Load your model and get the root node

First, load your glTF/glb model and attach it to an AnchorNode (or a regular Node). Once loaded, grab the root node of your model:

ModelRenderable.builder()
    .setSource(context, R.raw.your_3d_model)
    .build()
    .thenAccept { renderable ->
        val modelRootNode = Node().apply {
            this.renderable = renderable
            name = "ModelRoot" // Optional: Name the root for easier debugging
        }
        // Attach the model node to your AR anchor node
        yourAnchorNode.addChild(modelRootNode)
        
        // Now find and hide your target child node
        val targetNode = findNodeByName(modelRootNode, "YourTargetChildName")
        targetNode?.isEnabled = false
    }
    .exceptionally { throwable ->
        Log.e("ARCore", "Failed to load model", throwable)
        null
    }

Step 2: Recursive node lookup method

Sceneform doesn't have a built-in findChildByName method, so we'll write a recursive function to search the node tree:

private fun findNodeByName(rootNode: Node?, targetName: String): Node? {
    if (rootNode == null) return null
    
    // Check if the current node matches the target name
    if (rootNode.name == targetName) {
        return rootNode
    }
    
    // Recursively check all child nodes
    for (childNode in rootNode.children) {
        val foundNode = findNodeByName(childNode, targetName)
        if (foundNode != null) return foundNode
    }
    
    return null
}

How it works

Setting isEnabled = false will completely hide the node and all its children, plus disable any interaction with it. If you only want to hide the node's renderable but keep interactions active, you can set targetNode.renderable = null instead.

2. Using Filament (Latest ARCore Recommendation)

Google now recommends using Filament for ARCore rendering, as it's more lightweight and flexible. Here's how to achieve the same result with Filament:

Step 1: Load your model and get the root entity

Filament uses an entity-component system, so your model will be represented as a tree of Entity objects. Load your model first:

val filamentEngine = ArCoreSession.getSession(context).engine
val assetLoader = AssetLoader.create(filamentEngine)
val gltfLoader = GltfLoader.create(filamentEngine)
val resourceLoader = ResourceLoader.create(filamentEngine)

// Load the model from raw resources
context.resources.openRawResource(R.raw.your_3d_model).use { inputStream ->
    val asset = gltfLoader.loadAsset(inputStream)
    assetLoader.loadResources(asset, resourceLoader)
    
    val rootEntity = asset.root
    // Find and hide the target entity
    val targetEntity = findEntityByName(filamentEngine, rootEntity, "YourTargetChildName")
    targetEntity?.let { hideEntity(filamentEngine, it) }
}

Step 2: Recursive entity lookup and hide methods

// Find an entity by name in the entity tree
private fun findEntityByName(engine: Engine, root: Entity, targetName: String): Entity? {
    val nameManager = engine.nameComponentManager
    // Check if the current entity has a name matching the target
    if (nameManager.hasComponent(root)) {
        if (nameManager.getName(root) == targetName) {
            return root
        }
    }
    
    // Recursively check all child entities
    val transformManager = engine.transformManager
    val childCount = transformManager.getChildCount(root)
    for (i in 0 until childCount) {
        val childEntity = transformManager.getChild(root, i)
        val foundEntity = findEntityByName(engine, childEntity, targetName)
        if (foundEntity != null) return foundEntity
    }
    
    return null
}

// Hide the target entity
private fun hideEntity(engine: Engine, entity: Entity) {
    val transformManager = engine.transformManager
    val currentVisibility = transformManager.getVisibility(entity)
    // Remove the VISIBLE flag from the entity's visibility mask
    transformManager.setVisibility(entity, currentVisibility and ~TransformManager.Visibility.VISIBLE)
}
3. Edge Cases & Pro Tips
  • Model Naming: Make sure your 3D model's child components have clear, unique names set in your 3D editor (like Blender or Maya) before exporting to glTF/glb. Without proper names, the lookup will fail.
  • Submeshes vs. Nodes: If your model's child parts are submeshes within a single node (not separate nodes), use Sceneform's setSubmeshEnabled method instead:
    val renderable = modelRootNode.renderable as ModelRenderable
    val submeshIndex = renderable.submeshNames.indexOf("TargetSubmesh")
    if (submeshIndex != -1) {
        renderable.setSubmeshEnabled(submeshIndex, false)
    }
    

内容的提问来源于stack exchange,提问作者raviteja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:46:34