How to convert spelling camera to Perspective and vice versa?

I am using sharedcamera.js along with orbitcontrols.js https://github.com/mrdoob/three.js/blob/master/examples/js/cameras/CombinedCamera.js https://github.com/mrdoob/three.js /blob/master/examples/js/controls/OrbitControls.js

I am working so that the cameras can switch and both can be zoomed in and out. However, orbitcontrols repositions the perspective camera to simulate zooming, and it does not do it with the spelling camera (it changes fov, etc.).

This causes the far angle camera to move in perspective mode (I want this) and it does not move in orthographic mode (I want it to move).

I fixed this by doing a perspective and spelling camera override. The spelling camera does not use its position to determine scaling, so a problem arises.

The problem is that when switching between cameras, they don't have the same zoom value.

I guess the question is, how do I make the spelling camera rely on the position of the camera to determine the zoom amount so that it always looks the same as the perspective camera?

+3


source to share


1 answer


Ok, so with a lot of experimenting I found a hacky way to get the result that is close enough. I accidentally discovered that if the far truncate value was set to 25 it would work just fine. So I made an equation to compensate if the value is different. It's close enough, but maybe someone could see where it could be improved?

I replaced in combcamera.js

halfHeight /= this.zoom;
halfWidth /= this.zoom;

      

from

halfHeight /= ((this.cameraP.far/25)*this.zoom);
halfWidth /= ((this.cameraP.far/25)*this.zoom);

      

And I added this line in the ccccamera.js file

this.cameraO.far = this.cameraP.far+((this.cameraP.far/25)*this.zoom)-0.5;

      

before that



this.cameraO.updateProjectionMatrix();

      

here's the full section

 THREE.CombinedCamera.prototype.toOrthographic = function () {

// Switches to the Orthographic camera estimating viewport from Perspective

var fov = this.fov;
var aspect = this.cameraP.aspect;
var near = this.cameraP.near;
var far = this.cameraP.far;

// The size that we set is the mid plane of the viewing frustum

var hyperfocus = ( near + far ) / 2;

var halfHeight = Math.tan( fov * Math.PI / 180 / 2 ) * hyperfocus;
var planeHeight = 2 * halfHeight;
var planeWidth = planeHeight * aspect;
var halfWidth = planeWidth / 2;

halfHeight /= ((this.cameraP.far/25)*this.zoom);
halfWidth /= ((this.cameraP.far/25)*this.zoom);

this.cameraO.left = -halfWidth;
this.cameraO.right = halfWidth;
this.cameraO.top = halfHeight;
this.cameraO.bottom = -halfHeight;

// this.cameraO.left = -farHalfWidth;
// this.cameraO.right = farHalfWidth;
// this.cameraO.top = farHalfHeight;
// this.cameraO.bottom = -farHalfHeight;

// this.cameraO.left = this.left / this.zoom;
// this.cameraO.right = this.right / this.zoom;
// this.cameraO.top = this.top / this.zoom;
// this.cameraO.bottom = this.bottom / this.zoom;

this.cameraO.far = this.cameraP.far+((this.cameraP.far/25)*this.zoom)-0.5;
this.cameraO.updateProjectionMatrix();

this.near = this.cameraO.near;
this.far = this.cameraO.far;
this.projectionMatrix = this.cameraO.projectionMatrix;

this.inPerspectiveMode = false;
this.inOrthographicMode = true;

 };

      

also i change this.zoom to 1 for perspective camera

 THREE.CombinedCamera.prototype.toPerspective = function () {

// Switches to the Perspective Camera

this.near = this.cameraP.near;
this.far = this.cameraP.far;

this.cameraP.fov =  this.fov / 1 ;

this.cameraP.updateProjectionMatrix();

this.projectionMatrix = this.cameraP.projectionMatrix;

this.inPerspectiveMode = true;
this.inOrthographicMode = false;

 };

      

Also, I had to tweak the orbit control

this.dollyIn = function ( dollyScale ) {

    if ( dollyScale === undefined ) {

        dollyScale = getZoomScale();

    }

        scale /= dollyScale;
        scope.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom * dollyScale ) );
};

this.dollyOut = function ( dollyScale ) {

    if ( dollyScale === undefined ) {

        dollyScale = getZoomScale();

    }

        scale *= dollyScale;
        scope.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom / dollyScale ) );
};

      

0


source







All Articles