0

This may be a really stupid question, but I am new to three.js and while I've gotten the obj file to load on the web and be controllable via mouse, I'm not quite sure how to handle the next step.

What I'd really like to do is overlay a clickable .jpg or .png file over a section of the existing mesh linking out to some web pages I already have completed. How would I go about doing this? I'd appreciate it if someone could point me to an example or let me know if it's not doable so I can look for possible alternatives.

The code I currently have is below -- it's mostly cobbled together from online example so forgive me if it seems redundant or inelegant.

var container, stats;

        var camera, scene, renderer;

        var mouseX = 0, mouseY = 0;

        var windowHalfX = window.innerWidth / 2;
        var windowHalfY = window.innerHeight / 2;


        init();
        animate();


        function init() {

            container = document.createElement( 'div' );
            document.body.appendChild( container );

            camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
            camera.position.z = 10;


        controls = new THREE.TrackballControls( camera );

        controls.rotateSpeed = 1.0;
        controls.zoomSpeed = 1.2;
        controls.panSpeed = 0.8;

        controls.noZoom = false;
        controls.noPan = false;

        controls.staticMoving = true;
        controls.dynamicDampingFactor = 0.3;

        controls.keys = [ 65, 83, 68 ];

        controls.addEventListener( render );


            // scene

            scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight( 0xFFFFFF );
            scene.add( ambient );

            /*var directionalLight = new THREE.DirectionalLight( 0xffffff );
            directionalLight.position.set( 1, 1, 0 ).normalize();
            scene.add( directionalLight );*/

            var hemisphereLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, .70);
            scene.add( hemisphereLight );

            // model

            var onProgress = function ( xhr ) {
                if ( xhr.lengthComputable ) {
                    var percentComplete = xhr.loaded / xhr.total * 100;
                    console.log( Math.round(percentComplete, 2) + '% downloaded' );
                }
            };

            var onError = function ( xhr ) {
            };


            THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );

        THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );

            var loader = new THREE.OBJMTLLoader();
            loader.load( 'obj/test/test_model.obj', 'obj/test/test_model.mtl', function ( object ) {

                object.scale = new THREE.Vector3( 25, 25, 25 );

                //object.position.y = - 80;
                scene.add( object );

            }, onProgress, onError );

            //

            renderer = new THREE.WebGLRenderer({ alpha: true });
            renderer.setSize( window.innerWidth, window.innerHeight );
            container.appendChild( renderer.domElement );

            document.addEventListener( 'mousemove', onDocumentMouseMove, false );

            //

            window.addEventListener( 'resize', onWindowResize, false );

        }

        function onWindowResize() {

            windowHalfX = window.innerWidth / 2;
            windowHalfY = window.innerHeight / 2;

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize( window.innerWidth, window.innerHeight );

            controls.handleResize();

        }

        function onDocumentMouseMove( event ) {

//              mouseX = ( event.clientX - windowHalfX ) / 2;
//              mouseY = ( event.clientY - windowHalfY ) / 2;

        }


        //

        function animate() {

            requestAnimationFrame( animate );
            controls.update();
            render();

        }

        function render() {

            //camera.position.x += ( mouseX - camera.position.x ) * .05;
            //camera.position.y += ( - mouseY - camera.position.y ) * .05;
            //camera.lookAt( scene.position );

            renderer.render( scene, camera );

        }
medievalmatt
  • 427
  • 2
  • 12

1 Answers1

0

In your onDocumentMouseMove - or in a click event - you must compute a ray-picking intersection with http://threejs.org/docs/#Reference/Core/Raycaster and handle the reaction from there.

There are multiples examples of this, in the Three.js examples (like http://threejs.org/examples/#webgl_geometry_terrain_raycast) and on StackOverflow.

A very naive solution could be:

// note that you may have to use other properties if the renderer is not fullscreen"
// like here http://stackoverflow.com/questions/13542175/three-js-ray-intersect-fails-by-adding-div 
var mouseX = ( event.clientX / window.innerWidth ) * 2 - 1;
var mouseY = -( event.clientY / window.innerHeight ) * 2 + 1;

var vector = new THREE.Vector3( mouseX, mouseY, camera.near );
// Convert the [-1, 1] screen coordinate into a world coordinate on the near plane
vector.unproject( camera );

var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );

// See if the ray from the camera into the world hits one of our meshes
var intersects = raycaster.intersectObjects( scene, true ); // true for recursive

// Toggle rotation bool for meshes that we clicked
if ( intersects.length > 0 ) {

    var clickedObject = intersects[ 0 ].object;

    // here, handle the clickedObject properties to react accordingly
    // show an overlay, jump to a page, etc..
}
vincent
  • 1,525
  • 12
  • 18