Skip to content

ColladaLoader object position/center swapped values #24289

@BenedictLang

Description

@BenedictLang

Context: Im programming a 3D Room Search PWA for my university

Describe the bug

I was moving from OBJLoader to ColladaLoader and recognized, that my added Labels from CSS2DRenderer had wrong positions when they are correct in the OBJ file.

To Reproduce

Steps to reproduce the behavior:

  1. Load collada.dae file
  2. get Position of element
  3. get geometry.boundingBox.getCenter(matrix);
  4. Value Y is swapped with actual value Z

Code
Context: the function creates a tooltip to show the room number linked as a label to the position above the searched room in my scene.

/**
 * Adds a tooltip above a room with the given room number if exists in model
 * @param roomNumber object.name value that is compared to the given room number
 */
export function addTooltip(roomNumber) {

    const roomCard_tooltip = createRoomCard(returnRoom(roomNumber), true) //some HTML content for the tooltip
    roomCard_tooltip.style.marginTop = '-10em'; //set center position up
    tooltip = new CSS2DObject( roomCard_tooltip ) //add as global instance of label
    const room = scene.getObjectByName(roomNumber); //return RoomID of room in my model
    if (room) {
        let offset = null;
        console.log(`Room:  ${room}`)
        console.log(`Room init pos:  ${room.position.x}, ${room.position.y}, ${room.position.z}`) //is always 0, 0, 0 because not set
        if (room.position.x === 0 && room.position.z === 0) { //if coordinates not already set
            room.geometry.computeBoundingBox();
            let matrix = new THREE.Vector3();
            offset = room.geometry.boundingBox.getCenter(matrix); //compute center point of room
            console.log(`Room center:  ${offset.x}, ${offset.y}, ${offset.z}`)
            room.geometry.applyMatrix4(new THREE.Matrix4().makeTranslation(-offset.x, -offset.y, -offset.z));
            room.position.copy(offset); //set position from offset data
        }

        console.log(`Room pos:  ${room.position.x}, ${room.position.y}, ${room.position.z}`)
        room.material = new THREE.MeshStandardMaterial( { color: 0xE31433}); //sets color of room highlighted
        tooltip.position.copy( room.position ); // ERROR!!!!!!!!!!!!!!, position is not correct when loaded with ColladaLoader()
        addLightPoint(room.position.x, room.position.y, room.position.z, scene) //highlight position of initial room point
        if (offset != null) tooltip.position.set( offset.x, offset.z, - offset.y); // SOLUTION: swapped Z and Y value
        scene.add(tooltip)
        console.log(`tooltip pos:  ${tooltip.position.x}, ${tooltip.position.y}, ${tooltip.position.z}`)

        addLightPoint(tooltip.position.x, tooltip.position.y, tooltip.position.z, scene) //highlight position of tooltip point

    } else {
        console.error("Sorry, can't find room in object!")
    }
    
/**
 * Adds a light point to the position given
 * @param $x X-coordinate
 * @param $y Y-coordinate
 * @param $z Z-coordinate
 * @param scene the scene/context
 */
export function addLightPoint($x, $y, $z, scene) {
    const pointLight = new THREE.PointLight( 0xff0000, 1, 200 );
    pointLight.position.set( $x, $y, $z );
    scene.add( pointLight );

    const sphereSize = 1;
    const pointLightHelper = new THREE.PointLightHelper( pointLight, sphereSize );
    scene.add( pointLightHelper );
}

Simple Loader:

let daeModelHdM = "" + new URL("../assets/models/dae/HdM_campus.dae",
    import.meta.url);

const loader = new ColladaLoader(manager);
loader.load( daeModelHdM, function ( collada ) {

    const object = collada.scene;
    const animations = object.animations;

    object.traverse( function ( child ) {
        if (child.isMesh) { //later and if is room or building
            //TODO: sorting into storys and buildings 2D-array
            
           //child.name <=> roomNumber/building

            objects.push(child); //saved in global instance
        }
    } );

    scene.add( object );

    let scaleFactor = 1;
    object.scale.set(scaleFactor, scaleFactor, scaleFactor);
    //object.rotateX(11);

    }, (xhr) => {
        console.debug(`${((xhr.loaded / xhr.total) * 100).toFixed(2)}% of model loaded`)
    }, function (error) {
        console.error(`An error happened: ${error}`);
    }
);

Live example

Expected behavior

Same position calculation with the other loaders (tested with OBJLoader and Rhino3dmLoader).
I havent seen an obvious issue in the position of ColladaLoader code on a quick look so I guess the swapped values are in the getCenter, boundingBox or geometry.

Screenshots

Big PointLightHelper is 0,0,0 (Ground Zero, initial position) - small PointLightHelper is 21, 76, 10 (the collada room center -> wrong!) - tooltip + PointLightHelper is 21, 10 , 76 (if changed values correct position)

image

Platform:

  • Device: Desktop, Mobile
  • OS: Windows 11, MacOS, Android
  • Browser: Chrome
  • Three.js version: "three": "^0.140.0"
  • ColladaLoader: "three/examples/jsm/loaders/ColladaLoader"

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions