1

I have started with three.js and I trying to move a object randomly around. But I am facing a problem of detecting that when does my 3d model moves outside of the visible area of the scene. I don't want the 3d model to move outside the scene. When I logged the position of the 3d model and the window.innerwidth I found that there was a huge difference in them even when the model is at the corner of the visible area. Can anyone help me out here?

Also if there are any suggestions on how can I achieve the bigger objective of random movement of the 3d object, please do share.

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();

renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xff0000, .5);
document.body.appendChild(renderer.domElement);

var geometry = new THREE.BoxGeometry();
var material = new THREE.MeshBasicMaterial({
  color: 0x00ff00
});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;


let pos = new THREE.Vector3();
pos = pos.setFromMatrixPosition(cube.matrixWorld);
pos.project(camera);

let widthHalf = window.innerWidth / 2;
let heightHalf = window.innerHeight / 2;

pos.x = (pos.x * widthHalf) + widthHalf;
pos.y = - (pos.y * heightHalf) + heightHalf;
pos.z = 0;


var numFlag = 0,
  value = 0.01;

function animate() {
  requestAnimationFrame(animate);
  firstQuadrant();
  renderer.render(scene, camera);
}

animate();

function firstQuadrant() {
  if (numFlag < 300) {
    cube.position.x += value;
    cube.position.y += value;
  } else {
    cube.position.x -= value;
    cube.position.y -= value;
  }
  console.log(cube.position.x, window.innerHeight,pos.x);
  numFlag = numFlag > 600 ? 0 : numFlag + 1;
}
body {
  margin: 0;
}

canvas {
  display: block;
}

Update

When I try to change world coordinates to screen coordinates, by adding foloowing lines

let pos = new THREE.Vector3();
pos = pos.setFromMatrixPosition(cube.matrixWorld);
pos.project(camera);

let widthHalf = window.innerWidth / 2;
let heightHalf = window.innerHeight / 2;

pos.x = (pos.x * widthHalf) + widthHalf;
pos.y = - (pos.y * heightHalf) + heightHalf;
pos.z = 0;

then I get the pos.x value as NaN. What did I miss/went wrong?

abhishek ranjan
  • 612
  • 7
  • 23
  • Couple of things which might help you out. Your console log is logging the cube's X position (Y is up). window.innerHeight won't match the co-ordinates you're expecting. You've got screen values and 3d world co-ordinates. You should also remember that world position 0,0,0 is in the middle of the screen, so window.innerHeight would need to be halved to get closer to what you expect. Take a look at this link, which could help you with your objective - https://stackoverflow.com/a/11605007/8837901 – danlong Mar 25 '20 at 09:00
  • thanks for the reply @danlong, i am getting pos.x value as a NaN. where did I went wrong? – abhishek ranjan Mar 25 '20 at 09:59
  • Can you add the code block into your original example so I can see it as a whole? – danlong Mar 25 '20 at 10:13
  • @danlong I added it. – abhishek ranjan Mar 25 '20 at 10:16
  • OK I see. I think you might need a different approach. Take a look at this thread - https://discourse.threejs.org/t/functions-to-calculate-the-visible-width-height-at-a-given-z-depth-from-a-perspective-camera/269 It has a useful code example in which will create a plane within the window size. Once you have that, you know the bounding box in which your cube can move. It might be easier to pick a random co-ordinate within the bounding box and tween to that position. The `firstQuadrant` function you have might limit the 'random' movement'. – danlong Mar 25 '20 at 12:01

0 Answers0