ThreeJS update Camera position, so that the position of the planet in the world corresponds to the position of the DIV screen

purpose

I want to update the position of the camera so that the position of the plane of the plane matches the position of the DIV screen.

before updating after update another perspective

First thoughts

I need to calculate camera.position.z- so that the planes fit the size DIV- even when resizing the canvas.

this.computeZ = function(meshHandle, cameraHandle, faceHeight, targetHeight){
    var face = meshHandle.geometry.vertices[2]
    var vFOV = cameraHandle.fov * Math.PI / 180;  
    var vHeightPartial = 2 * Math.tan( vFOV / 2 );
    var p1 = faceHeight * window.innerHeight;
    var p2 = face.z * vHeightPartial;
    var p3 = targetHeight * vHeightPartial;
    var p4 = targetHeight * p2;
    var p5 = p1 + p4;
    var z = p5/p3;
    return z;
}

See here computeZ.

Next steps

The face size in the world now corresponds to the size of the screen pixel DIV.

Next we need to find camera.position.xand camera.position.y- so that the face crosses directly DIV.

...

Three.js -
THREE.JS:
Three.js Projection

... -, computeX computeY

,

computeX computeY , . - - .

?

Update

Craig post. .

+5
2

<!DOCTYPE html>

<html>

<head>
    <title>SO code</title>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"></script>
    <style>
          html,body{
		  height:100%;
		  width:100%;
		  padding:0px;
		  margin:0px;
		}
		#content{
		  width:100%;
		  height:100%;
		  position:relative;
		}
		#box{
		  position:absolute;
		  background:orange;
		  height:100px;
		  width:100px;
		  bottom:100px;
		  right:100px;
		}
    </style>
    </head>
	<body>
	<div id="content">
	  <div id="box"></div>
	</div>
<script>
	function Terrain(){

	  this.container = document.getElementById('content');
	  this.camera;
	  this.scene; 
	  this.renderer;
	  this.light;

	  this.computeZ = function(meshHandle, cameraHandle, faceHeight, targetHeight){
	  	var face = meshHandle.geometry.vertices[2]
			var vFOV = cameraHandle.fov * Math.PI / 180;  
			var vHeightPartial = 2 * Math.tan( vFOV / 2 );
			var p1 = faceHeight * window.innerHeight;
			var p2 = face.z * vHeightPartial;
			var p3 = targetHeight * vHeightPartial;
			var p4 = targetHeight * p2;
			var p5 = p1 + p4;
			var z = p5/p3;
      
			//calculate dom element center coordinate
			var screenPositionX = 0;
			var screenPositionY = 0;
			var div = document.getElementById('box');
			var divDim = div.getBoundingClientRect();
			screenPositionX = (divDim.left + divDim.right) / 2;
			screenPositionY = (divDim.bottom + divDim.top) / 2;
			var vector = new THREE.Vector3((screenPositionX / window.innerWidth) * 2 -1, (screenPositionY / window.innerHeight) * 2 -1, 0.5);
    //unproject camera
			vector = vector.unproject(this.camera);
			var distanceZ = this.camera.position.z - vector.z ;
			var offsetX = vector.x * (z-10) / distanceZ;
			var offsetY = vector.y * (z-10) / distanceZ;
			var cameraPosition = new THREE.Vector3(offsetX,offsetY,z);
			return cameraPosition;
		}
	  
		this.computeX = function(meshHandle, cameraHandle, faceHeight, targetWidth){
	  	var div = document.getElementById('box');
			var divDim = div.getBoundingClientRect();
			var y =  ((divDim.left + (targetWidth/2)) / window.innerHeight ) * 2 + 1;
			return y;
	  }
	  
	  this.computeY = function(meshHandle, cameraHandle, faceHeight, targetHeight){
			var div = document.getElementById('box');
			var divDim = div.getBoundingClientRect();
			var y =  ((divDim.top + (targetHeight/2)) / window.innerHeight ) * 2 + 1;
			return y;
	  }
	  this.onDocumentClick = function(event)
	  {
	  			var vector = new THREE.Vector3(( event.clientX / (window.innerWidth) ) * 2 - 1, -( event.clientY / window.innerHeight ) * 2 + 1, 0.5);
                vector = vector.unproject(this.camera);

                console.log(vector);
	  }
	  this.init();
	}

	Terrain.prototype.init = function () {

		this.camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
		this.scene = new THREE.Scene();

		this.geometry = new THREE.BoxGeometry(20, 20, 20);
		this.material = new THREE.MeshPhongMaterial();
		this.mesh = new THREE.Mesh( this.geometry, this.material );
		this.scene.add( this.mesh );
		
		var ambient = new THREE.AmbientLight( 0x00ff00, 0.5 );
		this.scene.add( ambient );

		this.renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
		this.renderer.setPixelRatio( window.devicePixelRatio );
		this.renderer.setSize( window.innerWidth, window.innerHeight );
		this.container.appendChild(this.renderer.domElement );
	  
		window.animations['terrain'] = this.animate.bind(this);
		window.addEventListener( 'resize', this.onWindowResize.bind(this), false );
		document.addEventListener('click',this.onDocumentClick.bind(this), false);
	}

	Terrain.prototype.onWindowResize = function(){
		this.renderer.setSize( window.innerWidth, window.innerHeight );
	  this.camera.aspect = window.innerWidth / window.innerHeight;
	  this.camera.updateProjectionMatrix();
	}

	Terrain.prototype.animate = function(){
	  	//this.camera.position.x = this.computeX(this.mesh, this.camera, 20, 100);
	  //this.camera.position.y = this.computeY(this.mesh, this.camera, 20, 100);
	  this.renderer.render( this.scene, this.camera );
	}

	function animate(){
	  for(var i in window.animations){
	    window.animations[i]();
	  };
	  window.requestAnimationFrame(animate);
	}

	window.animations = {};
	var terrain = new Terrain();
	window.requestAnimationFrame(animate);
	var newPosition = terrain.computeZ(terrain.mesh,terrain.camera,20,100);
	terrain.camera.position.x -= newPosition.x;
	terrain.camera.position.y += newPosition.y;
	terrain.camera.position.z += newPosition.z;
</script>
</body>
</html>
Hide result

, : 1: dom . 2: , x y. , .

enter image description here

, . dom, , Y, .

dom 3D-, "z", . x ( ). , . vector.x / offsetX = vector.z / z - mesh.geometry.parameters.depth. , offsetY.

+6

, Z ? .

Terrain.prototype.computeZ = function(meshHandle, cameraHandle, faceHeight, targetHeight){

var face = meshHandle.geometry.vertices[2]
var vFOV = cameraHandle.fov * Math.PI / 180;  
var vHeightPartial = 2 * Math.tan( vFOV / 2 );
var p1 = faceHeight * window.innerHeight;
console.log(p1);
var p2 = face.z * vHeightPartial;
console.log(p2)
var p3 = targetHeight * vHeightPartial;
var p4 = targetHeight * p2;
var p5 = p1 + p4;
var z = p5/p3;

//unproject camera
vector = this.getUnprojectedVector(cameraHandle);
this.previousUnprojection = vector;
this.previousCamera = cameraHandle.clone();
var distanceZ = cameraHandle.position.z - vector.z ;
var offsetX = -vector.x * (z-10) / distanceZ;
var offsetY = vector.y * (z-10) / distanceZ;
var cameraPosition = new THREE.Vector3(offsetX,offsetY,z);
return cameraPosition;

}

0

Source: https://habr.com/ru/post/1676206/


All Articles