@hology/core 0.0.32 → 0.0.33
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/csm.d.ts +1 -1
- package/dist/csm.js +1 -1
- package/dist/effects/vfx/index.d.ts +2 -2
- package/dist/effects/vfx/index.js +1 -1
- package/dist/effects/vfx/initializsers.d.ts +14 -7
- package/dist/effects/vfx/initializsers.js +1 -1
- package/dist/effects/vfx/vfx-actor.d.ts +2 -2
- package/dist/effects/vfx/vfx-actor.js +1 -1
- package/dist/effects/vfx/vfx-asset.d.ts +3 -3
- package/dist/effects/vfx/vfx-asset.js +1 -1
- package/dist/effects/vfx/vfx-defs.d.ts +5 -2
- package/dist/effects/vfx/vfx-defs.js +1 -1
- package/dist/effects/vfx/vfx-materializer.d.ts +1 -1
- package/dist/effects/vfx/vfx-materializer.js +1 -1
- package/dist/effects/vfx/vfx-param.d.ts +1 -1
- package/dist/gameplay/actors/actor.d.ts +1 -1
- package/dist/gameplay/actors/actor.js +1 -1
- package/dist/gameplay/actors/builtin/camera-actor.d.ts +3 -3
- package/dist/gameplay/actors/builtin/camera-actor.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-animation.d.ts +3 -3
- package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-movement copy.d.ts +4 -4
- package/dist/gameplay/actors/builtin/components/character/character-movement copy.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-movement.d.ts +4 -4
- package/dist/gameplay/actors/builtin/components/character/character-movement.js +1 -1
- package/dist/gameplay/actors/builtin/components/mesh-component.d.ts +2 -2
- package/dist/gameplay/actors/builtin/components/mesh-component.js +1 -1
- package/dist/gameplay/actors/builtin/components/scene-component.d.ts +1 -1
- package/dist/gameplay/actors/builtin/components/scene-component.js +1 -1
- package/dist/gameplay/actors/builtin/index.d.ts +4 -4
- package/dist/gameplay/actors/builtin/index.js +1 -1
- package/dist/gameplay/actors/builtin/positional-audio-actor.d.ts +6 -5
- package/dist/gameplay/actors/builtin/positional-audio-actor.js +1 -1
- package/dist/gameplay/actors/builtin/spawn-point.d.ts +3 -3
- package/dist/gameplay/actors/builtin/spawn-point.js +1 -1
- package/dist/gameplay/actors/builtin/trigger-volume.d.ts +4 -4
- package/dist/gameplay/actors/builtin/trigger-volume.js +1 -1
- package/dist/gameplay/actors/camera/camera-component.d.ts +2 -2
- package/dist/gameplay/actors/camera/camera-component.js +1 -1
- package/dist/gameplay/actors/camera/third-party-camera-component.d.ts +5 -5
- package/dist/gameplay/actors/camera/third-party-camera-component.js +1 -1
- package/dist/gameplay/actors/component.d.ts +1 -1
- package/dist/gameplay/actors/component.js +1 -1
- package/dist/gameplay/actors/factory.d.ts +3 -3
- package/dist/gameplay/actors/factory.js +1 -1
- package/dist/gameplay/actors/index.d.ts +10 -10
- package/dist/gameplay/actors/index.js +1 -1
- package/dist/gameplay/actors/internal/component-init.d.ts +2 -2
- package/dist/gameplay/actors/internal/component-init.js +1 -1
- package/dist/gameplay/actors/internal/container-map.d.ts +1 -1
- package/dist/gameplay/animation/anim-sm.js +1 -1
- package/dist/gameplay/index.d.ts +14 -13
- package/dist/gameplay/index.js +1 -1
- package/dist/gameplay/initiate.d.ts +2 -2
- package/dist/gameplay/initiate.js +1 -1
- package/dist/gameplay/inject.js +1 -1
- package/dist/gameplay/input/index.d.ts +3 -3
- package/dist/gameplay/input/index.js +1 -1
- package/dist/gameplay/input/input-service.d.ts +1 -1
- package/dist/gameplay/input/input-service.js +1 -1
- package/dist/gameplay/input/input.js +1 -1
- package/dist/gameplay/services/asset-loader.d.ts +5 -5
- package/dist/gameplay/services/asset-loader.js +1 -1
- package/dist/gameplay/services/physics/physics-system.d.ts +5 -5
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/gameplay/services/pointer-events.d.ts +58 -0
- package/dist/gameplay/services/pointer-events.js +5 -0
- package/dist/gameplay/services/render.d.ts +3 -3
- package/dist/gameplay/services/render.js +1 -1
- package/dist/gameplay/services/world.d.ts +2 -2
- package/dist/gameplay/services/world.js +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/rendering.js +1 -1
- package/dist/scene/asset-resource-loader.d.ts +2 -2
- package/dist/scene/asset-resource-loader.js +1 -1
- package/dist/scene/assets-provider.d.ts +1 -1
- package/dist/scene/bootstrap.d.ts +7 -7
- package/dist/scene/bootstrap.js +1 -1
- package/dist/scene/collision/collision-shape-import.d.ts +1 -1
- package/dist/scene/collision/collision-shape-import.js +1 -1
- package/dist/scene/landscape/landscape-manager.d.ts +6 -6
- package/dist/scene/landscape/landscape-manager.js +1 -1
- package/dist/scene/landscape/landscape.js +1 -1
- package/dist/scene/landscape/utils.d.ts +1 -1
- package/dist/scene/landscape/utils.js +1 -1
- package/dist/scene/materializer.d.ts +10 -10
- package/dist/scene/materializer.js +1 -1
- package/dist/scene/materials/grass-foliage.d.ts +2 -2
- package/dist/scene/materials/grass-foliage.js +1 -1
- package/dist/scene/materials/grass.d.ts +1 -1
- package/dist/scene/materials/grass.js +1 -1
- package/dist/scene/materials/water.d.ts +1 -1
- package/dist/scene/materials/water.js +1 -1
- package/dist/scene/model.d.ts +5 -5
- package/dist/scene/objects/shapes.d.ts +3 -3
- package/dist/scene/objects/shapes.js +1 -1
- package/dist/scene/runtime-asset-service.d.ts +3 -3
- package/dist/scene/runtime-asset-service.js +1 -1
- package/dist/scene/runtime-backend-service.d.ts +1 -1
- package/dist/scene/runtime-backend-service.js +1 -1
- package/dist/scene/scene-data-service.d.ts +1 -1
- package/dist/scene/scene-data-service.js +1 -1
- package/dist/scene/storage/storage.js +1 -1
- package/dist/shader/builtin/index.d.ts +2 -2
- package/dist/shader/builtin/index.js +1 -1
- package/dist/shader/builtin/lambert-shader.d.ts +1 -1
- package/dist/shader/builtin/lambert-shader.js +1 -1
- package/dist/shader/builtin/standard-shader.d.ts +1 -1
- package/dist/shader/builtin/standard-shader.js +1 -1
- package/dist/shader/index.d.ts +3 -3
- package/dist/shader/index.js +1 -1
- package/dist/shader/parameter.d.ts +4 -4
- package/dist/shader/parameter.js +1 -1
- package/dist/shader/shader.d.ts +4 -4
- package/dist/shader/shader.js +1 -1
- package/dist/shader-nodes/effects.js +1 -1
- package/dist/shader-nodes/index.d.ts +9 -9
- package/dist/shader-nodes/index.js +1 -1
- package/dist/shader-nodes/layers.js +1 -1
- package/dist/test/injection.test.js +1 -1
- package/dist/utils/collections.js +1 -1
- package/dist/utils/three/depth-pass.js +1 -1
- package/dist/utils/three/outline-pass.d.ts +2 -2
- package/dist/utils/three/transform-controls.d.ts +2 -2
- package/package.json +6 -7
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/cannon/CannonUtils.d.ts +0 -17
- package/dist/utils/cannon/CannonUtils.js +0 -5
- package/dist/utils/cannon/three-to-cannon/ConvexHull.d.ts +0 -47
- package/dist/utils/cannon/three-to-cannon/ConvexHull.js +0 -5
- package/dist/utils/cannon/three-to-cannon/index.d.ts +0 -63
- package/dist/utils/cannon/three-to-cannon/index.js +0 -5
- package/dist/utils/cannon/three-to-cannon/utils.d.ts +0 -9
- package/dist/utils/cannon/three-to-cannon/utils.js +0 -5
@@ -1,9 +1,9 @@
|
|
1
1
|
import { Camera } from "three";
|
2
|
-
import { RenderingView } from
|
2
|
+
import { RenderingView } from '../../rendering.js';
|
3
3
|
import { Observable } from "rxjs";
|
4
4
|
import * as THREE from "three";
|
5
|
-
import { CameraActor } from
|
6
|
-
import { BaseActor } from
|
5
|
+
import { CameraActor } from '../../gameplay/actors/builtin/camera-actor.js';
|
6
|
+
import { BaseActor } from '../../gameplay/actors/actor.js';
|
7
7
|
export declare class ViewController {
|
8
8
|
private view;
|
9
9
|
private readonly tick;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{__decorate as t,__metadata as e}from"tslib";import{Service as i}from"typedi";import{RenderingView as s}from"../../rendering";import{Subject as
|
1
|
+
import{__decorate as t,__metadata as e}from"tslib";import{Service as i}from"typedi";import{RenderingView as s}from"../../rendering.js";import{Subject as r,takeUntil as a}from"rxjs";import*as o from"three";import{CameraActor as n}from"../../gameplay/actors/builtin/camera-actor.js";let p=class{constructor(t){this.view=t,this.tick=new r,this.lateTick=new r,this.audioListener=new o.AudioListener,t.onLoop((t=>{this.tick.next(t),this.lateTick.next(t)})),t.camera.add(this.audioListener),window.hology_view=this}set fpsCap(t){this.view.fpsCap=t}get fpsCap(){return this.view.fpsCap}set showStats(t){this.view.showStats=t}get showStats(){return this.view.showStats}onUpdate(t){return null!=t&&this.tick.pipe(a(t.disposed)),this.tick}onLateUpdate(t){return null!=t&&this.lateTick.pipe(a(t.disposed)),this.lateTick}setCamera(t){const e=t instanceof n?t.camera.instance:t;this.view.setCamera(e),e.add(this.audioListener)}getCamera(){return this.view.camera}get htmlElement(){return this.view.container}pauseRendering(){this.view.paused=!0}unpauseRendering(){this.view.paused=!1}dispose(){this.view.stop(),this.audioListener.removeFromParent()}};p=t([i(),e("design:paramtypes",[s])],p);export{p as ViewController};
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Constructable } from "typedi";
|
2
|
-
import { BaseActor } from
|
3
|
-
import { ActorFactory } from
|
2
|
+
import { BaseActor } from '../actors/actor.js';
|
3
|
+
import { ActorFactory } from '../actors/factory.js';
|
4
4
|
import { Euler, Scene, Vector3 } from 'three';
|
5
5
|
import { Observable } from 'rxjs';
|
6
6
|
export declare class World {
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{
|
1
|
+
import{__decorate as t,__metadata as o}from"tslib";import{Service as e}from"typedi";import{ActorFactory as r}from"../actors/factory.js";import{ActorComponent as c}from"../../gameplay/actors/component.js";import{Subject as s}from"rxjs";let i=class{constructor(t){this.actorFactory=t,this.actors=[],this.actorAdded=new s,this.actorRemoved=new s}async spawnActor(t,o,e){const r=await this.actorFactory.create(t,o,e);return this.addActor(r,o,e),r}addActor(t,o,e){o&&t.object.position.copy(o),e&&t.object.rotation.copy(e),this.scene.add(t.object),this.actors.push(t),n(t,(t=>t.onBeginPlay())),this.actorAdded.next(t)}removeActor(t){n(t,(t=>t.onEndPlay())),this.actors.splice(this.actors.indexOf(t),1),this.scene.remove(t.object),t.disposed.next(!0),this.actorRemoved.next(t)}findActorByType(t,o){return this.actors.find((e=>e instanceof t&&(null==o||e.object.name==o)))}findActorsByType(t,o){return this.actors.filter((e=>e instanceof t&&(null==o||e.object.name==o)))}};i=t([e(),o("design:paramtypes",[r])],i);export{i as World};function n(t,o){return o(t),Object.entries(t).filter((([t,o])=>o instanceof c)).forEach((([t,e])=>{n(e,o)}))}
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
package/dist/index.d.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
export { loadScene } from './scene/bootstrap';
|
2
|
-
export { BaseGameController } from './controllers/base-game-controller';
|
3
|
-
export * from './scene/collision/collision-shape';
|
4
|
-
export { AssetMeshInstance } from './scene/asset-resource-loader';
|
1
|
+
export { loadScene } from './scene/bootstrap.js';
|
2
|
+
export { BaseGameController } from './controllers/base-game-controller.js';
|
3
|
+
export * from './scene/collision/collision-shape.js';
|
4
|
+
export { AssetMeshInstance } from './scene/asset-resource-loader.js';
|
package/dist/index.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
export{loadScene}from"./scene/bootstrap";export{BaseGameController}from"./controllers/base-game-controller";export*from"./scene/collision/collision-shape";export{AssetMeshInstance}from"./scene/asset-resource-loader";
|
1
|
+
export{loadScene}from"./scene/bootstrap.js";export{BaseGameController}from"./controllers/base-game-controller.js";export*from"./scene/collision/collision-shape.js";export{AssetMeshInstance}from"./scene/asset-resource-loader.js";
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
package/dist/rendering.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import*as e from"three";import{Mesh as t,Matrix4 as i,ShaderMaterial as s,Color as r,PerspectiveCamera as n,ShaderChunk as a}from"three";import{EffectComposer as o,UnrealBloomPass as h,VRButton as l}from"three-stdlib";import{RenderPass as d}from"three-stdlib";import{ShaderPass as c}from"three-stdlib";import{FXAAShader as m}from"three-stdlib";import{CSM as u}from"three-stdlib";import{CSMUtil as p}from"./csm";import{GammaCorrectionShader as v}from"three-stdlib";import{Reflector as g}from"three-stdlib";import{depthUniformName as f,resolutionUniformName as w,supportsDepthTextureExtension as b,nearUniformName as x,farUniformName as C}from"./shader-nodes/depth";import{elapsedTimeUniformName as R}from"./shader-nodes/time";import{OutlinePass as S}from"./utils/three/outline-pass";import T from"./utils/three/stats";import{findFirstVisibleObject as y}from"./utils/three/traverse";import{lambertVertexShaderOverride as P}from"./rendering/shader-override";import{DepthPass as M}from"./utils/three/depth-pass";(new e.Layers).set(9);const W=new e.MeshBasicMaterial({color:"black"}),L=new e.MeshDepthMaterial;L.depthPacking=e.RGBADepthPacking,L.blending=e.NoBlending;a.lights_pars_begin;a.lights_lambert_vertex=P;export class RenderingView{setPaused(e){this.paused=e}resizeRender(){this.previousClientWith===this.container.clientWidth&&this.previousClientHeight===this.container.clientHeight||(this.camera instanceof n&&(this.camera.aspect=this.container.clientWidth/this.container.clientHeight,this.camera.updateProjectionMatrix()),this.renderer.setPixelRatio(window.devicePixelRatio*this.resolutionScale),this.renderer.setSize(this.container.clientWidth,this.container.clientHeight),this.composer.setSize(this.container.clientWidth*this.resolutionScale,this.container.clientHeight*this.resolutionScale),this.previousClientWith=this.container.clientWidth,this.previousClientHeight=this.container.clientHeight)}constructor(t,i={}){var s;this.container=t,this.options=i,this.windowVisible=!0,this.running=!0,this.paused=!1,this.fpsCap=null,this.resolutionScale=1,this.onResize=()=>{this.resizeRender(),this.paused||this.render()},this.onVisiblityChane=()=>{this.windowVisible=!document.hidden},this.isDepthTextureExtensionSupported=!1,this.onLoopCallbacks=[],this.stats=T(),this._showStats=!1,this.insetHeight=200,this.insetWidth=this.insetHeight*(16/9),this.insetOffsetY=250,this.insetMargin=10,this.maxInsetCameras=4,this.overlayCameras=new Set,this.prevClearColor=new r,this.bloomStoredMaterials={},window.renderer=this.renderer=new e.WebGLRenderer({antialias:!0,powerPreference:"high-performance"}),this.scene=new e.Scene,this.renderer.setPixelRatio(window.devicePixelRatio*this.resolutionScale),this.renderer.setSize(t.clientWidth,t.clientHeight),this.renderer.xr.enabled=null!==(s=this.options.enableXR)&&void 0!==s&&s,!0===this.options.enableXR&&document.body.appendChild(l.createButton(this.renderer)),this.composer=new o(this.renderer);var n=t.clientWidth/t.clientHeight;const a=new e.PerspectiveCamera(45,n,.5,500);a.layers.enable(19),this.setCamera(a),this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=e.PCFSoftShadowMap,this.renderer.shadowMap.autoUpdate=!1,this.renderer.outputEncoding=e.sRGBEncoding,this.renderer.physicallyCorrectLights=!1,this.renderer.gammaFactor=1.4,p.renderingView=this,p.patchThreeAdd(),this.isDepthTextureExtensionSupported=b(this.renderer),t.replaceChildren(this.renderer.domElement),this.setupEventListeners(),this.depthRenderTarget=RenderingView.createDepthRenderTarget(this.renderer,this.container);const u=new d(this.scene,this.camera);this.composer.addPass(u);const g=new h(new e.Vector2(t.clientWidth,t.clientHeight),1.5,.4,.85);g.threshold=0,g.strength=.9,g.radius=1;const f=new o(this.renderer);f.renderToScreen=!1,f.addPass(u),f.addPass(g),this.bloomComposer=f;const w=new c(new e.ShaderMaterial({uniforms:{baseTexture:{value:null},bloomTexture:{value:f.renderTarget2.texture}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }",fragmentShader:"\n uniform sampler2D baseTexture;\n uniform sampler2D bloomTexture;\n varying vec2 vUv;\n void main() {\n gl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) );\n }",defines:{}}),"baseTexture");if(w.needsSwap=!0,this.composer.addPass(w),this.outlinePass=new S(new e.Vector2(t.clientWidth,t.clientHeight),this.scene,this.camera),!0===i.enableOutlines){this.outlinePass.edgeThickness=0,this.outlinePass.edgeGlow=0,this.outlinePass.edgeThickness=1.5,this.outlinePass.edgeStrength=5,this.outlinePass.clear=!1,this.composer.addPass(this.outlinePass);const e=new c(m);e.uniforms.resolution.value.set(1/t.clientWidth,1/t.clientHeight),this.composer.addPass(e)}var x=new c(v);x.clear=!1,this.composer.addPass(x)}setCamera(t){this.camera=t,this.composer.passes.forEach((e=>{e instanceof d?e.camera=t:e instanceof S?e.renderCamera=t:e instanceof M&&(e.camera=t)})),null==this.csm?this.csm=new u({maxFar:200,lightFar:300,cascades:5,shadowMapSize:2048,lightDirection:new e.Vector3(.5,-1,-.6).normalize(),lightIntensity:.5,camera:this.camera,parent:this.scene}):(this.csm.camera=this.camera,this.camera instanceof n&&(this.csm.maxFar=this.camera.far)),this.csm.updateFrustums()}setSelectedObjects(e){const t=new Map;for(const i of e)t.set(i.uuid,i);for(const i of e)i.traverse((e=>{e.uuid!==i.uuid&&t.has(e.uuid)&&t.delete(e.uuid)}));this.outlinePass.selectedObjects=Array.from(t.values())}static createDepthRenderTarget(t,i){var s=!!t.extensions.get("WEBGL_depth_texture");const r=new e.WebGLRenderTarget(i.clientWidth*t.getPixelRatio(),i.clientHeight*t.getPixelRatio());return r.texture.minFilter=e.NearestFilter,r.texture.magFilter=e.NearestFilter,r.texture.generateMipmaps=!1,r.stencilBuffer=!1,!0===s&&(r.depthTexture=new e.DepthTexture(128,128),r.depthTexture.type=e.UnsignedShortType,r.depthTexture.minFilter=e.NearestFilter,r.depthTexture.magFilter=e.NearestFilter),r}setupEventListeners(){window.addEventListener("resize",this.onResize),window.addEventListener("orientationchange",this.onResize),document.addEventListener("visibilitychange",this.onVisiblityChane)}stop(){this.running=!1,window.removeEventListener("resize",this.onResize),window.removeEventListener("orientationchange",this.onResize),document.removeEventListener("visibilitychange",this.onVisiblityChane),this.onLoopCallbacks=[],this.renderer.dispose(),this.depthRenderTarget.dispose(),this.csm.dispose(),this.container.replaceChildren()}onLoop(e){this.onLoopCallbacks.push(e)}removeOnLoop(e){const t=this.onLoopCallbacks.find(e);this.onLoopCallbacks.splice(t,1)}set showStats(e){this._showStats=e,this._showStats&&!this.container.contains(this.stats.dom)?this.container.appendChild(this.stats.dom):!this._showStats&&this.container.contains(this.stats.dom)&&this.container.removeChild(this.stats.dom)}get showStats(){return this._showStats}loop(s,r=!1){const n=this.stats;n.showPanel(0),this.showStats=r;performance.now();e.Ray.prototype.intersectTriangle;let a=0;const o=new i,h=new i,l=e=>{var i,r;const d=this.renderer.getContext();if(this.paused&&this.running&&d.drawingBufferHeight>1)return void setTimeout((()=>l(e)),500);this.renderer.autoClear=!1,this.renderer.clear(),this.renderer.setViewport(0,0,this.container.clientWidth,this.container.clientHeight),this.camera,n.begin();let c=(e*=.001)-a;if(a=e,o.copy(this.camera.matrixWorld),c>1){let e=c;for(;e>.05;)s(D),e-=D;s(e)}else s(c);this.onLoopCallbacks.forEach((e=>e(c))),null===(i=this.camera)||void 0===i||i.updateMatrixWorld(),h.copy(this.camera.matrixWorld),h.equals(o)||(this.renderer.shadowMap.needsUpdate=!0),this.resizeRender();const m=[],u=[];if(this.scene.traverse((i=>{var s,r,n,a,o,h;i instanceof t&&i.visible&&((null===(r=null===(s=i.material)||void 0===s?void 0:s.userData)||void 0===r?void 0:r.water)||(null===(n=i.material)||void 0===n?void 0:n.uniforms)&&null!=(null===(a=i.material)||void 0===a?void 0:a.uniforms[f]))?(i.visible=!1,m.push(i),this.initDepthUniform(i.material),i.renderOrder=100):i instanceof g&&(i.visible=!1,u.push(i)),i instanceof t&&(null===(o=i.material)||void 0===o?void 0:o.uniforms)&&null!=(null===(h=i.material)||void 0===h?void 0:h.uniforms[R])&&(i.material.uniforms[R].value=e)})),m.length>0){if(this.scene.overrideMaterial=L,this.renderer.setRenderTarget(this.depthRenderTarget),!this.paused&&null!=this.camera)try{this.renderer.clear(),this.renderer.render(this.scene,this.camera)}catch(e){console.warn(e)}this.renderer.setRenderTarget(null),this.scene.overrideMaterial=null}m.forEach((e=>e.visible=!0)),u.forEach((e=>e.visible=!0));try{!this.paused&&this.running&&(this.render(c),this.renderOverlay())}catch(e){console.warn(e)}n.end(),null===(r=this.csm)||void 0===r||r.update(),this.running&&!0!==this.options.enableXR&&(this.fpsCap?setTimeout((()=>{requestAnimationFrame(l)}),1e3/this.fpsCap):requestAnimationFrame(l))};!0===this.options.enableXR?this.renderer.setAnimationLoop(l):requestAnimationFrame(l)}renderOverlay(){const e=Array.from(this.overlayCameras.values()).slice(0,this.maxInsetCameras),t=this.container.clientWidth/2,i=e.length*this.insetWidth+(e.length-1)*this.insetMargin;for(let s=0;s<e.length;s++)this.renderer.clearDepth(),this.renderer.setViewport(t-i/2+this.insetWidth*s+this.insetMargin*s,this.insetOffsetY,this.insetWidth,this.insetHeight),this.renderer.render(this.scene,e[s])}addOverlayCamera(e){this.overlayCameras.add(e)}clearOverlayCameras(){this.overlayCameras.clear()}removeOverlayCamera(e){this.overlayCameras.delete(e)}render(e){if(this.hasBloom()){const e=this.scene.fog;this.scene.fog=null;const t=this.renderer.getClearColor(this.prevClearColor);this.renderer.setClearColor(0),this.scene.traverseVisible((e=>this.darkenNonBloomed(e))),this.bloomComposer.render(),this.scene.traverse((e=>this.restoreMaterial(e))),this.renderer.setClearColor(t),this.scene.fog=e}this.composer.render(e)}hasBloom(){return null!=y(this.scene,(e=>{var i,s;return e instanceof t&&!0===(null===(s=null===(i=e.material)||void 0===i?void 0:i.userData)||void 0===s?void 0:s.hasBloom)}))}darkenNonBloomed(e){e.isMesh&&e.visible&&!0!==e.material.userData.hasBloom&&(this.bloomStoredMaterials[e.uuid]=e.material,!0!==e.material.transparent?e.material=W:e.visible=!1)}restoreMaterial(e){this.bloomStoredMaterials[e.uuid]&&(e.material=this.bloomStoredMaterials[e.uuid],delete this.bloomStoredMaterials[e.uuid],e.visible=!0)}initDepthUniform(e){e instanceof s&&(e.uniforms[f].value=this.isDepthTextureExtensionSupported?this.depthRenderTarget.depthTexture:this.depthRenderTarget.texture,null!=e.uniforms[w]&&e.uniforms[w].value.set(this.container.clientWidth*this.renderer.getPixelRatio(),this.container.clientHeight*this.renderer.getPixelRatio()),this.camera instanceof n&&(e.uniforms[x].value=this.camera.near,e.uniforms[C].value=this.camera.far))}}export function setRenderingPaused(e){var t,i;null!=(null===(i=null===(t=window.editor)||void 0===t?void 0:t.viewer)||void 0===i?void 0:i.renderingView)&&(window.editor.viewer.renderingView.paused=e)}const D=.05;
|
1
|
+
import*as e from"three";import{Mesh as t,Matrix4 as i,ShaderMaterial as s,Color as r,PerspectiveCamera as n,ShaderChunk as a}from"three";import{EffectComposer as o,UnrealBloomPass as h,VRButton as l}from"three-stdlib";import{RenderPass as d}from"three-stdlib";import{ShaderPass as c}from"three-stdlib";import{FXAAShader as m}from"three-stdlib";import{CSM as u}from"three-stdlib";import{CSMUtil as p}from"./csm.js";import{GammaCorrectionShader as g}from"three-stdlib";import{Reflector as v}from"three-stdlib";import{depthUniformName as f,resolutionUniformName as w,supportsDepthTextureExtension as b,nearUniformName as x,farUniformName as C}from"./shader-nodes/depth.js";import{elapsedTimeUniformName as R}from"./shader-nodes/time.js";import{OutlinePass as S}from"./utils/three/outline-pass.js";import T from"./utils/three/stats.js";import{findFirstVisibleObject as y}from"./utils/three/traverse.js";import{lambertVertexShaderOverride as P}from"./rendering/shader-override.js";import{DepthPass as M}from"./utils/three/depth-pass.js";(new e.Layers).set(9);const W=new e.MeshBasicMaterial({color:"black"}),L=new e.MeshDepthMaterial;L.depthPacking=e.RGBADepthPacking,L.blending=e.NoBlending;a.lights_pars_begin;a.lights_lambert_vertex=P;export class RenderingView{setPaused(e){this.paused=e}resizeRender(){this.previousClientWith===this.container.clientWidth&&this.previousClientHeight===this.container.clientHeight||(this.camera instanceof n&&(this.camera.aspect=this.container.clientWidth/this.container.clientHeight,this.camera.updateProjectionMatrix()),this.renderer.setPixelRatio(window.devicePixelRatio*this.resolutionScale),this.renderer.setSize(this.container.clientWidth,this.container.clientHeight),this.composer.setSize(this.container.clientWidth*this.resolutionScale,this.container.clientHeight*this.resolutionScale),this.previousClientWith=this.container.clientWidth,this.previousClientHeight=this.container.clientHeight)}constructor(t,i={}){this.container=t,this.options=i,this.windowVisible=!0,this.running=!0,this.paused=!1,this.fpsCap=null,this.resolutionScale=1,this.onResize=()=>{this.resizeRender(),this.paused||this.render()},this.onVisiblityChane=()=>{this.windowVisible=!document.hidden},this.isDepthTextureExtensionSupported=!1,this.onLoopCallbacks=[],this.stats=T(),this._showStats=!1,this.insetHeight=200,this.insetWidth=this.insetHeight*(16/9),this.insetOffsetY=250,this.insetMargin=10,this.maxInsetCameras=4,this.overlayCameras=new Set,this.prevClearColor=new r,this.bloomStoredMaterials={},window.renderer=this.renderer=new e.WebGLRenderer({antialias:!0,powerPreference:"high-performance"}),this.scene=new e.Scene,this.renderer.setPixelRatio(window.devicePixelRatio*this.resolutionScale),this.renderer.setSize(t.clientWidth,t.clientHeight),this.renderer.xr.enabled=this.options.enableXR??!1,!0===this.options.enableXR&&document.body.appendChild(l.createButton(this.renderer)),this.composer=new o(this.renderer);var s=t.clientWidth/t.clientHeight;const n=new e.PerspectiveCamera(45,s,.5,500);n.layers.enable(19),this.setCamera(n),this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=e.PCFSoftShadowMap,this.renderer.shadowMap.autoUpdate=!1,this.renderer.outputEncoding=e.sRGBEncoding,this.renderer.physicallyCorrectLights=!1,this.renderer.gammaFactor=1.4,p.renderingView=this,p.patchThreeAdd(),this.isDepthTextureExtensionSupported=b(this.renderer),t.replaceChildren(this.renderer.domElement),this.setupEventListeners(),this.depthRenderTarget=RenderingView.createDepthRenderTarget(this.renderer,this.container);const a=new d(this.scene,this.camera);this.composer.addPass(a);const u=new h(new e.Vector2(t.clientWidth,t.clientHeight),1.5,.4,.85);u.threshold=0,u.strength=.9,u.radius=1;const v=new o(this.renderer);v.renderToScreen=!1,v.addPass(a),v.addPass(u),this.bloomComposer=v;const f=new c(new e.ShaderMaterial({uniforms:{baseTexture:{value:null},bloomTexture:{value:v.renderTarget2.texture}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }",fragmentShader:"\n uniform sampler2D baseTexture;\n uniform sampler2D bloomTexture;\n varying vec2 vUv;\n void main() {\n gl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) );\n }",defines:{}}),"baseTexture");if(f.needsSwap=!0,this.composer.addPass(f),this.outlinePass=new S(new e.Vector2(t.clientWidth,t.clientHeight),this.scene,this.camera),!0===i.enableOutlines){this.outlinePass.edgeThickness=0,this.outlinePass.edgeGlow=0,this.outlinePass.edgeThickness=1.5,this.outlinePass.edgeStrength=5,this.outlinePass.clear=!1,this.composer.addPass(this.outlinePass);const e=new c(m);e.uniforms.resolution.value.set(1/t.clientWidth,1/t.clientHeight),this.composer.addPass(e)}var w=new c(g);w.clear=!1,this.composer.addPass(w)}setCamera(t){this.camera=t,this.composer.passes.forEach((e=>{e instanceof d?e.camera=t:e instanceof S?e.renderCamera=t:e instanceof M&&(e.camera=t)})),null==this.csm?this.csm=new u({maxFar:200,lightFar:300,cascades:5,shadowMapSize:2048,lightDirection:new e.Vector3(.5,-1,-.6).normalize(),lightIntensity:.5,camera:this.camera,parent:this.scene}):(this.csm.camera=this.camera,this.camera instanceof n&&(this.csm.maxFar=this.camera.far)),this.csm.updateFrustums()}setSelectedObjects(e){const t=new Map;for(const i of e)t.set(i.uuid,i);for(const i of e)i.traverse((e=>{e.uuid!==i.uuid&&t.has(e.uuid)&&t.delete(e.uuid)}));this.outlinePass.selectedObjects=Array.from(t.values())}static createDepthRenderTarget(t,i){var s=!!t.extensions.get("WEBGL_depth_texture");const r=new e.WebGLRenderTarget(i.clientWidth*t.getPixelRatio(),i.clientHeight*t.getPixelRatio());return r.texture.minFilter=e.NearestFilter,r.texture.magFilter=e.NearestFilter,r.texture.generateMipmaps=!1,r.stencilBuffer=!1,!0===s&&(r.depthTexture=new e.DepthTexture(128,128),r.depthTexture.type=e.UnsignedShortType,r.depthTexture.minFilter=e.NearestFilter,r.depthTexture.magFilter=e.NearestFilter),r}setupEventListeners(){window.addEventListener("resize",this.onResize),window.addEventListener("orientationchange",this.onResize),document.addEventListener("visibilitychange",this.onVisiblityChane)}stop(){this.running=!1,window.removeEventListener("resize",this.onResize),window.removeEventListener("orientationchange",this.onResize),document.removeEventListener("visibilitychange",this.onVisiblityChane),this.onLoopCallbacks=[],this.renderer.dispose(),this.depthRenderTarget.dispose(),this.csm.dispose(),this.container.replaceChildren()}onLoop(e){this.onLoopCallbacks.push(e)}removeOnLoop(e){const t=this.onLoopCallbacks.find(e);this.onLoopCallbacks.splice(t,1)}set showStats(e){this._showStats=e,this._showStats&&!this.container.contains(this.stats.dom)?this.container.appendChild(this.stats.dom):!this._showStats&&this.container.contains(this.stats.dom)&&this.container.removeChild(this.stats.dom)}get showStats(){return this._showStats}loop(s,r=!1){const n=this.stats;n.showPanel(0),this.showStats=r;performance.now();e.Ray.prototype.intersectTriangle;let a=0;const o=new i,h=new i,l=e=>{const i=this.renderer.getContext();if(this.paused&&this.running&&i.drawingBufferHeight>1)return void setTimeout((()=>l(e)),500);this.renderer.autoClear=!1,this.renderer.clear(),this.renderer.setViewport(0,0,this.container.clientWidth,this.container.clientHeight),this.camera,n.begin();let r=(e*=.001)-a;if(a=e,o.copy(this.camera.matrixWorld),r>1){let e=r;for(;e>.05;)s(D),e-=D;s(e)}else s(r);this.onLoopCallbacks.forEach((e=>e(r))),this.camera?.updateMatrixWorld(),h.copy(this.camera.matrixWorld),h.equals(o)||(this.renderer.shadowMap.needsUpdate=!0),this.resizeRender();const d=[],c=[];if(this.scene.traverse((i=>{i instanceof t&&i.visible&&(i.material?.userData?.water||i.material?.uniforms&&null!=i.material?.uniforms[f])?(i.visible=!1,d.push(i),this.initDepthUniform(i.material),i.renderOrder=100):i instanceof v&&(i.visible=!1,c.push(i)),i instanceof t&&i.material?.uniforms&&null!=i.material?.uniforms[R]&&(i.material.uniforms[R].value=e)})),d.length>0){if(this.scene.overrideMaterial=L,this.renderer.setRenderTarget(this.depthRenderTarget),!this.paused&&null!=this.camera)try{this.renderer.clear(),this.renderer.render(this.scene,this.camera)}catch(e){console.warn(e)}this.renderer.setRenderTarget(null),this.scene.overrideMaterial=null}d.forEach((e=>e.visible=!0)),c.forEach((e=>e.visible=!0));try{!this.paused&&this.running&&(this.render(r),this.renderOverlay())}catch(e){console.warn(e)}n.end(),this.csm?.update(),this.running&&!0!==this.options.enableXR&&(this.fpsCap?setTimeout((()=>{requestAnimationFrame(l)}),1e3/this.fpsCap):requestAnimationFrame(l))};!0===this.options.enableXR?this.renderer.setAnimationLoop(l):requestAnimationFrame(l)}renderOverlay(){const e=Array.from(this.overlayCameras.values()).slice(0,this.maxInsetCameras),t=this.container.clientWidth/2,i=e.length*this.insetWidth+(e.length-1)*this.insetMargin;for(let s=0;s<e.length;s++)this.renderer.clearDepth(),this.renderer.setViewport(t-i/2+this.insetWidth*s+this.insetMargin*s,this.insetOffsetY,this.insetWidth,this.insetHeight),this.renderer.render(this.scene,e[s])}addOverlayCamera(e){this.overlayCameras.add(e)}clearOverlayCameras(){this.overlayCameras.clear()}removeOverlayCamera(e){this.overlayCameras.delete(e)}render(e){if(this.hasBloom()){const e=this.scene.fog;this.scene.fog=null;const t=this.renderer.getClearColor(this.prevClearColor);this.renderer.setClearColor(0),this.scene.traverseVisible((e=>this.darkenNonBloomed(e))),this.bloomComposer.render(),this.scene.traverse((e=>this.restoreMaterial(e))),this.renderer.setClearColor(t),this.scene.fog=e}this.composer.render(e)}hasBloom(){return null!=y(this.scene,(e=>e instanceof t&&!0===e.material?.userData?.hasBloom))}darkenNonBloomed(e){e.isMesh&&e.visible&&!0!==e.material.userData.hasBloom&&(this.bloomStoredMaterials[e.uuid]=e.material,!0!==e.material.transparent?e.material=W:e.visible=!1)}restoreMaterial(e){this.bloomStoredMaterials[e.uuid]&&(e.material=this.bloomStoredMaterials[e.uuid],delete this.bloomStoredMaterials[e.uuid],e.visible=!0)}initDepthUniform(e){e instanceof s&&(e.uniforms[f].value=this.isDepthTextureExtensionSupported?this.depthRenderTarget.depthTexture:this.depthRenderTarget.texture,null!=e.uniforms[w]&&e.uniforms[w].value.set(this.container.clientWidth*this.renderer.getPixelRatio(),this.container.clientHeight*this.renderer.getPixelRatio()),this.camera instanceof n&&(e.uniforms[x].value=this.camera.near,e.uniforms[C].value=this.camera.far))}}export function setRenderingPaused(e){null!=window.editor?.viewer?.renderingView&&(window.editor.viewer.renderingView.paused=e)}const D=.05;
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Object3D, Texture } from 'three';
|
2
|
-
import { Asset } from './model';
|
3
|
-
import { CollisionShape } from './collision/collision-shape';
|
2
|
+
import { Asset } from './model.js';
|
3
|
+
import { CollisionShape } from './collision/collision-shape.js';
|
4
4
|
export declare class AssetResourceLoader {
|
5
5
|
private basePath;
|
6
6
|
private cache;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{
|
1
|
+
import{AudioLoader as e,Group as t,LoadingManager as s,Mesh as a,Object3D as i,TextureLoader as r}from"three";import{GLTFLoader as n,MTLLoader as o,OBJLoader as c}from"three-stdlib";import{FBXLoader as l}from"three-stdlib";import{cloneMesh as h}from"../utils/mesh.js";import{pathJoin as d}from"../utils/files.js";import{Subject as p,firstValueFrom as u}from"rxjs";import{importCollisionShapes as f}from"./collision/collision-shape-import.js";import*as m from"three";import{iterateMaterials as g}from"../utils/materials.js";const w=["glb","gltf","fbx","obj"];export class AssetResourceLoader{onError(e){console.error(e)}constructor(){this.cache=new Map,this.textureCache=new Map,this.loadingManager=new s,this.glbLoader=new n(this.loadingManager),this.fbxLoader=new l(this.loadingManager),this.objLoader=new c(this.loadingManager),this.textureLoader=new r(this.loadingManager),this.audioLoader=new e(this.loadingManager),this.makeReady=new p,this.ready=u(this.makeReady),this.collisionShapeCache=new Map}setDataDir(e){this.basePath=d(e,"asset-resources"),this.makeReady.next(!0)}getUri(e){return d(this.basePath,e)+`?windowId=${getElectronArg("windowId")}`}async getTexture(e){return null==e?null:(await this.ready,this.cache.has(e.id)||await this.textureLoader.loadAsync(this.getUri(e.fileKey)).then((t=>(t.wrapS=L(e.texture?.wrapS),t.wrapT=L(e.texture?.wrapT),t.flipY=e.texture?.flipY??!0,this.textureCache.set(e.id,t),t))),this.textureCache.get(e.id))}async getMesh(e){if(await this.ready,!w.includes(e.fileFormat?.toLowerCase()))return console.error("Unsupported mesh file format "+e.fileFormat,e),{scene:new t};if(!this.cache.has(e.fileKey))try{this.cache.set(e.fileKey,await this.loadMesh(e))}catch(e){return this.onError(e),{scene:new t}}const s=h(this.cache.get(e.fileKey).scene);s.traverse((e=>{e instanceof a&&e.material instanceof Array&&(e.material=e.material.slice())}));const i=this.computeCollisionShapes(e,s),r=(new AssetMeshInstance).copy(s);return r.collisionShapes=i,{scene:r}}async getAudio(e){return await this.ready,this.audioLoader.loadAsync(this.getUri(e.fileKey))}computeCollisionShapes(e,t){return this.collisionShapeCache.get(e.id)||this.collisionShapeCache.set(e.id,f(t)),this.collisionShapeCache.get(e.id)}async loadMesh(e){return await this.ready,await this.loadByAsset(e).then((e=>(e.scene.animations=[],e.scene=function(e,t){let s=!1;if(t.traverseVisible((e=>{b.test(e.name)&&(s=!0)})),!s)return t;const a=new m.LOD,i=[t];for(;i.length>0;){const e=i.shift(),t=e.name.match(b);if(null!=t){const s=parseInt(t[1]);0===s?a.addLevel(e,0):console.warn(`Skipping LOD level ${s} for now as LOD is not fully supported`)}else i.push(...e.children)}return a}(0,e.scene),e)))}async loadByAsset(e){const t=this.getUri(e.fileKey);switch(e.fileFormat){case"glb":case"gltf":return this.glbLoader.loadAsync(t).then((e=>({scene:e.scene})));case"fbx":return this.fbxLoader.loadAsync(t).then((e=>({scene:e})));case"obj":if(null!=e.materialLib){const t=new o;t.materialOptions={normalizeRGB:!1};const s=await t.loadAsync(this.getUri(e.materialLib));this.objLoader.setMaterials(s)}return this.objLoader.loadAsync(t).then((e=>(y(e),e))).then((e=>({scene:e})))}}}function y(e){if(e instanceof a)for(const t of g(e.material))t instanceof m.MeshPhongMaterial&&!t.color.isLinear&&(t.color.isLinear=!0,t.color.convertSRGBToLinear());e.children?.forEach(y)}export class AssetMeshInstance extends i{}export function getElectronArg(e){const t=`--${e}=`,s=window.process?.argv.find((e=>e.startsWith(t)));return s?.substring(t.length)}function L(e){switch(e){case"clamp":return m.ClampToEdgeWrapping;case"repeat":return m.RepeatWrapping;case"mirror":return m.MirroredRepeatWrapping}return m.RepeatWrapping}const b=/_LOD(\d+)$/;
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,10 +1,10 @@
|
|
1
1
|
import * as THREE from 'three';
|
2
|
-
import { RenderingView } from '../rendering';
|
3
|
-
import { AssetResourceLoader } from './asset-resource-loader';
|
4
|
-
import { ActorProvider, SceneMaterializer } from './materializer';
|
5
|
-
import { RuntimeBackendService } from './runtime-backend-service';
|
6
|
-
import { RuntimeAssetsService } from './runtime-asset-service';
|
7
|
-
import { ShaderType, ActorType } from '../shader/shader';
|
2
|
+
import { RenderingView } from '../rendering.js';
|
3
|
+
import { AssetResourceLoader } from './asset-resource-loader.js';
|
4
|
+
import { ActorProvider, SceneMaterializer } from './materializer.js';
|
5
|
+
import { RuntimeBackendService } from './runtime-backend-service.js';
|
6
|
+
import { RuntimeAssetsService } from './runtime-asset-service.js';
|
7
|
+
import { ShaderType, ActorType } from '../shader/shader.js';
|
8
8
|
export type ShaderDefinitions = {
|
9
9
|
[name: string]: ShaderType;
|
10
10
|
};
|
@@ -17,5 +17,5 @@ export declare function loadScene(view: RenderingView, sceneName: string, dataDi
|
|
17
17
|
materializer: SceneMaterializer;
|
18
18
|
assetResourceLoader: AssetResourceLoader;
|
19
19
|
assetsService: RuntimeAssetsService;
|
20
|
-
actors: import("../gameplay").BaseActor[];
|
20
|
+
actors: import("../gameplay/index.js").BaseActor[];
|
21
21
|
}>;
|
package/dist/scene/bootstrap.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import{
|
1
|
+
import{polyfill as e}from"../utils/polyfill.js";import{SceneDataService as t}from"./scene-data-service.js";import{SceneMaterializer as n}from"./materializer.js";import{basicSceneSetup as a}from"./sky.js";export async function loadScene(r,i,s,o,c,m,l,p,f){e();const{scene:w,renderer:d,camera:j}=r;a(w);const u=await l.getScene(i);if(null==u)throw Error(`Could not find scene with name ${i}`);const y=await l.getSceneData(u.id),S=new t;S.initiate(y,!0);const g=Object.entries(o).map((([e,t])=>({name:e,type:t}))),h=Object.entries(c).map((([e,t])=>({name:e,type:t}))),v=new n(w,S,p,f,r,g,h,m);return await v.initWithInstancing(),{scene:w,view:r,materializer:v,assetResourceLoader:f,assetsService:p,actors:v.actorInstances}}
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,4 +1,4 @@
|
|
1
1
|
import { Object3D } from "three";
|
2
|
-
import { CollisionShape } from
|
2
|
+
import { CollisionShape } from './collision-shape.js';
|
3
3
|
export declare function importCollisionShapes(group: Object3D): CollisionShape[];
|
4
4
|
export declare function isCollisionMesh(object: Object3D): boolean;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{Box3 as e,Euler as t,Mesh as n,Quaternion as o,Vector3 as i}from"three";import{BoxCollisionShape as r,ConvexPolyhedronCollisionShape as s,SphereCollisionShape as a,TrimeshCollisionShape as m}from"./collision-shape";const c=new o;export function importCollisionShapes(o){const x=[];return o.traverse((o=>{if(o instanceof n||o.isMesh){const n=function(t){if(t.name.startsWith(u.convex))return new s(t);if(t.name.startsWith(u.box)){const n=t.clone();n.quaternion.set(0,0,0,1),n.updateMatrixWorld();const o=(new e).setFromObject(n);return isFinite(o.min.lengthSq())?new r(new i(o.max.x-o.min.x,o.max.y-o.min.y,o.max.z-o.min.z)):null}if(t.name.startsWith(u.sphere)){t.geometry.computeBoundingSphere();const e=t.geometry.boundingSphere.radius*Math.max(t.scale.x,t.scale.y,t.scale.z);return new a(e)}if(t.name.startsWith(u.trimesh))return new m(t.geometry);{t.geometry.computeBoundingBox();const e=function(e){const t=e.max.x-e.min.x,n=e.max.y-e.min.y,o=e.max.z-e.min.z;return t+n+o}(h.copy(t.geometry.boundingBox).applyMatrix4(t.matrixWorld));if(e>.001)return new s(t)}}(o);null!=n&&(n.offset=o.getWorldPosition(new i),n.rotation=(new t).setFromQuaternion(o.getWorldQuaternion(c)),x.push(n),isCollisionMesh(o)&&(o.visible=!1))}})),x}export function isCollisionMesh(e){return e.name.startsWith(u.convex)||e.name.startsWith(u.box)||e.name.startsWith(u.sphere)||e.name.startsWith(u.trimesh)}var u;!function(e){e.convex="UCX_",e.box="UBX_",e.sphere="USP_",e.trimesh="UTM_"}(u||(u={}));const h=new e;
|
1
|
+
import{Box3 as e,Euler as t,Mesh as n,Quaternion as o,Vector3 as i}from"three";import{BoxCollisionShape as r,ConvexPolyhedronCollisionShape as s,SphereCollisionShape as a,TrimeshCollisionShape as m}from"./collision-shape.js";const c=new o;export function importCollisionShapes(o){const x=[];return o.traverse((o=>{if(o instanceof n||o.isMesh){const n=function(t){if(t.name.startsWith(u.convex))return new s(t);if(t.name.startsWith(u.box)){const n=t.clone();n.quaternion.set(0,0,0,1),n.updateMatrixWorld();const o=(new e).setFromObject(n);return isFinite(o.min.lengthSq())?new r(new i(o.max.x-o.min.x,o.max.y-o.min.y,o.max.z-o.min.z)):null}if(t.name.startsWith(u.sphere)){t.geometry.computeBoundingSphere();const e=t.geometry.boundingSphere.radius*Math.max(t.scale.x,t.scale.y,t.scale.z);return new a(e)}if(t.name.startsWith(u.trimesh))return new m(t.geometry);{t.geometry.computeBoundingBox();const e=function(e){const t=e.max.x-e.min.x,n=e.max.y-e.min.y,o=e.max.z-e.min.z;return t+n+o}(h.copy(t.geometry.boundingBox).applyMatrix4(t.matrixWorld));if(e>.001)return new s(t)}}(o);null!=n&&(n.offset=o.getWorldPosition(new i),n.rotation=(new t).setFromQuaternion(o.getWorldQuaternion(c)),x.push(n),isCollisionMesh(o)&&(o.visible=!1))}})),x}export function isCollisionMesh(e){return e.name.startsWith(u.convex)||e.name.startsWith(u.box)||e.name.startsWith(u.sphere)||e.name.startsWith(u.trimesh)}var u;!function(e){e.convex="UCX_",e.box="UBX_",e.sphere="USP_",e.trimesh="UTM_"}(u||(u={}));const h=new e;
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,10 +1,10 @@
|
|
1
|
-
import { SceneObject } from '../../scene/materializer';
|
2
|
-
import { RenderingView } from '../../rendering';
|
1
|
+
import { SceneObject } from '../../scene/materializer.js';
|
2
|
+
import { RenderingView } from '../../rendering.js';
|
3
3
|
import { Mesh, Vector3 } from 'three';
|
4
|
-
import { LandscapeGroup } from './landscape';
|
5
|
-
import { AssetResourceLoader } from '../asset-resource-loader';
|
6
|
-
import { AssetsProvider } from '../../scene/assets-provider';
|
7
|
-
import { ShaderImpl } from '../../shader/shader';
|
4
|
+
import { LandscapeGroup } from './landscape.js';
|
5
|
+
import { AssetResourceLoader } from '../asset-resource-loader.js';
|
6
|
+
import { AssetsProvider } from '../../scene/assets-provider.js';
|
7
|
+
import { ShaderImpl } from '../../shader/shader.js';
|
8
8
|
/**
|
9
9
|
* Creates landscape with varying level of detail depending on the
|
10
10
|
*/
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{__awaiter as e}from"tslib";import{materialFromAsset as t}from"../../scene/materializer";import{Mesh as s,PlaneGeometry as o,Vector3 as n,InstancedMesh as i,Matrix4 as a,MeshLambertMaterial as r,Color as c,Vector2 as l,Triangle as h,Box3 as u,MathUtils as d,MeshStandardMaterial as f,ShaderMaterial as m,DoubleSide as p,PerspectiveCamera as w}from"three";import{indexBy as y}from"../../utils/collections";import{smoothNormalsCrossMeshes as v}from"./utils";import*as M from"three";import{defaultLandscapeMaterial as g,LandscapeMesh as x}from"./landscape";import{meanVectors3withWeight as b,clamp as S}from"../../utils/math";import{whenIdle as A}from"../../utils/async";import{Subject as z,debounceTime as P}from"rxjs";new n,new n;const L=new n,B=new n,G=new n;export class LandscapeManager{constructor(e,t,s,o,i,r,c){this.source=e,this.view=t,this.landscape=s,this.assetManagerService=o,this.assetService=i,this.shaders=r,this.applyMaterial=c,this.scatterMeshes=new Map,this.loadedScatterSquares=new Set,this.refreshRequests=new z,this.defaultLandscapeMaterial=g.clone(),this.onLoopHandler=()=>this.update(),this.sectionCache=new Map,this._matrix=new a,this.scatterGeometryCache=new Map,this._lastUpdatePosition=new n,this._cameraPosition=new n,this.view.onLoop(this.onLoopHandler),this.defaultLandscapeMaterial.name=g.name,this.defaultLandscapeMaterial.color=g.color,this.refreshRequests.pipe(P(500)).subscribe((e=>this.refreshScatter(e.origin,e.force,e.predicate)))}updateShaders(e){this.shaders=e}loadGrass(){return e(this,void 0,void 0,(function*(){const e=yield this.assetService.getAsset("6ij937n72g");yield this.assetManagerService.getMesh(e);this.grassGeometry=new o(2,2,3,3);const t=this.grassGeometry.getAttribute("normal");for(let e=0;e<t.count;e++)t.setXYZ(e,0,1,0);t.needsUpdate=!0,this.grassMaterial=new f({color:3765785})}))}refreshGeometry(){const e=this.source.landscape.options,t=(new n,new n);this.view.camera.getWorldPosition(t);const s=[];G.fromArray(this.source.position);const o=this.view.camera instanceof w?Math.min(this.view.camera.far,1e3):1e3,i=1.1*o,a=e.sections.y*e.sectionSize/-2,r=e.sections.x*e.sectionSize/-2;for(let n=0;n<e.sections.x;n++)if(L.x=r+n*e.sectionSize,!(Math.abs(t.x-L.x)>i))for(let c=0;c<e.sections.y;c++){L.z=a+c*e.sectionSize,B.copy(G).add(L);const l=B.distanceTo(t),h=`${n},${c}`,u=this.landscape.sections.find((e=>e.x===n&&e.y===c));if(l<=o){if(null==u){this.sectionCache.has(h)||this.sectionCache.set(h,this.createLandscapeMesh(this.source,e,r,a,n,c));const t=this.sectionCache.get(h);this.applyMaterial(t),this.landscape.add(t),s.push(t)}}else l>i&&this.landscape.remove(u)}v(s)}applyHeightMap(e,t,s,o=1){var n,i,a,r;const c=Math.pow(s+1,2),l=e.getAttribute("position"),h=y(null!==(n=t.points)&&void 0!==n?n:[],(e=>e.i));if(1===o)for(const e of t.points)l.setY(e.i,e.y);else for(let e=0;e<l.count;e++){const t=$(e,l.count,c);let s=0;s=t%1==0?null!==(a=null===(i=h.get(t))||void 0===i?void 0:i.y)&&void 0!==a?a:0:Math.floor(null===(r=h.get(t))||void 0===r?void 0:r.y),l.setY(e,s)}l.needsUpdate=!0,e.computeVertexNormals()}deleteOldScatterMeshes(){var e,t;const s=new Set;for(const[o,n]of null!==(t=null===(e=this.source.grass)||void 0===e?void 0:e.layers.entries())&&void 0!==t?t:[])for(const[e,t]of n.meshes.entries()){const t=`${o}-${e}`;s.add(t)}for(const e of this.scatterMeshes.keys())if(!s.has(e)){this.scatterMeshes.get(e).forEach((e=>{var t;null===(t=e.parent)||void 0===t||t.remove(e),e.dispose()})),this.scatterMeshes.delete(e)}}queueRefreshScatter(e,t=!1,s=(()=>!0)){this.refreshRequests.next({origin:e,force:t,predicate:s})}refreshScatter(a,l=!1,u=(()=>!0)){var f,w,v,g;return e(this,void 0,void 0,(function*(){l&&this.scatterGeometryCache.clear(),this.deleteOldScatterMeshes();for(const[x,z]of null!==(w=null===(f=this.source.grass)||void 0===f?void 0:f.layers.entries())&&void 0!==w?w:[])for(const[f,w]of z.meshes.entries()){const z=`${x}-${f}`;this.scatterMeshes.has(z)||this.scatterMeshes.set(z,new Map);const P=this.scatterMeshes.get(z),L=yield this.assetService.getAsset(w.assetId),B=yield this.assetManagerService.getMesh(L),G=[];if(B.scene.traverse((e=>{e instanceof s&&G.push(e)})),1!==G.length){console.log(B),console.warn("Dynamic grass only works for meshes with a single geometry.");continue}if(!(G[0]instanceof s)){console.warn("Only meshes can be used for dynamic grass. Found:",B.scene);continue}const $=G[0];let _=$.geometry;this.scatterGeometryCache.has($.geometry.uuid)?_=this.scatterGeometryCache.get($.geometry.uuid):(_=$.geometry.clone(),!0===w.normalsUp&&E(_),this.scatterGeometryCache.set($.geometry.uuid,_),null==_.userData.updatedMatrix&&(B.scene.updateMatrixWorld(),_.applyMatrix4($.matrixWorld),_.userData.updatedMatrix=!0));const U=_.getIndex().count/3;if(U>400){console.warn(`The triangle count of ${L.name} is too big ${U}. Keep it below 400`);continue}const D=null!=L.materialAssignments&&L.materialAssignments.length>0?L.materialAssignments[0].materialId:null,I=null!=D&&"null"!==D?yield t(yield this.assetService.getAsset(D),null,this.assetService,this.assetManagerService,this.shaders,!1):null;let O=null!=I?I:$.material;O instanceof m&&(O.side=p);const Y=d.degToRad(null!==(v=w.maxSlope)&&void 0!==v?v:90),X=Math.cos(Y),F=this.landscape.sections,N=F.filter(k(a,w.viewDistance)).filter((e=>!P.has(e.uuid)||l)).filter((e=>u(e)));F.filter(C(a,2*w.viewDistance)).forEach((e=>{var t;const s=P.get(e.uuid);null===(t=null==s?void 0:s.parent)||void 0===t||t.remove(s),P.delete(e.uuid)}));performance.now();const Z=this.source.landscape.options,K=Z.sectionSize,V=null!==(g=w.density)&&void 0!==g?g:1,J=null!=V?V:1,Q=Z.density,ee=K/Q,te=J,se=ee/Math.sqrt(te),oe=Math.pow(Q,2),ne=se/ee,ie=Math.floor(oe*te),ae=[0,0,0];for(const t of N)yield A((()=>e(this,void 0,void 0,(function*(){var e,s,a,u,d,f,m;t.updateWorldMatrix(!0,!1);const p=this._matrix,v=new n,g=t.geometry.getAttribute("position"),A=t.geometry.getAttribute("normal"),z=(null!==(e=this.source.vertexMaterials)&&void 0!==e?e:[]).filter((e=>e.m===t.name)),L=y(z,(e=>e.i));let B=P.get(t.uuid);if(null==B||B.count==ie&&!l||(null===(s=B.parent)||void 0===s||s.remove(B),P.delete(t.uuid),B=null),null==B){const e=new o(.15,.75).getAttribute("normal");for(let t=0;t<e.count;t++);new r({color:new c(3765785),side:M.DoubleSide});B=new i(_,O,ie),B.raycast=()=>{},B.receiveShadow=!0}const G=new h(new n,new n,new n);let[$,C,k,U]=[new n,new n,new n,new n],[D,I,Y]=[[],[],[]],[E,F,N]=[new n,new n,new n,new n];const Z=new n,K=new n,V=new n,J=new n,ee=new h(new n,new n,new n),se=new h(new n,new n,new n),re=new h(new n,new n,new n),ce=new h(new n,new n,new n);let le=0;e:for(let e=0;e<oe;e++){const s=Math.floor(e/Q);$.fromBufferAttribute(g,e+s),J.copy($).applyMatrix4(t.matrixWorld),ee.a.copy($),ee.b.fromBufferAttribute(g,e+1+s),ee.c.fromBufferAttribute(g,e+Q+1+s),se.a.copy(ee.b),se.b.copy(ee.c),se.c.fromBufferAttribute(g,e+Q+2+s),re.a.fromBufferAttribute(A,e+s),re.b.fromBufferAttribute(A,e+1+s),re.c.fromBufferAttribute(A,e+Q+1+s),ce.a.copy(re.b),ce.b.copy(re.c),ce.c.fromBufferAttribute(A,e+Q+2+s);const o=[];o[0]=null===(a=L.get(e+s))||void 0===a?void 0:a.w,o[1]=null===(u=L.get(e+1+s))||void 0===u?void 0:u.w,o[2]=null===(d=L.get(e+Q+1+s))||void 0===d?void 0:d.w,o[3]=null===(f=L.get(e+Q+2+s))||void 0===f?void 0:f.w;let n=0;for(let e=0;e<=1+ne;e+=ne)for(let s=0;s<=1+ne;s+=ne){if(le>ie)break e;if(n++,n>te)continue e;1-e>s?(C=ee.a,k=ee.b,U=ee.c,E=re.a,F=re.b,N=re.c,D=o[0],I=o[1],Y=o[2]):(C=se.a,k=se.b,U=se.c,E=ce.a,F=ce.b,N=ce.c,D=o[1],I=o[2],Y=o[3]),G.a.copy(C),G.b.copy(k),G.c.copy(U),q(G),Z.set($.x,0,$.z),Z.x=T(G.a.x,G.b.x),Z.z=T(G.a.z,G.c.z),G.getBarycoord(Z,v).toArray(ae);if(R([D,I,Y],ae,.2)!==x-1)continue;const i=[C,k,U];b(i,ae,K),b([E,F,N],ae,V);const a=i.map((e=>e.y)),r=Math.max(...a),c=Math.min(...a);if(K.y=S(K.y,c,r),null!=w.maxSlope&&w.maxSlope<90&&V.y<X)continue;const l=K.applyMatrix4(t.matrixWorld);l.y+=T(w.offsetMin,w.offsetMax);const h=T(w.scaleMin,w.scaleMax);p.makeScale(1,1,1),p.setPosition(l),p.scale(W(h)),w.alignToNormal&&H(p,l,B.matrixWorld,V),!1!==w.randomRotation&&j(p),B.setMatrixAt(le,p),le++}}B.instanceMatrix.count=le,p.makeScale(0,0,0);for(let e=le;e<ie;e++)B.setMatrixAt(e,p);B.instanceMatrix.needsUpdate=!0,P.has(t.uuid)||null===(m=this.landscape)||void 0===m||m.attach(B),P.set(t.uuid,B)}))));performance.now()}}))}stop(){this.view.removeOnLoop(this.onLoopHandler)}update(){this.view.camera&&(this.view.camera.getWorldPosition(this._cameraPosition),this._cameraPosition.distanceTo(this._lastUpdatePosition)>10&&(this._lastUpdatePosition.copy(this._cameraPosition),this.refreshGeometry(),this.refreshScatter(this._cameraPosition)))}clear(){this.scatterMeshes.forEach((e=>e.forEach((e=>{var t;return null===(t=e.parent)||void 0===t?void 0:t.remove(e)}))))}createLandscapeMesh(e,t,s,n,i,a){const r=new o(t.sectionSize,t.sectionSize,t.density,t.density);r.rotateX(Math.PI/-2);const c=this.defaultLandscapeMaterial,l=new x(r,c);l.position.x=s+i*t.sectionSize,l.position.z=n+a*t.sectionSize,l.receiveShadow=!0,l.castShadow=!1,l.userData.landscape={x:i,y:a},l.x=i,l.y=a,l.name=`${i},${a}`;const h=e.landscape.heightMaps.find((e=>e.x===i&&e.y===a));return null!=h&&this.applyHeightMap(r,h,t.density,1),r.computeBoundsTree(),l}}function $(e,t,s){const o=Math.sqrt(t),n=Math.floor(e/o)/(o-1),i=e%o/(o-1),a=Math.sqrt(s);return(s-1)*n-(a-1)*n+(a-1)*i}new Map,new l(0,0),new l(1,0),new l(0,1),new l(1,0),new l(0,1),new l(1,1),new n;const _=new u;function C(e,t){return function(s){return _.setFromObject(s).distanceToPoint(e)>t}}function k(e,t){return function(s){return _.setFromObject(s).distanceToPoint(e)<t}}function q(e){e.a.y=0,e.b.y=0,e.c.y=0}function R(e,t,s=.5){let o=-1,n=0;for(let i=0;i<e.length;i++)if(null!=e[i])for(let a=0;a<e[i].length;a++){const r=e[i][a]*t[i];r>s&&r>n&&(n=r,o=a)}return o}function T(e,t){let s=t-e,o=Math.random();return o*=s,o+=e,o}const U=new n;function W(e){return U.set(e,e,e)}new n;const D=new n,I=new n(0,1,0),O=(new a).makeRotationX(Math.PI/-2);function H(e,t,s,o){e.lookAt(D,o,I).multiply(O)}const Y=new a;function j(e){e.multiply(Y.makeRotationY(Math.random()*Math.PI/2))}function E(e){const t=e.getAttribute("normal");for(let e=0;e<t.count;e++)t.setXYZ(e,0,1,0);t.needsUpdate=!0}
|
1
|
+
import{materialFromAsset as e}from"../../scene/materializer.js";import{Mesh as t,PlaneGeometry as s,Vector3 as n,InstancedMesh as a,Matrix4 as o,MeshLambertMaterial as i,Color as r,Vector2 as c,Triangle as l,Box3 as h,MathUtils as u,MeshStandardMaterial as f,ShaderMaterial as m,DoubleSide as d,PerspectiveCamera as p}from"three";import{indexBy as w}from"../../utils/collections.js";import{smoothNormalsCrossMeshes as y}from"./utils.js";import*as M from"three";import{defaultLandscapeMaterial as g,LandscapeMesh as x}from"./landscape.js";import{meanVectors3withWeight as S,clamp as b}from"../../utils/math.js";import{whenIdle as v}from"../../utils/async.js";import{Subject as A,debounceTime as z}from"rxjs";new n,new n;const P=new n,L=new n,j=new n;export class LandscapeManager{constructor(e,t,s,a,i,r,c){this.source=e,this.view=t,this.landscape=s,this.assetManagerService=a,this.assetService=i,this.shaders=r,this.applyMaterial=c,this.scatterMeshes=new Map,this.loadedScatterSquares=new Set,this.refreshRequests=new A,this.defaultLandscapeMaterial=g.clone(),this.onLoopHandler=()=>this.update(),this.sectionCache=new Map,this._matrix=new o,this.scatterGeometryCache=new Map,this._lastUpdatePosition=new n,this._cameraPosition=new n,this.view.onLoop(this.onLoopHandler),this.defaultLandscapeMaterial.name=g.name,this.defaultLandscapeMaterial.color=g.color,this.refreshRequests.pipe(z(500)).subscribe((e=>this.refreshScatter(e.origin,e.force,e.predicate)))}updateShaders(e){this.shaders=e}async loadGrass(){const e=await this.assetService.getAsset("6ij937n72g");await this.assetManagerService.getMesh(e);this.grassGeometry=new s(2,2,3,3);const t=this.grassGeometry.getAttribute("normal");for(let e=0;e<t.count;e++)t.setXYZ(e,0,1,0);t.needsUpdate=!0,this.grassMaterial=new f({color:3765785})}refreshGeometry(){const e=this.source.landscape.options,t=(new n,new n);this.view.camera.getWorldPosition(t);const s=[];j.fromArray(this.source.position);const a=this.view.camera instanceof p?Math.min(this.view.camera.far,1e3):1e3,o=1.1*a,i=e.sections.y*e.sectionSize/-2,r=e.sections.x*e.sectionSize/-2;for(let n=0;n<e.sections.x;n++)if(P.x=r+n*e.sectionSize,!(Math.abs(t.x-P.x)>o))for(let c=0;c<e.sections.y;c++){P.z=i+c*e.sectionSize,L.copy(j).add(P);const l=L.distanceTo(t),h=`${n},${c}`,u=this.landscape.sections.find((e=>e.x===n&&e.y===c));if(l<=a){if(null==u){this.sectionCache.has(h)||this.sectionCache.set(h,this.createLandscapeMesh(this.source,e,r,i,n,c));const t=this.sectionCache.get(h);this.applyMaterial(t),this.landscape.add(t),s.push(t)}}else l>o&&this.landscape.remove(u)}y(s)}applyHeightMap(e,t,s,n=1){const a=Math.pow(s+1,2),o=e.getAttribute("position"),i=w(t.points??[],(e=>e.i));if(1===n)for(const e of t.points)o.setY(e.i,e.y);else for(let e=0;e<o.count;e++){const t=B(e,o.count,a);let s=0;s=t%1==0?i.get(t)?.y??0:Math.floor(i.get(t)?.y),o.setY(e,s)}o.needsUpdate=!0,e.computeVertexNormals()}deleteOldScatterMeshes(){const e=new Set;for(const[t,s]of this.source.grass?.layers.entries()??[])for(const[n,a]of s.meshes.entries()){const s=`${t}-${n}`;e.add(s)}for(const t of this.scatterMeshes.keys())if(!e.has(t)){this.scatterMeshes.get(t).forEach((e=>{e.parent?.remove(e),e.dispose()})),this.scatterMeshes.delete(t)}}queueRefreshScatter(e,t=!1,s=(()=>!0)){this.refreshRequests.next({origin:e,force:t,predicate:s})}async refreshScatter(o,c=!1,h=(()=>!0)){c&&this.scatterGeometryCache.clear(),this.deleteOldScatterMeshes();for(const[f,p]of this.source.grass?.layers.entries()??[])for(const[y,g]of p.meshes.entries()){const p=`${f}-${y}`;this.scatterMeshes.has(p)||this.scatterMeshes.set(p,new Map);const x=this.scatterMeshes.get(p),A=await this.assetService.getAsset(g.assetId),z=await this.assetManagerService.getMesh(A),P=[];if(z.scene.traverse((e=>{e instanceof t&&P.push(e)})),1!==P.length){console.log(z),console.warn("Dynamic grass only works for meshes with a single geometry.");continue}if(!(P[0]instanceof t)){console.warn("Only meshes can be used for dynamic grass. Found:",z.scene);continue}const L=P[0];let j=L.geometry;this.scatterGeometryCache.has(L.geometry.uuid)?j=this.scatterGeometryCache.get(L.geometry.uuid):(j=L.geometry.clone(),!0===g.normalsUp&&Y(j),this.scatterGeometryCache.set(L.geometry.uuid,j),null==j.userData.updatedMatrix&&(z.scene.updateMatrixWorld(),j.applyMatrix4(L.matrixWorld),j.userData.updatedMatrix=!0));const B=j.getIndex().count/3;if(B>400){console.warn(`The triangle count of ${A.name} is too big ${B}. Keep it below 400`);continue}const G=null!=A.materialAssignments&&A.materialAssignments.length>0?A.materialAssignments[0].materialId:null,R=null!=G&&"null"!==G?await e(await this.assetService.getAsset(G),null,this.assetService,this.assetManagerService,this.shaders,!1):null;let U=null!=R?R:L.material;U instanceof m&&(U.side=d);const W=u.degToRad(g.maxSlope??90),D=Math.cos(W),O=this.landscape.sections,E=O.filter(_(o,g.viewDistance)).filter((e=>!x.has(e.uuid)||c)).filter((e=>h(e)));O.filter($(o,2*g.viewDistance)).forEach((e=>{const t=x.get(e.uuid);t?.parent?.remove(t),x.delete(e.uuid)}));performance.now();const X=this.source.landscape.options,F=X.sectionSize,N=g.density??1??1,Z=X.density,K=F/Z,V=N,J=K/Math.sqrt(V),Q=Math.pow(Z,2),ee=J/K,te=Math.floor(Q*V),se=[0,0,0];for(const e of E)await v((async()=>{e.updateWorldMatrix(!0,!1);const t=this._matrix,o=new n,h=e.geometry.getAttribute("position"),u=e.geometry.getAttribute("normal"),m=(this.source.vertexMaterials??[]).filter((t=>t.m===e.name)),d=w(m,(e=>e.i));let p=x.get(e.uuid);if(null==p||p.count==te&&!c||(p.parent?.remove(p),x.delete(e.uuid),p=null),null==p){const e=new s(.15,.75).getAttribute("normal");for(let t=0;t<e.count;t++);new i({color:new r(3765785),side:M.DoubleSide});p=new a(j,U,te),p.raycast=()=>{},p.receiveShadow=!0}const y=new l(new n,new n,new n);let[v,A,z,P]=[new n,new n,new n,new n],[L,B,G]=[[],[],[]],[$,_,R]=[new n,new n,new n,new n];const W=new n,O=new n,Y=new n,E=new n,X=new l(new n,new n,new n),F=new l(new n,new n,new n),N=new l(new n,new n,new n),K=new l(new n,new n,new n);let J=0;e:for(let s=0;s<Q;s++){const n=Math.floor(s/Z);v.fromBufferAttribute(h,s+n),E.copy(v).applyMatrix4(e.matrixWorld),X.a.copy(v),X.b.fromBufferAttribute(h,s+1+n),X.c.fromBufferAttribute(h,s+Z+1+n),F.a.copy(X.b),F.b.copy(X.c),F.c.fromBufferAttribute(h,s+Z+2+n),N.a.fromBufferAttribute(u,s+n),N.b.fromBufferAttribute(u,s+1+n),N.c.fromBufferAttribute(u,s+Z+1+n),K.a.copy(N.b),K.b.copy(N.c),K.c.fromBufferAttribute(u,s+Z+2+n);const a=[];a[0]=d.get(s+n)?.w,a[1]=d.get(s+1+n)?.w,a[2]=d.get(s+Z+1+n)?.w,a[3]=d.get(s+Z+2+n)?.w;let i=0;for(let s=0;s<=1+ee;s+=ee)for(let n=0;n<=1+ee;n+=ee){if(J>te)break e;if(i++,i>V)continue e;1-s>n?(A=X.a,z=X.b,P=X.c,$=N.a,_=N.b,R=N.c,L=a[0],B=a[1],G=a[2]):(A=F.a,z=F.b,P=F.c,$=K.a,_=K.b,R=K.c,L=a[1],B=a[2],G=a[3]),y.a.copy(A),y.b.copy(z),y.c.copy(P),C(y),W.set(v.x,0,v.z),W.x=q(y.a.x,y.b.x),W.z=q(y.a.z,y.c.z),y.getBarycoord(W,o).toArray(se);if(k([L,B,G],se,.2)!==f-1)continue;const r=[A,z,P];S(r,se,O),S([$,_,R],se,Y);const c=r.map((e=>e.y)),l=Math.max(...c),h=Math.min(...c);if(O.y=b(O.y,h,l),null!=g.maxSlope&&g.maxSlope<90&&Y.y<D)continue;const u=O.applyMatrix4(e.matrixWorld);u.y+=q(g.offsetMin,g.offsetMax);const m=q(g.scaleMin,g.scaleMax);t.makeScale(1,1,1),t.setPosition(u),t.scale(T(m)),g.alignToNormal&&I(t,u,p.matrixWorld,Y),!1!==g.randomRotation&&H(t),p.setMatrixAt(J,t),J++}}p.instanceMatrix.count=J,t.makeScale(0,0,0);for(let e=J;e<te;e++)p.setMatrixAt(e,t);p.instanceMatrix.needsUpdate=!0,x.has(e.uuid)||this.landscape?.attach(p),x.set(e.uuid,p)}));performance.now()}}stop(){this.view.removeOnLoop(this.onLoopHandler)}update(){this.view.camera&&(this.view.camera.getWorldPosition(this._cameraPosition),this._cameraPosition.distanceTo(this._lastUpdatePosition)>10&&(this._lastUpdatePosition.copy(this._cameraPosition),this.refreshGeometry(),this.refreshScatter(this._cameraPosition)))}clear(){this.scatterMeshes.forEach((e=>e.forEach((e=>e.parent?.remove(e)))))}createLandscapeMesh(e,t,n,a,o,i){const r=new s(t.sectionSize,t.sectionSize,t.density,t.density);r.rotateX(Math.PI/-2);const c=this.defaultLandscapeMaterial,l=new x(r,c);l.position.x=n+o*t.sectionSize,l.position.z=a+i*t.sectionSize,l.receiveShadow=!0,l.castShadow=!1,l.userData.landscape={x:o,y:i},l.x=o,l.y=i,l.name=`${o},${i}`;const h=e.landscape.heightMaps.find((e=>e.x===o&&e.y===i));return null!=h&&this.applyHeightMap(r,h,t.density,1),r.computeBoundsTree(),l}}function B(e,t,s){const n=Math.sqrt(t),a=Math.floor(e/n)/(n-1),o=e%n/(n-1),i=Math.sqrt(s);return(s-1)*a-(i-1)*a+(i-1)*o}new Map,new c(0,0),new c(1,0),new c(0,1),new c(1,0),new c(0,1),new c(1,1),new n;const G=new h;function $(e,t){return function(s){return G.setFromObject(s).distanceToPoint(e)>t}}function _(e,t){return function(s){return G.setFromObject(s).distanceToPoint(e)<t}}function C(e){e.a.y=0,e.b.y=0,e.c.y=0}function k(e,t,s=.5){let n=-1,a=0;for(let o=0;o<e.length;o++)if(null!=e[o])for(let i=0;i<e[o].length;i++){const r=e[o][i]*t[o];r>s&&r>a&&(a=r,n=i)}return n}function q(e,t){let s=t-e,n=Math.random();return n*=s,n+=e,n}const R=new n;function T(e){return R.set(e,e,e)}new n;const U=new n,W=new n(0,1,0),D=(new o).makeRotationX(Math.PI/-2);function I(e,t,s,n){e.lookAt(U,n,W).multiply(D)}const O=new o;function H(e){e.multiply(O.makeRotationY(Math.random()*Math.PI/2))}function Y(e){const t=e.getAttribute("normal");for(let e=0;e<t.count;e++)t.setXYZ(e,0,1,0);t.needsUpdate=!0}
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{Group as e,Mesh as a}from"three";import{Color as r}from"three";import{varyingAttributes as t,float as
|
1
|
+
import{Group as e,Mesh as a}from"three";import{Color as r}from"three";import{varyingAttributes as t,float as n,mod as o,dot as s,vec2 as c,step as i,fract as l,mix as p,rgb as d,NodeShaderMaterial as u,rgba as m,standardMaterial as f}from"three-shader-graph";import{mixColorsByLayer as h,select as x}from"../../shader-nodes/index.js";export function initLandscape(e){e.sections.y,e.sectionSize,e.sections.x,e.sectionSize;return new LandscapeGroup}export function createLandscapeDefaultMaterial(){const e=t.uv,a=n(10),x=n(7),L=o(s(c(1,1),i(c(.5,.5),l(e.multiplyScalar(a)))),n(2)),y=o(s(c(1,1),i(c(.5,.5),l(e.multiplyScalar(x.multiply(a))))),n(2)),D=p(d(4473924),d(5592405),L),M=p(D,D.addScalar(n(.1)),y),S=h({layerColors:[m(M).rgb(),...["#55DDE0","#33658A","#2F4858"].map((e=>d(e))).reverse()],enableNoise:!1}),g=new u({color:f({color:S})});return g.color=new r("#aaaaaa"),g.name="Default",g}export const defaultLandscapeMaterial=createLandscapeDefaultMaterial();export class LandscapeMesh extends a{}export class LandscapeGroup extends e{get sections(){return this.children.filter((e=>e instanceof LandscapeMesh))}}
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{Vector3 as e}from"three";export function smoothNormalsCrossMeshes(t){const r=new SectionGrid(t);performance.now();const n=new e,o=new e,i=new e,s=new e;for(const e of t){const t=e.geometry.getAttribute("position"),c=e.geometry.getAttribute("normal");for(const d of
|
1
|
+
import{Vector3 as e}from"three";export function smoothNormalsCrossMeshes(t){const r=new SectionGrid(t);performance.now();const n=new e,o=new e,i=new e,s=new e;for(const e of t){const t=e.geometry.getAttribute("position"),c=e.geometry.getAttribute("normal");for(const d of u(t.count)){const{otherMesh:u,j:a}=f(d,t.count,e,r,o);if(null==u)continue;n.fromBufferAttribute(t,d),n.applyMatrix4(e.matrixWorld);const x=u.geometry.getAttribute("position"),h=u.geometry.getAttribute("normal");u.updateMatrixWorld(),o.fromBufferAttribute(x,a),o.applyMatrix4(u.matrixWorld),i.fromBufferAttribute(c,d),s.fromBufferAttribute(h,a);const m=i.add(s).divideScalar(2);c.setXYZ(d,m.x,m.y,m.z),h.setXYZ(a,m.x,m.y,m.z),c.needsUpdate=!0,h.needsUpdate=!0;const l=(t.getY(d)+x.getY(a))/2;t.setY(d,l),x.setY(a,l)}}performance.now()}export class SectionGrid{constructor(e){this.grid=new Map;for(const t of e){const{x:e,y:r}=t;this.grid.has(e)||this.grid.set(e,new Map),this.grid.get(e).set(r,t)}}find(e,t){return this.grid.get(e)?.get(t)}}const t={meshPredicate:(e,t)=>e.find(t.x,t.y-1),vertexFunc:(e,t)=>e+t*(t-1)},r={meshPredicate:(e,t)=>e.find(t.x-1,t.y-1),vertexFunc:(e,t)=>t*t-1},n={meshPredicate:(e,t)=>e.find(t.x+1,t.y-1),vertexFunc:(e,t)=>t*t-t},o={meshPredicate:(e,t)=>e.find(t.x,t.y+1),vertexFunc:(e,t)=>e-t*(t-1)},i={meshPredicate:(e,t)=>e.find(t.x-1,t.y+1),vertexFunc:(e,t)=>t-1},s={meshPredicate:(e,t)=>e.find(t.x+1,t.y+1),vertexFunc:(e,t)=>0},c={meshPredicate:(e,t)=>e.find(t.x-1,t.y),vertexFunc:(e,t)=>e+t-1},d={meshPredicate:(e,t)=>e.find(t.x+1,t.y),vertexFunc:(e,t)=>e-t+1};function f(e,f,u,a,x){const h=Math.sqrt(f),m=(e+1)%h==0,l=e%h==0;let y;if(e<h?(y=t,l&&(y=r),m&&(y=n)):e>=f-h?(y=o,l?y=i:m&&(y=s)):l?y=c:m&&(y=d),null==y)return{otherMesh:null,j:null};return{otherMesh:y.meshPredicate(a,u),j:y.vertexFunc(e,h)}}function*u(e){const t=Math.sqrt(e);for(let r=0;r<t;r++)yield r,yield r+e-t;for(let e=1,r=t-1;e<r;e++)yield e*t,yield e*t+t-1}export function onEdge(e,t){const r=Math.sqrt(t);return e<r||e%r==0||e>=t-r||(e+1)%r==0}
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,16 +1,16 @@
|
|
1
1
|
import { Subject } from "rxjs";
|
2
2
|
import * as THREE from "three";
|
3
3
|
import { Euler, Material, Object3D, Scene, Vector3 } from "three";
|
4
|
-
import { GameComponent } from
|
5
|
-
import { RenderingView } from
|
6
|
-
import { ParameterType, PropertyParameter } from
|
7
|
-
import { ShaderImpl, ActorImpl } from '../shader/shader';
|
8
|
-
import { Type } from
|
9
|
-
import { AssetResourceLoader } from './asset-resource-loader';
|
10
|
-
import { AssetsProvider } from
|
11
|
-
import { LandscapeInitOptions } from
|
12
|
-
import { Asset, CustomParamValue, MaterialAssignment, SerializedParamType, ShapeType } from
|
13
|
-
import { BaseActor } from '../gameplay/actors/actor';
|
4
|
+
import { GameComponent } from '../game-component/game-component.js';
|
5
|
+
import { RenderingView } from '../rendering.js';
|
6
|
+
import { ParameterType, PropertyParameter } from '../shader/parameter.js';
|
7
|
+
import { ShaderImpl, ActorImpl } from '../shader/shader.js';
|
8
|
+
import { Type } from '../utils/type.js';
|
9
|
+
import { AssetResourceLoader } from './asset-resource-loader.js';
|
10
|
+
import { AssetsProvider } from './assets-provider.js';
|
11
|
+
import { LandscapeInitOptions } from './landscape/landscape.js';
|
12
|
+
import { Asset, CustomParamValue, MaterialAssignment, SerializedParamType, ShapeType } from './model.js';
|
13
|
+
import { BaseActor } from '../gameplay/actors/actor.js';
|
14
14
|
import { ContainerInstance } from "typedi";
|
15
15
|
export type SceneObjectId = string;
|
16
16
|
export type SceneObjectType = "asset_mesh" | "light" | "shape_mesh" | "spline" | "landscape" | "particles" | "global_fog" | "global_light" | "actor" | "group" | "prefab" | "vfx" | "sky";
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{__awaiter as e}from"tslib";import{Subject as t}from"rxjs";import*as i from"three";import{BoxGeometry as r,Color as a,Euler as s,Fog as o,FogExp2 as n,Group as l,Material as c,Mesh as d,MeshLambertMaterial as h,MeshPhongMaterial as u,MeshStandardMaterial as m,Object3D as p,PointLight as f,Quaternion as v,SphereGeometry as y,Texture as g,Vector2 as w,Vector3 as A,Vector4 as b}from"three";import S,{SpriteRenderer as M}from"three-nebula";import{bool as x,BooleanNode as I,float as P,FloatNode as D,NodeShaderMaterial as j,rgb as V,RgbNode as E,Texture2dLookupNode as N,textureSampler2d as C,vec2 as O,Vec2Node as F,vec3 as k,Vec3Node as z,vec4 as B}from"three-shader-graph";import _ from"../gameplay/actors/builtin";import{extractShaderParameters as T}from"../shader/parameter";import{groupBy as $,ArrayMap as L}from"../utils/collections";import{filterChildrenShallow as R,filterSceneShallow as U}from"../utils/three/traverse";import{AssetMeshInstance as H}from"./asset-resource-loader";import{BoxCollisionShape as W,PhysicalShapeMesh as G}from"./collision/collision-shape";import{isCollisionMesh as J}from"./collision/collision-shape-import";import{initLandscape as X}from"./landscape/landscape";import{LandscapeManager as Y}from"./landscape/landscape-manager";import{SectionGrid as q,smoothNormalsCrossMeshes as Z}from"./landscape/utils";import{createGrassMaterial as K}from"./materials/grass";import{createGrassFoliageMaterial as Q}from"./materials/grass-foliage";import{getMaterialAttribute as ee}from"./materials/utils/material-painting";import{createWaterMaterial as te}from"./materials/water";import{SerializedParamType as ie}from"./model";import{Matrix4 as re}from"three";import{BaseActor as ae}from"../gameplay/actors/actor";import{Sampler2DNode as se}from"../shader-nodes";import{StandardShader as oe}from"../shader/builtin/standard-shader";import{LambertShader as ne}from"../shader/builtin/lambert-shader";import{ShapeLibrary as le,ShapeLibraryKeys as ce}from"./objects/shapes";import{ambientLightName as de,createSky as he,defaultSkyMaterial as ue}from"./sky";import{ActorComponent as me,withInjectionContext as pe}from"../gameplay";import{iterateMaterials as fe}from"../utils/materials";import{VfxActor as ve}from"../effects/vfx/vfx-actor";import{VisualEffect as ye}from"../effects/vfx/vfx-param";const ge={};export const shapeDefaultColor="#aaaaaa";export class SceneMaterializerLoader{constructor(e,t,i){this.dataProvider=e,this.assetsService=t,this.assetManagerService=i}get(t,i){return new SceneMaterializer(t,this.dataProvider,this.assetsService,this.assetManagerService,i,[],[],{create:()=>null,initActor:()=>e(this,void 0,void 0,(function*(){}))})}}export class SceneMaterializer{constructor(i,r,a,s,o,n,l,c){this.scene=i,this.dataProvider=r,this.assetsService=a,this.assetManagerService=s,this.renderingView=o,this.shaders=n,this.actorTypes=l,this.actorProvider=c,this.objectMap=new Map,this.sceneObjectMap=new Map,this.components=[],this.landscapeManagers=[],this.materializedActors=new Map,this.inEditor=!0,this.updated$=new t,this.removed$=new t,this.error$=new t,this.editorActorParamSnapshot=new Map,this._canBeInstancedCache=new Map,this._originalMaterials=new Map,this.originalFog=null,r.onUpdate((e=>this.update(e))),r.onRemove((e=>this.remove(e))),this.updateSubscription=a.onUpdate.subscribe((t=>e(this,void 0,void 0,(function*(){"material"==t.type?((yield this.assetsService.getAssets()).filter((e=>{var i;return(null!==(i=e.materialAssignments)&&void 0!==i?i:[]).some((e=>e.materialId===t.id))})).forEach((e=>{const t=this.findByAssetId(e.id);e.materialAssignments.forEach((e=>{t.forEach((t=>{const i=t.userData.src.materialAssignments;null!=i&&i.some((t=>t.color===e.color))||this.applyMaterial(t,e)}))}))})),U(this.scene,(e=>{var i;return null!=e.userData.src&&(null!==(i=e.userData.src.materialAssignments)&&void 0!==i?i:[]).some((e=>e.materialId===t.id))}),(e=>null!=e.userData.src)).forEach((t=>e(this,void 0,void 0,(function*(){this.deleteSceneObject(t.userData.src),this.materialize(t.userData.src)}))))):"mesh"==t.type?this.findByAssetId(t.id).forEach((e=>{je(e.userData.src.materialAssignments,t.materialAssignments).forEach((t=>{this.applyMaterial(e,t)}))})):"prefab"===t.type&&this.findByAssetId(t.id).forEach((e=>{const t=e.userData.src;this.remove(t),this.materializeAndInitActor(t)}))}))))}get actorInstances(){return Array.from(this.materializedActors.values())}prefetchAssets(){return e(this,void 0,void 0,(function*(){const e=Array.from(new Set(this.dataProvider.getObjects().filter((e=>null!=e.assetId&&"asset_mesh"==e.type)).filter((e=>e.assetId))));yield Promise.all(e.map((e=>this.assetsService.getAsset(e.assetId).then((e=>e&&this.assetManagerService.getMesh(e))))))}))}init(){return e(this,void 0,void 0,(function*(){this.preInit(),Ae.clear(),yield this.prefetchAssets(),yield Promise.all(this.dataProvider.getObjects().map((e=>this.materialize(e)))),yield this.initActorsPostInit()}))}initActorsPostInit(t=this.actorInstances){const i=t.map((t=>e(this,void 0,void 0,(function*(){var e,i,r,a,s;const o=t.object.userData.src;if("vfx"===o.type)return Promise.resolve();const n=yield this.assetsService.getAsset(o.assetId),l=Object.assign(Object.assign({},null!==(i=null===(e=null==n?void 0:n.actor)||void 0===e?void 0:e.params)&&void 0!==i?i:{}),null!==(a=null===(r=o.actor)||void 0===r?void 0:r.params)&&void 0!==a?a:{});this.removeVfxChildActors(t);for(const e of null!==(s=o.actor.innerParams)&&void 0!==s?s:[])yield this.applyActorComponentParams(t,e.path.slice(),e.params);const c=yield Me(l,t.constructor,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders,this.actorProvider);Object.assign(t,c),this.addVfxChildActors(t);try{return yield this.actorProvider.initActor(t)}catch(e){console.error(`Failed to initiate actor (name="${o.name}", id=${o.id})`,e)}}))));return Promise.all(i)}addVfxChildActors(e,t=e){for(const i of Object.keys(t))t[i]instanceof ye?null!=t[i].actor&&(console.log("add actor to world",t[i].actor),e.object.add(t[i].actor.object)):t[i]instanceof me&&this.addVfxChildActors(e,t[i])}removeVfxChildActors(e,t=e){for(const i of Object.keys(t))if(t[i]instanceof ye){if(null!=t[i].actor){t[i].actor.onEndPlay(),console.log("remve actor from world",t[i].actor),e.object.remove(t[i].actor.object)}}else t[i]instanceof me&&this.removeVfxChildActors(e,t[i])}applyActorComponentParams(t,i,r){return e(this,void 0,void 0,(function*(){const e=i.length,a=i.shift();if(0==e){const e=yield Me(r,null,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders);for(const[i,r]of Object.entries(e))null!=r&&(t[i]=r)}else null!=t[a]&&(yield this.applyActorComponentParams(t[a],i,r))}))}canAssetBeInstanced(t){return e(this,void 0,void 0,(function*(){if(!this._canBeInstancedCache.has(t.assetId)){const e=yield this.createFromAsset(t);if(null==e)return!1;const i=[];e.traverse((e=>{!J(e)&&e.isMesh&&i.push(e)}));const r=1==i.length&&0==i[0].children.length,a=!0;this._canBeInstancedCache.set(t.assetId,r&&a)}return this._canBeInstancedCache.get(t.assetId)}))}preInit(){var e;null===(e=this.renderingView)||void 0===e||e.onLoop((()=>{var e;return null===(e=this.sky)||void 0===e?void 0:e.position.copy(this.renderingView.camera.position)}))}initWithInstancing(){return e(this,void 0,void 0,(function*(){this.preInit();const t=new L;for(const i of this.dataProvider.getObjects())yield De(i,((i,r,a)=>e(this,void 0,void 0,(function*(){var e,s;const o="asset_mesh"==i.type&&(yield this.canAssetBeInstanced(i))?i.assetId+JSON.stringify(null!==(e=i.materialAssignments)&&void 0!==e?e:[]):"other";"other"!==o&&r&&(null===(s=r.children)||void 0===s?void 0:s.length)>0&&r.children.splice(r.children.findIndex((e=>e.id===i.id)),1),"other"===o&&r||t.push(o,Object.assign(Object.assign({},i),{parentTransform:a}))}))));for(const[e,i]of t.entries())if("other"!==e&&i.length>0){const e=yield this.createFromAsset(i[0]);if(null==e)continue;const t=yield this.createInstancedMesh(i,e),r=new H;r.add(t),r.userData.src=i[0],e instanceof H&&(r.collisionShapes=e.collisionShapes),r.castShadow=!1,r.receiveShadow=!1,this.scene.add(r)}else yield Promise.all(i.map((e=>this.materialize(e))));yield this.initActorsPostInit()}))}createInstancedMesh(t,r){var a,o;return e(this,void 0,void 0,(function*(){const e=r.children.filter((e=>!J(e)))[0],n=yield this.assetsService.getAsset(t[0].assetId);yield this.applyMaterials(r,je(t[0].materialAssignments,n.materialAssignments)),e.updateMatrix();const l=e.geometry.clone().applyMatrix4(e.matrix),c=new i.InstancedMesh(l,e.material.clone(),t.length);c.material.side=i.FrontSide;for(let e=0;e<t.length;e++){const r=(new i.Matrix4).compose((new A).fromArray(t[e].position),(new v).setFromEuler((new s).fromArray(t[e].rotation)),(new A).fromArray(t[e].scale)),a=(new re).copy(t[e].parentTransform).multiply(r);c.setMatrixAt(e,a)}return c.castShadow=null===(a=n.castShadow)||void 0===a||a,c.receiveShadow=null===(o=n.receiveShadow)||void 0===o||o,c}))}remove(e){if(console.log("Remove scene object",e),"global_fog"==e.type)return void(this.scene.fog=this.originalFog);if("actor"==e.type){const t=this.materializedActors.get(e.id);null!=t&&(t.disposed.next(!0),t.onEndPlay(),this.removeVfxChildActors(t))}const t=this.sceneObjectMap.get(e.id);null==t||t.parent.remove(t),this.sceneObjectMap.delete(e.id),this.components.filter((t=>{var i;return(null===(i=t.object.userData.src)||void 0===i?void 0:i.id)===e.id})).forEach((e=>this.components.splice(this.components.indexOf(e,1)))),this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>{e.clear(),e.stop(),this.landscapeManagers.splice(this.landscapeManagers.indexOf(e,1))})),this.removed$.next({object:t,source:e})}deleteSceneObject(e){const t=this.sceneObjectMap.get(e.id);if(this.scene.remove(t),"landscape"==e.type){const t=this.landscapeManagers.findIndex((t=>t.source.id===e.id));if(t>-1){const e=this.landscapeManagers.splice(t,1)[0];e.clear(),e.stop()}}}findByAssetId(e){return U(this.scene,(t=>{var i;return(null===(i=t.userData.src)||void 0===i?void 0:i.assetId)==e}),(e=>null!=e.userData.src))}applyMaterials(e,t){return null==t?Promise.resolve([]):Promise.all(t.filter((e=>"null"!==e.materialId)).map((t=>this.applyMaterial(e,t))))}applyMaterial(t,i){const r=[];return t.traverse((t=>e(this,void 0,void 0,(function*(){if(t instanceof d||t.isMesh)for(const e of fe(t.material))e.hasOwnProperty("color")&&r.push(t)})))),Promise.all(r.map((t=>e(this,void 0,void 0,(function*(){var e,r,s,o;if(t.material instanceof Array)for(let s=0;s<t.material.length;s++){const o=t.material[s];if(null==o.color||!(o.color instanceof a))continue;const n="#"+o.color.getHexString(),l=o.name;if(n===i.color&&(o.name===i.name||null==i.name)||t.userData["originalColor_"+s]===i.color&&t.userData["originalMaterialName_"+s]===i.name){const a=yield this.assetsService.getAsset(i.materialId),o=t.material[s];a&&(t.material[s]=yield materialFromAsset(a,this.renderingView,this.assetsService,this.assetManagerService,this.shaders),t.userData["originalColor_"+s]=null!==(e=t.userData["originalColor_"+s])&&void 0!==e?e:n,t.userData["originalMaterialName_"+s]=null!==(r=t.userData["originalMaterialName_"+s])&&void 0!==r?r:l,this.inEditor&&this._originalMaterials.set(t.id+"#"+s,o))}}else{const e="#"+t.material.color.getHexString(),r=t.material.name;if(e===i.color&&(t.material.name===i.name||null==i.name)||t.userData.originalColor===i.color&&t.userData.originalName===i.name){const a=yield this.assetsService.getAsset(i.materialId),n=t.material;a&&(t.material=yield materialFromAsset(a,this.renderingView,this.assetsService,this.assetManagerService,this.shaders),t.userData.originalColor=null!==(s=t.userData.originalColor)&&void 0!==s?s:e,t.userData.originalMaterialName=null!==(o=t.userData.originalMaterialName)&&void 0!==o?o:r,this.inEditor&&this._originalMaterials.set(t.id,n))}}})))))}unapplyMaterials(t){t.traverse((t=>e(this,void 0,void 0,(function*(){var e,i;if(t instanceof d)if(t.material instanceof Array)for(let i=0;i<t.material.length;i++)t.material[i]=null!==(e=this._originalMaterials.get(t.id+"#"+i))&&void 0!==e?e:t.material[i];else t.material=null!==(i=this._originalMaterials.get(t.id))&&void 0!==i?i:t.material}))))}updateActors(t){this.actorTypes=t;const i=new Set(Object.values(_));U(this.scene,(e=>{var t,r;return(null===(t=e.userData.src)||void 0===t?void 0:t.id)&&"actor"===e.userData.src.type&&this.materializedActors.has(null===(r=e.userData.src)||void 0===r?void 0:r.id)&&!i.has(e.userData.src.actor.type)})).forEach((t=>e(this,void 0,void 0,(function*(){this.remove(t.userData.src),yield this.materializeAndInitActor(t.userData.src)}))))}updateShaders(e){this.shaders=e;for(const[e,t]of Ae.entries())t.userData.customShaderName&&Ae.delete(e);this.landscapeManagers.forEach((t=>t.updateShaders(e))),U(this.scene,(e=>!0)).forEach((e=>{e.traverse((e=>{var t,i;if(e instanceof d){if(null!=(null===(t=e.material.userData)||void 0===t?void 0:t.customShaderName)){const t=null===(i=function(e,t){if(t(e))return e;let i;return e.traverseAncestors((e=>{null==i&&t(e)&&(i=e)})),i}(e,(e=>{var t;return null!=(null===(t=e.userData.src)||void 0===t?void 0:t.id)})))||void 0===i?void 0:i.userData.src;null!=t&&this.update(t)}}}))}))}update(t){return e(this,void 0,void 0,(function*(){if("sky"===t.type&&null!=this.sky&&null!=this.sky.parent)return void this.updateSky(t);const e=this.sceneObjectMap.get(t.id);if(e){const r=this.findParent(t);if(null!=r&&r.uuid!=e.uuid?r.attach(e):console.error("Parent is wrong"),"prefab"!==t.type){this.unapplyMaterials(e);this.inEditor&&t.hidden&&!1?e.traverse((e=>{e instanceof d&&(e.material.wireframe=!0)})):e.traverse((e=>{e instanceof d&&(e.material.wireframe=!1)}))}if("asset_mesh"===t.type){const i=yield this.assetsService.getAsset(t.assetId);je(t.materialAssignments,i.materialAssignments).forEach((t=>this.applyMaterial(e,t)))}else"shape_mesh"===t.type&&this.applyMaterials(e,t.materialAssignments);let s=!1;if(e.traverseAncestors((e=>{"_hology_transform_group"===e.name&&(s=!0)})),s||(e.position.fromArray(t.position),e.scale.fromArray(t.scale),e.rotation.fromArray(t.rotation)),this.applyVertexMaterials(t,e),"light"==t.type)if("point"==t.light.type){const i=e;i.color=new a(t.light.point.color),i.intensity=t.light.point.intensity,i.decay=t.light.point.decay,i.castShadow=t.light.point.castShadow,i.distance=Math.max(t.light.point.distance,0)}else"directional"===t.light.type?this.applyDirectionalLight(t.light.directional):"ambient"===t.light.type&&this.applyDirectionalAmbientLight(e,t.light.ambient);else if("landscape"===t.shape)this.applyHeightMaps(e,t.landscape.heightMaps),this.inEditor&&this.landscapeManagers.filter((e=>e.source.id===t.id)).forEach((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>!0))));else if("global_fog"===t.type){const e=(this.scene.fog instanceof n?"density":"linear")!==t.fog.type;this.scene.fog=Ie(t.fog),e&&(i=this.scene).traverse((e=>{if(e instanceof d){const t=e.material;t instanceof j&&(i.fog instanceof o?(t.uniforms.fogFar.value=i.fog.far,t.uniforms.fogNear.value=i.fog.near):i.fog instanceof n&&(t.uniforms.density={value:i.fog.density}),t.needsUpdate=!0,t.uniformsNeedUpdate=!0)}})),this.fixFogColor()}else if("actor"===t.type){if(this.materializedActors.has(t.id)){const e=this.editorActorParamSnapshot.get(t.id);null!=e&&e===JSON.stringify(t.actor)||(console.log("Rematerializing actor because parameters changed"),this.remove(t),yield this.materializeAndInitActor(t))}}else if("shape_mesh"===t.type){const i=yield this.createMeshByShape(t.shape,e.material,t.shapeParams);e instanceof G&&(e.geometry=i.geometry,e.collisionShape=i.collisionShape)}("asset_mesh"===t.type||"shape_mesh"===t.type&&"landscape"!==t.shape)&&we(e,t.castShadow,t.receiveShadow),t.name&&t.name.length>0&&(e.name=t.name),this.updated$.next({object:e,source:t})}else{const e=yield this.materializeAndInitActor(t);this.updated$.next({object:e,source:t})}var i}))}materializeAndInitActor(t,i=this.findParent(t)){return e(this,void 0,void 0,(function*(){const r=yield this.materialize(t,i);return De(t,(t=>e(this,void 0,void 0,(function*(){if("actor"===t.type){const e=this.materializedActors.get(t.id);null!=e?yield this.initActorsPostInit([e]):console.error(`Something went wrong when creating actor ${t.id}`)}})))),r}))}findParent(e){const t=this.dataProvider.getObjects().flatMap((t=>t.id===e.id?null:R(t,(t=>{var i;return null===(i=t.children)||void 0===i?void 0:i.some((t=>t.id===e.id))}),(()=>!0))))[0];return null==t?this.scene:null!=t?U(this.scene,(e=>{var i,r;return(null===(r=null===(i=e.userData)||void 0===i?void 0:i.src)||void 0===r?void 0:r.id)===t.id}),(e=>{var t;return null!=(null===(t=e.userData)||void 0===t?void 0:t.src)}))[0]:void 0}fixFogColor(){!0===this.renderingView.options.enableOutlines&&(this.scene.fog.color=new a(this.scene.fog.color).convertSRGBToLinear())}findMeshWithGeometry(e){let t;return e.traverse((e=>{e instanceof d&&e.geometry&&(t=e)})),t}applyVertexMaterials(e,t){if(null==e.vertexMaterials||0===e.vertexMaterials.length)return;const i=$(e.vertexMaterials,(e=>e.m));t.traverse((e=>{if(e instanceof d){const t=ee(e,!1);if(null!=t){for(let e=0;e<t.array.length;e++)t.setX(e,0);t.needsUpdate=!0}}}));const r=new Set;for(const[e,a]of i.entries()){const i=null!=e?t.getObjectByName(e):this.findMeshWithGeometry(t);let s=!1;if(null==i)return void console.warn(`Failed to apply vertex materials on mesh with name "${e}"`);const o=ee(i,!0);for(let e=0;e<o.array.length;e++)o.setX(e,0);for(const e of a)o.setX(e.i,e.w[0]),o.setY(e.i,e.w[1]),o.setZ(e.i,e.w[2]),s=!0;s&&r.add(e)}this.inEditor&&this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>r.has(e.name)))))}materialize(t,i,a=!1){var s,o,n,c;return e(this,void 0,void 0,(function*(){let e;switch(t.type){case"asset_mesh":e=yield this.createFromAsset(t);break;case"shape_mesh":e=yield this.createFromShape(t);break;case"light":e=yield this.createLight(t);break;case"particles":e=yield this.createParticleSystem(t),t.collisionDetection=!1;break;case"global_fog":this.scene.fog=Ie(t.fog),this.fixFogColor(),e=new l;break;case"sky":this.sky=he(),this.updateSky(t),e=this.sky;break;case"actor":e=yield this.createFromActor(t);break;case"group":e=new l;break;case"prefab":e=yield this.createFromPrefabAsset(t);break;case"vfx":e=yield this.createFromVfx(t);break;default:if(this.inEditor)throw new Error("unknown type "+t.type);console.warn(`Failed to materialize object. Unknown type '${t.type}'. This might be because the hology/core library is not compatible with the editor version.`)}if(null!=e){if(t.name&&t.name.length>0&&(e.name=t.name),e.position.fromArray(t.position),e.scale.fromArray(t.scale),e.rotation.fromArray(t.rotation),a||(e.userData.src=t),!this.inEditor){const i=null!==(s=t.components)&&void 0!==s?s:[],r=null!=t.assetId&&null!==(n=null===(o=yield this.assetsService.getAsset(t.assetId))||void 0===o?void 0:o.components)&&void 0!==n?n:[];i.push(...r),i.length>0?e.userData.componentRefs=yield Promise.all(i.map(((i,r)=>this.createComponent(e,t,i,r)))):"asset_mesh"==t.type&&function(e){e.traverse((e=>{e.matrixAutoUpdate=!1,e.matrixWorldNeedsUpdate=!1}));const t=e.updateMatrixWorld;e.updateMatrixWorld=function(){t.apply(e),e.updateMatrixWorld=function(){}}}(e)}if(this.inEditor){let t=null;e instanceof G&&(t=function(e){if(e instanceof W)return new d(new r(...e.offset.toArray()),Pe);return null}(e.collisionShape)),null!=t&&(t.layers.disable(0),t.layers.enable(18),t.scale.multiplyScalar(1.1),e.add(t))}return this.objectMap.set(e.uuid,t),this.sceneObjectMap.set(t.id,e),null==i?this.scene.add(e):null==i||i.add(e),null!=t.children&&(yield Promise.all(null===(c=t.children)||void 0===c?void 0:c.map((t=>this.materialize(t,e,a))))),e}}))}updateSky(t){var r;return e(this,void 0,void 0,(function*(){if(null==(null===(r=null==t?void 0:t.sky)||void 0===r?void 0:r.materialId))return void(this.sky.material=ue);const e=yield this.assetsService.getAsset(t.sky.materialId),a=yield materialFromAsset(e,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!1);a.side=i.BackSide,null!=this.sky?this.sky.material=a:console.warn("No sky has been created")}))}createComponent(t,i,r,a){return e(this,void 0,void 0,(function*(){const e=new ge[r.path+"/"+r.className],s=i.id+a;e.id=s,e.object=t;for(const t of r.params)null!=t.value&&(e[t.name]=t.value);return this.components.push(e),s}))}createFromActor(t){var i,r,a;return e(this,void 0,void 0,(function*(){const e=null!==(r=null===(i=this.actorTypes.find((e=>{var i;return e.name===(null===(i=t.actor)||void 0===i?void 0:i.type)})))||void 0===i?void 0:i.type)&&void 0!==r?r:_[null===(a=t.actor)||void 0===a?void 0:a.type];if(null==e)return null;this.inEditor&&this.editorActorParamSnapshot.set(t.id,JSON.stringify(t.actor));const o=yield this.actorProvider.create(e,(new A).fromArray(t.position),(new s).fromArray(t.rotation),!0);return this.materializedActors.set(t.id,o),null==o?void 0:o.object}))}createFromVfx(t){return e(this,void 0,void 0,(function*(){const e=yield this.assetsService.getAsset(t.assetId);null==e&&console.error("Could not find asset",t);const i=ve,r=yield this.actorProvider.create(i,(new A).fromArray(t.position),(new s).fromArray(t.rotation),!1);return yield r.fromAsset(e),r.play(),this.materializedActors.set(t.id,r),null==r?void 0:r.object}))}cleanup(){this.materializedActors.clear()}createFromShape(t){var i,r,s;return e(this,void 0,void 0,(function*(){const e=this.inEditor&&t.hidden;let o;if("landscape"==t.shape)o=this.createLandscape(t);else{let s=new m({name:"Default",color:new a("#aaaaaa"),visible:this.inEditor||!t.hidden,wireframe:!!e});const n=yield this.createMeshByShape(t.shape,s,t.shapeParams);n.castShadow=null===(i=t.castShadow)||void 0===i||i,n.receiveShadow=null!==(r=t.castShadow)&&void 0!==r&&r,t.collisionDetection||(n.collisionShape=null),o=n,this._originalMaterials.set(o.id,n.material),o.traverse((e=>{}))}return e||((null!==(s=t.materialAssignments)&&void 0!==s?s:[]).filter((e=>null!=e.materialId)).forEach((e=>this.applyMaterial(o,e))),this.applyVertexMaterials(t,o)),o}))}createLandscape(e){var t;if(null==(null===(t=e.landscape)||void 0===t?void 0:t.options))return console.error(`No landscape options exist on scene object ${e.id} ${e.name}`),new l;const i=X(e.landscape.options);this.applyHeightMaps(i,e.landscape.heightMaps,!0);const r=new Y(e,this.renderingView,i,this.assetManagerService,this.assetsService,this.shaders,(t=>{var i;(null!==(i=e.materialAssignments)&&void 0!==i?i:[]).filter((e=>null!=e.materialId)).forEach((e=>this.applyMaterial(t,e)))}));return this.landscapeManagers.push(r),r.refreshGeometry(),i}applyHeightMaps(e,t,i=!1){const r=new q(e.sections);for(const e of null!=t?t:[]){const t=r.find(e.x,e.y);if(!t)return;const i=t.geometry.getAttribute("position");for(const t of e.points)i.setY(t.i,t.y);i.needsUpdate=!0}const a=e.sections;a.forEach((e=>{e.geometry.computeBoundsTree(),e.geometry.computeVertexNormals()})),this.inEditor&&!i||setTimeout((()=>Z(a)),50)}createMeshByShape(t,i,r={}){return e(this,void 0,void 0,(function*(){if("landscape"!==t&&ce.includes(t)){const e=yield prepareShapeParameters(null!=r?r:{});return"cylinder"==t&&e.openEnded,new G(le[t].geometry(e),i,le[t].collision(e))}if(this.inEditor)throw new Error(`Unsupported shape '${t}'`);console.warn(`Failed to create shape. Unsupported shape '${t}'. This might be because the hology/core library is not compatible with the editor version.`)}))}createFromAsset(t){var i,r,a,s;return e(this,void 0,void 0,(function*(){const e=yield this.assetsService.getAsset(t.assetId);if(null==e)return void console.warn(`Can not find asset with id ${t.assetId} and name ${t.name}`);let{scene:o}=yield this.assetManagerService.getMesh(e);je(t.materialAssignments,e.materialAssignments).forEach((e=>this.applyMaterial(o,e)));const n=null===(r=null!==(i=t.receiveShadow)&&void 0!==i?i:!!e.receiveShadow)||void 0===r||r,l=null!==(s=null!==(a=t.castShadow)&&void 0!==a?a:!!e.castShadow)&&void 0!==s&&s;return o.receiveShadow=n,we(o,l,n),t.collisionDetection||(o.collisionShapes=[]),this.applyVertexMaterials(t,o),o.traverse((e=>{e instanceof d&&"computeBoundsTree"in e.geometry&&e.geometry.computeBoundsTree()})),o}))}createFromPrefabAsset(t){return e(this,void 0,void 0,(function*(){const e=yield this.assetsService.getAsset(t.assetId);if(null==e)return void console.warn(`Can not find asset with id ${t.assetId} and name ${t.name}`);const i=new l;return e.prefab.objects.filter((e=>"global_fog"!==e.type)).forEach((e=>this.materialize(e,i,!0))),i}))}createParticleSystem(t){return e(this,void 0,void 0,(function*(){const e=yield this.assetsService.getAsset(t.assetId),r=new p;return yield S.fromJSONAsync(e.particleSystem,i).then((e=>{const t=new M(r,i);e.addRenderer(t),this.renderingView.onLoop((t=>e.update()))})),r}))}createLight(t){var i;return e(this,void 0,void 0,(function*(){if("point"===t.light.type){const e=new f(t.light.point.color,t.light.point.intensity,t.light.point.distance,t.light.point.decay);if(e.castShadow=null===(i=t.light.point.castShadow)||void 0===i||i,this.inEditor){const t=new y(.3,10,10),i=new m({color:new a(16771709)}),r=new d(t,i);e.add(r)}return e}return"directional"===t.light.type?(this.applyDirectionalLight(t.light.directional),new l):"ambient"===t.light.type?(this.applyDirectionalAmbientLight(null,t.light.ambient),new l):void 0}))}applyDirectionalAmbientLight(e,t){const i=this.scene.children.find((e=>e.name===de));null!=i?(i.intensity=t.intensity,i.color.set(t.color),i.groundColor.set(t.color)):console.warn("Couldn't find ambient light")}applyDirectionalLight(e){for(const t of this.renderingView.csm.lights)t.intensity=e.intensity,t.color.set(e.color),t.castShadow=e.castShadow;this.renderingView.csm.lightDirection.fromArray(e.direction).normalize()}dispose(){this.updateSubscription.unsubscribe()}}function we(e,t,i){e.castShadow=t,e.receiveShadow=i,e.traverse((e=>{e.castShadow=t,e.receiveShadow=i}))}const Ae=new Map,be=new h({color:16711935}),Se=new Map;export function materialFromAsset(t,r,s,o,n,l=!0){var c,d,h,m,p,f,v,y,g,w,A;return e(this,void 0,void 0,(function*(){const e=JSON.stringify(t.material);if(l&&Ae.has(e))return Ae.get(e);const b={opacity:t.material.params.opacity,map:null,emissive:null!==(c=t.material.params.emissive)&&void 0!==c?c:null,metalness:null!==(d=t.material.params.metalness)&&void 0!==d?d:0,flatShading:null!==(h=t.material.params.flatShading)&&void 0!==h&&h,color:new a(t.material.params.color).convertSRGBToLinear(),transparent:null!=t.material.params.opacity&&t.material.params.opacity<1},S={};if(null!=t.material.params.map){const e=t.material.params.map,i=yield s.getAsset(e);null!=i&&(b.map=yield o.getTexture(i))}let M;switch(t.material.type){case"phong":M=new u(Object.assign(Object.assign({},b),S));break;case"water":M=te(b,r);break;case"grassFoliage":M=Q({color:b.color,map:b.map},r);break;case"grass":M=K(Object.assign(Object.assign({},b),{colorTwo:new a(t.material.params.colorTwo),colorThree:new a(t.material.params.colorThree)}),r);break;case"standard":case"lambert":case"shader":const e=null!==(m={standard:oe,lambert:ne}[t.material.type])&&void 0!==m?m:null===(p=n.find((e=>e.name==t.material.shader)))||void 0===p?void 0:p.type;if(e){const i=new e,a=yield Me(null!==(v=null===(f=t.material)||void 0===f?void 0:f.shaderParams)&&void 0!==v?v:{},e,s,o,null,r,n);Object.assign(i,a);try{M=i.build()}catch(e){console.log("Shader runtime error: "+e),Se.has(t.material.shader)||Se.set(t.material.shader,be.clone()),M=Se.get(t.material.shader)}M.userData.customShaderName=t.material.shader}else console.warn("Missing shader implementation with name "+t.material.shader),M=be;break;default:throw new Error("Unsupported material type"+t.material.type)}return null==r||r.csm.setupMaterial(M),l&&Ae.set(e,M),M.side=null!==(g=null!==(y=t.material.side)&&void 0!==y?y:M.side)&&void 0!==g?g:i.FrontSide,M.transparent=null!==(A=null!==(w=t.material.transparent)&&void 0!==w?w:b.transparent)&&void 0!==A&&A||M.transparent,t.material.bloom&&(M.userData.hasBloom=!0),M}))}function Me(t,i,r,a,s,o,n,l){return e(this,void 0,void 0,(function*(){const e={};for(const[i,c]of Object.entries(t)){const t=yield xe(c,r,a,s,o,n,l);null!=t&&(e[i]=t)}return e}))}export function prepareShapeParameters(t){return e(this,void 0,void 0,(function*(){const e={};for(const[i,r]of Object.entries(t)){const t=yield xe(r,null,null,null);null!=t&&(e[i]=t)}return e}))}function xe(t,i,r,o,n,l,c){return e(this,void 0,void 0,(function*(){if(null==t||null==t.value||""==t.value)return null;const e=t.value;switch(t.type){case ie.Number:case ie.FloatNode:let d="string"==typeof e?parseFloat(e):e;return t.type===ie.FloatNode?P(d):d;case ie.Texture:return yield r.getTexture(yield i.getAsset(e));case ie.Sampler2DNode:return C(yield r.getTexture(yield i.getAsset(e)));case ie.Boolean:return e;case ie.BooleanNode:return x(e);case ie.Vector2:case ie.Vec2Node:if("object"==typeof e){const i=e instanceof Array?(new w).fromArray(e):new w(e.x,e.y);return t.type===ie.Vec2Node?O(i):i}return null;case ie.Vector3:case ie.Vec3Node:if("object"==typeof e){const i=e instanceof Array?(new A).fromArray(e):new A(e.x,e.y,e.z);return t.type===ie.Vec3Node?k(i):i}return null;case ie.Color:case ie.RgbNode:const h=new a(e).convertSRGBToLinear();return t.type===ie.RgbNode?V(h):h;case ie.String:return e;case ie.BaseActor:const u=e;return null==o&&console.warn("Class parameters can not be prepared as actors are not passed in"),null==o?void 0:o.get(u);case ie.Euler:const m=e;return(new s).fromArray(m);case ie.Object3D:return(yield r.getMesh(yield i.getAsset(e))).scene;case ie.Material:return yield materialFromAsset(yield i.getAsset(e),n,i,r,l);case ie.AudioBuffer:return yield r.getAudio(yield i.getAsset(e));case ie.VisualEffect:const p=yield i.getAsset(e);if(null==c){console.error("Can not create instance of visual effect because missing actor provider");break}if("vfx"in p){const e=yield c.create(ve);return yield e.fromAsset(p),new ye(e)}console.error("Using a non-vfx asset for visual effect parameter")}return null}))}function Ie(e){var t,i;return"linear"===e.type?new o(new a(e.color),null!==(t=e.near)&&void 0!==t?t:100,null!==(i=e.far)&&void 0!==i?i:1e3):"density"===e.type?new n(e.color,e.density):void console.warn("Invalid fog type",e)}const Pe=new m({color:4229780});function De(t,r,a,o){var n;return e(this,void 0,void 0,(function*(){null==o&&(o=(new re).identity()),yield r(t,a,o);const e=o.clone().multiply(function(e,t){return t.compose((new A).fromArray(e.position),(new v).setFromEuler((new s).fromArray(e.rotation)),(new A).fromArray(e.scale))}(t,new i.Matrix4));return Promise.all((null!==(n=t.children)&&void 0!==n?n:[]).map((i=>De(i,r,t,e))))}))}export function toSerializedParamType(e){const t=e.constructor.prototype;return t instanceof Number||e===Number?ie.Number:t instanceof D||"function"==typeof e.prototype.isFloat?ie.FloatNode:t instanceof g||e===g||e.isTexture?ie.Texture:t instanceof se||e===N?ie.Sampler2DNode:t instanceof Boolean||e===Boolean?ie.Boolean:t instanceof I?ie.BooleanNode:t instanceof a||e==a?ie.Color:t instanceof E||"function"==typeof e.prototype.isRgb?ie.RgbNode:t instanceof w||e==w?ie.Vector2:t instanceof F||"function"==typeof e.prototype.isVec2?ie.Vec2Node:t instanceof A||e==A?ie.Vector3:t instanceof z||"function"==typeof e.prototype.isVec3?ie.Vec3Node:t instanceof String||e===String?ie.String:t instanceof ae||e==ae||e.prototype instanceof ae||e.prototype==ae?ie.BaseActor:t instanceof s||e==s?ie.Euler:t instanceof p||e==p?ie.Object3D:t instanceof c||e==c?ie.Material:t instanceof AudioBuffer||e==AudioBuffer?ie.AudioBuffer:t instanceof ye||e==ye?ie.VisualEffect:void console.warn("Failed to map parameter type to serialized version",{type:e})}export function prepareCustomParams(e,t,i={}){return Object.fromEntries(e.map((e=>{var r,a,s;return[e.name,{type:toSerializedParamType(e.type),value:null!==(s=null!==(a=null===(r=t[e.name])||void 0===r?void 0:r.value)&&void 0!==a?a:i[e.name])&&void 0!==s?s:customParameterDefaultValueByType.get(toSerializedParamType(e.type))}]})))}export function prepareCustomParamsFromType(e,t,i=null){const r=T(e);if(0===r.length)return{};let a;null!=i?pe(i,(()=>{a=i.get(e)})):a=new e;const s={};for(const e of r){const t=a[e.name];if(null!=t){const i=serializeCustomParameter(e.type,t);null!=i&&(s[e.name]=i)}}return prepareCustomParams(r,t,s)}export function serializeCustomParameter(e,t){function i(){console.error("Failed to serialize value",{type:e,value:t})}switch(e){case Number:case Boolean:return t;case w:return t instanceof w?t.toArray():void i();case A:return t instanceof A?t.toArray():void i();case b:return t instanceof b?t.toArray():void i();case a:return t instanceof a?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new a(t).getHexString():void i();case String:return t;case s:return t instanceof s?t.toArray():void i()}}function je(e,t){return function(e,t,i){const r=[],a=new Set;for(const s of[...null!=e?e:[],...null!=t?t:[]]){const e=i(s);a.has(e)||(a.add(e),r.push(s))}return r}((null!=e?e:[]).filter((e=>Ve(e.materialId))),(null!=t?t:[]).filter((e=>Ve(e.materialId))),(e=>e.color+e.name))}function Ve(e){return"null"!=e&&null!=e}export const customParameterDefaultValueByType=new Map([[ie.RgbNode,"#000000"],[ie.Color,"#000000"],[ie.Vector4,[0,0,0,0]],[ie.Vec4Node,[0,0,0,0]],[ie.Vector3,[0,0,0]],[ie.Vec3Node,[0,0,0]],[ie.Vector2,[0,0]],[ie.Vec2Node,[0,0]],[ie.Euler,[0,0,0,"XYZ"]]]);
|
1
|
+
import{Subject as e}from"rxjs";import*as t from"three";import{BoxGeometry as a,Color as s,Euler as r,Fog as i,FogExp2 as n,Group as o,Material as c,Mesh as l,MeshLambertMaterial as h,MeshPhongMaterial as m,MeshStandardMaterial as d,Object3D as p,PointLight as f,Quaternion as u,SphereGeometry as g,Texture as y,Vector2 as w,Vector3 as A,Vector4 as v}from"three";import S,{SpriteRenderer as b}from"three-nebula";import{bool as M,BooleanNode as x,float as j,FloatNode as I,NodeShaderMaterial as P,rgb as D,RgbNode as V,Texture2dLookupNode as E,textureSampler2d as N,vec2 as C,Vec2Node as F,vec3 as k,Vec3Node as z,vec4 as B}from"three-shader-graph";import O from"../gameplay/actors/builtin/index.js";import{extractShaderParameters as _}from"../shader/parameter.js";import{groupBy as T,ArrayMap as $}from"../utils/collections.js";import{filterChildrenShallow as L,filterSceneShallow as R}from"../utils/three/traverse.js";import{AssetMeshInstance as U}from"./asset-resource-loader.js";import{BoxCollisionShape as H,PhysicalShapeMesh as W}from"./collision/collision-shape.js";import{isCollisionMesh as G}from"./collision/collision-shape-import.js";import{initLandscape as J}from"./landscape/landscape.js";import{LandscapeManager as X}from"./landscape/landscape-manager.js";import{SectionGrid as Y,smoothNormalsCrossMeshes as q}from"./landscape/utils.js";import{createGrassMaterial as Z}from"./materials/grass.js";import{createGrassFoliageMaterial as K}from"./materials/grass-foliage.js";import{getMaterialAttribute as Q}from"./materials/utils/material-painting.js";import{createWaterMaterial as ee}from"./materials/water.js";import{SerializedParamType as te}from"./model.js";import{Matrix4 as ae}from"three";import{BaseActor as se}from"../gameplay/actors/actor.js";import{Sampler2DNode as re}from"../shader-nodes/index.js";import{StandardShader as ie}from"../shader/builtin/standard-shader.js";import{LambertShader as ne}from"../shader/builtin/lambert-shader.js";import{ShapeLibrary as oe,ShapeLibraryKeys as ce}from"./objects/shapes.js";import{ambientLightName as le,createSky as he,defaultSkyMaterial as me}from"./sky.js";import{ActorComponent as de,withInjectionContext as pe}from"../gameplay/index.js";import{iterateMaterials as fe}from"../utils/materials.js";import{VfxActor as ue}from"../effects/vfx/vfx-actor.js";import{VisualEffect as ge}from"../effects/vfx/vfx-param.js";const ye={};export const shapeDefaultColor="#aaaaaa";export class SceneMaterializerLoader{constructor(e,t,a){this.dataProvider=e,this.assetsService=t,this.assetManagerService=a}get(e,t){return new SceneMaterializer(e,this.dataProvider,this.assetsService,this.assetManagerService,t,[],[],{create:()=>null,initActor:async()=>{}})}}export class SceneMaterializer{constructor(t,a,s,r,i,n,o,c){this.scene=t,this.dataProvider=a,this.assetsService=s,this.assetManagerService=r,this.renderingView=i,this.shaders=n,this.actorTypes=o,this.actorProvider=c,this.objectMap=new Map,this.sceneObjectMap=new Map,this.components=[],this.landscapeManagers=[],this.materializedActors=new Map,this.inEditor=!0,this.updated$=new e,this.removed$=new e,this.error$=new e,this.editorActorParamSnapshot=new Map,this._canBeInstancedCache=new Map,this._originalMaterials=new Map,this.originalFog=null,a.onUpdate((e=>this.update(e))),a.onRemove((e=>this.remove(e))),this.updateSubscription=s.onUpdate.subscribe((async e=>{"material"==e.type?((await this.assetsService.getAssets()).filter((t=>(t.materialAssignments??[]).some((t=>t.materialId===e.id)))).forEach((e=>{const t=this.findByAssetId(e.id);e.materialAssignments.forEach((e=>{t.forEach((t=>{const a=t.userData.src.materialAssignments;null!=a&&a.some((t=>t.color===e.color))||this.applyMaterial(t,e)}))}))})),R(this.scene,(t=>null!=t.userData.src&&(t.userData.src.materialAssignments??[]).some((t=>t.materialId===e.id))),(e=>null!=e.userData.src)).forEach((async e=>{this.deleteSceneObject(e.userData.src),this.materialize(e.userData.src)}))):"mesh"==e.type?this.findByAssetId(e.id).forEach((t=>{Pe(t.userData.src.materialAssignments,e.materialAssignments).forEach((e=>{this.applyMaterial(t,e)}))})):"prefab"===e.type&&this.findByAssetId(e.id).forEach((e=>{const t=e.userData.src;this.remove(t),this.materializeAndInitActor(t)}))}))}get actorInstances(){return Array.from(this.materializedActors.values())}async prefetchAssets(){const e=Array.from(new Set(this.dataProvider.getObjects().filter((e=>null!=e.assetId&&"asset_mesh"==e.type)).filter((e=>e.assetId))));await Promise.all(e.map((e=>this.assetsService.getAsset(e.assetId).then((e=>e&&this.assetManagerService.getMesh(e))))))}async init(){this.preInit(),Ae.clear(),await this.prefetchAssets(),await Promise.all(this.dataProvider.getObjects().map((e=>this.materialize(e)))),await this.initActorsPostInit()}initActorsPostInit(e=this.actorInstances){const t=e.map((async e=>{const t=e.object.userData.src;if("vfx"===t.type)return Promise.resolve();const a=await this.assetsService.getAsset(t.assetId),s={...a?.actor?.params??{},...t.actor?.params??{}};this.removeVfxChildActors(e);for(const a of t.actor.innerParams??[])await this.applyActorComponentParams(e,a.path.slice(),a.params);const r=await be(s,e.constructor,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders,this.actorProvider);Object.assign(e,r),this.addVfxChildActors(e);try{return await this.actorProvider.initActor(e)}catch(e){console.error(`Failed to initiate actor (name="${t.name}", id=${t.id})`,e)}}));return Promise.all(t)}addVfxChildActors(e,t=e){for(const a of Object.keys(t))t[a]instanceof ge?null!=t[a].actor&&(console.log("add actor to world",t[a].actor),e.object.add(t[a].actor.object)):t[a]instanceof de&&this.addVfxChildActors(e,t[a])}removeVfxChildActors(e,t=e){for(const a of Object.keys(t))if(t[a]instanceof ge){if(null!=t[a].actor){t[a].actor.onEndPlay(),console.log("remve actor from world",t[a].actor),e.object.remove(t[a].actor.object)}}else t[a]instanceof de&&this.removeVfxChildActors(e,t[a])}async applyActorComponentParams(e,t,a){const s=t.length,r=t.shift();if(0==s){const t=await be(a,null,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders);for(const[a,s]of Object.entries(t))null!=s&&(e[a]=s)}else null!=e[r]&&await this.applyActorComponentParams(e[r],t,a)}async canAssetBeInstanced(e){if(!this._canBeInstancedCache.has(e.assetId)){const t=await this.createFromAsset(e);if(null==t)return!1;const a=[];t.traverse((e=>{!G(e)&&e.isMesh&&a.push(e)}));const s=1==a.length&&0==a[0].children.length,r=!0;this._canBeInstancedCache.set(e.assetId,s&&r)}return this._canBeInstancedCache.get(e.assetId)}preInit(){this.renderingView?.onLoop((()=>this.sky?.position.copy(this.renderingView.camera.position)))}async initWithInstancing(){this.preInit();const e=new $;for(const t of this.dataProvider.getObjects())await Ie(t,(async(t,a,s)=>{const r="asset_mesh"==t.type&&await this.canAssetBeInstanced(t)?t.assetId+JSON.stringify(t.materialAssignments??[]):"other";"other"!==r&&a&&a.children?.length>0&&a.children.splice(a.children.findIndex((e=>e.id===t.id)),1),"other"===r&&a||e.push(r,{...t,parentTransform:s})}));for(const[t,a]of e.entries())if("other"!==t&&a.length>0){const e=await this.createFromAsset(a[0]);if(null==e)continue;const t=await this.createInstancedMesh(a,e),s=new U;s.add(t),s.userData.src=a[0],e instanceof U&&(s.collisionShapes=e.collisionShapes),s.castShadow=!1,s.receiveShadow=!1,this.scene.add(s)}else await Promise.all(a.map((e=>this.materialize(e))));await this.initActorsPostInit()}async createInstancedMesh(e,a){const s=a.children.filter((e=>!G(e)))[0],i=await this.assetsService.getAsset(e[0].assetId);await this.applyMaterials(a,Pe(e[0].materialAssignments,i.materialAssignments)),s.updateMatrix();const n=s.geometry.clone().applyMatrix4(s.matrix),o=new t.InstancedMesh(n,s.material.clone(),e.length);o.material.side=t.FrontSide;for(let a=0;a<e.length;a++){const s=(new t.Matrix4).compose((new A).fromArray(e[a].position),(new u).setFromEuler((new r).fromArray(e[a].rotation)),(new A).fromArray(e[a].scale)),i=(new ae).copy(e[a].parentTransform).multiply(s);o.setMatrixAt(a,i)}return o.castShadow=i.castShadow??!0,o.receiveShadow=i.receiveShadow??!0,o}remove(e){if(console.log("Remove scene object",e),"global_fog"==e.type)return void(this.scene.fog=this.originalFog);if("actor"==e.type){const t=this.materializedActors.get(e.id);null!=t?(t.disposed.next(!0),t.onEndPlay(),this.removeVfxChildActors(t)):console.warn("Failed to remove actor",e)}const t=this.sceneObjectMap.get(e.id);t?.parent.remove(t),this.sceneObjectMap.delete(e.id),this.components.filter((t=>t.object.userData.src?.id===e.id)).forEach((e=>this.components.splice(this.components.indexOf(e,1)))),this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>{e.clear(),e.stop(),this.landscapeManagers.splice(this.landscapeManagers.indexOf(e,1))})),this.removed$.next({object:t,source:e})}deleteSceneObject(e){const t=this.sceneObjectMap.get(e.id);if(this.scene.remove(t),"landscape"==e.type){const t=this.landscapeManagers.findIndex((t=>t.source.id===e.id));if(t>-1){const e=this.landscapeManagers.splice(t,1)[0];e.clear(),e.stop()}}}findByAssetId(e){return R(this.scene,(t=>t.userData.src?.assetId==e),(e=>null!=e.userData.src))}applyMaterials(e,t){return null==t?Promise.resolve([]):Promise.all(t.filter((e=>"null"!==e.materialId)).map((t=>this.applyMaterial(e,t))))}applyMaterial(e,t){const a=[];return e.traverse((async e=>{if(e instanceof l||e.isMesh)for(const t of fe(e.material))t.hasOwnProperty("color")&&a.push(e)})),Promise.all(a.map((async e=>{if(e.material instanceof Array)for(let a=0;a<e.material.length;a++){const r=e.material[a];if(null==r.color||!(r.color instanceof s))continue;const i="#"+r.color.getHexString(),n=r.name;if(i===t.color&&(r.name===t.name||null==t.name)||e.userData["originalColor_"+a]===t.color&&e.userData["originalMaterialName_"+a]===t.name){const s=await this.assetsService.getAsset(t.materialId),r=e.material[a];s&&(e.material[a]=await materialFromAsset(s,this.renderingView,this.assetsService,this.assetManagerService,this.shaders),e.userData["originalColor_"+a]=e.userData["originalColor_"+a]??i,e.userData["originalMaterialName_"+a]=e.userData["originalMaterialName_"+a]??n,this.inEditor&&this._originalMaterials.set(e.id+"#"+a,r))}}else{const a="#"+e.material.color.getHexString(),s=e.material.name;if(a===t.color&&(e.material.name===t.name||null==t.name)||e.userData.originalColor===t.color&&e.userData.originalName===t.name){const r=await this.assetsService.getAsset(t.materialId),i=e.material;r&&(e.material=await materialFromAsset(r,this.renderingView,this.assetsService,this.assetManagerService,this.shaders),e.userData.originalColor=e.userData.originalColor??a,e.userData.originalMaterialName=e.userData.originalMaterialName??s,this.inEditor&&this._originalMaterials.set(e.id,i))}}})))}unapplyMaterials(e){e.traverse((async e=>{if(e instanceof l)if(e.material instanceof Array)for(let t=0;t<e.material.length;t++)e.material[t]=this._originalMaterials.get(e.id+"#"+t)??e.material[t];else e.material=this._originalMaterials.get(e.id)??e.material}))}updateActors(e){this.actorTypes=e;const t=new Set(Object.values(O));R(this.scene,(e=>e.userData.src?.id&&"actor"===e.userData.src.type&&this.materializedActors.has(e.userData.src?.id)&&!t.has(e.userData.src.actor.type))).forEach((async e=>{this.remove(e.userData.src),await this.materializeAndInitActor(e.userData.src)}))}updateShaders(e){this.shaders=e;for(const[e,t]of Ae.entries())t.userData.customShaderName&&Ae.delete(e);this.landscapeManagers.forEach((t=>t.updateShaders(e))),R(this.scene,(e=>!0)).forEach((e=>{e.traverse((e=>{if(e instanceof l){const t=e.material.userData?.customShaderName;if(null!=t){const t=function(e,t){if(t(e))return e;let a;return e.traverseAncestors((e=>{null==a&&t(e)&&(a=e)})),a}(e,(e=>null!=e.userData.src?.id))?.userData.src;null!=t&&this.update(t)}}}))}))}async update(e){if("sky"===e.type&&null!=this.sky&&null!=this.sky.parent)return void this.updateSky(e);const t=this.sceneObjectMap.get(e.id);if(t){const r=this.findParent(e);if(null!=r&&r.uuid!=t.uuid?r.attach(t):console.error("Parent is wrong"),"prefab"!==e.type){this.unapplyMaterials(t);this.inEditor&&e.hidden&&!1?t.traverse((e=>{e instanceof l&&(e.material.wireframe=!0)})):t.traverse((e=>{e instanceof l&&(e.material.wireframe=!1)}))}if("asset_mesh"===e.type){const a=await this.assetsService.getAsset(e.assetId);Pe(e.materialAssignments,a.materialAssignments).forEach((e=>this.applyMaterial(t,e)))}else"shape_mesh"===e.type&&this.applyMaterials(t,e.materialAssignments);let o=!1;if(t.traverseAncestors((e=>{"_hology_transform_group"===e.name&&(o=!0)})),o||(t.position.fromArray(e.position),t.scale.fromArray(e.scale),t.rotation.fromArray(e.rotation)),this.applyVertexMaterials(e,t),"light"==e.type)if("point"==e.light.type){const a=t;a.color=new s(e.light.point.color),a.intensity=e.light.point.intensity,a.decay=e.light.point.decay,a.castShadow=e.light.point.castShadow,a.distance=Math.max(e.light.point.distance,0)}else"directional"===e.light.type?this.applyDirectionalLight(e.light.directional):"ambient"===e.light.type&&this.applyDirectionalAmbientLight(t,e.light.ambient);else if("landscape"===e.shape)this.applyHeightMaps(t,e.landscape.heightMaps),this.inEditor&&this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>!0))));else if("global_fog"===e.type){const t=(this.scene.fog instanceof n?"density":"linear")!==e.fog.type;this.scene.fog=xe(e.fog),t&&(a=this.scene).traverse((e=>{if(e instanceof l){const t=e.material;t instanceof P&&(a.fog instanceof i?(t.uniforms.fogFar.value=a.fog.far,t.uniforms.fogNear.value=a.fog.near):a.fog instanceof n&&(t.uniforms.density={value:a.fog.density}),t.needsUpdate=!0,t.uniformsNeedUpdate=!0)}})),this.fixFogColor()}else if("actor"===e.type){if(this.materializedActors.has(e.id)){const t=this.editorActorParamSnapshot.get(e.id);null!=t&&t===JSON.stringify(e.actor)||(console.log("Rematerializing actor because parameters changed"),this.remove(e),await this.materializeAndInitActor(e))}}else if("shape_mesh"===e.type){const a=await this.createMeshByShape(e.shape,t.material,e.shapeParams);t instanceof W&&(t.geometry=a.geometry,t.collisionShape=a.collisionShape)}("asset_mesh"===e.type||"shape_mesh"===e.type&&"landscape"!==e.shape)&&we(t,e.castShadow,e.receiveShadow),e.name&&e.name.length>0&&(t.name=e.name),this.updated$.next({object:t,source:e})}else{const t=await this.materializeAndInitActor(e);this.updated$.next({object:t,source:e})}var a}async materializeAndInitActor(e,t=this.findParent(e)){const a=await this.materialize(e,t);return Ie(e,(async e=>{if("actor"===e.type){const t=this.materializedActors.get(e.id);null!=t?await this.initActorsPostInit([t]):console.error(`Something went wrong when creating actor ${e.id}`)}})),a}findParent(e){const t=this.dataProvider.getObjects().flatMap((t=>t.id===e.id?null:L(t,(t=>t.children?.some((t=>t.id===e.id))),(()=>!0))))[0];return null==t?this.scene:null!=t?R(this.scene,(e=>e.userData?.src?.id===t.id),(e=>null!=e.userData?.src))[0]:void 0}fixFogColor(){!0===this.renderingView.options.enableOutlines&&(this.scene.fog.color=new s(this.scene.fog.color).convertSRGBToLinear())}findMeshWithGeometry(e){let t;return e.traverse((e=>{e instanceof l&&e.geometry&&(t=e)})),t}applyVertexMaterials(e,t){if(null==e.vertexMaterials||0===e.vertexMaterials.length)return;const a=T(e.vertexMaterials,(e=>e.m));t.traverse((e=>{if(e instanceof l){const t=Q(e,!1);if(null!=t){for(let e=0;e<t.array.length;e++)t.setX(e,0);t.needsUpdate=!0}}}));const s=new Set;for(const[e,r]of a.entries()){const a=null!=e?t.getObjectByName(e):this.findMeshWithGeometry(t);let i=!1;if(null==a)return void console.warn(`Failed to apply vertex materials on mesh with name "${e}"`);const n=Q(a,!0);for(let e=0;e<n.array.length;e++)n.setX(e,0);for(const e of r)n.setX(e.i,e.w[0]),n.setY(e.i,e.w[1]),n.setZ(e.i,e.w[2]),i=!0;i&&s.add(e)}this.inEditor&&this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>s.has(e.name)))))}async materialize(e,t,s=!1){let r;switch(e.type){case"asset_mesh":r=await this.createFromAsset(e);break;case"shape_mesh":r=await this.createFromShape(e);break;case"light":r=await this.createLight(e);break;case"particles":r=await this.createParticleSystem(e),e.collisionDetection=!1;break;case"global_fog":this.scene.fog=xe(e.fog),this.fixFogColor(),r=new o;break;case"sky":this.sky=he(),this.updateSky(e),r=this.sky;break;case"actor":r=await this.createFromActor(e);break;case"group":r=new o;break;case"prefab":r=await this.createFromPrefabAsset(e);break;case"vfx":r=await this.createFromVfx(e);break;default:if(this.inEditor)throw new Error("unknown type "+e.type);console.warn(`Failed to materialize object. Unknown type '${e.type}'. This might be because the hology/core library is not compatible with the editor version.`)}if(null!=r){if(e.name&&e.name.length>0&&(r.name=e.name),r.position.fromArray(e.position),r.scale.fromArray(e.scale),r.rotation.fromArray(e.rotation),s||(r.userData.src=e),!this.inEditor){const t=e.components??[],a=null!=e.assetId?(await this.assetsService.getAsset(e.assetId))?.components??[]:[];t.push(...a),t.length>0?r.userData.componentRefs=await Promise.all(t.map(((t,a)=>this.createComponent(r,e,t,a)))):"asset_mesh"==e.type&&function(e){e.traverse((e=>{e.matrixAutoUpdate=!1,e.matrixWorldNeedsUpdate=!1}));const t=e.updateMatrixWorld;e.updateMatrixWorld=function(){t.apply(e),e.updateMatrixWorld=function(){}}}(r)}if(this.inEditor){let e=null;r instanceof W&&(e=function(e){if(e instanceof H)return new l(new a(...e.offset.toArray()),je);return null}(r.collisionShape)),null!=e&&(e.layers.disable(0),e.layers.enable(18),e.scale.multiplyScalar(1.1),r.add(e))}return this.objectMap.set(r.uuid,e),this.sceneObjectMap.set(e.id,r),null==t?this.scene.add(r):t?.add(r),null!=e.children&&await Promise.all(e.children?.map((e=>this.materialize(e,r,s)))),r}}async updateSky(e){if(null==e?.sky?.materialId)return void(this.sky.material=me);const a=await this.assetsService.getAsset(e.sky.materialId),s=await materialFromAsset(a,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!1);s.side=t.BackSide,null!=this.sky?this.sky.material=s:console.warn("No sky has been created")}async createComponent(e,t,a,s){const r=new ye[a.path+"/"+a.className],i=t.id+s;r.id=i,r.object=e;for(const e of a.params)null!=e.value&&(r[e.name]=e.value);return this.components.push(r),i}async createFromActor(e){const t=this.actorTypes.find((t=>t.name===e.actor?.type))?.type??O[e.actor?.type];if(null==t)return null;this.inEditor&&this.editorActorParamSnapshot.set(e.id,JSON.stringify(e.actor));const a=await this.actorProvider.create(t,(new A).fromArray(e.position),(new r).fromArray(e.rotation),!0);return this.materializedActors.set(e.id,a),a?.object}async createFromVfx(e){const t=await this.assetsService.getAsset(e.assetId);null==t&&console.error("Could not find asset",e);const a=await this.actorProvider.create(ue,(new A).fromArray(e.position),(new r).fromArray(e.rotation),!1);return await a.fromAsset(t),a.play(),this.materializedActors.set(e.id,a),a?.object}cleanup(){this.materializedActors.clear()}async createFromShape(e){const t=this.inEditor&&e.hidden;let a;if("landscape"==e.shape)a=this.createLandscape(e);else{let r=new d({name:"Default",color:new s("#aaaaaa"),visible:this.inEditor||!e.hidden,wireframe:!!t});const i=await this.createMeshByShape(e.shape,r,e.shapeParams);i.castShadow=e.castShadow??!0,i.receiveShadow=e.castShadow??!1,e.collisionDetection||(i.collisionShape=null),a=i,this._originalMaterials.set(a.id,i.material),a.traverse((e=>{}))}return t||((e.materialAssignments??[]).filter((e=>null!=e.materialId)).forEach((e=>this.applyMaterial(a,e))),this.applyVertexMaterials(e,a)),a}createLandscape(e){const t=e.landscape?.options;if(null==t)return console.error(`No landscape options exist on scene object ${e.id} ${e.name}`),new o;const a=J(e.landscape.options);this.applyHeightMaps(a,e.landscape.heightMaps,!0);const s=new X(e,this.renderingView,a,this.assetManagerService,this.assetsService,this.shaders,(t=>{(e.materialAssignments??[]).filter((e=>null!=e.materialId)).forEach((e=>this.applyMaterial(t,e)))}));return this.landscapeManagers.push(s),s.refreshGeometry(),a}applyHeightMaps(e,t,a=!1){const s=new Y(e.sections);for(const e of t??[]){const t=s.find(e.x,e.y);if(!t)return;const a=t.geometry.getAttribute("position");for(const t of e.points)a.setY(t.i,t.y);a.needsUpdate=!0}const r=e.sections;r.forEach((e=>{e.geometry.computeBoundsTree(),e.geometry.computeVertexNormals()})),this.inEditor&&!a||setTimeout((()=>q(r)),50)}async createMeshByShape(e,t,a={}){if("landscape"!==e&&ce.includes(e)){const s=await prepareShapeParameters(a??{});return"cylinder"==e&&s.openEnded,new W(oe[e].geometry(s),t,oe[e].collision(s))}if(this.inEditor)throw new Error(`Unsupported shape '${e}'`);console.warn(`Failed to create shape. Unsupported shape '${e}'. This might be because the hology/core library is not compatible with the editor version.`)}async createFromAsset(e){const t=await this.assetsService.getAsset(e.assetId);if(null==t)return void console.warn(`Can not find asset with id ${e.assetId} and name ${e.name}`);let{scene:a}=await this.assetManagerService.getMesh(t);Pe(e.materialAssignments,t.materialAssignments).forEach((e=>this.applyMaterial(a,e)));const s=e.receiveShadow??!!t.receiveShadow??!0,r=e.castShadow??!!t.castShadow??!1;return a.receiveShadow=s,we(a,r,s),e.collisionDetection||(a.collisionShapes=[]),this.applyVertexMaterials(e,a),a.traverse((e=>{e instanceof l&&"computeBoundsTree"in e.geometry&&e.geometry.computeBoundsTree()})),a}async createFromPrefabAsset(e){const t=await this.assetsService.getAsset(e.assetId);if(null==t)return void console.warn(`Can not find asset with id ${e.assetId} and name ${e.name}`);const a=new o;return t.prefab.objects.filter((e=>"global_fog"!==e.type)).forEach((e=>this.materialize(e,a,!0))),a}async createParticleSystem(e){const a=await this.assetsService.getAsset(e.assetId),s=new p;return await S.fromJSONAsync(a.particleSystem,t).then((e=>{const a=new b(s,t);e.addRenderer(a),this.renderingView.onLoop((t=>e.update()))})),s}async createLight(e){if("point"===e.light.type){const t=new f(e.light.point.color,e.light.point.intensity,e.light.point.distance,e.light.point.decay);if(t.castShadow=e.light.point.castShadow??!0,this.inEditor){const e=new g(.3,10,10),a=new d({color:new s(16771709)}),r=new l(e,a);t.add(r)}return t}return"directional"===e.light.type?(this.applyDirectionalLight(e.light.directional),new o):"ambient"===e.light.type?(this.applyDirectionalAmbientLight(null,e.light.ambient),new o):void 0}applyDirectionalAmbientLight(e,t){const a=this.scene.children.find((e=>e.name===le));null!=a?(a.intensity=t.intensity,a.color.set(t.color),a.groundColor.set(t.color)):console.warn("Couldn't find ambient light")}applyDirectionalLight(e){for(const t of this.renderingView.csm.lights)t.intensity=e.intensity,t.color.set(e.color),t.castShadow=e.castShadow;this.renderingView.csm.lightDirection.fromArray(e.direction).normalize()}dispose(){this.updateSubscription.unsubscribe(),this.materializedActors.forEach((e=>e.disposed.next(!0)))}}function we(e,t,a){e.castShadow=t,e.receiveShadow=a,e.traverse((e=>{e.castShadow=t,e.receiveShadow=a}))}const Ae=new Map,ve=new h({color:16711935}),Se=new Map;export async function materialFromAsset(e,a,r,i,n,o=!0){const c=JSON.stringify(e.material);if(o&&Ae.has(c))return Ae.get(c);const l={opacity:e.material.params.opacity,map:null,emissive:e.material.params.emissive??null,metalness:e.material.params.metalness??0,flatShading:e.material.params.flatShading??!1,color:new s(e.material.params.color).convertSRGBToLinear(),transparent:null!=e.material.params.opacity&&e.material.params.opacity<1},h={};if(null!=e.material.params.map){const t=e.material.params.map,a=await r.getAsset(t);null!=a&&(l.map=await i.getTexture(a))}let d;switch(e.material.type){case"phong":d=new m({...l,...h});break;case"water":d=ee(l,a);break;case"grassFoliage":d=K({color:l.color,map:l.map},a);break;case"grass":d=Z({...l,colorTwo:new s(e.material.params.colorTwo),colorThree:new s(e.material.params.colorThree)},a);break;case"standard":case"lambert":case"shader":const t={standard:ie,lambert:ne}[e.material.type]??n.find((t=>t.name==e.material.shader))?.type;if(t){const s=new t,o=await be(e.material?.shaderParams??{},t,r,i,null,a,n);Object.assign(s,o);try{d=s.build()}catch(t){console.log("Shader runtime error: "+t),Se.has(e.material.shader)||Se.set(e.material.shader,ve.clone()),d=Se.get(e.material.shader)}d.userData.customShaderName=e.material.shader}else console.warn("Missing shader implementation with name "+e.material.shader),d=ve;break;default:throw new Error("Unsupported material type"+e.material.type)}return a?.csm.setupMaterial(d),o&&Ae.set(c,d),d.side=e.material.side??d.side??t.FrontSide,d.transparent=(e.material.transparent??l.transparent??!1)||d.transparent,e.material.bloom&&(d.userData.hasBloom=!0),d}async function be(e,t,a,s,r,i,n,o){const c={};for(const[t,l]of Object.entries(e)){const e=await Me(l,a,s,r,i,n,o);null!=e&&(c[t]=e)}return c}export async function prepareShapeParameters(e){const t={};for(const[a,s]of Object.entries(e)){const e=await Me(s,null,null,null);null!=e&&(t[a]=e)}return t}async function Me(e,t,a,i,n,o,c){if(te.String,null==e||null==e.value||""==e.value)return null;const l=e.value;switch(e.type){case te.Number:case te.FloatNode:let h="string"==typeof l?parseFloat(l):l;return e.type===te.FloatNode?j(h):h;case te.Texture:return await a.getTexture(await t.getAsset(l));case te.Sampler2DNode:return N(await a.getTexture(await t.getAsset(l)));case te.Boolean:return l;case te.BooleanNode:return M(l);case te.Vector2:case te.Vec2Node:if("object"==typeof l){const t=l instanceof Array?(new w).fromArray(l):new w(l.x,l.y);return e.type===te.Vec2Node?C(t):t}return null;case te.Vector3:case te.Vec3Node:if("object"==typeof l){const t=l instanceof Array?(new A).fromArray(l):new A(l.x,l.y,l.z);return e.type===te.Vec3Node?k(t):t}return null;case te.Color:case te.RgbNode:const m=new s(l).convertSRGBToLinear();return e.type===te.RgbNode?D(m):m;case te.String:return l;case te.BaseActor:const d=l;return null==i&&console.warn("Class parameters can not be prepared as actors are not passed in"),i?.get(d);case te.Euler:const p=l;return(new r).fromArray(p);case te.Object3D:return(await a.getMesh(await t.getAsset(l))).scene;case te.Material:return await materialFromAsset(await t.getAsset(l),n,t,a,o);case te.AudioBuffer:return await a.getAudio(await t.getAsset(l));case te.VisualEffect:const f=await t.getAsset(l);if(null==c){console.error("Can not create instance of visual effect because missing actor provider");break}if("vfx"in f){const e=await c.create(ue);return await e.fromAsset(f),new ge(e)}console.error("Using a non-vfx asset for visual effect parameter")}return null}function xe(e){return"linear"===e.type?new i(new s(e.color),e.near??100,e.far??1e3):"density"===e.type?new n(e.color,e.density):void console.warn("Invalid fog type",e)}const je=new d({color:4229780});async function Ie(e,a,s,i){null==i&&(i=(new ae).identity()),await a(e,s,i);const n=i.clone().multiply(function(e,t){return t.compose((new A).fromArray(e.position),(new u).setFromEuler((new r).fromArray(e.rotation)),(new A).fromArray(e.scale))}(e,new t.Matrix4));return Promise.all((e.children??[]).map((t=>Ie(t,a,e,n))))}export function toSerializedParamType(e){const t=e.constructor.prototype;return t instanceof Number||e===Number?te.Number:t instanceof I||"function"==typeof e.prototype.isFloat?te.FloatNode:t instanceof y||e===y||e.isTexture?te.Texture:t instanceof re||e===E?te.Sampler2DNode:t instanceof Boolean||e===Boolean?te.Boolean:t instanceof x?te.BooleanNode:t instanceof s||e==s?te.Color:t instanceof V||"function"==typeof e.prototype.isRgb?te.RgbNode:t instanceof w||e==w?te.Vector2:t instanceof F||"function"==typeof e.prototype.isVec2?te.Vec2Node:t instanceof A||e==A?te.Vector3:t instanceof z||"function"==typeof e.prototype.isVec3?te.Vec3Node:t instanceof String||e===String?te.String:t instanceof se||e==se||e.prototype instanceof se||e.prototype==se?te.BaseActor:t instanceof r||e==r?te.Euler:t instanceof p||e==p?te.Object3D:t instanceof c||e==c?te.Material:t instanceof AudioBuffer||e==AudioBuffer?te.AudioBuffer:t instanceof ge||e==ge?te.VisualEffect:void console.warn("Failed to map parameter type to serialized version",{type:e})}export function prepareCustomParams(e,t,a={}){return Object.fromEntries(e.map((e=>[e.name,{type:toSerializedParamType(e.type),value:t[e.name]?.value??a[e.name]??customParameterDefaultValueByType.get(toSerializedParamType(e.type))}])))}export function prepareCustomParamsFromType(e,t,a=null){const s=_(e);if(0===s.length)return{};let r;null!=a?pe(a,(()=>{r=a.get(e)})):r=new e;const i={};for(const e of s){const t=r[e.name];if(null!=t){const a=serializeCustomParameter(e.type,t);null!=a&&(i[e.name]=a)}}return prepareCustomParams(s,t,i)}export function serializeCustomParameter(e,t){function a(){console.error("Failed to serialize value",{type:e,value:t})}switch(e){case Number:case Boolean:return t;case w:return t instanceof w?t.toArray():void a();case A:return t instanceof A?t.toArray():void a();case v:return t instanceof v?t.toArray():void a();case s:return t instanceof s?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new s(t).getHexString():void a();case String:return t;case r:return t instanceof r?t.toArray():void a()}}function Pe(e,t){return function(e,t,a){const s=[],r=new Set;for(const i of[...e??[],...t??[]]){const e=a(i);r.has(e)||(r.add(e),s.push(i))}return s}((e??[]).filter((e=>De(e.materialId))),(t??[]).filter((e=>De(e.materialId))),(e=>e.color+e.name))}function De(e){return"null"!=e&&null!=e}export const customParameterDefaultValueByType=new Map([[te.RgbNode,"#000000"],[te.Color,"#000000"],[te.Vector4,[0,0,0,0]],[te.Vec4Node,[0,0,0,0]],[te.Vector3,[0,0,0]],[te.Vec3Node,[0,0,0]],[te.Vector2,[0,0]],[te.Vec2Node,[0,0]],[te.Euler,[0,0,0,"XYZ"]]]);
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,6 +1,6 @@
|
|
1
|
-
import { NodeShaderMaterial } from '../../shader-nodes';
|
1
|
+
import { NodeShaderMaterial } from '../../shader-nodes/index.js';
|
2
2
|
import { Color, Texture } from 'three';
|
3
|
-
import { RenderingView } from '../../rendering';
|
3
|
+
import { RenderingView } from '../../rendering.js';
|
4
4
|
export interface GrassFoliageMaterialParameters {
|
5
5
|
map: Texture;
|
6
6
|
color: Color;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{attributes as m,float as o,lambertMaterial as l,NodeShaderMaterial as
|
1
|
+
import{attributes as m,float as o,lambertMaterial as l,NodeShaderMaterial as e,rgb as r,rgba as i,select as t,sin as a,smoothstep as p,transformed as n,translateAxis as u,uniformFloat as s,uniformSampler2d as f,varyingFloat as y,varyingVec2 as c}from"../../shader-nodes/index.js";import{Vector3 as v}from"three";import{CSMUtil as d}from"../../csm.js";export function createGrassFoliageMaterial(g,w){const x=n.mvPosition.z().multiply(o(-1)),h=y(p(o(100),o(60),x)),j=m.uv.y(),z=r(11977268),B=o(.2),C=l(r(g.color)).rgb().multiplyScalar(o(.9)).add(z.multiplyScalar(y(j).multiply(B))),S=c(m.uv),b=f("map").sample(S,o(0)),F=i(C,b.x().multiply(h)),G=s("time"),L=o(.5).multiply(t(j.gt(o(0)),j.multiply(j),o(0))).multiply(a(G.multiply(o(.001)))),M=u(new v(1,0,0).normalize(),L),P=new e({color:F,transform:M,uniforms:{map:{value:g.map},time:{value:0}},transparent:!0});return P.onBeforeCompile=m=>{d.onBeforeCompile(P,m)},P.uniforms.map.value=g.map,w.onLoop((()=>{P.uniforms.time.value=performance.now()})),P}
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,4 +1,4 @@
|
|
1
1
|
import * as THREE from 'three';
|
2
|
-
import { RenderingView } from '../../rendering';
|
2
|
+
import { RenderingView } from '../../rendering.js';
|
3
3
|
export declare function createGrassMaterial(params: any, renderingView: RenderingView): THREE.MeshStandardMaterial;
|
4
4
|
export declare function createGrassMaterialOld(params: any, renderingView: RenderingView): THREE.ShaderMaterial;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import*as e from"three";import{CSMUtil as r}from"../../csm";import{noiseChunk as n}from"./utils/noise.glsl";export function createGrassMaterial(a,i){var t=new e.MeshStandardMaterial({color:a.color,roughness:.8,metalness:0});return t.onBeforeCompile=(e,i)=>{r.onBeforeCompile(t,e);const l="varying vec3 vViewPosition;",v=`${l}\n varying vec3 vOriginalNormal;\n varying vec2 vNoiseCoord;\n attribute vec3 material;\n varying vec3 vMaterial;\n `,c="#include <fog_vertex>",s=`${c}\n vOriginalNormal = objectNormal;\n vMaterial = material;\n vNoiseCoord = position.xz / 5.0;\n `;e.vertexShader=e.vertexShader.replace(l,v),e.vertexShader=e.vertexShader.replace(c,s);const d="uniform vec3 diffuse;",m=`${d}\n varying vec3 vOriginalNormal;\n varying vec3 vMaterial;\n varying vec2 vNoiseCoord;\n\n ${n}\n `,g=o(a.color),f=o(a.colorTwo),h=`\n float thresholdStatic = 0.5;\n float thresholdWithNoise = thresholdStatic + snoise(vNoiseCoord) * 0.1;\n vec3 painted = (\n vMaterial.y > thresholdWithNoise \n ? ${o(a.colorThree)}\n : (vMaterial.x > thresholdWithNoise\n ? ${f}\n : ${g}\n )\n );\n\n float colorAngle = pow(vOriginalNormal.y, 3.0);\n vec4 diffuseColor = vec4(mix(painted, ${f}, smoothstep(colorAngle-0.0003, colorAngle, 0.9)), opacity);\n `.trim();e.fragmentShader=e.fragmentShader.replace(d,m),e.fragmentShader=e.fragmentShader.replace("vec4 diffuseColor = vec4( diffuse, opacity );",h)},t.userData.instancing=!1,t.userData.grass=!0,t}function o(e){return`vec3(${e.r.toFixed(5)}, ${e.g.toFixed(5)}, ${e.b.toFixed(5)})`}export function createGrassMaterialOld(r,n){return new e.ShaderMaterial({uniforms:{colorOne:{value:r.color}},vertexShader:"\n uniform float time;\n varying vec3 vNormal;\n void main() {\n vNormal = normal;\n #include <begin_vertex>\n #include <project_vertex>\n #include <fog_vertex>\n }",fragmentShader:"\n varying vec3 vNormal;\n uniform vec3 colorOne;\n void main() {\n gl_FragColor = vec4(mix(colorOne, vec3(.86,.8,.7), step(pow(vNormal.y, 3.0), 0.9)), 1.0);\t\n\n #include <tonemapping_fragment>\n #include <encodings_fragment>\n #include <fog_fragment>\n }"})}
|
1
|
+
import*as e from"three";import{CSMUtil as r}from"../../csm.js";import{noiseChunk as n}from"./utils/noise.glsl.js";export function createGrassMaterial(a,i){var t=new e.MeshStandardMaterial({color:a.color,roughness:.8,metalness:0});return t.onBeforeCompile=(e,i)=>{r.onBeforeCompile(t,e);const l="varying vec3 vViewPosition;",v=`${l}\n varying vec3 vOriginalNormal;\n varying vec2 vNoiseCoord;\n attribute vec3 material;\n varying vec3 vMaterial;\n `,c="#include <fog_vertex>",s=`${c}\n vOriginalNormal = objectNormal;\n vMaterial = material;\n vNoiseCoord = position.xz / 5.0;\n `;e.vertexShader=e.vertexShader.replace(l,v),e.vertexShader=e.vertexShader.replace(c,s);const d="uniform vec3 diffuse;",m=`${d}\n varying vec3 vOriginalNormal;\n varying vec3 vMaterial;\n varying vec2 vNoiseCoord;\n\n ${n}\n `,g=o(a.color),f=o(a.colorTwo),h=`\n float thresholdStatic = 0.5;\n float thresholdWithNoise = thresholdStatic + snoise(vNoiseCoord) * 0.1;\n vec3 painted = (\n vMaterial.y > thresholdWithNoise \n ? ${o(a.colorThree)}\n : (vMaterial.x > thresholdWithNoise\n ? ${f}\n : ${g}\n )\n );\n\n float colorAngle = pow(vOriginalNormal.y, 3.0);\n vec4 diffuseColor = vec4(mix(painted, ${f}, smoothstep(colorAngle-0.0003, colorAngle, 0.9)), opacity);\n `.trim();e.fragmentShader=e.fragmentShader.replace(d,m),e.fragmentShader=e.fragmentShader.replace("vec4 diffuseColor = vec4( diffuse, opacity );",h)},t.userData.instancing=!1,t.userData.grass=!0,t}function o(e){return`vec3(${e.r.toFixed(5)}, ${e.g.toFixed(5)}, ${e.b.toFixed(5)})`}export function createGrassMaterialOld(r,n){return new e.ShaderMaterial({uniforms:{colorOne:{value:r.color}},vertexShader:"\n uniform float time;\n varying vec3 vNormal;\n void main() {\n vNormal = normal;\n #include <begin_vertex>\n #include <project_vertex>\n #include <fog_vertex>\n }",fragmentShader:"\n varying vec3 vNormal;\n uniform vec3 colorOne;\n void main() {\n gl_FragColor = vec4(mix(colorOne, vec3(.86,.8,.7), step(pow(vNormal.y, 3.0), 0.9)), 1.0);\t\n\n #include <tonemapping_fragment>\n #include <encodings_fragment>\n #include <fog_fragment>\n }"})}
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|