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

409 lines
10 KiB
JavaScript

/**
* Renders a scene with a camera
* @param graphics GameLib.D3.Graphics
* @param apiRenderer GameLib.D3.API.Renderer
* @constructor
*/
GameLib.D3.Renderer = function (
graphics,
apiRenderer
) {
this.graphics = graphics;
this.graphics.isNotThreeThrow();
if (GameLib.Utils.UndefinedOrNull(apiRenderer)) {
apiRenderer = {};
}
if (apiRenderer instanceof GameLib.D3.Renderer) {
return apiRenderer;
}
GameLib.D3.API.Renderer.call(
this,
apiRenderer.id,
apiRenderer.name,
apiRenderer.autoClear,
apiRenderer.localClipping,
apiRenderer.width,
apiRenderer.height,
apiRenderer.preserveDrawingBuffer,
apiRenderer.domElement,
apiRenderer.clearColor,
apiRenderer.camera,
apiRenderer.scenes,
apiRenderer.viewports,
apiRenderer.clippingPlanes,
apiRenderer.bufferScene,
apiRenderer.bufferCamera,
apiRenderer.renderTarget,
apiRenderer.defaultScene,
apiRenderer.sortObjects,
apiRenderer.parentEntity
);
this.clearColor = new GameLib.Color(
this.graphics,
this.clearColor,
this
);
if (this.domElement instanceof GameLib.API.DomElement) {
this.domElement = new GameLib.DomElement(
this.domElement
);
}
if (this.camera instanceof GameLib.D3.API.Camera) {
this.camera = new GameLib.D3.Camera(
this.graphics,
this.camera
)
}
this.scenes = this.scenes.map(function(scene){
if (scene instanceof GameLib.D3.API.Scene) {
return new GameLib.D3.Scene(
this.graphics,
scene
);
} else {
return scene;
}
}.bind(this));
this.viewports = this.viewports.map(function(viewport){
if (viewport instanceof GameLib.D3.API.Viewport) {
return new GameLib.D3.Viewport(
this.graphics,
viewport
);
} else {
return viewport;
}
}.bind(this));
this.clippingPlanes = this.clippingPlanes.map(function(clippingPlane){
if (clippingPlane instanceof GameLib.D3.API.Mesh) {
return new GameLib.D3.Mesh.Plane(
this.graphics,
clippingPlane,
clippingPlane.width,
clippingPlane.height,
clippingPlane.widthSegments,
clippingPlane.heightSegments,
clippingPlane.heightMapScale,
clippingPlane.isHeightMap,
clippingPlane.isClippingPlane,
clippingPlane.distanceFromOrigin
);
} else {
return clippingPlane;
}
}.bind(this));
if (this.bufferScene instanceof GameLib.D3.API.Scene) {
this.bufferScene = new GameLib.D3.Scene(
this.graphics,
this.bufferScene
)
}
if (this.bufferCamera instanceof GameLib.D3.API.Camera) {
this.bufferCamera = new GameLib.D3.Camera(
this.graphics,
this.bufferCamera
)
}
if (this.renderTarget instanceof GameLib.D3.API.RenderTarget) {
this.renderTarget = new GameLib.D3.RenderTarget(
this.graphics,
this.renderTarget
)
}
GameLib.Component.call(
this,
GameLib.Component.COMPONENT_RENDERER,
{
'domElement' : GameLib.DomElement,
'camera' : GameLib.D3.Camera,
'scenes' : [GameLib.D3.Scene],
'viewports' : [GameLib.D3.Viewport],
'clippingPlanes': [GameLib.D3.Mesh.Plane],
'bufferScene' : GameLib.D3.Scene,
'bufferCamera' : GameLib.D3.Camera,
'renderTarget' : GameLib.D3.RenderTarget,
'defaultScene' : GameLib.D3.Scene
}
);
};
GameLib.D3.Renderer.prototype = Object.create(GameLib.D3.API.Renderer.prototype);
GameLib.D3.Renderer.prototype.constructor = GameLib.D3.Renderer;
/**
* Create Renderer Instance
* @returns {*}
*/
GameLib.D3.Renderer.prototype.createInstance = function() {
if (GameLib.Utils.UndefinedOrNull(this.domElement)) {
throw new Error('no dom element');
}
if (GameLib.Utils.UndefinedOrNull(this.domElement.instance)) {
throw new Error('no dom element instance');
}
this.instance = new THREE.WebGLRenderer(
{
canvas : this.domElement.instance
}
);
if (this.clippingPlanes.length > 0) {
this.instance.clippingPlanes = this.clippingPlanes.map(
function(clippingPlane) {
if (!clippingPlane.isClippingPlane || !clippingPlane.instance || !clippingPlane.instance.clipping) {
throw new Error('is not a clipping plane or no clipping plane instance');
}
return clippingPlane.instance.clipping;
}
)
}
this.instance.localClippingEnabled = this.localClipping;
this.instance.setSize(
this.width,
this.height
);
this.instance.setClearColor(
new THREE.Color(
this.clearColor.r,
this.clearColor.g,
this.clearColor.b
),
1 - this.clearColor.a
);
this.instance.domElement.width = this.width;
this.instance.domElement.height = this.height;
this.instance.autoClear = this.autoClear;
this.instance.preserveDrawingBuffer = this.preserveDrawingBuffer;
this.instance.sortObjects = this.sortObjects;
GameLib.Component.prototype.createInstance.call(this);
};
/**
*
*/
GameLib.D3.Renderer.prototype.updateInstance = function() {
if (!this.instance) {
try {
this.createInstance();
} catch (error) {
console.error(error.message);
return;
}
}
this.instance.localClippingEnabled = this.localClipping;
this.instance.setSize(
this.width,
this.height
);
this.instance.setClearColor(
new THREE.Color(
this.clearColor.r,
this.clearColor.g,
this.clearColor.b
),
1 - this.clearColor.a
);
this.instance.domElement.width = this.width;
this.instance.domElement.height = this.height;
this.instance.autoClear = this.autoClear;
this.instance.preserveDrawingBuffer = this.preserveDrawingBuffer;
if (this.clippingPlanes.length > 0) {
this.instance.clippingPlanes = this.clippingPlanes.map(
function(clippingPlane) {
if (!clippingPlane.isClippingPlane || !clippingPlane.instance || !clippingPlane.instance.clipping) {
throw new Error('is not a clipping plane or no clipping plane instance');
}
return clippingPlane.instance.clipping;
}
)
} else {
this.instance.clippingPlanes = [];
}
this.instance.sortObjects = this.sortObjects;
};
/**
*
* @returns {GameLib.D3.API.Renderer}
*/
GameLib.D3.Renderer.prototype.toApiObject = function() {
var apiRenderer = new GameLib.D3.API.Renderer(
this.id,
this.name,
this.autoClear,
this.localClipping,
this.width,
this.height,
this.preserveDrawingBuffer,
GameLib.Utils.IdOrNull(this.domElement),
this.clearColor.toApiObject(),
GameLib.Utils.IdOrNull(this.camera),
this.scenes.map(function(scene){
return GameLib.Utils.IdOrNull(scene);
}),
this.viewports.map(function(viewport){
return GameLib.Utils.IdOrNull(viewport);
}),
this.clippingPlanes.map(
function(clippingPlane) {
return GameLib.Utils.IdOrNull(clippingPlane);
}
),
GameLib.Utils.IdOrNull(this.bufferScene),
GameLib.Utils.IdOrNull(this.bufferCamera),
GameLib.Utils.IdOrNull(this.renderTarget),
GameLib.Utils.IdOrNull(this.defaultScene),
this.sortObjects,
GameLib.Utils.IdOrNull(this.parentEntity)
);
return apiRenderer;
};
/**
*
* @param graphics
* @param objectComponent
* @returns {GameLib.D3.Renderer}
* @constructor
*/
GameLib.D3.Renderer.FromObject = function(graphics, objectComponent) {
var apiRenderer = GameLib.D3.API.Renderer.FromObject(objectComponent);
return new GameLib.D3.Renderer(
graphics,
apiRenderer
);
};
/**
* Convenience render function
*/
GameLib.D3.Renderer.prototype.render = function(delta, scenes) {
if (!this.instance) {
return;
}
if (GameLib.Utils.UndefinedOrNull(scenes)) {
scenes = this.scenes;
}
if (this.viewports.length > 1) {
this.instance.autoClear = false;
}
if (scenes.length > 1) {
this.instance.autoClear = false;
}
this.instance.clear();
if (
this.bufferScene &&
this.bufferScene.instance &&
this.bufferCamera &&
this.bufferCamera.instance &&
this.renderTarget &&
this.renderTarget.instance
) {
/**
* We have a buffer that should render to an offscreen render target
*/
this.instance.render(
this.bufferScene.instance,
this.bufferCamera.instance,
this.renderTarget.instance
);
}
this.viewports.map(
function(viewport) {
this.instance.setViewport(
viewport.x * this.width,
viewport.y * this.height,
viewport.width * this.width,
viewport.height * this.height
);
scenes.map(function(scene) {
if (!scene.instance) {
return;
}
if (!this.camera.instance && !(scene.renderCamera || scene.renderCamera.instance)) {
return;
}
/**
* A scene's renderCamera instance overrides the default renderer camera
*/
if (scene.renderCamera && scene.renderCamera.instance) {
this.instance.render(
scene.instance,
scene.renderCamera.instance
)
} else {
this.instance.render(
scene.instance,
this.camera.instance
)
}
}.bind(this));
}.bind(this)
);
};
GameLib.D3.Renderer.prototype.setSize = function(width, height) {
this.width = width;
this.height = height;
this.updateInstance();
};