Table of Contents

Wie man 3D-Inhalte zur Laufzeit in xr-frame in AR-Szenen lädt

Dieser Artikel erläutert detailliert den Trennmechanismus zwischen Ressourcenladen und Knoteneinhängen in xr-frame. Durch dynamische Skripterstellung wird eine flexible Einhängung von 3D-Inhalten unter Block-Knoten realisiert, um AR zu ermöglichen.

Offizielle Dokumentation

Die offizielle Dokumentation enthält bereits umfassende Erklärungen zum Laden von 3D-Inhalten zur Laufzeit. Dieser Artikel beschreibt nur kurz einige in AR-Szenen häufig verwendete Inhalte und Lademethoden.

Ressourcenladen vs. Knoteneinhängen

In xr-frame ist die Anzeige eines 3D-Modells in zwei Phasen unterteilt:

  1. Ressourcenladen: Bezieht sich auf das Herunterladen und Parsen der Modelldatei (z.B. .glb) aus dem Netzwerk oder lokal in den Speicher. Das Modell ist nun bereit, aber in der Szene noch nicht sichtbar.

  2. Knoteneinhängen: Bezieht sich auf das Erstellen eines Knotens in der Szenenbaumstruktur und das Verknüpfen der geladenen Ressource mit diesem Knoten. Erst dann erscheint das Modell auf dem Render-Canvas.

Wie man 3D-Inhalte dynamisch per Code lädt

  1. Ressourcenladen

    Manuelles Laden von Ressourcen durch Aufruf von loadAsset über das Ressourcenverwaltungssystem der xr-frame-Szene.

    type im Parameter gibt den Ressourcentyp an, assetId die Ressourcen-ID nach dem Laden, src die URL der Ressource (normalerweise die Adresse des Ressourcen-Hosting-Servers).

    assetId muss für nachfolgendes Einhängen und Freigeben von Ressourcen 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. Knoteneinhängen

    Verwenden von 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 spezieller Wurzelknoten in xr-frame für das dynamische Erstellen und Entfernen von Knoten. Siehe Shadow-Knoten.

    Die Methode createXRNodeFromNodeAnnotation des Plugin-Objekts ermöglicht das Erstellen von Block-Unterknoten basierend auf EMA-Daten, um die korrekte Positionierung von 3D-Inhalten sicherzustellen.

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

Wie man Inhalte ohne Annotation direkt unter einem Block einhängt

Warnung

Voraussetzung für diese Methode ist, dass Sie verifiziert haben, dass die LocalTransform-Werte im xr-frame-Koordinatensystem das gewünschte Rendering-Ergebnis liefern.

In allen anderen Fällen verwenden Sie bitte die Annotierungsfunktion des Unity-Editors.

Verwenden Sie getBlockById(id), um das Block-Knotenobjekt im Szenenbaum zu erhalten. Wenn kein entsprechender Block-Knoten existiert, wurde dieser Block noch nicht erfolgreich lokalisiert (der Knoten wird automatisch bei der ersten erfolgreichen Lokalisierung erstellt). Sie können mit holdBlock(blockInfo, blockTransformInput) einen Block-Knoten erstellen oder in der Lokalisierungsrückruffunktion prüfen, ob die Block-Lokalisierung erfolgreich war, bevor Sie Inhalte einhängen.

Tipp

Wählen Sie im Szenenbaum des Unity-Editors den Block-Knoten aus und notieren Sie die im Inspector-Panel angezeigte ID

BlockID im Unity-Editor

Die Block-ID kann auch auf der Cloud-Lokalisierungsbibliotheksseite gefunden werden

BlockID in der Lokalisierungsbibliothek

const blockID = "aaaa1234-bbbb-cccc-dddd-eeeeee123456"
if (!blockHolder.getBlockById(blockParent.id)) {
    // Kein existierender Block-Knoten, erstelle einen
    blockHolder.holdBlock({
        id: blockID
    })
}
let blockElement = blockHolder.getBlockById(blockParent.id).el;

Hängen Sie den Modellknoten unter den spezifizierten Block und setzen Sie den LocalTransform des Modellknotens mit position.setArray(), quaternion.set() und scale.setArray().

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

// Angenommen, es gibt einen bekannten LocalTransform unter dem 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
    ]);

Von xr-frame unterstützte Ressourcentypen

  • Texture Texturen und Bilder
  • CubeTexture Würfeltexturen
  • VideoTexture Videotexturen
  • EnvData Umgebung
  • GLTF Modelle
  • Keyframe Keyframe-Animationen
  • Atlas Texturatlas

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

Anmerkung

Unterstützte GLTF-Formate und Erweiterungen siehe xr-frame offizielle GLTF-Spezifikation