Click and drag only grabs part of an object

Question!

I'm on the final stretch of a this project I've been working on and I'm having issues with the ability to click and drag objects. I've added them all into an array called items, and it sort of works right now. Here is the link to the page in action. If you add any of the items from the menu in the upper right, it'll show up but you can only drag it around piece by piece. From what I can tell, the issue is that it is treating each item as a series of items instead of as one item. This makes sense as each model is several models pieced together, but I'm not sure how to work around that. Any ideas?

Here are the three functions I have controlling mouse interaction:

function onMouseMove( event ){
    event.preventDefault();

    mouse.x = ( event.clientX / width ) * 2 - 1;
    mouse.y = - ( event.clientY / height ) * 2 + 1;

    var vector = new THREE.Vector3( mouse.x, mouse.y, 0 );
    projector.unprojectVector( vector, camera );

    var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );

    if ( SELECTED ) {

            var intersects = ray.intersectObject( plane );
            SELECTED.position.copy( intersects[ 0 ].point.subSelf( offset ) );
            return;

    }

    var intersects = ray.intersectObjects( items );

    if ( intersects.length > 0 ) {

            if ( INTERSECTED != intersects[ 0 ] ) {

                    INTERSECTED = intersects[ 0 ].object;

                    plane.position.copy( INTERSECTED.position );
            }

            container.style.cursor = 'pointer';
    }
     else {
                    INTERSECTED = null;
                    container.style.cursor = 'auto';
    }

}

function onMouseDown( event ) {
    event.preventDefault();

    var vector = new THREE.Vector3( mouse.x, mouse.y, 0 );
    projector.unprojectVector( vector, camera );

    var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );

    var intersects = ray.intersectObjects( items );

    if ( intersects.length > 0 ) {

            SELECTED = intersects[ 0 ].object;

            var intersects = ray.intersectObject( plane );
            offset.copy( intersects[ 0 ].point ).subSelf( plane.position );

            container.style.cursor = 'move';

    }

}

function onMouseUp( event ) {
    event.preventDefault();

    if ( INTERSECTED ) {
            plane.position.copy( INTERSECTED.position );
            SELECTED = null;
    }

    container.style.cursor = 'auto';
}

It's heavily based on this example, but without the color bits.

By changing the code in onMouseDown like so

// OLD
SELECTED = intersects[0].object;
// NEW
SELECTED = intersects[0].object.parent;

I can now move the full object. This only works if the object only has one parent though, and so some items are not able to move with this code. Anyone have a suggestion on determining if it has parent objects and moving up if it does?

By : rougegoat


Answers

Resolved by adding the following to onMouseDown

SELECTED = intersects[0].object;
while(SELECTED.parent != scene){
    SELECTED = SELECTED.parent;
}

This ensures that the object grabbed will be the highest level that isn't the scene and makes all the models drag-able.

By : rougegoat


This video can help you solving your question :)
By: admin