infamous
Version:
A CSS3D/WebGL UI library.
157 lines (123 loc) • 5.35 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getWebGLRendererThree = getWebGLRendererThree;
exports.destroyWebGLRendererThree = destroyWebGLRendererThree;
var _WebVR = _interopRequireDefault(require("./WebVR.js"));
var _three = require("three");
var _lowclass = _interopRequireDefault(require("lowclass"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const sceneStates = new WeakMap(); // A singleton responsible for setting up and drawing a WebGL scene for a given
// infamous/core/Scene using Three.js
const WebGLRendererThree = (0, _lowclass.default)('WebGLRendererThree', {
initGl(scene) {
let sceneState = sceneStates.has(scene);
if (sceneState) sceneState = sceneStates.get(scene);else sceneStates.set(scene, sceneState = {
// TODO: get the active camera from the scene
//camera: new PerspectiveCamera( 75, 16/9, 0.1, 1000 ),
// TODO: options controlled by HTML attributes on scene elements.
renderer: new _three.WebGLRenderer({
// TODO: how do we change alpha:true to alpha:false after the
// fact?
alpha: true,
antialias: true
})
});
const {
renderer
} = sceneState; // TODO: make configurable by property/attribute
renderer.setPixelRatio(window.devicePixelRatio);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = _three.PCFSoftShadowMap; // default PCFShadowMap
this.updateResolution(scene);
scene.on('sizechange', () => this.updateResolution(scene)); // TODO? Maybe the html/scene.js element should be responsible for
// making this, so that DOM logic is encapsulated there?
scene._canvasContainer.appendChild(renderer.domElement);
},
drawScene(scene) {
const {
renderer
/* , scene: threeScene, camera */
} = sceneStates.get(scene);
renderer.render(scene.threeObject3d, scene.threeCamera);
},
// TODO FIXME This is tied to the `sizechange` event of Scene, which means
// camera and renderer resize happens outside of the animation loop, but as
// with _calcSize, we want to see if we can put this in the nimation loop
// as well. Putting this logic in the loop depends on putting _calcSize in
// the loop. #66
updateResolution(scene) {
const state = sceneStates.get(scene);
scene._updateCameraAspect();
scene._updateCameraPerspective();
scene._updateCameraProjection();
state.renderer.setSize(scene._calculatedSize.x, scene._calculatedSize.y); // Indirectly causes Motor to call this.drawScene(). It's important to
// call this rather than just this.drawScene() directly because Motor
// will make sure it runs in an animation frame.
scene._needsToBeRendered();
},
setClearColor(scene, color, opacity) {
sceneStates.get(scene).renderer.setClearColor(color, opacity);
},
setClearAlpha(scene, opacity) {
sceneStates.get(scene).renderer.setClearAlpha(opacity);
},
setShadowMapType(scene, type) {
type = type.toLowerCase();
if (type == 'pcf') {
sceneStates.get(scene).renderer.shadowMap.type = _three.PCFShadowMap;
} else if (type == 'pcfsoft') {
sceneStates.get(scene).renderer.shadowMap.type = _three.PCFSoftShadowMap;
} else if (type == 'basic') {
sceneStates.get(scene).renderer.shadowMap.type = _three.BasicShadowMap;
} else {
// default
sceneStates.get(scene).renderer.shadowMap.type = _three.PCFShadowMap;
}
},
requestFrame(scene, fn) {
const renderer = sceneStates.get(scene).renderer;
if (renderer.animate) // < r94
renderer.animate(fn);else if (renderer.setAnimationLoop) // >= r94
renderer.setAnimationLoop(fn);
},
// This needs work: at the moment it has only been tested toggling it on
// once and nothing more.
enableVR(scene, enable) {
const renderer = sceneStates.get(scene).renderer;
renderer.vr.enabled = enable;
},
createDefaultWebVREntryUI(scene) {
const renderer = sceneStates.get(scene).renderer;
window.addEventListener('vrdisplaypointerrestricted', onPointerRestricted, false);
window.addEventListener('vrdisplaypointerunrestricted', onPointerUnrestricted, false);
function onPointerRestricted() {
var pointerLockElement = renderer.domElement;
if (pointerLockElement && typeof pointerLockElement.requestPointerLock === 'function') {
pointerLockElement.requestPointerLock();
}
}
function onPointerUnrestricted() {
var currentPointerLockElement = document.pointerLockElement;
var expectedPointerLockElement = renderer.domElement;
if (currentPointerLockElement && currentPointerLockElement === expectedPointerLockElement && typeof document.exitPointerLock === 'function') {
document.exitPointerLock();
}
}
const button = _WebVR.default.createButton(renderer);
button.setAttribute('id', 'vrButton');
button.style.color = 'black';
button.style['border-color'] = 'black';
button.setAttribute('slot', 'misc');
scene.appendChild(button);
return button;
}
});
let instance = null;
function getWebGLRendererThree(scene) {
if (instance) return instance;else return instance = new WebGLRendererThree();
}
function destroyWebGLRendererThree() {
instance = null;
}
;