Uncaught TypeError: Cannot read property 'position' of undefined at render

Hi everyone,
this is a part of my code and i always get error that at: “if(Math.abs(kuka.children[0].position.x - hall.children[1].position.x) < 0.5) {” position is undefined. Does somebody know why?

var hall, kuka, staub, roboter1;
var objects = [];
var renderer, scene, camera;
var controls, gltfLoader, dragControls;

init();
requestAnimationFrame(render);

// to init the scene and load the models
function init() {
    const canvas = document.querySelector('#c');
    renderer = new THREE.WebGLRenderer({canvas});
    const fov = 45;
    const aspect = 2;  // the canvas default
    const near = 0.1;
    const far = 100;
    camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
    camera.position.set(0, 10, 20);
    controls = new THREE.OrbitControls(camera, canvas);
    controls.target.set(0, 5, 0);
    controls.update();
    scene = new THREE.Scene();
    scene.background = new THREE.Color('black');

    gltfLoader = new THREE.GLTFLoader();
    gltfLoader.load('aruco_Halle.gltf', (gltf) => {
        hall = gltf.scene;
        scene.add(hall);
        // move scene a little bit up to see everything 
        hall.children[0].position().y += 0.07;
        hall.children[1].position().y += 0.07;
        hall.children[2].position().y += 0.07;
    });

    gltfLoader.load('images/roboter/kuka_kr6_r900.gltf', (gltf) => {    
        kuka = gltf.scene;
        scene.add(kuka);
        gltf.scene.traverse( function( object ) {
            if ( object.isMesh) objects.push( object);
        } );
    }, null, null);

    // to make it possible to drag the roboter around
    dragControls = new THREE.DragControls( objects, camera, renderer.domElement );
    dragControls.addEventListener( 'dragstart', function ( event ) { controls.enabled = false; } );
    dragControls.addEventListener( 'dragend', function ( event ) { controls.enabled = true; } );        
}

// to render the loadet scene
function render() {
    renderer.render(scene, camera);
    requestAnimationFrame(render);
 
    // to make sure its near to the arucomarker
    if(Math.abs(staub.children[0].position.x - hall.children[0].position.x) < 0.5) {
        if(Math.abs(staub.children[0].position.y - hall.children[0].position.y) < 0.5) {
            if(Math.abs(staub.children[0].position.z - hall.children[0].position.z) < 0.5) {
                place_Staub ();
            }
        }       
    }
    if(Math.abs(kuka.children[0].position.x - hall.children[1].position.x) < 0.5) {
        if(Math.abs(kuka.children[0].position.y - hall.children[1].position.y) < 0.5) {
            if(Math.abs(kuka.children[0].position.z - hall.children[1].position.z) < 0.5) {
                place_Kuka ();
            }
        }       
    }
}

function place_Staub () {
    staub.children[0].position.x = hall.children[0].position.x;
    staub.children[0].position.y = hall.children[0].position.y;
    staub.children[0].position.z = hall.children[0].position.z;
}
function place_Kuka () {
    kuka.children[0].position.x = hall.children[1].position.x;
    kuka.children[0].position.y = hall.children[1].position.y + 0.035;
    kuka.children[0].position.z = hall.children[1].position.z;
}

First of all, you should only access meshes if they are actually defined. Since you assign kuka in an onLoad() callback but the app renders right from the beginning, you should actually do this in render():

if ( kuka ) {

    // now access kuka

}

Anyway, the runtime error indicates that kuka seems to have no children. Can you please check in the debugger if this is the case?

1 Like

Thank you very much --> with checking first if the meshes are already defined it’s working fine.

I have another question to DragControl: when i import my industriel robots, i load the parent part in the objects array. Unfortunatly i can drag each part individual around. The parent part takes all parts, but the rest is just moving without the whole robot (–> only a child). Is there a way to take the whole robot as one part or to just make the parent able to drag around? :wink:

I’m afraid DragControls can’t do this out-of-the-box. Um, have you tried to merge all individual meshes into a single one?

yes I put him together in Blender to just one part. With dragControl I can unfortunately still move a few parts individually. I’m afraid I don’t see why. When i use transformControls, its working fine and i can move the whole robot.

In this case you have still not a single mesh. You can easily verify this by traversing through the object hierarchy like so:

mesh.traverse( ( object ) => {

    console.log( object );

} );

If you have more than one log, you obviously have more than one mesh in your scene.

BTW: You can also merge meshes with three.js via BufferGeometryUtils.mergeBufferGeometries(). The method is used in the following official example:

https://threejs.org/examples/webgl_geometry_minecraft

Your right. In Blender it’s just on Mesh. When i import it in Three.js it still has 8 child meshes, which DragControl splits apart :see_no_evil:

I switched now to transformControl and activate the control by a click event on the diffrent roboter.
There is a bit of performance Problem. My scene just get really slow with transformControl. Do you think it because of the diffrent Meshes, that i move them together or did i code it wrong?

    transformControls = new THREE.TransformControls( camera, renderer.domElement);
    transformControls.addEventListener('change', render);
    transformControls.addEventListener('mouseDown', function () {
        controls.enabled = false;
    });

   transformControls.addEventListener('mouseUp', function () {

       controls.enabled = true;
    });
    addEventListener('dblclick', function () {
        transformControls.detach();
    });
    scene.add(transformControls);
    domEvents = new THREEx.DomEvents(camera, renderer.domElement);
    // load roboter 1:
    gltfLoader.load('images/roboter/kuka_kr6_r900.gltf', (gltf) => {  
        kuka = gltf.scene;
        scene.add(kuka);

        kuka.children[0].position.x += 8.8;
        kuka.children[0].position.y += 0.1
        kuka.children[0].position.z += -4;

        domEvents.addEventListener(kuka, 'click', onDocumentMouseDown_Kuka, false); }, null, null);

 function onDocumentMouseDown_Kuka(event) {
        transformControls.detach();
        try {
            transformControls.attach(kuka.children[0]);
        }
        catch (err) {
            console.log("kuka: ", err); 
        }
    }

Um, it’s really hard to say this based on your code. Are you able to share a live example that demonstrates the performance issue?

Is it ok to send you a link to oneDrive with my complete Folder? there’re also the models in it:
https://onedrive.live.com/?authkey=!Ar2AdWpHVXzElgM&id=4F9C41CE144EF8C9!42294&cid=4F9C41CE144EF8C9

When you click on a roboter you can move it around. Doubleclick will datach the transform control. As soon as i move it around my application gets really slow