Table of Contents

Comment charger du contenu 3D dans des scenes AR au runtime avec xr-frame

Cet article décrit en détail le mécanisme de séparation entre resource loading et node mounting dans xr-frame. Grâce à des scripts dynamiques, le contenu 3D peut être monté de manière flexible sous les nodes Block afin de réaliser l'AR.

Ressources officielles

Les ressources officielles expliquent déjà suffisamment comment charger du contenu 3D au runtime. Cet article ne présente brièvement que certains contenus et méthodes de chargement couramment utilisés dans les scenes AR.

Resource loading vs node mounting

Dans xr-frame, l'affichage d'un modèle 3D se divise en deux étapes:

  1. Resource loading: télécharger un fichier de modèle (par exemple .glb) depuis le réseau ou en local, puis le parser en mémoire. À ce moment, le modèle est prêt mais n'est pas visible dans la scene.

  2. Node mounting: créer un node dans le scene tree et associer la resource chargée à ce node. Le modèle apparaît alors officiellement dans le rendering canvas.

Comment charger dynamiquement du contenu 3D avec du code

  1. Resource loading

    Chargez manuellement les resources en appelant loadAsset via le système de gestion des resources de la scene xr-frame.

    Le paramètre type indique le type de resource, assetId l'id de la resource après chargement, et src l'url de la resource, généralement l'adresse du resource hosting server.

    Il faut enregistrer assetId pour le mounting ultérieur et la libération des resources.

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

    Utilisez element.addChild() pour placer le modèle chargé sous ShadowRoot.

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

    L'élément ShadowRoot est le root node spécialement utilisé par xr-frame pour empêcher la création et la suppression dynamiques de nodes. Voir Shadow node pour plus de détails.

    La méthode createXRNodeFromNodeAnnotation fournie par le plugin object permet de créer les child nodes de Block à partir des données EMA, afin que le contenu 3D s'affiche à la bonne position spatiale.

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

Comment monter directement du contenu sous Block sans utiliser annotation

Avertissement

Le prérequis pour utiliser cette méthode est que vous ayez vérifié que la valeur LocalTransform peut produire l'effet de rendering attendu dans le système de coordonnées xr-frame.

Dans les autres cas, veuillez utiliser la fonction annotation de Unity Editor.

Obtenez le block node object dans le scene tree via getBlockById(id). Si le block node correspondant n'existe pas, cela signifie que la localization de ce Block n'a pas encore réussi (le node sera créé automatiquement lors de la première localization réussie de ce Block). Vous pouvez utiliser holdBlock(blockInfo, blockTransformInput) pour créer un node pour ce Block, ou attendre dans le localization callback que la localization de ce Block réussisse avant de monter le contenu.

Astuce

Sélectionnez le node Block dans le scene tree de Unity Editor et notez l'ID affiché dans le panneau Inspector

BlockID dans Unity Editor

Vous pouvez aussi trouver le Block ID sur la page de la cloud localization library

BlockID dans localization library

const blockID = "aaaa1234-bbbb-cccc-dddd-eeeeee123456"
if (!blockHolder.getBlockById(blockParent.id)) {
    // aucun noeud Block n existe ; en creer un
    blockHolder.holdBlock({
        id: blockID
    })
}
let blockElement = blockHolder.getBlockById(blockParent.id).el;

Montez le model node sous le Block spécifié, puis utilisez position.setArray(), quaternion.set() et scale.setArray() pour modifier le LocalTransform du model node.

export interface LocalTransform {
    /** @description position */
    position: xrfs.Vector3;
    /** @description rotation */
    rotation: xrfs.Quaternion;
    /** @description Scale */
    scale: xrfs.Vector3;
}

// suppose qu un LocalTransform connu existe sous 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
    ]);

Types de resources pris en charge par xr-frame

  • Texture, textures et images
  • CubeTexture, textures cubiques
  • VideoTexture, textures vidéo
  • EnvData, environment
  • GLTF models
  • Keyframe, frame animation
  • Atlas

Les méthodes détaillées de chargement de chaque resource sont disponibles dans la documentation officielle WeChat et les exemples officiels xr-frame

Note

Pour les formats et extensions GLTF pris en charge, consultez les instructions officielles xr-frame d'utilisation de GLTF