@hology/core 0.0.23 → 0.0.25

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- import{__decorate as t,__metadata as s}from"tslib";import{EdgesGeometry as i,LineSegments as e,LineBasicMaterial as o,Vector3 as r,BoxGeometry as n,Mesh as c,MeshBasicMaterial as h,Group as p}from"three";import{Actor as a,BaseActor as d}from"../actor";import{Component as m,ActorComponent as y,Attach as l}from"../component";import{PhysicsSystem as v}from"../../services/physics/physics-system";import{BoxCollisionShape as g}from"../../../scene/collision/collision-shape";import{firstValueFrom as w}from"rxjs";let A=class extends y{constructor(){super(...arguments),this.dimensions=new r(1,1,1)}onInit(){const t=new n(this.dimensions.x,this.dimensions.y,this.dimensions.z),s=new i(t),r=new e(s,new o({color:16777215})),a=(new c(t,new h({color:16777215,transparent:!0,opacity:.3,visible:!1})),new p);a.add(r),this.actor.object.add(a)}};A=t([m({inEditor:!0,editorOnly:!0})],A);export{A as TriggerVolumeMesh};let O=class extends y{constructor(t){super(),this.physicsSystem=t,this.dimensions=new r(1,1,1)}onInit(){this.editorMesh=this.attach(A),console.log("add actor",this.actor),this.physicsSystem.addActor(this.actor,[new g(this.dimensions)],{isTrigger:!0}),w(this.disposed).then((()=>{this.physicsSystem.removeActor(this.actor)}))}onBeginOverlapWithActor(t){return this.physicsSystem.onBeginOverlapWithActor(this.actor,t)}onEndOverlapWithActor(t){return this.physicsSystem.onEndOverlapWithActor(this.actor,t)}onBeginOverlapWithActorType(t){return this.physicsSystem.onBeginOverlapWithActorType(this.actor,t)}onEndOverlapWithActorType(t){return this.physicsSystem.onEndOverlapWithActorType(this.actor,t)}};O=t([m({inEditor:!0,editorOnly:!1}),s("design:paramtypes",[v])],O);export{O as TriggerVolumeComponent};let u=class extends d{};t([l(),s("design:type",O)],u.prototype,"trigger",void 0),u=t([a()],u);export{u as TriggerVolume};
1
+ import{__decorate as t,__metadata as s}from"tslib";import{EdgesGeometry as i,LineSegments as e,LineBasicMaterial as o,Vector3 as r,BoxGeometry as n,Mesh as c,MeshBasicMaterial as h,Group as p}from"three";import{Actor as m,BaseActor as a}from"../actor";import{Component as d,ActorComponent as y,Attach as l}from"../component";import{PhysicsSystem as v}from"../../services/physics/physics-system";import{BoxCollisionShape as g}from"../../../scene/collision/collision-shape";import{firstValueFrom as w}from"rxjs";let A=class extends y{constructor(){super(...arguments),this.dimensions=new r(1,1,1)}onInit(){const t=new n(this.dimensions.x,this.dimensions.y,this.dimensions.z),s=new i(t),r=new e(s,new o({color:16777215})),m=(new c(t,new h({color:16777215,transparent:!0,opacity:.3,visible:!1})),new p);m.add(r),this.actor.object.add(m)}};A=t([d({inEditor:!0,editorOnly:!0})],A);export{A as TriggerVolumeMesh};let O=class extends y{constructor(t){super(),this.physicsSystem=t,this.dimensions=new r(1,1,1)}onInit(){this.editorMesh=this.attach(A),this.physicsSystem.addActor(this.actor,[new g(this.dimensions)],{isTrigger:!0}),w(this.disposed).then((()=>{this.physicsSystem.removeActor(this.actor)}))}onBeginOverlapWithActor(t){return this.physicsSystem.onBeginOverlapWithActor(this.actor,t)}onEndOverlapWithActor(t){return this.physicsSystem.onEndOverlapWithActor(this.actor,t)}onBeginOverlapWithActorType(t){return this.physicsSystem.onBeginOverlapWithActorType(this.actor,t)}onEndOverlapWithActorType(t){return this.physicsSystem.onEndOverlapWithActorType(this.actor,t)}};O=t([d({inEditor:!0,editorOnly:!1}),s("design:paramtypes",[v])],O);export{O as TriggerVolumeComponent};let u=class extends a{};t([l(),s("design:type",O)],u.prototype,"trigger",void 0),u=t([m()],u);export{u as TriggerVolume};
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -4,11 +4,10 @@ import { Observable, Subject } from "rxjs";
4
4
  import * as THREE from "three";
5
5
  import { ColorRepresentation, Object3D, Vector3 } from "three";
6
6
  import { CollisionShape } from "../../../";
7
- import { Type } from "../../../utils/type";
8
- import { BaseActor } from "../../actors/actor";
7
+ import { AbstractType } from "../../../utils/type";
8
+ import { BaseActor } from '../../actors/actor';
9
9
  import { ViewController } from "../render";
10
10
  import { World } from "../world";
11
- import { CollisionContact } from "./collision-contact";
12
11
  export declare class RayTestResult {
13
12
  _internal: RayColliderIntersection;
14
13
  actor: BaseActor;
@@ -109,25 +108,23 @@ export declare class PhysicsSystem {
109
108
  removeSceneObject(object: Object3D): void;
110
109
  private activateActorEvents;
111
110
  private _onCollisionWithActorEvent;
112
- onBeginOverlapWithActorType<T extends BaseActor, A extends BaseActor>(self: T, actorType: Type<A>): Observable<A>;
113
- onEndOverlapWithActorType<T extends BaseActor, A extends BaseActor>(self: T, actorType: Type<A>): Observable<A>;
111
+ /**
112
+ * Get a subscription to contact started events where the value of the subscription
113
+ * is some unique number identifying the object in which the actor is in contact.
114
+ */
115
+ onBeginContact(self: BaseActor): Observable<number>;
116
+ /**
117
+ * Get a subscription to contact ended events where the value of the subscription
118
+ * is some unique number identifying the object in which the actor is in contact.
119
+ */
120
+ onEndContact(self: BaseActor): Observable<number>;
121
+ onHasContactChanged(self: BaseActor): Observable<boolean>;
122
+ onBeginOverlapWithActorType<T extends BaseActor, A extends BaseActor>(self: T, actorType: AbstractType<A>): Observable<A>;
123
+ onEndOverlapWithActorType<T extends BaseActor, A extends BaseActor>(self: T, actorType: AbstractType<A>): Observable<A>;
114
124
  onBeginOverlapWithActor<T extends BaseActor, A extends BaseActor>(self: T, actor: A): Observable<A>;
115
125
  onEndOverlapWithActor<T extends BaseActor, A extends BaseActor>(self: T, actor: A): Observable<A>;
116
126
  onCollisionWithActor<A extends BaseActor, S extends BaseActor>(self: S, actor: A): Observable<A>;
117
- onCollisionWithActorType<A extends BaseActor, S extends BaseActor>(self: S, actorType: Type<A>): Observable<A>;
118
- /**
119
- * Whenever there is collision with anything in the world which is not a trigger volume?
120
- * I suppose I can filter out trigger bodies.
121
- * Only return collision contact information
122
- *
123
- * It should be possible to pass in a collision filter (mask) to be able to narrow down the search.
124
- * Collision groups should be defined in code as integers. I suppose I can also have predefined collision groups that are available both in the editor and here.
125
- *
126
- * You might want more information about the object you are colliding with.
127
- * If it is a static object, I could provide the raw threejs mesh object.
128
- * I could also provide scene object information.
129
- */
130
- onCollision<S extends BaseActor>(self: S): Observable<CollisionContact>;
127
+ onCollisionWithActorType<A extends BaseActor, S extends BaseActor>(self: S, actorType: AbstractType<A>): Observable<A>;
131
128
  updateActorTransform(actor: BaseActor): void;
132
129
  private setupWorld;
133
130
  getActorContacts(actor: BaseActor, direction: Vector3): {
@@ -1,4 +1,4 @@
1
- import{__awaiter as e,__decorate as t,__metadata as i}from"tslib";import*as o from"@dimforge/rapier3d-compat";import{QueryFilterFlags as s}from"@dimforge/rapier3d-compat";import{Quaternion as r,RaycastResult as n,Vec3 as l}from"cannon-es";import{filter as a,map as d,Observable as c,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 M,CapsuleCollisionShape as T,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.fixedupdateSub=this.viewController.onUpdate().subscribe((e=>{e=Math.min(.1,e),this.beforeStep.next(e),this.updatePhysics(e),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(e){this.world.timestep=e,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 d=new o.Ray(e,a),c=l.length(),h=this.world.castRayAndGetNormal(d,c,!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=d.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,c,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 d=t.landscape.options.density,c=l.flatMap((e=>e.reverse())),h=o.ColliderDesc.heightfield(d,d,new Float32Array(c),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)),d((({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))),d((({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 c((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,d=.3;const c=this.world.castShape(n,l,a,r,d,!0,null,null,null,this.actorBodies.get(e.id),(e=>e.shape.type!=o.ShapeType.HeightField));if(null!=c){const e=new C,t=new C,i=new C;return Y(e,c.witness2),Y(t,c.witness1),Y(i,c.normal1),i.negate(),[{ri:e,rj:t,ni:i}]}return[]}return console.warn("Actor is not added to the physics system"),[]}stop(){var e,t,i;null===(e=this.world)||void 0===e||e.bodies.forEach((e=>this.world.removeRigidBody(e))),null===(t=this.world)||void 0===t||t.free(),null===(i=this.fixedupdateSub)||void 0===i||i.unsubscribe()}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 M)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 T){return o.ColliderDesc.capsule(e.length/2*t.y,e.radius*Math.max(t.z,t.x))}if(e instanceof V){const t=null!=e.geometry.getIndex()?e.geometry:L.mergeVertices(e.geometry);return o.ColliderDesc.trimesh(new Float32Array(t.getAttribute("position").array),new Uint32Array(t.getIndex().array))}if(e instanceof S){let i;e.mesh instanceof y.Mesh?i=e.mesh.geometry:e.mesh instanceof y.BufferGeometry?i=e.mesh:console.log("Unknownd shape",{shapeInfo:e});const s=new Float32Array(i.getAttribute("position").array);if(e.mesh instanceof y.Mesh){const t=O(e.mesh);for(let e=0;e<s.length;e+=3)s[e]*=t.x,s[e+1]*=t.y,s[e+2]*=t.z}for(let e=0;e<s.length;e+=3)s[e]*=t.x,s[e+1]*=t.y,s[e+2]*=t.z;return o.ColliderDesc.convexHull(s)}return e instanceof F?o.ColliderDesc.ball(e.radius*Math.max(t.x,t.y,t.z)):e instanceof E?o.ColliderDesc.cylinder(e.height/2*t.y,e.radiusTop*Math.max(t.z,t.x)):e instanceof R?o.ColliderDesc.cone(e.height*t.y,e.radiusBottom/2*Math.max(t.z,t.x)):e instanceof _?o.ColliderDesc.cuboid(e.width/2*t.x,e.height/2*t.y,.01):(console.error("Unsupported shape",e),o.ColliderDesc.cuboid(1,1,1))}};j=t([D(),i("design:paramtypes",[k,I])],j);export{j as PhysicsSystem};const N=new C,q=new y.Quaternion;function G(e,t){const i=t.getWorldPosition(N),s=t.getWorldQuaternion(q);e.setTranslation(new o.Vector3(i.x,i.y,i.z),!1),e.setRotation(new o.Quaternion(s.x,s.y,s.z,s.w),!1)}const Q=new C,U=new o.Vector3(0,0,0),H=new o.Vector3(0,0,0),K=(new C,{x:0,y:0}),X=()=>e(void 0,void 0,void 0,(function*(){let e=yield import("@dimforge/rapier3d-compat");return yield e.init(),e}));function J(e,t){e.x=t.x,e.y=t.y,e.z=t.z}function Y(e,t){e.x=t.x,e.y=t.y,e.z=t.z}function Z(e,t){for(let i=0,o=e.numColliders();i<o;i++){t(e.collider(i))}}const $=new C,ee=new C,te=e=>!e.isSensor();
1
+ import{__awaiter as t,__decorate as e,__metadata as i}from"tslib";import*as s from"@dimforge/rapier3d-compat";import{QueryFilterFlags as o}from"@dimforge/rapier3d-compat";import{Quaternion as n,RaycastResult as r,Vec3 as a}from"cannon-es";import{BehaviorSubject as l,distinctUntilChanged as d,filter as c,map as h,Subject as u,takeUntil as y}from"rxjs";import*as p from"three";import{ArrowHelper as g,BufferAttribute as m,BufferGeometry as v,Group as f,LineSegments as w,Matrix4 as x,MeshBasicMaterial as b,Object3D as B,Raycaster as A,Scene as C,Vector3 as D}from"three";import{Service as z}from"typedi";import{AssetMeshInstance as T}from"../../../scene/asset-resource-loader";import{BoxCollisionShape as M,CapsuleCollisionShape as E,ConeCollisionShape as S,ConvexPolyhedronCollisionShape as R,CylinderCollisionShape as W,PhysicalShapeMesh as _,PlaneCollisionShape as V,SphereCollisionShape as F,TrimeshCollisionShape as P}from"../../../";import{LandscapeGroup as k}from"../../../scene/landscape/landscape";import{ViewController as I}from"../render";import{World as L}from"../world";import*as O from"three/examples/jsm/utils/BufferGeometryUtils.js";import{calculateEffectiveScale as N}from"../../../utils/three/traverse";export class RayTestResult{constructor(){this.hasHit=!1,this.hitPoint=new D,this.hitNormal=new D}}new r,new a,new a;export var PhysicsBodyType;!function(t){t[t.dynamic=1]="dynamic",t[t.static=2]="static",t[t.kinematic=4]="kinematic",t[t.kinematicVelocityBased=8]="kinematicVelocityBased"}(PhysicsBodyType||(PhysicsBodyType={}));let j=class{set showDebug(t){this.shouldRenderDebug=t,this.debugMesh&&(this.debugMesh.visible=t)}get showDebug(){return this.shouldRenderDebug}constructor(t,e){this.viewController=t,this.gameWorld=e,this.staticMeshes=new Map,this.staticBodies=new Map,this.actorBodies=new Map,this.bodyActors=new Map,this.collisionEvents=new u,this.beforeStep=new u,this.afterStep=new u,this.shouldRenderDebug=!1,this._raycaster=new A,this._reusableResult=new RayTestResult,this._raytestDiff=new D,this._raytestDirection=new D,this.controlledActors=new Set,this.ready=this.setup()}createDebugMesh(){return new w(new v,new b({color:255}))}start(){return t(this,void 0,void 0,(function*(){return yield this.ready,this.handleTick(),this.ready}))}renderDebug(){null==this.debugMesh&&(this.debugMesh=this.createDebugMesh(),this.debugMesh.visible=this.shouldRenderDebug,this.debugMesh.raycast=function(){},this.gameWorld.scene.add(this.debugMesh));const t=this.world.debugRender();this.debugMesh.geometry.setAttribute("position",new m(t.vertices,3))}setup(){return t(this,void 0,void 0,(function*(){if(null!=this.rapier)throw new Error("Rapier is already estup");this.rapier=yield J(),this.eventQueue=new s.EventQueue(!0),this.setupWorld()}))}handleTick(){this.fixedupdateSub=this.viewController.onUpdate().subscribe((t=>{t=Math.min(.1,t),this.beforeStep.next(t),this.updatePhysics(t),this.afterStep.next(t),this.showDebug&&this.renderDebug(),this.world.bodies.forEach((t=>{var e,i,s;if(t.isFixed())return;const o=null!==(e=this.staticMeshes.get(t))&&void 0!==e?e:null===(i=this.bodyActors.get(t))||void 0===i?void 0:i.object;var n,r;null!=o&&(o.parent instanceof C&&(Z(o.position,t.translation()),(t.isDynamic()||t.isKinematic()&&!this.controlledActors.has(null===(s=this.bodyActors.get(t))||void 0===s?void 0:s.id))&&(n=o.quaternion,r=t.rotation(),n.x=r.x,n.y=r.y,n.z=r.z,n.w=r.w)))}))}))}_updateWorld(){this.world.timestep=0,this.world.step()}updatePhysics(t){this.world.timestep=t,this.world.step(this.eventQueue),this.eventQueue.drainCollisionEvents(((t,e,i)=>{this.collisionEvents.next({handle1:t,handle2:e,started:i}),this.collisionEvents.next({handle1:e,handle2:t,started:i})}))}rayTestFromCamera(t,e,i){this._raycaster.setFromCamera(X,this.viewController.getCamera());const s=this._raycaster.ray.origin,o=this._raycaster.ray.direction.multiplyScalar(t).add(s);return this.rayTest(s,o,e,i)}rayTest(t,e,i,o){var n,r;null==i&&(i=this._reusableResult);const a=this._raytestDiff,l=this._raytestDirection;if(a.subVectors(e,t),l.copy(a).normalize(),0===l.length())return console.warn("Ray test called with to and from being equal"),i;const d=new s.Ray(t,l),c=a.length(),h=this.world.castRayAndGetNormal(d,c,!1,void 0,void 0,void 0,null!=(null==o?void 0:o.excludeActor)?this.actorBodies.get(o.excludeActor.id):void 0);if(i.hasHit=null!=h,i.hasHit){const e=d.pointAt(h.toi);i._internal=h,Z(i.hitNormal,h.normal),Z(i.hitPoint,e),i.distance=tt.subVectors(i.hitPoint,t).length();const s=this.world.bodies.getAll().find((t=>function(t,e){for(let i=0,s=t.numColliders();i<s;i++){const s=t.collider(i);if(e(s))return s}}(t,(t=>t===h.collider))));i.actor=null!=s?this.bodyActors.get(s):null}if(this.showDebug){const e=new g(l,t,c,null!==(n=null==o?void 0:o.debugColor)&&void 0!==n?n:255);this.gameWorld.scene.add(e),setTimeout((()=>this.gameWorld.scene.remove(e)),null!==(r=null==o?void 0:o.debugLifetime)&&void 0!==r?r:200)}return this._reusableResult}setGravity(t,e,i){this.world.gravity.x=t,this.world.gravity.y=e,this.world.gravity.z=i}getGravity(){return H.set(this.world.gravity.x,this.world.gravity.y,this.world.gravity.z)}addFromScene(t){this.addRecursively(t);for(const t of this.staticBodies.values())$(t,(t=>t.setActiveEvents(s.ActiveEvents.COLLISION_EVENTS)))}addRecursively(t){var e,i;if(this.removeSceneObject(t),!function(t){var e,i;if(null!=(null===(e=t.userData)||void 0===e?void 0:e.src)){return"actor"===(null===(i=t.userData)||void 0===i?void 0:i.src).type}return!1}(t))if(t instanceof _&&null!=t.collisionShape){const e=this.createStaticBody(t,[t.collisionShape]);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else if(t instanceof T&&!1!==(null===(i=null===(e=t.userData)||void 0===e?void 0:e.src)||void 0===i?void 0:i.collisionDetection))if(t.children[0]&&t.children[0].instanceMatrix)this.createForInstancedMesh(t.children[0],t.collisionShapes);else{const e=this.createStaticBody(t,t.collisionShapes);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else t instanceof k?this.addLandscapeGroup(t):(t instanceof f||t instanceof C)&&t.children.forEach((t=>this.addRecursively(t)))}createForInstancedMesh(t,e){const i=new x;for(let s=0;s<t.count;s++){const o=new B;o.matrix.identity(),i.fromArray(t.instanceMatrix.array,16*s),o.applyMatrix4(i);this.createStaticBody(o,e)}}getCharacterController(t=.01){var e;return null===(e=this.world)||void 0===e?void 0:e.createCharacterController(t)}getActorComputedMovement(t,e,i){const s=this.actorBodies.get(t.id);this.controlledActors.add(t.id);const n=s.collider(0);e.computeColliderMovement(n,i,o.EXCLUDE_SENSORS,null,it);const r=e.computedMovement();return Z(et,r),et}setNextKinematicTranslation(t,e){const i=this.actorBodies.get(t.id),s=i.translation();s.x+=e.x,s.y+=e.y,s.z+=e.z,null==i||i.setNextKinematicTranslation(s)}setAngularVelocity(t,e){const i=this.actorBodies.get(t.id);U.x=e.x,U.y=e.y,U.z=e.z,null==i||i.setAngvel(U,!0)}setLinearVelocity(t,e){const i=this.actorBodies.get(t.id);U.x=e.x,U.y=e.y,U.z=e.z,null==i||i.setLinvel(U,!0)}getLinearVelocity(t,e=new D){const i=this.actorBodies.get(t.id).linvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}getAngularVelocity(t,e=new D){const i=this.actorBodies.get(t.id).angvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}setLinearDamping(t,e){const i=this.actorBodies.get(t.id);null==i||i.setLinearDamping(e)}setAngularDamping(t,e){const i=this.actorBodies.get(t.id);null==i||i.setAngularDamping(e)}createCharacterCollision(){return new s.CharacterCollision}addLandscapeGroup(t){const e=t.userData.src,i=e.landscape.heightMaps;for(const n of t.sections){this.staticBodies.has(n)&&this.world.removeRigidBody(this.staticBodies.get(n));const t=e.landscape.options.density+1,r=e.landscape.options.sectionSize,a=new Array(t);for(let e=0;e<t;e++)a[e]=new Array(t).fill(0);const l=i.find((t=>t.x===n.x&&t.y==n.y));if(null!=l)for(const e of l.points){if(null==a[e.i%t])continue;const i=t-1-Math.floor(e.i/t);i in a[e.i%t]?a[e.i%t][i]=e.y/r:console.warn("wrong index",{points:a,point:e,i:e.i%t,k:i,heightMap:l})}const d=e.landscape.options.density,c=a.flatMap((t=>t.reverse())),h=s.ColliderDesc.heightfield(d,d,new Float32Array(c),new s.Vector3(r,r,r));var o=n.getWorldPosition(new D);const u=this.world.createRigidBody(s.RigidBodyDesc.fixed()),y=new s.Vector3(0,0,0);Y(y,o),u.setTranslation(y,!1),this.world.createCollider(h,u),this.staticBodies.set(n,u)}}addActor(t,e,i={}){var o,n;if(0==e.length)return void console.error("No collision shapes were defined when adding actor to the physics system.");this.removeActor(t);const r=t.object;let a;switch(null!==(o=i.type)&&void 0!==o?o:PhysicsBodyType.static){case PhysicsBodyType.dynamic:a=s.RigidBodyDesc.dynamic(),a.mass=null!==(n=i.mass)&&void 0!==n?n:1;break;case PhysicsBodyType.kinematic:a=s.RigidBodyDesc.kinematicPositionBased();break;case PhysicsBodyType.kinematicVelocityBased:a=s.RigidBodyDesc.kinematicVelocityBased();break;default:a=(i.isTrigger,s.RigidBodyDesc.kinematicVelocityBased())}const l=this.world.createRigidBody(a);l.enableCcd(1==i.continousCollisionDetection);for(const t of e)this.addShape(l,t,r);$(l,(t=>{null!=i.isTrigger&&(t.setSensor(i.isTrigger),t.setActiveCollisionTypes(s.ActiveCollisionTypes.ALL),t.setActiveEvents(s.ActiveEvents.COLLISION_EVENTS)),null!=i.friction&&t.setFriction(i.friction),null!=i.restitution&&t.setDensity(i.restitution),null!=i.mass&&t.setMass(i.mass),null!=i.restitution&&t.setRestitution(i.restitution)})),Q(l,r),this.actorBodies.set(t.id,l),this.bodyActors.set(l,t)}applyTorque(t,e){const i=this.actorBodies.get(t.id);U.x=e.x,U.y=e.y,U.z=e.z,null==i||i.addTorque(U,!0)}applyTorqueImpulse(t,e){const i=this.actorBodies.get(t.id);U.x=e.x,U.y=e.y,U.z=e.z,null==i||i.applyTorqueImpulse(U,!0)}resetForces(t){const e=this.actorBodies.get(t.id);null==e||e.resetForces(!1)}resetTorques(t){const e=this.actorBodies.get(t.id);null==e||e.resetTorques(!1)}applyForce(t,e){const i=this.actorBodies.get(t.id);U.x=e.x,U.y=e.y,U.z=e.z,null==i||i.addForce(U,!0)}applyImpulse(t,e){const i=this.actorBodies.get(t.id);U.x=e.x,U.y=e.y,U.z=e.z,null==i||i.applyImpulse(U,!0)}applyLocalForce(t,e,i){const s=this.actorBodies.get(t.id);Y(U,e),null==i?null==s||s.addForce(U,!0):(Y(K,i),null==s||s.addForceAtPoint(U,K,!0))}applyLocalImpulse(t,e,i){const s=this.actorBodies.get(t.id);Y(U,e),null==i?s.applyImpulse(U,!0):(Y(K,i),s.applyImpulseAtPoint(U,K,!0))}removeActor(t){this.controlledActors.delete(t.id);const e=this.actorBodies.get(t.id);null!=e&&(this.bodyActors.delete(e),this.world.removeRigidBody(e)),this.actorBodies.delete(t.id)}removeSceneObject(t){let e=this.staticBodies.get(t);null!=e&&this.world.getRigidBody(e.handle)&&this.world.removeRigidBody(e)}activateActorEvents(t){this.actorBodies.get(t.id)}_onCollisionWithActorEvent(t,e,i){return this.activateActorEvents(t),this.collisionEvents.pipe(y(t.disposed),c((({started:t})=>t===i)),h((({handle1:t,handle2:e,started:i})=>({a1:this.bodyActors.get(this.world.getCollider(t).parent()),a2:this.bodyActors.get(this.world.getCollider(e).parent()),started:i}))),c((({a1:i,a2:s})=>null!=i&&null!=s&&i.id===t.id&&e(i,s))),h((({a2:t})=>t)))}onBeginContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(y(t.disposed),c((t=>t.started)),c((({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e).parent());return null!=i&&i.id===t.id})),h((t=>t.handle2)))}onEndContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(y(t.disposed),c((t=>!t.started)),c((({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e).parent());return null!=i&&i.id===t.id})),h((t=>t.handle2)))}onHasContactChanged(t){const e=new Set,i=new l(!1);return this.onBeginContact(t).subscribe((t=>{e.add(t),i.next(e.size>0)})),this.onEndContact(t).subscribe((t=>{e.delete(t),i.next(e.size>0)})),i.pipe(d())}onBeginOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>i instanceof e),!0)}onEndOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>i instanceof e),!1)}onBeginOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>e.id===i.id),!0)}onEndOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>e.id===i.id),!1)}onCollisionWithActor(t,e){return this.onBeginOverlapWithActor(t,e)}onCollisionWithActorType(t,e){return this.onBeginOverlapWithActorType(t,e)}updateActorTransform(t){const e=this.actorBodies.get(t.id);null!=e?Q(e,t.object):console.warn("Actor has not been added to physics world",t)}setupWorld(){const t=new s.World({x:0,y:-9.81,z:0});this.world=t,t.maxVelocityIterations=4}getActorContacts(t,e){const i=this.actorBodies.get(t.id);if(i&&i.numColliders()>0){const o=i.collider(0);let n=o.shape,r=o.translation(),a=o.rotation(),l=e,d=.3;const c=this.world.castShape(r,a,l,n,d,!0,null,null,null,this.actorBodies.get(t.id),(t=>t.shape.type!=s.ShapeType.HeightField));if(null!=c){const t=new D,e=new D,i=new D;return Z(t,c.witness2),Z(e,c.witness1),Z(i,c.normal1),i.negate(),[{ri:t,rj:e,ni:i}]}return[]}return console.warn("Actor is not added to the physics system"),[]}stop(){var t,e,i;null===(t=this.world)||void 0===t||t.bodies.forEach((t=>this.world.removeRigidBody(t))),null===(e=this.world)||void 0===e||e.free(),null===(i=this.fixedupdateSub)||void 0===i||i.unsubscribe()}createStaticBody(t,e){const i=this.world.createRigidBody(s.RigidBodyDesc.kinematicPositionBased());for(const s of e)this.addShape(i,s,t);return Q(i,t),i}addShape(t,e,i){const s=this.createShape(e,i.scale);s.friction=.1;const o=e.offset.clone().multiply(i.scale);var r,a;Y(s.translation,o),r=s.rotation,a=(new n).setFromEuler(e.rotation.x,e.rotation.y,e.rotation.z),r.x=a.x,r.y=a.y,r.z=a.z,r.w=a.w;this.world.createCollider(s,t)}createShape(t,e){if(t instanceof M)return s.ColliderDesc.cuboid(t.dimensions.x*e.x/2,t.dimensions.y*e.y/2,t.dimensions.z*e.z/2);if(t instanceof E){return s.ColliderDesc.capsule(t.length/2*e.y,t.radius*Math.max(e.z,e.x))}if(t instanceof P){const e=null!=t.geometry.getIndex()?t.geometry:O.mergeVertices(t.geometry);return s.ColliderDesc.trimesh(new Float32Array(e.getAttribute("position").array),new Uint32Array(e.getIndex().array))}if(t instanceof R){let i;t.mesh instanceof p.Mesh?i=t.mesh.geometry:t.mesh instanceof p.BufferGeometry?i=t.mesh:console.log("Unknownd shape",{shapeInfo:t});const o=new Float32Array(i.getAttribute("position").array);if(t.mesh instanceof p.Mesh){const e=N(t.mesh);for(let t=0;t<o.length;t+=3)o[t]*=e.x,o[t+1]*=e.y,o[t+2]*=e.z}for(let t=0;t<o.length;t+=3)o[t]*=e.x,o[t+1]*=e.y,o[t+2]*=e.z;return s.ColliderDesc.convexHull(o)}return t instanceof F?s.ColliderDesc.ball(t.radius*Math.max(e.x,e.y,e.z)):t instanceof W?s.ColliderDesc.cylinder(t.height/2*e.y,t.radiusTop*Math.max(e.z,e.x)):t instanceof S?s.ColliderDesc.cone(t.height*e.y,t.radiusBottom/2*Math.max(e.z,e.x)):t instanceof V?s.ColliderDesc.cuboid(t.width/2*e.x,t.height/2*e.y,.01):(console.error("Unsupported shape",t),s.ColliderDesc.cuboid(1,1,1))}};j=e([z(),i("design:paramtypes",[I,L])],j);export{j as PhysicsSystem};const q=new D,G=new p.Quaternion;function Q(t,e){const i=e.getWorldPosition(q),o=e.getWorldQuaternion(G);t.setTranslation(new s.Vector3(i.x,i.y,i.z),!1),t.setRotation(new s.Quaternion(o.x,o.y,o.z,o.w),!1)}const H=new D,U=new s.Vector3(0,0,0),K=new s.Vector3(0,0,0),X=(new D,{x:0,y:0}),J=()=>t(void 0,void 0,void 0,(function*(){let t=yield import("@dimforge/rapier3d-compat");return yield t.init(),t}));function Y(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function Z(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function $(t,e){for(let i=0,s=t.numColliders();i<s;i++){e(t.collider(i))}}const tt=new D,et=new D,it=t=>!t.isSensor();
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -1,4 +1,4 @@
1
- import { Group, Texture } from 'three';
1
+ import { Object3D, Texture } from 'three';
2
2
  import { Asset } from './model';
3
3
  import { CollisionShape } from './collision/collision-shape';
4
4
  export declare class AssetResourceLoader {
@@ -28,7 +28,7 @@ export declare class AssetResourceLoader {
28
28
  export interface LoadedMesh {
29
29
  scene: AssetMeshInstance;
30
30
  }
31
- export declare class AssetMeshInstance extends Group {
31
+ export declare class AssetMeshInstance extends Object3D {
32
32
  collisionShapes?: CollisionShape[];
33
33
  }
34
34
  export declare function getElectronArg(name: string): string;
@@ -1,4 +1,4 @@
1
- import{__awaiter as e}from"tslib";import{AudioLoader as t,Group as i,LoadingManager as s,Mesh as o,TextureLoader as r}from"three";import{GLTFLoader as n,MTLLoader as a,OBJLoader as h}from"three-stdlib";import{FBXLoader as l}from"three-stdlib";import{cloneMesh as c}from"../utils/mesh";import{pathJoin as d}from"../utils/files";import{Subject as u,firstValueFrom as f}from"rxjs";import{importCollisionShapes as p}from"./collision/collision-shape-import";import*as g from"three";import{iterateMaterials as m}from"../utils/materials";const y=["glb","gltf","fbx","obj"];export class AssetResourceLoader{onError(e){console.error(e)}constructor(){this.cache=new Map,this.textureCache=new Map,this.loadingManager=new s,this.glbLoader=new n(this.loadingManager),this.fbxLoader=new l(this.loadingManager),this.objLoader=new h(this.loadingManager),this.textureLoader=new r(this.loadingManager),this.audioLoader=new t(this.loadingManager),this.makeReady=new u,this.ready=f(this.makeReady),this.collisionShapeCache=new Map}setDataDir(e){this.basePath=d(e,"asset-resources"),this.makeReady.next(!0)}getUri(e){return d(this.basePath,e)+`?windowId=${getElectronArg("windowId")}`}getTexture(t){return e(this,void 0,void 0,(function*(){return null==t?null:(yield this.ready,this.cache.has(t.id)||(yield this.textureLoader.loadAsync(this.getUri(t.fileKey)).then((e=>(e.wrapS=g.RepeatWrapping,e.wrapT=g.RepeatWrapping,e.flipY=!1,this.textureCache.set(t.id,e),e)))),this.textureCache.get(t.id))}))}getMesh(t){var s;return e(this,void 0,void 0,(function*(){if(yield this.ready,!y.includes(null===(s=t.fileFormat)||void 0===s?void 0:s.toLowerCase()))return console.error("Unsupported mesh file format "+t.fileFormat,t),{scene:new i};if(!this.cache.has(t.fileKey))try{yield this.loadMesh(t)}catch(e){return this.onError(e),{scene:new i}}const{scene:e}=this.cache.get(t.fileKey),o=this.computeCollisionShapes(t,e),r=(new AssetMeshInstance).copy(c(e));return r.collisionShapes=o,{scene:r}}))}getAudio(t){return e(this,void 0,void 0,(function*(){return yield this.ready,this.audioLoader.loadAsync(this.getUri(t.fileKey))}))}computeCollisionShapes(e,t){return this.collisionShapeCache.get(e.id)||this.collisionShapeCache.set(e.id,p(t)),this.collisionShapeCache.get(e.id)}loadMesh(t){return e(this,void 0,void 0,(function*(){return yield this.ready,yield this.loadByAsset(t).then((e=>(e.scene.animations=[],this.cache.set(t.fileKey,e),e)))}))}loadByAsset(t){return e(this,void 0,void 0,(function*(){const e=this.getUri(t.fileKey);switch(t.fileFormat){case"glb":case"gltf":return this.glbLoader.loadAsync(e).then((e=>({scene:e.scene})));case"fbx":return this.fbxLoader.loadAsync(e).then((e=>({scene:e})));case"obj":if(null!=t.materialLib){const e=new a;e.materialOptions={normalizeRGB:!1};const i=yield e.loadAsync(this.getUri(t.materialLib));this.objLoader.setMaterials(i)}return this.objLoader.loadAsync(e).then((e=>(w(e),e))).then((e=>({scene:e})))}}))}}function w(e){var t;if(e instanceof o)for(const t of m(e.material))t instanceof g.MeshPhongMaterial&&!t.color.isLinear&&(t.color.isLinear=!0,t.color.convertSRGBToLinear());null===(t=e.children)||void 0===t||t.forEach(w)}export class AssetMeshInstance extends i{}export function getElectronArg(e){var t;const i=`--${e}=`,s=null===(t=window.process)||void 0===t?void 0:t.argv.find((e=>e.startsWith(i)));return null==s?void 0:s.substring(i.length)}
1
+ import{__awaiter as e}from"tslib";import{AudioLoader as t,Group as i,LoadingManager as s,Mesh as r,Object3D as o,TextureLoader as n}from"three";import{GLTFLoader as a,MTLLoader as l,OBJLoader as h}from"three-stdlib";import{FBXLoader as c}from"three-stdlib";import{cloneMesh as d}from"../utils/mesh";import{pathJoin as u}from"../utils/files";import{Subject as f,firstValueFrom as p}from"rxjs";import{importCollisionShapes as m}from"./collision/collision-shape-import";import*as g from"three";import{iterateMaterials as y}from"../utils/materials";const v=["glb","gltf","fbx","obj"];export class AssetResourceLoader{onError(e){console.error(e)}constructor(){this.cache=new Map,this.textureCache=new Map,this.loadingManager=new s,this.glbLoader=new a(this.loadingManager),this.fbxLoader=new c(this.loadingManager),this.objLoader=new h(this.loadingManager),this.textureLoader=new n(this.loadingManager),this.audioLoader=new t(this.loadingManager),this.makeReady=new f,this.ready=p(this.makeReady),this.collisionShapeCache=new Map}setDataDir(e){this.basePath=u(e,"asset-resources"),this.makeReady.next(!0)}getUri(e){return u(this.basePath,e)+`?windowId=${getElectronArg("windowId")}`}getTexture(t){return e(this,void 0,void 0,(function*(){return null==t?null:(yield this.ready,this.cache.has(t.id)||(yield this.textureLoader.loadAsync(this.getUri(t.fileKey)).then((e=>{var i,s;return e.wrapS=g.RepeatWrapping,e.wrapT=g.RepeatWrapping,e.flipY=null===(s=null===(i=t.texture)||void 0===i?void 0:i.flipY)||void 0===s||s,this.textureCache.set(t.id,e),e}))),this.textureCache.get(t.id))}))}getMesh(t){var s;return e(this,void 0,void 0,(function*(){if(yield this.ready,!v.includes(null===(s=t.fileFormat)||void 0===s?void 0:s.toLowerCase()))return console.error("Unsupported mesh file format "+t.fileFormat,t),{scene:new i};if(!this.cache.has(t.fileKey))try{this.cache.set(t.fileKey,yield this.loadMesh(t))}catch(e){return this.onError(e),{scene:new i}}const e=d(this.cache.get(t.fileKey).scene);e.traverse((e=>{e instanceof r&&e.material instanceof Array&&(e.material=e.material.slice())}));const o=this.computeCollisionShapes(t,e),n=(new AssetMeshInstance).copy(e);return n.collisionShapes=o,{scene:n}}))}getAudio(t){return e(this,void 0,void 0,(function*(){return yield this.ready,this.audioLoader.loadAsync(this.getUri(t.fileKey))}))}computeCollisionShapes(e,t){return this.collisionShapeCache.get(e.id)||this.collisionShapeCache.set(e.id,m(t)),this.collisionShapeCache.get(e.id)}loadMesh(t){return e(this,void 0,void 0,(function*(){return yield this.ready,yield this.loadByAsset(t).then((e=>(e.scene.animations=[],e.scene=function(e,t){let i=!1;if(t.traverseVisible((e=>{L.test(e.name)&&(i=!0)})),!i)return t;const s=new g.LOD,r=[t];for(;r.length>0;){const e=r.shift(),t=e.name.match(e.name);if(null!=t){const i=parseInt(t[1]);0===i?s.addLevel(e,0):console.warn(`Skipping LOD level ${i} for now as LOD is not fully supported`)}else r.push(...e.children)}return s}(0,e.scene),e)))}))}loadByAsset(t){return e(this,void 0,void 0,(function*(){const e=this.getUri(t.fileKey);switch(t.fileFormat){case"glb":case"gltf":return this.glbLoader.loadAsync(e).then((e=>({scene:e.scene})));case"fbx":return this.fbxLoader.loadAsync(e).then((e=>({scene:e})));case"obj":if(null!=t.materialLib){const e=new l;e.materialOptions={normalizeRGB:!1};const i=yield e.loadAsync(this.getUri(t.materialLib));this.objLoader.setMaterials(i)}return this.objLoader.loadAsync(e).then((e=>(w(e),e))).then((e=>({scene:e})))}}))}}function w(e){var t;if(e instanceof r)for(const t of y(e.material))t instanceof g.MeshPhongMaterial&&!t.color.isLinear&&(t.color.isLinear=!0,t.color.convertSRGBToLinear());null===(t=e.children)||void 0===t||t.forEach(w)}export class AssetMeshInstance extends o{}export function getElectronArg(e){var t;const i=`--${e}=`,s=null===(t=window.process)||void 0===t?void 0:t.argv.find((e=>e.startsWith(i)));return null==s?void 0:s.substring(i.length)}const L=/_LOD(\d+)$/;
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -1,4 +1,4 @@
1
- import{__awaiter as e}from"tslib";import{materialFromAsset as t}from"../../scene/materializer";import{Mesh as s,PlaneGeometry as o,Vector3 as n,InstancedMesh as i,Matrix4 as a,MeshLambertMaterial as r,Color as c,Vector2 as l,Triangle as h,Box3 as u,MathUtils as d,MeshStandardMaterial as f,ShaderMaterial as m,DoubleSide as p,PerspectiveCamera as w}from"three";import{indexBy as y}from"../../utils/collections";import{smoothNormalsCrossMeshes as v}from"./utils";import*as M from"three";import{defaultLandscapeMaterial as g,LandscapeMesh as x}from"./landscape";import{meanVectors3withWeight as S,clamp as b}from"../../utils/math";import{whenIdle as A}from"../../utils/async";import{Subject as P,debounceTime as z}from"rxjs";new n,new n;const L=new n,B=new n,G=new n;export class LandscapeManager{constructor(e,t,s,o,i,r,c){this.source=e,this.view=t,this.landscape=s,this.assetManagerService=o,this.assetService=i,this.shaders=r,this.applyMaterial=c,this.scatterMeshes=new Map,this.loadedScatterSquares=new Set,this.refreshRequests=new P,this.defaultLandscapeMaterial=g.clone(),this.onLoopHandler=()=>this.update(),this.sectionCache=new Map,this._matrix=new a,this.scatterGeometryCache=new Map,this._lastUpdatePosition=new n,this._cameraPosition=new n,this.view.onLoop(this.onLoopHandler),this.defaultLandscapeMaterial.color=g.color,this.refreshRequests.pipe(z(500)).subscribe((e=>this.refreshScatter(e.origin,e.force,e.predicate)))}updateShaders(e){this.shaders=e}loadGrass(){return e(this,void 0,void 0,(function*(){const e=yield this.assetService.getAsset("6ij937n72g");yield this.assetManagerService.getMesh(e);this.grassGeometry=new o(2,2,3,3);const t=this.grassGeometry.getAttribute("normal");for(let e=0;e<t.count;e++)t.setXYZ(e,0,1,0);t.needsUpdate=!0,this.grassMaterial=new f({color:3765785})}))}refreshGeometry(){const e=this.source.landscape.options,t=(new n,new n);this.view.camera.getWorldPosition(t);const s=[];G.fromArray(this.source.position);const o=this.view.camera instanceof w?Math.min(this.view.camera.far,1e3):1e3,i=1.1*o,a=e.sections.y*e.sectionSize/-2,r=e.sections.x*e.sectionSize/-2;for(let n=0;n<e.sections.x;n++)if(L.x=r+n*e.sectionSize,!(Math.abs(t.x-L.x)>i))for(let c=0;c<e.sections.y;c++){L.z=a+c*e.sectionSize,B.copy(G).add(L);const l=B.distanceTo(t),h=`${n},${c}`,u=this.landscape.sections.find((e=>e.x===n&&e.y===c));if(l<=o){if(null==u){this.sectionCache.has(h)||this.sectionCache.set(h,this.createLandscapeMesh(this.source,e,r,a,n,c));const t=this.sectionCache.get(h);this.applyMaterial(t),this.landscape.add(t),s.push(t)}}else l>i&&this.landscape.remove(u)}v(s)}applyHeightMap(e,t,s,o=1){var n,i,a,r;const c=Math.pow(s+1,2),l=e.getAttribute("position"),h=y(null!==(n=t.points)&&void 0!==n?n:[],(e=>e.i));if(1===o)for(const e of t.points)l.setY(e.i,e.y);else for(let e=0;e<l.count;e++){const t=$(e,l.count,c);let s=0;s=t%1==0?null!==(a=null===(i=h.get(t))||void 0===i?void 0:i.y)&&void 0!==a?a:0:Math.floor(null===(r=h.get(t))||void 0===r?void 0:r.y),l.setY(e,s)}l.needsUpdate=!0,e.computeVertexNormals()}deleteOldScatterMeshes(){var e,t;const s=new Set;for(const[o,n]of null!==(t=null===(e=this.source.grass)||void 0===e?void 0:e.layers.entries())&&void 0!==t?t:[])for(const[e,t]of n.meshes.entries()){const t=`${o}-${e}`;s.add(t)}for(const e of this.scatterMeshes.keys())if(!s.has(e)){this.scatterMeshes.get(e).forEach((e=>{var t;null===(t=e.parent)||void 0===t||t.remove(e),e.dispose()})),this.scatterMeshes.delete(e)}}queueRefreshScatter(e,t=!1,s=(()=>!0)){this.refreshRequests.next({origin:e,force:t,predicate:s})}refreshScatter(a,l=!1,u=(()=>!0)){var f,w,v,g;return e(this,void 0,void 0,(function*(){l&&this.scatterGeometryCache.clear(),this.deleteOldScatterMeshes();for(const[x,P]of null!==(w=null===(f=this.source.grass)||void 0===f?void 0:f.layers.entries())&&void 0!==w?w:[])for(const[f,w]of P.meshes.entries()){const P=`${x}-${f}`;this.scatterMeshes.has(P)||this.scatterMeshes.set(P,new Map);const z=this.scatterMeshes.get(P),L=yield this.assetService.getAsset(w.assetId),B=yield this.assetManagerService.getMesh(L),G=[];if(B.scene.traverse((e=>{e instanceof s&&G.push(e)})),1!==G.length){console.log(B),console.warn("Dynamic grass only works for meshes with a single geometry.");continue}if(!(G[0]instanceof s)){console.warn("Only meshes can be used for dynamic grass. Found:",B.scene);continue}const $=G[0];let _=$.geometry;this.scatterGeometryCache.has($.geometry.uuid)?_=this.scatterGeometryCache.get($.geometry.uuid):(_=$.geometry.clone(),!0===w.normalsUp&&E(_),this.scatterGeometryCache.set($.geometry.uuid,_),null==_.userData.updatedMatrix&&(B.scene.updateMatrixWorld(),_.applyMatrix4($.matrixWorld),_.userData.updatedMatrix=!0));const U=_.getIndex().count/3;if(U>400){console.warn(`The triangle count of ${L.name} is too big ${U}. Keep it below 400`);continue}const D=null!=L.materialAssignments&&L.materialAssignments.length>0?L.materialAssignments[0].materialId:null,I=null!=D&&"null"!==D?yield t(yield this.assetService.getAsset(D),null,this.assetService,this.assetManagerService,this.shaders,!1):null;let O=null!=I?I:$.material;O instanceof m&&(O.side=p);const Y=d.degToRad(null!==(v=w.maxSlope)&&void 0!==v?v:90),X=Math.cos(Y),F=this.landscape.sections,N=F.filter(k(a,w.viewDistance)).filter((e=>!z.has(e.uuid)||l)).filter((e=>u(e)));F.filter(C(a,2*w.viewDistance)).forEach((e=>{var t;const s=z.get(e.uuid);null===(t=null==s?void 0:s.parent)||void 0===t||t.remove(s),z.delete(e.uuid)}));performance.now();const Z=this.source.landscape.options,K=Z.sectionSize,V=null!==(g=w.density)&&void 0!==g?g:1,J=null!=V?V:1,Q=Z.density,ee=K/Q,te=J,se=ee/Math.sqrt(te),oe=Math.pow(Q,2),ne=se/ee,ie=Math.floor(oe*te),ae=[0,0,0];for(const t of N)yield A((()=>e(this,void 0,void 0,(function*(){var e,s,a,u,d,f,m;t.updateWorldMatrix(!0,!1);const p=this._matrix,v=new n,g=t.geometry.getAttribute("position"),A=t.geometry.getAttribute("normal"),P=(null!==(e=this.source.vertexMaterials)&&void 0!==e?e:[]).filter((e=>e.m===t.name)),L=y(P,(e=>e.i));let B=z.get(t.uuid);if(null==B||B.count==ie&&!l||(null===(s=B.parent)||void 0===s||s.remove(B),z.delete(t.uuid),B=null),null==B){const e=new o(.15,.75).getAttribute("normal");for(let t=0;t<e.count;t++);new r({color:new c(3765785),side:M.DoubleSide});B=new i(_,O,ie),B.raycast=()=>{},B.receiveShadow=!0}const G=new h(new n,new n,new n);let[$,C,k,U]=[new n,new n,new n,new n],[D,I,Y]=[[],[],[]],[E,F,N]=[new n,new n,new n,new n];const Z=new n,K=new n,V=new n,J=new n,ee=new h(new n,new n,new n),re=new h(new n,new n,new n),ce=new h(new n,new n,new n),le=new h(new n,new n,new n);let he=0;e:for(let e=0;e<oe;e++){const s=Math.floor(e/Q);$.fromBufferAttribute(g,e+s),J.copy($).applyMatrix4(t.matrixWorld),ee.a.copy($),ee.b.fromBufferAttribute(g,e+1+s),ee.c.fromBufferAttribute(g,e+Q+1+s),re.a.copy(ee.b),re.b.copy(ee.c),re.c.fromBufferAttribute(g,e+Q+2+s),ce.a.fromBufferAttribute(A,e+s),ce.b.fromBufferAttribute(A,e+1+s),ce.c.fromBufferAttribute(A,e+Q+1+s),le.a.copy(ce.b),le.b.copy(ce.c),le.c.fromBufferAttribute(A,e+Q+2+s);const o=[];o[0]=null===(a=L.get(e+s))||void 0===a?void 0:a.w,o[1]=null===(u=L.get(e+1+s))||void 0===u?void 0:u.w,o[2]=null===(d=L.get(e+Q+1+s))||void 0===d?void 0:d.w,o[3]=null===(f=L.get(e+Q+2+s))||void 0===f?void 0:f.w;let n=0;for(let e=0;e<1;e+=ne)for(let s=0;s<1;s+=ne){if(he>ie)break e;if(n++,n>te)continue e;1-e>s?(C=ee.a,k=ee.b,U=ee.c,E=ce.a,F=ce.b,N=ce.c,D=o[0],I=o[1],Y=o[2]):(C=re.a,k=re.b,U=re.c,E=le.a,F=le.b,N=le.c,D=o[1],I=o[2],Y=o[3]),G.a.copy(C),G.b.copy(k),G.c.copy(U),q(G),Z.set($.x,0,$.z);const i=1.5;Z.x+=(2*Math.random()-1)*i*se,Z.z+=(2*Math.random()-1)*i*se,G.getBarycoord(Z,v).toArray(ae);if(R([D,I,Y],ae,.2)!==x-1)continue;const a=[C,k,U];S(a,ae,K),S([E,F,N],ae,V);const r=a.map((e=>e.y)),c=Math.max(...r),l=Math.min(...r);if(K.y=b(K.y,l,c),null!=w.maxSlope&&w.maxSlope<90&&V.y<X)continue;const h=K.applyMatrix4(t.matrixWorld);h.y+=T(w.offsetMin,w.offsetMax);const u=T(w.scaleMin,w.scaleMax);p.makeScale(1,1,1),p.setPosition(h),p.scale(W(u)),w.alignToNormal&&H(p,h,B.matrixWorld,V),!1!==w.randomRotation&&j(p),B.setMatrixAt(he,p),he++}}B.instanceMatrix.count=he,p.makeScale(0,0,0);for(let e=he;e<ie;e++)B.setMatrixAt(e,p);B.instanceMatrix.needsUpdate=!0,z.has(t.uuid)||null===(m=this.landscape)||void 0===m||m.attach(B),z.set(t.uuid,B)}))));performance.now()}}))}stop(){this.view.removeOnLoop(this.onLoopHandler)}update(){this.view.camera&&(this.view.camera.getWorldPosition(this._cameraPosition),this._cameraPosition.distanceTo(this._lastUpdatePosition)>10&&(this._lastUpdatePosition.copy(this._cameraPosition),this.refreshGeometry(),this.refreshScatter(this._cameraPosition)))}clear(){this.scatterMeshes.forEach((e=>e.forEach((e=>{var t;return null===(t=e.parent)||void 0===t?void 0:t.remove(e)}))))}createLandscapeMesh(e,t,s,n,i,a){const r=new o(t.sectionSize,t.sectionSize,t.density,t.density);r.rotateX(Math.PI/-2);const c=this.defaultLandscapeMaterial,l=new x(r,c);l.position.x=s+i*t.sectionSize,l.position.z=n+a*t.sectionSize,l.receiveShadow=!0,l.castShadow=!1,l.userData.landscape={x:i,y:a},l.x=i,l.y=a,l.name=`${i},${a}`;const h=e.landscape.heightMaps.find((e=>e.x===i&&e.y===a));return null!=h&&this.applyHeightMap(r,h,t.density,1),r.computeBoundsTree(),l}}function $(e,t,s){const o=Math.sqrt(t),n=Math.floor(e/o)/(o-1),i=e%o/(o-1),a=Math.sqrt(s);return(s-1)*n-(a-1)*n+(a-1)*i}new Map,new l(0,0),new l(1,0),new l(0,1),new l(1,0),new l(0,1),new l(1,1),new n;const _=new u;function C(e,t){return function(s){return _.setFromObject(s).distanceToPoint(e)>t}}function k(e,t){return function(s){return _.setFromObject(s).distanceToPoint(e)<t}}function q(e){e.a.y=0,e.b.y=0,e.c.y=0}function R(e,t,s=.5){let o=-1,n=0;for(let i=0;i<e.length;i++)if(null!=e[i])for(let a=0;a<e[i].length;a++){const r=e[i][a]*t[i];r>s&&r>n&&(n=r,o=a)}return o}function T(e,t){let s=t-e,o=Math.random();return o*=s,o+=e,o}const U=new n;function W(e){return U.set(e,e,e)}new n;const D=new n,I=new n(0,1,0),O=(new a).makeRotationX(Math.PI/-2);function H(e,t,s,o){e.lookAt(D,o,I).multiply(O)}const Y=new a;function j(e){e.multiply(Y.makeRotationY(Math.random()*Math.PI/2))}function E(e){const t=e.getAttribute("normal");for(let e=0;e<t.count;e++)t.setXYZ(e,0,1,0);t.needsUpdate=!0}
1
+ import{__awaiter as e}from"tslib";import{materialFromAsset as t}from"../../scene/materializer";import{Mesh as s,PlaneGeometry as o,Vector3 as n,InstancedMesh as i,Matrix4 as a,MeshLambertMaterial as r,Color as c,Vector2 as l,Triangle as h,Box3 as u,MathUtils as d,MeshStandardMaterial as f,ShaderMaterial as m,DoubleSide as p,PerspectiveCamera as w}from"three";import{indexBy as y}from"../../utils/collections";import{smoothNormalsCrossMeshes as v}from"./utils";import*as M from"three";import{defaultLandscapeMaterial as g,LandscapeMesh as x}from"./landscape";import{meanVectors3withWeight as b,clamp as S}from"../../utils/math";import{whenIdle as A}from"../../utils/async";import{Subject as z,debounceTime as P}from"rxjs";new n,new n;const L=new n,B=new n,G=new n;export class LandscapeManager{constructor(e,t,s,o,i,r,c){this.source=e,this.view=t,this.landscape=s,this.assetManagerService=o,this.assetService=i,this.shaders=r,this.applyMaterial=c,this.scatterMeshes=new Map,this.loadedScatterSquares=new Set,this.refreshRequests=new z,this.defaultLandscapeMaterial=g.clone(),this.onLoopHandler=()=>this.update(),this.sectionCache=new Map,this._matrix=new a,this.scatterGeometryCache=new Map,this._lastUpdatePosition=new n,this._cameraPosition=new n,this.view.onLoop(this.onLoopHandler),this.defaultLandscapeMaterial.color=g.color,this.refreshRequests.pipe(P(500)).subscribe((e=>this.refreshScatter(e.origin,e.force,e.predicate)))}updateShaders(e){this.shaders=e}loadGrass(){return e(this,void 0,void 0,(function*(){const e=yield this.assetService.getAsset("6ij937n72g");yield this.assetManagerService.getMesh(e);this.grassGeometry=new o(2,2,3,3);const t=this.grassGeometry.getAttribute("normal");for(let e=0;e<t.count;e++)t.setXYZ(e,0,1,0);t.needsUpdate=!0,this.grassMaterial=new f({color:3765785})}))}refreshGeometry(){const e=this.source.landscape.options,t=(new n,new n);this.view.camera.getWorldPosition(t);const s=[];G.fromArray(this.source.position);const o=this.view.camera instanceof w?Math.min(this.view.camera.far,1e3):1e3,i=1.1*o,a=e.sections.y*e.sectionSize/-2,r=e.sections.x*e.sectionSize/-2;for(let n=0;n<e.sections.x;n++)if(L.x=r+n*e.sectionSize,!(Math.abs(t.x-L.x)>i))for(let c=0;c<e.sections.y;c++){L.z=a+c*e.sectionSize,B.copy(G).add(L);const l=B.distanceTo(t),h=`${n},${c}`,u=this.landscape.sections.find((e=>e.x===n&&e.y===c));if(l<=o){if(null==u){this.sectionCache.has(h)||this.sectionCache.set(h,this.createLandscapeMesh(this.source,e,r,a,n,c));const t=this.sectionCache.get(h);this.applyMaterial(t),this.landscape.add(t),s.push(t)}}else l>i&&this.landscape.remove(u)}v(s)}applyHeightMap(e,t,s,o=1){var n,i,a,r;const c=Math.pow(s+1,2),l=e.getAttribute("position"),h=y(null!==(n=t.points)&&void 0!==n?n:[],(e=>e.i));if(1===o)for(const e of t.points)l.setY(e.i,e.y);else for(let e=0;e<l.count;e++){const t=$(e,l.count,c);let s=0;s=t%1==0?null!==(a=null===(i=h.get(t))||void 0===i?void 0:i.y)&&void 0!==a?a:0:Math.floor(null===(r=h.get(t))||void 0===r?void 0:r.y),l.setY(e,s)}l.needsUpdate=!0,e.computeVertexNormals()}deleteOldScatterMeshes(){var e,t;const s=new Set;for(const[o,n]of null!==(t=null===(e=this.source.grass)||void 0===e?void 0:e.layers.entries())&&void 0!==t?t:[])for(const[e,t]of n.meshes.entries()){const t=`${o}-${e}`;s.add(t)}for(const e of this.scatterMeshes.keys())if(!s.has(e)){this.scatterMeshes.get(e).forEach((e=>{var t;null===(t=e.parent)||void 0===t||t.remove(e),e.dispose()})),this.scatterMeshes.delete(e)}}queueRefreshScatter(e,t=!1,s=(()=>!0)){this.refreshRequests.next({origin:e,force:t,predicate:s})}refreshScatter(a,l=!1,u=(()=>!0)){var f,w,v,g;return e(this,void 0,void 0,(function*(){l&&this.scatterGeometryCache.clear(),this.deleteOldScatterMeshes();for(const[x,z]of null!==(w=null===(f=this.source.grass)||void 0===f?void 0:f.layers.entries())&&void 0!==w?w:[])for(const[f,w]of z.meshes.entries()){const z=`${x}-${f}`;this.scatterMeshes.has(z)||this.scatterMeshes.set(z,new Map);const P=this.scatterMeshes.get(z),L=yield this.assetService.getAsset(w.assetId),B=yield this.assetManagerService.getMesh(L),G=[];if(B.scene.traverse((e=>{e instanceof s&&G.push(e)})),1!==G.length){console.log(B),console.warn("Dynamic grass only works for meshes with a single geometry.");continue}if(!(G[0]instanceof s)){console.warn("Only meshes can be used for dynamic grass. Found:",B.scene);continue}const $=G[0];let _=$.geometry;this.scatterGeometryCache.has($.geometry.uuid)?_=this.scatterGeometryCache.get($.geometry.uuid):(_=$.geometry.clone(),!0===w.normalsUp&&E(_),this.scatterGeometryCache.set($.geometry.uuid,_),null==_.userData.updatedMatrix&&(B.scene.updateMatrixWorld(),_.applyMatrix4($.matrixWorld),_.userData.updatedMatrix=!0));const U=_.getIndex().count/3;if(U>400){console.warn(`The triangle count of ${L.name} is too big ${U}. Keep it below 400`);continue}const D=null!=L.materialAssignments&&L.materialAssignments.length>0?L.materialAssignments[0].materialId:null,I=null!=D&&"null"!==D?yield t(yield this.assetService.getAsset(D),null,this.assetService,this.assetManagerService,this.shaders,!1):null;let O=null!=I?I:$.material;O instanceof m&&(O.side=p);const Y=d.degToRad(null!==(v=w.maxSlope)&&void 0!==v?v:90),X=Math.cos(Y),F=this.landscape.sections,N=F.filter(k(a,w.viewDistance)).filter((e=>!P.has(e.uuid)||l)).filter((e=>u(e)));F.filter(C(a,2*w.viewDistance)).forEach((e=>{var t;const s=P.get(e.uuid);null===(t=null==s?void 0:s.parent)||void 0===t||t.remove(s),P.delete(e.uuid)}));performance.now();const Z=this.source.landscape.options,K=Z.sectionSize,V=null!==(g=w.density)&&void 0!==g?g:1,J=null!=V?V:1,Q=Z.density,ee=K/Q,te=J,se=ee/Math.sqrt(te),oe=Math.pow(Q,2),ne=se/ee,ie=Math.floor(oe*te),ae=[0,0,0];for(const t of N)yield A((()=>e(this,void 0,void 0,(function*(){var e,s,a,u,d,f,m;t.updateWorldMatrix(!0,!1);const p=this._matrix,v=new n,g=t.geometry.getAttribute("position"),A=t.geometry.getAttribute("normal"),z=(null!==(e=this.source.vertexMaterials)&&void 0!==e?e:[]).filter((e=>e.m===t.name)),L=y(z,(e=>e.i));let B=P.get(t.uuid);if(null==B||B.count==ie&&!l||(null===(s=B.parent)||void 0===s||s.remove(B),P.delete(t.uuid),B=null),null==B){const e=new o(.15,.75).getAttribute("normal");for(let t=0;t<e.count;t++);new r({color:new c(3765785),side:M.DoubleSide});B=new i(_,O,ie),B.raycast=()=>{},B.receiveShadow=!0}const G=new h(new n,new n,new n);let[$,C,k,U]=[new n,new n,new n,new n],[D,I,Y]=[[],[],[]],[E,F,N]=[new n,new n,new n,new n];const Z=new n,K=new n,V=new n,J=new n,ee=new h(new n,new n,new n),se=new h(new n,new n,new n),re=new h(new n,new n,new n),ce=new h(new n,new n,new n);let le=0;e:for(let e=0;e<oe;e++){const s=Math.floor(e/Q);$.fromBufferAttribute(g,e+s),J.copy($).applyMatrix4(t.matrixWorld),ee.a.copy($),ee.b.fromBufferAttribute(g,e+1+s),ee.c.fromBufferAttribute(g,e+Q+1+s),se.a.copy(ee.b),se.b.copy(ee.c),se.c.fromBufferAttribute(g,e+Q+2+s),re.a.fromBufferAttribute(A,e+s),re.b.fromBufferAttribute(A,e+1+s),re.c.fromBufferAttribute(A,e+Q+1+s),ce.a.copy(re.b),ce.b.copy(re.c),ce.c.fromBufferAttribute(A,e+Q+2+s);const o=[];o[0]=null===(a=L.get(e+s))||void 0===a?void 0:a.w,o[1]=null===(u=L.get(e+1+s))||void 0===u?void 0:u.w,o[2]=null===(d=L.get(e+Q+1+s))||void 0===d?void 0:d.w,o[3]=null===(f=L.get(e+Q+2+s))||void 0===f?void 0:f.w;let n=0;for(let e=0;e<=1+ne;e+=ne)for(let s=0;s<=1+ne;s+=ne){if(le>ie)break e;if(n++,n>te)continue e;1-e>s?(C=ee.a,k=ee.b,U=ee.c,E=re.a,F=re.b,N=re.c,D=o[0],I=o[1],Y=o[2]):(C=se.a,k=se.b,U=se.c,E=ce.a,F=ce.b,N=ce.c,D=o[1],I=o[2],Y=o[3]),G.a.copy(C),G.b.copy(k),G.c.copy(U),q(G),Z.set($.x,0,$.z),Z.x=T(G.a.x,G.b.x),Z.z=T(G.a.z,G.c.z),G.getBarycoord(Z,v).toArray(ae);if(R([D,I,Y],ae,.2)!==x-1)continue;const i=[C,k,U];b(i,ae,K),b([E,F,N],ae,V);const a=i.map((e=>e.y)),r=Math.max(...a),c=Math.min(...a);if(K.y=S(K.y,c,r),null!=w.maxSlope&&w.maxSlope<90&&V.y<X)continue;const l=K.applyMatrix4(t.matrixWorld);l.y+=T(w.offsetMin,w.offsetMax);const h=T(w.scaleMin,w.scaleMax);p.makeScale(1,1,1),p.setPosition(l),p.scale(W(h)),w.alignToNormal&&H(p,l,B.matrixWorld,V),!1!==w.randomRotation&&j(p),B.setMatrixAt(le,p),le++}}B.instanceMatrix.count=le,p.makeScale(0,0,0);for(let e=le;e<ie;e++)B.setMatrixAt(e,p);B.instanceMatrix.needsUpdate=!0,P.has(t.uuid)||null===(m=this.landscape)||void 0===m||m.attach(B),P.set(t.uuid,B)}))));performance.now()}}))}stop(){this.view.removeOnLoop(this.onLoopHandler)}update(){this.view.camera&&(this.view.camera.getWorldPosition(this._cameraPosition),this._cameraPosition.distanceTo(this._lastUpdatePosition)>10&&(this._lastUpdatePosition.copy(this._cameraPosition),this.refreshGeometry(),this.refreshScatter(this._cameraPosition)))}clear(){this.scatterMeshes.forEach((e=>e.forEach((e=>{var t;return null===(t=e.parent)||void 0===t?void 0:t.remove(e)}))))}createLandscapeMesh(e,t,s,n,i,a){const r=new o(t.sectionSize,t.sectionSize,t.density,t.density);r.rotateX(Math.PI/-2);const c=this.defaultLandscapeMaterial,l=new x(r,c);l.position.x=s+i*t.sectionSize,l.position.z=n+a*t.sectionSize,l.receiveShadow=!0,l.castShadow=!1,l.userData.landscape={x:i,y:a},l.x=i,l.y=a,l.name=`${i},${a}`;const h=e.landscape.heightMaps.find((e=>e.x===i&&e.y===a));return null!=h&&this.applyHeightMap(r,h,t.density,1),r.computeBoundsTree(),l}}function $(e,t,s){const o=Math.sqrt(t),n=Math.floor(e/o)/(o-1),i=e%o/(o-1),a=Math.sqrt(s);return(s-1)*n-(a-1)*n+(a-1)*i}new Map,new l(0,0),new l(1,0),new l(0,1),new l(1,0),new l(0,1),new l(1,1),new n;const _=new u;function C(e,t){return function(s){return _.setFromObject(s).distanceToPoint(e)>t}}function k(e,t){return function(s){return _.setFromObject(s).distanceToPoint(e)<t}}function q(e){e.a.y=0,e.b.y=0,e.c.y=0}function R(e,t,s=.5){let o=-1,n=0;for(let i=0;i<e.length;i++)if(null!=e[i])for(let a=0;a<e[i].length;a++){const r=e[i][a]*t[i];r>s&&r>n&&(n=r,o=a)}return o}function T(e,t){let s=t-e,o=Math.random();return o*=s,o+=e,o}const U=new n;function W(e){return U.set(e,e,e)}new n;const D=new n,I=new n(0,1,0),O=(new a).makeRotationX(Math.PI/-2);function H(e,t,s,o){e.lookAt(D,o,I).multiply(O)}const Y=new a;function j(e){e.multiply(Y.makeRotationY(Math.random()*Math.PI/2))}function E(e){const t=e.getAttribute("normal");for(let e=0;e<t.count;e++)t.setXYZ(e,0,1,0);t.needsUpdate=!0}
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -1,4 +1,4 @@
1
- import{__awaiter as e}from"tslib";import{Subject as t}from"rxjs";import*as i from"three";import{BoxGeometry as a,Color as r,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 m,Object3D as p,PointLight as f,Quaternion as v,SphereGeometry as g,Texture as y,Vector2 as w,Vector3 as A,Vector4 as S}from"three";import b,{SpriteRenderer as M}from"three-nebula";import{bool as D,BooleanNode as x,float as I,FloatNode as N,NodeShaderMaterial as P,rgb as j,RgbNode as E,Texture2dLookupNode as O,textureSampler2d as F,vec2 as V,Vec2Node as B,vec3 as z,Vec3Node as C,vec4 as _}from"three-shader-graph";import T 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 H}from"./asset-resource-loader";import{BoxCollisionShape as W,PhysicalShapeMesh as G}from"./collision/collision-shape";import{isCollisionMesh as J}from"./collision/collision-shape-import";import{initLandscape as X}from"./landscape/landscape";import{LandscapeManager as Y}from"./landscape/landscape-manager";import{SectionGrid as q,smoothNormalsCrossMeshes as Z}from"./landscape/utils";import{createGrassMaterial as K}from"./materials/grass";import{createGrassFoliageMaterial as Q}from"./materials/grass-foliage";import{getMaterialAttribute as ee}from"./materials/utils/material-painting";import{createWaterMaterial as te}from"./materials/water";import{SerializedParamType as ie}from"./model";import{Matrix4 as ae}from"three";import{BaseActor as re}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";import{iterateMaterials as ue}from"../utils/materials";const me={};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,a,r,s,n,o,l,c){this.scene=i,this.dataProvider=a,this.assetsService=r,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,a.onUpdate((e=>this.update(e))),a.onRemove((e=>this.remove(e))),this.updateSubscription=r.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=>{De(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*(){fe.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,a,r;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!==(a=s.actor.params)&&void 0!==a?a:{});for(const e of null!==(r=s.actor.innerParams)&&void 0!==r?r:[])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,a){return e(this,void 0,void 0,(function*(){const e=i.length,r=i.shift();if(0==e){const e=yield ye(a,null,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders);for(const[i,a]of Object.entries(e))null!=a&&(t[i]=a)}else null!=t[r]&&(yield this.applyActorComponentParams(t[r],i,a))}))}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 a=1==i.length&&0==i[0].children.length,r=!0;this._canBeInstancedCache.set(t.assetId,a&&r)}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 be(i,((i,a,r)=>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&&a&&(null===(s=a.children)||void 0===s?void 0:s.length)>0&&a.children.splice(a.children.findIndex((e=>e.id===i.id)),1),t.push(n,Object.assign(Object.assign({},i),{parentTransform:r}))}))));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),a=new H;a.add(t),a.userData.src=i[0],e instanceof H&&(a.collisionShapes=e.collisionShapes),a.castShadow=!1,a.receiveShadow=!1,this.scene.add(a)}else yield Promise.all(i.map((e=>this.materialize(e))));yield this.initActorsPostInit()}))}createInstancedMesh(t,a){var r,n;return e(this,void 0,void 0,(function*(){const e=a.children.filter((e=>!J(e)))[0],o=yield this.assetsService.getAsset(t[0].assetId);yield this.applyMaterials(a,De(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 a=(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)),r=(new ae).copy(t[e].parentTransform).multiply(a);c.setMatrixAt(e,r)}return c.castShadow=null===(r=o.castShadow)||void 0===r||r,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 a=[];return t.traverse((t=>e(this,void 0,void 0,(function*(){if(t instanceof d||t.isMesh)for(const e of ue(t.material))e.hasOwnProperty("color")&&a.push(t)})))),Promise.all(a.map((t=>e(this,void 0,void 0,(function*(){var e,a,r,s;if(t.material instanceof Array)for(let r=0;r<t.material.length;r++){const s=t.material[r];if(null==s.color)continue;const n="#"+s.color.getHexString(),o=s.name;if(n===i.color&&(s.name===i.name||null==i.name)||t.userData["originalColor_"+r]===i.color&&t.userData["originalMaterialName_"+r]===i.name){const s=yield this.assetsService.getAsset(i.materialId),l=t.material[r];s&&(t.material[r]=yield materialFromAsset(s,this.renderingView,this.assetsService,this.assetManagerService,this.shaders),t.userData["originalColor_"+r]=null!==(e=t.userData["originalColor_"+r])&&void 0!==e?e:n,t.userData["originalMaterialName_"+r]=null!==(a=t.userData["originalMaterialName_"+r])&&void 0!==a?a:o,this.inEditor&&this._originalMaterials.set(t.id+"#"+r,l))}}else{const e="#"+t.material.color.getHexString(),a=t.material.name;if(e===i.color&&(t.material.name===i.name||null==i.name)||t.userData.originalColor===i.color&&t.userData.originalName===i.name){const n=yield this.assetsService.getAsset(i.materialId),o=t.material;n&&(t.material=yield materialFromAsset(n,this.renderingView,this.assetsService,this.assetManagerService,this.shaders),t.userData.originalColor=null!==(r=t.userData.originalColor)&&void 0!==r?r:e,t.userData.originalMaterialName=null!==(s=t.userData.originalMaterialName)&&void 0!==s?s:a,this.inEditor&&this._originalMaterials.set(t.id,o))}}})))))}unapplyMaterials(t){t.traverse((t=>e(this,void 0,void 0,(function*(){var e,i;if(t instanceof d)if(t.material instanceof Array)for(let i=0;i<t.material.length;i++)t.material[i]=null!==(e=this._originalMaterials.get(t.id+"#"+i))&&void 0!==e?e:t.material[i];else t.material=null!==(i=this._originalMaterials.get(t.id))&&void 0!==i?i:t.material}))))}updateActors(t){this.actorTypes=t;const i=new Set(Object.values(T));U(this.scene,(e=>{var t,a;return(null===(t=e.userData.src)||void 0===t?void 0:t.id)&&"actor"===e.userData.src.type&&this.materializedActors.has(null===(a=e.userData.src)||void 0===a?void 0:a.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 fe.entries())t.userData.customShaderName&&fe.delete(e);this.landscapeManagers.forEach((t=>t.updateShaders(e))),U(this.scene,(e=>!0)).forEach((e=>{e.traverse((e=>{var t,i;if(e instanceof d){if(null!=(null===(t=e.material.userData)||void 0===t?void 0:t.customShaderName)){const t=null===(i=function(e,t){if(t(e))return e;let i;return e.traverseAncestors((e=>{null==i&&t(e)&&(i=e)})),i}(e,(e=>{var t;return null!=(null===(t=e.userData.src)||void 0===t?void 0:t.id)})))||void 0===i?void 0:i.userData.src;null!=t&&this.update(t)}}}))}))}update(t){var i;return e(this,void 0,void 0,(function*(){const e=this.sceneObjectMap.get(t.id);if(e){const s=this.findParent(t);if(null!=s&&s.uuid!=e.uuid?s.attach(e):console.error("Parent is wrong"),"prefab"!==t.type){this.unapplyMaterials(e);this.inEditor&&t.hidden&&!1?e.traverse((e=>{e instanceof d&&(e.material.wireframe=!0)})):(e.traverse((e=>{e instanceof d&&(e.material.wireframe=!1)})),(null!==(i=t.materialAssignments)&&void 0!==i?i:[]).forEach((t=>this.applyMaterial(e,t))))}if(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 r(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=Ae(t.fog),e&&(a=this.scene).traverse((e=>{if(e instanceof d){const t=e.material;t instanceof P&&(a.fog instanceof n?(t.uniforms.fogFar.value=a.fog.far,t.uniforms.fogNear.value=a.fog.near):a.fog instanceof o&&(t.uniforms.density={value:a.fog.density}),t.needsUpdate=!0,t.uniformsNeedUpdate=!0)}})),this.fixFogColor()}else if("actor"===t.type){if(this.materializedActors.has(t.id)){const e=this.editorActorParamSnapshot.get(t.id);null!=e&&e===JSON.stringify(t.actor)||(console.log("Rematerializing actor because parameters changed"),this.remove(t),yield this.materializeAndInitActor(t))}}else if("shape_mesh"===t.type){const i=yield this.createMeshByShape(t.shape,e.material,t.shapeParams);e instanceof G&&(e.geometry=i.geometry,e.collisionShape=i.collisionShape)}"asset_mesh"!==t.type&&"shape_mesh"!==t.type||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 a}))}materializeAndInitActor(t,i=this.findParent(t)){return e(this,void 0,void 0,(function*(){const e=yield this.materialize(t,i);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 e}))}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,a;return(null===(a=null===(i=e.userData)||void 0===i?void 0:i.src)||void 0===a?void 0:a.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 r(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 a=new Set;for(const[e,r]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 r)n.setX(e.i,e.w[0]),n.setY(e.i,e.w[1]),n.setZ(e.i,e.w[2]),s=!0;s&&a.add(e)}this.inEditor&&this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>a.has(e.name)))))}materialize(t,i,r=!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=Ae(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),r||(e.userData.src=t),!this.inEditor){const i=null!==(s=t.components)&&void 0!==s?s:[],a=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(...a),i.length>0?e.userData.componentRefs=yield Promise.all(i.map(((i,a)=>this.createComponent(e,t,i,a)))):"asset_mesh"==t.type&&function(e){e.traverse((e=>{e.matrixAutoUpdate=!1,e.matrixWorldNeedsUpdate=!1}));const t=e.updateMatrixWorld;e.updateMatrixWorld=function(){t.apply(e),e.updateMatrixWorld=function(){}}}(e)}if(this.inEditor){let t=null;e instanceof G&&(t=function(e){if(e instanceof W)return new d(new a(...e.offset.toArray()),Se);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,r)})),e}}))}createComponent(t,i,a,r){return e(this,void 0,void 0,(function*(){const e=new me[a.path+"/"+a.className],s=i.id+r;e.id=s,e.object=t;for(const t of a.params)null!=t.value&&(e[t.name]=t.value);return this.components.push(e),s}))}createFromActor(t){var i,a,r;return e(this,void 0,void 0,(function*(){const e=null!==(a=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!==a?a:T[null===(r=t.actor)||void 0===r?void 0:r.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,a,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 m({color:new r("#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!==(a=t.castShadow)&&void 0!==a&&a,t.collisionDetection||(o.collisionShape=null),n=o,this._originalMaterials.set(n.id,o.material),n.traverse((e=>{}))}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 a=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(a),a.refreshGeometry(),i}applyHeightMaps(e,t,i=!1){const a=new q(e.sections);for(const e of null!=t?t:[]){const t=a.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 r=e.sections;r.forEach((e=>{e.geometry.computeBoundsTree(),e.geometry.computeVertexNormals()})),this.inEditor&&!i||setTimeout((()=>Z(r)),50)}createMeshByShape(t,i,a={}){return e(this,void 0,void 0,(function*(){if("landscape"!==t&&ce.includes(t)){const r=yield function(t){return e(this,void 0,void 0,(function*(){const e={};for(const[i,a]of Object.entries(t)){const t=yield we(a,null,null,null);null!=t&&(e[i]=t)}return e}))}(null!=a?a:{});return"cylinder"==t&&r.openEnded,new G(le[t].geometry(r),i,le[t].collision(r))}throw new Error(`Unsupported shape '${t}'`)}))}createFromAsset(t){var i,a,r,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);De(t.materialAssignments,e.materialAssignments).forEach((e=>this.applyMaterial(n,e)));const o=null===(a=null!==(i=t.receiveShadow)&&void 0!==i?i:!!e.receiveShadow)||void 0===a||a,l=null!==(s=null!==(r=t.castShadow)&&void 0!==r?r:!!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),a=new p;return yield b.fromJSONAsync(e.particleSystem,i).then((e=>{const t=new M(a,i);e.addRenderer(t),this.renderingView.onLoop((t=>e.update()))})),a}))}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 g(.3,10,10),i=new m({color:new r(16771709)}),a=new d(t,i);e.add(a)}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 fe=new Map,ve=new h({color:16711935}),ge=new Map;export function materialFromAsset(t,a,s,n,o,l=!0){var c,d,h,m,p,f,v,g,y,w,A;return e(this,void 0,void 0,(function*(){const e=JSON.stringify(t.material);if(l&&fe.has(e))return fe.get(e);const S={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 r(t.material.params.color).convertSRGBToLinear(),transparent:null!=t.material.params.opacity&&t.material.params.opacity<1},b={};if(null!=t.material.params.map){const e=t.material.params.map,i=yield s.getAsset(e);null!=i&&(S.map=yield n.getTexture(i))}let M;switch(t.material.type){case"phong":M=new u(Object.assign(Object.assign({},S),b));break;case"water":M=te(S,a);break;case"grassFoliage":M=Q({color:S.color,map:S.map},a);break;case"grass":M=K(Object.assign(Object.assign({},S),{colorTwo:new r(t.material.params.colorTwo),colorThree:new r(t.material.params.colorThree)}),a);break;case"standard":case"lambert":case"shader":const e=null!==(m={standard:ne,lambert:oe}[t.material.type])&&void 0!==m?m:null===(p=o.find((e=>e.name==t.material.shader)))||void 0===p?void 0:p.type;if(e){const i=new e,r=yield ye(null!==(v=null===(f=t.material)||void 0===f?void 0:f.shaderParams)&&void 0!==v?v:{},e,s,n,null,a,o);Object.assign(i,r);try{M=i.build()}catch(e){console.log("Shader runtime error: "+e),ge.has(t.material.shader)||ge.set(t.material.shader,ve.clone()),M=ge.get(t.material.shader)}M.userData.customShaderName=t.material.shader}else console.warn("Missing shader implementation with name "+t.material.shader),M=ve;break;default:throw new Error("Unsupported material type"+t.material.type)}return null==a||a.csm.setupMaterial(M),l&&fe.set(e,M),M.side=null!==(y=null!==(g=t.material.side)&&void 0!==g?g:M.side)&&void 0!==y?y:i.FrontSide,M.transparent=null!==(A=null!==(w=t.material.transparent)&&void 0!==w?w:S.transparent)&&void 0!==A&&A||M.transparent,M}))}function ye(t,i,a,r,s,n,o){return e(this,void 0,void 0,(function*(){const e={};for(const[i,l]of Object.entries(t)){const t=yield we(l,a,r,s,n,o);null!=t&&(e[i]=t)}return e}))}function we(t,i,a,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?I(c):c;case ie.Texture:return yield a.getTexture(yield i.getAsset(e));case ie.Sampler2DNode:return F(yield a.getTexture(yield i.getAsset(e)));case ie.Boolean:return e;case ie.BooleanNode:return D(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 r(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.Object3D:return(yield a.getMesh(yield i.getAsset(e))).scene;case ie.Material:return yield materialFromAsset(yield i.getAsset(e),o,i,a,l);case ie.AudioBuffer:return yield a.getAudio(yield i.getAsset(e))}return null}))}function Ae(e){var t,i;return"linear"===e.type?new n(new r(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 Se=new m({color:4229780});function be(t,a,r,n){var o;return e(this,void 0,void 0,(function*(){null==n&&(n=(new ae).identity()),yield a(t,r,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=>be(i,a,t,e))))}))}function Me(e){const t=e.constructor.prototype;return t instanceof Number||e===Number?ie.Number:t instanceof N||"function"==typeof e.prototype.isFloat?ie.FloatNode:t instanceof y||e===y||e.isTexture?ie.Texture:t instanceof se||e===O?ie.Sampler2DNode:t instanceof Boolean||e===Boolean?ie.Boolean:t instanceof x?ie.BooleanNode:t instanceof r||e==r?ie.Color:t instanceof E||"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 re||e==re||e.prototype instanceof re||e.prototype==re?ie.BaseActor:t instanceof s||e==s?ie.Euler:t instanceof p||e==p?ie.Object3D:t instanceof c||e==c?ie.Material:t instanceof AudioBuffer||e==AudioBuffer?ie.AudioBuffer: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 a,r,s;return[e.name,{type:Me(e.type),value:null!==(s=null!==(r=null===(a=t[e.name])||void 0===a?void 0:a.value)&&void 0!==r?r:i[e.name])&&void 0!==s?s:Ie.get(Me(e.type))}]})))}export function prepareCustomParamsFromType(e,t,i=null){const a=$(e);if(0===a.length)return{};let r;null!=i?he(i,(()=>{r=i.get(e)})):r=new e;const s={};for(const e of a){const t=r[e.name];if(null!=t){const i=serializeCustomParameter(e.type,t);null!=i&&(s[e.name]=i)}}return prepareCustomParams(a,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 r:return t instanceof r?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new r(t).getHexString():void i();case String:return t;case s:return t instanceof s?t.toArray():void i()}}function De(e,t){return function(e,t,i){const a=[],r=new Set;for(const s of[...null!=e?e:[],...null!=t?t:[]]){const e=i(s);r.has(e)||(r.add(e),a.push(s))}return a}((null!=e?e:[]).filter((e=>xe(e.materialId))),(null!=t?t:[]).filter((e=>xe(e.materialId))),(e=>e.color+e.name))}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 a,Color as r,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 m,Object3D as p,PointLight as f,Quaternion as v,SphereGeometry as g,Texture as y,Vector2 as w,Vector3 as A,Vector4 as S}from"three";import b,{SpriteRenderer as M}from"three-nebula";import{bool as D,BooleanNode as x,float as I,FloatNode as N,NodeShaderMaterial as P,rgb as j,RgbNode as E,Texture2dLookupNode as O,textureSampler2d as F,vec2 as V,Vec2Node as B,vec3 as z,Vec3Node as C,vec4 as _}from"three-shader-graph";import T 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 H}from"./asset-resource-loader";import{BoxCollisionShape as W,PhysicalShapeMesh as G}from"./collision/collision-shape";import{isCollisionMesh as J}from"./collision/collision-shape-import";import{initLandscape as X}from"./landscape/landscape";import{LandscapeManager as Y}from"./landscape/landscape-manager";import{SectionGrid as q,smoothNormalsCrossMeshes as Z}from"./landscape/utils";import{createGrassMaterial as K}from"./materials/grass";import{createGrassFoliageMaterial as Q}from"./materials/grass-foliage";import{getMaterialAttribute as ee}from"./materials/utils/material-painting";import{createWaterMaterial as te}from"./materials/water";import{SerializedParamType as ie}from"./model";import{Matrix4 as ae}from"three";import{BaseActor as re}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";import{iterateMaterials as ue}from"../utils/materials";const me={};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,a,r,s,n,o,l,c){this.scene=i,this.dataProvider=a,this.assetsService=r,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,a.onUpdate((e=>this.update(e))),a.onRemove((e=>this.remove(e))),this.updateSubscription=r.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=>{De(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*(){fe.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,a,r;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!==(a=s.actor.params)&&void 0!==a?a:{});for(const e of null!==(r=s.actor.innerParams)&&void 0!==r?r:[])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,a){return e(this,void 0,void 0,(function*(){const e=i.length,r=i.shift();if(0==e){const e=yield ye(a,null,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders);for(const[i,a]of Object.entries(e))null!=a&&(t[i]=a)}else null!=t[r]&&(yield this.applyActorComponentParams(t[r],i,a))}))}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 a=1==i.length&&0==i[0].children.length,r=!0;this._canBeInstancedCache.set(t.assetId,a&&r)}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 be(i,((i,a,r)=>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&&a&&(null===(s=a.children)||void 0===s?void 0:s.length)>0&&a.children.splice(a.children.findIndex((e=>e.id===i.id)),1),"other"===n&&a||t.push(n,Object.assign(Object.assign({},i),{parentTransform:r}))}))));for(const[e,i]of t.entries())if("other"!==e&&i.length>0){const e=yield this.createFromAsset(i[0]);if(null==e)continue;const t=yield this.createInstancedMesh(i,e),a=new H;a.add(t),a.userData.src=i[0],e instanceof H&&(a.collisionShapes=e.collisionShapes),a.castShadow=!1,a.receiveShadow=!1,this.scene.add(a)}else yield Promise.all(i.map((e=>this.materialize(e))));yield this.initActorsPostInit()}))}createInstancedMesh(t,a){var r,n;return e(this,void 0,void 0,(function*(){const e=a.children.filter((e=>!J(e)))[0],o=yield this.assetsService.getAsset(t[0].assetId);yield this.applyMaterials(a,De(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 a=(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)),r=(new ae).copy(t[e].parentTransform).multiply(a);c.setMatrixAt(e,r)}return c.castShadow=null===(r=o.castShadow)||void 0===r||r,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 a=[];return t.traverse((t=>e(this,void 0,void 0,(function*(){if(t instanceof d||t.isMesh)for(const e of ue(t.material))e.hasOwnProperty("color")&&a.push(t)})))),Promise.all(a.map((t=>e(this,void 0,void 0,(function*(){var e,a,r,s;if(t.material instanceof Array)for(let r=0;r<t.material.length;r++){const s=t.material[r];if(null==s.color)continue;const n="#"+s.color.getHexString(),o=s.name;if(n===i.color&&(s.name===i.name||null==i.name)||t.userData["originalColor_"+r]===i.color&&t.userData["originalMaterialName_"+r]===i.name){const s=yield this.assetsService.getAsset(i.materialId),l=t.material[r];s&&(t.material[r]=yield materialFromAsset(s,this.renderingView,this.assetsService,this.assetManagerService,this.shaders),t.userData["originalColor_"+r]=null!==(e=t.userData["originalColor_"+r])&&void 0!==e?e:n,t.userData["originalMaterialName_"+r]=null!==(a=t.userData["originalMaterialName_"+r])&&void 0!==a?a:o,this.inEditor&&this._originalMaterials.set(t.id+"#"+r,l))}}else{const e="#"+t.material.color.getHexString(),a=t.material.name;if(e===i.color&&(t.material.name===i.name||null==i.name)||t.userData.originalColor===i.color&&t.userData.originalName===i.name){const n=yield this.assetsService.getAsset(i.materialId),o=t.material;n&&(t.material=yield materialFromAsset(n,this.renderingView,this.assetsService,this.assetManagerService,this.shaders),t.userData.originalColor=null!==(r=t.userData.originalColor)&&void 0!==r?r:e,t.userData.originalMaterialName=null!==(s=t.userData.originalMaterialName)&&void 0!==s?s:a,this.inEditor&&this._originalMaterials.set(t.id,o))}}})))))}unapplyMaterials(t){t.traverse((t=>e(this,void 0,void 0,(function*(){var e,i;if(t instanceof d)if(t.material instanceof Array)for(let i=0;i<t.material.length;i++)t.material[i]=null!==(e=this._originalMaterials.get(t.id+"#"+i))&&void 0!==e?e:t.material[i];else t.material=null!==(i=this._originalMaterials.get(t.id))&&void 0!==i?i:t.material}))))}updateActors(t){this.actorTypes=t;const i=new Set(Object.values(T));U(this.scene,(e=>{var t,a;return(null===(t=e.userData.src)||void 0===t?void 0:t.id)&&"actor"===e.userData.src.type&&this.materializedActors.has(null===(a=e.userData.src)||void 0===a?void 0:a.id)&&!i.has(e.userData.src.actor.type)})).forEach((t=>e(this,void 0,void 0,(function*(){this.remove(t.userData.src),yield this.materializeAndInitActor(t.userData.src)}))))}updateShaders(e){this.shaders=e;for(const[e,t]of fe.entries())t.userData.customShaderName&&fe.delete(e);this.landscapeManagers.forEach((t=>t.updateShaders(e))),U(this.scene,(e=>!0)).forEach((e=>{e.traverse((e=>{var t,i;if(e instanceof d){if(null!=(null===(t=e.material.userData)||void 0===t?void 0:t.customShaderName)){const t=null===(i=function(e,t){if(t(e))return e;let i;return e.traverseAncestors((e=>{null==i&&t(e)&&(i=e)})),i}(e,(e=>{var t;return null!=(null===(t=e.userData.src)||void 0===t?void 0:t.id)})))||void 0===i?void 0:i.userData.src;null!=t&&this.update(t)}}}))}))}update(t){var i;return e(this,void 0,void 0,(function*(){const e=this.sceneObjectMap.get(t.id);if(e){const s=this.findParent(t);if(null!=s&&s.uuid!=e.uuid?s.attach(e):console.error("Parent is wrong"),"prefab"!==t.type){this.unapplyMaterials(e);this.inEditor&&t.hidden&&!1?e.traverse((e=>{e instanceof d&&(e.material.wireframe=!0)})):(e.traverse((e=>{e instanceof d&&(e.material.wireframe=!1)})),(null!==(i=t.materialAssignments)&&void 0!==i?i:[]).forEach((t=>this.applyMaterial(e,t))))}if(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 r(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=Ae(t.fog),e&&(a=this.scene).traverse((e=>{if(e instanceof d){const t=e.material;t instanceof P&&(a.fog instanceof n?(t.uniforms.fogFar.value=a.fog.far,t.uniforms.fogNear.value=a.fog.near):a.fog instanceof o&&(t.uniforms.density={value:a.fog.density}),t.needsUpdate=!0,t.uniformsNeedUpdate=!0)}})),this.fixFogColor()}else if("actor"===t.type){if(this.materializedActors.has(t.id)){const e=this.editorActorParamSnapshot.get(t.id);null!=e&&e===JSON.stringify(t.actor)||(console.log("Rematerializing actor because parameters changed"),this.remove(t),yield this.materializeAndInitActor(t))}}else if("shape_mesh"===t.type){const i=yield this.createMeshByShape(t.shape,e.material,t.shapeParams);e instanceof G&&(e.geometry=i.geometry,e.collisionShape=i.collisionShape)}("asset_mesh"===t.type||"shape_mesh"===t.type&&"landscape"!==t.shape)&&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 a}))}materializeAndInitActor(t,i=this.findParent(t)){return e(this,void 0,void 0,(function*(){const e=yield this.materialize(t,i);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 e}))}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,a;return(null===(a=null===(i=e.userData)||void 0===i?void 0:i.src)||void 0===a?void 0:a.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 r(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 a=new Set;for(const[e,r]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 r)n.setX(e.i,e.w[0]),n.setY(e.i,e.w[1]),n.setZ(e.i,e.w[2]),s=!0;s&&a.add(e)}this.inEditor&&this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>a.has(e.name)))))}materialize(t,i,r=!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=Ae(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),r||(e.userData.src=t),!this.inEditor){const i=null!==(s=t.components)&&void 0!==s?s:[],a=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(...a),i.length>0?e.userData.componentRefs=yield Promise.all(i.map(((i,a)=>this.createComponent(e,t,i,a)))):"asset_mesh"==t.type&&function(e){e.traverse((e=>{e.matrixAutoUpdate=!1,e.matrixWorldNeedsUpdate=!1}));const t=e.updateMatrixWorld;e.updateMatrixWorld=function(){t.apply(e),e.updateMatrixWorld=function(){}}}(e)}if(this.inEditor){let t=null;e instanceof G&&(t=function(e){if(e instanceof W)return new d(new a(...e.offset.toArray()),Se);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,r)})),e}}))}createComponent(t,i,a,r){return e(this,void 0,void 0,(function*(){const e=new me[a.path+"/"+a.className],s=i.id+r;e.id=s,e.object=t;for(const t of a.params)null!=t.value&&(e[t.name]=t.value);return this.components.push(e),s}))}createFromActor(t){var i,a,r;return e(this,void 0,void 0,(function*(){const e=null!==(a=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!==a?a:T[null===(r=t.actor)||void 0===r?void 0:r.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,a,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 m({color:new r("#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!==(a=t.castShadow)&&void 0!==a&&a,t.collisionDetection||(o.collisionShape=null),n=o,this._originalMaterials.set(n.id,o.material),n.traverse((e=>{}))}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 a=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(a),a.refreshGeometry(),i}applyHeightMaps(e,t,i=!1){const a=new q(e.sections);for(const e of null!=t?t:[]){const t=a.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 r=e.sections;r.forEach((e=>{e.geometry.computeBoundsTree(),e.geometry.computeVertexNormals()})),this.inEditor&&!i||setTimeout((()=>Z(r)),50)}createMeshByShape(t,i,a={}){return e(this,void 0,void 0,(function*(){if("landscape"!==t&&ce.includes(t)){const r=yield function(t){return e(this,void 0,void 0,(function*(){const e={};for(const[i,a]of Object.entries(t)){const t=yield we(a,null,null,null);null!=t&&(e[i]=t)}return e}))}(null!=a?a:{});return"cylinder"==t&&r.openEnded,new G(le[t].geometry(r),i,le[t].collision(r))}throw new Error(`Unsupported shape '${t}'`)}))}createFromAsset(t){var i,a,r,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);De(t.materialAssignments,e.materialAssignments).forEach((e=>this.applyMaterial(n,e)));const o=null===(a=null!==(i=t.receiveShadow)&&void 0!==i?i:!!e.receiveShadow)||void 0===a||a,l=null!==(s=null!==(r=t.castShadow)&&void 0!==r?r:!!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),a=new p;return yield b.fromJSONAsync(e.particleSystem,i).then((e=>{const t=new M(a,i);e.addRenderer(t),this.renderingView.onLoop((t=>e.update()))})),a}))}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 g(.3,10,10),i=new m({color:new r(16771709)}),a=new d(t,i);e.add(a)}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 fe=new Map,ve=new h({color:16711935}),ge=new Map;export function materialFromAsset(t,a,s,n,o,l=!0){var c,d,h,m,p,f,v,g,y,w,A;return e(this,void 0,void 0,(function*(){const e=JSON.stringify(t.material);if(l&&fe.has(e))return fe.get(e);const S={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 r(t.material.params.color).convertSRGBToLinear(),transparent:null!=t.material.params.opacity&&t.material.params.opacity<1},b={};if(null!=t.material.params.map){const e=t.material.params.map,i=yield s.getAsset(e);null!=i&&(S.map=yield n.getTexture(i))}let M;switch(t.material.type){case"phong":M=new u(Object.assign(Object.assign({},S),b));break;case"water":M=te(S,a);break;case"grassFoliage":M=Q({color:S.color,map:S.map},a);break;case"grass":M=K(Object.assign(Object.assign({},S),{colorTwo:new r(t.material.params.colorTwo),colorThree:new r(t.material.params.colorThree)}),a);break;case"standard":case"lambert":case"shader":const e=null!==(m={standard:ne,lambert:oe}[t.material.type])&&void 0!==m?m:null===(p=o.find((e=>e.name==t.material.shader)))||void 0===p?void 0:p.type;if(e){const i=new e,r=yield ye(null!==(v=null===(f=t.material)||void 0===f?void 0:f.shaderParams)&&void 0!==v?v:{},e,s,n,null,a,o);Object.assign(i,r);try{M=i.build()}catch(e){console.log("Shader runtime error: "+e),ge.has(t.material.shader)||ge.set(t.material.shader,ve.clone()),M=ge.get(t.material.shader)}M.userData.customShaderName=t.material.shader}else console.warn("Missing shader implementation with name "+t.material.shader),M=ve;break;default:throw new Error("Unsupported material type"+t.material.type)}return null==a||a.csm.setupMaterial(M),l&&fe.set(e,M),M.side=null!==(y=null!==(g=t.material.side)&&void 0!==g?g:M.side)&&void 0!==y?y:i.FrontSide,M.transparent=null!==(A=null!==(w=t.material.transparent)&&void 0!==w?w:S.transparent)&&void 0!==A&&A||M.transparent,M}))}function ye(t,i,a,r,s,n,o){return e(this,void 0,void 0,(function*(){const e={};for(const[i,l]of Object.entries(t)){const t=yield we(l,a,r,s,n,o);null!=t&&(e[i]=t)}return e}))}function we(t,i,a,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?I(c):c;case ie.Texture:return yield a.getTexture(yield i.getAsset(e));case ie.Sampler2DNode:return F(yield a.getTexture(yield i.getAsset(e)));case ie.Boolean:return e;case ie.BooleanNode:return D(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 r(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.Object3D:return(yield a.getMesh(yield i.getAsset(e))).scene;case ie.Material:return yield materialFromAsset(yield i.getAsset(e),o,i,a,l);case ie.AudioBuffer:return yield a.getAudio(yield i.getAsset(e))}return null}))}function Ae(e){var t,i;return"linear"===e.type?new n(new r(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 Se=new m({color:4229780});function be(t,a,r,n){var o;return e(this,void 0,void 0,(function*(){null==n&&(n=(new ae).identity()),yield a(t,r,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=>be(i,a,t,e))))}))}function Me(e){const t=e.constructor.prototype;return t instanceof Number||e===Number?ie.Number:t instanceof N||"function"==typeof e.prototype.isFloat?ie.FloatNode:t instanceof y||e===y||e.isTexture?ie.Texture:t instanceof se||e===O?ie.Sampler2DNode:t instanceof Boolean||e===Boolean?ie.Boolean:t instanceof x?ie.BooleanNode:t instanceof r||e==r?ie.Color:t instanceof E||"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 re||e==re||e.prototype instanceof re||e.prototype==re?ie.BaseActor:t instanceof s||e==s?ie.Euler:t instanceof p||e==p?ie.Object3D:t instanceof c||e==c?ie.Material:t instanceof AudioBuffer||e==AudioBuffer?ie.AudioBuffer: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 a,r,s;return[e.name,{type:Me(e.type),value:null!==(s=null!==(r=null===(a=t[e.name])||void 0===a?void 0:a.value)&&void 0!==r?r:i[e.name])&&void 0!==s?s:Ie.get(Me(e.type))}]})))}export function prepareCustomParamsFromType(e,t,i=null){const a=$(e);if(0===a.length)return{};let r;null!=i?he(i,(()=>{r=i.get(e)})):r=new e;const s={};for(const e of a){const t=r[e.name];if(null!=t){const i=serializeCustomParameter(e.type,t);null!=i&&(s[e.name]=i)}}return prepareCustomParams(a,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 r:return t instanceof r?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new r(t).getHexString():void i();case String:return t;case s:return t instanceof s?t.toArray():void i()}}function De(e,t){return function(e,t,i){const a=[],r=new Set;for(const s of[...null!=e?e:[],...null!=t?t:[]]){const e=i(s);r.has(e)||(r.add(e),a.push(s))}return a}((null!=e?e:[]).filter((e=>xe(e.materialId))),(null!=t?t:[]).filter((e=>xe(e.materialId))),(e=>e.color+e.name))}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.
@@ -32,6 +32,9 @@ export type CustomParamValue = {
32
32
  type: SerializedParamType;
33
33
  value: unknown;
34
34
  };
35
+ export type TextureSettings = {
36
+ flipY?: boolean;
37
+ };
35
38
  export interface Asset {
36
39
  id: string;
37
40
  name: string;
@@ -63,6 +66,7 @@ export interface Asset {
63
66
  particleSystem?: ParticleSystemConfig;
64
67
  components?: AttachedComponent[];
65
68
  actor?: ActorSettings;
69
+ texture?: TextureSettings;
66
70
  receiveShadow?: boolean;
67
71
  castShadow?: boolean;
68
72
  }
@@ -16,6 +16,7 @@ export type ActorImpl = ClassImpl<BaseActor>;
16
16
  export type ShaderImpl = ClassImpl<Shader>;
17
17
  export type NodeShaderOutput = {
18
18
  color: RgbaNode;
19
+ alphaTest?: number;
19
20
  transform?: Mat4Node;
20
21
  transparent?: boolean;
21
22
  };
@@ -1,4 +1,4 @@
1
- import{NodeShaderMaterial as r}from"../shader-nodes";export*from"./parameter";export class Shader{}export class NodeShader{build(){return new r(Object.assign({transparent:!0},this.output()))}}
1
+ import{NodeShaderMaterial as r}from"../shader-nodes";export*from"./parameter";export class Shader{}export class NodeShader{build(){return new r(Object.assign({transparent:!1},this.output()))}}
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hology/core",
3
- "version": "0.0.23",
3
+ "version": "0.0.25",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {