2013-10-15 115 views
3

我想用鼠标沿平行于投影平面的平面移动物体。这意味着在移动过程中,任何拾取物体和相机投影平面(不是相机位置)之间的距离必须保持不变。一个类似的问题已被问到:Mouse/Canvas X, Y to Three.js World X, Y, Z,但不像那里,我需要一个解决方案,适用于任意摄像机角度和相机/物体位置,不仅适用于z = 0的平面。它也必须用于正射投影。现在,我创建了一个小提琴在three.js中移动平行于投影平面的物体

http://jsfiddle.net/nmrNR/

在mousemove事件处理程序的代码:

var v = new THREE.Vector3(
    (event.clientX/window.innerWidth)*2-1, 
    -(event.clientY/window.innerHeight)*2+1, 
    1 
); 
projector.unprojectVector(v,camera); 
var dist = circle.position.sub(camera.position,circle.position), 
    pos = camera.position.clone(); 
pos = pos.add(pos, 
    v.sub(v,camera.position).normalize().multiplyScalar(dist.length()) 
); 

跟随鼠标的位置,但到摄像机位置的距离圆是恒定的,因此在实际执行一个球形运动。当切换到直接摄像机(单击)时,它也不像预期的那样跟随鼠标位置。

回答

0

一个较早的问题,你现在可能已经很久以前解决了,无论如何这里是一个答案。

您没有使用像OrbitControls这样的控件,如果只是为了在头脑中将其可视化,可能会稍微简单一些。 OrbitControls不仅有相机,还有一个指向相机的目标物体(它总是看着它,而Y轴始终向上)。你想要实现的运动与从摄像机到target的矢量垂直,而不是随着移动对象而改变的对象的矢量,其变化解释了圆形运动。并且,OrbitControls提供您需要的数学。

https://github.com/mrdoob/three.js/blob/master/examples/js/controls/OrbitControls.js#L147-L171,这些函数计算一个矢量,用于移动相机和目标(它应该对你的对象也适用,尽管你可能需要反转该运动)。请注意,this.object是相机。

// pass in distance in world space to move left 
this.panLeft = function (distance) { 

    var te = this.object.matrix.elements; 

    // get X column of matrix 
    panOffset.set(te[ 0 ], te[ 1 ], te[ 2 ]); 
    panOffset.multiplyScalar(- distance); 

    pan.add(panOffset); 

}; 

// pass in distance in world space to move up 
this.panUp = function (distance) { 

    var te = this.object.matrix.elements; 

    // get Y column of matrix 
    panOffset.set(te[ 4 ], te[ 5 ], te[ 6 ]); 
    panOffset.multiplyScalar(distance); 

    pan.add(panOffset); 

}; 

代码来自r.68,如果您有旧版本,它可能无法修改无法正常工作。

1

我修改了提问者优秀的工作版本,可以在更新的版本中工作(对我来说效率更高一些 - 只需回馈,谢谢 起初,我发现自己使用克隆来避免跳跃行为,然后我注意移动的物体来回蹑手蹑脚向前所以我用了一个初始的点击位置(以获得distanceTo)。 那地方也问题与警告说,使用addVectors和子向量,但是这是没有必要的无论是。

camPos = cam.position; 
var mv = new THREE.Vector3((event.clientX/window.innerWidth) * 2 - 1, -(event.clientY/window.innerHeight) * 2 + 1, 1).unproject(cam); 
var pos = camPos.clone(); 
pos.add(mv.sub(camPos).normalize().multiplyScalar(initalClickPos.distanceTo(camPos))); 

将正在移动的目标对象的位置设置为位置会将其从当前摄像机平面中的鼠标移动位置移开,但它以某种方式旋转为在透视图中保持物体的相机距离。

它仍然看起来有点时髦,所以我想也许这可以进一步改善与添加和子更清洁。可能如在其他答案中所见。

我仍然有偏移问题,我最初点击的位置,所以位置中心不会弹出,也许暂时设置对象枢轴值得探索。 这是与r71。