Three.js - VRControls 集成 - 如何在场景中移动?
Three.js - VRControls integration - How to move in the scene?
我使用Three.js在小场景中渲染和移动(我的orbitControl变化camera.position)。
现在我有一个 oculus rift。所以我添加了 VRControls 和 VREffect。
移动头部没有问题。
但是我不能再在场景中移动,因为 VRControls 覆盖了相机参数:
object.quaternion.copy( state.orientation ); // object is the camera
我认为这很容易纠正:我只需要更新相机而不是覆盖它:
object.quaternion.copy(stateOrientationQuat.multiply(currentCameraQuat));
但它不起作用:它呈现移动的轻弹场景。 VRControls 和 orbitControl 好像在打架...
你能告诉我如何将 VRControls 集成到现有项目中吗?如果你有更新代码(我真的不知道四元数......)它会很有帮助。
谢谢
编辑:请参阅 以获得更好的方法。
您可以通过创建作用于假相机的 VRControls 实例来组合这两个控件,然后在轨道控件上应用变换:
相关片段:
var orbitControls = new THREE.OrbitControls(camera);
// Store the position of the VR HMD in a dummy camera.
var fakeCamera = new THREE.Object3D();
var vrControls = new THREE.VRControls(fakeCamera);
...
var render = function() {
requestAnimationFrame(render);
orbitControls.update();
vrControls.update();
// Temporarily save the orbited camera position
var orbitPos = camera.position.clone();
// Apply the VR HMD camera position and rotation
// on top of the orbited camera.
var rotatedPosition = fakeCamera.position.applyQuaternion(
camera.quaternion);
camera.position.add(rotatedPosition);
camera.quaternion.multiply(fakeCamera.quaternion);
vrEffect.render(scene, camera);
// Restore the orbit position, so that the OrbitControls can
// pickup where it left off.
camera.position.copy(orbitPos);
};
完整示例:
var renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var vrEffect = new THREE.VREffect(renderer, function () {});
var camera = new THREE.PerspectiveCamera(
75, window.innerWidth / window.innerHeight, 0.1, 1000);
var orbitControls = new THREE.OrbitControls(camera);
// Store the position of the VR HMD in a dummy camera.
var fakeCamera = new THREE.Object3D();
var vrControls = new THREE.VRControls(fakeCamera);
var scene;
var createScene = function () {
scene = new THREE.Scene();
scene.add(new THREE.PointLight());
var cube = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshLambertMaterial({
color: 'green'
})
);
cube.position.set(-1, -2, -5);
scene.add(cube);
orbitControls.target = cube.position;
for (var i = 0; i < 10; i++) {
cube = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshLambertMaterial()
);
cube.position.set(
(Math.random() - 0.5) * 20,
(Math.random() - 0.5) * 20,
(Math.random() - 0.5) * 20
);
scene.add(cube);
}
};
createScene();
var render = function() {
requestAnimationFrame(render);
orbitControls.update();
vrControls.update();
// Temporarily save the orbited camera position
var orbitPos = camera.position.clone();
// Apply the VR HMD camera position and rotation
// on top of the orbited camera.
var rotatedPosition = fakeCamera.position.applyQuaternion(
camera.quaternion);
camera.position.add(rotatedPosition);
camera.quaternion.multiply(fakeCamera.quaternion);
vrEffect.render(scene, camera);
// Restore the orbit position, so that the OrbitControls can
// pickup where it left off.
camera.position.copy(orbitPos);
};
render();
window.addEventListener('resize', function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
vrEffect.setSize( window.innerWidth, window.innerHeight );
}, false );
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/8125c7dac9bf0c7df19bd1d7d9695cbfc0425867/build/three.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/8125c7dac9bf0c7df19bd1d7d9695cbfc0425867/examples/js/effects/VREffect.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/8125c7dac9bf0c7df19bd1d7d9695cbfc0425867/examples/js/controls/VRControls.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/8125c7dac9bf0c7df19bd1d7d9695cbfc0425867/examples/js/controls/OrbitControls.js"></script>
我发现有一种更简洁的方法可以做到这一点。您可以创建一个 "dolly" 相机并将 VR 相机添加为子相机。
然后你可以让 OrbitControls 控制小车,让 VRControls 控制实际的相机,而不需要求助于混乱的计算。
相关片段:
var camera = new THREE.PerspectiveCamera(
75, window.innerWidth / window.innerHeight, 0.1, 1000);
var vrControls = new THREE.VRControls(camera);
var scene = new THREE.Scene();
// The dolly has to be a PerspectiveCamera, as opposed
// to a simple Object3D, since that's what
// OrbitControls expects.
var dollyCam = new THREE.PerspectiveCamera();
var orbitControls = new THREE.OrbitControls(dollyCam);
dollyCam.add(camera);
scene.add(dollyCam);
...
var render = function() {
requestAnimationFrame(render);
orbitControls.update();
vrControls.update();
vrEffect.render(scene, camera);
};
完整示例:
var renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var vrEffect = new THREE.VREffect(renderer);
var camera = new THREE.PerspectiveCamera(
75, window.innerWidth / window.innerHeight, 0.1, 1000);
var vrControls = new THREE.VRControls(camera);
var orbitControls;
var scene;
var createScene = function () {
scene = new THREE.Scene();
// The dolly has to be a PerspectiveCamera, as opposed
// to a simple Object3D, since that's what
// OrbitControls expects.
var dollyCam = new THREE.PerspectiveCamera();
orbitControls = new THREE.OrbitControls(dollyCam);
dollyCam.add(camera);
scene.add(dollyCam);
scene.add(new THREE.PointLight());
var cube = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshLambertMaterial({
color: 'green'
})
);
cube.position.set(-1, -2, -5);
scene.add(cube);
orbitControls.target.copy(cube.position);
for (var i = 0; i < 10; i++) {
cube = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshLambertMaterial()
);
cube.position.set(
(Math.random() - 0.5) * 20,
(Math.random() - 0.5) * 20,
(Math.random() - 0.5) * 20
);
scene.add(cube);
}
};
createScene();
var render = function() {
requestAnimationFrame(render);
orbitControls.update();
vrControls.update();
vrEffect.render(scene, camera);
};
render();
window.addEventListener('resize', function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
vrEffect.setSize( window.innerWidth, window.innerHeight );
}, false );
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/r72/build/three.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/r72/examples/js/effects/VREffect.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/r72/examples/js/controls/VRControls.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/r72/examples/js/controls/OrbitControls.js"></script>
我使用Three.js在小场景中渲染和移动(我的orbitControl变化camera.position)。
现在我有一个 oculus rift。所以我添加了 VRControls 和 VREffect。
移动头部没有问题。
但是我不能再在场景中移动,因为 VRControls 覆盖了相机参数:
object.quaternion.copy( state.orientation ); // object is the camera
我认为这很容易纠正:我只需要更新相机而不是覆盖它:
object.quaternion.copy(stateOrientationQuat.multiply(currentCameraQuat));
但它不起作用:它呈现移动的轻弹场景。 VRControls 和 orbitControl 好像在打架...
你能告诉我如何将 VRControls 集成到现有项目中吗?如果你有更新代码(我真的不知道四元数......)它会很有帮助。
谢谢
编辑:请参阅
您可以通过创建作用于假相机的 VRControls 实例来组合这两个控件,然后在轨道控件上应用变换:
相关片段:
var orbitControls = new THREE.OrbitControls(camera);
// Store the position of the VR HMD in a dummy camera.
var fakeCamera = new THREE.Object3D();
var vrControls = new THREE.VRControls(fakeCamera);
...
var render = function() {
requestAnimationFrame(render);
orbitControls.update();
vrControls.update();
// Temporarily save the orbited camera position
var orbitPos = camera.position.clone();
// Apply the VR HMD camera position and rotation
// on top of the orbited camera.
var rotatedPosition = fakeCamera.position.applyQuaternion(
camera.quaternion);
camera.position.add(rotatedPosition);
camera.quaternion.multiply(fakeCamera.quaternion);
vrEffect.render(scene, camera);
// Restore the orbit position, so that the OrbitControls can
// pickup where it left off.
camera.position.copy(orbitPos);
};
完整示例:
var renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var vrEffect = new THREE.VREffect(renderer, function () {});
var camera = new THREE.PerspectiveCamera(
75, window.innerWidth / window.innerHeight, 0.1, 1000);
var orbitControls = new THREE.OrbitControls(camera);
// Store the position of the VR HMD in a dummy camera.
var fakeCamera = new THREE.Object3D();
var vrControls = new THREE.VRControls(fakeCamera);
var scene;
var createScene = function () {
scene = new THREE.Scene();
scene.add(new THREE.PointLight());
var cube = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshLambertMaterial({
color: 'green'
})
);
cube.position.set(-1, -2, -5);
scene.add(cube);
orbitControls.target = cube.position;
for (var i = 0; i < 10; i++) {
cube = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshLambertMaterial()
);
cube.position.set(
(Math.random() - 0.5) * 20,
(Math.random() - 0.5) * 20,
(Math.random() - 0.5) * 20
);
scene.add(cube);
}
};
createScene();
var render = function() {
requestAnimationFrame(render);
orbitControls.update();
vrControls.update();
// Temporarily save the orbited camera position
var orbitPos = camera.position.clone();
// Apply the VR HMD camera position and rotation
// on top of the orbited camera.
var rotatedPosition = fakeCamera.position.applyQuaternion(
camera.quaternion);
camera.position.add(rotatedPosition);
camera.quaternion.multiply(fakeCamera.quaternion);
vrEffect.render(scene, camera);
// Restore the orbit position, so that the OrbitControls can
// pickup where it left off.
camera.position.copy(orbitPos);
};
render();
window.addEventListener('resize', function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
vrEffect.setSize( window.innerWidth, window.innerHeight );
}, false );
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/8125c7dac9bf0c7df19bd1d7d9695cbfc0425867/build/three.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/8125c7dac9bf0c7df19bd1d7d9695cbfc0425867/examples/js/effects/VREffect.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/8125c7dac9bf0c7df19bd1d7d9695cbfc0425867/examples/js/controls/VRControls.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/8125c7dac9bf0c7df19bd1d7d9695cbfc0425867/examples/js/controls/OrbitControls.js"></script>
我发现有一种更简洁的方法可以做到这一点。您可以创建一个 "dolly" 相机并将 VR 相机添加为子相机。 然后你可以让 OrbitControls 控制小车,让 VRControls 控制实际的相机,而不需要求助于混乱的计算。
相关片段:
var camera = new THREE.PerspectiveCamera(
75, window.innerWidth / window.innerHeight, 0.1, 1000);
var vrControls = new THREE.VRControls(camera);
var scene = new THREE.Scene();
// The dolly has to be a PerspectiveCamera, as opposed
// to a simple Object3D, since that's what
// OrbitControls expects.
var dollyCam = new THREE.PerspectiveCamera();
var orbitControls = new THREE.OrbitControls(dollyCam);
dollyCam.add(camera);
scene.add(dollyCam);
...
var render = function() {
requestAnimationFrame(render);
orbitControls.update();
vrControls.update();
vrEffect.render(scene, camera);
};
完整示例:
var renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var vrEffect = new THREE.VREffect(renderer);
var camera = new THREE.PerspectiveCamera(
75, window.innerWidth / window.innerHeight, 0.1, 1000);
var vrControls = new THREE.VRControls(camera);
var orbitControls;
var scene;
var createScene = function () {
scene = new THREE.Scene();
// The dolly has to be a PerspectiveCamera, as opposed
// to a simple Object3D, since that's what
// OrbitControls expects.
var dollyCam = new THREE.PerspectiveCamera();
orbitControls = new THREE.OrbitControls(dollyCam);
dollyCam.add(camera);
scene.add(dollyCam);
scene.add(new THREE.PointLight());
var cube = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshLambertMaterial({
color: 'green'
})
);
cube.position.set(-1, -2, -5);
scene.add(cube);
orbitControls.target.copy(cube.position);
for (var i = 0; i < 10; i++) {
cube = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshLambertMaterial()
);
cube.position.set(
(Math.random() - 0.5) * 20,
(Math.random() - 0.5) * 20,
(Math.random() - 0.5) * 20
);
scene.add(cube);
}
};
createScene();
var render = function() {
requestAnimationFrame(render);
orbitControls.update();
vrControls.update();
vrEffect.render(scene, camera);
};
render();
window.addEventListener('resize', function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
vrEffect.setSize( window.innerWidth, window.innerHeight );
}, false );
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/r72/build/three.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/r72/examples/js/effects/VREffect.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/r72/examples/js/controls/VRControls.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/r72/examples/js/controls/OrbitControls.js"></script>