phaser/src/gameobjects/mesh/MeshCamera.js
2020-10-06 18:05:14 +01:00

302 lines
6 KiB
JavaScript

/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2020 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
var Class = require('../../utils/Class');
var DegToRad = require('../../math/DegToRad');
var Matrix4 = require('../../math/Matrix4');
var Vector3 = require('../../math/Vector3');
var Vector4 = require('../../math/Vector4');
/**
* @classdesc
* The Mesh Camera.
*
* @class MeshCamera
* @memberof Phaser.GameObjects
* @constructor
* @since 3.50.0
*/
var MeshCamera = new Class({
initialize:
function MeshCamera (fov, x, y, z, near, far)
{
this.dirty = true;
this.aspectRatio = 1;
this._fov = fov;
this._near = near;
this._far = far;
this.position = new Vector3(x, y, z);
this.rotation = new Vector3();
this.forward = new Vector4();
this.up = new Vector4(); // What the up direction is, invert to get bottom
this.right = new Vector4(); // What the right direction is, invert to get left
this.matView = new Matrix4();
this.viewMatrix = new Matrix4();
this.projectionMatrix = new Matrix4();
this.mode = MeshCamera.MODE_ORBIT;
},
panX: function (v)
{
this.updateViewMatrix();
this.position.addScale(this.right, v);
},
panY: function (v)
{
this.updateViewMatrix();
this.position.y += this.up.y * v;
if (this.mode === MeshCamera.MODE_ORBIT)
{
// Can only move up and down the y axix in orbit mode
return;
}
this.position.x += this.up.x * v;
this.position.z += this.up.z * v;
},
panZ: function (v)
{
this.updateViewMatrix();
if (this.mode === MeshCamera.MODE_ORBIT)
{
// orbit mode does translate after rotate, so only need to set Z, the rotate will handle the rest.
this.position.z += v;
}
else
{
// In freemode to move forward, we need to move based on our forward which is relative to our current rotation
this.position.addScale(this.forward, v);
}
},
// To have different modes of movements, this function handles the view matrix update for the transform object.
updateViewMatrix: function ()
{
var d = Math.PI / 180;
var matView = this.matView;
var rotation = this.rotation;
matView.identity();
// Optimize camera transform update, no need for scale nor rotateZ
if (this.mode === MeshCamera.MODE_FREE)
{
matView.translate(this.position);
matView.rotateX(rotation.x * d);
matView.rotateY(rotation.y * d);
}
else
{
matView.rotateX(rotation.x * d);
matView.rotateY(rotation.y * d);
matView.translate(this.position);
}
this.updateDirection();
this.viewMatrix.copy(matView);
this.viewMatrix.invert();
this.dirty = true;
},
update: function (width, height)
{
this.aspectRatio = width / height;
this.updateViewMatrix();
this.projectionMatrix.perspective(DegToRad(this._fov), this.aspectRatio, this._near, this._far);
},
updateDirection: function ()
{
var matView = this.matView;
this.forward.set(0, 0, 1, 0).transformMat4(matView);
this.up.set(0, 1, 0, 0).transformMat4(matView);
this.right.set(1, 0, 0, 0).transformMat4(matView);
},
reset: function ()
{
this.position.set();
this.rotation.set();
this.updateViewMatrix();
},
fov: {
get: function ()
{
return this._fov;
},
set: function (value)
{
if (value > 0 && value < 180)
{
this._fov = value;
this.dirty = true;
}
}
},
near: {
get: function ()
{
return this._near;
},
set: function (value)
{
if (value > 0)
{
this._near = value;
this.dirty = true;
}
}
},
far: {
get: function ()
{
return this._far;
},
set: function (value)
{
if (value > 0)
{
this._far = value;
this.dirty = true;
}
}
},
x: {
get: function ()
{
return this.position.x;
},
set: function (value)
{
this.position.x = value;
this.updateViewMatrix();
}
},
y: {
get: function ()
{
return this.position.y;
},
set: function (value)
{
this.position.y = value;
this.updateViewMatrix();
}
},
z: {
get: function ()
{
return this.position.z;
},
set: function (value)
{
this.position.z = value;
this.updateViewMatrix();
}
},
rotationX: {
get: function ()
{
return this.rotation.x;
},
set: function (value)
{
this.rotation.x = value;
this.updateViewMatrix();
}
},
rotationY: {
get: function ()
{
return this.rotation.y;
},
set: function (value)
{
this.rotation.y = value;
this.updateViewMatrix();
}
},
rotationZ: {
get: function ()
{
return this.rotation.z;
},
set: function (value)
{
this.rotation.z = value;
this.updateViewMatrix();
}
},
destroy: function ()
{
// TODO - Needed?
}
});
// Allows free movement of position and rotation
MeshCamera.MODE_FREE = 0;
// Movement is locked to rotate around the origin
MeshCamera.MODE_ORBIT = 1;
module.exports = MeshCamera;