Table of Contents

Cómo cargar contenido 3D en tiempo de ejecución en xr-frame para escenarios AR

Este artículo detalla el mecanismo de separación entre carga de recursos y montaje de nodos en xr-frame, implementando dinámicamente mediante scripts el montaje flexible de contenido 3D bajo nodos Block para lograr AR.

Material oficial

El material oficial ya contiene explicaciones suficientes sobre cómo cargar contenido 3D en tiempo de ejecución. Este artículo solo resume brevemente algunos contenidos y métodos de carga comúnmente utilizados en escenarios AR.

Carga de recursos vs Montaje de nodos

En xr-frame, mostrar un modelo 3D consta de dos etapas:

  1. Carga de recursos: Descargar y analizar el archivo del modelo (por ejemplo, .glb) desde la red o localmente a la memoria. En este punto el modelo está listo pero no es visible en la escena.

  2. Montaje de nodos: Crear un nodo en el árbol de escena y asociar el recurso cargado a este nodo. Solo entonces el modelo aparecerá en el lienzo de renderizado.

Cómo cargar contenido 3D dinámicamente mediante código

  1. Carga de recursos

    Usar el sistema de gestión de recursos de la escena xr-frame para llamar a loadAsset manualmente.

    El parámetro type indica el tipo de recurso, assetId es el id del recurso después de cargar, src es la url del recurso, generalmente la dirección del servidor donde está alojado.

    Es necesario registrar assetId para su posterior montaje y liberación de recursos.

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

    Usar element.addChild() para colocar el modelo cargado bajo ShadowRoot.

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

    El elemento ShadowRoot es un nodo raíz especial de xr-frame para prevenir la creación y eliminación dinámica de nodos. Ver más en Nodo Shadow.

    Usar el método createXRNodeFromNodeAnnotation proporcionado por el objeto plugin permite crear nodos hijos de Block según datos EMA, asegurando que el contenido 3D se muestre en la posición espacial correcta.

    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);
    

Cómo montar contenido directamente bajo Block sin usar anotaciones

Advertencia

El requisito para usar este método es que haya verificado que los valores de LocalTransform en el sistema de coordenadas de xr-frame logran el efecto de renderizado deseado.

En otros casos, utilice la función de anotación del editor de Unity.

Obtener el objeto nodo block en el árbol de escena mediante getBlockById(id). Si no existe el nodo block correspondiente, significa que la localización de este Block aún no ha tenido éxito (el nodo se crea automáticamente al localizar el Block por primera vez). Puede usar holdBlock(blockInfo, blockTransformInput) para crear un nodo para este Block, o determinar el éxito de la localización en la devolución de llamada antes de montar contenido.

Consejo

En el árbol de escena del editor de Unity, seleccione el nodo Block y registre el ID mostrado en el panel Inspector

BlockID en el editor de Unity

También puede consultar el Block ID en la página de la biblioteca de localización en la nube

BlockID en la biblioteca de localización

const blockID = "aaaa1234-bbbb-cccc-dddd-eeeeee123456"
if (!blockHolder.getBlockById(blockParent.id)) {
    // No existe nodo Block, crear uno
    blockHolder.holdBlock({
        id: blockID
    })
}
let blockElement = blockHolder.getBlockById(blockParent.id).el;

Montar el nodo del modelo bajo el Block especificado, usando position.setArray(), quaternion.set() y scale.setArray() para modificar el LocalTransform del nodo del modelo.

export interface LocalTransform {
    /** @description Posición */
    position: xrfs.Vector3;
    /** @description Rotación */
    rotation: xrfs.Quaternion;
    /** @description Escala */
    scale: xrfs.Vector3;
}

// Suponiendo un LocalTransform conocido bajo 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 soportados por xr-frame

  • Texture texturas e imágenes
  • CubeTexture texturas cúbicas
  • VideoTexture texturas de video
  • EnvData entorno
  • GLTF modelos
  • Keyframe animación cuadro por cuadro
  • Atlas atlas de texturas

Los métodos detallados de carga para cada recurso se encuentran en la documentación oficial de WeChat y en los ejemplos oficiales de xr-frame

Nota

Formatos y extensiones GLTF soportados, consultar la especificación GLTF oficial de xr-frame