UNPKG

@croquet/microverse-library

Version:

An npm package version of Microverse

152 lines (127 loc) 5.12 kB
// the following import statement is solely for the type checking and // autocompletion features in IDE. A Behavior cannot inherit from // another behavior or a base class but can use the methods and // properties of the card to which it is installed. // The prototype classes ActorBehavior and PawnBehavior provide // the features defined at the card object. import {PawnBehavior} from "../PrototypeBehavior"; class LightPawn extends PawnBehavior { setup() { let trm = this.service("ThreeRenderManager"); let group = this.shape; let THREE = Microverse.THREE; // window.myRenderer = trm; if (this.actor._cardData.toneMappingExposure !== undefined) { trm.renderer.toneMappingExposure = this.actor._cardData.toneMappingExposure; } this.removeLights(); this.lights = []; const ambient = new THREE.AmbientLight( 0xffffff, .5 ); group.add(ambient); this.lights.push(ambient); const sun = new THREE.DirectionalLight( 0xffffff, 0.3 ); sun.position.set(9, 150, -10); sun.castShadow = true; sun.shadow.blurSamples = 5; sun.shadow.camera.left = 40; sun.shadow.camera.right = -30; sun.shadow.camera.top = 30; sun.shadow.camera.bottom = -30; sun.shadow.mapSize.width = 2048; // default sun.shadow.mapSize.height = 2048; // default sun.shadow.normalBias = 1e-2; sun.shadow.bias = - 1e-3; sun.shadow.radius = 4; group.add(sun); this.lights.push(sun); const blueLight = new THREE.DirectionalLight(0x444488, 0.5); blueLight.position.set(1, 100, 150); group.add(blueLight); this.lights.push(blueLight); const redLight = new THREE.DirectionalLight(0x774444, 0.5); redLight.position.set(1, 100, -150); group.add(redLight); this.lights.push(redLight); this.constructBackground(this.actor._cardData); let moduleName = this._behavior.module.externalName; this.addUpdateRequest([`${moduleName}$LightPawn`, "update"]); this.listen("updateShape", "updateShape"); } removeLights() { if (this.lights) { [...this.lights].forEach((light) => { if (light.dispose) { light.dispose(); } this.shape.remove(light); }); } delete this.lights; if (this.csm) { for ( let i = 0; i < this.csm.lights.length; i ++ ) { this.csm.parent.remove( this.csm.lights[ i ].target ); } this.csm.remove(); this.csm.dispose(); delete this.csm; } } teardown() { console.log("teardown lights"); this.removeLights(); let scene = this.service("ThreeRenderManager").scene; scene.background?.dispose(); scene.environment?.dispose(); scene.background = null; scene.environment = null; } updateShape(options) { this.constructBackground(options); } constructBackground(options) { let assetManager = this.service("AssetManager").assetManager; let dataType = options.dataType; if (!options.dataLocation) {return;} return this.getBuffer(options.dataLocation).then((buffer) => { return assetManager.load(buffer, dataType, Microverse.THREE, options).then((texture) => { let TRM = this.service("ThreeRenderManager"); let renderer = TRM.renderer; let scene = TRM.scene; let pmremGenerator = new Microverse.THREE.PMREMGenerator(renderer); pmremGenerator.compileEquirectangularShader(); // we treat the color space of the loaded exr texture. // texture.colorSpace = THREE.SRGBColorSpace; let exrCubeRenderTarget = pmremGenerator.fromEquirectangular(texture); let exrBackground = exrCubeRenderTarget.texture; // we don't set the color space for exrBackground as PMREM generator // spits out purposefully // srgb-linear color space and we don't necessarily override it. // exrBackground.colorSpace = THREE.SRGBColorSpace; let bg = scene.background; let e = scene.environment; scene.background = exrBackground; scene.environment = exrBackground; if(e !== bg) if(bg) bg.dispose(); if(e) e.dispose(); texture.dispose(); }).then(() => { if (this.actor._cardData.loadSynchronously) { this.publish( this.sessionId, "synchronousCardLoaded", {id: this.actor.id}); } }); }); } update(_time) { if(this.csm) this.csm.update(); } } export default { modules: [ { name: "Light", pawnBehaviors: [LightPawn] } ] } /* globals Microverse */