Table of Contents

Como carregar conteúdo 3D em tempo de execução no xr-frame para cenários AR

Este artigo detalha o mecanismo de separação entre carregamento de recursos e montagem de nós no xr-frame, implementando dinamicamente a montagem flexível de conteúdo 3D sob nós Block via script para realizar AR.

Documentação oficial

A documentação oficial já possui conteúdo suficiente sobre como carregar conteúdo 3D em tempo de execução. Este artigo resume apenas alguns conteúdos e métodos de carregamento comumente usados em cenários AR.

Carregamento de recursos vs montagem de nós

No xr-frame, exibir um modelo 3D envolve duas etapas:

  1. Carregamento de recursos: Refere-se ao download e análise do arquivo de modelo (ex: .glb) da rede ou local para a memória. Neste ponto, o modelo está pronto, mas não é visível na cena.

  2. Montagem de nós: Refere-se à criação de um nó na árvore de cena e à associação do recurso carregado a esse nó. Somente então o modelo aparece na tela de renderização.

Como carregar conteúdo 3D dinamicamente usando código

  1. Carregamento de recursos

    Use o sistema de gerenciamento de recursos da cena do xr-frame para chamar loadAsset manualmente.

    O parâmetro type indica o tipo de recurso, assetId é o id do recurso após o carregamento, src é a URL do recurso, geralmente o endereço do servidor de hospedagem.

    Registre o assetId para uso posterior na montagem e liberação do recurso.

    try {
        await scene.assets.loadAsset({type: 'gltf', assetId: 'panda', src: 'url/EasyARPanda.glb'});
    } catch (err) {
        console.error(`Failed to load assets: ${err.message}`);
    }
    
  2. Montagem de nós

    Use element.addChild() para colocar o modelo carregado sob o ShadowRoot.

    const root = scene.getElementById("shadow-root");
    let panda = scene.createElement(xrFrameSystem.XRGLTF,
        {
            "model": "panda",
            "anim-autoplay": ""
        }
    );
    root.addChild(panda);
    

    O elemento ShadowRoot é um nó raiz especial do xr-frame para criação e remoção dinâmica de nós. Consulte Nó Shadow para detalhes.

    O método createXRNodeFromNodeAnnotation fornecido pelo objeto do plug-in pode criar um nó filho do Block com base nos dados EMA, garantindo que o conteúdo 3D seja exibido na posição espacial correta.

    const nodeAnnotation = annotation as easyar.ema.v0_5.Node;
    const xrNode: xrfs.XRNode = easyarPlugin.createXRNodeFromNodeAnnotation(nodeAnnotation, blockHolder);
    let panda = scene.createElement(xrFrameSystem.XRGLTF,
        {
            "model": "panda",
            "anim-autoplay": ""
        }
    );
    xrNode.addChild(panda);
    

Como montar conteúdo diretamente sob o Block sem usar anotações

Aviso

O pré-requisito para usar este método é que você tenha verificado que os valores do LocalTransform no sistema de coordenadas do xr-frame produzem o efeito de renderização desejado.

Para outros casos, use a funcionalidade de anotação do editor Unity.

Use getBlockById(id) para obter o objeto do nó block na árvore de cena. Se o nó block correspondente não existir, significa que a localização desse Block ainda não teve sucesso (o nó é criado automaticamente na primeira localização bem-sucedida). Você pode usar holdBlock(blockInfo, blockTransformInput) para criar um nó para esse Block, ou verificar o sucesso da localização no callback antes de montar o conteúdo.

Dica

No editor Unity, selecione o nó Block na árvore de cena e anote o ID exibido no painel Inspector.

BlockID no editor Unity

Você também pode encontrar o Block ID na página da biblioteca de localização na nuvem.

BlockID na biblioteca de localização

const blockID = "aaaa1234-bbbb-cccc-dddd-eeeeee123456"
if (!blockHolder.getBlockById(blockParent.id)) {
    // Não existe nó Block, crie um
    blockHolder.holdBlock({
        id: blockID
    })
}
let blockElement = blockHolder.getBlockById(blockParent.id).el;

Monte o nó do modelo sob o Block especificado. Use position.setArray(), quaternion.set() e scale.setArray() para modificar o LocalTransform do nó do modelo.

export interface LocalTransform {
    /** @description Posição */
    position: xrfs.Vector3;
    /** @description Rotação */
    rotation: xrfs.Quaternion;
    /** @description Escala */
    scale: xrfs.Vector3;
}

// Suponha um LocalTransform conhecido sob o Block
const targetTransform: LocalTransform;

blockElement.addChild(modelNode);
let modelTransform = modelNode.getComponent(xrFrameSystem.Transform);
    modelTransform.position.setArray([
        targetTransform.position.x,
        targetTransform.position.y,
        targetTransform.position.z
    ]);
    let annoRotation = new xrFrameSystem.Quaternion().setValue(
        targetTransform.rotation.x,
        targetTransform.rotation.y,
        targetTransform.rotation.z,
        targetTransform.rotation.w
    );
    modelTransform.quaternion.set(annoRotation);
    modelTransform.scale.setArray([
        targetTransform.scale.x,
        targetTransform.scale.y,
        targetTransform.scale.z
    ]);

Tipos de recursos suportados pelo xr-frame

  • Texture Texturas e imagens
  • CubeTexture Texturas cúbicas
  • VideoTexture Texturas de vídeo
  • EnvData Ambiente
  • GLTF Modelos
  • Keyframe Animações de quadro-chave
  • Atlas Atlas de sprites

Os métodos detalhados de carregamento para cada tipo de recurso estão na documentação oficial do WeChat e nos exemplos oficiais do xr-frame.

Nota

Formatos GLTF suportados e extensões: consulte Especificações GLTF do xr-frame