Skip to content

Commit

Permalink
improve renderer types
Browse files Browse the repository at this point in the history
  • Loading branch information
trusktr committed Jul 16, 2019
1 parent a3c5eeb commit c0057fc
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 24 deletions.
20 changes: 14 additions & 6 deletions src/core/CSS3DRendererThree.ts
@@ -1,7 +1,12 @@
import {CSS3DRendererNested} from '../lib/three/CSS3DRendererNested'
import {Scene} from './Scene'

const sceneStates = new WeakMap()
interface SceneState {
renderer: CSS3DRendererNested
sizeChangeHandler: () => void
}

const sceneStates = new WeakMap<Scene, SceneState>()

let instance: CSS3DRendererThree | null = null
let isCreatingSingleton = false
Expand Down Expand Up @@ -36,14 +41,14 @@ export class CSS3DRendererThree {
scene,
(sceneState = {
renderer: new CSS3DRendererNested(),
sizeChangeHandler: () => this.updateResolution(scene),
})
)

const {renderer} = sceneState

this.updateResolution(scene)

sceneState.sizeChangeHandler = () => this.updateResolution(scene)
scene.on('sizechange', sceneState.sizeChangeHandler)

// @ts-ignore: access protected property
Expand All @@ -64,21 +69,24 @@ export class CSS3DRendererThree {
//
.removeChild(sceneState.renderer.domElement)

sceneState.renderer = null
sceneState.sizeChangeHandler = null

sceneStates.delete(scene)
}

drawScene(scene: Scene) {
const {renderer} = sceneStates.get(scene)
const sceneState = sceneStates.get(scene)

if (!sceneState) throw new ReferenceError('Can not draw scene. Scene state should be initialized first.')

const {renderer} = sceneState

renderer.render(scene.threeCSS, scene.threeCamera)
}

updateResolution(scene: Scene) {
const state = sceneStates.get(scene)

if (!state) throw new ReferenceError('Unable to update resolution. Scene state should be initialized first.')

// @ts-ignore: call protected method
scene._updateCameraAspect()
// @ts-ignore: call protected method
Expand Down
4 changes: 2 additions & 2 deletions src/core/Scene.ts
Expand Up @@ -52,6 +52,8 @@ function SceneMixin<T extends Constructor>(Base: T) {
disableCss!: boolean

three!: ThreeScene
threeCSS!: ThreeScene
threeCamera!: ThreePerspectiveCamera

isScene = true

Expand Down Expand Up @@ -229,8 +231,6 @@ function SceneMixin<T extends Constructor>(Base: T) {
return new ThreeScene()
}

threeCamera: ThreePerspectiveCamera | null = null

protected _cameraSetup() {
// this.threeCamera holds the active camera. There can be many
// cameras in the scene tree, but the last one with active="true"
Expand Down
58 changes: 43 additions & 15 deletions src/core/WebGLRendererThree.ts
Expand Up @@ -8,7 +8,12 @@ import {
} from 'three'
import {Scene} from './Scene'

const sceneStates = new WeakMap()
interface SceneState {
renderer: WebGLRenderer
sizeChangeHandler: () => void
}

const sceneStates = new WeakMap<Scene, SceneState>()

let instance: WebGLRendererThree | null = null
let isCreatingSingleton = false
Expand Down Expand Up @@ -57,7 +62,7 @@ export class WebGLRendererThree {
antialias: true,
}),

sizeChangeHandler: null,
sizeChangeHandler: () => this.updateResolution(scene),
})
)

Expand All @@ -70,7 +75,6 @@ export class WebGLRendererThree {

this.updateResolution(scene)

sceneState.sizeChangeHandler = () => this.updateResolution(scene)
scene.on('sizechange', sceneState.sizeChangeHandler)

// TODO? Maybe the html/scene.js element should be responsible for
Expand All @@ -85,20 +89,25 @@ export class WebGLRendererThree {
const sceneState = sceneStates.get(scene)

if (!sceneState) return

scene.off('sizechange', sceneState.sizeChangeHandler)

// @ts-ignore: access protected member
scene._glLayer
//
.removeChild(sceneState.renderer.domElement)

sceneState.renderer.dispose()
sceneState.renderer = null
sceneState.sizeChangeHandler = null

sceneStates.delete(scene)
}

drawScene(scene: Scene) {
const {renderer} = sceneStates.get(scene)
const sceneState = sceneStates.get(scene)

if (!sceneState) throw new ReferenceError('Can not draw scene. Scene state should be initialized first.')

const {renderer} = sceneState

renderer.render(scene.three, scene.threeCamera)
}
Expand All @@ -110,6 +119,9 @@ export class WebGLRendererThree {
// the loop. #66
updateResolution(scene: Scene) {
const state = sceneStates.get(scene)

if (!state) throw new ReferenceError('Unable to update resolution. Scene state should be initialized first.')

// @ts-ignore: access protected member
scene._updateCameraAspect()
// @ts-ignore: access protected member
Expand All @@ -123,31 +135,41 @@ export class WebGLRendererThree {
}

setClearColor(scene: Scene, color: any, opacity: number) {
sceneStates.get(scene).renderer.setClearColor(color, opacity)
const state = sceneStates.get(scene)
if (!state) throw new ReferenceError('Unable to set clear color. Scene state should be initialized first.')
state.renderer.setClearColor(color, opacity)
}

setClearAlpha(scene: Scene, opacity: number) {
sceneStates.get(scene).renderer.setClearAlpha(opacity)
const state = sceneStates.get(scene)
if (!state) throw new ReferenceError('Unable to set clear alpha. Scene state should be initialized first.')
state.renderer.setClearAlpha(opacity)
}

setShadowMapType(scene: Scene, type: ShadowMapTypeString) {
const state = sceneStates.get(scene)
if (!state) throw new ReferenceError('Unable to set clear alpha. Scene state should be initialized first.')

// TODO shouldn't need a cast here. Bug on TypeScript: https://github.com/microsoft/TypeScript/issues/32054
type = type.toLowerCase() as ShadowMapTypeString

if (type == 'pcf') {
sceneStates.get(scene).renderer.shadowMap.type = PCFShadowMap
state.renderer.shadowMap.type = PCFShadowMap
} else if (type == 'pcfsoft') {
sceneStates.get(scene).renderer.shadowMap.type = PCFSoftShadowMap
state.renderer.shadowMap.type = PCFSoftShadowMap
} else if (type == 'basic') {
sceneStates.get(scene).renderer.shadowMap.type = BasicShadowMap
state.renderer.shadowMap.type = BasicShadowMap
} else {
// default
sceneStates.get(scene).renderer.shadowMap.type = PCFShadowMap
state.renderer.shadowMap.type = PCFShadowMap
}
}

requestFrame(scene: Scene, fn: FrameRequestCallback) {
const renderer = sceneStates.get(scene).renderer
const state = sceneStates.get(scene)
if (!state) throw new ReferenceError('Unable to request frame. Scene state should be initialized first.')

const {renderer} = state

if (renderer.animate)
// < r94
Expand All @@ -160,13 +182,19 @@ export class WebGLRendererThree {
// TODO: at the moment this has only been tested toggling it on
// once. Should we be able to turn it off too (f.e. the vr attribute is removed)?
enableVR(scene: Scene, enable: boolean) {
const renderer = sceneStates.get(scene).renderer
const state = sceneStates.get(scene)
if (!state) throw new ReferenceError('Unable to enable VR. Scene state should be initialized first.')

const {renderer} = state
renderer.vr.enabled = enable
}

// TODO the UI here should be configurable via HTML
createDefaultWebVREntryUI(scene: Scene) {
const renderer = sceneStates.get(scene).renderer
const state = sceneStates.get(scene)
if (!state) throw new ReferenceError('Unable to create VR button. Scene state should be initialized first.')

const {renderer} = state

window.addEventListener('vrdisplaypointerrestricted', onPointerRestricted, false)
window.addEventListener('vrdisplaypointerunrestricted', onPointerUnrestricted, false)
Expand Down
2 changes: 1 addition & 1 deletion src/lib/three/CSS3DRendererNested.ts
Expand Up @@ -28,7 +28,7 @@ export class CSS3DNestedSprite extends CSS3DObjectNested {}
//

export class CSS3DRendererNested {
private domElement: HTMLDivElement
domElement: HTMLDivElement
private matrix = new THREE.Matrix4()

private cache = {
Expand Down

0 comments on commit c0057fc

Please sign in to comment.