使用webvr-boilerplate将three.js对象放在相机前面,但不要绑在相机上

时间:2015-12-24 04:08:30

标签: three.js webvr

我有一个不可见的object3D。我可以使用webvr-boilerplate自由地环顾四周。点击后,我想将这个物体3D放在相机前面,使其可见,但在“地面”上方的某个y位置。

我试过以下但是如果我看到那里它会将object3D置于半空中,并且在“地面”之上的某个位置没有它:

for

我想我需要从中提取某些相机旋转和定位组件并将其应用到我的object3D以获得我想要的效果。

非常欢迎任何提示!

1 个答案:

答案 0 :(得分:4)

这样做的一种方法是将物体放在您希望它出现的位置的枢轴上,然后旋转并定位枢轴,而不是试图同时计算物体的旋转和位置。

var pivot = new THREE.Object3D();
scene.add(pivot);
pivot.add(object3D);
// position the object on the pivot, so that it appears 5 meters 
// in front of the user.
object3D.position.z = -5;

接下来,一般来说,您希望将相机的四元数分解为相对于平面的组件。在你的情况下,飞机是地面(X-Z,我假设)。

another Stack Overflow answer派生,您可以通过一些操作在three.js中执行此操作:

var yaxis = new THREE.Vector3(0, 1, 0);
var zaxis = new THREE.Vector3(0, 0, 1);
var direction = zaxis.clone();
// Apply the camera's quaternion onto the unit vector of one of the axes
// of our desired rotation plane (the z axis of the xz plane, in this case).
direction.applyQuaternion(camera.quaternion);
// Project the direction vector onto the y axis to get the y component
// of the direction.
var ycomponent = yaxis.clone().multiplyScalar(direction.dot(yaxis));
// Subtract the y component from the direction vector so that we are
// left with the x and z components.
direction.sub(ycomponent);
// Normalize the direction into a unit vector again.
direction.normalize();
// Set the pivot's quaternion to the rotation required to get from the z axis
// to the xz component of the camera's direction.
pivot.quaternion.setFromUnitVectors(zaxis, direction);
// Finally, set the pivot's position as well, so that it follows the camera.
pivot.position.copy(camera.position);

完整的示例代码:



var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000);
var controls = new THREE.VRControls(camera);
var effect = new THREE.VREffect(renderer);
effect.setSize(window.innerWidth, window.innerHeight);
var manager = new WebVRManager(renderer, effect, {hideButton: false});

// Add a repeating grid as a skybox.
var boxWidth = 5;
THREE.ImageUtils.crossOrigin = '';
var texture = THREE.ImageUtils.loadTexture(
  'http://cdn.rawgit.com/borismus/webvr-boilerplate/0.3.3/img/box.png'
);
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(boxWidth, boxWidth);
var skybox = new THREE.Mesh(
  new THREE.BoxGeometry(boxWidth, boxWidth, boxWidth),
  new THREE.MeshBasicMaterial({
    map: texture,
    color: 0x01BE00,
    side: THREE.BackSide
  })
);
scene.add(skybox);

var floorPos = -1.5;
var floor = new THREE.Mesh(
  new THREE.PlaneGeometry(100, 100, 2, 2),
  new THREE.MeshBasicMaterial({color: 'white'})
);
floor.position.set(0, floorPos, 0);
floor.rotation.x = -Math.PI / 2;
scene.add(floor);

var thingDistance = -1;

var box = new THREE.Mesh(
  new THREE.BoxGeometry(0.5, 0.5, 0.5),
  new THREE.MeshNormalMaterial()
  );
box.position.set(-0.5, floorPos, thingDistance);
var boxPos = box.position.clone();
scene.add(box);

var ball = new THREE.Mesh(
  new THREE.SphereGeometry(0.3),
  new THREE.MeshNormalMaterial()
  );
ball.position.set(0.5, floorPos, thingDistance);
var ballPos = ball.position.clone();
scene.add(ball);

var pivot = new THREE.Object3D();
scene.add(pivot);

var ballInFront = false;
document.addEventListener('click', function () {
  if (ballInFront) {
    scene.add(ball);
    ball.position.copy(ballPos);
    
    pivot.add(box);
    box.position.set(0, 0, thingDistance);
    ballInFront = false;
  }
  else {
    scene.add(box);
    box.position.copy(boxPos);
    
    pivot.add(ball);
    ball.position.set(0, 0, thingDistance);
    ballInFront = true;
  }
});


var yaxis = new THREE.Vector3(0, 1, 0);
var zaxis = new THREE.Vector3(0, 0, 1);
function animate(timestamp) {
  controls.update();
  
  var direction = zaxis.clone();
  // Apply the camera's quaternion onto the unit vector of one of the axes
  // of our desired rotation plane (the z axis of the xz plane, in this case).
  direction.applyQuaternion(camera.quaternion);
  // Project the direction vector onto the y axis to get the y component
  // of the direction.
  var ycomponent = yaxis.clone().multiplyScalar(direction.dot(yaxis));
  // Subtract the y component from the direction vector so that we are
  // left with the x and z components.
  direction.sub(ycomponent);
  // Normalize the direction into a unit vector again.
  direction.normalize();
  // Set the pivot's quaternion to the rotation required to get from the z axis
  // to the xz component of the camera's direction.
  pivot.quaternion.setFromUnitVectors(zaxis, direction);
  
  pivot.position.copy(camera.position);
  
  manager.render(scene, camera, timestamp);
  requestAnimationFrame(animate);
}
animate();

function onKey(event) {
  if (event.keyCode == 90) { // z
    controls.resetSensor();
  }
}
window.addEventListener('keydown', onKey, true);

<!DOCTYPE html>
<html>
<head>
<meta name="description" content="SO 34447119">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  <meta name="mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
  <title>JS Bin</title>
  <script src="https://cdn.rawgit.com/borismus/webvr-boilerplate/0.2.2/bower_components/threejs/build/three.js"></script>
  <script src="https://cdn.rawgit.com/borismus/webvr-boilerplate/0.2.2/bower_components/threejs/examples/js/controls/VRControls.js"></script>
  <script src="https://cdn.rawgit.com/borismus/webvr-boilerplate/0.2.2/bower_components/threejs/examples/js/effects/VREffect.js"></script>
  <script src="https://cdn.rawgit.com/borismus/webvr-boilerplate/0.2.2/bower_components/webvr-polyfill/build/webvr-polyfill.js"></script>
  <script src="https://cdn.rawgit.com/borismus/webvr-boilerplate/0.2.2/build/webvr-manager.js"></script>
</head>
<body>
</body> 
</html>
&#13;
&#13;
&#13;