question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ColladaLoader object position/center swapped values

See original GitHub issue

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”

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:8 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
Mugen87commented, Jul 7, 2022

Yeah, that would help to avoid confusion. I’m struggling a bit with the wording though^^. How about:

THREE.ColladaLoader: You are loading an asset with a Z-UP coordinate system. The loader just rotates the asset to transform it into Y-UP. The vertex data are not converted, see https://github.com/mrdoob/three.js/issues/24289.

1reaction
mrdoobcommented, Jul 7, 2022

@Mugen87

The loader just rotates the entire asset to display it correctly. However, the coordinates are of course not “as expected”.

Maybe we should add a warning in the console when we do that?

Read more comments on GitHub >

github_iconTop Results From Across the Web

object-position - CSS: Cascading Style Sheets - MDN Web Docs
The object-position CSS property specifies the alignment of the selected replaced element's contents within the element's box.
Read more >
Fit 3D Object (Collada File) within Three.JS Canvas on initial ...
When I manually up the camera.position x,y,z values, the object is in the screen. The challenge I have is how to determine what...
Read more >
C Index - API Documentation
This event occurs whenever the technique or blendMode has changed. CHANGE_TECHNIQUE — Constant Static Property, class flare.materials.flsl.FLSLFilter.
Read more >
A Quick Overview of `object-fit` and `object-position`
object -fit and object-position are my two favourite CSS properties ... centers all objects horizontally and vertically without a value:
Read more >
A Noob's Guide to Three.js
This line is the object's local position. This sets the x, ... To insert our 3D object to the scene we have to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found