@hology/core 0.0.21 → 0.0.24

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,6 @@
1
+ export declare const projectConfigFileName = "hology.config.json";
1
2
  export interface ProjectConfig {
3
+ name: string;
2
4
  dataPath: string;
3
5
  shadersPath: string;
4
6
  actorsPath: string;
@@ -1,4 +1,4 @@
1
- export{};
1
+ export const projectConfigFileName="hology.config.json";
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
package/dist/csm.js CHANGED
@@ -1,4 +1,4 @@
1
- import*as e from"three";const a=e.Object3D.prototype.add,n=new WeakMap,t=new WeakMap;export const CSMUtil={renderingView:null,onBeforeCompile(e,a){e.defines=e.defines||{},e.defines.USE_CSM=1,e.defines.CSM_CASCADES=this.renderingView.csm.cascades;const n=Math.min(this.renderingView.camera.far,this.renderingView.csm.maxFar),t=[];this.renderingView.csm.getExtendedBreaks(t),a.uniforms.CSM_cascades={value:t},a.uniforms.cameraNear={value:this.renderingView.camera.near},a.uniforms.shadowFar={value:n}},patchThreeAdd(){const r=this.renderingView;n.set(r.scene,r.csm),e.Object3D.prototype.add=function(...r){let i=this;for(;null!=i.parent;)i=i.parent;const s=i,d=n.get(s);if(null==d)return a.apply(this,arguments),this;t.has(s)||t.set(s,new WeakSet);const o=t.get(s);return r.forEach((a=>null==a?void 0:a.traverse((a=>{(a instanceof e.Mesh||a instanceof e.SkinnedMesh)&&a.material&&!o.has(a.material)&&(o.add(a.material),null==d||d.setupMaterial(a.material))})))),a.apply(this,arguments),this}}};
1
+ import*as e from"three";const n=e.Object3D.prototype.add,t=new WeakMap,a=new WeakMap;export const CSMUtil={renderingView:null,onBeforeCompile(e,n){e.defines=e.defines||{},e.defines.USE_CSM=1,e.defines.CSM_CASCADES=this.renderingView.csm.cascades;const t=Math.min(this.renderingView.camera.far,this.renderingView.csm.maxFar),a=[];this.renderingView.csm.getExtendedBreaks(a),n.uniforms.CSM_cascades={value:a},n.uniforms.cameraNear={value:this.renderingView.camera.near},n.uniforms.shadowFar={value:t}},patchThreeAdd(){const r=this.renderingView;t.set(r.scene,r.csm),e.Object3D.prototype.add=function(...r){let i=this;for(;null!=i.parent;)i=i.parent;const s=i,o=t.get(s);if(null==o)return n.apply(this,arguments),this;a.has(s)||a.set(s,new WeakSet);const c=a.get(s);function d(e){e&&!c.has(e)&&(c.add(e),null==o||o.setupMaterial(e))}return r.forEach((n=>null==n?void 0:n.traverse((n=>{if(n instanceof e.Mesh||n instanceof e.SkinnedMesh)if(n.material instanceof Array)for(const e of n.material)d(e);else d(n.material)})))),n.apply(this,arguments),this}}};
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -1,4 +1,4 @@
1
- import{__decorate as t,__metadata as s}from"tslib";import{PhysicsBodyType as i,PhysicsSystem as e}from"../../../../gameplay/services/physics/physics-system";import{AssetMeshInstance as o}from"../../../../scene/asset-resource-loader";import{PhysicalShapeMesh as n}from"../../../../";import{Parameter as r}from"../../../../shader/parameter";import{Euler as c,Vector3 as h}from"three";import{ActorComponent as p,Component as a}from"../../component";import{firstValueFrom as l}from"rxjs";const m={friction:.1,mass:0,bodyType:i.static,continousCollisionDetection:!1};let y=class extends p{constructor(t){super(),this.physicsSystem=t,this.position=new h,this.rotation=new c,this.scale=new h(1,1,1),this.mass=m.mass,this.friction=m.friction,this.bodyType=i.static,this.continousCollisionDetection=m.continousCollisionDetection}onInit(){null!=this.object&&(this.currentMesh=this.object,this.updateMesh()),l(this.disposed).then((()=>{this.physicsSystem.removeActor(this.actor)}))}setObject(t){null!=this.currentMesh&&this.actor.object.remove(this.currentMesh),this.object=this.currentMesh=t,this.updateMesh()}updateMesh(){this.currentMesh.position.copy(this.position),this.currentMesh.rotation.copy(this.rotation),this.currentMesh.scale.copy(this.scale);const t=this.getCollisionShapes();t.length>0&&this.physicsSystem.addActor(this.actor,t,Object.assign(Object.assign({},m),{isTrigger:!1,mass:this.mass,friction:this.friction,type:this.bodyType,continousCollisionDetection:this.continousCollisionDetection})),this.actor.object.add(this.currentMesh)}getCollisionShapes(){return this.currentMesh instanceof o?this.currentMesh.collisionShapes:this.currentMesh instanceof n?[this.currentMesh.collisionShape]:"collisionShape"in this.currentMesh?(console.error("Could not understand wehre to get collision shapes from. This is likely due to an import issue"),[this.currentMesh.collisionShape]):[]}};t([r(),s("design:type",Object)],y.prototype,"object",void 0),t([r(),s("design:type",h)],y.prototype,"position",void 0),t([r(),s("design:type",c)],y.prototype,"rotation",void 0),t([r(),s("design:type",h)],y.prototype,"scale",void 0),t([r(),s("design:type",Number)],y.prototype,"mass",void 0),t([r(),s("design:type",Number)],y.prototype,"friction",void 0),t([r({options:[{name:"Static",value:i.static},{name:"Dynamic",value:i.dynamic}]}),s("design:type",Number)],y.prototype,"bodyType",void 0),y=t([a({inEditor:!0}),s("design:paramtypes",[e])],y);export{y as MeshComponent};
1
+ import{__decorate as t,__metadata as s}from"tslib";import{PhysicsBodyType as i,PhysicsSystem as e}from"../../../../gameplay/services/physics/physics-system";import{AssetMeshInstance as o}from"../../../../scene/asset-resource-loader";import{PhysicalShapeMesh as n}from"../../../../";import{Parameter as r}from"../../../../shader/parameter";import{Euler as c,Object3D as h,Vector3 as p}from"three";import{ActorComponent as a,Component as l}from"../../component";import{firstValueFrom as m}from"rxjs";const y={friction:.1,mass:0,bodyType:i.static,continousCollisionDetection:!1};let d=class extends a{constructor(t){super(),this.physicsSystem=t,this.position=new p,this.rotation=new c,this.scale=new p(1,1,1),this.mass=y.mass,this.friction=y.friction,this.bodyType=i.static,this.continousCollisionDetection=y.continousCollisionDetection}onInit(){null!=this.object&&(this.currentMesh=this.object,this.updateMesh()),m(this.disposed).then((()=>{this.physicsSystem.removeActor(this.actor)}))}setObject(t){null!=this.currentMesh&&this.actor.object.remove(this.currentMesh),this.object=this.currentMesh=t,this.updateMesh()}updateMesh(){this.currentMesh.position.copy(this.position),this.currentMesh.rotation.copy(this.rotation),this.currentMesh.scale.copy(this.scale);const t=this.getCollisionShapes();t.length>0&&this.physicsSystem.addActor(this.actor,t,Object.assign(Object.assign({},y),{isTrigger:!1,mass:this.mass,friction:this.friction,type:this.bodyType,continousCollisionDetection:this.continousCollisionDetection})),this.actor.object.add(this.currentMesh)}getCollisionShapes(){return this.currentMesh instanceof o?this.currentMesh.collisionShapes:this.currentMesh instanceof n?[this.currentMesh.collisionShape]:"collisionShape"in this.currentMesh?(console.error("Could not understand wehre to get collision shapes from. This is likely due to an import issue"),[this.currentMesh.collisionShape]):[]}};t([r({type:h}),s("design:type",Object)],d.prototype,"object",void 0),t([r(),s("design:type",p)],d.prototype,"position",void 0),t([r(),s("design:type",c)],d.prototype,"rotation",void 0),t([r(),s("design:type",p)],d.prototype,"scale",void 0),t([r(),s("design:type",Number)],d.prototype,"mass",void 0),t([r(),s("design:type",Number)],d.prototype,"friction",void 0),t([r({options:[{name:"Static",value:i.static},{name:"Dynamic",value:i.dynamic}]}),s("design:type",Number)],d.prototype,"bodyType",void 0),d=t([l({inEditor:!0}),s("design:paramtypes",[e])],d);export{d as MeshComponent};
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -5,7 +5,7 @@ export declare class SpawnPointMesh extends ActorComponent {
5
5
  onInit(): void | Promise<void>;
6
6
  }
7
7
  export declare class SpawnPoint extends BaseActor {
8
- mesh: SpawnPointMesh;
8
+ private mesh;
9
9
  private readonly world;
10
10
  spawnActor<T extends BaseActor>(type: Type<T>): Promise<T>;
11
11
  }
@@ -1,4 +1,4 @@
1
- import{__decorate as t,__metadata as o}from"tslib";import{EdgesGeometry as e,ArrowHelper as r,Vector3 as i,BoxGeometry as n,Euler as s}from"three";import{Actor as p,BaseActor as c}from"../actor";import{Component as m,ActorComponent as a,Attach as d}from"../component";import{World as l}from"../../../gameplay/services/world";import{inject as w}from"../../../gameplay/inject";import{createLineSphere as h}from"../../../utils/three/line-sphere";let f=class extends a{onInit(){const t=new n(1,1,1),o=(new e(t),h(1));this.actor.object.add(o);this.actor.object.getWorldDirection(new i);const s=new r(new i(0,0,1),new i,1,16773120);this.actor.object.add(s)}};f=t([m({inEditor:!0,editorOnly:!0})],f);export{f as SpawnPointMesh};let y=class extends c{constructor(){super(...arguments),this.world=w(l)}spawnActor(t){return this.world.spawnActor(t,this.position,new s(0,this.rotation.y,0,"XYZ"))}};t([d(),o("design:type",f)],y.prototype,"mesh",void 0),y=t([p()],y);export{y as SpawnPoint};
1
+ import{__decorate as t,__metadata as o}from"tslib";import{ArrowHelper as r,Vector3 as e,Euler as i}from"three";import{Actor as s,BaseActor as n}from"../actor";import{Component as p,ActorComponent as m,Attach as c}from"../component";import{World as a}from"../../../gameplay/services/world";import{inject as d}from"../../../gameplay/inject";import{createLineSphere as l}from"../../../utils/three/line-sphere";let h=class extends m{onInit(){const t=l(1);this.actor.object.add(t);const o=new r(new e(0,0,1),new e,1,1268122,.3,.3);this.actor.object.add(o)}};h=t([p({inEditor:!0,editorOnly:!0})],h);export{h as SpawnPointMesh};let w=class extends n{constructor(){super(...arguments),this.world=d(a)}spawnActor(t){return this.world.spawnActor(t,this.position,new i(0,this.rotation.y,0,"XYZ"))}};t([c(),o("design:type",h)],w.prototype,"mesh",void 0),w=t([s()],w);export{w as SpawnPoint};
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -1,4 +1,4 @@
1
- import{__decorate as t,__metadata as s}from"tslib";import{EdgesGeometry as i,LineSegments as e,LineBasicMaterial as o,Vector3 as r,BoxGeometry as n,Mesh as c,MeshBasicMaterial as h,Group as p}from"three";import{Actor as a,BaseActor as d}from"../actor";import{Component as m,ActorComponent as y,Attach as l}from"../component";import{PhysicsSystem as v}from"../../services/physics/physics-system";import{BoxCollisionShape as g}from"../../../scene/collision/collision-shape";import{firstValueFrom as w}from"rxjs";let A=class extends y{constructor(){super(...arguments),this.dimensions=new r(1,1,1)}onInit(){const t=new n(this.dimensions.x,this.dimensions.y,this.dimensions.z),s=new i(t),r=new e(s,new o({color:16777215})),a=(new c(t,new h({color:16777215,transparent:!0,opacity:.3,visible:!1})),new p);a.add(r),this.actor.object.add(a)}};A=t([m({inEditor:!0,editorOnly:!0})],A);export{A as TriggerVolumeMesh};let O=class extends y{constructor(t){super(),this.physicsSystem=t,this.dimensions=new r(1,1,1)}onInit(){this.editorMesh=this.attach(A),console.log("add actor",this.actor),this.physicsSystem.addActor(this.actor,[new g(this.dimensions)],{isTrigger:!0}),w(this.disposed).then((()=>{this.physicsSystem.removeActor(this.actor)}))}onBeginOverlapWithActor(t){return this.physicsSystem.onBeginOverlapWithActor(this.actor,t)}onEndOverlapWithActor(t){return this.physicsSystem.onEndOverlapWithActor(this.actor,t)}onBeginOverlapWithActorType(t){return this.physicsSystem.onBeginOverlapWithActorType(this.actor,t)}onEndOverlapWithActorType(t){return this.physicsSystem.onEndOverlapWithActorType(this.actor,t)}};O=t([m({inEditor:!0,editorOnly:!1}),s("design:paramtypes",[v])],O);export{O as TriggerVolumeComponent};let u=class extends d{};t([l(),s("design:type",O)],u.prototype,"trigger",void 0),u=t([a()],u);export{u as TriggerVolume};
1
+ import{__decorate as t,__metadata as s}from"tslib";import{EdgesGeometry as i,LineSegments as e,LineBasicMaterial as o,Vector3 as r,BoxGeometry as n,Mesh as c,MeshBasicMaterial as h,Group as p}from"three";import{Actor as m,BaseActor as a}from"../actor";import{Component as d,ActorComponent as y,Attach as l}from"../component";import{PhysicsSystem as v}from"../../services/physics/physics-system";import{BoxCollisionShape as g}from"../../../scene/collision/collision-shape";import{firstValueFrom as w}from"rxjs";let A=class extends y{constructor(){super(...arguments),this.dimensions=new r(1,1,1)}onInit(){const t=new n(this.dimensions.x,this.dimensions.y,this.dimensions.z),s=new i(t),r=new e(s,new o({color:16777215})),m=(new c(t,new h({color:16777215,transparent:!0,opacity:.3,visible:!1})),new p);m.add(r),this.actor.object.add(m)}};A=t([d({inEditor:!0,editorOnly:!0})],A);export{A as TriggerVolumeMesh};let O=class extends y{constructor(t){super(),this.physicsSystem=t,this.dimensions=new r(1,1,1)}onInit(){this.editorMesh=this.attach(A),this.physicsSystem.addActor(this.actor,[new g(this.dimensions)],{isTrigger:!0}),w(this.disposed).then((()=>{this.physicsSystem.removeActor(this.actor)}))}onBeginOverlapWithActor(t){return this.physicsSystem.onBeginOverlapWithActor(this.actor,t)}onEndOverlapWithActor(t){return this.physicsSystem.onEndOverlapWithActor(this.actor,t)}onBeginOverlapWithActorType(t){return this.physicsSystem.onBeginOverlapWithActorType(this.actor,t)}onEndOverlapWithActorType(t){return this.physicsSystem.onEndOverlapWithActorType(this.actor,t)}};O=t([d({inEditor:!0,editorOnly:!1}),s("design:paramtypes",[v])],O);export{O as TriggerVolumeComponent};let u=class extends a{};t([l(),s("design:type",O)],u.prototype,"trigger",void 0),u=t([m()],u);export{u as TriggerVolume};
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -1,4 +1,4 @@
1
- import{__awaiter as t,__decorate as e,__metadata as s}from"tslib";import{ActorComponent as i,Component as o,Attach as n}from"../component";import{CameraComponent as h}from"./camera-component";import{Vector3 as a}from"three";import{ViewController as r}from"../../services/render";import{DecimalInput as c,RestrictedRotationInput as m}from"../../input";import{PhysicsSystem as d,RayTestResult as l}from"../../services/physics/physics-system";import{clamp as u,lerp as p}from"three/src/math/MathUtils";let f=class extends i{constructor(t,e){super(),this.viewController=t,this.physicsSystem=e,this.distance=9,this.minDistance=1.5,this.maxDistance=this.distance,this.height=3,this.offsetX=-1,this.offsetZ=1.5,this.autoActivate=!0,this.bounceBackSpeed=5,this.collisionCheckRadius=.5,this.restrictedDistance=Math.max(this.distance,this.maxDistance),this.rotationInput=new m(-Math.PI/4,Math.PI/2-.7),this.zoomInput=new c(1,0,1),this.offset=new a,this.lookAtOffset=new a(this.offsetX,0,this.offsetZ),this.isMouseLocked=!1,this.canvas=null,this.pointerLockInactivatedAt=null,this.onMouseDown=t=>{this.isMouseLocked||this.hideCursor()},this.onKeyDown=t=>{"Escape"===t.key&&this.showCursor()},this.onPointerLockChange=()=>{null!=document.pointerLockElement||null!=document.mozPointerLockElement||this.showCursor()}}onInit(){return t(this,void 0,void 0,(function*(){this.restrictedDistance=Math.max(this.distance,this.maxDistance),this.lookAtOffset.set(this.offsetX,0,this.offsetZ),this.autoActivate&&this.viewController.setCamera(this.camera.instance),this.physicsSystem.beforeStep.subscribe((t=>{this.setFromRotation(t)}));const t=this.element;t.addEventListener("mousedown",this.onMouseDown),t.addEventListener("keydown",this.onKeyDown),document.addEventListener("pointerlockchange",this.onPointerLockChange,!1),this.disposed.subscribe((()=>{t.removeEventListener("mousedown",this.onMouseDown),t.removeEventListener("keydown",this.onKeyDown),document.removeEventListener("pointerlockchange",this.onPointerLockChange,!1)}))}))}get element(){return this.viewController.htmlElement}hideCursor(){null!=this.pointerLockInactivatedAt&&performance.now()-this.pointerLockInactivatedAt<1600||(this.element.style.cursor="none",null==this.canvas&&(this.canvas=this.element.getElementsByTagName("canvas")[0]),this.canvas&&(this.canvas.requestPointerLock(),this.isMouseLocked=!0))}showCursor(){this.pointerLockInactivatedAt=performance.now(),this.element.style.cursor="default",window.document.exitPointerLock(),this.isMouseLocked=!1}setFromRotation(t){const e=u(Math.min(this.restrictedDistance,this.distance),this.minDistance,Math.max(this.distance*this.zoomInput.value,this.minDistance)),s=Math.cos(this.rotationInput.rotation.x)*e;this.offset.x=Math.sin(this.rotationInput.rotation.y)*s,this.offset.y=Math.sin(this.rotationInput.rotation.x)*e+2,this.offset.z=Math.cos(this.rotationInput.rotation.y)*-s,this.offset.add(this.lookAtOffset),this.updateCameraPosition(),this.checkForCollision(t)}checkForCollision(t){const e=this.getLookAtPosition(),s=v;let i=!1,o=this.distance;const n=new l,h=this.camera.instance.getWorldPosition(y);for(let t=-1;t<=1;t++){const a=w.subVectors(h,e);s.copy(h).add(a.multiplyScalar(1.2)),s.x+=t*this.collisionCheckRadius,this.physicsSystem.rayTest(e,s,n,{debugLifetime:0}),n.hasHit&&n.distance<this.distance&&(o=Math.min(n.distance,o),i||(i=n.hasHit))}i||(this.restrictedDistance=p(this.restrictedDistance,this.distance,this.bounceBackSpeed*t))}getLookAtPosition(){const t=k;return t.set(0,0,0),t.y=this.height,t.add(this.lookAtOffset),t.applyMatrix4(this.actor.object.matrixWorld),t}updateCameraPosition(){this.camera.instance.position.copy(this.offset);const t=this.getLookAtPosition();this.camera.instance.lookAt(t)}};e([n(),s("design:type",h)],f.prototype,"camera",void 0),f=e([o(),s("design:paramtypes",[r,d])],f);export{f as ThirdPartyCameraComponent};const k=new a,v=new a,w=(new a,new a),y=new a;
1
+ import{__awaiter as t,__decorate as s,__metadata as e}from"tslib";import{ActorComponent as i,Component as o,Attach as n}from"../component";import{CameraComponent as h}from"./camera-component";import{Vector3 as a}from"three";import{ViewController as r}from"../../services/render";import{DecimalInput as c,RestrictedRotationInput as m}from"../../input";import{PhysicsSystem as d,RayTestResult as l}from"../../services/physics/physics-system";import{clamp as u,lerp as p}from"three/src/math/MathUtils";let f=class extends i{constructor(t,s){super(),this.viewController=t,this.physicsSystem=s,this.distance=9,this.minDistance=1.5,this.maxDistance=this.distance,this.height=3,this.offsetX=-1,this.offsetZ=1.5,this.autoActivate=!0,this.bounceBackSpeed=5,this.collisionCheckRadius=.5,this.restrictedDistance=Math.max(this.distance,this.maxDistance),this.rotationInput=new m(-Math.PI/4,Math.PI/2-.7),this.zoomInput=new c(1,0,1),this.offset=new a,this.lookAtOffset=new a(this.offsetX,0,this.offsetZ),this.isMouseLocked=!1,this.canvas=null,this.pointerLockInactivatedAt=null,this.onMouseDown=t=>{this.isMouseLocked||this.hideCursor()},this.onKeyDown=t=>{"Escape"===t.key&&this.showCursor()},this.onPointerLockChange=()=>{null!=document.pointerLockElement||null!=document.mozPointerLockElement||this.showCursor()}}onInit(){return t(this,void 0,void 0,(function*(){this.restrictedDistance=Math.max(this.distance,this.maxDistance),this.lookAtOffset.set(this.offsetX,0,this.offsetZ),this.autoActivate&&this.viewController.setCamera(this.camera.instance),this.physicsSystem.afterStep.subscribe((t=>{this.setFromRotation(t)}));const t=this.element;t.addEventListener("mousedown",this.onMouseDown),t.addEventListener("keydown",this.onKeyDown),document.addEventListener("pointerlockchange",this.onPointerLockChange,!1),this.disposed.subscribe((()=>{t.removeEventListener("mousedown",this.onMouseDown),t.removeEventListener("keydown",this.onKeyDown),document.removeEventListener("pointerlockchange",this.onPointerLockChange,!1)}))}))}get element(){return this.viewController.htmlElement}hideCursor(){null!=this.pointerLockInactivatedAt&&performance.now()-this.pointerLockInactivatedAt<1600||(this.element.style.cursor="none",null==this.canvas&&(this.canvas=this.element.getElementsByTagName("canvas")[0]),this.canvas&&(this.canvas.requestPointerLock(),this.isMouseLocked=!0))}showCursor(){this.pointerLockInactivatedAt=performance.now(),this.element.style.cursor="default",window.document.exitPointerLock(),this.isMouseLocked=!1}setFromRotation(t){const s=u(Math.min(this.restrictedDistance,this.distance),this.minDistance,Math.max(this.distance*this.zoomInput.value,this.minDistance)),e=Math.cos(this.rotationInput.rotation.x)*s;this.offset.x=Math.sin(this.rotationInput.rotation.y)*e,this.offset.y=Math.sin(this.rotationInput.rotation.x)*s+2,this.offset.z=Math.cos(this.rotationInput.rotation.y)*-e,this.offset.add(this.lookAtOffset),this.updateCameraPosition(),this.checkForCollision(t)}checkForCollision(t){const s=this.getLookAtPosition(),e=v;let i=!1,o=this.distance;const n=new l,h=this.camera.instance.getWorldPosition(y);for(let t=-1;t<=1;t++){const a=w.subVectors(h,s);e.copy(h).add(a.multiplyScalar(1.2)),e.x+=t*this.collisionCheckRadius,this.physicsSystem.rayTest(s,e,n,{debugLifetime:0}),n.hasHit&&n.distance<this.distance&&(o=Math.min(n.distance,o),i||(i=n.hasHit))}i||(this.restrictedDistance=p(this.restrictedDistance,this.distance,this.bounceBackSpeed*t))}getLookAtPosition(){const t=k;return t.set(0,0,0),t.y=this.height,t.add(this.lookAtOffset),t.applyMatrix4(this.actor.object.matrixWorld),t}updateCameraPosition(){this.camera.instance.position.copy(this.offset);const t=this.getLookAtPosition();this.camera.instance.lookAt(t)}};s([n(),e("design:type",h)],f.prototype,"camera",void 0),f=s([o(),e("design:paramtypes",[r,d])],f);export{f as ThirdPartyCameraComponent};const k=new a,v=new a,w=(new a,new a),y=new a;
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -35,6 +35,7 @@ export declare class HologyRuntime<T_Game = unknown> {
35
35
  private containerInstance;
36
36
  status: HologyRuntimeStatus;
37
37
  gameInstance?: T_Game;
38
+ isShutdown: boolean;
38
39
  private _resolver;
39
40
  /**
40
41
  * A promise that you can await on to delay some logic until the runtime has finished loading
@@ -1,4 +1,4 @@
1
- import{__awaiter as e}from"tslib";import t from"typedi";import{loadScene as n}from"../scene/bootstrap";import{ActorFactory as o}from"./actors/factory";import{World as s}from"./services/world";import{ViewController as r}from"./services/render";import{RenderingView as i}from"../rendering";import{PhysicsSystem as a}from"./services/physics/physics-system";import{MeshComponent as c}from"./actors/builtin/components/mesh-component";import{activeContainerInstance as m}from"./actors/internal/container-map";import{InputService as l}from"./input";import{RuntimeBackendService as p}from"../scene/runtime-backend-service";import{RuntimeAssetsService as d}from"../scene/runtime-asset-service";import{AssetResourceLoader as h}from"../scene/asset-resource-loader";import{AssetLoader as f}from"./services/asset-loader";export function initiateGame(l,u){if(0!=u.element.childNodes.length)return console.error("Can not initialize the game with a non-empty html element"),null;t.has(r);const g=t.of("default"),w=new HologyRuntime(g),v=new o(g,{inEditor:!1});var y;t.set(o,v),y=u.element,Object.assign(y.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%"});const I=new i(u.element);I.renderer.shadowMap.autoUpdate=!0,t.set(i,I);const S=new r(I);t.set(r,S);const b=new s(t.get(o));t.set(s,b);const D=new p(u.dataDir),x=new d(D),G=new h;G.setDataDir(u.dataDir);const H=new f(G,x);return t.set(f,H),(()=>{e(this,void 0,void 0,(function*(){const e=t.get(a);yield e.start();const{scene:o,actors:s}=yield n(I,u.sceneName,u.dataDir,u.shaders,u.actors,v,D,x,G);b.scene=o,t.import([c]);for(const e of s)b.addActor(e);e.addFromScene(o),I.loop((e=>{})),w.status=5,m.value=g,g.remove(l),g.set({id:l,type:l});const r=g.get(l);m.value=null,w.gameInstance=r,r instanceof GameInstance&&r.onStart(),w._resolver(!0)}))})(),w}export class GameInstance{onStart(){}onShutdown(){}}export function createHologyScene(){}export class HologyRuntime{constructor(e){this.containerInstance=e,this.status=0,this.ready=new Promise((e=>{this._resolver=e}))}getWorld(){return this.containerInstance.get(s)}getService(e){return this.containerInstance.get(e)}shutdown(){this.gameInstance instanceof GameInstance&&this.gameInstance.onShutdown(),this.containerInstance.get(l).stop();const e=this.containerInstance.get(i);null==e||e.stop();for(const e of this.getWorld().actors)this.getWorld().removeActor(e);this.containerInstance.get(a).stop(),this.containerInstance.reset()}}
1
+ import{__awaiter as t}from"tslib";import e from"typedi";import{loadScene as n}from"../scene/bootstrap";import{ActorFactory as o}from"./actors/factory";import{World as s}from"./services/world";import{ViewController as r}from"./services/render";import{RenderingView as i}from"../rendering";import{PhysicsSystem as a}from"./services/physics/physics-system";import{MeshComponent as c}from"./actors/builtin/components/mesh-component";import{activeContainerInstance as m}from"./actors/internal/container-map";import{InputService as d}from"./input";import{RuntimeBackendService as l}from"../scene/runtime-backend-service";import{RuntimeAssetsService as p}from"../scene/runtime-asset-service";import{AssetResourceLoader as h}from"../scene/asset-resource-loader";import{AssetLoader as u}from"./services/asset-loader";export function initiateGame(d,f){if(0!=f.element.childNodes.length)return console.error("Can not initialize the game with a non-empty html element"),null;e.has(r);const g=e.of("default"),w=new HologyRuntime(g),v=new o(g,{inEditor:!1});var y;e.set(o,v),y=f.element,Object.assign(y.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%"});const I=new i(f.element);I.renderer.shadowMap.autoUpdate=!0,e.set(i,I);const S=new r(I);e.set(r,S);const b=new s(e.get(o));e.set(s,b);const D=new l(f.dataDir),x=new p(D),G=new h;G.setDataDir(f.dataDir);const H=new u(G,x);return e.set(u,H),(()=>{t(this,void 0,void 0,(function*(){const t=e.get(a);if(yield t.start(),w.isShutdown)return;const{scene:o,actors:s}=yield n(I,f.sceneName,f.dataDir,f.shaders,f.actors,v,D,x,G);if(b.scene=o,w.isShutdown)return void I.stop();e.import([c]);for(const t of s)b.addActor(t);t.addFromScene(o),I.loop((t=>{})),w.status=5,m.value=g,g.remove(d),g.set({id:d,type:d});const r=g.get(d);m.value=null,w.gameInstance=r,r instanceof GameInstance&&r.onStart(),w._resolver(!0)}))})(),w}export class GameInstance{onStart(){}onShutdown(){}}export function createHologyScene(){}export class HologyRuntime{constructor(t){this.containerInstance=t,this.status=0,this.isShutdown=!1,this.ready=new Promise((t=>{this._resolver=t}))}getWorld(){return this.containerInstance.get(s)}getService(t){return this.containerInstance.get(t)}shutdown(){this.isShutdown=!0,this.gameInstance instanceof GameInstance&&this.gameInstance.onShutdown(),this.containerInstance.get(d).stop();const t=this.containerInstance.get(i);null==t||t.stop();for(const t of this.getWorld().actors)this.getWorld().removeActor(t);this.containerInstance.get(a).stop(),this.containerInstance.reset()}}
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -4,11 +4,10 @@ import { Observable, Subject } from "rxjs";
4
4
  import * as THREE from "three";
5
5
  import { ColorRepresentation, Object3D, Vector3 } from "three";
6
6
  import { CollisionShape } from "../../../";
7
- import { Type } from "../../../utils/type";
8
- import { BaseActor } from "../../actors/actor";
7
+ import { AbstractType } from "../../../utils/type";
8
+ import { BaseActor } from '../../actors/actor';
9
9
  import { ViewController } from "../render";
10
10
  import { World } from "../world";
11
- import { CollisionContact } from "./collision-contact";
12
11
  export declare class RayTestResult {
13
12
  _internal: RayColliderIntersection;
14
13
  actor: BaseActor;
@@ -49,6 +48,7 @@ export declare class PhysicsSystem {
49
48
  private actorBodies;
50
49
  private bodyActors;
51
50
  private eventQueue;
51
+ private fixedupdateSub;
52
52
  private readonly collisionEvents;
53
53
  readonly beforeStep: Subject<number>;
54
54
  readonly afterStep: Subject<number>;
@@ -108,25 +108,23 @@ export declare class PhysicsSystem {
108
108
  removeSceneObject(object: Object3D): void;
109
109
  private activateActorEvents;
110
110
  private _onCollisionWithActorEvent;
111
- onBeginOverlapWithActorType<T extends BaseActor, A extends BaseActor>(self: T, actorType: Type<A>): Observable<A>;
112
- onEndOverlapWithActorType<T extends BaseActor, A extends BaseActor>(self: T, actorType: Type<A>): Observable<A>;
111
+ /**
112
+ * Get a subscription to contact started events where the value of the subscription
113
+ * is some unique number identifying the object in which the actor is in contact.
114
+ */
115
+ onBeginContact(self: BaseActor): Observable<number>;
116
+ /**
117
+ * Get a subscription to contact ended events where the value of the subscription
118
+ * is some unique number identifying the object in which the actor is in contact.
119
+ */
120
+ onEndContact(self: BaseActor): Observable<number>;
121
+ onHasContactChanged(self: BaseActor): Observable<boolean>;
122
+ onBeginOverlapWithActorType<T extends BaseActor, A extends BaseActor>(self: T, actorType: AbstractType<A>): Observable<A>;
123
+ onEndOverlapWithActorType<T extends BaseActor, A extends BaseActor>(self: T, actorType: AbstractType<A>): Observable<A>;
113
124
  onBeginOverlapWithActor<T extends BaseActor, A extends BaseActor>(self: T, actor: A): Observable<A>;
114
125
  onEndOverlapWithActor<T extends BaseActor, A extends BaseActor>(self: T, actor: A): Observable<A>;
115
126
  onCollisionWithActor<A extends BaseActor, S extends BaseActor>(self: S, actor: A): Observable<A>;
116
- onCollisionWithActorType<A extends BaseActor, S extends BaseActor>(self: S, actorType: Type<A>): Observable<A>;
117
- /**
118
- * Whenever there is collision with anything in the world which is not a trigger volume?
119
- * I suppose I can filter out trigger bodies.
120
- * Only return collision contact information
121
- *
122
- * It should be possible to pass in a collision filter (mask) to be able to narrow down the search.
123
- * Collision groups should be defined in code as integers. I suppose I can also have predefined collision groups that are available both in the editor and here.
124
- *
125
- * You might want more information about the object you are colliding with.
126
- * If it is a static object, I could provide the raw threejs mesh object.
127
- * I could also provide scene object information.
128
- */
129
- onCollision<S extends BaseActor>(self: S): Observable<CollisionContact>;
127
+ onCollisionWithActorType<A extends BaseActor, S extends BaseActor>(self: S, actorType: AbstractType<A>): Observable<A>;
130
128
  updateActorTransform(actor: BaseActor): void;
131
129
  private setupWorld;
132
130
  getActorContacts(actor: BaseActor, direction: Vector3): {
@@ -1,4 +1,4 @@
1
- import{__awaiter as e,__decorate as t,__metadata as i}from"tslib";import*as o from"@dimforge/rapier3d-compat";import{QueryFilterFlags as s}from"@dimforge/rapier3d-compat";import{Quaternion as r,RaycastResult as n,Vec3 as l}from"cannon-es";import{filter as a,map as c,Observable as d,Subject as h,takeUntil as u}from"rxjs";import*as y from"three";import{ArrowHelper as p,BufferAttribute as g,BufferGeometry as m,Group as f,LineSegments as w,Matrix4 as v,MeshBasicMaterial as x,Object3D as B,Raycaster as b,Scene as A,Vector3 as C}from"three";import{Service as D}from"typedi";import{AssetMeshInstance as z}from"../../../scene/asset-resource-loader";import{BoxCollisionShape as T,CapsuleCollisionShape as M,ConeCollisionShape as R,ConvexPolyhedronCollisionShape as S,CylinderCollisionShape as E,PhysicalShapeMesh as W,PlaneCollisionShape as _,SphereCollisionShape as F,TrimeshCollisionShape as V}from"../../../";import{LandscapeGroup as P}from"../../../scene/landscape/landscape";import{ViewController as k}from"../render";import{World as I}from"../world";import*as L from"three/examples/jsm/utils/BufferGeometryUtils.js";import{calculateEffectiveScale as O}from"../../../utils/three/traverse";export class RayTestResult{constructor(){this.hasHit=!1,this.hitPoint=new C,this.hitNormal=new C}}new n,new l,new l;export var PhysicsBodyType;!function(e){e[e.dynamic=1]="dynamic",e[e.static=2]="static",e[e.kinematic=4]="kinematic",e[e.kinematicVelocityBased=8]="kinematicVelocityBased"}(PhysicsBodyType||(PhysicsBodyType={}));let j=class{set showDebug(e){this.shouldRenderDebug=e,this.debugMesh&&(this.debugMesh.visible=e)}get showDebug(){return this.shouldRenderDebug}constructor(e,t){this.viewController=e,this.gameWorld=t,this.staticMeshes=new Map,this.staticBodies=new Map,this.actorBodies=new Map,this.bodyActors=new Map,this.collisionEvents=new h,this.beforeStep=new h,this.afterStep=new h,this.shouldRenderDebug=!1,this._raycaster=new b,this._reusableResult=new RayTestResult,this._raytestDiff=new C,this._raytestDirection=new C,this.controlledActors=new Set,this.ready=this.setup()}createDebugMesh(){return new w(new m,new x({color:255}))}start(){return e(this,void 0,void 0,(function*(){return yield this.ready,this.handleTick(),this.ready}))}renderDebug(){null==this.debugMesh&&(this.debugMesh=this.createDebugMesh(),this.debugMesh.visible=this.shouldRenderDebug,this.debugMesh.raycast=function(){},this.gameWorld.scene.add(this.debugMesh));const e=this.world.debugRender();this.debugMesh.geometry.setAttribute("position",new g(e.vertices,3))}setup(){return e(this,void 0,void 0,(function*(){if(null!=this.rapier)throw new Error("Rapier is already estup");this.rapier=yield X(),this.eventQueue=new o.EventQueue(!0),this.setupWorld()}))}handleTick(){this.viewController.onUpdate().subscribe((e=>{this.beforeStep.next(e),this.updatePhysics(),this.afterStep.next(e),this.showDebug&&this.renderDebug(),this.world.bodies.forEach((e=>{var t,i,o;if(e.isFixed())return;const s=null!==(t=this.staticMeshes.get(e))&&void 0!==t?t:null===(i=this.bodyActors.get(e))||void 0===i?void 0:i.object;var r,n;null!=s&&(Y(s.position,e.translation()),(e.isDynamic()||e.isKinematic()&&!this.controlledActors.has(null===(o=this.bodyActors.get(e))||void 0===o?void 0:o.id))&&(r=s.quaternion,n=e.rotation(),r.x=n.x,r.y=n.y,r.z=n.z,r.w=n.w))}))}))}_updateWorld(){this.world.timestep=0,this.world.step()}updatePhysics(){this.world.step(this.eventQueue),this.eventQueue.drainCollisionEvents(((e,t,i)=>{this.collisionEvents.next({handle1:e,handle2:t,started:i}),this.collisionEvents.next({handle1:t,handle2:e,started:i})}))}rayTestFromCamera(e,t,i){this._raycaster.setFromCamera(K,this.viewController.getCamera());const o=this._raycaster.ray.origin,s=this._raycaster.ray.direction.multiplyScalar(e).add(o);return this.rayTest(o,s,t,i)}rayTest(e,t,i,s){var r,n;null==i&&(i=this._reusableResult);const l=this._raytestDiff,a=this._raytestDirection;if(l.subVectors(t,e),a.copy(l).normalize(),0===a.length())return console.warn("Ray test called with to and from being equal"),i;const c=new o.Ray(e,a),d=l.length(),h=this.world.castRayAndGetNormal(c,d,!1,void 0,void 0,void 0,null!=(null==s?void 0:s.excludeActor)?this.actorBodies.get(s.excludeActor.id):void 0);if(i.hasHit=null!=h,i.hasHit){const t=c.pointAt(h.toi);i._internal=h,Y(i.hitNormal,h.normal),Y(i.hitPoint,t),i.distance=$.subVectors(i.hitPoint,e).length();const o=this.world.bodies.getAll().find((e=>function(e,t){for(let i=0,o=e.numColliders();i<o;i++){const o=e.collider(i);if(t(o))return o}}(e,(e=>e===h.collider))));i.actor=null!=o?this.bodyActors.get(o):null}if(this.showDebug){const t=new p(a,e,d,null!==(r=null==s?void 0:s.debugColor)&&void 0!==r?r:255);this.gameWorld.scene.add(t),setTimeout((()=>this.gameWorld.scene.remove(t)),null!==(n=null==s?void 0:s.debugLifetime)&&void 0!==n?n:200)}return this._reusableResult}setGravity(e,t,i){this.world.gravity.x=e,this.world.gravity.y=t,this.world.gravity.z=i}getGravity(){return Q.set(this.world.gravity.x,this.world.gravity.y,this.world.gravity.z)}addFromScene(e){this.addRecursively(e)}addRecursively(e){var t,i;if(this.removeSceneObject(e),!function(e){var t,i;if(null!=(null===(t=e.userData)||void 0===t?void 0:t.src)){return"actor"===(null===(i=e.userData)||void 0===i?void 0:i.src).type}return!1}(e))if(e instanceof W&&null!=e.collisionShape){const t=this.createStaticBody(e,[e.collisionShape]);this.staticMeshes.set(t,e),this.staticBodies.set(e,t)}else if(e instanceof z&&!1!==(null===(i=null===(t=e.userData)||void 0===t?void 0:t.src)||void 0===i?void 0:i.collisionDetection))if(e.children[0]&&e.children[0].instanceMatrix)this.createForInstancedMesh(e.children[0],e.collisionShapes);else{const t=this.createStaticBody(e,e.collisionShapes);this.staticMeshes.set(t,e),this.staticBodies.set(e,t)}else e instanceof P?this.addLandscapeGroup(e):(e instanceof f||e instanceof A)&&e.children.forEach((e=>this.addRecursively(e)))}createForInstancedMesh(e,t){const i=new v;for(let o=0;o<e.count;o++){const s=new B;s.matrix.identity(),i.fromArray(e.instanceMatrix.array,16*o),s.applyMatrix4(i);this.createStaticBody(s,t)}}getCharacterController(e=.01){var t;return null===(t=this.world)||void 0===t?void 0:t.createCharacterController(e)}getActorComputedMovement(e,t,i){const o=this.actorBodies.get(e.id);this.controlledActors.add(e.id);const r=o.collider(0);t.computeColliderMovement(r,i,s.EXCLUDE_SENSORS,null,te);const n=t.computedMovement();return Y(ee,n),ee}setNextKinematicTranslation(e,t){const i=this.actorBodies.get(e.id),o=i.translation();o.x+=t.x,o.y+=t.y,o.z+=t.z,null==i||i.setNextKinematicTranslation(o)}setAngularVelocity(e,t){const i=this.actorBodies.get(e.id);U.x=t.x,U.y=t.y,U.z=t.z,null==i||i.setAngvel(U,!0)}setLinearVelocity(e,t){const i=this.actorBodies.get(e.id);U.x=t.x,U.y=t.y,U.z=t.z,null==i||i.setLinvel(U,!0)}getLinearVelocity(e,t=new C){const i=this.actorBodies.get(e.id).linvel();return t.x=i.x,t.y=i.y,t.z=i.z,t}getAngularVelocity(e,t=new C){const i=this.actorBodies.get(e.id).angvel();return t.x=i.x,t.y=i.y,t.z=i.z,t}setLinearDamping(e,t){const i=this.actorBodies.get(e.id);null==i||i.setLinearDamping(t)}setAngularDamping(e,t){const i=this.actorBodies.get(e.id);null==i||i.setAngularDamping(t)}createCharacterCollision(){return new o.CharacterCollision}addLandscapeGroup(e){const t=e.userData.src,i=t.landscape.heightMaps;for(const r of e.sections){this.staticBodies.has(r)&&this.world.removeRigidBody(this.staticBodies.get(r));const e=t.landscape.options.density+1,n=t.landscape.options.sectionSize,l=new Array(e);for(let t=0;t<e;t++)l[t]=new Array(e).fill(0);const a=i.find((e=>e.x===r.x&&e.y==r.y));if(null!=a)for(const t of a.points){if(null==l[t.i%e])continue;const i=e-1-Math.floor(t.i/e);i in l[t.i%e]?l[t.i%e][i]=t.y/n:console.warn("wrong index",{points:l,point:t,i:t.i%e,k:i,heightMap:a})}const c=t.landscape.options.density,d=l.flatMap((e=>e.reverse())),h=o.ColliderDesc.heightfield(c,c,new Float32Array(d),new o.Vector3(n,n,n));var s=r.getWorldPosition(new C);const u=this.world.createRigidBody(o.RigidBodyDesc.fixed()),y=new o.Vector3(0,0,0);J(y,s),u.setTranslation(y,!1),this.world.createCollider(h,u),this.staticBodies.set(r,u)}}addActor(e,t,i={}){var s,r;if(0==t.length)return void console.error("No collision shapes were defined when adding actor to the physics system.");this.removeActor(e);const n=e.object;let l;switch(null!==(s=i.type)&&void 0!==s?s:PhysicsBodyType.static){case PhysicsBodyType.dynamic:l=o.RigidBodyDesc.dynamic(),l.mass=null!==(r=i.mass)&&void 0!==r?r:1;break;case PhysicsBodyType.kinematic:l=o.RigidBodyDesc.kinematicPositionBased();break;case PhysicsBodyType.kinematicVelocityBased:l=o.RigidBodyDesc.kinematicVelocityBased();break;default:l=(i.isTrigger,o.RigidBodyDesc.kinematicVelocityBased())}const a=this.world.createRigidBody(l);a.enableCcd(1==i.continousCollisionDetection);for(const e of t)this.addShape(a,e,n);Z(a,(e=>{null!=i.isTrigger&&(e.setSensor(i.isTrigger),e.setActiveCollisionTypes(o.ActiveCollisionTypes.ALL)),null!=i.friction&&e.setFriction(i.friction),null!=i.restitution&&e.setDensity(i.restitution),null!=i.mass&&e.setMass(i.mass),null!=i.restitution&&e.setRestitution(i.restitution)})),G(a,n),this.actorBodies.set(e.id,a),this.bodyActors.set(a,e)}applyTorque(e,t){const i=this.actorBodies.get(e.id);U.x=t.x,U.y=t.y,U.z=t.z,null==i||i.addTorque(U,!0)}applyTorqueImpulse(e,t){const i=this.actorBodies.get(e.id);U.x=t.x,U.y=t.y,U.z=t.z,null==i||i.applyTorqueImpulse(U,!0)}resetForces(e){const t=this.actorBodies.get(e.id);null==t||t.resetForces(!1)}resetTorques(e){const t=this.actorBodies.get(e.id);null==t||t.resetTorques(!1)}applyForce(e,t){const i=this.actorBodies.get(e.id);U.x=t.x,U.y=t.y,U.z=t.z,null==i||i.addForce(U,!0)}applyImpulse(e,t){const i=this.actorBodies.get(e.id);U.x=t.x,U.y=t.y,U.z=t.z,null==i||i.applyImpulse(U,!0)}applyLocalForce(e,t,i){const o=this.actorBodies.get(e.id);J(U,t),null==i?null==o||o.addForce(U,!0):(J(H,i),null==o||o.addForceAtPoint(U,H,!0))}applyLocalImpulse(e,t,i){const o=this.actorBodies.get(e.id);J(U,t),null==i?o.applyImpulse(U,!0):(J(H,i),o.applyImpulseAtPoint(U,H,!0))}removeActor(e){this.controlledActors.delete(e.id);const t=this.actorBodies.get(e.id);null!=t&&(this.bodyActors.delete(t),this.world.removeRigidBody(t)),this.actorBodies.delete(e.id)}removeSceneObject(e){let t=this.staticBodies.get(e);null!=t&&this.world.getRigidBody(t.handle)&&this.world.removeRigidBody(t)}activateActorEvents(e){const t=this.actorBodies.get(e.id);t&&Z(t,(e=>e.setActiveEvents(o.ActiveEvents.COLLISION_EVENTS)))}_onCollisionWithActorEvent(e,t,i){return this.activateActorEvents(e),this.collisionEvents.pipe(u(e.disposed),a((({started:e})=>e===i)),c((({handle1:e,handle2:t,started:i})=>({a1:this.bodyActors.get(this.world.getCollider(e).parent()),a2:this.bodyActors.get(this.world.getCollider(t).parent()),started:i}))),a((({a1:i,a2:o})=>null!=i&&null!=o&&i.id===e.id&&t(i,o))),c((({a2:e})=>e)))}onBeginOverlapWithActorType(e,t){return this._onCollisionWithActorEvent(e,((e,i)=>i instanceof t),!0)}onEndOverlapWithActorType(e,t){return this._onCollisionWithActorEvent(e,((e,i)=>i instanceof t),!1)}onBeginOverlapWithActor(e,t){return this._onCollisionWithActorEvent(e,((e,i)=>t.id===i.id),!0)}onEndOverlapWithActor(e,t){return this._onCollisionWithActorEvent(e,((e,i)=>t.id===i.id),!1)}onCollisionWithActor(e,t){return this.onBeginOverlapWithActor(e,t)}onCollisionWithActorType(e,t){return this.onBeginOverlapWithActorType(e,t)}onCollision(e){return new d((t=>{if(null==this.actorBodies.get(e.id))throw new Error("Actor must be added to the physics system before setting up collision event handler");return()=>{}}))}updateActorTransform(e){const t=this.actorBodies.get(e.id);null!=t?G(t,e.object):console.warn("Actor has not been added to physics world",e)}setupWorld(){const e=new o.World({x:0,y:-9.81,z:0});this.world=e,e.maxVelocityIterations=4}getActorContacts(e,t){const i=this.actorBodies.get(e.id);if(i&&i.numColliders()>0){const s=i.collider(0);let r=s.shape,n=s.translation(),l=s.rotation(),a=t,c=.3;const d=this.world.castShape(n,l,a,r,c,!0,null,null,null,this.actorBodies.get(e.id),(e=>e.shape.type!=o.ShapeType.HeightField));if(null!=d){const e=new C,t=new C,i=new C;return Y(e,d.witness2),Y(t,d.witness1),Y(i,d.normal1),i.negate(),[{ri:e,rj:t,ni:i}]}return[]}return console.warn("Actor is not added to the physics system"),[]}stop(){this.world.free()}createStaticBody(e,t){const i=this.world.createRigidBody(o.RigidBodyDesc.kinematicPositionBased());for(const o of t)this.addShape(i,o,e);return G(i,e),i}addShape(e,t,i){const o=this.createShape(t,i.scale);o.friction=.1;const s=t.offset.clone().multiply(i.scale);var n,l;J(o.translation,s),n=o.rotation,l=(new r).setFromEuler(t.rotation.x,t.rotation.y,t.rotation.z),n.x=l.x,n.y=l.y,n.z=l.z,n.w=l.w;this.world.createCollider(o,e)}createShape(e,t){if(e instanceof T)return o.ColliderDesc.cuboid(e.dimensions.x*t.x/2,e.dimensions.y*t.y/2,e.dimensions.z*t.z/2);if(e instanceof M){return o.ColliderDesc.capsule(e.length/2*t.y,e.radius*Math.max(t.z,t.x))}if(e instanceof V){const t=null!=e.geometry.getIndex()?e.geometry:L.mergeVertices(e.geometry);return o.ColliderDesc.trimesh(new Float32Array(t.getAttribute("position").array),new Uint32Array(t.getIndex().array))}if(e instanceof S){let i;e.mesh instanceof y.Mesh?i=e.mesh.geometry:e.mesh instanceof y.BufferGeometry?i=e.mesh:console.log("Unknownd shape",{shapeInfo:e});const s=new Float32Array(i.getAttribute("position").array);if(e.mesh instanceof y.Mesh){const t=O(e.mesh);for(let e=0;e<s.length;e+=3)s[e]*=t.x,s[e+1]*=t.y,s[e+2]*=t.z}for(let e=0;e<s.length;e+=3)s[e]*=t.x,s[e+1]*=t.y,s[e+2]*=t.z;return o.ColliderDesc.convexHull(s)}return e instanceof F?o.ColliderDesc.ball(e.radius*Math.max(t.x,t.y,t.z)):e instanceof E?o.ColliderDesc.cylinder(e.height/2*t.y,e.radiusTop*Math.max(t.z,t.x)):e instanceof R?o.ColliderDesc.cone(e.height*t.y,e.radiusBottom/2*Math.max(t.z,t.x)):e instanceof _?o.ColliderDesc.cuboid(e.width/2*t.x,e.height/2*t.y,.01):(console.error("Unsupported shape",e),o.ColliderDesc.cuboid(1,1,1))}};j=t([D(),i("design:paramtypes",[k,I])],j);export{j as PhysicsSystem};const N=new C,q=new y.Quaternion;function G(e,t){const i=t.getWorldPosition(N),s=t.getWorldQuaternion(q);e.setTranslation(new o.Vector3(i.x,i.y,i.z),!1),e.setRotation(new o.Quaternion(s.x,s.y,s.z,s.w),!1)}const Q=new C,U=new o.Vector3(0,0,0),H=new o.Vector3(0,0,0),K=(new C,{x:0,y:0}),X=()=>e(void 0,void 0,void 0,(function*(){let e=yield import("@dimforge/rapier3d-compat");return yield e.init(),e}));function J(e,t){e.x=t.x,e.y=t.y,e.z=t.z}function Y(e,t){e.x=t.x,e.y=t.y,e.z=t.z}function Z(e,t){for(let i=0,o=e.numColliders();i<o;i++){t(e.collider(i))}}const $=new C,ee=new C,te=e=>!e.isSensor();
1
+ import{__awaiter as t,__decorate as e,__metadata as i}from"tslib";import*as s from"@dimforge/rapier3d-compat";import{QueryFilterFlags as o}from"@dimforge/rapier3d-compat";import{Quaternion as n,RaycastResult as r,Vec3 as a}from"cannon-es";import{BehaviorSubject as l,distinctUntilChanged as d,filter as c,map as h,Subject as u,takeUntil as y}from"rxjs";import*as p from"three";import{ArrowHelper as g,BufferAttribute as m,BufferGeometry as v,Group as f,LineSegments as w,Matrix4 as x,MeshBasicMaterial as b,Object3D as B,Raycaster as A,Scene as C,Vector3 as D}from"three";import{Service as z}from"typedi";import{AssetMeshInstance as T}from"../../../scene/asset-resource-loader";import{BoxCollisionShape as M,CapsuleCollisionShape as E,ConeCollisionShape as S,ConvexPolyhedronCollisionShape as R,CylinderCollisionShape as W,PhysicalShapeMesh as _,PlaneCollisionShape as V,SphereCollisionShape as F,TrimeshCollisionShape as P}from"../../../";import{LandscapeGroup as k}from"../../../scene/landscape/landscape";import{ViewController as I}from"../render";import{World as L}from"../world";import*as O from"three/examples/jsm/utils/BufferGeometryUtils.js";import{calculateEffectiveScale as N}from"../../../utils/three/traverse";export class RayTestResult{constructor(){this.hasHit=!1,this.hitPoint=new D,this.hitNormal=new D}}new r,new a,new a;export var PhysicsBodyType;!function(t){t[t.dynamic=1]="dynamic",t[t.static=2]="static",t[t.kinematic=4]="kinematic",t[t.kinematicVelocityBased=8]="kinematicVelocityBased"}(PhysicsBodyType||(PhysicsBodyType={}));let j=class{set showDebug(t){this.shouldRenderDebug=t,this.debugMesh&&(this.debugMesh.visible=t)}get showDebug(){return this.shouldRenderDebug}constructor(t,e){this.viewController=t,this.gameWorld=e,this.staticMeshes=new Map,this.staticBodies=new Map,this.actorBodies=new Map,this.bodyActors=new Map,this.collisionEvents=new u,this.beforeStep=new u,this.afterStep=new u,this.shouldRenderDebug=!1,this._raycaster=new A,this._reusableResult=new RayTestResult,this._raytestDiff=new D,this._raytestDirection=new D,this.controlledActors=new Set,this.ready=this.setup()}createDebugMesh(){return new w(new v,new b({color:255}))}start(){return t(this,void 0,void 0,(function*(){return yield this.ready,this.handleTick(),this.ready}))}renderDebug(){null==this.debugMesh&&(this.debugMesh=this.createDebugMesh(),this.debugMesh.visible=this.shouldRenderDebug,this.debugMesh.raycast=function(){},this.gameWorld.scene.add(this.debugMesh));const t=this.world.debugRender();this.debugMesh.geometry.setAttribute("position",new m(t.vertices,3))}setup(){return t(this,void 0,void 0,(function*(){if(null!=this.rapier)throw new Error("Rapier is already estup");this.rapier=yield J(),this.eventQueue=new s.EventQueue(!0),this.setupWorld()}))}handleTick(){this.fixedupdateSub=this.viewController.onUpdate().subscribe((t=>{t=Math.min(.1,t),this.beforeStep.next(t),this.updatePhysics(t),this.afterStep.next(t),this.showDebug&&this.renderDebug(),this.world.bodies.forEach((t=>{var e,i,s;if(t.isFixed())return;const o=null!==(e=this.staticMeshes.get(t))&&void 0!==e?e:null===(i=this.bodyActors.get(t))||void 0===i?void 0:i.object;var n,r;null!=o&&(o.parent instanceof C&&(Z(o.position,t.translation()),(t.isDynamic()||t.isKinematic()&&!this.controlledActors.has(null===(s=this.bodyActors.get(t))||void 0===s?void 0:s.id))&&(n=o.quaternion,r=t.rotation(),n.x=r.x,n.y=r.y,n.z=r.z,n.w=r.w)))}))}))}_updateWorld(){this.world.timestep=0,this.world.step()}updatePhysics(t){this.world.timestep=t,this.world.step(this.eventQueue),this.eventQueue.drainCollisionEvents(((t,e,i)=>{this.collisionEvents.next({handle1:t,handle2:e,started:i}),this.collisionEvents.next({handle1:e,handle2:t,started:i})}))}rayTestFromCamera(t,e,i){this._raycaster.setFromCamera(X,this.viewController.getCamera());const s=this._raycaster.ray.origin,o=this._raycaster.ray.direction.multiplyScalar(t).add(s);return this.rayTest(s,o,e,i)}rayTest(t,e,i,o){var n,r;null==i&&(i=this._reusableResult);const a=this._raytestDiff,l=this._raytestDirection;if(a.subVectors(e,t),l.copy(a).normalize(),0===l.length())return console.warn("Ray test called with to and from being equal"),i;const d=new s.Ray(t,l),c=a.length(),h=this.world.castRayAndGetNormal(d,c,!1,void 0,void 0,void 0,null!=(null==o?void 0:o.excludeActor)?this.actorBodies.get(o.excludeActor.id):void 0);if(i.hasHit=null!=h,i.hasHit){const e=d.pointAt(h.toi);i._internal=h,Z(i.hitNormal,h.normal),Z(i.hitPoint,e),i.distance=tt.subVectors(i.hitPoint,t).length();const s=this.world.bodies.getAll().find((t=>function(t,e){for(let i=0,s=t.numColliders();i<s;i++){const s=t.collider(i);if(e(s))return s}}(t,(t=>t===h.collider))));i.actor=null!=s?this.bodyActors.get(s):null}if(this.showDebug){const e=new g(l,t,c,null!==(n=null==o?void 0:o.debugColor)&&void 0!==n?n:255);this.gameWorld.scene.add(e),setTimeout((()=>this.gameWorld.scene.remove(e)),null!==(r=null==o?void 0:o.debugLifetime)&&void 0!==r?r:200)}return this._reusableResult}setGravity(t,e,i){this.world.gravity.x=t,this.world.gravity.y=e,this.world.gravity.z=i}getGravity(){return H.set(this.world.gravity.x,this.world.gravity.y,this.world.gravity.z)}addFromScene(t){this.addRecursively(t);for(const t of this.staticBodies.values())$(t,(t=>t.setActiveEvents(s.ActiveEvents.COLLISION_EVENTS)))}addRecursively(t){var e,i;if(this.removeSceneObject(t),!function(t){var e,i;if(null!=(null===(e=t.userData)||void 0===e?void 0:e.src)){return"actor"===(null===(i=t.userData)||void 0===i?void 0:i.src).type}return!1}(t))if(t instanceof _&&null!=t.collisionShape){const e=this.createStaticBody(t,[t.collisionShape]);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else if(t instanceof T&&!1!==(null===(i=null===(e=t.userData)||void 0===e?void 0:e.src)||void 0===i?void 0:i.collisionDetection))if(t.children[0]&&t.children[0].instanceMatrix)this.createForInstancedMesh(t.children[0],t.collisionShapes);else{const e=this.createStaticBody(t,t.collisionShapes);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else t instanceof k?this.addLandscapeGroup(t):(t instanceof f||t instanceof C)&&t.children.forEach((t=>this.addRecursively(t)))}createForInstancedMesh(t,e){const i=new x;for(let s=0;s<t.count;s++){const o=new B;o.matrix.identity(),i.fromArray(t.instanceMatrix.array,16*s),o.applyMatrix4(i);this.createStaticBody(o,e)}}getCharacterController(t=.01){var e;return null===(e=this.world)||void 0===e?void 0:e.createCharacterController(t)}getActorComputedMovement(t,e,i){const s=this.actorBodies.get(t.id);this.controlledActors.add(t.id);const n=s.collider(0);e.computeColliderMovement(n,i,o.EXCLUDE_SENSORS,null,it);const r=e.computedMovement();return Z(et,r),et}setNextKinematicTranslation(t,e){const i=this.actorBodies.get(t.id),s=i.translation();s.x+=e.x,s.y+=e.y,s.z+=e.z,null==i||i.setNextKinematicTranslation(s)}setAngularVelocity(t,e){const i=this.actorBodies.get(t.id);U.x=e.x,U.y=e.y,U.z=e.z,null==i||i.setAngvel(U,!0)}setLinearVelocity(t,e){const i=this.actorBodies.get(t.id);U.x=e.x,U.y=e.y,U.z=e.z,null==i||i.setLinvel(U,!0)}getLinearVelocity(t,e=new D){const i=this.actorBodies.get(t.id).linvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}getAngularVelocity(t,e=new D){const i=this.actorBodies.get(t.id).angvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}setLinearDamping(t,e){const i=this.actorBodies.get(t.id);null==i||i.setLinearDamping(e)}setAngularDamping(t,e){const i=this.actorBodies.get(t.id);null==i||i.setAngularDamping(e)}createCharacterCollision(){return new s.CharacterCollision}addLandscapeGroup(t){const e=t.userData.src,i=e.landscape.heightMaps;for(const n of t.sections){this.staticBodies.has(n)&&this.world.removeRigidBody(this.staticBodies.get(n));const t=e.landscape.options.density+1,r=e.landscape.options.sectionSize,a=new Array(t);for(let e=0;e<t;e++)a[e]=new Array(t).fill(0);const l=i.find((t=>t.x===n.x&&t.y==n.y));if(null!=l)for(const e of l.points){if(null==a[e.i%t])continue;const i=t-1-Math.floor(e.i/t);i in a[e.i%t]?a[e.i%t][i]=e.y/r:console.warn("wrong index",{points:a,point:e,i:e.i%t,k:i,heightMap:l})}const d=e.landscape.options.density,c=a.flatMap((t=>t.reverse())),h=s.ColliderDesc.heightfield(d,d,new Float32Array(c),new s.Vector3(r,r,r));var o=n.getWorldPosition(new D);const u=this.world.createRigidBody(s.RigidBodyDesc.fixed()),y=new s.Vector3(0,0,0);Y(y,o),u.setTranslation(y,!1),this.world.createCollider(h,u),this.staticBodies.set(n,u)}}addActor(t,e,i={}){var o,n;if(0==e.length)return void console.error("No collision shapes were defined when adding actor to the physics system.");this.removeActor(t);const r=t.object;let a;switch(null!==(o=i.type)&&void 0!==o?o:PhysicsBodyType.static){case PhysicsBodyType.dynamic:a=s.RigidBodyDesc.dynamic(),a.mass=null!==(n=i.mass)&&void 0!==n?n:1;break;case PhysicsBodyType.kinematic:a=s.RigidBodyDesc.kinematicPositionBased();break;case PhysicsBodyType.kinematicVelocityBased:a=s.RigidBodyDesc.kinematicVelocityBased();break;default:a=(i.isTrigger,s.RigidBodyDesc.kinematicVelocityBased())}const l=this.world.createRigidBody(a);l.enableCcd(1==i.continousCollisionDetection);for(const t of e)this.addShape(l,t,r);$(l,(t=>{null!=i.isTrigger&&(t.setSensor(i.isTrigger),t.setActiveCollisionTypes(s.ActiveCollisionTypes.ALL),t.setActiveEvents(s.ActiveEvents.COLLISION_EVENTS)),null!=i.friction&&t.setFriction(i.friction),null!=i.restitution&&t.setDensity(i.restitution),null!=i.mass&&t.setMass(i.mass),null!=i.restitution&&t.setRestitution(i.restitution)})),Q(l,r),this.actorBodies.set(t.id,l),this.bodyActors.set(l,t)}applyTorque(t,e){const i=this.actorBodies.get(t.id);U.x=e.x,U.y=e.y,U.z=e.z,null==i||i.addTorque(U,!0)}applyTorqueImpulse(t,e){const i=this.actorBodies.get(t.id);U.x=e.x,U.y=e.y,U.z=e.z,null==i||i.applyTorqueImpulse(U,!0)}resetForces(t){const e=this.actorBodies.get(t.id);null==e||e.resetForces(!1)}resetTorques(t){const e=this.actorBodies.get(t.id);null==e||e.resetTorques(!1)}applyForce(t,e){const i=this.actorBodies.get(t.id);U.x=e.x,U.y=e.y,U.z=e.z,null==i||i.addForce(U,!0)}applyImpulse(t,e){const i=this.actorBodies.get(t.id);U.x=e.x,U.y=e.y,U.z=e.z,null==i||i.applyImpulse(U,!0)}applyLocalForce(t,e,i){const s=this.actorBodies.get(t.id);Y(U,e),null==i?null==s||s.addForce(U,!0):(Y(K,i),null==s||s.addForceAtPoint(U,K,!0))}applyLocalImpulse(t,e,i){const s=this.actorBodies.get(t.id);Y(U,e),null==i?s.applyImpulse(U,!0):(Y(K,i),s.applyImpulseAtPoint(U,K,!0))}removeActor(t){this.controlledActors.delete(t.id);const e=this.actorBodies.get(t.id);null!=e&&(this.bodyActors.delete(e),this.world.removeRigidBody(e)),this.actorBodies.delete(t.id)}removeSceneObject(t){let e=this.staticBodies.get(t);null!=e&&this.world.getRigidBody(e.handle)&&this.world.removeRigidBody(e)}activateActorEvents(t){this.actorBodies.get(t.id)}_onCollisionWithActorEvent(t,e,i){return this.activateActorEvents(t),this.collisionEvents.pipe(y(t.disposed),c((({started:t})=>t===i)),h((({handle1:t,handle2:e,started:i})=>({a1:this.bodyActors.get(this.world.getCollider(t).parent()),a2:this.bodyActors.get(this.world.getCollider(e).parent()),started:i}))),c((({a1:i,a2:s})=>null!=i&&null!=s&&i.id===t.id&&e(i,s))),h((({a2:t})=>t)))}onBeginContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(y(t.disposed),c((t=>t.started)),c((({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e).parent());return null!=i&&i.id===t.id})),h((t=>t.handle2)))}onEndContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(y(t.disposed),c((t=>!t.started)),c((({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e).parent());return null!=i&&i.id===t.id})),h((t=>t.handle2)))}onHasContactChanged(t){const e=new Set,i=new l(!1);return this.onBeginContact(t).subscribe((t=>{e.add(t),i.next(e.size>0)})),this.onEndContact(t).subscribe((t=>{e.delete(t),i.next(e.size>0)})),i.pipe(d())}onBeginOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>i instanceof e),!0)}onEndOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>i instanceof e),!1)}onBeginOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>e.id===i.id),!0)}onEndOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>e.id===i.id),!1)}onCollisionWithActor(t,e){return this.onBeginOverlapWithActor(t,e)}onCollisionWithActorType(t,e){return this.onBeginOverlapWithActorType(t,e)}updateActorTransform(t){const e=this.actorBodies.get(t.id);null!=e?Q(e,t.object):console.warn("Actor has not been added to physics world",t)}setupWorld(){const t=new s.World({x:0,y:-9.81,z:0});this.world=t,t.maxVelocityIterations=4}getActorContacts(t,e){const i=this.actorBodies.get(t.id);if(i&&i.numColliders()>0){const o=i.collider(0);let n=o.shape,r=o.translation(),a=o.rotation(),l=e,d=.3;const c=this.world.castShape(r,a,l,n,d,!0,null,null,null,this.actorBodies.get(t.id),(t=>t.shape.type!=s.ShapeType.HeightField));if(null!=c){const t=new D,e=new D,i=new D;return Z(t,c.witness2),Z(e,c.witness1),Z(i,c.normal1),i.negate(),[{ri:t,rj:e,ni:i}]}return[]}return console.warn("Actor is not added to the physics system"),[]}stop(){var t,e,i;null===(t=this.world)||void 0===t||t.bodies.forEach((t=>this.world.removeRigidBody(t))),null===(e=this.world)||void 0===e||e.free(),null===(i=this.fixedupdateSub)||void 0===i||i.unsubscribe()}createStaticBody(t,e){const i=this.world.createRigidBody(s.RigidBodyDesc.kinematicPositionBased());for(const s of e)this.addShape(i,s,t);return Q(i,t),i}addShape(t,e,i){const s=this.createShape(e,i.scale);s.friction=.1;const o=e.offset.clone().multiply(i.scale);var r,a;Y(s.translation,o),r=s.rotation,a=(new n).setFromEuler(e.rotation.x,e.rotation.y,e.rotation.z),r.x=a.x,r.y=a.y,r.z=a.z,r.w=a.w;this.world.createCollider(s,t)}createShape(t,e){if(t instanceof M)return s.ColliderDesc.cuboid(t.dimensions.x*e.x/2,t.dimensions.y*e.y/2,t.dimensions.z*e.z/2);if(t instanceof E){return s.ColliderDesc.capsule(t.length/2*e.y,t.radius*Math.max(e.z,e.x))}if(t instanceof P){const e=null!=t.geometry.getIndex()?t.geometry:O.mergeVertices(t.geometry);return s.ColliderDesc.trimesh(new Float32Array(e.getAttribute("position").array),new Uint32Array(e.getIndex().array))}if(t instanceof R){let i;t.mesh instanceof p.Mesh?i=t.mesh.geometry:t.mesh instanceof p.BufferGeometry?i=t.mesh:console.log("Unknownd shape",{shapeInfo:t});const o=new Float32Array(i.getAttribute("position").array);if(t.mesh instanceof p.Mesh){const e=N(t.mesh);for(let t=0;t<o.length;t+=3)o[t]*=e.x,o[t+1]*=e.y,o[t+2]*=e.z}for(let t=0;t<o.length;t+=3)o[t]*=e.x,o[t+1]*=e.y,o[t+2]*=e.z;return s.ColliderDesc.convexHull(o)}return t instanceof F?s.ColliderDesc.ball(t.radius*Math.max(e.x,e.y,e.z)):t instanceof W?s.ColliderDesc.cylinder(t.height/2*e.y,t.radiusTop*Math.max(e.z,e.x)):t instanceof S?s.ColliderDesc.cone(t.height*e.y,t.radiusBottom/2*Math.max(e.z,e.x)):t instanceof V?s.ColliderDesc.cuboid(t.width/2*e.x,t.height/2*e.y,.01):(console.error("Unsupported shape",t),s.ColliderDesc.cuboid(1,1,1))}};j=e([z(),i("design:paramtypes",[I,L])],j);export{j as PhysicsSystem};const q=new D,G=new p.Quaternion;function Q(t,e){const i=e.getWorldPosition(q),o=e.getWorldQuaternion(G);t.setTranslation(new s.Vector3(i.x,i.y,i.z),!1),t.setRotation(new s.Quaternion(o.x,o.y,o.z,o.w),!1)}const H=new D,U=new s.Vector3(0,0,0),K=new s.Vector3(0,0,0),X=(new D,{x:0,y:0}),J=()=>t(void 0,void 0,void 0,(function*(){let t=yield import("@dimforge/rapier3d-compat");return yield t.init(),t}));function Y(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function Z(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function $(t,e){for(let i=0,s=t.numColliders();i<s;i++){e(t.collider(i))}}const tt=new D,et=new D,it=t=>!t.isSensor();
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -9,6 +9,10 @@ export declare class ViewController {
9
9
  private readonly lateTick;
10
10
  readonly audioListener: THREE.AudioListener;
11
11
  constructor(view: RenderingView);
12
+ set fpsCap(fps: number);
13
+ get fpsCap(): number;
14
+ set showStats(value: boolean);
15
+ get showStats(): boolean;
12
16
  onUpdate(actor?: any): Observable<number>;
13
17
  onLateUpdate(actor?: any): Observable<number>;
14
18
  setCamera(camera: Camera | CameraActor): void;
@@ -1,4 +1,4 @@
1
- import{__decorate as e,__metadata as t}from"tslib";import{Service as i}from"typedi";import{RenderingView as s}from"../../rendering";import{Subject as r,takeUntil as a}from"rxjs";import*as n from"three";import{CameraActor as o}from"../../gameplay/actors/builtin/camera-actor";let p=class{constructor(e){this.view=e,this.tick=new r,this.lateTick=new r,this.audioListener=new n.AudioListener,e.onLoop((e=>{this.tick.next(e),this.lateTick.next(e)})),e.camera.add(this.audioListener)}onUpdate(e){return null!=e&&this.tick.pipe(a(e.disposed)),this.tick}onLateUpdate(e){return null!=e&&this.lateTick.pipe(a(e.disposed)),this.lateTick}setCamera(e){const t=e instanceof o?e.camera.instance:e;this.view.setCamera(t),t.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()}};p=e([i(),t("design:paramtypes",[s])],p);export{p as ViewController};
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 a,takeUntil as r}from"rxjs";import*as o from"three";import{CameraActor as n}from"../../gameplay/actors/builtin/camera-actor";let p=class{constructor(t){this.view=t,this.tick=new a,this.lateTick=new a,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(r(t.disposed)),this.tick}onLateUpdate(t){return null!=t&&this.lateTick.pipe(r(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()}};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.
@@ -36,6 +36,10 @@ export declare class RenderingView {
36
36
  private onLoopCallbacks;
37
37
  onLoop(onFrame: (deltaTime: number) => any): void;
38
38
  removeOnLoop(onFrame: (deltaTime: number) => any): void;
39
+ private stats;
40
+ private _showStats;
41
+ set showStats(value: boolean);
42
+ get showStats(): boolean;
39
43
  loop(onFrame: (deltaTime: number) => any, showStats?: boolean): void;
40
44
  private insetHeight;
41
45
  private insetWidth;
package/dist/rendering.js CHANGED
@@ -1,4 +1,4 @@
1
- import*as e from"three";import{Mesh as t,Matrix4 as i,ShaderMaterial as r,PerspectiveCamera as s,ShaderChunk as n}from"three";import{EffectComposer as a}from"three-stdlib";import{RenderPass as o}from"three-stdlib";import{ShaderPass as h}from"three-stdlib";import{FXAAShader as d}from"three-stdlib";import{CSM as l}from"three-stdlib";import{CSMUtil as c}from"./csm";import{GammaCorrectionShader as m}from"three-stdlib";import{Reflector as p}from"three-stdlib";import{depthUniformName as u,resolutionUniformName as g,supportsDepthTextureExtension as v,nearUniformName as f,farUniformName as w}from"./shader-nodes/depth";import{elapsedTimeUniformName as x}from"./shader-nodes/time";import{OutlinePass as b}from"./utils/three/outline-pass";import C from"./utils/three/stats";import{lambertVertexShaderOverride as R}from"./rendering/shader-override";import{DepthPass as y}from"./utils/three/depth-pass";const P=new e.MeshDepthMaterial;P.depthPacking=e.RGBADepthPacking,P.blending=e.NoBlending;n.lights_pars_begin;n.lights_lambert_vertex=R;export class RenderingView{setPaused(e){this.paused=e}resizeRender(){this.previousClientWith===this.container.clientWidth&&this.previousClientHeight===this.container.clientHeight||(this.camera instanceof s&&(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.composer.render()},this.onVisiblityChane=()=>{this.windowVisible=!document.hidden},this.isDepthTextureExtensionSupported=!1,this.onLoopCallbacks=[],this.insetHeight=200,this.insetWidth=this.insetHeight*(16/9),this.insetOffsetY=250,this.insetMargin=10,this.maxInsetCameras=4,this.overlayCameras=new Set,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.composer=new a(this.renderer);var r=t.clientWidth/t.clientHeight;const s=new e.PerspectiveCamera(45,r,.5,500);s.layers.enable(19),this.setCamera(s),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,c.renderingView=this,c.patchThreeAdd(),this.isDepthTextureExtensionSupported=v(this.renderer),t.replaceChildren(this.renderer.domElement),this.setupEventListeners(),this.depthRenderTarget=RenderingView.createDepthRenderTarget(this.renderer,this.container);const n=new o(this.scene,this.camera);if(this.composer.addPass(n),this.outlinePass=new b(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 h(d);e.uniforms.resolution.value.set(1/t.clientWidth,1/t.clientHeight),this.composer.addPass(e);var l=new h(m);l.clear=!1,this.composer.addPass(l)}}setCamera(t){this.camera=t,this.composer.passes.forEach((e=>{e instanceof o?e.camera=t:e instanceof b?e.renderCamera=t:e instanceof y&&(e.camera=t)})),null==this.csm?this.csm=new l({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 s&&(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 r=!!t.extensions.get("WEBGL_depth_texture");const s=new e.WebGLRenderTarget(i.clientWidth*t.getPixelRatio(),i.clientHeight*t.getPixelRatio());return s.texture.minFilter=e.NearestFilter,s.texture.magFilter=e.NearestFilter,s.texture.generateMipmaps=!1,s.stencilBuffer=!1,!0===r&&(s.depthTexture=new e.DepthTexture(128,128),s.depthTexture.type=e.UnsignedShortType,s.depthTexture.minFilter=e.NearestFilter,s.depthTexture.magFilter=e.NearestFilter),s}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)}loop(r,s=!1){var n=C();n.showPanel(0);performance.now();e.Ray.prototype.intersectTriangle;let a=0;const o=new i,h=new i,d=e=>{var i,s;const l=this.renderer.getContext();if(this.paused&&this.running&&l.drawingBufferHeight>1)return void setTimeout((()=>d(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;)r(T),e-=T;r(e)}else r(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=[],g=[];if(this.scene.traverse((i=>{var r,s,n,a,o,h;i instanceof t&&i.visible&&((null===(s=null===(r=i.material)||void 0===r?void 0:r.userData)||void 0===s?void 0:s.water)||(null===(n=i.material)||void 0===n?void 0:n.uniforms)&&null!=(null===(a=i.material)||void 0===a?void 0:a.uniforms[u]))?(i.visible=!1,m.push(i),this.initDepthUniform(i.material),i.renderOrder=100):i instanceof p&&(i.visible=!1,g.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[x])&&(i.material.uniforms[x].value=e)})),m.length>0){if(this.scene.overrideMaterial=P,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)),g.forEach((e=>e.visible=!0));try{!this.paused&&this.running&&(this.composer.render(c),this.renderOverlay())}catch(e){console.warn(e)}n.end(),null===(s=this.csm)||void 0===s||s.update(),this.running&&(this.fpsCap?setTimeout((()=>{requestAnimationFrame(d)}),1e3/this.fpsCap):requestAnimationFrame(d))};requestAnimationFrame(d)}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 r=0;r<e.length;r++)this.renderer.clearDepth(),this.renderer.setViewport(t-i/2+this.insetWidth*r+this.insetMargin*r,this.insetOffsetY,this.insetWidth,this.insetHeight),this.renderer.render(this.scene,e[r])}addOverlayCamera(e){this.overlayCameras.add(e)}clearOverlayCameras(){this.overlayCameras.clear()}removeOverlayCamera(e){this.overlayCameras.delete(e)}render(){this.composer.render()}initDepthUniform(e){e instanceof r&&(e.uniforms[u].value=this.isDepthTextureExtensionSupported?this.depthRenderTarget.depthTexture:this.depthRenderTarget.texture,null!=e.uniforms[g]&&e.uniforms[g].value.set(this.container.clientWidth*this.renderer.getPixelRatio(),this.container.clientHeight*this.renderer.getPixelRatio()),this.camera instanceof s&&(e.uniforms[f].value=this.camera.near,e.uniforms[w].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 T=.05;
1
+ import*as e from"three";import{Mesh as t,Matrix4 as i,ShaderMaterial as s,PerspectiveCamera as r,ShaderChunk as n}from"three";import{EffectComposer as a}from"three-stdlib";import{RenderPass as h}from"three-stdlib";import{ShaderPass as o}from"three-stdlib";import{FXAAShader as d}from"three-stdlib";import{CSM as l}from"three-stdlib";import{CSMUtil as c}from"./csm";import{GammaCorrectionShader as m}from"three-stdlib";import{Reflector as p}from"three-stdlib";import{depthUniformName as u,resolutionUniformName as g,supportsDepthTextureExtension as v,nearUniformName as f,farUniformName as w}from"./shader-nodes/depth";import{elapsedTimeUniformName as x}from"./shader-nodes/time";import{OutlinePass as C}from"./utils/three/outline-pass";import b from"./utils/three/stats";import{lambertVertexShaderOverride as R}from"./rendering/shader-override";import{DepthPass as y}from"./utils/three/depth-pass";const P=new e.MeshDepthMaterial;P.depthPacking=e.RGBADepthPacking,P.blending=e.NoBlending;n.lights_pars_begin;n.lights_lambert_vertex=R;export class RenderingView{setPaused(e){this.paused=e}resizeRender(){this.previousClientWith===this.container.clientWidth&&this.previousClientHeight===this.container.clientHeight||(this.camera instanceof r&&(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.composer.render()},this.onVisiblityChane=()=>{this.windowVisible=!document.hidden},this.isDepthTextureExtensionSupported=!1,this.onLoopCallbacks=[],this.stats=b(),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,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.composer=new a(this.renderer);var s=t.clientWidth/t.clientHeight;const r=new e.PerspectiveCamera(45,s,.5,500);r.layers.enable(19),this.setCamera(r),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,c.renderingView=this,c.patchThreeAdd(),this.isDepthTextureExtensionSupported=v(this.renderer),t.replaceChildren(this.renderer.domElement),this.setupEventListeners(),this.depthRenderTarget=RenderingView.createDepthRenderTarget(this.renderer,this.container);const n=new h(this.scene,this.camera);if(this.composer.addPass(n),this.outlinePass=new C(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 o(d);e.uniforms.resolution.value.set(1/t.clientWidth,1/t.clientHeight),this.composer.addPass(e);var l=new o(m);l.clear=!1,this.composer.addPass(l)}}setCamera(t){this.camera=t,this.composer.passes.forEach((e=>{e instanceof h?e.camera=t:e instanceof C?e.renderCamera=t:e instanceof y&&(e.camera=t)})),null==this.csm?this.csm=new l({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 r&&(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 h=new i,o=new i,d=e=>{var i,r;const l=this.renderer.getContext();if(this.paused&&this.running&&l.drawingBufferHeight>1)return void setTimeout((()=>d(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,h.copy(this.camera.matrixWorld),c>1){let e=c;for(;e>.05;)s(S),e-=S;s(e)}else s(c);this.onLoopCallbacks.forEach((e=>e(c))),null===(i=this.camera)||void 0===i||i.updateMatrixWorld(),o.copy(this.camera.matrixWorld),o.equals(h)||(this.renderer.shadowMap.needsUpdate=!0),this.resizeRender();const m=[],g=[];if(this.scene.traverse((i=>{var s,r,n,a,h,o;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[u]))?(i.visible=!1,m.push(i),this.initDepthUniform(i.material),i.renderOrder=100):i instanceof p&&(i.visible=!1,g.push(i)),i instanceof t&&(null===(h=i.material)||void 0===h?void 0:h.uniforms)&&null!=(null===(o=i.material)||void 0===o?void 0:o.uniforms[x])&&(i.material.uniforms[x].value=e)})),m.length>0){if(this.scene.overrideMaterial=P,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)),g.forEach((e=>e.visible=!0));try{!this.paused&&this.running&&(this.composer.render(c),this.renderOverlay())}catch(e){console.warn(e)}n.end(),null===(r=this.csm)||void 0===r||r.update(),this.running&&(this.fpsCap?setTimeout((()=>{requestAnimationFrame(d)}),1e3/this.fpsCap):requestAnimationFrame(d))};requestAnimationFrame(d)}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(){this.composer.render()}initDepthUniform(e){e instanceof s&&(e.uniforms[u].value=this.isDepthTextureExtensionSupported?this.depthRenderTarget.depthTexture:this.depthRenderTarget.texture,null!=e.uniforms[g]&&e.uniforms[g].value.set(this.container.clientWidth*this.renderer.getPixelRatio(),this.container.clientHeight*this.renderer.getPixelRatio()),this.camera instanceof r&&(e.uniforms[f].value=this.camera.near,e.uniforms[w].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 S=.05;
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, Texture } from 'three';
1
+ import { Object3D, Texture } from 'three';
2
2
  import { Asset } from './model';
3
3
  import { CollisionShape } from './collision/collision-shape';
4
4
  export declare class AssetResourceLoader {
@@ -8,8 +8,10 @@ export declare class AssetResourceLoader {
8
8
  private loadingManager;
9
9
  private glbLoader;
10
10
  private fbxLoader;
11
+ private objLoader;
11
12
  private textureLoader;
12
13
  private audioLoader;
14
+ protected onError(error: unknown): void;
13
15
  private makeReady;
14
16
  private ready;
15
17
  constructor();
@@ -26,7 +28,7 @@ export declare class AssetResourceLoader {
26
28
  export interface LoadedMesh {
27
29
  scene: AssetMeshInstance;
28
30
  }
29
- export declare class AssetMeshInstance extends Group {
31
+ export declare class AssetMeshInstance extends Object3D {
30
32
  collisionShapes?: CollisionShape[];
31
33
  }
32
34
  export declare function getElectronArg(name: string): string;
@@ -1,4 +1,4 @@
1
- import{__awaiter as e}from"tslib";import{AudioLoader as t,Group as i,LoadingManager as s,TextureLoader as o}from"three";import{GLTFLoader as r}from"three-stdlib";import{FBXLoader as n}from"three-stdlib";import{cloneMesh as a}from"../utils/mesh";import{pathJoin as h}from"../utils/files";import{Subject as l,firstValueFrom as d}from"rxjs";import{importCollisionShapes as c}from"./collision/collision-shape-import";const u=["glb","fbx"];export class AssetResourceLoader{constructor(){this.cache=new Map,this.textureCache=new Map,this.loadingManager=new s,this.glbLoader=new r(this.loadingManager),this.fbxLoader=new n(this.loadingManager),this.textureLoader=new o(this.loadingManager),this.audioLoader=new t(this.loadingManager),this.makeReady=new l,this.ready=d(this.makeReady),this.collisionShapeCache=new Map}setDataDir(e){this.basePath=h(e,"asset-resources"),this.makeReady.next(!0)}getUri(e){return h(this.basePath,e)+`?windowId=${getElectronArg("windowId")}`}getTexture(t){return e(this,void 0,void 0,(function*(){return null==t?null:(yield this.ready,this.cache.has(t.id)||(yield this.textureLoader.loadAsync(this.getUri(t.fileKey)).then((e=>(e.flipY=!1,this.textureCache.set(t.id,e),e)))),this.textureCache.get(t.id))}))}getMesh(t){var s;return e(this,void 0,void 0,(function*(){if(yield this.ready,!u.includes(null===(s=t.fileFormat)||void 0===s?void 0:s.toLowerCase()))return console.error("Unsupported mesh file format "+t.fileFormat,t),{scene:new i};this.cache.has(t.fileKey)||(yield this.loadMesh(t));const{scene:e}=this.cache.get(t.fileKey),o=this.computeCollisionShapes(t,e),r=(new AssetMeshInstance).copy(a(e));return r.collisionShapes=o,{scene:r}}))}getAudio(t){return e(this,void 0,void 0,(function*(){return yield this.ready,this.audioLoader.loadAsync(this.getUri(t.fileKey))}))}computeCollisionShapes(e,t){return this.collisionShapeCache.get(e.id)||this.collisionShapeCache.set(e.id,c(t)),this.collisionShapeCache.get(e.id)}loadMesh(t){return e(this,void 0,void 0,(function*(){return yield this.ready,yield this.loadByAsset(t).then((e=>(e.scene.animations=[],this.cache.set(t.fileKey,e),e)))}))}loadByAsset(e){const t=this.getUri(e.fileKey);switch(e.fileFormat){case"glb":return this.glbLoader.loadAsync(t).then((e=>({scene:e.scene})));case"fbx":return this.fbxLoader.loadAsync(t).then((e=>({scene:e})))}}}export class AssetMeshInstance extends i{}export function getElectronArg(e){var t;const i=`--${e}=`,s=null===(t=window.process)||void 0===t?void 0:t.argv.find((e=>e.startsWith(i)));return null==s?void 0:s.substring(i.length)}
1
+ import{__awaiter as e}from"tslib";import{AudioLoader as t,Group as i,LoadingManager as s,Mesh as r,Object3D as o,TextureLoader as n}from"three";import{GLTFLoader as a,MTLLoader as l,OBJLoader as h}from"three-stdlib";import{FBXLoader as c}from"three-stdlib";import{cloneMesh as d}from"../utils/mesh";import{pathJoin as u}from"../utils/files";import{Subject as f,firstValueFrom as p}from"rxjs";import{importCollisionShapes as m}from"./collision/collision-shape-import";import*as g from"three";import{iterateMaterials as y}from"../utils/materials";const v=["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 a(this.loadingManager),this.fbxLoader=new c(this.loadingManager),this.objLoader=new h(this.loadingManager),this.textureLoader=new n(this.loadingManager),this.audioLoader=new t(this.loadingManager),this.makeReady=new f,this.ready=p(this.makeReady),this.collisionShapeCache=new Map}setDataDir(e){this.basePath=u(e,"asset-resources"),this.makeReady.next(!0)}getUri(e){return u(this.basePath,e)+`?windowId=${getElectronArg("windowId")}`}getTexture(t){return e(this,void 0,void 0,(function*(){return null==t?null:(yield this.ready,this.cache.has(t.id)||(yield this.textureLoader.loadAsync(this.getUri(t.fileKey)).then((e=>{var i,s;return e.wrapS=g.RepeatWrapping,e.wrapT=g.RepeatWrapping,e.flipY=null===(s=null===(i=t.texture)||void 0===i?void 0:i.flipY)||void 0===s||s,this.textureCache.set(t.id,e),e}))),this.textureCache.get(t.id))}))}getMesh(t){var s;return e(this,void 0,void 0,(function*(){if(yield this.ready,!v.includes(null===(s=t.fileFormat)||void 0===s?void 0:s.toLowerCase()))return console.error("Unsupported mesh file format "+t.fileFormat,t),{scene:new i};if(!this.cache.has(t.fileKey))try{this.cache.set(t.fileKey,yield this.loadMesh(t))}catch(e){return this.onError(e),{scene:new i}}const e=d(this.cache.get(t.fileKey).scene);e.traverse((e=>{e instanceof r&&e.material instanceof Array&&(e.material=e.material.slice())}));const o=this.computeCollisionShapes(t,e),n=(new AssetMeshInstance).copy(e);return n.collisionShapes=o,{scene:n}}))}getAudio(t){return e(this,void 0,void 0,(function*(){return yield this.ready,this.audioLoader.loadAsync(this.getUri(t.fileKey))}))}computeCollisionShapes(e,t){return this.collisionShapeCache.get(e.id)||this.collisionShapeCache.set(e.id,m(t)),this.collisionShapeCache.get(e.id)}loadMesh(t){return e(this,void 0,void 0,(function*(){return yield this.ready,yield this.loadByAsset(t).then((e=>(e.scene.animations=[],e.scene=function(e,t){let i=!1;if(t.traverseVisible((e=>{L.test(e.name)&&(i=!0)})),!i)return t;const s=new g.LOD,r=[t];for(;r.length>0;){const e=r.shift(),t=e.name.match(e.name);if(null!=t){const i=parseInt(t[1]);0===i?s.addLevel(e,0):console.warn(`Skipping LOD level ${i} for now as LOD is not fully supported`)}else r.push(...e.children)}return s}(0,e.scene),e)))}))}loadByAsset(t){return e(this,void 0,void 0,(function*(){const e=this.getUri(t.fileKey);switch(t.fileFormat){case"glb":case"gltf":return this.glbLoader.loadAsync(e).then((e=>({scene:e.scene})));case"fbx":return this.fbxLoader.loadAsync(e).then((e=>({scene:e})));case"obj":if(null!=t.materialLib){const e=new l;e.materialOptions={normalizeRGB:!1};const i=yield e.loadAsync(this.getUri(t.materialLib));this.objLoader.setMaterials(i)}return this.objLoader.loadAsync(e).then((e=>(w(e),e))).then((e=>({scene:e})))}}))}}function w(e){var t;if(e instanceof r)for(const t of y(e.material))t instanceof g.MeshPhongMaterial&&!t.color.isLinear&&(t.color.isLinear=!0,t.color.convertSRGBToLinear());null===(t=e.children)||void 0===t||t.forEach(w)}export class AssetMeshInstance extends o{}export function getElectronArg(e){var t;const i=`--${e}=`,s=null===(t=window.process)||void 0===t?void 0:t.argv.find((e=>e.startsWith(i)));return null==s?void 0:s.substring(i.length)}const L=/_LOD(\d+)$/;
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -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 S,clamp as b}from"../../utils/math";import{whenIdle as A}from"../../utils/async";import{Subject as P,debounceTime as z}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 P,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.color=g.color,this.refreshRequests.pipe(z(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,P]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 P.meshes.entries()){const P=`${x}-${f}`;this.scatterMeshes.has(P)||this.scatterMeshes.set(P,new Map);const z=this.scatterMeshes.get(P),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=>!z.has(e.uuid)||l)).filter((e=>u(e)));F.filter(C(a,2*w.viewDistance)).forEach((e=>{var t;const s=z.get(e.uuid);null===(t=null==s?void 0:s.parent)||void 0===t||t.remove(s),z.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"),P=(null!==(e=this.source.vertexMaterials)&&void 0!==e?e:[]).filter((e=>e.m===t.name)),L=y(P,(e=>e.i));let B=z.get(t.uuid);if(null==B||B.count==ie&&!l||(null===(s=B.parent)||void 0===s||s.remove(B),z.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),re=new h(new n,new n,new n),ce=new h(new n,new n,new n),le=new h(new n,new n,new n);let he=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),re.a.copy(ee.b),re.b.copy(ee.c),re.c.fromBufferAttribute(g,e+Q+2+s),ce.a.fromBufferAttribute(A,e+s),ce.b.fromBufferAttribute(A,e+1+s),ce.c.fromBufferAttribute(A,e+Q+1+s),le.a.copy(ce.b),le.b.copy(ce.c),le.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;e+=ne)for(let s=0;s<1;s+=ne){if(he>ie)break e;if(n++,n>te)continue e;1-e>s?(C=ee.a,k=ee.b,U=ee.c,E=ce.a,F=ce.b,N=ce.c,D=o[0],I=o[1],Y=o[2]):(C=re.a,k=re.b,U=re.c,E=le.a,F=le.b,N=le.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);const i=1.5;Z.x+=(2*Math.random()-1)*i*se,Z.z+=(2*Math.random()-1)*i*se,G.getBarycoord(Z,v).toArray(ae);if(R([D,I,Y],ae,.2)!==x-1)continue;const a=[C,k,U];S(a,ae,K),S([E,F,N],ae,V);const r=a.map((e=>e.y)),c=Math.max(...r),l=Math.min(...r);if(K.y=b(K.y,l,c),null!=w.maxSlope&&w.maxSlope<90&&V.y<X)continue;const h=K.applyMatrix4(t.matrixWorld);h.y+=T(w.offsetMin,w.offsetMax);const u=T(w.scaleMin,w.scaleMax);p.makeScale(1,1,1),p.setPosition(h),p.scale(W(u)),w.alignToNormal&&H(p,h,B.matrixWorld,V),!1!==w.randomRotation&&j(p),B.setMatrixAt(he,p),he++}}B.instanceMatrix.count=he,p.makeScale(0,0,0);for(let e=he;e<ie;e++)B.setMatrixAt(e,p);B.instanceMatrix.needsUpdate=!0,z.has(t.uuid)||null===(m=this.landscape)||void 0===m||m.attach(B),z.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{__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.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}
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -1,4 +1,5 @@
1
1
  import { Subject } from "rxjs";
2
+ import * as THREE from "three";
2
3
  import { Euler, Material, Object3D, Scene, Vector3 } from "three";
3
4
  import { GameComponent } from "../game-component/game-component";
4
5
  import { RenderingView } from "../rendering";
@@ -207,7 +208,7 @@ export declare class SceneMaterializer {
207
208
  updateActors(actors: ActorImpl[]): void;
208
209
  updateShaders(shaders: ShaderImpl[]): void;
209
210
  private update;
210
- private materializeAndInitActor;
211
+ materializeAndInitActor(source: SceneObject, parent?: THREE.Object3D<THREE.Event>): Promise<THREE.Object3D<THREE.Event>>;
211
212
  private findParent;
212
213
  private fixFogColor;
213
214
  private findMeshWithGeometry;