Skip to content

Blazor 3D Integration #163

@hernandoz

Description

@hernandoz

Hi , I am trying to load a 3d model to azure maps in Blazor .net9 webassembly , I can load the maps ok , but I cannot get to load the 3 model, I am following this example https://github.com/Azure-Samples/AzureMapsCodeSamples/blob/main/Samples/3D-layer/three.js/three.js.html , but i am having problem converting the html code to blazer , I have created a map.js script that load the map fine but I dont how to create the render and add the layer to the map.

is there a blazor example available or can someone explain to me how to write a new script , sorry I am c# developer but never used JS before .

this the current script but i have an error on the loader: new GLTFLoader(), ReferenceError: GLTFLoader is not defined

//script map.js
var map, layer;

// 3D model to render
var modelDetails = {
    url: "/3d-layer/three.js/parrot.glb",
    origin: [-122.128929, 47.644042],
    mercatorOrigin: atlas.data.MercatorPoint.fromPosition([-122.128929, 47.644042]),
    rotateX: Math.PI / 2,
    rotateY: 0,
    rotateZ: 0,
    scale: 1e-7,
    animate: true
};

// Create a renderer that implements atlas.WebGLRenderer
var renderer = {
    renderingMode: "3d",
    loader: new GLTFLoader(),
    modelDetails: modelDetails,

    // Method called when the layer is added to the map
    onAdd: function (map, gl) {
        this.map = map;
        this.camera = new THREE.Camera();
        this.scene = new THREE.Scene();
        this.clock = new THREE.Clock();

        // Create lights to illuminate the model
        var directionalLight = new THREE.DirectionalLight(0xffffff);
        directionalLight.position.set(0, 70, 100).normalize();
        this.scene.add(directionalLight);

        var ambientLight = new THREE.AmbientLight(0x808080);
        this.scene.add(ambientLight);

        // Load the model
        this.loadModel();

        // Use the Azure Maps map canvas for three.js
        this.renderer = new THREE.WebGLRenderer({
            canvas: map.getCanvas(),
            context: gl
        });

        this.renderer.autoClear = false;
    },

    // Method called on each animation frame
    render: function (gl, matrix) {
        var md = this.modelDetails;

        if (md) {
            var rotationX = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(1, 0, 0), md.rotateX);
            var rotationY = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 1, 0), md.rotateY);
            var rotationZ = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 0, 1), md.rotateZ);

            var m = new THREE.Matrix4().fromArray(matrix);
            var l = new THREE.Matrix4()
                .makeTranslation(md.mercatorOrigin[0], md.mercatorOrigin[1], md.mercatorOrigin[2])
                .scale(new THREE.Vector3(md.scale, -md.scale, md.scale))
                .multiply(rotationX)
                .multiply(rotationY)
                .multiply(rotationZ);

            this.camera.projectionMatrix.elements = matrix;
            this.camera.projectionMatrix = m.multiply(l);
            this.renderer.resetState();
            this.renderer.render(this.scene, this.camera);
            this.renderer.resetState();
        }

        map.triggerRepaint();
    },

    loadModel: function () {
        var md = this.modelDetails;
        this.mixer = null;

        if (md) {
            // Use the three.js GLTF loader to add the 3D model to the three.js scene
            this.loader.load(
                md.url,
                function (gltf) {
                    this.gltfModelScene = gltf.scene;

                    this.scene.add(gltf.scene);

                    if (md.animate) {
                        this.mixer = new THREE.AnimationMixer(gltf.scene);
                        var action = this.mixer.clipAction(gltf.animations[0]);
                        action.play();

                        this.animate();
                    }
                }.bind(this)
            );

            this.map.setCamera({
                center: md.origin
            });
        }
    },

    animate: function () {
        if (this.mixer) {
            this.mixer.update(this.clock.getDelta());
            this.renderer.render(this.scene, this.camera);
            requestAnimationFrame(() => {
                this.animate();
            });
        }
    }
};


window.AzureMap = {
    map: null,
    layer: null,
    LoadMap: function (subKey, lat, long) {

        this.map = new atlas.Map("mapContainer", {
            authOptions: {
                authType: 'subscriptionKey',
                subscriptionKey: subKey
            },
            view: "Auto",
            center: [long, lat],
            zoom: 17.5

        });

        map.events.add("ready", function () {
            // Create a WebGL layer
            layer = new atlas.layer.WebGLLayer("3d-model", { renderer });
            // Add the layer to the map
            map.layers.add(layer);

            // Add controls
            map.controls.add(
                [
                    new atlas.control.ZoomControl(),
                    new atlas.control.PitchControl(),
                    new atlas.control.CompassControl(),
                    new atlas.control.StyleControl({
                        mapStyles: "all"
                    })
                ],
                {
                    position: "top-right"
                }
            );
        });
    }
}

thanks for your help.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions