- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在为我们的 THREE.js 应用开发正交相机。从本质上讲,该摄像头将以 2D 形式向用户呈现场景(用户可以选择在 2D 和 3D 摄像头之间切换)。此相机将允许平移和缩放到鼠标点。我有平移工作,我有缩放工作,但没有缩放到鼠标点。这是我的代码:
import React from 'react';
import T from 'three';
let panDamper = 0.15;
let OrthoCamera = React.createClass({
getInitialState: function () {
return {
distance: 150,
position: { x: 8 * 12, y: 2 * 12, z: 20 * 12 },
};
},
getThreeCameraObject: function () {
return this.camera;
},
applyPan: function (x, y) { // Apply pan by changing the position of the camera
let newPosition = {
x: this.state.position.x + x * -1 * panDamper,
y: this.state.position.y + y * panDamper,
z: this.state.position.z
};
this.setState({position: newPosition});
},
applyDirectedZoom: function(x, y, z) {
let zoomChange = 10;
if(z < 0) zoomChange *= -1;
let newDistance = this.state.distance + zoomChange;
let mouse3D = {
x: ( x / window.innerWidth ) * 2 - 1,
y: -( y / window.innerHeight ) * 2 + 1
};
let newPositionVector = new T.Vector3(mouse3D.x, mouse3D.y, 0.5);
newPositionVector.unproject(this.camera);
newPositionVector.sub(this.camera.position);
let newPosition = {
x: newPositionVector.x,
y: newPositionVector.y,
z: this.state.position.z
};
this.setState({
distance: newDistance,
position: newPosition
});
},
render: function () {
let position = new T.Vector3(this.state.position.x, this.state.position.y, this.state.position.z);
let left = (this.state.distance / -2) * this.props.aspect + this.state.position.x;
let right = (this.state.distance / 2) * this.props.aspect + this.state.position.x;
let top = (this.state.distance / 2) + this.state.position.y;
let bottom = (this.state.distance / -2) + this.state.position.y;
// Using react-three-renderer
// https://github.com/toxicFork/react-three-renderer
return <orthographicCamera
{...(_.pick(this.props, ['near', 'far', 'name']))}
position={position}
left={left}
right={right}
top={top}
bottom={bottom}
ref={(camera) => this.camera = camera}/>
}
});
module.exports = OrthoCamera;
有些会向鼠标点缩放,但看起来不稳定。我想保持 2D View ,所以在缩放时,我也移动相机(而不是有一个非垂直的目标,这会破坏 2D 效果)。
我从 this question 得到了启发.据我所知,我已成功转换为 mouse3D
中的 THREE.js 坐标(参见 this question 的答案)。
那么,鉴于此设置,我如何才能使用正交相机平滑地缩放到鼠标点 (mouse3D
) 并保持二维 View ?提前致谢。
最佳答案
假设您有一个由世界坐标中的位置和观察(或枢轴)点描述的相机,在其核心处缩放(或远离)特定点非常简单。
您的表示似乎更简单:只是一个位置/距离对。我没有看到旋转组件,所以我假设您的相机是自上而下的正交相机。
在那种情况下,您的观察点(您不需要)只是(position.x, position.y - distance, position.z)
。
在一般情况下,您需要做的就是将相机位置和观察点都移向放大点,同时保持相机法线(即方向)。请注意,无论投影类型或相机旋转如何,这都会起作用。编辑(2020/05/01):使用正交投影时,这不是您需要做的全部(请参阅底部的更新)。
如果您仔细想想,这正是您在 3D 中缩放某个点时发生的情况。你一直看着同一个方向,但你离目标越来越近(但从未到达)。
例如,如果您想缩放 1.1 倍,您可以想象将连接相机位置和缩放点的矢量缩放 1/1.1。
你可以通过简单的插值来做到这一点:
var newPosition = new THREE.Vector3();
newPosition.x = (orgPosition.x - zoomAt.x) / zoomFactor + zoomAt.x;
newPosition.y = (orgPosition.y - zoomAt.y) / zoomFactor + zoomAt.y;
newPosition.z = (orgPosition.z - zoomAt.z) / zoomFactor + zoomAt.z;
正如我上面所说,在您的情况下,您实际上不需要更新观察点然后计算新距离。您的新距离将是:
var newDistance = newPosition.y
应该这样做。
如果您想在位置/注视点和位置/缩放点对之间设置最小和最大距离限制,它只会变得更复杂一点(主要是在一般情况下)。
更新(2020/05/01):
我刚刚意识到上述内容虽然正确(除了缺少一个次要但非常重要的步骤)并不是对 OP 问题的完整答案。在正交模式下改变相机的位置当然不会改变正在渲染的图形的比例。为此,必须更新相机的投影矩阵(即必须更改正交投影的左、右、上和下参数)。
出于这个原因,许多图形库在它们的正交相机类中包含一个比例因子,它就是这样做的。我没有使用 ThreeJS 的经验,但我认为该属性称为“缩放”。
所以,总结一下:
var newPosition = new THREE.Vector3();
newPosition.x = (orgPosition.x - zoomAt.x) / zoomFactor + zoomAt.x;
newPosition.y = (orgPosition.y - zoomAt.y) / zoomFactor + zoomAt.y;
newPosition.z = (orgPosition.z - zoomAt.z) / zoomFactor + zoomAt.z;
myCamera.zoom = myCamera.zoom * zoomFactor
myCamera.updateProjectionMatrix()
如果您想改用上面的正交相机类代码,您可能必须更改计算左、右、上和下的部分,并在计算中添加比例因子。这是一个例子:
var aspect = this.viewportWidth / this.viewportHeight
var dX = (this.right - this.left)
var dY = (this.top - this.bottom) / aspect
var left = -dX / (2 * this.scale)
var right = dX / (2 * this.scale)
var bottom = -dY / (2 * this.scale)
var top = dY / (2 * this.scale)
mat4.ortho(this.mProjection, left, right, bottom, top, this.near, this.far)
关于javascript - THREE.js 正交相机缩放到鼠标点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39905892/
我正试图在使用 webvr-boilerplate 的项目中使镜像效果正常工作当 VREffect 处于事件状态时。 我尝试(使用 r72dev 和 r72)使用 THREE.Mirror:
我正在尝试为 localClipping 配置 THREE.plane 的位置,但我发现它有点不直观。我有一个想法,是否可以创建一些planeGeometry,操纵它,并将其位置和方向转换为在其位置创
我有 8 个从 Object3D 到不同方向的光线转换器,用于碰撞检测。我想根据对象旋转旋转他们指向的方向。我遵循了 here 中的解决方案 光线转换器开始旋转,但方式很奇怪。它开始检测来自不同方向的
我在微信上用three.js开发3D游戏,但是有个问题,three.js怎么设置渐变的背景色。我在文档上看到了背景色,但是没有渐变的背景色。请说明我是中国人英语不好。 最佳答案 对于高级效果,请尝试使
我试图通过使用Three.js挤压形状来给SVG路径(lineto和moveto)3D感觉,但是该过程会导致一些我无法删除的瑕疵。 什么会导致渲染的3D形状出现奇异的伪像?有没有办法删除它们? 这些伪
我试图在THREE.js中学习有关性能几何的更多信息,并且已经了解索引BufferGeometry和InstancedBufferGeometry是两种性能最高的几何类型。 到目前为止,我的理解是,在
three.js带有许多有用的控件,这些控件会导致相机响应键盘和鼠标输入而移动。 它们都位于https://github.com/mrdoob/three.js/blob/master/example
几个小时以来,我尝试了数十种不同的方法,但都没有效果,如下所示: document.body.addEventListener("keydown", function() { THREEx.Ful
几个小时以来,我尝试了数十种不同的方法,但都没有效果,如下所示: document.body.addEventListener("keydown", function() { THREEx.Ful
当我创建一个 JSON 模型并使用 THREE.JSONLoader.load 加载它时,它的加载没有任何问题,但是当我尝试从中创建一个变量并将数据包含在主脚本中时,THREE.JSONLoader.
我正在尝试添加一个系统粒子,一个三点到场景,但我有这个错误: “THREE.Object3D.add:对象不是 THREE.Object3D 的实例。未定义” 代码: var backCount =
请参阅以下 fiddle : https://jsfiddle.net/1jmws2bp/ 如果将鼠标移动到线条或圆圈上,它应该将颜色更改为白色(对我来说,本地有效,在 jsfiddle 中有时会有一
我正在努力处理我正在处理的涉及重复图像流的可视化。我让它与一个带有 ParticleSystem 的 Sprite 一起工作,但我只能将一种 Material 应用于系统。因为我想在纹理之间进行选择,
我想移动和旋转摄像头,但要保持PointLight相对于摄像头的位置相同。我读过一堆线程说,您可以将灯光对象添加到摄影机而不是场景。像这样: pointLight = new THREE.PointL
我是 three.js 的新手。我创建了多个网格并使用 JSONLoader 进行了分组。现在我的问题是将动画应用于该组或多个网格。是否可以将动画应用于 JSONLoader 中的该组。 提前致谢。
我想了解如何three.js在内部工作。我不明白的一件事是如何three.js编译并运行着色器程序。如果我要重新实现 three.js我自己我会有一个顶点着色器归因于 Geometry以及归因于 Ma
我以前设法显示了框,但在这里,我已经剥离了所有内容,以便通过定位 collada 模型来试验扩展框,但框不会显示。 function loadObjects(){ cobj = new THREE
我是3D编程的新手,我确实开始使用Three.JS从WebGL探索3D世界。 我想在更改camera.position.z和对象的“Z”位置时预先确定对象的大小。 例如: 我有一个大小为 100x10
在 BufferGeometry 中,有没有一种方法可以访问面索引和法线而不转换为 Geometry? 手头的几何体是由 Threejs 编辑器创建的 SphereBufferGeometry。 我只
我遵循了这个 stackoverflow 示例: ThreeJS geometry flipping 我成功镜像了我的几何体。然而现在我的几何图形是黑色的。我可以在翻转几何体的同时翻转法线来纠正这个问
我是一名优秀的程序员,十分优秀!