Table of Contents

3D-Inhalte in AR-scenes zur Laufzeit in xr-frame laden

Dieser Artikel erläutert den Trennmechanismus von resource loading und node mounting in xr-frame. Durch dynamische scripts können 3D-Inhalte flexibel unter Block nodes montiert werden, um AR zu realisieren.

Offizielle Materialien

Die offiziellen Materialien erklären bereits ausführlich, wie 3D-Inhalte zur Laufzeit geladen werden. Dieser Artikel beschreibt nur kurz einige häufig verwendete Inhalte und Lademethoden in AR-scenes.

Resource loading vs node mounting

In xr-frame besteht das Anzeigen eines 3D-Modells aus zwei Phasen:

  1. Resource loading: Modelldateien (z. B. .glb) werden aus dem Netzwerk oder lokal heruntergeladen und in den Speicher geparst. Zu diesem Zeitpunkt ist das Modell bereit, aber in der scene noch nicht sichtbar.

  2. Node mounting: In der scene tree wird ein node erstellt und die geladene resource diesem node zugeordnet. Erst dann erscheint das Modell offiziell auf dem rendering canvas.

3D-Inhalte dynamisch per Code laden

  1. Resource loading

    Laden Sie resources manuell, indem Sie loadAsset über das resource management system der xr-frame scene aufrufen.

    type in den Parametern bezeichnet den resource-Typ, assetId die resource id nach dem Laden und src die resource-url, normalerweise die Adresse des resource hosting server.

    assetId muss für späteres mounting und resource release gespeichert werden.

    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

    Verwenden Sie element.addChild(), um das geladene Modell unter ShadowRoot zu platzieren.

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

    Das ShadowRoot-Element ist ein root node, den xr-frame speziell zum Verhindern dynamischer node-Erstellung und -Entfernung verwendet. Details siehe Shadow node.

    Mit der vom plugin object bereitgestellten Methode createXRNodeFromNodeAnnotation können anhand von EMA-Daten child nodes von Block erstellt werden, sodass 3D-Inhalte an der richtigen räumlichen Position angezeigt werden.

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

Inhalte direkt unter Block ohne annotation montieren

Warnung

Voraussetzung für diese Methode ist, dass Sie überprüft haben, dass der LocalTransform-Wert im xr-frame-Koordinatensystem den erwarteten rendering effect erzielen kann.

In anderen Fällen verwenden Sie bitte die annotation-Funktion des Unity Editors.

Rufen Sie über getBlockById(id) das block node object im scene tree ab. Wenn der entsprechende block node nicht existiert, war die localization für diesen Block noch nicht erfolgreich (der node wird automatisch erstellt, wenn dieser Block zum ersten Mal lokalisiert wird). Sie können mit holdBlock(blockInfo, blockTransformInput) einen node für diesen Block erstellen oder im localization callback prüfen, ob die localization dieses Block erfolgreich war, bevor Inhalte montiert werden.

Tipp

Wählen Sie im scene tree des Unity Editors den Block node aus und notieren Sie die im Inspector-Panel angezeigte ID

BlockID im Unity Editor

Sie können die Block ID auch auf der Seite der cloud localization library finden

BlockID in der localization library

const blockID = "aaaa1234-bbbb-cccc-dddd-eeeeee123456"
if (!blockHolder.getBlockById(blockParent.id)) {
    // 没有存在的 Block 节点,创建一个
    blockHolder.holdBlock({
        id: blockID
    })
}
let blockElement = blockHolder.getBlockById(blockParent.id).el;

Montieren Sie den model node unter dem angegebenen Block und verwenden Sie position.setArray(), quaternion.set() und scale.setArray(), um den LocalTransform des model node zu ändern.

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

// 假设有一个已知的在 Block 下的 LocalTransform
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
    ]);

Von xr-frame unterstützte resource-Typen

  • Texture, Texturen und Bilder
  • CubeTexture, Würfeltexturen
  • VideoTexture, Videotexturen
  • EnvData, environment
  • GLTF models
  • Keyframe, frame animation
  • Atlas

Detaillierte Lademethoden für jede resource finden Sie in der offiziellen WeChat-Dokumentation und den offiziellen xr-frame-Beispielen

Anmerkung

Unterstützte GLTF-Formate und extensions siehe offizielle GLTF-Nutzungsanleitung von xr-frame