-1

I'm really struggling with this and have gone through several discussions that are not really related to my problem. If anybody can help, I would greatly appreciate.

I'm writing a html document using the three.js library. There is a scene called scaledScene as below (scaledMap and scaledScene are already defined):

scaledMap = new THREE.Mesh( 
                            new THREE.PlaneGeometry( 1600, 1200 ),
                            new THREE.MeshBasicMaterial( {
                            map: new THREE.ImageUtils.loadTexture( 'texture/test1.png' ),
                                        //wireframe: true,
                                        side: THREE.DoubleSide
                                } )
                        );
scaledScene.add( scaledMap );

The scene is created by a high solution picture that's zoomed in to the highest level. Zooming is not allowed but only panning.

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

I would like to get the absolute coordinates on the scene when panning. For example, if I pan to the top left corner, I'd like to get the information that the cursor or the view is located at top left corner. Is this possible? If so, how do I do it?

Andrew Myers
  • 2,754
  • 5
  • 32
  • 40

1 Answers1

0

You want a picking ray.

A ray can be sent from the center of the viewport to the map in 3d space. this will tell you the pixel of the map that's currently at the center of the viewport.

I have created a fiddle.

The code is as follows. It disables rotation of the camera so that only panning is available. The pixel of the image that is at the center of the view port is listed below the viewport. Remember that threejs uses cartesian space. So an image that is 150px / 150px will report pixels from -75 to 75. So if both of your x is negative and your y is positive, then you know you're viewing the top left portion of the image.

The fiddle: http://jsfiddle.net/v1g64zkb/

var width = 400;
var height = 300;
var aspect = width/height;
var near = 1;
var far = 1000;
var angle = 45;

var createRenderer = function(){
    var renderer =  new THREE.WebGLRenderer();
    renderer.setSize(width,height);
    return renderer;
}
var camera;
var createCamera = function(){
    camera = new THREE.PerspectiveCamera(
        angle, aspect, near, far);    
    camera.position.set( 0, 0, 100 );
    camera.lookAt(new THREE.Vector3( 0, 0, 0 ));
    return camera;
}


var createScene = function(){
    var scene = new THREE.Scene();
    return scene;
}
var createControls = function(camera){

    var controls = new 
        THREE.OrbitControls(camera);

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

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





    return controls;
}
var createLight = function(){
    var light = new THREE.PointLight(0xFFFFFF);
    light.position.x=0;
    light.position.y=0;
    light.position.z=100;
    return light;
}


var scene = createScene();
var camera = createCamera();
var controls = createControls(camera);
var light = createLight();

var renderer = createRenderer();

scene.add(light);


scaledMap = new THREE.Mesh( 
                            new THREE.PlaneGeometry( 150, 150 ),
                            new THREE.MeshBasicMaterial( {
                                                    map: new THREE.ImageUtils.loadTexture( '../img/logo.png' ),
                                        color:0xFFFFFF,
                                        side: THREE.DoubleSide
                                } )
                        );
scene.add( scaledMap );

var raycaster = new THREE.Raycaster();
var cameraPosition = new THREE.Vector2();
cameraPosition.x = 0; 
cameraPosition.y = 0; 

console.log(cameraPosition)
var render = function(){
   renderer.render(scene,camera);


    raycaster.setFromCamera( cameraPosition, camera );


    var intersects = raycaster.intersectObjects( scene.children );

    if(intersects[0] != undefined){
        $("#output").html(intersects[0].point.x.toFixed(2)+" "+intersects[0].point.y.toFixed(2));
  }


    renderer.render( scene, camera );


}
controls.addEventListener('change',render);
var animate = function(){
    requestAnimationFrame(animate);    
    render();
    controls.update();
}

animate();

$("#container").append(renderer.domElement);

//edit: I would not run a picking ray inside a render call. This is just a simplified example. Use the controls change event or whatever to fire the picking ray.

Radio
  • 2,810
  • 1
  • 21
  • 43