@hology/core 0.0.20 → 0.0.21
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/gameplay/actors/actor.d.ts +2 -2
- package/dist/gameplay/actors/actor.js +1 -1
- package/dist/gameplay/actors/builtin/camera-actor.d.ts +1 -1
- package/dist/gameplay/actors/builtin/camera-actor.js +1 -1
- package/dist/gameplay/actors/builtin/components/mesh-component.d.ts +4 -4
- package/dist/gameplay/actors/builtin/components/mesh-component.js +1 -1
- package/dist/gameplay/actors/builtin/positional-audio-actor.js +1 -1
- package/dist/gameplay/actors/builtin/spawn-point.js +1 -1
- package/dist/gameplay/actors/builtin/trigger-volume.js +1 -1
- package/dist/gameplay/actors/camera/camera-component.js +1 -1
- package/dist/gameplay/actors/camera/third-party-camera-component.js +1 -1
- package/dist/gameplay/actors/factory.js +1 -1
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/gameplay/services/render.d.ts +2 -1
- package/dist/gameplay/services/render.js +1 -1
- package/dist/gameplay/services/world.js +1 -1
- package/dist/scene/materializer.js +1 -1
- package/dist/scene/model.d.ts +1 -1
- package/dist/scene/model.js +1 -1
- package/dist/shader/parameter.d.ts +2 -2
- package/package.json +2 -2
- package/tsconfig.tsbuildinfo +1 -1
@@ -1,5 +1,5 @@
|
|
1
1
|
import { Subject } from "rxjs";
|
2
|
-
import {
|
2
|
+
import { Object3D } from "three";
|
3
3
|
import { Constructable } from "typedi";
|
4
4
|
import { ActorComponent, ComponentAttachProps } from "./component";
|
5
5
|
export declare function Actor(): (targetConstructor: any) => void;
|
@@ -10,7 +10,7 @@ export type ActorId = number;
|
|
10
10
|
export declare abstract class BaseActor {
|
11
11
|
readonly id: ActorId;
|
12
12
|
__isInitialised: boolean;
|
13
|
-
readonly
|
13
|
+
readonly object: Object3D;
|
14
14
|
readonly disposed: Subject<true>;
|
15
15
|
get position(): import("three").Vector3;
|
16
16
|
get quaternion(): import("three").Quaternion;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{__decorate as t,__metadata as e}from"tslib";import o,{ignore as i}from"@plumier/reflect";import{Subject as n,skipWhile as r}from"rxjs";import{Group as s}from"three";import a,{Service as p}from"typedi";import{ActorComponent as d}from"./component";import{initComponents as c}from"./internal/component-init";import{activeContainerInstance as l,containerRefMap as u}from"./internal/container-map";import{randomString as m}from"../../utils/math";import{inject as h}from"../inject";import{ViewController as f}from"../services/render";export function Actor(){const t=p({transient:!0});return function(e){e.__isActor=!0,t(e),o.noop()(e),o.parameterProperties()(e)}}let v=0;export class BaseActor{get position(){var t;return null===(t=this.
|
1
|
+
import{__decorate as t,__metadata as e}from"tslib";import o,{ignore as i}from"@plumier/reflect";import{Subject as n,skipWhile as r}from"rxjs";import{Group as s}from"three";import a,{Service as p}from"typedi";import{ActorComponent as d}from"./component";import{initComponents as c}from"./internal/component-init";import{activeContainerInstance as l,containerRefMap as u}from"./internal/container-map";import{randomString as m}from"../../utils/math";import{inject as h}from"../inject";import{ViewController as f}from"../services/render";export function Actor(){const t=p({transient:!0});return function(e){e.__isActor=!0,t(e),o.noop()(e),o.parameterProperties()(e)}}let v=0;export class BaseActor{get position(){var t;return null===(t=this.object)||void 0===t?void 0:t.position}get quaternion(){var t;return null===(t=this.object)||void 0===t?void 0:t.quaternion}get rotation(){var t;return null===(t=this.object)||void 0===t?void 0:t.rotation}onInit(){}onBeginPlay(){}onEndPlay(){}onUpdate(t){}onLateUpdate(t){}constructor(){this.id=++v,this.__isInitialised=!1,this.object=new s,this.disposed=new n,this.onUpdate!==BaseActor.prototype.onUpdate&&h(f).onUpdate(this).pipe(r((()=>!this.__isInitialised))).subscribe((t=>this.onUpdate(t))),this.onLateUpdate!==BaseActor.prototype.onLateUpdate&&h(f).onLateUpdate(this).pipe(r((()=>!this.__isInitialised))).subscribe((t=>this.onLateUpdate(t)))}attach(t,e){var o,i;const n=l.value,r=null!==(i=null!==(o=u.get(this))&&void 0!==o?o:l.value)&&void 0!==i?i:a.of("default");l.value=r;const s=m();r.set({id:s,type:t,transient:!0});const p=r.get(s);if(l.value=n,null!=e)for(const t of Object.keys(e))p[t]=e[t];return this.__isInitialised&&(p.actor=this,p.onInit(),c(p,this)),p}getComponent(t){for(const e of Object.values(this))if(e instanceof t)return e}}t([i(),e("design:type",Object),e("design:paramtypes",[])],BaseActor.prototype,"position",null),t([i(),e("design:type",Object),e("design:paramtypes",[])],BaseActor.prototype,"quaternion",null),t([i(),e("design:type",Object),e("design:paramtypes",[])],BaseActor.prototype,"rotation",null);export function _setupActorUpdateEventHandlers(){this.onUpdate!==d.prototype.onUpdate&&h(f).onUpdate(this.actor).pipe(r((()=>!this.actor.__isInitialised))).subscribe((t=>this.onUpdate(t))),this.onLateUpdate!==d.prototype.onLateUpdate&&h(f).onLateUpdate(this.actor).pipe(r((()=>!this.actor.__isInitialised))).subscribe((t=>this.onLateUpdate(t)))}
|
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 e,__metadata as o}from"tslib";import{ArrowHelper as r,ConeGeometry as t,EdgesGeometry as a,LineBasicMaterial as n,LineSegments as s,MeshStandardMaterial as l,Vector3 as i}from"three";import{Actor as c,BaseActor as m}from"../actor";import{CameraComponent as p}from"../camera/camera-component";import{ActorComponent as d,Attach as w,Component as y}from"../component";let h=class extends d{constructor(){super(...arguments),this.arrowColor=16101442}onInit(){const e=new t(1,1,4);e.rotateX(Math.PI/2),e.rotateZ(Math.PI/4),e.scale(1,9/16,1);const o=new a(e),c=(new l({color:3355443}),new s(o,new n({color:16777215}))),m=new r(new i(0,0,-1),new i(0,0,0),1.2,this.arrowColor,.15,.2);c.add(m),m.layers.disableAll(),m.layers.enable(19),m.traverse((e=>{e.layers.disableAll(),e.layers.enable(19)})),this.actor.
|
1
|
+
import{__decorate as e,__metadata as o}from"tslib";import{ArrowHelper as r,ConeGeometry as t,EdgesGeometry as a,LineBasicMaterial as n,LineSegments as s,MeshStandardMaterial as l,Vector3 as i}from"three";import{Actor as c,BaseActor as m}from"../actor";import{CameraComponent as p}from"../camera/camera-component";import{ActorComponent as d,Attach as w,Component as y}from"../component";let h=class extends d{constructor(){super(...arguments),this.arrowColor=16101442}onInit(){const e=new t(1,1,4);e.rotateX(Math.PI/2),e.rotateZ(Math.PI/4),e.scale(1,9/16,1);const o=new a(e),c=(new l({color:3355443}),new s(o,new n({color:16777215}))),m=new r(new i(0,0,-1),new i(0,0,0),1.2,this.arrowColor,.15,.2);c.add(m),m.layers.disableAll(),m.layers.enable(19),m.traverse((e=>{e.layers.disableAll(),e.layers.enable(19)})),this.actor.object.add(c)}};h=e([y({inEditor:!0,editorOnly:!0})],h);export{h as CameraMesh};let b=class extends m{};e([w(),o("design:type",p)],b.prototype,"camera",void 0),e([w(),o("design:type",h)],b.prototype,"mesh",void 0),b=e([c()],b);export{b as CameraActor};
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import { PhysicsBodyType, PhysicsSystem } from "../../../../gameplay/services/physics/physics-system";
|
2
|
-
import { Euler,
|
2
|
+
import { Euler, Object3D, Vector3 } from "three";
|
3
3
|
import { ActorComponent } from "../../component";
|
4
|
-
export declare class MeshComponent extends ActorComponent {
|
4
|
+
export declare class MeshComponent<TObj extends Object3D = Object3D> extends ActorComponent {
|
5
5
|
private physicsSystem;
|
6
|
-
|
6
|
+
object: TObj;
|
7
7
|
readonly position: Vector3;
|
8
8
|
readonly rotation: Euler;
|
9
9
|
readonly scale: Vector3;
|
@@ -14,7 +14,7 @@ export declare class MeshComponent extends ActorComponent {
|
|
14
14
|
private currentMesh;
|
15
15
|
constructor(physicsSystem: PhysicsSystem);
|
16
16
|
onInit(): void | Promise<void>;
|
17
|
-
|
17
|
+
setObject(replacement: TObj): void;
|
18
18
|
private updateMesh;
|
19
19
|
private getCollisionShapes;
|
20
20
|
}
|
@@ -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
|
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};
|
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 i}from"tslib";import*as e from"three";import{Actor as o,BaseActor as r}from"../actor";import{ActorComponent as
|
1
|
+
import{__decorate as t,__metadata as i}from"tslib";import*as e from"three";import{Actor as o,BaseActor as r}from"../actor";import{ActorComponent as s,Component as n,attach as a}from"../component";import{Parameter as l}from"../../../shader";import{ViewController as d}from"../../services/render";import{inject as u}from"../../inject";import{PositionalAudioHelper as p}from"../../../utils/three/positional-audio-helper";let c=class extends r{constructor(){super(...arguments),this.audio=a(m)}};c=t([o()],c);export{c as PositionalAudioActor};let h=class extends s{onInit(){const t=(new e.TextureLoader).load("assets/audio.png"),i=new e.SpriteMaterial({map:t}),o=new e.Sprite(i);this.actor.object.add(o),this.helper=new p(this.positionalAudio)}};h=t([n({inEditor:!0,editorOnly:!0})],h);let m=class extends s{constructor(){super(...arguments),this.view=u(d),this.sound=new e.PositionalAudio(this.view.audioListener),this.visualisation=a(h,{positionalAudio:this.sound})}onInit(){var t,i;this.sound.setBuffer(this.audioBuffer),null!=this.refDistance&&this.sound.setRefDistance(this.refDistance),null!=this.rollofFactor&&this.sound.setRolloffFactor(this.rollofFactor),null!=this.maxDistance&&this.sound.setMaxDistance(this.maxDistance),null!=this.directionalInnerAngle&&null!=this.directionalOuterAngle&&null!=this.directionalOuterGain&&this.sound.setDirectionalCone(this.directionalInnerAngle,this.directionalOuterAngle,this.directionalOuterGain),null===(i=null===(t=this.visualisation)||void 0===t?void 0:t.helper)||void 0===i||i.update(),this.actor.object.add(this.sound),this.sound.play()}};t([l(),i("design:type",AudioBuffer)],m.prototype,"audioBuffer",void 0),t([l(),i("design:type",Number)],m.prototype,"refDistance",void 0),t([l(),i("design:type",Number)],m.prototype,"rollofFactor",void 0),t([l(),i("design:type",Number)],m.prototype,"maxDistance",void 0),t([l(),i("design:type",Number)],m.prototype,"directionalInnerAngle",void 0),t([l(),i("design:type",Number)],m.prototype,"directionalOuterAngle",void 0),t([l({range:[0,1]}),i("design:type",Number)],m.prototype,"directionalOuterGain",void 0),m=t([n({inEditor:!0})],m);export{m as PositionalAudioComponent};
|
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 o}from"tslib";import{EdgesGeometry as
|
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};
|
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.
|
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};
|
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 e,__metadata as t}from"tslib";import{ActorComponent as i,Component as r}from"../component";import{ViewController as n}from"../../services/render";import{PerspectiveCamera as s}from"three";import{Parameter as o}from"../../../shader/parameter";const a=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let h=class extends i{constructor(e){super(),this.viewController=e,this.near=.5,this.far=500,this.viewAngle=a?30:45,this.aspect=this.viewController.htmlElement.clientWidth/this.viewController.htmlElement.clientHeight,this.instance=new s(this.viewAngle,this.aspect,this.near,this.far)}onInit(){this.actor.
|
1
|
+
import{__decorate as e,__metadata as t}from"tslib";import{ActorComponent as i,Component as r}from"../component";import{ViewController as n}from"../../services/render";import{PerspectiveCamera as s}from"three";import{Parameter as o}from"../../../shader/parameter";const a=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let h=class extends i{constructor(e){super(),this.viewController=e,this.near=.5,this.far=500,this.viewAngle=a?30:45,this.aspect=this.viewController.htmlElement.clientWidth/this.viewController.htmlElement.clientHeight,this.instance=new s(this.viewAngle,this.aspect,this.near,this.far)}onInit(){this.actor.object.add(this.instance),this.instance.near=this.near,this.instance.far=this.far,this.instance.fov=this.viewAngle}};e([o(),t("design:type",Object)],h.prototype,"near",void 0),e([o(),t("design:type",Number)],h.prototype,"far",void 0),e([o(),t("design:type",Number)],h.prototype,"viewAngle",void 0),h=e([r({inEditor:!0}),t("design:paramtypes",[n])],h);export{h as CameraComponent};
|
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.
|
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;
|
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 i,__metadata as
|
1
|
+
import{__awaiter as t,__decorate as i,__metadata as o}from"tslib";import{ContainerInstance as n}from"typedi";import{Service as e}from"typedi";import{initComponents as r}from"./internal/component-init";import{activeContainerInstance as s,containerRefMap as c}from"./internal/container-map";let a=class{constructor(t,i){this.container=t,this.env=i}create(i,o,n,e){return t(this,void 0,void 0,(function*(){const t=this.container;s.value=t;const r=(1e4*Math.random()).toString();t.set({id:r,type:i,transient:!0});const a=t.get(r);return s.value=null,t.remove(i),c.set(a,t),o&&a.object.position.copy(o),n&&a.object.rotation.copy(n),!0!==e&&(yield this.initActor(a)),a}))}initActor(i){var o;return t(this,void 0,void 0,(function*(){yield r(i,i,null!==(o=this.env.inEditor)&&void 0!==o&&o),yield i.onInit(),i.__isInitialised=!0}))}};a=i([e(),o("design:paramtypes",[n,Object])],a);export{a as ActorFactory};
|
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,__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 a}from"cannon-es";import{filter as l,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 A,Scene as b,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 a,new a;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 N=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 A,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.container;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 a=this._raytestDiff,l=this._raytestDirection;if(a.subVectors(t,e),l.copy(a).normalize(),0===l.length())return console.warn("Ray test called with to and from being equal"),i;const c=new o.Ray(e,l),d=a.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(l,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 j.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 b)&&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,a=new Array(e);for(let t=0;t<e;t++)a[t]=new Array(e).fill(0);const l=i.find((e=>e.x===r.x&&e.y==r.y));if(null!=l)for(const t of l.points){if(null==a[t.i%e])continue;const i=e-1-Math.floor(t.i/e);i in a[t.i%e]?a[t.i%e][i]=t.y/n:console.warn("wrong index",{points:a,point:t,i:t.i%e,k:i,heightMap:l})}const c=t.landscape.options.density,d=a.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.container;let a;switch(null!==(s=i.type)&&void 0!==s?s:PhysicsBodyType.static){case PhysicsBodyType.dynamic:a=o.RigidBodyDesc.dynamic(),a.mass=null!==(r=i.mass)&&void 0!==r?r:1;break;case PhysicsBodyType.kinematic:a=o.RigidBodyDesc.kinematicPositionBased();break;case PhysicsBodyType.kinematicVelocityBased:a=o.RigidBodyDesc.kinematicVelocityBased();break;default:a=(i.isTrigger,o.RigidBodyDesc.kinematicVelocityBased())}const l=this.world.createRigidBody(a);l.enableCcd(1==i.continousCollisionDetection);for(const e of t)this.addShape(l,e,n);Z(l,(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)})),Q(l,n),this.actorBodies.set(e.id,l),this.bodyActors.set(l,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),l((({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}))),l((({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?Q(t,e.container):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(),a=s.rotation(),l=t,c=.3;const d=this.world.castShape(n,a,l,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 Q(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,a;J(o.translation,s),n=o.rotation,a=(new r).setFromEuler(t.rotation.x,t.rotation.y,t.rotation.z),n.x=a.x,n.y=a.y,n.z=a.z,n.w=a.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))}};N=t([D(),i("design:paramtypes",[k,I])],N);export{N as PhysicsSystem};const q=new C,G=new y.Quaternion;function Q(e,t){const i=t.getWorldPosition(q),s=t.getWorldQuaternion(G);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 j=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 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();
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -2,6 +2,7 @@ import { Camera } from "three";
|
|
2
2
|
import { RenderingView } from "../../rendering";
|
3
3
|
import { Observable } from "rxjs";
|
4
4
|
import * as THREE from "three";
|
5
|
+
import { CameraActor } from "../../gameplay/actors/builtin/camera-actor";
|
5
6
|
export declare class ViewController {
|
6
7
|
private view;
|
7
8
|
private readonly tick;
|
@@ -10,7 +11,7 @@ export declare class ViewController {
|
|
10
11
|
constructor(view: RenderingView);
|
11
12
|
onUpdate(actor?: any): Observable<number>;
|
12
13
|
onLateUpdate(actor?: any): Observable<number>;
|
13
|
-
setCamera(camera: Camera): void;
|
14
|
+
setCamera(camera: Camera | CameraActor): void;
|
14
15
|
getCamera(): Camera;
|
15
16
|
get htmlElement(): HTMLElement;
|
16
17
|
pauseRendering(): 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";let
|
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};
|
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 o,__metadata as r}from"tslib";import{Service as
|
1
|
+
import{__awaiter as t,__decorate as o,__metadata as r}from"tslib";import{Service as e}from"typedi";import{ActorFactory as c}from"../actors/factory";import{ActorComponent as i}from"../../gameplay/actors/component";let s=class{constructor(t){this.actorFactory=t,this.actors=[]}spawnActor(o,r,e){return t(this,void 0,void 0,(function*(){const t=yield this.actorFactory.create(o,r,e);return this.addActor(t,r,e),t}))}addActor(t,o,r){o&&t.object.position.copy(o),r&&t.object.rotation.copy(r),this.scene.add(t.object),this.actors.push(t),n(t,(t=>t.onBeginPlay()))}removeActor(t){n(t,(t=>t.onEndPlay())),this.actors.splice(this.actors.indexOf(t),1),this.scene.remove(t.object),t.disposed.next(!0)}findActorByType(t,o){return this.actors.find((r=>r instanceof t&&(null==o||r.object.name==o)))}findActorsByType(t,o){return this.actors.filter((r=>r instanceof t&&(null==o||r.object.name==o)))}};s=o([e(),r("design:paramtypes",[c])],s);export{s as World};function n(t,o){return o(t),Object.entries(t).filter((([t,o])=>o instanceof i)).forEach((([t,r])=>{n(r,o)}))}
|
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{Subject as t}from"rxjs";import*as i from"three";import{BoxGeometry as r,Color as a,Euler as s,Fog as n,FogExp2 as o,Group as l,Material as c,Mesh as d,MeshLambertMaterial as h,MeshPhongMaterial as u,MeshStandardMaterial as p,Object3D as m,PointLight as f,Quaternion as v,SphereGeometry as y,Texture as g,Vector2 as w,Vector3 as A,Vector4 as S}from"three";import b,{SpriteRenderer as M}from"three-nebula";import{bool as x,BooleanNode as I,float as D,FloatNode as P,NodeShaderMaterial as E,rgb as j,RgbNode as N,Texture2dLookupNode as O,textureSampler2d as F,vec2 as V,Vec2Node as B,vec3 as z,Vec3Node as C,vec4 as T}from"three-shader-graph";import _ from"../gameplay/actors/builtin";import{extractShaderParameters as $}from"../shader/parameter";import{groupBy as k,ArrayMap as L}from"../utils/collections";import{filterChildrenShallow as R,filterSceneShallow as U}from"../utils/three/traverse";import{AssetMeshInstance as W}from"./asset-resource-loader";import{BoxCollisionShape as G,PhysicalShapeMesh as H}from"./collision/collision-shape";import{isCollisionMesh as J}from"./collision/collision-shape-import";import{initLandscape as X}from"./landscape/landscape";import{LandscapeManager as Y}from"./landscape/landscape-manager";import{SectionGrid as q,smoothNormalsCrossMeshes as Z}from"./landscape/utils";import{createGrassMaterial as K}from"./materials/grass";import{createGrassFoliageMaterial as Q}from"./materials/grass-foliage";import{getMaterialAttribute as ee}from"./materials/utils/material-painting";import{createWaterMaterial as te}from"./materials/water";import{SerializedParamType as ie}from"./model";import{Matrix4 as re}from"three";import{BaseActor as ae}from"../gameplay/actors/actor";import{Sampler2DNode as se}from"../shader-nodes";import{StandardShader as ne}from"../shader/builtin/standard-shader";import{LambertShader as oe}from"../shader/builtin/lambert-shader";import{ShapeLibrary as le,ShapeLibraryKeys as ce}from"./objects/shapes";import{ambientLightName as de}from"./sky";import{withInjectionContext as he}from"../gameplay";const ue={};export const shapeDefaultColor="#aaaaaa";export class SceneMaterializerLoader{constructor(e,t,i){this.dataProvider=e,this.assetsService=t,this.assetManagerService=i}get(t,i){return new SceneMaterializer(t,this.dataProvider,this.assetsService,this.assetManagerService,i,[],[],{create:()=>null,initActor:()=>e(this,void 0,void 0,(function*(){}))})}}export class SceneMaterializer{constructor(i,r,a,s,n,o,l,c){this.scene=i,this.dataProvider=r,this.assetsService=a,this.assetManagerService=s,this.renderingView=n,this.shaders=o,this.actorTypes=l,this.actorProvider=c,this.objectMap=new Map,this.sceneObjectMap=new Map,this.components=[],this.landscapeManagers=[],this.materializedActors=new Map,this.inEditor=!0,this.updated$=new t,this.removed$=new t,this.error$=new t,this.editorActorParamSnapshot=new Map,this._canBeInstancedCache=new Map,this._originalMaterials=new Map,this.originalFog=null,r.onUpdate((e=>this.update(e))),r.onRemove((e=>this.remove(e))),this.updateSubscription=a.onUpdate.subscribe((t=>e(this,void 0,void 0,(function*(){"material"==t.type?((yield this.assetsService.getAssets()).filter((e=>{var i;return(null!==(i=e.materialAssignments)&&void 0!==i?i:[]).some((e=>e.materialId===t.id))})).forEach((e=>{const t=this.findByAssetId(e.id);e.materialAssignments.forEach((e=>{t.forEach((t=>{const i=t.userData.src.materialAssignments;null!=i&&i.some((t=>t.color===e.color))||this.applyMaterial(t,e)}))}))})),U(this.scene,(e=>{var i;return null!=e.userData.src&&(null!==(i=e.userData.src.materialAssignments)&&void 0!==i?i:[]).some((e=>e.materialId===t.id))}),(e=>null!=e.userData.src)).forEach((t=>e(this,void 0,void 0,(function*(){this.deleteSceneObject(t.userData.src),this.materialize(t.userData.src)}))))):"mesh"==t.type?this.findByAssetId(t.id).forEach((e=>{Me(e.userData.src.materialAssignments,t.materialAssignments).forEach((t=>{this.applyMaterial(e,t)}))})):"prefab"===t.type&&this.findByAssetId(t.id).forEach((e=>{const t=e.userData.src;this.remove(t),this.materializeAndInitActor(t)}))}))))}get actorInstances(){return Array.from(this.materializedActors.values())}prefetchAssets(){return e(this,void 0,void 0,(function*(){const e=Array.from(new Set(this.dataProvider.getObjects().filter((e=>null!=e.assetId&&"asset_mesh"==e.type)).filter((e=>e.assetId))));yield Promise.all(e.map((e=>this.assetsService.getAsset(e.assetId).then((e=>e&&this.assetManagerService.getMesh(e))))))}))}init(){return e(this,void 0,void 0,(function*(){me.clear(),yield this.prefetchAssets(),yield Promise.all(this.dataProvider.getObjects().map((e=>this.materialize(e)))),yield this.initActorsPostInit()}))}initActorsPostInit(t=this.actorInstances){const i=t.map((t=>e(this,void 0,void 0,(function*(){var e,i,r,a;const s=t.container.userData.src,n=yield this.assetsService.getAsset(s.assetId),o=Object.assign(Object.assign({},null!==(i=null===(e=null==n?void 0:n.actor)||void 0===e?void 0:e.params)&&void 0!==i?i:{}),null!==(r=s.actor.params)&&void 0!==r?r:{});for(const e of null!==(a=s.actor.innerParams)&&void 0!==a?a:[])yield this.applyActorComponentParams(t,e.path.slice(),e.params);const l=yield ye(o,t.constructor,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders);Object.assign(t,l);try{return yield this.actorProvider.initActor(t)}catch(e){console.error(`Failed to initiate actor (name="${s.name}", id=${s.id})`,e)}}))));return Promise.all(i)}applyActorComponentParams(t,i,r){return e(this,void 0,void 0,(function*(){const e=i.length,a=i.shift();if(0==e){const e=yield ye(r,null,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders);for(const[i,r]of Object.entries(e))null!=r&&(t[i]=r)}else null!=t[a]&&(yield this.applyActorComponentParams(t[a],i,r))}))}canAssetBeInstanced(t){return e(this,void 0,void 0,(function*(){if(!this._canBeInstancedCache.has(t.assetId)){const e=yield this.createFromAsset(t);if(null==e)return!1;const i=[];e.traverse((e=>{!J(e)&&e.isMesh&&i.push(e)}));const r=1==i.length&&0==i[0].children.length,a=!0;this._canBeInstancedCache.set(t.assetId,r&&a)}return this._canBeInstancedCache.get(t.assetId)}))}initWithInstancing(){return e(this,void 0,void 0,(function*(){const t=new L;for(const i of this.dataProvider.getObjects())yield Se(i,((i,r,a)=>e(this,void 0,void 0,(function*(){var e,s;const n="asset_mesh"==i.type&&(yield this.canAssetBeInstanced(i))?i.assetId+JSON.stringify(null!==(e=i.materialAssignments)&&void 0!==e?e:[]):"other";"other"!==n&&r&&(null===(s=r.children)||void 0===s?void 0:s.length)>0&&r.children.splice(r.children.findIndex((e=>e.id===i.id)),1),t.push(n,Object.assign(Object.assign({},i),{parentTransform:a}))}))));for(const[e,i]of t.entries())if("other"!==e&&i.length>1){const e=yield this.createFromAsset(i[0]);if(null==e)continue;const t=yield this.createInstancedMesh(i,e),r=new W;r.add(t),r.userData.src=i[0],e instanceof W&&(r.collisionShapes=e.collisionShapes),r.castShadow=!1,r.receiveShadow=!1,this.scene.add(r)}else yield Promise.all(i.map((e=>this.materialize(e))));yield this.initActorsPostInit()}))}createInstancedMesh(t,r){var a,n;return e(this,void 0,void 0,(function*(){const e=r.children.filter((e=>!J(e)))[0],o=yield this.assetsService.getAsset(t[0].assetId);yield this.applyMaterials(r,Me(t[0].materialAssignments,o.materialAssignments)),e.updateMatrix();const l=e.geometry.clone().applyMatrix4(e.matrix),c=new i.InstancedMesh(l,e.material.clone(),t.length);c.material.side=i.FrontSide;for(let e=0;e<t.length;e++){const r=(new i.Matrix4).compose((new A).fromArray(t[e].position),(new v).setFromEuler((new s).fromArray(t[e].rotation)),(new A).fromArray(t[e].scale)),a=(new re).copy(t[e].parentTransform).multiply(r);c.setMatrixAt(e,a)}return c.castShadow=null===(a=o.castShadow)||void 0===a||a,c.receiveShadow=null===(n=o.receiveShadow)||void 0===n||n,c}))}remove(e){if("global_fog"==e.type)return void(this.scene.fog=this.originalFog);if("actor"==e.type){const t=this.materializedActors.get(e.id);null!=t&&t.disposed.next(!0)}const t=this.sceneObjectMap.get(e.id);null==t||t.parent.remove(t),this.sceneObjectMap.delete(e.id),this.components.filter((t=>{var i;return(null===(i=t.object.userData.src)||void 0===i?void 0:i.id)===e.id})).forEach((e=>this.components.splice(this.components.indexOf(e,1)))),this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>{e.clear(),e.stop(),this.landscapeManagers.splice(this.landscapeManagers.indexOf(e,1))})),this.removed$.next({object:t,source:e})}deleteSceneObject(e){const t=this.sceneObjectMap.get(e.id);if(this.scene.remove(t),"landscape"==e.type){const t=this.landscapeManagers.findIndex((t=>t.source.id===e.id));if(t>-1){const e=this.landscapeManagers.splice(t,1)[0];e.clear(),e.stop()}}}findByAssetId(e){return U(this.scene,(t=>{var i;return(null===(i=t.userData.src)||void 0===i?void 0:i.assetId)==e}),(e=>null!=e.userData.src))}applyMaterials(e,t){return Promise.all(t.filter((e=>"null"!==e.materialId)).map((t=>this.applyMaterial(e,t))))}applyMaterial(t,i){const r=[];return t.traverse((t=>e(this,void 0,void 0,(function*(){(t instanceof d||t.isMesh)&&t.material.hasOwnProperty("color")&&r.push(t)})))),Promise.all(r.map((t=>e(this,void 0,void 0,(function*(){var e;const r="#"+t.material.color.getHexString();if(r===i.color||t.userData.originalColor===i.color){const a=yield this.assetsService.getAsset(i.materialId),s=t.material;a&&(t.material=yield materialFromAsset(a,this.renderingView,this.assetsService,this.assetManagerService,this.shaders),t.userData.originalColor=null!==(e=t.userData.originalColor)&&void 0!==e?e:r,this.inEditor&&this._originalMaterials.set(t.id,s))}})))))}unapplyMaterials(t){t.traverse((t=>e(this,void 0,void 0,(function*(){t instanceof d&&this._originalMaterials.has(t.id)&&(t.material=this._originalMaterials.get(t.id))}))))}updateActors(t){this.actorTypes=t;const i=new Set(Object.values(_));U(this.scene,(e=>{var t,r;return(null===(t=e.userData.src)||void 0===t?void 0:t.id)&&"actor"===e.userData.src.type&&this.materializedActors.has(null===(r=e.userData.src)||void 0===r?void 0:r.id)&&!i.has(e.userData.src.actor.type)})).forEach((t=>e(this,void 0,void 0,(function*(){this.remove(t.userData.src),console.time(t.userData.src.id),yield this.materializeAndInitActor(t.userData.src),console.timeEnd(t.userData.src.id)}))))}updateShaders(e){this.shaders=e;for(const[e,t]of me.entries())t.userData.customShaderName&&me.delete(e);this.landscapeManagers.forEach((t=>t.updateShaders(e))),U(this.scene,(e=>!0)).forEach((e=>{e.traverse((e=>{var t;if(e instanceof d){if(null!=e.material.userData.customShaderName){const i=null===(t=function(e,t){if(t(e))return e;let i;return e.traverseAncestors((e=>{null==i&&t(e)&&(i=e)})),i}(e,(e=>{var t;return null!=(null===(t=e.userData.src)||void 0===t?void 0:t.id)})))||void 0===t?void 0:t.userData.src;null!=i&&this.update(i)}}}))}))}update(t){var i;return e(this,void 0,void 0,(function*(){const e=this.sceneObjectMap.get(t.id);if(e){const s=this.findParent(t);null!=s&&s.uuid!=e.uuid?s.attach(e):console.error("Parent is wrong"),this.unapplyMaterials(e);if(this.inEditor&&t.hidden&&!1?e.traverse((e=>{e instanceof d&&(e.material.wireframe=!0)})):(e.traverse((e=>{e instanceof d&&(e.material.wireframe=!1)})),(null!==(i=t.materialAssignments)&&void 0!==i?i:[]).forEach((t=>this.applyMaterial(e,t)))),e.position.fromArray(t.position),e.scale.fromArray(t.scale),e.rotation.fromArray(t.rotation),this.applyVertexMaterials(t,e),"light"==t.type)if("point"==t.light.type){const i=e;i.color=new a(t.light.point.color),i.intensity=t.light.point.intensity,i.decay=t.light.point.decay,i.castShadow=t.light.point.castShadow,i.distance=Math.max(t.light.point.distance,0)}else"directional"===t.light.type?this.applyDirectionalLight(t.light.directional):"ambient"===t.light.type&&this.applyDirectionalAmbientLight(e,t.light.ambient);else if("landscape"===t.shape)this.applyHeightMaps(e,t.landscape.heightMaps),this.inEditor&&this.landscapeManagers.filter((e=>e.source.id===t.id)).forEach((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>!0))));else if("global_fog"===t.type){const e=(this.scene.fog instanceof o?"density":"linear")!==t.fog.type;this.scene.fog=we(t.fog),e&&(r=this.scene).traverse((e=>{if(e instanceof d){const t=e.material;t instanceof E&&(r.fog instanceof n?(t.uniforms.fogFar.value=r.fog.far,t.uniforms.fogNear.value=r.fog.near):r.fog instanceof o&&(t.uniforms.density={value:r.fog.density}),t.needsUpdate=!0,t.uniformsNeedUpdate=!0)}})),this.fixFogColor()}else if("actor"===t.type){if(this.materializedActors.has(t.id)){const e=this.editorActorParamSnapshot.get(t.id);null!=e&&e===JSON.stringify(t.actor)||(console.log("Rematerializing actor because parameters changed"),this.remove(t),yield this.materializeAndInitActor(t))}}else if("shape_mesh"===t.type){const i=yield this.createMeshByShape(t.shape,e.material,t.shapeParams);e instanceof H&&(e.geometry=i.geometry,e.collisionShape=i.collisionShape)}"asset_mesh"!==t.type&&"shape_mesh"!==t.type||pe(e,t.castShadow,t.receiveShadow),t.name&&t.name.length>0&&(e.name=t.name),this.updated$.next({object:e,source:t})}else{const e=yield this.materializeAndInitActor(t);this.updated$.next({object:e,source:t})}var r}))}materializeAndInitActor(t){return e(this,void 0,void 0,(function*(){const e=this.findParent(t),i=yield this.materialize(t,e);if("actor"===t.type){const e=this.materializedActors.get(t.id);null!=e?yield this.initActorsPostInit([e]):console.error(`Something went wrong when creating actor ${t.id}`)}return i}))}findParent(e){const t=this.dataProvider.getObjects().flatMap((t=>t.id===e.id?null:R(t,(t=>{var i;return null===(i=t.children)||void 0===i?void 0:i.some((t=>t.id===e.id))}),(()=>!0))))[0];return null==t?this.scene:null!=t?U(this.scene,(e=>{var i,r;return(null===(r=null===(i=e.userData)||void 0===i?void 0:i.src)||void 0===r?void 0:r.id)===t.id}),(e=>{var t;return null!=(null===(t=e.userData)||void 0===t?void 0:t.src)}))[0]:void 0}fixFogColor(){!0===this.renderingView.options.enableOutlines&&(this.scene.fog.color=new a(this.scene.fog.color).convertSRGBToLinear())}findMeshWithGeometry(e){let t;return e.traverse((e=>{e instanceof d&&e.geometry&&(t=e)})),t}applyVertexMaterials(e,t){if(null==e.vertexMaterials||0===e.vertexMaterials.length)return;const i=k(e.vertexMaterials,(e=>e.m));t.traverse((e=>{if(e instanceof d){const t=ee(e,!1);if(null!=t){for(let e=0;e<t.array.length;e++)t.setX(e,0);t.needsUpdate=!0}}}));const r=new Set;for(const[e,a]of i.entries()){const i=null!=e?t.getObjectByName(e):this.findMeshWithGeometry(t);let s=!1;if(null==i)return void console.warn(`Failed to apply vertex materials on mesh with name "${e}"`);const n=ee(i,!0);for(let e=0;e<n.array.length;e++)n.setX(e,0);for(const e of a)n.setX(e.i,e.w[0]),n.setY(e.i,e.w[1]),n.setZ(e.i,e.w[2]),s=!0;s&&r.add(e)}this.inEditor&&this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>r.has(e.name)))))}materialize(t,i,a=!1){var s,n,o,c;return e(this,void 0,void 0,(function*(){let e;switch(t.type){case"asset_mesh":e=yield this.createFromAsset(t);break;case"shape_mesh":e=yield this.createFromShape(t);break;case"light":e=yield this.createLight(t);break;case"particles":e=yield this.createParticleSystem(t),t.collisionDetection=!1;break;case"global_fog":this.scene.fog=we(t.fog),this.fixFogColor(),e=new l;break;case"actor":e=yield this.createFromActor(t);break;case"group":e=new l;break;case"prefab":e=yield this.createFromPrefabAsset(t);break;default:throw console.log(t),new Error("unknown type "+t.type)}if(null!=e){if(t.name&&t.name.length>0&&(e.name=t.name),e.position.fromArray(t.position),e.scale.fromArray(t.scale),e.rotation.fromArray(t.rotation),a||(e.userData.src=t),!this.inEditor){const i=null!==(s=t.components)&&void 0!==s?s:[],r=null!=t.assetId&&null!==(o=null===(n=yield this.assetsService.getAsset(t.assetId))||void 0===n?void 0:n.components)&&void 0!==o?o:[];i.push(...r),i.length>0?e.userData.componentRefs=yield Promise.all(i.map(((i,r)=>this.createComponent(e,t,i,r)))):"asset_mesh"==t.type&&function(e){e.traverse((e=>{e.matrixAutoUpdate=!1,e.matrixWorldNeedsUpdate=!1}));const t=e.updateMatrixWorld;e.updateMatrixWorld=function(){t.apply(e),e.updateMatrixWorld=function(){}}}(e)}if(this.inEditor){let t=null;e instanceof H&&(t=function(e){if(e instanceof G)return new d(new r(...e.offset.toArray()),Ae);return null}(e.collisionShape)),null!=t&&(t.layers.disable(0),t.layers.enable(18),t.scale.multiplyScalar(1.1),e.add(t))}return this.objectMap.set(e.uuid,t),this.sceneObjectMap.set(t.id,e),null==i?this.scene.add(e):null==i||i.add(e),null===(c=t.children)||void 0===c||c.forEach((t=>{this.materialize(t,e,a)})),e}}))}createComponent(t,i,r,a){return e(this,void 0,void 0,(function*(){const e=new ue[r.path+"/"+r.className],s=i.id+a;e.id=s,e.object=t;for(const t of r.params)null!=t.value&&(e[t.name]=t.value);return this.components.push(e),s}))}createFromActor(t){var i,r,a;return e(this,void 0,void 0,(function*(){const e=null!==(r=null===(i=this.actorTypes.find((e=>{var i;return e.name===(null===(i=t.actor)||void 0===i?void 0:i.type)})))||void 0===i?void 0:i.type)&&void 0!==r?r:_[null===(a=t.actor)||void 0===a?void 0:a.type];if(null==e)return null;this.inEditor&&this.editorActorParamSnapshot.set(t.id,JSON.stringify(t.actor));const n=yield this.actorProvider.create(e,(new A).fromArray(t.position),(new s).fromArray(t.rotation),!0);return this.materializedActors.set(t.id,n),null==n?void 0:n.container}))}cleanup(){this.materializedActors.clear()}createFromShape(t){var i,r,s;return e(this,void 0,void 0,(function*(){const e=this.inEditor&&t.hidden;let n;if("landscape"==t.shape)n=this.createLandscape(t);else{const s=new p({color:new a("#aaaaaa"),visible:this.inEditor||!t.hidden,wireframe:e}),o=yield this.createMeshByShape(t.shape,s,t.shapeParams);o.castShadow=null===(i=t.castShadow)||void 0===i||i,o.receiveShadow=null!==(r=t.castShadow)&&void 0!==r&&r,t.collisionDetection||(o.collisionShape=null),n=o}return e||((null!==(s=t.materialAssignments)&&void 0!==s?s:[]).filter((e=>null!=e.materialId)).forEach((e=>this.applyMaterial(n,e))),this.applyVertexMaterials(t,n)),n}))}createLandscape(e){var t;if(null==(null===(t=e.landscape)||void 0===t?void 0:t.options))return console.error(`No landscape options exist on scene object ${e.id} ${e.name}`),new l;const i=X(e.landscape.options);this.applyHeightMaps(i,e.landscape.heightMaps,!0);const r=new Y(e,this.renderingView,i,this.assetManagerService,this.assetsService,this.shaders,(t=>{var i;(null!==(i=e.materialAssignments)&&void 0!==i?i:[]).filter((e=>null!=e.materialId)).forEach((e=>this.applyMaterial(t,e)))}));return this.landscapeManagers.push(r),r.refreshGeometry(),i}applyHeightMaps(e,t,i=!1){const r=new q(e.sections);for(const e of null!=t?t:[]){const t=r.find(e.x,e.y);if(!t)return;const i=t.geometry.getAttribute("position");for(const t of e.points)i.setY(t.i,t.y);i.needsUpdate=!0}const a=e.sections;a.forEach((e=>{e.geometry.computeBoundsTree(),e.geometry.computeVertexNormals()})),this.inEditor&&!i||setTimeout((()=>Z(a)),50)}createMeshByShape(t,i,r={}){return e(this,void 0,void 0,(function*(){if("landscape"!==t&&ce.includes(t)){const a=yield function(t){return e(this,void 0,void 0,(function*(){const e={};for(const[i,r]of Object.entries(t)){const t=yield ge(r,null,null,null);null!=t&&(e[i]=t)}return e}))}(null!=r?r:{});return"cylinder"==t&&a.openEnded,new H(le[t].geometry(a),i,le[t].collision(a))}throw new Error(`Unsupported shape '${t}'`)}))}createFromAsset(t){var i,r,a,s;return e(this,void 0,void 0,(function*(){const e=yield this.assetsService.getAsset(t.assetId);if(null==e)return void console.warn(`Can not find asset with id ${t.assetId} and name ${t.name}`);let{scene:n}=yield this.assetManagerService.getMesh(e);Me(t.materialAssignments,e.materialAssignments).forEach((e=>this.applyMaterial(n,e)));const o=null===(r=null!==(i=t.receiveShadow)&&void 0!==i?i:!!e.receiveShadow)||void 0===r||r,l=null!==(s=null!==(a=t.castShadow)&&void 0!==a?a:!!e.castShadow)&&void 0!==s&&s;return n.receiveShadow=o,pe(n,l,o),t.collisionDetection||(n.collisionShapes=[]),this.applyVertexMaterials(t,n),n.traverse((e=>{e instanceof d&&"computeBoundsTree"in e.geometry&&e.geometry.computeBoundsTree()})),n}))}createFromPrefabAsset(t){return e(this,void 0,void 0,(function*(){const e=yield this.assetsService.getAsset(t.assetId);if(null==e)return void console.warn(`Can not find asset with id ${t.assetId} and name ${t.name}`);const i=new l;return e.prefab.objects.filter((e=>"global_fog"!==e.type)).forEach((e=>this.materialize(e,i,!0))),i}))}createParticleSystem(t){return e(this,void 0,void 0,(function*(){const e=yield this.assetsService.getAsset(t.assetId),r=new m;return yield b.fromJSONAsync(e.particleSystem,i).then((e=>{const t=new M(r,i);e.addRenderer(t),this.renderingView.onLoop((t=>e.update()))})),r}))}createLight(t){var i;return e(this,void 0,void 0,(function*(){if("point"===t.light.type){const e=new f(t.light.point.color,t.light.point.intensity,t.light.point.distance,t.light.point.decay);if(e.castShadow=null===(i=t.light.point.castShadow)||void 0===i||i,this.inEditor){const t=new y(1,10,10),i=new p({color:new a("#aaaaaa")}),r=new d(t,i);e.add(r)}return e}return"directional"===t.light.type?(this.applyDirectionalLight(t.light.directional),new l):"ambient"===t.light.type?(this.applyDirectionalAmbientLight(null,t.light.ambient),new l):void 0}))}applyDirectionalAmbientLight(e,t){const i=this.scene.children.find((e=>e.name===de));null!=i?(i.intensity=t.intensity,i.color.set(t.color),i.groundColor.set(t.color)):console.warn("Couldn't find ambient light")}applyDirectionalLight(e){for(const t of this.renderingView.csm.lights)t.intensity=e.intensity,t.color.set(e.color),t.castShadow=e.castShadow;this.renderingView.csm.lightDirection.fromArray(e.direction).normalize()}dispose(){this.updateSubscription.unsubscribe()}}function pe(e,t,i){e.castShadow=t,e.receiveShadow=i,e.traverse((e=>{e.castShadow=t,e.receiveShadow=i}))}const me=new Map,fe=new h({color:16711935}),ve=new Map;export function materialFromAsset(t,r,s,n,o,l=!0){var c,d,h,p,m,f,v,y,g;return e(this,void 0,void 0,(function*(){const e=JSON.stringify(t.material);if(l&&me.has(e))return me.get(e);const w={opacity:t.material.params.opacity,map:null,emissive:null!==(c=t.material.params.emissive)&&void 0!==c?c:null,metalness:null!==(d=t.material.params.metalness)&&void 0!==d?d:0,flatShading:null!==(h=t.material.params.flatShading)&&void 0!==h&&h,color:new a(t.material.params.color).convertSRGBToLinear(),transparent:null!=t.material.params.opacity&&t.material.params.opacity<1},A={};if(null!=t.material.params.map){const e=t.material.params.map,i=yield s.getAsset(e);null!=i&&(w.map=yield n.getTexture(i))}let S;switch(t.material.type){case"phong":S=new u(Object.assign(Object.assign({},w),A));break;case"water":S=te(w,r);break;case"grassFoliage":S=Q({color:w.color,map:w.map},r);break;case"grass":S=K(Object.assign(Object.assign({},w),{colorTwo:new a(t.material.params.colorTwo),colorThree:new a(t.material.params.colorThree)}),r);break;case"standard":case"lambert":case"shader":const e=null!==(p={standard:ne,lambert:oe}[t.material.type])&&void 0!==p?p:null===(m=o.find((e=>e.name==t.material.shader)))||void 0===m?void 0:m.type;if(e){const i=new e,a=yield ye(null!==(v=null===(f=t.material)||void 0===f?void 0:f.shaderParams)&&void 0!==v?v:{},e,s,n,null,r,o);Object.assign(i,a);try{S=i.build()}catch(e){console.log("Shader runtime error: "+e),ve.has(t.material.shader)||ve.set(t.material.shader,fe.clone()),S=ve.get(t.material.shader)}S.userData.customShaderName=t.material.shader}else console.warn("Missing shader implementation with name "+t.material.shader),S=fe;break;default:throw new Error("Unsupported material type"+t.material.type)}return null==r||r.csm.setupMaterial(S),l&&me.set(e,S),S.side=null!==(g=null!==(y=t.material.side)&&void 0!==y?y:S.side)&&void 0!==g?g:i.FrontSide,S}))}function ye(t,i,r,a,s,n,o){return e(this,void 0,void 0,(function*(){const e={};for(const[i,l]of Object.entries(t)){const t=yield ge(l,r,a,s,n,o);null!=t&&(e[i]=t)}return e}))}function ge(t,i,r,n,o,l){return e(this,void 0,void 0,(function*(){if(null==t||null==t.value||""==t.value)return null;const e=t.value;switch(t.type){case ie.Number:case ie.FloatNode:let c="string"==typeof e?parseFloat(e):e;return t.type===ie.FloatNode?D(c):c;case ie.Texture:return yield r.getTexture(yield i.getAsset(e));case ie.Sampler2DNode:return F(yield r.getTexture(yield i.getAsset(e)));case ie.Boolean:return e;case ie.BooleanNode:return x(e);case ie.Vector2:case ie.Vec2Node:if("object"==typeof e){const i=e instanceof Array?(new w).fromArray(e):new w(i.x,i.y);return t.type===ie.Vec2Node?V(i):i}return null;case ie.Vector3:case ie.Vec3Node:if("object"==typeof e){const i=e instanceof Array?(new A).fromArray(e):new A(i.x,i.y,i.z);return t.type===ie.Vec3Node?z(i):i}return null;case ie.Color:case ie.RgbNode:const d=new a(e).convertSRGBToLinear();return t.type===ie.RgbNode?j(d):d;case ie.String:return e;case ie.BaseActor:const h=e;return null==n&&console.warn("Class parameters can not be prepared as actors are not passed in"),null==n?void 0:n.get(h);case ie.Euler:const u=e;return(new s).fromArray(u);case ie.Mesh:return(yield r.getMesh(yield i.getAsset(e))).scene;case ie.Material:return yield materialFromAsset(yield i.getAsset(e),o,i,r,l);case ie.AudioBuffer:return yield r.getAudio(yield i.getAsset(e))}return null}))}function we(e){var t,i;return"linear"===e.type?new n(new a(e.color),null!==(t=e.near)&&void 0!==t?t:100,null!==(i=e.far)&&void 0!==i?i:1e3):"density"===e.type?new o(e.color,e.density):void console.warn("Invalid fog type",e)}const Ae=new p({color:4229780});function Se(t,r,a,n){var o;return e(this,void 0,void 0,(function*(){null==n&&(n=(new re).identity()),yield r(t,a,n);const e=n.clone().multiply(function(e,t){return t.compose((new A).fromArray(e.position),(new v).setFromEuler((new s).fromArray(e.rotation)),(new A).fromArray(e.scale))}(t,new i.Matrix4));return Promise.all((null!==(o=t.children)&&void 0!==o?o:[]).map((i=>Se(i,r,t,e))))}))}function be(e){const t=e.constructor.prototype;return t instanceof Number||e===Number?ie.Number:t instanceof P||"function"==typeof e.prototype.isFloat?ie.FloatNode:t instanceof g||e===g||e.isTexture?ie.Texture:t instanceof se||e===O?ie.Sampler2DNode:t instanceof Boolean||e===Boolean?ie.Boolean:t instanceof I?ie.BooleanNode:t instanceof a||e==a?ie.Color:t instanceof N||"function"==typeof e.prototype.isRgb?ie.RgbNode:t instanceof w||e==w?ie.Vector2:t instanceof B||"function"==typeof e.prototype.isVec2?ie.Vec2Node:t instanceof A||e==A?ie.Vector3:t instanceof C||"function"==typeof e.prototype.isVec3?ie.Vec3Node:t instanceof String||e===String?ie.String:t instanceof ae||e==ae||e.prototype instanceof ae||e.prototype==ae?ie.BaseActor:t instanceof s||e==s?ie.Euler:t instanceof d||e==d?ie.Mesh:t instanceof c||e==c?ie.Material:t instanceof AudioBuffer||e==AudioBuffer?ie.AudioBuffer:void console.warn("Failed to map parameter type to serialized version",{type:e})}export function prepareCustomParams(e,t,i={}){return Object.fromEntries(e.map((e=>{var r,a,s;return[e.name,{type:be(e.type),value:null!==(s=null!==(a=null===(r=t[e.name])||void 0===r?void 0:r.value)&&void 0!==a?a:i[e.name])&&void 0!==s?s:Ie.get(be(e.type))}]})))}export function prepareCustomParamsFromType(e,t,i=null){const r=$(e);if(0===r.length)return{};let a;null!=i?he(i,(()=>{a=i.get(e)})):a=new e;const s={};for(const e of r){const t=a[e.name];if(null!=t){const i=serializeCustomParameter(e.type,t);null!=i&&(s[e.name]=i)}}return prepareCustomParams(r,t,s)}export function serializeCustomParameter(e,t){function i(){console.error("Failed to serialize value",{type:e,value:t})}switch(e){case Number:case Boolean:return t;case w:return t instanceof w?t.toArray():void i();case A:return t instanceof A?t.toArray():void i();case S:return t instanceof S?t.toArray():void i();case a:return t instanceof a?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new a(t).getHexString():void i();case String:return t;case s:return t instanceof s?t.toArray():void i()}}function Me(e,t){return function(e,t,i){const r=[],a=new Set;for(const s of[...null!=e?e:[],...null!=t?t:[]]){const e=i(s);a.has(e)||(a.add(e),r.push(s))}return r}((null!=e?e:[]).filter((e=>xe(e.materialId))),(null!=t?t:[]).filter((e=>xe(e.materialId))),(e=>e.color))}function xe(e){return"null"!=e&&null!=e}const Ie=new Map([[ie.RgbNode,"#000000"],[ie.Color,"#000000"],[ie.Vector4,[0,0,0,0]],[ie.Vec4Node,[0,0,0,0]],[ie.Vector3,[0,0,0]],[ie.Vec3Node,[0,0,0]],[ie.Vector2,[0,0]],[ie.Vec2Node,[0,0]],[ie.Euler,[0,0,0,"XYZ"]]]);
|
1
|
+
import{__awaiter as e}from"tslib";import{Subject as t}from"rxjs";import*as i from"three";import{BoxGeometry as r,Color as a,Euler as s,Fog as n,FogExp2 as o,Group as l,Material as c,Mesh as d,MeshLambertMaterial as h,MeshPhongMaterial as u,MeshStandardMaterial as p,Object3D as m,PointLight as f,Quaternion as v,SphereGeometry as y,Texture as g,Vector2 as w,Vector3 as A,Vector4 as S}from"three";import b,{SpriteRenderer as M}from"three-nebula";import{bool as x,BooleanNode as I,float as D,FloatNode as P,NodeShaderMaterial as j,rgb as E,RgbNode as N,Texture2dLookupNode as O,textureSampler2d as F,vec2 as V,Vec2Node as B,vec3 as z,Vec3Node as C,vec4 as T}from"three-shader-graph";import _ from"../gameplay/actors/builtin";import{extractShaderParameters as $}from"../shader/parameter";import{groupBy as k,ArrayMap as L}from"../utils/collections";import{filterChildrenShallow as R,filterSceneShallow as U}from"../utils/three/traverse";import{AssetMeshInstance as W}from"./asset-resource-loader";import{BoxCollisionShape as G,PhysicalShapeMesh as H}from"./collision/collision-shape";import{isCollisionMesh as J}from"./collision/collision-shape-import";import{initLandscape as X}from"./landscape/landscape";import{LandscapeManager as Y}from"./landscape/landscape-manager";import{SectionGrid as q,smoothNormalsCrossMeshes as Z}from"./landscape/utils";import{createGrassMaterial as K}from"./materials/grass";import{createGrassFoliageMaterial as Q}from"./materials/grass-foliage";import{getMaterialAttribute as ee}from"./materials/utils/material-painting";import{createWaterMaterial as te}from"./materials/water";import{SerializedParamType as ie}from"./model";import{Matrix4 as re}from"three";import{BaseActor as ae}from"../gameplay/actors/actor";import{Sampler2DNode as se}from"../shader-nodes";import{StandardShader as ne}from"../shader/builtin/standard-shader";import{LambertShader as oe}from"../shader/builtin/lambert-shader";import{ShapeLibrary as le,ShapeLibraryKeys as ce}from"./objects/shapes";import{ambientLightName as de}from"./sky";import{withInjectionContext as he}from"../gameplay";const ue={};export const shapeDefaultColor="#aaaaaa";export class SceneMaterializerLoader{constructor(e,t,i){this.dataProvider=e,this.assetsService=t,this.assetManagerService=i}get(t,i){return new SceneMaterializer(t,this.dataProvider,this.assetsService,this.assetManagerService,i,[],[],{create:()=>null,initActor:()=>e(this,void 0,void 0,(function*(){}))})}}export class SceneMaterializer{constructor(i,r,a,s,n,o,l,c){this.scene=i,this.dataProvider=r,this.assetsService=a,this.assetManagerService=s,this.renderingView=n,this.shaders=o,this.actorTypes=l,this.actorProvider=c,this.objectMap=new Map,this.sceneObjectMap=new Map,this.components=[],this.landscapeManagers=[],this.materializedActors=new Map,this.inEditor=!0,this.updated$=new t,this.removed$=new t,this.error$=new t,this.editorActorParamSnapshot=new Map,this._canBeInstancedCache=new Map,this._originalMaterials=new Map,this.originalFog=null,r.onUpdate((e=>this.update(e))),r.onRemove((e=>this.remove(e))),this.updateSubscription=a.onUpdate.subscribe((t=>e(this,void 0,void 0,(function*(){"material"==t.type?((yield this.assetsService.getAssets()).filter((e=>{var i;return(null!==(i=e.materialAssignments)&&void 0!==i?i:[]).some((e=>e.materialId===t.id))})).forEach((e=>{const t=this.findByAssetId(e.id);e.materialAssignments.forEach((e=>{t.forEach((t=>{const i=t.userData.src.materialAssignments;null!=i&&i.some((t=>t.color===e.color))||this.applyMaterial(t,e)}))}))})),U(this.scene,(e=>{var i;return null!=e.userData.src&&(null!==(i=e.userData.src.materialAssignments)&&void 0!==i?i:[]).some((e=>e.materialId===t.id))}),(e=>null!=e.userData.src)).forEach((t=>e(this,void 0,void 0,(function*(){this.deleteSceneObject(t.userData.src),this.materialize(t.userData.src)}))))):"mesh"==t.type?this.findByAssetId(t.id).forEach((e=>{Me(e.userData.src.materialAssignments,t.materialAssignments).forEach((t=>{this.applyMaterial(e,t)}))})):"prefab"===t.type&&this.findByAssetId(t.id).forEach((e=>{const t=e.userData.src;this.remove(t),this.materializeAndInitActor(t)}))}))))}get actorInstances(){return Array.from(this.materializedActors.values())}prefetchAssets(){return e(this,void 0,void 0,(function*(){const e=Array.from(new Set(this.dataProvider.getObjects().filter((e=>null!=e.assetId&&"asset_mesh"==e.type)).filter((e=>e.assetId))));yield Promise.all(e.map((e=>this.assetsService.getAsset(e.assetId).then((e=>e&&this.assetManagerService.getMesh(e))))))}))}init(){return e(this,void 0,void 0,(function*(){me.clear(),yield this.prefetchAssets(),yield Promise.all(this.dataProvider.getObjects().map((e=>this.materialize(e)))),yield this.initActorsPostInit()}))}initActorsPostInit(t=this.actorInstances){const i=t.map((t=>e(this,void 0,void 0,(function*(){var e,i,r,a;const s=t.object.userData.src,n=yield this.assetsService.getAsset(s.assetId),o=Object.assign(Object.assign({},null!==(i=null===(e=null==n?void 0:n.actor)||void 0===e?void 0:e.params)&&void 0!==i?i:{}),null!==(r=s.actor.params)&&void 0!==r?r:{});for(const e of null!==(a=s.actor.innerParams)&&void 0!==a?a:[])yield this.applyActorComponentParams(t,e.path.slice(),e.params);const l=yield ye(o,t.constructor,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders);Object.assign(t,l);try{return yield this.actorProvider.initActor(t)}catch(e){console.error(`Failed to initiate actor (name="${s.name}", id=${s.id})`,e)}}))));return Promise.all(i)}applyActorComponentParams(t,i,r){return e(this,void 0,void 0,(function*(){const e=i.length,a=i.shift();if(0==e){const e=yield ye(r,null,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders);for(const[i,r]of Object.entries(e))null!=r&&(t[i]=r)}else null!=t[a]&&(yield this.applyActorComponentParams(t[a],i,r))}))}canAssetBeInstanced(t){return e(this,void 0,void 0,(function*(){if(!this._canBeInstancedCache.has(t.assetId)){const e=yield this.createFromAsset(t);if(null==e)return!1;const i=[];e.traverse((e=>{!J(e)&&e.isMesh&&i.push(e)}));const r=1==i.length&&0==i[0].children.length,a=!0;this._canBeInstancedCache.set(t.assetId,r&&a)}return this._canBeInstancedCache.get(t.assetId)}))}initWithInstancing(){return e(this,void 0,void 0,(function*(){const t=new L;for(const i of this.dataProvider.getObjects())yield Se(i,((i,r,a)=>e(this,void 0,void 0,(function*(){var e,s;const n="asset_mesh"==i.type&&(yield this.canAssetBeInstanced(i))?i.assetId+JSON.stringify(null!==(e=i.materialAssignments)&&void 0!==e?e:[]):"other";"other"!==n&&r&&(null===(s=r.children)||void 0===s?void 0:s.length)>0&&r.children.splice(r.children.findIndex((e=>e.id===i.id)),1),t.push(n,Object.assign(Object.assign({},i),{parentTransform:a}))}))));for(const[e,i]of t.entries())if("other"!==e&&i.length>1){const e=yield this.createFromAsset(i[0]);if(null==e)continue;const t=yield this.createInstancedMesh(i,e),r=new W;r.add(t),r.userData.src=i[0],e instanceof W&&(r.collisionShapes=e.collisionShapes),r.castShadow=!1,r.receiveShadow=!1,this.scene.add(r)}else yield Promise.all(i.map((e=>this.materialize(e))));yield this.initActorsPostInit()}))}createInstancedMesh(t,r){var a,n;return e(this,void 0,void 0,(function*(){const e=r.children.filter((e=>!J(e)))[0],o=yield this.assetsService.getAsset(t[0].assetId);yield this.applyMaterials(r,Me(t[0].materialAssignments,o.materialAssignments)),e.updateMatrix();const l=e.geometry.clone().applyMatrix4(e.matrix),c=new i.InstancedMesh(l,e.material.clone(),t.length);c.material.side=i.FrontSide;for(let e=0;e<t.length;e++){const r=(new i.Matrix4).compose((new A).fromArray(t[e].position),(new v).setFromEuler((new s).fromArray(t[e].rotation)),(new A).fromArray(t[e].scale)),a=(new re).copy(t[e].parentTransform).multiply(r);c.setMatrixAt(e,a)}return c.castShadow=null===(a=o.castShadow)||void 0===a||a,c.receiveShadow=null===(n=o.receiveShadow)||void 0===n||n,c}))}remove(e){if("global_fog"==e.type)return void(this.scene.fog=this.originalFog);if("actor"==e.type){const t=this.materializedActors.get(e.id);null!=t&&t.disposed.next(!0)}const t=this.sceneObjectMap.get(e.id);null==t||t.parent.remove(t),this.sceneObjectMap.delete(e.id),this.components.filter((t=>{var i;return(null===(i=t.object.userData.src)||void 0===i?void 0:i.id)===e.id})).forEach((e=>this.components.splice(this.components.indexOf(e,1)))),this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>{e.clear(),e.stop(),this.landscapeManagers.splice(this.landscapeManagers.indexOf(e,1))})),this.removed$.next({object:t,source:e})}deleteSceneObject(e){const t=this.sceneObjectMap.get(e.id);if(this.scene.remove(t),"landscape"==e.type){const t=this.landscapeManagers.findIndex((t=>t.source.id===e.id));if(t>-1){const e=this.landscapeManagers.splice(t,1)[0];e.clear(),e.stop()}}}findByAssetId(e){return U(this.scene,(t=>{var i;return(null===(i=t.userData.src)||void 0===i?void 0:i.assetId)==e}),(e=>null!=e.userData.src))}applyMaterials(e,t){return Promise.all(t.filter((e=>"null"!==e.materialId)).map((t=>this.applyMaterial(e,t))))}applyMaterial(t,i){const r=[];return t.traverse((t=>e(this,void 0,void 0,(function*(){(t instanceof d||t.isMesh)&&t.material.hasOwnProperty("color")&&r.push(t)})))),Promise.all(r.map((t=>e(this,void 0,void 0,(function*(){var e;const r="#"+t.material.color.getHexString();if(r===i.color||t.userData.originalColor===i.color){const a=yield this.assetsService.getAsset(i.materialId),s=t.material;a&&(t.material=yield materialFromAsset(a,this.renderingView,this.assetsService,this.assetManagerService,this.shaders),t.userData.originalColor=null!==(e=t.userData.originalColor)&&void 0!==e?e:r,this.inEditor&&this._originalMaterials.set(t.id,s))}})))))}unapplyMaterials(t){t.traverse((t=>e(this,void 0,void 0,(function*(){t instanceof d&&this._originalMaterials.has(t.id)&&(t.material=this._originalMaterials.get(t.id))}))))}updateActors(t){this.actorTypes=t;const i=new Set(Object.values(_));U(this.scene,(e=>{var t,r;return(null===(t=e.userData.src)||void 0===t?void 0:t.id)&&"actor"===e.userData.src.type&&this.materializedActors.has(null===(r=e.userData.src)||void 0===r?void 0:r.id)&&!i.has(e.userData.src.actor.type)})).forEach((t=>e(this,void 0,void 0,(function*(){this.remove(t.userData.src),console.time(t.userData.src.id),yield this.materializeAndInitActor(t.userData.src),console.timeEnd(t.userData.src.id)}))))}updateShaders(e){this.shaders=e;for(const[e,t]of me.entries())t.userData.customShaderName&&me.delete(e);this.landscapeManagers.forEach((t=>t.updateShaders(e))),U(this.scene,(e=>!0)).forEach((e=>{e.traverse((e=>{var t;if(e instanceof d){if(null!=e.material.userData.customShaderName){const i=null===(t=function(e,t){if(t(e))return e;let i;return e.traverseAncestors((e=>{null==i&&t(e)&&(i=e)})),i}(e,(e=>{var t;return null!=(null===(t=e.userData.src)||void 0===t?void 0:t.id)})))||void 0===t?void 0:t.userData.src;null!=i&&this.update(i)}}}))}))}update(t){var i;return e(this,void 0,void 0,(function*(){const e=this.sceneObjectMap.get(t.id);if(e){const s=this.findParent(t);null!=s&&s.uuid!=e.uuid?s.attach(e):console.error("Parent is wrong"),this.unapplyMaterials(e);if(this.inEditor&&t.hidden&&!1?e.traverse((e=>{e instanceof d&&(e.material.wireframe=!0)})):(e.traverse((e=>{e instanceof d&&(e.material.wireframe=!1)})),(null!==(i=t.materialAssignments)&&void 0!==i?i:[]).forEach((t=>this.applyMaterial(e,t)))),e.position.fromArray(t.position),e.scale.fromArray(t.scale),e.rotation.fromArray(t.rotation),this.applyVertexMaterials(t,e),"light"==t.type)if("point"==t.light.type){const i=e;i.color=new a(t.light.point.color),i.intensity=t.light.point.intensity,i.decay=t.light.point.decay,i.castShadow=t.light.point.castShadow,i.distance=Math.max(t.light.point.distance,0)}else"directional"===t.light.type?this.applyDirectionalLight(t.light.directional):"ambient"===t.light.type&&this.applyDirectionalAmbientLight(e,t.light.ambient);else if("landscape"===t.shape)this.applyHeightMaps(e,t.landscape.heightMaps),this.inEditor&&this.landscapeManagers.filter((e=>e.source.id===t.id)).forEach((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>!0))));else if("global_fog"===t.type){const e=(this.scene.fog instanceof o?"density":"linear")!==t.fog.type;this.scene.fog=we(t.fog),e&&(r=this.scene).traverse((e=>{if(e instanceof d){const t=e.material;t instanceof j&&(r.fog instanceof n?(t.uniforms.fogFar.value=r.fog.far,t.uniforms.fogNear.value=r.fog.near):r.fog instanceof o&&(t.uniforms.density={value:r.fog.density}),t.needsUpdate=!0,t.uniformsNeedUpdate=!0)}})),this.fixFogColor()}else if("actor"===t.type){if(this.materializedActors.has(t.id)){const e=this.editorActorParamSnapshot.get(t.id);null!=e&&e===JSON.stringify(t.actor)||(console.log("Rematerializing actor because parameters changed"),this.remove(t),yield this.materializeAndInitActor(t))}}else if("shape_mesh"===t.type){const i=yield this.createMeshByShape(t.shape,e.material,t.shapeParams);e instanceof H&&(e.geometry=i.geometry,e.collisionShape=i.collisionShape)}"asset_mesh"!==t.type&&"shape_mesh"!==t.type||pe(e,t.castShadow,t.receiveShadow),t.name&&t.name.length>0&&(e.name=t.name),this.updated$.next({object:e,source:t})}else{const e=yield this.materializeAndInitActor(t);this.updated$.next({object:e,source:t})}var r}))}materializeAndInitActor(t){return e(this,void 0,void 0,(function*(){const e=this.findParent(t),i=yield this.materialize(t,e);if("actor"===t.type){const e=this.materializedActors.get(t.id);null!=e?yield this.initActorsPostInit([e]):console.error(`Something went wrong when creating actor ${t.id}`)}return i}))}findParent(e){const t=this.dataProvider.getObjects().flatMap((t=>t.id===e.id?null:R(t,(t=>{var i;return null===(i=t.children)||void 0===i?void 0:i.some((t=>t.id===e.id))}),(()=>!0))))[0];return null==t?this.scene:null!=t?U(this.scene,(e=>{var i,r;return(null===(r=null===(i=e.userData)||void 0===i?void 0:i.src)||void 0===r?void 0:r.id)===t.id}),(e=>{var t;return null!=(null===(t=e.userData)||void 0===t?void 0:t.src)}))[0]:void 0}fixFogColor(){!0===this.renderingView.options.enableOutlines&&(this.scene.fog.color=new a(this.scene.fog.color).convertSRGBToLinear())}findMeshWithGeometry(e){let t;return e.traverse((e=>{e instanceof d&&e.geometry&&(t=e)})),t}applyVertexMaterials(e,t){if(null==e.vertexMaterials||0===e.vertexMaterials.length)return;const i=k(e.vertexMaterials,(e=>e.m));t.traverse((e=>{if(e instanceof d){const t=ee(e,!1);if(null!=t){for(let e=0;e<t.array.length;e++)t.setX(e,0);t.needsUpdate=!0}}}));const r=new Set;for(const[e,a]of i.entries()){const i=null!=e?t.getObjectByName(e):this.findMeshWithGeometry(t);let s=!1;if(null==i)return void console.warn(`Failed to apply vertex materials on mesh with name "${e}"`);const n=ee(i,!0);for(let e=0;e<n.array.length;e++)n.setX(e,0);for(const e of a)n.setX(e.i,e.w[0]),n.setY(e.i,e.w[1]),n.setZ(e.i,e.w[2]),s=!0;s&&r.add(e)}this.inEditor&&this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>r.has(e.name)))))}materialize(t,i,a=!1){var s,n,o,c;return e(this,void 0,void 0,(function*(){let e;switch(t.type){case"asset_mesh":e=yield this.createFromAsset(t);break;case"shape_mesh":e=yield this.createFromShape(t);break;case"light":e=yield this.createLight(t);break;case"particles":e=yield this.createParticleSystem(t),t.collisionDetection=!1;break;case"global_fog":this.scene.fog=we(t.fog),this.fixFogColor(),e=new l;break;case"actor":e=yield this.createFromActor(t);break;case"group":e=new l;break;case"prefab":e=yield this.createFromPrefabAsset(t);break;default:throw console.log(t),new Error("unknown type "+t.type)}if(null!=e){if(t.name&&t.name.length>0&&(e.name=t.name),e.position.fromArray(t.position),e.scale.fromArray(t.scale),e.rotation.fromArray(t.rotation),a||(e.userData.src=t),!this.inEditor){const i=null!==(s=t.components)&&void 0!==s?s:[],r=null!=t.assetId&&null!==(o=null===(n=yield this.assetsService.getAsset(t.assetId))||void 0===n?void 0:n.components)&&void 0!==o?o:[];i.push(...r),i.length>0?e.userData.componentRefs=yield Promise.all(i.map(((i,r)=>this.createComponent(e,t,i,r)))):"asset_mesh"==t.type&&function(e){e.traverse((e=>{e.matrixAutoUpdate=!1,e.matrixWorldNeedsUpdate=!1}));const t=e.updateMatrixWorld;e.updateMatrixWorld=function(){t.apply(e),e.updateMatrixWorld=function(){}}}(e)}if(this.inEditor){let t=null;e instanceof H&&(t=function(e){if(e instanceof G)return new d(new r(...e.offset.toArray()),Ae);return null}(e.collisionShape)),null!=t&&(t.layers.disable(0),t.layers.enable(18),t.scale.multiplyScalar(1.1),e.add(t))}return this.objectMap.set(e.uuid,t),this.sceneObjectMap.set(t.id,e),null==i?this.scene.add(e):null==i||i.add(e),null===(c=t.children)||void 0===c||c.forEach((t=>{this.materialize(t,e,a)})),e}}))}createComponent(t,i,r,a){return e(this,void 0,void 0,(function*(){const e=new ue[r.path+"/"+r.className],s=i.id+a;e.id=s,e.object=t;for(const t of r.params)null!=t.value&&(e[t.name]=t.value);return this.components.push(e),s}))}createFromActor(t){var i,r,a;return e(this,void 0,void 0,(function*(){const e=null!==(r=null===(i=this.actorTypes.find((e=>{var i;return e.name===(null===(i=t.actor)||void 0===i?void 0:i.type)})))||void 0===i?void 0:i.type)&&void 0!==r?r:_[null===(a=t.actor)||void 0===a?void 0:a.type];if(null==e)return null;this.inEditor&&this.editorActorParamSnapshot.set(t.id,JSON.stringify(t.actor));const n=yield this.actorProvider.create(e,(new A).fromArray(t.position),(new s).fromArray(t.rotation),!0);return this.materializedActors.set(t.id,n),null==n?void 0:n.object}))}cleanup(){this.materializedActors.clear()}createFromShape(t){var i,r,s;return e(this,void 0,void 0,(function*(){const e=this.inEditor&&t.hidden;let n;if("landscape"==t.shape)n=this.createLandscape(t);else{const s=new p({color:new a("#aaaaaa"),visible:this.inEditor||!t.hidden,wireframe:e}),o=yield this.createMeshByShape(t.shape,s,t.shapeParams);o.castShadow=null===(i=t.castShadow)||void 0===i||i,o.receiveShadow=null!==(r=t.castShadow)&&void 0!==r&&r,t.collisionDetection||(o.collisionShape=null),n=o}return e||((null!==(s=t.materialAssignments)&&void 0!==s?s:[]).filter((e=>null!=e.materialId)).forEach((e=>this.applyMaterial(n,e))),this.applyVertexMaterials(t,n)),n}))}createLandscape(e){var t;if(null==(null===(t=e.landscape)||void 0===t?void 0:t.options))return console.error(`No landscape options exist on scene object ${e.id} ${e.name}`),new l;const i=X(e.landscape.options);this.applyHeightMaps(i,e.landscape.heightMaps,!0);const r=new Y(e,this.renderingView,i,this.assetManagerService,this.assetsService,this.shaders,(t=>{var i;(null!==(i=e.materialAssignments)&&void 0!==i?i:[]).filter((e=>null!=e.materialId)).forEach((e=>this.applyMaterial(t,e)))}));return this.landscapeManagers.push(r),r.refreshGeometry(),i}applyHeightMaps(e,t,i=!1){const r=new q(e.sections);for(const e of null!=t?t:[]){const t=r.find(e.x,e.y);if(!t)return;const i=t.geometry.getAttribute("position");for(const t of e.points)i.setY(t.i,t.y);i.needsUpdate=!0}const a=e.sections;a.forEach((e=>{e.geometry.computeBoundsTree(),e.geometry.computeVertexNormals()})),this.inEditor&&!i||setTimeout((()=>Z(a)),50)}createMeshByShape(t,i,r={}){return e(this,void 0,void 0,(function*(){if("landscape"!==t&&ce.includes(t)){const a=yield function(t){return e(this,void 0,void 0,(function*(){const e={};for(const[i,r]of Object.entries(t)){const t=yield ge(r,null,null,null);null!=t&&(e[i]=t)}return e}))}(null!=r?r:{});return"cylinder"==t&&a.openEnded,new H(le[t].geometry(a),i,le[t].collision(a))}throw new Error(`Unsupported shape '${t}'`)}))}createFromAsset(t){var i,r,a,s;return e(this,void 0,void 0,(function*(){const e=yield this.assetsService.getAsset(t.assetId);if(null==e)return void console.warn(`Can not find asset with id ${t.assetId} and name ${t.name}`);let{scene:n}=yield this.assetManagerService.getMesh(e);Me(t.materialAssignments,e.materialAssignments).forEach((e=>this.applyMaterial(n,e)));const o=null===(r=null!==(i=t.receiveShadow)&&void 0!==i?i:!!e.receiveShadow)||void 0===r||r,l=null!==(s=null!==(a=t.castShadow)&&void 0!==a?a:!!e.castShadow)&&void 0!==s&&s;return n.receiveShadow=o,pe(n,l,o),t.collisionDetection||(n.collisionShapes=[]),this.applyVertexMaterials(t,n),n.traverse((e=>{e instanceof d&&"computeBoundsTree"in e.geometry&&e.geometry.computeBoundsTree()})),n}))}createFromPrefabAsset(t){return e(this,void 0,void 0,(function*(){const e=yield this.assetsService.getAsset(t.assetId);if(null==e)return void console.warn(`Can not find asset with id ${t.assetId} and name ${t.name}`);const i=new l;return e.prefab.objects.filter((e=>"global_fog"!==e.type)).forEach((e=>this.materialize(e,i,!0))),i}))}createParticleSystem(t){return e(this,void 0,void 0,(function*(){const e=yield this.assetsService.getAsset(t.assetId),r=new m;return yield b.fromJSONAsync(e.particleSystem,i).then((e=>{const t=new M(r,i);e.addRenderer(t),this.renderingView.onLoop((t=>e.update()))})),r}))}createLight(t){var i;return e(this,void 0,void 0,(function*(){if("point"===t.light.type){const e=new f(t.light.point.color,t.light.point.intensity,t.light.point.distance,t.light.point.decay);if(e.castShadow=null===(i=t.light.point.castShadow)||void 0===i||i,this.inEditor){const t=new y(1,10,10),i=new p({color:new a("#aaaaaa")}),r=new d(t,i);e.add(r)}return e}return"directional"===t.light.type?(this.applyDirectionalLight(t.light.directional),new l):"ambient"===t.light.type?(this.applyDirectionalAmbientLight(null,t.light.ambient),new l):void 0}))}applyDirectionalAmbientLight(e,t){const i=this.scene.children.find((e=>e.name===de));null!=i?(i.intensity=t.intensity,i.color.set(t.color),i.groundColor.set(t.color)):console.warn("Couldn't find ambient light")}applyDirectionalLight(e){for(const t of this.renderingView.csm.lights)t.intensity=e.intensity,t.color.set(e.color),t.castShadow=e.castShadow;this.renderingView.csm.lightDirection.fromArray(e.direction).normalize()}dispose(){this.updateSubscription.unsubscribe()}}function pe(e,t,i){e.castShadow=t,e.receiveShadow=i,e.traverse((e=>{e.castShadow=t,e.receiveShadow=i}))}const me=new Map,fe=new h({color:16711935}),ve=new Map;export function materialFromAsset(t,r,s,n,o,l=!0){var c,d,h,p,m,f,v,y,g;return e(this,void 0,void 0,(function*(){const e=JSON.stringify(t.material);if(l&&me.has(e))return me.get(e);const w={opacity:t.material.params.opacity,map:null,emissive:null!==(c=t.material.params.emissive)&&void 0!==c?c:null,metalness:null!==(d=t.material.params.metalness)&&void 0!==d?d:0,flatShading:null!==(h=t.material.params.flatShading)&&void 0!==h&&h,color:new a(t.material.params.color).convertSRGBToLinear(),transparent:null!=t.material.params.opacity&&t.material.params.opacity<1},A={};if(null!=t.material.params.map){const e=t.material.params.map,i=yield s.getAsset(e);null!=i&&(w.map=yield n.getTexture(i))}let S;switch(t.material.type){case"phong":S=new u(Object.assign(Object.assign({},w),A));break;case"water":S=te(w,r);break;case"grassFoliage":S=Q({color:w.color,map:w.map},r);break;case"grass":S=K(Object.assign(Object.assign({},w),{colorTwo:new a(t.material.params.colorTwo),colorThree:new a(t.material.params.colorThree)}),r);break;case"standard":case"lambert":case"shader":const e=null!==(p={standard:ne,lambert:oe}[t.material.type])&&void 0!==p?p:null===(m=o.find((e=>e.name==t.material.shader)))||void 0===m?void 0:m.type;if(e){const i=new e,a=yield ye(null!==(v=null===(f=t.material)||void 0===f?void 0:f.shaderParams)&&void 0!==v?v:{},e,s,n,null,r,o);Object.assign(i,a);try{S=i.build()}catch(e){console.log("Shader runtime error: "+e),ve.has(t.material.shader)||ve.set(t.material.shader,fe.clone()),S=ve.get(t.material.shader)}S.userData.customShaderName=t.material.shader}else console.warn("Missing shader implementation with name "+t.material.shader),S=fe;break;default:throw new Error("Unsupported material type"+t.material.type)}return null==r||r.csm.setupMaterial(S),l&&me.set(e,S),S.side=null!==(g=null!==(y=t.material.side)&&void 0!==y?y:S.side)&&void 0!==g?g:i.FrontSide,S}))}function ye(t,i,r,a,s,n,o){return e(this,void 0,void 0,(function*(){const e={};for(const[i,l]of Object.entries(t)){const t=yield ge(l,r,a,s,n,o);null!=t&&(e[i]=t)}return e}))}function ge(t,i,r,n,o,l){return e(this,void 0,void 0,(function*(){if(null==t||null==t.value||""==t.value)return null;const e=t.value;switch(t.type){case ie.Number:case ie.FloatNode:let c="string"==typeof e?parseFloat(e):e;return t.type===ie.FloatNode?D(c):c;case ie.Texture:return yield r.getTexture(yield i.getAsset(e));case ie.Sampler2DNode:return F(yield r.getTexture(yield i.getAsset(e)));case ie.Boolean:return e;case ie.BooleanNode:return x(e);case ie.Vector2:case ie.Vec2Node:if("object"==typeof e){const i=e instanceof Array?(new w).fromArray(e):new w(i.x,i.y);return t.type===ie.Vec2Node?V(i):i}return null;case ie.Vector3:case ie.Vec3Node:if("object"==typeof e){const i=e instanceof Array?(new A).fromArray(e):new A(i.x,i.y,i.z);return t.type===ie.Vec3Node?z(i):i}return null;case ie.Color:case ie.RgbNode:const d=new a(e).convertSRGBToLinear();return t.type===ie.RgbNode?E(d):d;case ie.String:return e;case ie.BaseActor:const h=e;return null==n&&console.warn("Class parameters can not be prepared as actors are not passed in"),null==n?void 0:n.get(h);case ie.Euler:const u=e;return(new s).fromArray(u);case ie.Object3D:return(yield r.getMesh(yield i.getAsset(e))).scene;case ie.Material:return yield materialFromAsset(yield i.getAsset(e),o,i,r,l);case ie.AudioBuffer:return yield r.getAudio(yield i.getAsset(e))}return null}))}function we(e){var t,i;return"linear"===e.type?new n(new a(e.color),null!==(t=e.near)&&void 0!==t?t:100,null!==(i=e.far)&&void 0!==i?i:1e3):"density"===e.type?new o(e.color,e.density):void console.warn("Invalid fog type",e)}const Ae=new p({color:4229780});function Se(t,r,a,n){var o;return e(this,void 0,void 0,(function*(){null==n&&(n=(new re).identity()),yield r(t,a,n);const e=n.clone().multiply(function(e,t){return t.compose((new A).fromArray(e.position),(new v).setFromEuler((new s).fromArray(e.rotation)),(new A).fromArray(e.scale))}(t,new i.Matrix4));return Promise.all((null!==(o=t.children)&&void 0!==o?o:[]).map((i=>Se(i,r,t,e))))}))}function be(e){const t=e.constructor.prototype;return t instanceof Number||e===Number?ie.Number:t instanceof P||"function"==typeof e.prototype.isFloat?ie.FloatNode:t instanceof g||e===g||e.isTexture?ie.Texture:t instanceof se||e===O?ie.Sampler2DNode:t instanceof Boolean||e===Boolean?ie.Boolean:t instanceof I?ie.BooleanNode:t instanceof a||e==a?ie.Color:t instanceof N||"function"==typeof e.prototype.isRgb?ie.RgbNode:t instanceof w||e==w?ie.Vector2:t instanceof B||"function"==typeof e.prototype.isVec2?ie.Vec2Node:t instanceof A||e==A?ie.Vector3:t instanceof C||"function"==typeof e.prototype.isVec3?ie.Vec3Node:t instanceof String||e===String?ie.String:t instanceof ae||e==ae||e.prototype instanceof ae||e.prototype==ae?ie.BaseActor:t instanceof s||e==s?ie.Euler:t instanceof m||e==m?ie.Object3D:t instanceof c||e==c?ie.Material:t instanceof AudioBuffer||e==AudioBuffer?ie.AudioBuffer:void console.warn("Failed to map parameter type to serialized version",{type:e})}export function prepareCustomParams(e,t,i={}){return Object.fromEntries(e.map((e=>{var r,a,s;return[e.name,{type:be(e.type),value:null!==(s=null!==(a=null===(r=t[e.name])||void 0===r?void 0:r.value)&&void 0!==a?a:i[e.name])&&void 0!==s?s:Ie.get(be(e.type))}]})))}export function prepareCustomParamsFromType(e,t,i=null){const r=$(e);if(0===r.length)return{};let a;null!=i?he(i,(()=>{a=i.get(e)})):a=new e;const s={};for(const e of r){const t=a[e.name];if(null!=t){const i=serializeCustomParameter(e.type,t);null!=i&&(s[e.name]=i)}}return prepareCustomParams(r,t,s)}export function serializeCustomParameter(e,t){function i(){console.error("Failed to serialize value",{type:e,value:t})}switch(e){case Number:case Boolean:return t;case w:return t instanceof w?t.toArray():void i();case A:return t instanceof A?t.toArray():void i();case S:return t instanceof S?t.toArray():void i();case a:return t instanceof a?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new a(t).getHexString():void i();case String:return t;case s:return t instanceof s?t.toArray():void i()}}function Me(e,t){return function(e,t,i){const r=[],a=new Set;for(const s of[...null!=e?e:[],...null!=t?t:[]]){const e=i(s);a.has(e)||(a.add(e),r.push(s))}return r}((null!=e?e:[]).filter((e=>xe(e.materialId))),(null!=t?t:[]).filter((e=>xe(e.materialId))),(e=>e.color))}function xe(e){return"null"!=e&&null!=e}const Ie=new Map([[ie.RgbNode,"#000000"],[ie.Color,"#000000"],[ie.Vector4,[0,0,0,0]],[ie.Vec4Node,[0,0,0,0]],[ie.Vector3,[0,0,0]],[ie.Vec3Node,[0,0,0]],[ie.Vector2,[0,0]],[ie.Vec2Node,[0,0]],[ie.Euler,[0,0,0,"XYZ"]]]);
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
package/dist/scene/model.d.ts
CHANGED
package/dist/scene/model.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
export var SerializedParamType;!function(e){e[e.FloatNode=0]="FloatNode",e[e.Number=1]="Number",e[e.Texture=2]="Texture",e[e.Sampler2DNode=3]="Sampler2DNode",e[e.Boolean=4]="Boolean",e[e.BooleanNode=5]="BooleanNode",e[e.Vector2=6]="Vector2",e[e.Vec2Node=7]="Vec2Node",e[e.Vector3=8]="Vector3",e[e.Vec3Node=9]="Vec3Node",e[e.Color=10]="Color",e[e.RgbNode=11]="RgbNode",e[e.String=12]="String",e[e.BaseActor=13]="BaseActor",e[e.Euler=14]="Euler",e[e.
|
1
|
+
export var SerializedParamType;!function(e){e[e.FloatNode=0]="FloatNode",e[e.Number=1]="Number",e[e.Texture=2]="Texture",e[e.Sampler2DNode=3]="Sampler2DNode",e[e.Boolean=4]="Boolean",e[e.BooleanNode=5]="BooleanNode",e[e.Vector2=6]="Vector2",e[e.Vec2Node=7]="Vec2Node",e[e.Vector3=8]="Vector3",e[e.Vec3Node=9]="Vec3Node",e[e.Color=10]="Color",e[e.RgbNode=11]="RgbNode",e[e.String=12]="String",e[e.BaseActor=13]="BaseActor",e[e.Euler=14]="Euler",e[e.Object3D=15]="Object3D",e[e.Material=16]="Material",e[e.AudioBuffer=17]="AudioBuffer",e[e.Vector4=18]="Vector4",e[e.Vec4Node=19]="Vec4Node"}(SerializedParamType||(SerializedParamType={}));
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import 'reflect-metadata';
|
2
2
|
import { Type } from '../utils/type';
|
3
3
|
import { BaseActor } from '../gameplay/actors/actor';
|
4
|
-
import { Color, Euler, Material,
|
4
|
+
import { Color, Euler, Material, Object3D, Texture, Vector2, Vector3, Vector4 } from 'three';
|
5
5
|
import { BooleanNode, FloatNode, RgbNode, Sampler2DNode, Vec2Node, Vec3Node, Vec4Node } from '../shader-nodes';
|
6
|
-
export type ParameterType = Type<FloatNode | Number | Texture | Sampler2DNode | Boolean | BooleanNode | Vector2 | Vec2Node | Vector3 | Vec3Node | Vector4 | Vec4Node | Color | RgbNode | String | BaseActor | Euler |
|
6
|
+
export type ParameterType = Type<FloatNode | Number | Texture | Sampler2DNode | Boolean | BooleanNode | Vector2 | Vec2Node | Vector3 | Vec3Node | Vector4 | Vec4Node | Color | RgbNode | String | BaseActor | Euler | Object3D | Material>;
|
7
7
|
export type ParameterOption<T> = {
|
8
8
|
name: string;
|
9
9
|
value: T;
|
package/package.json
CHANGED