我正在实现使用鼠标旋转网格的功能。
引用代码是链接站点。("http://3dit.bordeaux.inria.fr/testbed.html#navigation_Map_Navigation"(
我想知道如何使用鼠标绕 Z 轴(红线(旋转。
我发现 Three.js 中的所有示例都只有一种绕 x 或 y 轴旋转的方法。
真的需要帮助。
我的代码 : https://jsfiddle.net/pfk7j7a3/3/
<script type="text/javascript">
CustomOrbit = function () {
var EPS = 0.000001;
var rotateStart = new THREE.Vector2();
var rotateEnd = new THREE.Vector2();
var rotateDelta = new THREE.Vector2();
var phiDelta = 0;
var thetaDelta = 0;
var target = new THREE.Vector3();
/// How far you can orbit vertically, upper and lower limits.
var minPolarAngle = Math.PI / 2;
var maxPolarAngle = Math.PI * 0.91;
var onMouseDownPosition = new THREE.Vector2();
this.Initialize = function () {
renderer.domElement.addEventListener('mousedown', onMouseDown, false);
}
var onMouseMove = function (event) {
event.preventDefault();
rotateEnd.set(event.clientX, event.clientY);
rotateDelta.subVectors(rotateEnd, rotateStart);
thetaDelta -= 2 * Math.PI * rotateDelta.x / renderer.domElement.clientWidth;
phiDelta -= 2 * Math.PI * rotateDelta.y / renderer.domElement.clientHeight;
var position = camera.position;
var offset = position.clone().sub(target);
// angle from z-axis around y-axis
var theta = Math.atan2(offset.x, offset.z);
theta += thetaDelta;
// angle from y-axis
var phi = Math.atan2(Math.sqrt(offset.x * offset.x + offset.z * offset.z), offset.y);
phi += phiDelta;
phi = Math.max(minPolarAngle, Math.min(maxPolarAngle, phi));// restrict phi to be between desired limits
phi = Math.max(EPS, Math.min(Math.PI - EPS, phi)); // restrict phi to be between EPS and PI-EPS
var radius = offset.length();
radius = Math.max(0, Math.min(Infinity, radius)); // restrict radius to be between desired limits
offset.x = radius * Math.sin(phi) * Math.sin(theta);
offset.y = radius * Math.cos(phi);
offset.z = radius * Math.sin(phi) * Math.cos(theta);
position.copy(target).add(offset);
camera.lookAt(target);
thetaDelta = 0;
phiDelta = 0;
rotateStart.copy(rotateEnd);
}
var onMouseUp = function (event) {
renderer.domElement.removeEventListener('mousemove', onMouseMove, false);
renderer.domElement.removeEventListener('mouseup', onMouseUp, false);
}
var onMouseDown = function (event) {
event.preventDefault();
vector = new THREE.Vector3(0, 0, camera.near);
vector.unproject(camera);
raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize(), camera.near, camera.far);
intersects = raycaster.intersectObject(pickingMesh);
if (intersects.length > 0) {
target = intersects[0].point;
rotateStart.set(event.clientX, event.clientY);
renderer.domElement.addEventListener('mousemove', onMouseMove, false);
renderer.domElement.addEventListener('mouseup', onMouseUp, false);
}
}
};
</script>
<script type="text/javascript">
var camera, scene, renderer, pickingMesh, rendWidth = 500, rendHeight = 500;
init();
makeMesh();
makeAxis(200);
animate();
function init() {
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: false });
renderer.setSize(500, 500);
document.body.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(55, 500 / 500, 0.1, 10000);
camera.position.x = 200000;
camera.position.y = 400000;
camera.position.z = 300;
camera.lookAt(new THREE.Vector3(200000, 400000, 0.0));
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
//create red square mesh
function makeMesh() {
var geometry = new THREE.BufferGeometry();
var vertices = new Float32Array([
200000 - 100.0, 400000 - 100.0, 0.0,
200000 + 100.0, 400000 + 100.0, 0.0,
200000 - 100.0, 400000 + 100.0, 0.0,
200000 - 100.0, 400000 - 100.0, 0.0,
200000 + 100.0, 400000 - 100.0, 0.0,
200000 + 100.0, 400000 + 100.0, 0.0
]);
geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
var material = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: true, opacity: 0.5 });
material.side = THREE.DoubleSide;
pickingMesh = new THREE.Mesh(geometry, material);
scene.add(pickingMesh);
}
function makeAxis(axisLength) {
var x_axis = new THREE.Geometry(); x_axis.vertices.push(new THREE.Vector3(200000 - axisLength, 400000, 0), new THREE.Vector3(200000 + axisLength, 400000, 0));
var y_axis = new THREE.Geometry(); y_axis.vertices.push(new THREE.Vector3(200000, 400000 - axisLength, 0), new THREE.Vector3(200000, 400000 + axisLength, 0));
var z_axis = new THREE.Geometry(); z_axis.vertices.push(new THREE.Vector3(200000, 400000, -axisLength), new THREE.Vector3(200000, 400000, axisLength));
var x_axis_line = new THREE.Line(x_axis, new THREE.LineBasicMaterial({ linewidth: 1, transparent: true, color: 0x0000ff }));
var y_axis_line = new THREE.Line(y_axis, new THREE.LineBasicMaterial({ linewidth: 1, transparent: true, color: 0x00ff00 }));
var z_axis_line = new THREE.Line(z_axis, new THREE.LineBasicMaterial({ linewidth: 1, transparent: true, color: 0xff0000 }));
scene.add(x_axis_line);
scene.add(y_axis_line);
scene.add(z_axis_line);
};
var myOrbit = new CustomOrbit();
myOrbit.Initialize();
</script>
如果你尝试从0,0,0位置旋转(相机围绕某物,物体围绕中心的某些位置(,数学将开始变得更加复杂。
我最好的经验是轨道控制。https://threejs.org/examples/misc_controls_orbit.html
您可以设置角度限制和声移限制。