Ala Eddine Menai
Ala Eddine Menai

Reputation: 2880

How to display collada file content ( xml ) on mapbox using ThreeJS?

I get my Collada file as XML file from an API:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
    <asset>
        <contributor>
            <authoring_tool>3D City Database Importer/Exporter, version 4.3.0; Chair of Geoinformatics, Technical University of Munich</authoring_tool>
        </contributor>
        <created>2023-05-11T18:09:11.587</created>
        <modified>2023-05-11T18:09:11.587</modified>
        <unit meter="1.0" name="meters"/>
        <up_axis>Z_UP</up_axis>
    </asset>
    <library_materials>
        <material id="default_ai_0.2_sh_0.2_tr_0.0_dc_r_1.0_g_0.2_b_0.2_sc_r_1.0_g_1.0_b_1.0_ec_r_0.0_g_0.0_b_0_mat">
            <instance_effect url="#default_ai_0.2_sh_0.2_tr_0.0_dc_r_1.0_g_0.2_b_0.2_sc_r_1.0_g_1.0_b_1.0_ec_r_0.0_g_0.0_b_0_eff"/>
        </material>
        <material id="default_ai_0.2_sh_0.2_tr_0.0_dc_r_0.8_g_0.8_b_0.8_sc_r_1.0_g_1.0_b_1.0_ec_r_0.0_g_0.0_b_0_mat">
            <instance_effect url="#default_ai_0.2_sh_0.2_tr_0.0_dc_r_0.8_g_0.8_b_0.8_sc_r_1.0_g_1.0_b_1.0_ec_r_0.0_g_0.0_b_0_eff"/>
        </material>
    </library_materials>
    <library_effects>
        <effect id="default_ai_0.2_sh_0.2_tr_0.0_dc_r_1.0_g_0.2_b_0.2_sc_r_1.0_g_1.0_b_1.0_ec_r_0.0_g_0.0_b_0_eff">
            <profile_COMMON>
                <technique sid="COMMON">
                    <lambert>
                        <emission>
                            <color>0.0 0.0 0.0 1.0</color>
                        </emission>
                        <diffuse>
                            <color>1.0 0.2 0.2 1.0</color>
                        </diffuse>
                        <reflective>
                            <color>1.0 1.0 1.0 1.0</color>
                        </reflective>
                        <reflectivity>
                            <float>0.2</float>
                        </reflectivity>
                        <transparent opaque="A_ONE">
                            <color>1.0 1.0 1.0 1.0</color>
                        </transparent>
                        <transparency>
                            <float>1.0</float>
                        </transparency>
                    </lambert>
                </technique>
                <extra>
                    <technique profile="GOOGLEEARTH">
                        <double_sided>0</double_sided>
                    </technique>
                </extra>
            </profile_COMMON>
        </effect>
        <effect id="default_ai_0.2_sh_0.2_tr_0.0_dc_r_0.8_g_0.8_b_0.8_sc_r_1.0_g_1.0_b_1.0_ec_r_0.0_g_0.0_b_0_eff">
            <profile_COMMON>
                <technique sid="COMMON">
                    <lambert>
                        <emission>
                            <color>0.0 0.0 0.0 1.0</color>
                        </emission>
                        <diffuse>
                            <color>0.8 0.8 0.8 1.0</color>
                        </diffuse>
                        <reflective>
                            <color>1.0 1.0 1.0 1.0</color>
                        </reflective>
                        <reflectivity>
                            <float>0.2</float>
                        </reflectivity>
                        <transparent opaque="A_ONE">
                            <color>1.0 1.0 1.0 1.0</color>
                        </transparent>
                        <transparency>
                            <float>1.0</float>
                        </transparency>
                    </lambert>
                </technique>
                <extra>
                    <technique profile="GOOGLEEARTH">
                        <double_sided>0</double_sided>
                    </technique>
                </extra>
            </profile_COMMON>
        </effect>
    </library_effects>
    <library_geometries>
        <geometry id="geometry0">
            <mesh>
                <source id="geometry0-position">
                    <float_array id="geometry0-position-array" count="36">9.117 -5.468 8.896 9.656 -1.254 6.29 0.0 0.0 6.29 -0.538 -4.215 8.896 -1.077 -8.429 6.29 0.0 0.0 0.0 -0.538 -4.215 0.0 -1.077 -8.429 0.0 9.656 -1.254 0.0 9.117 -5.468 0.0 8.578 -9.683 0.0 8.578 -9.683 6.29</float_array>
                    <technique_common>
                        <accessor count="12" source="#geometry0-position-array" stride="3">
                            <param name="X" type="float"/>
                            <param name="Y" type="float"/>
                            <param name="Z" type="float"/>
                        </accessor>
                    </technique_common>
                </source>
                <source id="geometry0-normal">
                    <float_array id="geometry0-normal-array" count="102">0.0673118 0.5184916 0.8524292 0.0673398 0.518527 0.8524055 0.0673118 0.5184916 0.8524292 0.0672839 0.5184563 0.8524529 0.9919208 -0.1268586 1.1E-6 0.9919208 -0.1268585 2.45E-5 0.9919208 -0.1268586 1.23E-5 0.9919218 -0.1268511 -1.02E-5 0.9919208 -0.1268586 -1.02E-5 0.9919189 -0.1268735 0.0 -0.9919412 0.1266993 0.0 -0.9919189 0.1268734 0.0 -0.9919189 0.1268734 0.0 -0.9919356 0.1267428 0.0 -0.9919523 0.1266122 0.0 -0.9919523 0.1266122 0.0 0.128786 0.9916725 0.0 0.128786 0.9916725 0.0 0.128786 0.9916725 0.0 0.128786 0.9916725 0.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 0.0 0.0 -1.0 -0.0673145 -0.5184855 0.8524327 -0.0672824 -0.518445 0.8524599 -0.0673145 -0.5184855 0.8524327 -0.0673466 -0.5185261 0.8524055 -0.1287991 -0.9916707 0.0 -0.1287991 -0.9916707 0.0 -0.1287991 -0.9916707 0.0 -0.1287991 -0.9916707 0.0</float_array>
                    <technique_common>
                        <accessor count="34" source="#geometry0-normal-array" stride="3">
                            <param name="X" type="float"/>
                            <param name="Y" type="float"/>
                            <param name="Z" type="float"/>
                        </accessor>
                    </technique_common>
                </source>
                <vertices id="geometry0-vertex">
                    <input semantic="POSITION" source="#geometry0-position"/>
                </vertices>
                <triangles count="16" material="default_ai_0.2_sh_0.2_tr_0.0_dc_r_0.8_g_0.8_b_0.8_sc_r_1.0_g_1.0_b_1.0_ec_r_0.0_g_0.0_b_0_tri">
                    <input offset="0" semantic="VERTEX" source="#geometry0-vertex"/>
                    <input offset="1" semantic="NORMAL" source="#geometry0-normal"/>
                    <p>1 4 0 5 11 6 1 4 11 6 10 7 1 4 10 7 9 8 1 4 9 8 8 9 6 10 7 11 4 12 6 10 4 12 3 13 6 10 3 13 2 14 6 10 2 14 5 15 5 16 2 17 1 18 5 16 1 18 8 19 10 20 7 21 9 22 9 22 7 21 8 23 7 21 6 24 8 23 8 23 6 24 5 25 10 30 11 31 4 32 10 30 4 32 7 33</p>
                </triangles>
                <triangles count="4" material="default_ai_0.2_sh_0.2_tr_0.0_dc_r_1.0_g_0.2_b_0.2_sc_r_1.0_g_1.0_b_1.0_ec_r_0.0_g_0.0_b_0_tri">
                    <input offset="0" semantic="VERTEX" source="#geometry0-vertex"/>
                    <input offset="1" semantic="NORMAL" source="#geometry0-normal"/>
                    <p>0 0 1 1 2 2 0 0 2 2 3 3 11 26 0 27 3 28 11 26 3 28 4 29</p>
                </triangles>
            </mesh>
        </geometry>
    </library_geometries>
    <library_visual_scenes>
        <visual_scene id="Building_DEBY_LOD2_2339627">
            <node>
                <instance_geometry url="#geometry0">
                    <bind_material>
                        <technique_common>
                            <instance_material symbol="default_ai_0.2_sh_0.2_tr_0.0_dc_r_0.8_g_0.8_b_0.8_sc_r_1.0_g_1.0_b_1.0_ec_r_0.0_g_0.0_b_0_tri" target="#default_ai_0.2_sh_0.2_tr_0.0_dc_r_0.8_g_0.8_b_0.8_sc_r_1.0_g_1.0_b_1.0_ec_r_0.0_g_0.0_b_0_mat"/>
                            <instance_material symbol="default_ai_0.2_sh_0.2_tr_0.0_dc_r_1.0_g_0.2_b_0.2_sc_r_1.0_g_1.0_b_1.0_ec_r_0.0_g_0.0_b_0_tri" target="#default_ai_0.2_sh_0.2_tr_0.0_dc_r_1.0_g_0.2_b_0.2_sc_r_1.0_g_1.0_b_1.0_ec_r_0.0_g_0.0_b_0_mat"/>
                        </technique_common>
                    </bind_material>
                </instance_geometry>
            </node>
        </visual_scene>
    </library_visual_scenes>
    <scene>
        <instance_visual_scene url="#Building_DEBY_LOD2_2339627"/>
    </scene>
</COLLADA>

I use Mapbox and ThreeJS to display the 3d building but I got nothing without any error:


const MyComponent = ()=>{

// some code here

 const create3DLayer = () => {
        const customLayer = {
            id: '3d-buildings',
            type: 'custom',
            renderingMode: '3d',
            onAdd(map: mapboxgl.Map, gl: WebGLRenderingContext) {
                this.camera = new THREE.Camera();
                this.scene = new THREE.Scene();

                const directionalLight = new THREE.DirectionalLight(0xffffff);
                directionalLight.position.set(0, -70, 100).normalize();
                this.scene.add(directionalLight);

                const loader = new ColladaLoader();

                console.log("started here")

                buildingModels.forEach(({ data: modelXml, coordinates }, index) => {

                    console.log("parsing building")
                    try {
                        // The issue is here!
                        loader.parse(modelXml, (collada) => {
                            try {
                                console.log("Parsing started...");
                                const model = collada.scene;

                                // Undo the default Z-UP to Y-UP rotation
                                model.rotation.set(0, 0, 0); // Adjust rotation if necessary
                                model.scale.set(10, 10, 10); // Adjust scale as needed

                                // Convert coordinates to Mercator
                                const mercatorCoord = mapboxgl.MercatorCoordinate.fromLngLat(
                                    [coordinates.lng, coordinates.lat],
                                    0 // Altitude
                                );

                                model.position.set(mercatorCoord.x, mercatorCoord.y, mercatorCoord.z);

                                // Add model to the scene
                                this.scene.add(model);
                                modelRefs.current.push(model);
                                // This line is not reached
                                console.log('Model added:', model); // Debug log
                            } catch (modelError) {
                                console.error(`Error processing model at index ${index}:`, modelError);
                            }
                        });
                    } catch (parseError) {
                        console.error(`Error during parsing of model XML at index ${index}:`, parseError);
                    }

                    // Additional logging to debug
                    console.log(`Model XML for index ${index}:`, modelXml);
                    console.log(`Coordinates for index ${index}:`, coordinates);

                });


                this.map = map;
                this.renderer = new THREE.WebGLRenderer({
                    canvas: map.getCanvas(),
                    context: gl,
                    antialias: true
                });
                this.renderer.autoClear = false;
            },
            render(gl: WebGLRenderingContext, matrix: number[]) {
                const m = new THREE.Matrix4().fromArray(matrix);
                this.camera.projectionMatrix = m;
                this.renderer.state.reset();
                this.renderer.render(this.scene, this.camera);
                this.map.triggerRepaint();
            }
        };

        return customLayer;
    };



}


/// some unrelated code


useEffect(() => {
        if (!mapRef.current || !buildingModels?.length) return;


        console.log(buildingModels);

        if (customLayerRef.current) {
            mapRef.current.removeLayer(customLayerRef.current.id);
        }

        customLayerRef.current = create3DLayer();
        mapRef.current.addLayer(customLayerRef.current);
        console.log("layer added");


        return () => {
            if (mapRef.current && customLayerRef.current) {
                mapRef.current.removeLayer(customLayerRef.current.id);
            }
        };
    }, [buildingModels]);

return <div ref={mapContainer} className={className} />;
};

Upvotes: 0

Views: 9

Answers (0)

Related Questions