All files / app/codeCharta/ui/codeMap/threeViewer threeRenderer.service.ts

96.15% Statements 75/78
75.86% Branches 22/29
88.88% Functions 8/9
96.1% Lines 74/77

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 13951x 51x 51x 51x 51x 51x 51x 51x 51x 51x     51x 51x         51x   51x   51x           51x 51x                   226x 226x       2x 2x 2x 2x     226x             226x 10x 10x 10x 5x   10x 5x 5x 5x     5x         10x 10x   10x 5x       226x 13x   5x 5x 5x 5x   1x 1x 1x 1x   6x 6x 6x 6x   1x 1x 1x 1x       226x 7x   7x 7x 7x   7x 7x 7x 7x 7x     226x 2x     226x 2x       37x 37x 2x   35x        
import { Injectable } from "@angular/core"
import { Camera, RGBAFormat, Scene, Vector2, WebGLInfo, WebGLRenderer, WebGLRenderTarget } from "three"
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass"
import WEBGL from "three/examples/jsm/capabilities/WebGL"
import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass"
import { CustomComposer } from "../rendering/postprocessor/customComposer"
import { isWhiteBackgroundSelector } from "../../../state/store/appSettings/isWhiteBackground/isWhiteBackground.selector"
import { SharpnessMode, CcState } from "../../../codeCharta.model"
import { fxaaShaderStrings } from "../rendering/shaders/loaders/fxaaShaderStrings"
import { Store, State } from "@ngrx/store"
 
@Injectable({ providedIn: "root" })
export class ThreeRendererService {
    static BACKGROUND_COLOR = {
        white: 0xff_ff_ff,
        normal: 0xf4_f4_eb
    }
 
    static CLEAR_COLOR = ThreeRendererService.BACKGROUND_COLOR.normal
 
    static CLEAR_ALPHA = 1
 
    static RENDER_OPTIONS: WebGLContextAttributes = {
        antialias: true,
        preserveDrawingBuffer: true,
        alpha: true
    }
 
    static enableFXAA = false
    static setPixelRatio = false
 
    static instance: ThreeRendererService
 
    composer: CustomComposer
    renderer: WebGLRenderer
    scene: Scene
    camera: Camera
 
    constructor(
        private store: Store<CcState>,
        private state: State<CcState>
    ) {}
 
    init(containerWidth: number, containerHeight: number, scene: Scene, camera: Camera) {
        this.scene = scene
        this.camera = camera
        this.initGL(containerWidth, containerHeight)
        this.store.select(isWhiteBackgroundSelector).subscribe(this.setBackgroundColorToState)
    }
 
    private setBackgroundColorToState = (isWhiteBackground: boolean) => {
        ThreeRendererService.CLEAR_COLOR = isWhiteBackground
            ? ThreeRendererService.BACKGROUND_COLOR.white
            : ThreeRendererService.BACKGROUND_COLOR.normal
        this.renderer?.setClearColor(ThreeRendererService.CLEAR_COLOR, ThreeRendererService.CLEAR_ALPHA)
    }
 
    private initGL = (containerWidth: number, containerHeight: number) => {
        this.setGLOptions()
        this.renderer = new WebGLRenderer(ThreeRendererService.RENDER_OPTIONS)
        if (ThreeRendererService.setPixelRatio) {
            this.renderer.setPixelRatio(window.devicePixelRatio)
        }
        if (ThreeRendererService.enableFXAA) {
            if (WEBGL.isWebGL2Available) {
                const size = this.renderer.getDrawingBufferSize(new Vector2())
                const renderTarget = new WebGLRenderTarget(size.width, size.height, {
                    format: RGBAFormat
                })
                this.composer = new CustomComposer(this.renderer, renderTarget)
            } else E{
                this.composer = new CustomComposer(this.renderer)
            }
        }
        this.renderer.setSize(containerWidth, containerHeight)
        this.renderer.domElement.id = "codeMapScene"
 
        if (ThreeRendererService.enableFXAA) {
            this.initComposer()
        }
    }
 
    private setGLOptions = () => {
        switch (this.state.getValue().appSettings.sharpnessMode) {
            case SharpnessMode.Standard:
                ThreeRendererService.RENDER_OPTIONS.antialias = true
                ThreeRendererService.enableFXAA = false
                ThreeRendererService.setPixelRatio = false
                break
            case SharpnessMode.PixelRatioNoAA:
                ThreeRendererService.RENDER_OPTIONS.antialias = false
                ThreeRendererService.enableFXAA = false
                ThreeRendererService.setPixelRatio = true
                break
            case SharpnessMode.PixelRatioFXAA:
                ThreeRendererService.RENDER_OPTIONS.antialias = false
                ThreeRendererService.enableFXAA = true
                ThreeRendererService.setPixelRatio = true
                break
            case SharpnessMode.PixelRatioAA:
                ThreeRendererService.RENDER_OPTIONS.antialias = true
                ThreeRendererService.enableFXAA = false
                ThreeRendererService.setPixelRatio = true
                break
        }
    }
 
    private initComposer = () => {
        const pixelRatio = this.renderer.getPixelRatio()
 
        this.composer.setSize(window.innerWidth * pixelRatio, window.innerHeight * pixelRatio)
        const renderPass = new RenderPass(this.scene, this.camera)
        this.composer.addPass(renderPass)
 
        const effectFXAA = new ShaderPass(new fxaaShaderStrings())
        effectFXAA.renderToScreen = false
        effectFXAA.uniforms["resolution"].value.x = 1 / (window.innerWidth * pixelRatio)
        effectFXAA.uniforms["resolution"].value.y = 1 / (window.innerHeight * pixelRatio)
        this.composer.addPass(effectFXAA)
    }
 
    getInfo = (): WebGLInfo["render"] => {
        return ThreeRendererService.enableFXAA ? this.composer.getInfo() : this.renderer.info.render
    }
 
    getMemoryInfo = (): WebGLInfo["memory"] => {
        return ThreeRendererService.enableFXAA ? this.composer.getMemoryInfo() : this.renderer.info.memory
    }
 
    render() {
        const { scene, camera, composer, renderer } = this
        if (ThreeRendererService.enableFXAA) {
            composer?.render()
        } else {
            renderer?.render(scene, camera)
        }
    }
}