平行于投影平面移动物体,.js
Moving objects parallel to projection plane in three.js
我想用鼠标沿着平行于投影平面的平面移动对象。这意味着在移动过程中,任何拾取对象与摄像机投影平面(而不是摄像机位置)之间的距离必须保持不变。已经提出了类似的问题:鼠标/画布 X,Y 到三个.js世界 X、Y、Z ,但与那里不同的是,我需要一种适用于任意相机角度和相机/物体位置的解决方案,而不仅仅是适用于 z=0 的平面。它还必须适用于正交投影。现在我创建了一个小提琴
http://jsfiddle.net/nmrNR/
鼠标移动事件处理程序中的代码:
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())
);
圆圈跟随鼠标位置,但它与相机位置的距离是恒定的,因此它实际上是在执行球形运动。切换到地形相机(单击)时,它也不会按预期跟随鼠标位置。
我已经修改了提问者的优秀工作版本,使其在更新的版本中工作(对我来说更有效率 - 只是回馈,谢谢。起初,我发现自己使用克隆来避免跳跃行为。然后我注意到来回移动对象会让它向前爬行,所以我使用初始单击位置(以获得距离)。那里也有警告说使用addVectors和subVectors的问题,但这也没有必要。
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)));
将要移动的目标对象的位置设置为 pos 会将其从当前相机平面中的鼠标移动位置移动,但随着透视视图中对象的摄像机距离保持不变,它确实会以某种方式旋转。
对我来说,它看起来仍然有点时髦,所以我想也许可以通过添加和订阅更干净来进一步改进。可能如其他答案所示。
我最初单击的位置仍然有偏移问题,因此位置中心不会弹出,也许暂时设置对象枢轴值得探索。这适用于 r71。
一个你现在可能早就解决了的老问题,无论如何,这是一个答案。
您没有使用像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,如果您有旧版本,如果不修改它可能无法工作。
- Video.js+移动设备上的谷歌IMA:'点击'导致错误的事件
- JS-移动图像,暂停设置的时间,然后将图像向后移动
- 如何通过JS移动元素位置而不闪烁
- JS移动重定向到/mobile/而不是m
- 视差.js移动我的 CSS 定位元素
- jQuery.BlackAndWhite.js移动设备上不稳定
- 通过jQuery或JS移动鼠标
- 页面冻结,不要使用循环js移动wihle
- 使用d3.js移动折线图
- 在Snap.js移动面板插件中添加“destroy”方法
- 如何使js移动脚本具有可重复性
- d3.js移动平均线图(自定义插值)与工具提示
- 如何将控制器源代码从app.js移动到angular项目中所需的文件夹位置
- JS移动:我有多少内存可用
- 使用OrbitControls.js移动摄像机和灯光
- 织物js移动图像与键盘
- 当使用fabric.js移动元素时,如何将图像保持在画布的后面
- Node.js移动繁重的CPU绑定任务
- Fabric js:移动时不更新组成员
- Angular.js移动动画