r3-legacy/src/game-lib-d3-camera.js

276 lines
7.3 KiB
JavaScript

/**
* Creates a Camera object
* @param graphics GameLib.GraphicsRuntime
* @param apiCamera GameLib.D3.API.Camera
* @constructor
*/
GameLib.D3.Camera = function(
graphics,
apiCamera
) {
this.graphics = graphics;
this.graphics.isNotThreeThrow();
if (GameLib.Utils.UndefinedOrNull(apiCamera)) {
apiCamera = {};
}
GameLib.D3.API.Camera.call(
this,
apiCamera.id,
apiCamera.cameraType,
apiCamera.name,
apiCamera.fov,
apiCamera.aspect,
apiCamera.near,
apiCamera.far,
apiCamera.position,
apiCamera.lookAt,
apiCamera.minX,
apiCamera.maxX,
apiCamera.minY,
apiCamera.maxY,
apiCamera.minZ,
apiCamera.maxZ,
apiCamera.offsetX,
apiCamera.offsetY,
apiCamera.quaternion,
apiCamera.eyeSeparation,
apiCamera.focalLength,
apiCamera.parentEntity
);
this.position = new GameLib.Vector3(
graphics,
this.position,
this
);
this.quaternion = new GameLib.Quaternion(
graphics,
this.quaternion,
this
);
this.lookAt = new GameLib.Vector3(
graphics,
this.lookAt,
this
);
GameLib.Component.call(
this,
GameLib.Component.CAMERA
);
} ;
GameLib.D3.Camera.prototype = Object.create(GameLib.Component.prototype);
GameLib.D3.Camera.prototype.constructor = GameLib.D3.Camera;
GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE = 0x1;
GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL = 0x2;
GameLib.D3.Camera.CAMERA_TYPE_STEREO = 0x3;
/**
* Creates a camera instance of 'graphics' type (only THREE for now)
* @returns {THREE.Camera}
*/
GameLib.D3.Camera.prototype.createInstance = function() {
if (this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE ) {
this.instance = new THREE.PerspectiveCamera(
this.fov,
this.aspect,
this.near,
this.far
);
} else if (this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL) {
this.instance = new THREE.OrthographicCamera(
this.minX + this.offsetX,
this.maxX + this.offsetX,
this.maxY,
this.minY,
this.minZ,
this.maxZ
);
} else if (this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_STEREO) {
this.instance = new THREE.StereoCamera();
} else {
throw new Error('unsupported camera type : ' + this.cameraType);
}
this.instance.position.x = this.position.x;
this.instance.position.y = this.position.y;
this.instance.position.z = this.position.z;
this.instance.quaternion.x = this.quaternion.x;
this.instance.quaternion.y = this.quaternion.y;
this.instance.quaternion.z = this.quaternion.z;
this.instance.quaternion.w = this.quaternion.w;
this.instance.lookAt(this.lookAt.instance);
this.instance.updateProjectionMatrix();
GameLib.Component.prototype.createInstance.call(this);
};
/**
* Updates the instance with the current state
*/
GameLib.D3.Camera.prototype.updateInstance = function(property) {
if (GameLib.Utils.UndefinedOrNull(property)) {
console.warn('no camera property specified for : ' + this.name);
}
if (property === 'cameraType') {
if (
this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL &&
!(this.instance instanceof THREE.OrthographicCamera)
) {
this.createInstance();
}
if (
this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE &&
!(this.instance instanceof THREE.PerspectiveCamera)
) {
this.createInstance();
}
}
if (
property === 'aspect' ||
property === 'minX' ||
property === 'maxX' ||
property === 'minY' ||
property === 'maxY' ||
property === 'minZ' ||
property === 'maxZ' ||
property === 'offsetX' ||
property === 'offsetY' ||
property === 'fov' ||
property === 'near' ||
property === 'far' ||
property === 'eyeSeparation' ||
property === 'focalLength'
) {
if (this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL) {
this.minX = this.aspect * this.minY;
this.maxX = this.aspect * this.maxY;
this.instance.left = this.minX + this.offsetX;
this.instance.right = this.maxX + this.offsetX;
this.instance.bottom = this.minY + this.offsetY;
this.instance.top = this.maxY + this.offsetY;
this.instance.near = this.minZ;
this.instance.far = this.maxZ;
}
if (
this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE ||
this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_STEREO
) {
this.instance.fov = this.fov;
this.instance.aspect = this.aspect;
this.instance.near = this.near;
this.instance.far = this.far;
}
if (this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_STEREO) {
this.instance.eyeSeparation = this.eyeSeparation;
this.instance.focalLength = this.focalLength;
this.instance.update(this.instance);
}
}
if (property === 'position') {
this.instance.position.x = this.position.x;
this.instance.position.y = this.position.y;
this.instance.position.z = this.position.z;
}
if (property === 'quaternion') {
this.instance.quaternion.x = this.quaternion.x;
this.instance.quaternion.y = this.quaternion.y;
this.instance.quaternion.z = this.quaternion.z;
this.instance.quaternion.w = this.quaternion.w;
}
if (property === 'lookAt') {
this.lookAt.instance.x = this.lookAt.x;
this.lookAt.instance.y = this.lookAt.y;
this.lookAt.instance.z = this.lookAt.z;
this.instance.lookAt(this.lookAt.instance);
}
this.instance.updateProjectionMatrix();
};
/**
* Resize default
* @param width
* @param height
*/
GameLib.D3.Camera.prototype.resize = function(width, height) {
camera.aspect = width / height;
camera.updateInstance();
};
/**
* Converts a GameLib.D3.Camera to a new GameLib.D3.API.Camera
* @returns {GameLib.D3.API.Camera}
*/
GameLib.D3.Camera.prototype.toApiObject = function() {
return new GameLib.D3.API.Camera(
this.id,
this.cameraType,
this.name,
this.fov,
this.aspect,
this.near,
this.far,
this.position.toApiObject(),
this.lookAt.toApiObject(),
this.minX,
this.maxX,
this.minY,
this.maxY,
this.minZ,
this.maxZ,
this.offsetX,
this.offsetY,
this.quaternion.toApiObject(),
this.eyeSeparation,
this.focalLength,
GameLib.Utils.IdOrNull(this.parentEntity)
);
};
/**
* Converts from an Object Camera to a GameLib.D3.Camera
* @param graphics GameLib.GraphicsRuntime
* @param objectCamera Object
* @returns {GameLib.D3.Camera}
* @constructor
*/
GameLib.D3.Camera.FromObject = function(graphics, objectCamera) {
var apiCamera = GameLib.D3.API.Camera.FromObject(objectCamera);
return new GameLib.D3.Camera(
graphics,
apiCamera
);
};