@hology/core 0.0.41 → 0.0.42

Sign up to get free protection for your applications and to get access to all the features.
@@ -33,6 +33,8 @@ export declare class CharacterMovementComponent extends ActorComponent {
33
33
  set autoStepMaxHeight(maxHeight: number);
34
34
  get snapToGround(): number;
35
35
  set snapToGround(distance: number);
36
+ set offset(distance: number);
37
+ get offset(): number;
36
38
  readonly velocity: Vector3;
37
39
  mode: CharacterMovementMode;
38
40
  isSprinting: boolean;
@@ -1,4 +1,4 @@
1
- import{__decorate as t,__metadata as i}from"tslib";import{ActionInput as e,AxisInput as o,RotationInput as s}from"../../../../../gameplay/input/index.js";import{PhysicsSystem as n,RayTestResult as r}from"../../../../../gameplay/services/physics/physics-system.js";import{MathUtils as a,Vector3 as c}from"three";import{ActorComponent as l,Component as h}from"../../../component.js";import{CharacterMovementMode as p}from"./modes.js";import{CapsuleCollisionShape as m}from"../../../../../scene/collision/collision-shape.js";import{takeUntil as d}from"rxjs";import{PhysicsBodyType as y}from"../../../../services/physics/physics-system.js";import{RootMotionClip as u}from"../../../../../gameplay/animation/root-motion.js";const g=new c,S=new c,f=1/30;let v=class extends l{get autoStepMinWidth(){return this.cc.autostepMinWidth()}set autoStepMinWidth(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),t,this.cc.autostepIncludesDynamicBodies())}get autoStepDynamicObjects(){return this.cc.autostepIncludesDynamicBodies()}set autoStepDynamicObjects(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),this.cc.autostepMinWidth(),t)}get autoStepMaxHeight(){return this.cc.autostepMaxHeight()}set autoStepMaxHeight(t){this.cc.enableAutostep(t,this.cc.autostepMinWidth(),this.cc.autostepIncludesDynamicBodies())}get snapToGround(){return this.cc.snapToGroundDistance()}set snapToGround(t){this.cc.enableSnapToGround(t)}constructor(t){super(),this.physicsSystem=t,this.directionInput=new o,this.jumpInput=new e,this.sprintInput=new e,this.rotationInput=new s,this.horizontalSpeed=0,this.maxSpeed=8,this.maxSpeedBackwards=8,this.maxSpeedSprint=12,this.jumpVelocity=7,this.fallingMovementControl=.5,this.fallingReorientation=!1,this.gravityOverride=null,this.colliderHeight=2,this.colliderRadius=.5,this.jumpInAir=!1,this.mass=50,this.allowSliding=!0,this.minSlopeSlideAngle=a.degToRad(70),this.maxSlopeClimbAngle=a.degToRad(70),this.applyImpulsesToDynamicBodies=!0,this.velocity=new c,this.mode=p.walking,this.isSprinting=!1,this.pressedJump=!1,this.rayTestResult=new r,this.resetRootMotion=!1;const i=this.cc=this.physicsSystem.getCharacterController(.1);i.enableSnapToGround(.1),i.enableAutostep(0,.1,!1)}onInit(){const t=this.cc;t.setApplyImpulsesToDynamicBodies(this.applyImpulsesToDynamicBodies),t.setMinSlopeSlideAngle(this.minSlopeSlideAngle),t.setMaxSlopeClimbAngle(this.maxSlopeClimbAngle),t.setCharacterMass(this.mass),t.setSlideEnabled(this.allowSliding),this.physicsSystem.addActor(this.actor,[this.createCollisionShape()],{mass:0,type:y.kinematic,continousCollisionDetection:!0,friction:1}),this.rotationInput.rotation.copy(this.actor.rotation);let i=this.rotationInput.rotation.y;const e=new c,o=new c,s=new c,n=new c,r=new c,l=new c;let h=0,m=null;const v=new c,M=new c,x=new c,I=new c;this.physicsSystem.beforeStep.pipe(d(this.disposed)).subscribe((d=>{if(this.checkGrounded(d),null!=this.rootMotionAction){if(this.rootMotionAction.getClip()instanceof u){const t=this.rootMotionInterpolant;this.resetRootMotion&&(v.fromArray(t.evaluate(0)),this.resetRootMotion=!1),I.fromArray(t.evaluate(this.rootMotionAction.time)),M.subVectors(I,v),v.copy(I),this.rootMotionAction.getRoot().getWorldScale(x),M.multiply(x)}}d>f&&(d=f);const y=null!=this.rootMotionAction&&this.rootMotionAction.enabled&&0!=M.length();this.pressedJump=this.jumpInput.activated,this.isSprinting=this.sprintInput.activated&&this.directionInput.vertical>=0;let T=i-this.rotationInput.rotation.y;i=this.rotationInput.rotation.y,s.copy(this.actor.position),n.set(-this.directionInput.vector.x,0,this.directionInput.vector.y).normalize();const b=n.z<0?this.maxSpeedBackwards:this.isSprinting?this.maxSpeedSprint:this.maxSpeed;l.copy(n).applyAxisAngle(w,this.rotationInput.rotation.y),this.mode===p.walking?(0!==l.length()?(h=Math.min(b,h),h=a.lerp(h,b,4*d)):h=0,r.copy(l).multiplyScalar(h),this.pressedJump&&(this.mode=p.falling,this.velocity.copy(r),this.velocity.y=this.jumpVelocity),r.y=d*this.getEffectiveGravity()):this.mode===p.falling&&(this.pressedJump&&this.jumpInAir&&(this.mode=p.falling,this.velocity.copy(r),this.velocity.y=this.jumpVelocity),this.velocity.y+=d*this.getEffectiveGravity(),r.copy(this.velocity),r.add(l.clone().multiplyScalar(b*this.fallingMovementControl*d)),this.fallingReorientation&&r.applyAxisAngle(new c(0,1,0),-T)),o.copy(r).normalize(),e.copy(r),this.actor.rotation.y-=T,r.length(),y?(M.applyAxisAngle(w,this.actor.rotation.y),M.y+=d*this.getEffectiveGravity(),g.copy(M)):g.copy(r).multiplyScalar(d),this.isGrounded&&this.mode===p.walking&&(g.y=0),S.copy(this.physicsSystem.getActorComputedMovement(this.actor,t,g)),this.physicsSystem.setNextKinematicTranslation(this.actor,S);let j=function(t){if(t.numComputedCollisions()>0){const i=t.computedCollision(0);A.x=i.normal2.x,A.y=i.normal2.y,A.z=i.normal2.z;const e=A.angleTo(w);A.x=i.normal1.x,A.y=i.normal1.y,A.z=i.normal1.z;const o=A.angleTo(w);return!(e<100)&&o>t.minSlopeSlideAngle()}return!1}(t);y||this.isGrounded&&!j||this.mode!==p.falling&&(null==m?m=performance.now():performance.now()-m>100&&(this.mode=p.falling,this.velocity.copy(e))),this.isGrounded&&this.velocity.y<=0&&(this.mode,p.falling,this.mode=p.walking,this.velocity.y=0,m=null),this.mode,p.walking,this.horizontalSpeed=h}))}setRootMotionAction(t){const i=t?.getClip();if(i instanceof u){this.rootMotionAction=t,this.resetRootMotion=!0;const e=[];this.rootMotionInterpolant=i.motionTrack.InterpolantFactoryMethodSmooth(e)}}getWallDirection(t,i){const e=t.clone().negate().cross(w);return e.dot(i)<0?e.negate():e}moveTo(t){this.actor.position.copy(t),this.physicsSystem.updateActorTransform(this.actor)}getEffectiveGravity(){return this.gravityOverride??this.physicsSystem.getGravity().y}checkGrounded(t){const i=this.colliderHeight+2*this.colliderRadius;this.physicsSystem.rayTest(M.addVectors(this.actor.position,I.set(0,i/4,0)),x.addVectors(this.actor.position,T),this.rayTestResult,{excludeActor:this.actor})}get isGrounded(){return this.rayTestResult.hasHit||this.cc.computedGrounded()}createCollisionShape(){const t=new m(this.colliderHeight,this.colliderRadius);return t.offset.y=this.colliderRadius+this.colliderHeight/2,t}step(t){}performMovement(t){}};v=t([h({inEditor:!1}),i("design:paramtypes",[n])],v);export{v as CharacterMovementComponent};const w=new c(0,1,0),A=new c;const M=new c,x=new c,I=new c(0,1,0),T=new c(0,-.1,0);
1
+ import{__decorate as t,__metadata as i}from"tslib";import{ActionInput as e,AxisInput as o,RotationInput as s}from"../../../../../gameplay/input/index.js";import{PhysicsSystem as n,RayTestResult as r}from"../../../../../gameplay/services/physics/physics-system.js";import{MathUtils as c,Vector3 as a}from"three";import{ActorComponent as l,Component as h}from"../../../component.js";import{CharacterMovementMode as p}from"./modes.js";import{CapsuleCollisionShape as m}from"../../../../../scene/collision/collision-shape.js";import{takeUntil as d}from"rxjs";import{PhysicsBodyType as y}from"../../../../services/physics/physics-system.js";import{RootMotionClip as u}from"../../../../../gameplay/animation/root-motion.js";const g=new a,f=new a,S=1/30;let v=class extends l{get autoStepMinWidth(){return this.cc.autostepMinWidth()}set autoStepMinWidth(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),t,this.cc.autostepIncludesDynamicBodies())}get autoStepDynamicObjects(){return this.cc.autostepIncludesDynamicBodies()}set autoStepDynamicObjects(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),this.cc.autostepMinWidth(),t)}get autoStepMaxHeight(){return this.cc.autostepMaxHeight()}set autoStepMaxHeight(t){this.cc.enableAutostep(t,this.cc.autostepMinWidth(),this.cc.autostepIncludesDynamicBodies())}get snapToGround(){return this.cc.snapToGroundDistance()}set snapToGround(t){this.cc.enableSnapToGround(t)}set offset(t){this.cc.setOffset(t)}get offset(){return this.cc.offset()}constructor(t){super(),this.physicsSystem=t,this.directionInput=new o,this.jumpInput=new e,this.sprintInput=new e,this.rotationInput=new s,this.horizontalSpeed=0,this.maxSpeed=8,this.maxSpeedBackwards=8,this.maxSpeedSprint=12,this.jumpVelocity=7,this.fallingMovementControl=.5,this.fallingReorientation=!1,this.gravityOverride=null,this.colliderHeight=2,this.colliderRadius=.5,this.jumpInAir=!1,this.mass=50,this.allowSliding=!0,this.minSlopeSlideAngle=c.degToRad(70),this.maxSlopeClimbAngle=c.degToRad(70),this.applyImpulsesToDynamicBodies=!0,this.velocity=new a,this.mode=p.walking,this.isSprinting=!1,this.pressedJump=!1,this.rayTestResult=new r,this.resetRootMotion=!1;const i=this.cc=this.physicsSystem.getCharacterController(.1);i.enableSnapToGround(.1),i.enableAutostep(0,.1,!1)}onInit(){const t=this.cc;t.setApplyImpulsesToDynamicBodies(this.applyImpulsesToDynamicBodies),t.setMinSlopeSlideAngle(this.minSlopeSlideAngle),t.setMaxSlopeClimbAngle(this.maxSlopeClimbAngle),t.setCharacterMass(this.mass),t.setSlideEnabled(this.allowSliding),this.physicsSystem.addActor(this.actor,[this.createCollisionShape()],{mass:0,type:y.kinematic,continousCollisionDetection:!0,friction:1}),this.rotationInput.rotation.copy(this.actor.rotation);let i=this.rotationInput.rotation.y;const e=new a,o=new a,s=new a,n=new a,r=new a,l=new a;let h=0,m=null;const v=new a,M=new a,x=new a,I=new a;this.physicsSystem.beforeStep.pipe(d(this.disposed)).subscribe((d=>{if(this.checkGrounded(d),null!=this.rootMotionAction){if(this.rootMotionAction.getClip()instanceof u){const t=this.rootMotionInterpolant;this.resetRootMotion&&(v.fromArray(t.evaluate(0)),this.resetRootMotion=!1),I.fromArray(t.evaluate(this.rootMotionAction.time)),M.subVectors(I,v),v.copy(I),this.rootMotionAction.getRoot().getWorldScale(x),M.multiply(x)}}d>S&&(d=S);const y=null!=this.rootMotionAction&&this.rootMotionAction.enabled&&0!=M.length();this.pressedJump=this.jumpInput.activated,this.isSprinting=this.sprintInput.activated&&this.directionInput.vertical>=0;let T=i-this.rotationInput.rotation.y;i=this.rotationInput.rotation.y,s.copy(this.actor.position),n.set(-this.directionInput.vector.x,0,this.directionInput.vector.y).normalize();const b=n.z<0?this.maxSpeedBackwards:this.isSprinting?this.maxSpeedSprint:this.maxSpeed;l.copy(n).applyAxisAngle(w,this.rotationInput.rotation.y),this.mode===p.walking?(0!==l.length()?(h=Math.min(b,h),h=c.lerp(h,b,4*d)):h=0,r.copy(l).multiplyScalar(h),this.pressedJump&&(this.mode=p.falling,this.velocity.copy(r),this.velocity.y=this.jumpVelocity),r.y=d*this.getEffectiveGravity()):this.mode===p.falling&&(this.pressedJump&&this.jumpInAir&&(this.mode=p.falling,this.velocity.copy(r),this.velocity.y=this.jumpVelocity),this.velocity.y+=d*this.getEffectiveGravity(),r.copy(this.velocity),r.add(l.clone().multiplyScalar(b*this.fallingMovementControl*d)),this.fallingReorientation&&r.applyAxisAngle(new a(0,1,0),-T)),o.copy(r).normalize(),e.copy(r),this.actor.rotation.y-=T,r.length(),y?(M.applyAxisAngle(w,this.actor.rotation.y),M.y+=d*this.getEffectiveGravity(),g.copy(M)):g.copy(r).multiplyScalar(d),this.isGrounded&&this.mode===p.walking&&(g.y=0),f.copy(this.physicsSystem.getActorComputedMovement(this.actor,t,g)),this.physicsSystem.setNextKinematicTranslation(this.actor,f);let j=function(t){if(t.numComputedCollisions()>0){const i=t.computedCollision(0);A.x=i.normal2.x,A.y=i.normal2.y,A.z=i.normal2.z;const e=A.angleTo(w);A.x=i.normal1.x,A.y=i.normal1.y,A.z=i.normal1.z;const o=A.angleTo(w);return!(e<100)&&o>t.minSlopeSlideAngle()}return!1}(t);y||this.isGrounded&&!j||this.mode!==p.falling&&(null==m?m=performance.now():performance.now()-m>100&&(this.mode=p.falling,this.velocity.copy(e))),this.isGrounded&&this.velocity.y<=0&&(this.mode,p.falling,this.mode=p.walking,this.velocity.y=0,m=null),this.mode,p.walking,this.horizontalSpeed=h}))}setRootMotionAction(t){const i=t?.getClip();if(i instanceof u){this.rootMotionAction=t,this.resetRootMotion=!0;const e=[];this.rootMotionInterpolant=i.motionTrack.InterpolantFactoryMethodSmooth(e)}}getWallDirection(t,i){const e=t.clone().negate().cross(w);return e.dot(i)<0?e.negate():e}moveTo(t){this.actor.position.copy(t),this.physicsSystem.updateActorTransform(this.actor)}getEffectiveGravity(){return this.gravityOverride??this.physicsSystem.getGravity().y}checkGrounded(t){const i=this.colliderHeight+2*this.colliderRadius;this.physicsSystem.rayTest(M.addVectors(this.actor.position,I.set(0,i/4,0)),x.addVectors(this.actor.position,T),this.rayTestResult,{excludeActor:this.actor})}get isGrounded(){return this.rayTestResult.hasHit||this.cc.computedGrounded()}createCollisionShape(){const t=new m(this.colliderHeight,this.colliderRadius);return t.offset.y=this.colliderRadius+this.colliderHeight/2,t}step(t){}performMovement(t){}};v=t([h({inEditor:!1}),i("design:paramtypes",[n])],v);export{v as CharacterMovementComponent};const w=new a(0,1,0),A=new a;const M=new a,x=new a,I=new a(0,1,0),T=new a(0,-.1,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{__decorate as t,__metadata as e}from"tslib";import*as i from"@dimforge/rapier3d-compat";import{QueryFilterFlags as s}from"@dimforge/rapier3d-compat";import{BehaviorSubject as o,distinctUntilChanged as r,filter as n,map as a,Subject as c,takeUntil as l}from"rxjs";import*as d from"three";import{ArrowHelper as h,BufferAttribute as u,BufferGeometry as y,Group as p,LineSegments as g,Matrix4 as m,MeshBasicMaterial as f,Object3D as w,Quaternion as v,Raycaster as x,Scene as b,Vector3 as B}from"three";import{Service as A}from"typedi";import{AssetMeshInstance as C}from"../../../scene/asset-resource-loader.js";import{BoxCollisionShape as D,CapsuleCollisionShape as z,ConeCollisionShape as T,ConvexPolyhedronCollisionShape as M,CylinderCollisionShape as E,PhysicalShapeMesh as S,PlaneCollisionShape as R,SphereCollisionShape as W,TrimeshCollisionShape as _}from"../../../index.js";import{LandscapeGroup as V}from"../../../scene/landscape/landscape.js";import{ViewController as F}from"../render.js";import{World as P}from"../world.js";import*as k from"three/examples/jsm/utils/BufferGeometryUtils.js";import{calculateEffectiveScale as I}from"../../../utils/three/traverse.js";export class RayTestResult{constructor(){this.hasHit=!1,this.hitPoint=new B,this.hitNormal=new B}}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 L=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 c,this.beforeStep=new c,this.afterStep=new c,this.shouldRenderDebug=!1,this._raycaster=new x,this._reusableResult=new RayTestResult,this._raytestDiff=new B,this._raytestDirection=new B,this.controlledActors=new Set,this.ready=this.setup()}createDebugMesh(){return new g(new y,new f({color:255}))}async start(){return await 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 u(t.vertices,3))}async setup(){if(null!=this.rapier)throw new Error("Rapier is already estup");this.rapier=await U(),this.eventQueue=new i.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=>{if(t.isFixed())return;const e=this.staticMeshes.get(t)??this.bodyActors.get(t)?.object;var i,s;null!=e&&(e.parent instanceof b&&(X(e.position,t.translation()),(t.isDynamic()||t.isKinematic()&&!this.controlledActors.has(this.bodyActors.get(t)?.id))&&(i=e.quaternion,s=t.rotation(),i.x=s.x,i.y=s.y,i.z=s.z,i.w=s.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(H,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,s,o){null==s&&(s=this._reusableResult);const r=this._raytestDiff,n=this._raytestDirection;if(r.subVectors(e,t),n.copy(r).normalize(),0===n.length())return console.warn("Ray test called with to and from being equal"),s;const a=new i.Ray(t,n),c=r.length(),l=this.world.castRayAndGetNormal(a,c,!1,void 0,void 0,void 0,null!=o?.excludeActor?this.actorBodies.get(o.excludeActor.id):void 0);if(s.hasHit=null!=l,s.hasHit){const e=a.pointAt(l.toi);s._internal=l,X(s.hitNormal,l.normal),X(s.hitPoint,e),s.distance=Y.subVectors(s.hitPoint,t).length();const i=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===l.collider))));s.actor=null!=i?this.bodyActors.get(i):null}if(this.showDebug){const e=new h(n,t,c,o?.debugColor??255);this.gameWorld.scene.add(e),setTimeout((()=>this.gameWorld.scene.remove(e)),o?.debugLifetime??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 q.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())J(t,(t=>t.setActiveEvents(i.ActiveEvents.COLLISION_EVENTS)))}addRecursively(t){if(this.removeSceneObject(t),!function(t){if(null!=t.userData?.src){const e=t.userData?.src;return"actor"===e.type}return!1}(t))if(t instanceof S&&null!=t.collisionShape){const e=this.createStaticBody(t,[t.collisionShape]);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else if(t instanceof C&&!1!==t.userData?.src?.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 V?this.addLandscapeGroup(t):(t instanceof p||t instanceof b)&&t.children.forEach((t=>this.addRecursively(t)))}createForInstancedMesh(t,e){const i=new m;for(let s=0;s<t.count;s++){const o=new w;o.matrix.identity(),i.fromArray(t.instanceMatrix.array,16*s),o.applyMatrix4(i);this.createStaticBody(o,e)}}getCharacterController(t=.01){return this.world?.createCharacterController(t)}getActorComputedMovement(t,e,i){const o=this.actorBodies.get(t.id);this.controlledActors.add(t.id);const r=o.collider(0);e.computeColliderMovement(r,i,s.EXCLUDE_SENSORS,null,$);const n=e.computedMovement();return X(Z,n),Z}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,i?.setNextKinematicTranslation(s)}setAngularVelocity(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.setAngvel(G,!0)}setLinearVelocity(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.setLinvel(G,!0)}getLinearVelocity(t,e=new B){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 B){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);i?.setLinearDamping(e)}setAngularDamping(t,e){const i=this.actorBodies.get(t.id);i?.setAngularDamping(e)}createCharacterCollision(){return new i.CharacterCollision}addLandscapeGroup(t){const e=t.userData.src,s=e.landscape.heightMaps;for(const r of t.sections){this.staticBodies.has(r)&&this.world.removeRigidBody(this.staticBodies.get(r));const t=e.landscape.options.density+1,n=e.landscape.options.sectionSize,a=new Array(t);for(let e=0;e<t;e++)a[e]=new Array(t).fill(0);const c=s.find((t=>t.x===r.x&&t.y==r.y));if(null!=c)for(const e of c.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/n:console.warn("wrong index",{points:a,point:e,i:e.i%t,k:i,heightMap:c})}const l=e.landscape.options.density,d=a.flatMap((t=>t.reverse())),h=i.ColliderDesc.heightfield(l,l,new Float32Array(d),new i.Vector3(n,n,n));var o=r.getWorldPosition(new B);const u=this.world.createRigidBody(i.RigidBodyDesc.fixed()),y=new i.Vector3(0,0,0);K(y,o),u.setTranslation(y,!1),this.world.createCollider(h,u),this.staticBodies.set(r,u)}}addActor(t,e,s={}){if(0==e.length)return void console.error("No collision shapes were defined when adding actor to the physics system.");this.removeActor(t);const o=t.object;let r;switch(s.type??PhysicsBodyType.static){case PhysicsBodyType.dynamic:r=i.RigidBodyDesc.dynamic(),r.mass=s.mass??1;break;case PhysicsBodyType.kinematic:r=i.RigidBodyDesc.kinematicPositionBased();break;case PhysicsBodyType.kinematicVelocityBased:r=i.RigidBodyDesc.kinematicVelocityBased();break;default:r=(s.isTrigger,i.RigidBodyDesc.kinematicVelocityBased())}const n=this.world.createRigidBody(r);n.enableCcd(1==s.continousCollisionDetection);for(const t of e)this.addShape(n,t,o);J(n,(t=>{null!=s.isTrigger&&(t.setSensor(s.isTrigger),t.setActiveCollisionTypes(i.ActiveCollisionTypes.ALL),t.setActiveEvents(i.ActiveEvents.COLLISION_EVENTS)),null!=s.friction&&t.setFriction(s.friction),null!=s.restitution&&t.setDensity(s.restitution),null!=s.mass&&t.setMass(s.mass),null!=s.restitution&&t.setRestitution(s.restitution)})),N(n,o),this.actorBodies.set(t.id,n),this.bodyActors.set(n,t)}applyTorque(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.addTorque(G,!0)}applyTorqueImpulse(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.applyTorqueImpulse(G,!0)}resetForces(t){const e=this.actorBodies.get(t.id);e?.resetForces(!1)}resetTorques(t){const e=this.actorBodies.get(t.id);e?.resetTorques(!1)}applyForce(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.addForce(G,!0)}applyImpulse(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.applyImpulse(G,!0)}applyLocalForce(t,e,i){const s=this.actorBodies.get(t.id);K(G,e),null==i?s?.addForce(G,!0):(K(Q,i),s?.addForceAtPoint(G,Q,!0))}applyLocalImpulse(t,e,i){const s=this.actorBodies.get(t.id);K(G,e),null==i?s.applyImpulse(G,!0):(K(Q,i),s.applyImpulseAtPoint(G,Q,!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(l(t.disposed),n((({started:t})=>t===i)),a((({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}))),n((({a1:i,a2:s})=>null!=i&&null!=s&&i.id===t.id&&e(i,s))),a((({a2:t})=>t)))}onBeginContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(l(t.disposed),n((t=>t.started)),n((({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e).parent());return null!=i&&i.id===t.id})),a((t=>t.handle2)))}onEndContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(l(t.disposed),n((t=>!t.started)),n((({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e).parent());return null!=i&&i.id===t.id})),a((t=>t.handle2)))}onHasContactChanged(t){const e=new Set,i=new o(!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(r())}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?N(e,t.object):console.warn("Actor has not been added to physics world",t)}setupWorld(){const t=new i.World({x:0,y:-9.81,z:0});this.world=t,t.maxVelocityIterations=4}getActorContacts(t,e){const s=this.actorBodies.get(t.id);if(s&&s.numColliders()>0){const o=s.collider(0);let r=o.shape,n=o.translation(),a=o.rotation(),c=e,l=.3;const d=this.world.castShape(n,a,c,r,l,!0,null,null,null,this.actorBodies.get(t.id),(t=>t.shape.type!=i.ShapeType.HeightField));if(null!=d){const t=new B,e=new B,i=new B;return X(t,d.witness2),X(e,d.witness1),X(i,d.normal1),i.negate(),[{ri:t,rj:e,ni:i}]}return[]}return console.warn("Actor is not added to the physics system"),[]}stop(){this.world?.bodies.forEach((t=>this.world.removeRigidBody(t))),this.world?.free(),this.fixedupdateSub?.unsubscribe()}createStaticBody(t,e){const s=this.world.createRigidBody(i.RigidBodyDesc.kinematicPositionBased());for(const i of e)this.addShape(s,i,t);return N(s,t),s}addShape(t,e,i){const s=this.createShape(e,i.scale);s.friction=.1;const o=e.offset.clone().multiply(i.scale);var r,n;K(s.translation,o),r=s.rotation,n=(new v).setFromEuler(e.rotation),r.x=n.x,r.y=n.y,r.z=n.z,r.w=n.w;this.world.createCollider(s,t)}createShape(t,e){if(t instanceof D)return i.ColliderDesc.cuboid(t.dimensions.x*e.x/2,t.dimensions.y*e.y/2,t.dimensions.z*e.z/2);if(t instanceof z){return i.ColliderDesc.capsule(t.length/2*e.y,t.radius*Math.max(e.z,e.x))}if(t instanceof _){const e=null!=t.geometry.getIndex()?t.geometry:k.mergeVertices(t.geometry);return i.ColliderDesc.trimesh(new Float32Array(e.getAttribute("position").array),new Uint32Array(e.getIndex().array))}if(t instanceof M){let s;t.mesh instanceof d.Mesh?s=t.mesh.geometry:t.mesh instanceof d.BufferGeometry?s=t.mesh:console.log("Unknownd shape",{shapeInfo:t});const o=new Float32Array(s.getAttribute("position").array);if(t.mesh instanceof d.Mesh){const e=I(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 i.ColliderDesc.convexHull(o)}return t instanceof W?i.ColliderDesc.ball(t.radius*Math.max(e.x,e.y,e.z)):t instanceof E?i.ColliderDesc.cylinder(t.height/2*e.y,t.radiusTop*Math.max(e.z,e.x)):t instanceof T?i.ColliderDesc.cone(t.height*e.y,t.radiusBottom/2*Math.max(e.z,e.x)):t instanceof R?i.ColliderDesc.cuboid(t.width/2*e.x,t.height/2*e.y,.01):(console.error("Unsupported shape",t),i.ColliderDesc.cuboid(1,1,1))}};L=t([A(),e("design:paramtypes",[F,P])],L);export{L as PhysicsSystem};const j=new B,O=new d.Quaternion;function N(t,e){const s=e.getWorldPosition(j),o=e.getWorldQuaternion(O);t.setTranslation(new i.Vector3(s.x,s.y,s.z),!1),t.setRotation(new i.Quaternion(o.x,o.y,o.z,o.w),!1)}const q=new B,G=new i.Vector3(0,0,0),Q=new i.Vector3(0,0,0),H=(new B,{x:0,y:0}),U=async()=>{let t=await import("@dimforge/rapier3d-compat");return await t.init(),t};function K(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function X(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function J(t,e){for(let i=0,s=t.numColliders();i<s;i++){e(t.collider(i))}}const Y=new B,Z=new B,$=t=>!t.isSensor();
1
+ import{__decorate as t,__metadata as e}from"tslib";import*as i from"@dimforge/rapier3d-compat";import{QueryFilterFlags as s}from"@dimforge/rapier3d-compat";import{BehaviorSubject as o,distinctUntilChanged as n,filter as r,map as a,Subject as c,takeUntil as l}from"rxjs";import*as d from"three";import{ArrowHelper as h,BufferAttribute as u,BufferGeometry as y,Group as p,LineSegments as g,Matrix4 as m,MeshBasicMaterial as f,Object3D as w,Quaternion as v,Raycaster as x,Scene as B,Vector3 as b}from"three";import{Service as A}from"typedi";import{AssetMeshInstance as C}from"../../../scene/asset-resource-loader.js";import{BoxCollisionShape as D,CapsuleCollisionShape as z,ConeCollisionShape as T,ConvexPolyhedronCollisionShape as M,CylinderCollisionShape as R,PhysicalShapeMesh as E,PlaneCollisionShape as S,SphereCollisionShape as W,TrimeshCollisionShape as _}from"../../../index.js";import{LandscapeGroup as F}from"../../../scene/landscape/landscape.js";import{ViewController as V}from"../render.js";import{World as P}from"../world.js";import*as k from"three/examples/jsm/utils/BufferGeometryUtils.js";import{calculateEffectiveScale as I}from"../../../utils/three/traverse.js";export class RayTestResult{constructor(){this.hasHit=!1,this.hitPoint=new b,this.hitNormal=new b}}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 L=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 c,this.beforeStep=new c,this.afterStep=new c,this.shouldRenderDebug=!1,this._raycaster=new x,this._reusableResult=new RayTestResult,this._raytestDiff=new b,this._raytestDirection=new b,this.controlledActors=new Set,this.ready=this.setup()}createDebugMesh(){return new g(new y,new f({color:255}))}async start(){return await 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 u(t.vertices,3))}async setup(){if(null!=this.rapier)throw new Error("Rapier is already estup");this.rapier=await U(),this.eventQueue=new i.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=>{if(t.isFixed())return;const e=this.staticMeshes.get(t)??this.bodyActors.get(t)?.object;var i,s;null!=e&&(e.parent instanceof B&&(X(e.position,t.translation()),(t.isDynamic()||t.isKinematic()&&!this.controlledActors.has(this.bodyActors.get(t)?.id))&&(i=e.quaternion,s=t.rotation(),i.x=s.x,i.y=s.y,i.z=s.z,i.w=s.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(H,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,s,o){null==s&&(s=this._reusableResult);const n=this._raytestDiff,r=this._raytestDirection;if(n.subVectors(e,t),r.copy(n).normalize(),0===r.length())return console.warn("Ray test called with to and from being equal"),s;const a=new i.Ray(t,r),c=n.length(),l=this.world.castRayAndGetNormal(a,c,!1,void 0,void 0,void 0,null!=o?.excludeActor?this.actorBodies.get(o.excludeActor.id):void 0);if(s.hasHit=null!=l,s.hasHit){const e=a.pointAt(l.toi);s._internal=l,X(s.hitNormal,l.normal),X(s.hitPoint,e),s.distance=Y.subVectors(s.hitPoint,t).length();const i=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===l.collider))));s.actor=null!=i?this.bodyActors.get(i):null}if(this.showDebug){const e=new h(r,t,c,o?.debugColor??255);this.gameWorld.scene.add(e),setTimeout((()=>this.gameWorld.scene.remove(e)),o?.debugLifetime??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 q.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())J(t,(t=>t.setActiveEvents(i.ActiveEvents.COLLISION_EVENTS)))}addRecursively(t){if(this.removeSceneObject(t),!function(t){if(null!=t.userData?.src){const e=t.userData?.src;return"actor"===e.type}return!1}(t))if(t instanceof E&&null!=t.collisionShape){const e=this.createStaticBody(t,[t.collisionShape],t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else if(t instanceof C&&!1!==t.userData?.src?.collisionDetection)if(t.children[0]&&t.children[0].instanceMatrix)this.createForInstancedMesh(t.children[0],t.collisionShapes);else{const e=this.createStaticBody(t,t.collisionShapes,t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else t instanceof F?this.addLandscapeGroup(t):(t instanceof p||t instanceof B)&&t.children.forEach((t=>this.addRecursively(t)))}createForInstancedMesh(t,e){const i=new m;for(let s=0;s<t.count;s++){const o=new w;o.matrix.identity(),i.fromArray(t.instanceMatrix.array,16*s),o.applyMatrix4(i);this.createStaticBody(o,e)}}getCharacterController(t=.01){return this.world?.createCharacterController(t)}getActorComputedMovement(t,e,i){const o=this.actorBodies.get(t.id);this.controlledActors.add(t.id);const n=o.collider(0);e.computeColliderMovement(n,i,s.EXCLUDE_SENSORS,null,$);const r=e.computedMovement();return X(Z,r),Z}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,i?.setNextKinematicTranslation(s)}setAngularVelocity(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.setAngvel(G,!0)}setLinearVelocity(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.setLinvel(G,!0)}getLinearVelocity(t,e=new b){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 b){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);i?.setLinearDamping(e)}setAngularDamping(t,e){const i=this.actorBodies.get(t.id);i?.setAngularDamping(e)}createCharacterCollision(){return new i.CharacterCollision}addLandscapeGroup(t){const e=t.userData.src,s=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 c=s.find((t=>t.x===n.x&&t.y==n.y));if(null!=c)for(const e of c.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:c})}const l=e.landscape.options.density,d=a.flatMap((t=>t.reverse())),h=i.ColliderDesc.heightfield(l,l,new Float32Array(d),new i.Vector3(r,r,r));var o=n.getWorldPosition(new b);const u=this.world.createRigidBody(i.RigidBodyDesc.fixed()),y=new i.Vector3(0,0,0);K(y,o),u.setTranslation(y,!1),this.world.createCollider(h,u),this.staticBodies.set(n,u)}}addActor(t,e,s={}){if(0==e.length)return void console.error("No collision shapes were defined when adding actor to the physics system.");this.removeActor(t);const o=t.object;let n;switch(s.type??PhysicsBodyType.static){case PhysicsBodyType.dynamic:n=i.RigidBodyDesc.dynamic(),n.mass=s.mass??1;break;case PhysicsBodyType.kinematic:n=i.RigidBodyDesc.kinematicPositionBased();break;case PhysicsBodyType.kinematicVelocityBased:n=i.RigidBodyDesc.kinematicVelocityBased();break;default:n=(s.isTrigger,i.RigidBodyDesc.kinematicVelocityBased())}const r=this.world.createRigidBody(n);r.enableCcd(1==s.continousCollisionDetection);for(const t of e)this.addShape(r,t,o);J(r,(t=>{null!=s.isTrigger&&(t.setSensor(s.isTrigger),t.setActiveCollisionTypes(i.ActiveCollisionTypes.ALL),t.setActiveEvents(i.ActiveEvents.COLLISION_EVENTS)),null!=s.friction&&t.setFriction(s.friction),null!=s.density&&t.setDensity(s.density),null!=s.mass&&t.setMass(s.mass),null!=s.restitution&&t.setRestitution(s.restitution)})),N(r,o),this.actorBodies.set(t.id,r),this.bodyActors.set(r,t)}applyTorque(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.addTorque(G,!0)}applyTorqueImpulse(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.applyTorqueImpulse(G,!0)}resetForces(t){const e=this.actorBodies.get(t.id);e?.resetForces(!1)}resetTorques(t){const e=this.actorBodies.get(t.id);e?.resetTorques(!1)}applyForce(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.addForce(G,!0)}applyImpulse(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.applyImpulse(G,!0)}applyLocalForce(t,e,i){const s=this.actorBodies.get(t.id);K(G,e),null==i?s?.addForce(G,!0):(K(Q,i),s?.addForceAtPoint(G,Q,!0))}applyLocalImpulse(t,e,i){const s=this.actorBodies.get(t.id);K(G,e),null==i?s.applyImpulse(G,!0):(K(Q,i),s.applyImpulseAtPoint(G,Q,!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(l(t.disposed),r((({started:t})=>t===i)),a((({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}))),r((({a1:i,a2:s})=>null!=i&&null!=s&&i.id===t.id&&e(i,s))),a((({a2:t})=>t)))}onBeginContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(l(t.disposed),r((t=>t.started)),r((({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e).parent());return null!=i&&i.id===t.id})),a((t=>t.handle2)))}onEndContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(l(t.disposed),r((t=>!t.started)),r((({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e).parent());return null!=i&&i.id===t.id})),a((t=>t.handle2)))}onHasContactChanged(t){const e=new Set,i=new o(!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(n())}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?N(e,t.object):console.warn("Actor has not been added to physics world",t)}setupWorld(){const t=new i.World({x:0,y:-9.81,z:0});this.world=t,t.maxVelocityIterations=4}getActorContacts(t,e){const s=this.actorBodies.get(t.id);if(s&&s.numColliders()>0){const o=s.collider(0);let n=o.shape,r=o.translation(),a=o.rotation(),c=e,l=.3;const d=this.world.castShape(r,a,c,n,l,!0,null,null,null,this.actorBodies.get(t.id),(t=>t.shape.type!=i.ShapeType.HeightField));if(null!=d){const t=new b,e=new b,i=new b;return X(t,d.witness2),X(e,d.witness1),X(i,d.normal1),i.negate(),[{ri:t,rj:e,ni:i}]}return[]}return console.warn("Actor is not added to the physics system"),[]}stop(){this.world?.bodies.forEach((t=>this.world.removeRigidBody(t))),this.world?.free(),this.fixedupdateSub?.unsubscribe()}createStaticBody(t,e,s){const o=s?.type===PhysicsBodyType.dynamic?i.RigidBodyDesc.dynamic():i.RigidBodyDesc.kinematicPositionBased(),n=this.world.createRigidBody(o);for(const i of e){const o=this.addShape(n,i,t);null!=s?.friction&&o.setFriction(s.friction),null!=s?.density&&o.setDensity(s.density),null!=s?.mass&&o.setMass(s.mass/e.length),null!=s?.restitution&&o.setRestitution(s.restitution)}return N(n,t),n}addShape(t,e,i){const s=this.createShape(e,i.scale);s.friction=.1;const o=e.offset.clone().multiply(i.scale);var n,r;return K(s.translation,o),n=s.rotation,r=(new v).setFromEuler(e.rotation),n.x=r.x,n.y=r.y,n.z=r.z,n.w=r.w,this.world.createCollider(s,t)}createShape(t,e){if(t instanceof D)return i.ColliderDesc.cuboid(t.dimensions.x*e.x/2,t.dimensions.y*e.y/2,t.dimensions.z*e.z/2);if(t instanceof z){return i.ColliderDesc.capsule(t.length/2*e.y,t.radius*Math.max(e.z,e.x))}if(t instanceof _){const e=null!=t.geometry.getIndex()?t.geometry:k.mergeVertices(t.geometry);return i.ColliderDesc.trimesh(new Float32Array(e.getAttribute("position").array),new Uint32Array(e.getIndex().array))}if(t instanceof M){let s;t.mesh instanceof d.Mesh?s=t.mesh.geometry:t.mesh instanceof d.BufferGeometry?s=t.mesh:console.log("Unknownd shape",{shapeInfo:t});const o=new Float32Array(s.getAttribute("position").array);if(t.mesh instanceof d.Mesh){const e=I(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 i.ColliderDesc.convexHull(o)}return t instanceof W?i.ColliderDesc.ball(t.radius*Math.max(e.x,e.y,e.z)):t instanceof R?i.ColliderDesc.cylinder(t.height/2*e.y,t.radiusTop*Math.max(e.z,e.x)):t instanceof T?i.ColliderDesc.cone(t.height*e.y,t.radiusBottom/2*Math.max(e.z,e.x)):t instanceof S?i.ColliderDesc.cuboid(t.width/2*e.x,t.height/2*e.y,.01):(console.error("Unsupported shape",t),i.ColliderDesc.cuboid(1,1,1))}};L=t([A(),e("design:paramtypes",[V,P])],L);export{L as PhysicsSystem};const j=new b,O=new d.Quaternion;function N(t,e){const s=e.getWorldPosition(j),o=e.getWorldQuaternion(O);t.setTranslation(new i.Vector3(s.x,s.y,s.z),!1),t.setRotation(new i.Quaternion(o.x,o.y,o.z,o.w),!1)}const q=new b,G=new i.Vector3(0,0,0),Q=new i.Vector3(0,0,0),H=(new b,{x:0,y:0}),U=async()=>{let t=await import("@dimforge/rapier3d-compat");return await t.init(),t};function K(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function X(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function J(t,e){for(let i=0,s=t.numColliders();i<s;i++){e(t.collider(i))}}const Y=new b,Z=new b,$=t=>!t.isSensor();
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -54,6 +54,7 @@ export declare class RenderingView {
54
54
  clearOverlayCameras(): void;
55
55
  removeOverlayCamera(camera: Camera): void;
56
56
  private prevClearColor;
57
+ private hadBloom;
57
58
  render(deltaTime?: number): void;
58
59
  private bloomStoredMaterials;
59
60
  private hasBloom;
package/dist/rendering.js CHANGED
@@ -1,4 +1,4 @@
1
- var e;import{__decorate as t,__metadata as i}from"tslib";import*as s from"three";import{Mesh as r,Matrix4 as n,ShaderMaterial as a,Color as o,PerspectiveCamera as h,ShaderChunk as l}from"three";import{EffectComposer as d,UnrealBloomPass as c,VRButton as m}from"three-stdlib";import{RenderPass as p}from"three-stdlib";import{ShaderPass as u}from"three-stdlib";import{FXAAShader as g}from"three-stdlib";import{CSM as v}from"three-stdlib";import{CSMUtil as f}from"./csm.js";import{GammaCorrectionShader as w}from"three-stdlib";import{Reflector as b}from"three-stdlib";import{depthUniformName as x,resolutionUniformName as C,supportsDepthTextureExtension as S,nearUniformName as y,farUniformName as P}from"./shader-nodes/depth.js";import{elapsedTimeUniformName as T}from"./shader-nodes/time.js";import{OutlinePass as R}from"./utils/three/outline-pass.js";import M from"./utils/three/stats.js";import{findFirstVisibleObject as W}from"./utils/three/traverse.js";import{lambertVertexShaderOverride as L}from"./rendering/shader-override.js";import{DepthPass as E}from"./utils/three/depth-pass.js";import{Service as H}from"typedi";(new s.Layers).set(9);const D=new s.MeshBasicMaterial({color:"black"}),F=new s.MeshDepthMaterial;F.depthPacking=s.RGBADepthPacking,F.blending=s.NoBlending;l.lights_pars_begin;l.lights_lambert_vertex=L;const B=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let z=e=class{setPaused(e){this.paused=e}resizeRender(){this.previousClientWith===this.container.clientWidth&&this.previousClientHeight===this.container.clientHeight||(this.camera instanceof h&&(this.camera.aspect=this.container.clientWidth/this.container.clientHeight,this.camera.updateProjectionMatrix()),this.renderer.setPixelRatio(window.devicePixelRatio*this.resolutionScale),this.renderer.setSize(this.container.clientWidth,this.container.clientHeight),this.composer.setSize(this.container.clientWidth*this.resolutionScale,this.container.clientHeight*this.resolutionScale),this.previousClientWith=this.container.clientWidth,this.previousClientHeight=this.container.clientHeight)}constructor(t,i={}){this.container=t,this.options=i,this.windowVisible=!0,this.running=!0,this.paused=!1,this.fpsCap=null,this.resolutionScale=B?.5:1,this.onResize=()=>{this.resizeRender(),this.paused||this.render()},this.onVisiblityChane=()=>{this.windowVisible=!document.hidden},this.isDepthTextureExtensionSupported=!1,this.onLoopCallbacks=[],this.stats=M(),this._showStats=!1,this.insetHeight=200,this.insetWidth=this.insetHeight*(16/9),this.insetOffsetY=250,this.insetMargin=10,this.maxInsetCameras=4,this.overlayCameras=new Set,this.prevClearColor=new o,this.bloomStoredMaterials={},window.renderer=this.renderer=new s.WebGLRenderer({antialias:!0,powerPreference:"high-performance"}),this.scene=new s.Scene,this.renderer.setPixelRatio(window.devicePixelRatio*this.resolutionScale),this.renderer.setSize(t.clientWidth,t.clientHeight),this.renderer.xr.enabled=this.options.enableXR??!1,!0===this.options.enableXR&&document.body.appendChild(m.createButton(this.renderer)),this.composer=new d(this.renderer);var r=t.clientWidth/t.clientHeight;const n=new s.PerspectiveCamera(45,r,.5,800);n.layers.enable(19),this.setCamera(n),this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=s.PCFSoftShadowMap,this.renderer.shadowMap.autoUpdate=!1,this.renderer.outputEncoding=s.sRGBEncoding,this.renderer.physicallyCorrectLights=!1,this.renderer.gammaFactor=1.4,f.renderingView=this,f.patchThreeAdd(),this.isDepthTextureExtensionSupported=S(this.renderer),t.replaceChildren(this.renderer.domElement),this.setupEventListeners(),this.depthRenderTarget=e.createDepthRenderTarget(this.renderer,this.container);const a=new p(this.scene,this.camera);this.composer.addPass(a);const h=new c(new s.Vector2(t.clientWidth,t.clientHeight),1.5,.4,.85);h.threshold=0,h.strength=.9,h.radius=1;const l=new d(this.renderer);l.renderToScreen=!1,l.addPass(a),l.addPass(h),this.bloomComposer=l;const v=new u(new s.ShaderMaterial({uniforms:{baseTexture:{value:null},bloomTexture:{value:l.renderTarget2.texture}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }",fragmentShader:"\n uniform sampler2D baseTexture;\n uniform sampler2D bloomTexture;\n varying vec2 vUv;\n void main() {\n gl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) );\n }",defines:{}}),"baseTexture");if(v.needsSwap=!0,this.composer.addPass(v),this.outlinePass=new R(new s.Vector2(t.clientWidth,t.clientHeight),this.scene,this.camera),!0===i.enableOutlines){this.outlinePass.edgeThickness=0,this.outlinePass.edgeGlow=0,this.outlinePass.edgeThickness=1.5,this.outlinePass.edgeStrength=5,this.outlinePass.clear=!1,this.composer.addPass(this.outlinePass);const e=new u(g);e.uniforms.resolution.value.set(1/t.clientWidth,1/t.clientHeight),this.composer.addPass(e)}var b=new u(w);b.clear=!1,this.composer.addPass(b)}setCamera(e){this.camera=e,this.composer.passes.forEach((t=>{t instanceof p?t.camera=e:t instanceof R?t.renderCamera=e:t instanceof E&&(t.camera=e)})),null==this.csm?this.csm=new v({maxFar:200,lightFar:300,cascades:5,shadowMapSize:2048,lightDirection:new s.Vector3(.5,-1,-.6).normalize(),lightIntensity:.5,camera:this.camera,parent:this.scene}):(this.csm.camera=this.camera,this.camera instanceof h&&(this.csm.maxFar=this.camera.far)),this.csm.updateFrustums()}setSelectedObjects(e){const t=new Map;for(const i of e)t.set(i.uuid,i);for(const i of e)i.traverse((e=>{e.uuid!==i.uuid&&t.has(e.uuid)&&t.delete(e.uuid)}));this.outlinePass.selectedObjects=Array.from(t.values())}static createDepthRenderTarget(e,t){var i=!!e.extensions.get("WEBGL_depth_texture");const r=new s.WebGLRenderTarget(t.clientWidth*e.getPixelRatio(),t.clientHeight*e.getPixelRatio());return r.texture.minFilter=s.NearestFilter,r.texture.magFilter=s.NearestFilter,r.texture.generateMipmaps=!1,r.stencilBuffer=!1,!0===i&&(r.depthTexture=new s.DepthTexture(128,128),r.depthTexture.type=s.UnsignedShortType,r.depthTexture.minFilter=s.NearestFilter,r.depthTexture.magFilter=s.NearestFilter),r}setupEventListeners(){window.addEventListener("resize",this.onResize),window.addEventListener("orientationchange",this.onResize),document.addEventListener("visibilitychange",this.onVisiblityChane)}stop(){this.running=!1,window.removeEventListener("resize",this.onResize),window.removeEventListener("orientationchange",this.onResize),document.removeEventListener("visibilitychange",this.onVisiblityChane),this.onLoopCallbacks=[],this.renderer.dispose(),this.depthRenderTarget.dispose(),this.csm.dispose(),this.container.replaceChildren()}onLoop(e){this.onLoopCallbacks.push(e)}removeOnLoop(e){const t=this.onLoopCallbacks.find(e);this.onLoopCallbacks.splice(t,1)}set showStats(e){this._showStats=e,this._showStats&&!this.container.contains(this.stats.dom)?this.container.appendChild(this.stats.dom):!this._showStats&&this.container.contains(this.stats.dom)&&this.container.removeChild(this.stats.dom)}get showStats(){return this._showStats}loop(e,t=!1){const i=this.stats;i.showPanel(0),this.showStats=t;performance.now();s.Ray.prototype.intersectTriangle;let a=0;const o=new n,h=new n,l=t=>{const s=this.renderer.getContext();if(this.paused&&this.running&&s.drawingBufferHeight>1)return void setTimeout((()=>l(t)),500);this.renderer.autoClear=!1,this.renderer.clear(),this.renderer.setViewport(0,0,this.container.clientWidth,this.container.clientHeight),this.camera,i.begin();let n=(t*=.001)-a;if(a=t,o.copy(this.camera.matrixWorld),n>1){let t=n;for(;t>.05;)e(O),t-=O;e(t)}else e(n);this.onLoopCallbacks.forEach((e=>e(n))),this.camera?.updateMatrixWorld(),h.copy(this.camera.matrixWorld),h.equals(o)||(this.renderer.shadowMap.needsUpdate=!0),this.resizeRender();const d=[],c=[];if(this.scene.traverse((e=>{e instanceof r&&e.visible&&(e.material?.userData?.water||e.material?.uniforms&&null!=e.material?.uniforms[x])?(e.visible=!1,d.push(e),this.initDepthUniform(e.material),e.renderOrder=100):e instanceof b&&(e.visible=!1,c.push(e)),e instanceof r&&e.material?.uniforms&&null!=e.material?.uniforms[T]&&(e.material.uniforms[T].value=t)})),d.length>0){if(this.scene.overrideMaterial=F,this.renderer.setRenderTarget(this.depthRenderTarget),!this.paused&&null!=this.camera)try{this.renderer.clear(),this.renderer.render(this.scene,this.camera)}catch(e){console.warn(e)}this.renderer.setRenderTarget(null),this.scene.overrideMaterial=null}d.forEach((e=>e.visible=!0)),c.forEach((e=>e.visible=!0));try{!this.paused&&this.running&&(this.render(n),this.renderOverlay())}catch(e){console.warn(e)}i.end(),this.csm?.update(),this.running&&!0!==this.options.enableXR&&(this.fpsCap?setTimeout((()=>{requestAnimationFrame(l)}),1e3/this.fpsCap):requestAnimationFrame(l))};!0===this.options.enableXR?this.renderer.setAnimationLoop(l):requestAnimationFrame(l)}renderOverlay(){const e=Array.from(this.overlayCameras.values()).slice(0,this.maxInsetCameras),t=this.container.clientWidth/2,i=e.length*this.insetWidth+(e.length-1)*this.insetMargin;for(let s=0;s<e.length;s++)this.renderer.clearDepth(),this.renderer.setViewport(t-i/2+this.insetWidth*s+this.insetMargin*s,this.insetOffsetY,this.insetWidth,this.insetHeight),this.renderer.render(this.scene,e[s])}addOverlayCamera(e){this.overlayCameras.add(e)}clearOverlayCameras(){this.overlayCameras.clear()}removeOverlayCamera(e){this.overlayCameras.delete(e)}render(e){if(this.hasBloom()){const e=this.scene.fog;this.scene.fog=null;const t=this.renderer.getClearColor(this.prevClearColor);this.renderer.setClearColor(0),this.scene.traverseVisible((e=>this.darkenNonBloomed(e))),this.bloomComposer.render(),this.scene.traverse((e=>this.restoreMaterial(e))),this.renderer.setClearColor(t),this.scene.fog=e}this.composer.render(e)}hasBloom(){return null!=W(this.scene,(e=>e instanceof r&&!0===e.material?.userData?.hasBloom))}darkenNonBloomed(e){e.isMesh&&e.visible&&!0!==e.material.userData.hasBloom&&(this.bloomStoredMaterials[e.uuid]=e.material,!0!==e.material.transparent?e.material=D:e.visible=!1)}restoreMaterial(e){this.bloomStoredMaterials[e.uuid]&&(e.material=this.bloomStoredMaterials[e.uuid],delete this.bloomStoredMaterials[e.uuid],e.visible=!0)}initDepthUniform(e){e instanceof a&&(e.uniforms[x].value=this.isDepthTextureExtensionSupported?this.depthRenderTarget.depthTexture:this.depthRenderTarget.texture,null!=e.uniforms[C]&&e.uniforms[C].value.set(this.container.clientWidth*this.renderer.getPixelRatio(),this.container.clientHeight*this.renderer.getPixelRatio()),this.camera instanceof h&&(e.uniforms[y].value=this.camera.near,e.uniforms[P].value=this.camera.far))}};z=e=t([H(),i("design:paramtypes",[HTMLElement,Object])],z);export{z as RenderingView};export function setRenderingPaused(e){null!=window.editor?.viewer?.renderingView&&(window.editor.viewer.renderingView.paused=e)}const O=.05;
1
+ var e;import{__decorate as t,__metadata as i}from"tslib";import*as s from"three";import{Mesh as r,Matrix4 as n,ShaderMaterial as a,Color as o,PerspectiveCamera as h,ShaderChunk as l}from"three";import{EffectComposer as d,UnrealBloomPass as c,VRButton as m}from"three-stdlib";import{RenderPass as p}from"three-stdlib";import{ShaderPass as u}from"three-stdlib";import{FXAAShader as g}from"three-stdlib";import{CSM as v}from"three-stdlib";import{CSMUtil as f}from"./csm.js";import{GammaCorrectionShader as w}from"three-stdlib";import{Reflector as b}from"three-stdlib";import{depthUniformName as x,resolutionUniformName as C,supportsDepthTextureExtension as S,nearUniformName as y,farUniformName as P}from"./shader-nodes/depth.js";import{elapsedTimeUniformName as T}from"./shader-nodes/time.js";import{OutlinePass as R}from"./utils/three/outline-pass.js";import M from"./utils/three/stats.js";import{findFirstVisibleObject as W}from"./utils/three/traverse.js";import{lambertVertexShaderOverride as L}from"./rendering/shader-override.js";import{DepthPass as E}from"./utils/three/depth-pass.js";import{Service as H}from"typedi";(new s.Layers).set(9);const B=new s.MeshBasicMaterial({color:"black"}),D=new s.MeshDepthMaterial;D.depthPacking=s.RGBADepthPacking,D.blending=s.NoBlending;l.lights_pars_begin;l.lights_lambert_vertex=L;const F=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let z=e=class{setPaused(e){this.paused=e}resizeRender(){this.previousClientWith===this.container.clientWidth&&this.previousClientHeight===this.container.clientHeight||(this.camera instanceof h&&(this.camera.aspect=this.container.clientWidth/this.container.clientHeight,this.camera.updateProjectionMatrix()),this.renderer.setPixelRatio(window.devicePixelRatio*this.resolutionScale),this.renderer.setSize(this.container.clientWidth,this.container.clientHeight),this.composer.setSize(this.container.clientWidth*this.resolutionScale,this.container.clientHeight*this.resolutionScale),this.previousClientWith=this.container.clientWidth,this.previousClientHeight=this.container.clientHeight)}constructor(t,i={}){this.container=t,this.options=i,this.windowVisible=!0,this.running=!0,this.paused=!1,this.fpsCap=null,this.resolutionScale=F?.5:1,this.onResize=()=>{this.resizeRender(),this.paused||this.render()},this.onVisiblityChane=()=>{this.windowVisible=!document.hidden},this.isDepthTextureExtensionSupported=!1,this.onLoopCallbacks=[],this.stats=M(),this._showStats=!1,this.insetHeight=200,this.insetWidth=this.insetHeight*(16/9),this.insetOffsetY=250,this.insetMargin=10,this.maxInsetCameras=4,this.overlayCameras=new Set,this.prevClearColor=new o,this.hadBloom=!1,this.bloomStoredMaterials={},window.renderer=this.renderer=new s.WebGLRenderer({antialias:!0,powerPreference:"high-performance"}),this.scene=new s.Scene,this.renderer.setPixelRatio(window.devicePixelRatio*this.resolutionScale),this.renderer.setSize(t.clientWidth,t.clientHeight),this.renderer.xr.enabled=this.options.enableXR??!1,!0===this.options.enableXR&&document.body.appendChild(m.createButton(this.renderer)),this.composer=new d(this.renderer);var r=t.clientWidth/t.clientHeight;const n=new s.PerspectiveCamera(45,r,.5,800);n.layers.enable(19),this.setCamera(n),this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=s.PCFSoftShadowMap,this.renderer.shadowMap.autoUpdate=!1,this.renderer.outputEncoding=s.sRGBEncoding,this.renderer.physicallyCorrectLights=!1,this.renderer.gammaFactor=1.4,f.renderingView=this,f.patchThreeAdd(),this.isDepthTextureExtensionSupported=S(this.renderer),t.replaceChildren(this.renderer.domElement),this.setupEventListeners(),this.depthRenderTarget=e.createDepthRenderTarget(this.renderer,this.container);const a=new p(this.scene,this.camera);this.composer.addPass(a);const h=new c(new s.Vector2(t.clientWidth,t.clientHeight),1.5,.4,.85);h.threshold=0,h.strength=.9,h.radius=1;const l=new d(this.renderer);l.renderToScreen=!1,l.addPass(a),l.addPass(h),this.bloomComposer=l;const v=new u(new s.ShaderMaterial({uniforms:{baseTexture:{value:null},bloomTexture:{value:l.renderTarget2.texture}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }",fragmentShader:"\n uniform sampler2D baseTexture;\n uniform sampler2D bloomTexture;\n varying vec2 vUv;\n void main() {\n gl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) );\n }",defines:{}}),"baseTexture");if(v.needsSwap=!0,this.composer.addPass(v),this.outlinePass=new R(new s.Vector2(t.clientWidth,t.clientHeight),this.scene,this.camera),!0===i.enableOutlines){this.outlinePass.edgeThickness=0,this.outlinePass.edgeGlow=0,this.outlinePass.edgeThickness=1.5,this.outlinePass.edgeStrength=5,this.outlinePass.clear=!1,this.composer.addPass(this.outlinePass);const e=new u(g);e.uniforms.resolution.value.set(1/t.clientWidth,1/t.clientHeight),this.composer.addPass(e)}var b=new u(w);b.clear=!1,this.composer.addPass(b)}setCamera(e){this.camera=e,this.composer.passes.forEach((t=>{t instanceof p?t.camera=e:t instanceof R?t.renderCamera=e:t instanceof E&&(t.camera=e)})),null==this.csm?this.csm=new v({maxFar:200,lightFar:300,cascades:5,shadowMapSize:2048,lightDirection:new s.Vector3(.5,-1,-.6).normalize(),lightIntensity:.5,camera:this.camera,parent:this.scene}):(this.csm.camera=this.camera,this.camera instanceof h&&(this.csm.maxFar=this.camera.far)),this.csm.updateFrustums()}setSelectedObjects(e){const t=new Map;for(const i of e)t.set(i.uuid,i);for(const i of e)i.traverse((e=>{e.uuid!==i.uuid&&t.has(e.uuid)&&t.delete(e.uuid)}));this.outlinePass.selectedObjects=Array.from(t.values())}static createDepthRenderTarget(e,t){var i=!!e.extensions.get("WEBGL_depth_texture");const r=new s.WebGLRenderTarget(t.clientWidth*e.getPixelRatio(),t.clientHeight*e.getPixelRatio());return r.texture.minFilter=s.NearestFilter,r.texture.magFilter=s.NearestFilter,r.texture.generateMipmaps=!1,r.stencilBuffer=!1,!0===i&&(r.depthTexture=new s.DepthTexture(128,128),r.depthTexture.type=s.UnsignedShortType,r.depthTexture.minFilter=s.NearestFilter,r.depthTexture.magFilter=s.NearestFilter),r}setupEventListeners(){window.addEventListener("resize",this.onResize),window.addEventListener("orientationchange",this.onResize),document.addEventListener("visibilitychange",this.onVisiblityChane)}stop(){this.running=!1,window.removeEventListener("resize",this.onResize),window.removeEventListener("orientationchange",this.onResize),document.removeEventListener("visibilitychange",this.onVisiblityChane),this.onLoopCallbacks=[],this.renderer.dispose(),this.depthRenderTarget.dispose(),this.csm.dispose(),this.container.replaceChildren()}onLoop(e){this.onLoopCallbacks.push(e)}removeOnLoop(e){const t=this.onLoopCallbacks.find(e);this.onLoopCallbacks.splice(t,1)}set showStats(e){this._showStats=e,this._showStats&&!this.container.contains(this.stats.dom)?this.container.appendChild(this.stats.dom):!this._showStats&&this.container.contains(this.stats.dom)&&this.container.removeChild(this.stats.dom)}get showStats(){return this._showStats}loop(e,t=!1){const i=this.stats;i.showPanel(0),this.showStats=t;performance.now();s.Ray.prototype.intersectTriangle;let a=0;const o=new n,h=new n,l=t=>{const s=this.renderer.getContext();if(this.paused&&this.running&&s.drawingBufferHeight>1)return void setTimeout((()=>l(t)),500);this.renderer.autoClear=!1,this.renderer.clear(),this.renderer.setViewport(0,0,this.container.clientWidth,this.container.clientHeight),this.camera,i.begin();let n=(t*=.001)-a;if(a=t,o.copy(this.camera.matrixWorld),n>1){let t=n;for(;t>.05;)e(O),t-=O;e(t)}else e(n);this.onLoopCallbacks.forEach((e=>e(n))),this.camera?.updateMatrixWorld(),h.copy(this.camera.matrixWorld),h.equals(o)||(this.renderer.shadowMap.needsUpdate=!0),this.resizeRender();const d=[],c=[];if(this.scene.traverse((e=>{e instanceof r&&e.visible&&(e.material?.userData?.water||e.material?.uniforms&&null!=e.material?.uniforms[x])?(e.visible=!1,d.push(e),this.initDepthUniform(e.material),e.renderOrder=100):e instanceof b&&(e.visible=!1,c.push(e)),e instanceof r&&e.material?.uniforms&&null!=e.material?.uniforms[T]&&(e.material.uniforms[T].value=t)})),d.length>0){if(this.scene.overrideMaterial=D,this.renderer.setRenderTarget(this.depthRenderTarget),!this.paused&&null!=this.camera)try{this.renderer.clear(),this.renderer.render(this.scene,this.camera)}catch(e){console.warn(e)}this.renderer.setRenderTarget(null),this.scene.overrideMaterial=null}d.forEach((e=>e.visible=!0)),c.forEach((e=>e.visible=!0));try{!this.paused&&this.running&&(this.render(n),this.renderOverlay())}catch(e){console.warn(e)}i.end(),this.csm?.update(),this.running&&!0!==this.options.enableXR&&(this.fpsCap?setTimeout((()=>{requestAnimationFrame(l)}),1e3/this.fpsCap):requestAnimationFrame(l))};!0===this.options.enableXR?this.renderer.setAnimationLoop(l):requestAnimationFrame(l)}renderOverlay(){const e=Array.from(this.overlayCameras.values()).slice(0,this.maxInsetCameras),t=this.container.clientWidth/2,i=e.length*this.insetWidth+(e.length-1)*this.insetMargin;for(let s=0;s<e.length;s++)this.renderer.clearDepth(),this.renderer.setViewport(t-i/2+this.insetWidth*s+this.insetMargin*s,this.insetOffsetY,this.insetWidth,this.insetHeight),this.renderer.render(this.scene,e[s])}addOverlayCamera(e){this.overlayCameras.add(e)}clearOverlayCameras(){this.overlayCameras.clear()}removeOverlayCamera(e){this.overlayCameras.delete(e)}render(e){const t=this.hasBloom();if(t||this.hadBloom){const e=this.scene.fog;this.scene.fog=null;const t=this.renderer.getClearColor(this.prevClearColor);this.renderer.setClearColor(0),this.scene.traverseVisible((e=>this.darkenNonBloomed(e))),this.bloomComposer.render(),this.scene.traverse((e=>this.restoreMaterial(e))),this.renderer.setClearColor(t),this.scene.fog=e}this.hadBloom=t,this.composer.render(e)}hasBloom(){return null!=W(this.scene,(e=>e instanceof r&&!0===e.material?.userData?.hasBloom))}darkenNonBloomed(e){e.isMesh&&e.visible&&!0!==e.material.userData.hasBloom&&(this.bloomStoredMaterials[e.uuid]=e.material,!0!==e.material.transparent?e.material=B:e.visible=!1)}restoreMaterial(e){this.bloomStoredMaterials[e.uuid]&&(e.material=this.bloomStoredMaterials[e.uuid],delete this.bloomStoredMaterials[e.uuid],e.visible=!0)}initDepthUniform(e){e instanceof a&&(e.uniforms[x].value=this.isDepthTextureExtensionSupported?this.depthRenderTarget.depthTexture:this.depthRenderTarget.texture,null!=e.uniforms[C]&&e.uniforms[C].value.set(this.container.clientWidth*this.renderer.getPixelRatio(),this.container.clientHeight*this.renderer.getPixelRatio()),this.camera instanceof h&&(e.uniforms[y].value=this.camera.near,e.uniforms[P].value=this.camera.far))}};z=e=t([H(),i("design:paramtypes",[HTMLElement,Object])],z);export{z as RenderingView};export function setRenderingPaused(e){null!=window.editor?.viewer?.renderingView&&(window.editor.viewer.renderingView.paused=e)}const O=.05;
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -2,6 +2,7 @@ import { Object3D, Texture } from 'three';
2
2
  import { Asset } from './model.js';
3
3
  import { CollisionShape } from './collision/collision-shape.js';
4
4
  import * as THREE from 'three';
5
+ import { SceneObjectPhysicsSettings } from './materializer.js';
5
6
  export declare class AssetResourceLoader {
6
7
  private basePath;
7
8
  private cache;
@@ -32,5 +33,6 @@ export interface LoadedMesh {
32
33
  }
33
34
  export declare class AssetMeshInstance extends Object3D {
34
35
  collisionShapes?: CollisionShape[];
36
+ physics?: SceneObjectPhysicsSettings;
35
37
  }
36
38
  export declare function getElectronArg(name: string): string;
@@ -1,4 +1,4 @@
1
- import{polyfill as e}from"../utils/polyfill.js";import{SceneDataService as t}from"./scene-data-service.js";import{SceneMaterializer as n}from"./materializer.js";import{basicSceneSetup as a}from"./sky.js";export async function loadScene(r,i,s,o,c,m,l,p,f){e();const{scene:w,renderer:d,camera:j}=r;a(w);const u=await l.getScene(i);if(null==u)throw Error(`Could not find scene with name ${i}`);const y=await l.getSceneData(u.id),S=new t;S.initiate(y);const g=Object.entries(o).map((([e,t])=>({name:e,type:t}))),h=Object.entries(c).map((([e,t])=>({name:e,type:t}))),v=new n(w,S,p,f,r,g,h,m);return await v.initWithInstancing(),{scene:w,view:r,materializer:v,assetResourceLoader:f,assetsService:p,actors:v.actorInstances}}
1
+ import{polyfill as e}from"../utils/polyfill.js";import{SceneDataService as t}from"./scene-data-service.js";import{SceneMaterializer as n}from"./materializer.js";import{basicSceneSetup as i}from"./sky.js";export async function loadScene(r,a,s,o,c,m,l,p,d){e();const{scene:f,renderer:w,camera:j}=r;i(f);const u=await l.getScene(a);if(null==u)throw Error(`Could not find scene with name ${a}`);const y=await l.getSceneData(u.id),S=new t;S.initiate(y);const g=Object.entries(o).map((([e,t])=>({name:e,type:t}))),h=Object.entries(c).map((([e,t])=>({name:e,type:t}))),v=new n(f,S,p,d,r,g,h,m);return v.inEditor=!1,await v.initWithInstancing(),{scene:f,view:r,materializer:v,assetResourceLoader:d,assetsService:p,actors:v.actorInstances}}
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -1,4 +1,5 @@
1
- import { BoxGeometry, BufferGeometry, Euler, Material, Mesh, Vector3 } from "three";
1
+ import { SceneObjectPhysicsSettings } from "../../scene/materializer.js";
2
+ import { BufferGeometry, Euler, Material, Mesh, Vector3 } from "three";
2
3
  export declare class CollisionShape {
3
4
  offset: Vector3;
4
5
  rotation: Euler;
@@ -50,10 +51,7 @@ export declare class CapsuleCollisionShape extends CollisionShape {
50
51
  }
51
52
  export declare class PhysicalShapeMesh extends Mesh {
52
53
  collisionShape: CollisionShape;
54
+ physics?: SceneObjectPhysicsSettings;
53
55
  isPhysicalShapeMesh: boolean;
54
- constructor(geometry: BufferGeometry, material: Material, collisionShape: CollisionShape);
55
- }
56
- export declare class PhysicalBoxMesh extends PhysicalShapeMesh {
57
- isPhysicalBoxMesh: boolean;
58
- constructor(geometry: BoxGeometry, material: Material);
56
+ constructor(geometry: BufferGeometry, material: Material, collisionShape: CollisionShape, physics?: SceneObjectPhysicsSettings);
59
57
  }
@@ -1,4 +1,4 @@
1
- import{Euler as s,Mesh as e,Vector3 as o}from"three";export class CollisionShape{constructor(){this.offset=new o,this.rotation=new s}withOffset(s){return this.offset.copy(s),this}withRotation(s){return this.rotation.copy(s),this}}export class BoxCollisionShape extends CollisionShape{constructor(s){super(),this.dimensions=s}}export class PlaneCollisionShape extends CollisionShape{constructor(s,e){super(),this.width=s,this.height=e}}export class SphereCollisionShape extends CollisionShape{constructor(s){super(),this.radius=s}}export class CylinderCollisionShape extends CollisionShape{constructor(s,e,o,t,i){super(),this.radiusTop=s,this.radiusBottom=e,this.height=o,this.segments=t,this.orentation=i}}export class ConeCollisionShape extends CollisionShape{constructor(s,e){super(),this.radiusBottom=s,this.height=e}}export class ConvexPolyhedronCollisionShape extends CollisionShape{constructor(s){super(),this.mesh=s}}export class TrimeshCollisionShape extends CollisionShape{constructor(s){super(),this.geometry=s}}export class MeshCollisionShape extends CollisionShape{constructor(s){super(),this.geometry=s}}export class CapsuleCollisionShape extends CollisionShape{constructor(s,e){super(),this.length=s,this.radius=e}}export class PhysicalShapeMesh extends e{constructor(s,e,o){super(s,e),this.collisionShape=o,this.isPhysicalShapeMesh=!0}}export class PhysicalBoxMesh extends PhysicalShapeMesh{constructor(s,e){super(s,e,new BoxCollisionShape(new o(s.parameters.width,s.parameters.height,s.parameters.depth))),this.isPhysicalBoxMesh=!0}}
1
+ import{Euler as s,Mesh as o,Vector3 as e}from"three";export class CollisionShape{constructor(){this.offset=new e,this.rotation=new s}withOffset(s){return this.offset.copy(s),this}withRotation(s){return this.rotation.copy(s),this}}export class BoxCollisionShape extends CollisionShape{constructor(s){super(),this.dimensions=s}}export class PlaneCollisionShape extends CollisionShape{constructor(s,o){super(),this.width=s,this.height=o}}export class SphereCollisionShape extends CollisionShape{constructor(s){super(),this.radius=s}}export class CylinderCollisionShape extends CollisionShape{constructor(s,o,e,t,i){super(),this.radiusTop=s,this.radiusBottom=o,this.height=e,this.segments=t,this.orentation=i}}export class ConeCollisionShape extends CollisionShape{constructor(s,o){super(),this.radiusBottom=s,this.height=o}}export class ConvexPolyhedronCollisionShape extends CollisionShape{constructor(s){super(),this.mesh=s}}export class TrimeshCollisionShape extends CollisionShape{constructor(s){super(),this.geometry=s}}export class MeshCollisionShape extends CollisionShape{constructor(s){super(),this.geometry=s}}export class CapsuleCollisionShape extends CollisionShape{constructor(s,o){super(),this.length=s,this.radius=o}}export class PhysicalShapeMesh extends o{constructor(s,o,e,t){super(s,o),this.collisionShape=e,this.physics=t,this.isPhysicalShapeMesh=!0}}
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -12,6 +12,8 @@ import { LandscapeInitOptions } from './landscape/landscape.js';
12
12
  import { Asset, CustomParamValue, MaterialAssignment, SerializedParamType, ShapeType } from './model.js';
13
13
  import { BaseActor } from '../gameplay/actors/actor.js';
14
14
  import { ContainerInstance } from "typedi";
15
+ import { PhysicsBodyType } from '../gameplay/index.js';
16
+ import { AssetId } from './model.js';
15
17
  export type SceneObjectId = string;
16
18
  export type SceneObjectType = "asset_mesh" | "light" | "shape_mesh" | "spline" | "landscape" | "particles" | "global_fog" | "global_light" | "actor" | "group" | "prefab" | "vfx" | "sky";
17
19
  export type LightType = "point" | "directional" | "ambient";
@@ -32,11 +34,11 @@ type AmbientLightSettings = {
32
34
  color: string | number;
33
35
  intensity: number;
34
36
  };
35
- export interface SceneObject {
37
+ export type SceneObject = {
36
38
  id: SceneObjectId;
37
39
  name: string;
38
40
  children?: SceneObject[];
39
- assetId?: string;
41
+ assetId?: AssetId;
40
42
  shape?: ShapeType;
41
43
  shapeParams?: Record<string, CustomParamValue>;
42
44
  light?: {
@@ -49,10 +51,10 @@ export interface SceneObject {
49
51
  type: 'ambient';
50
52
  ambient: AmbientLightSettings;
51
53
  };
52
- position: number[];
53
- scale: number[];
54
- rotation: any[];
55
- collisionDetection: boolean;
54
+ position?: number[];
55
+ scale?: number[];
56
+ rotation?: any[];
57
+ collisionDetection?: boolean;
56
58
  components?: AttachedComponent[];
57
59
  hidden?: boolean;
58
60
  materialAssignments?: MaterialAssignment[];
@@ -65,9 +67,27 @@ export interface SceneObject {
65
67
  castShadow?: boolean;
66
68
  receiveShadow?: boolean;
67
69
  sky?: SkySettings;
68
- }
70
+ physics?: SceneObjectPhysicsSettings;
71
+ };
72
+ export type SceneObjectMesh = {
73
+ type: 'asset_mesh';
74
+ assetId?: AssetId;
75
+ physics?: SceneObjectPhysicsSettings;
76
+ } & SceneObject;
77
+ export type SceneObjectShape = {
78
+ type: 'shape_mesh';
79
+ shape?: ShapeType;
80
+ physics?: SceneObjectPhysicsSettings;
81
+ } & SceneObject;
82
+ export type SceneObjectPhysicsSettings = {
83
+ type: PhysicsBodyType.dynamic | PhysicsBodyType.static;
84
+ friction?: number;
85
+ density?: number;
86
+ restitution?: number;
87
+ mass?: number;
88
+ };
69
89
  export type SkySettings = {
70
- materialId: string;
90
+ materialId?: string;
71
91
  };
72
92
  export interface ActorSettings {
73
93
  type: string;
@@ -200,6 +220,7 @@ export declare class SceneMaterializer {
200
220
  private addVfxChildActors;
201
221
  private removeVfxChildActors;
202
222
  private applyActorComponentParams;
223
+ private canObjectBeInstanced;
203
224
  private _canBeInstancedCache;
204
225
  private canAssetBeInstanced;
205
226
  private sky;
@@ -236,6 +257,8 @@ export declare class SceneMaterializer {
236
257
  private createFromShape;
237
258
  private createLandscape;
238
259
  private applyHeightMaps;
260
+ private geometryCache;
261
+ private collisionShapeCache;
239
262
  private createMeshByShape;
240
263
  private createFromAsset;
241
264
  private createFromPrefabAsset;
@@ -1,4 +1,4 @@
1
- import{Subject as e}from"rxjs";import*as t from"three";import{BoxGeometry as a,Color as s,Euler as r,Fog as i,FogExp2 as n,Group as o,Material as c,Mesh as l,MeshLambertMaterial as h,MeshPhongMaterial as m,MeshStandardMaterial as d,Object3D as p,PointLight as f,Quaternion as u,SphereGeometry as g,Texture as y,Vector2 as w,Vector3 as v,Vector4 as A}from"three";import S,{SpriteRenderer as b}from"three-nebula";import{bool as M,BooleanNode as x,float as j,FloatNode as I,NodeShaderMaterial as P,rgb as D,RgbNode as E,Texture2dLookupNode as V,textureSampler2d as N,vec2 as F,Vec2Node as z,vec3 as C,Vec3Node as k,vec4 as B}from"three-shader-graph";import O from"../gameplay/actors/builtin/index.js";import{extractShaderParameters as _}from"../shader/parameter.js";import{groupBy as T,ArrayMap as $}from"../utils/collections.js";import{filterChildrenShallow as L,filterSceneShallow as R}from"../utils/three/traverse.js";import{AssetMeshInstance as U}from"./asset-resource-loader.js";import{BoxCollisionShape as H,PhysicalShapeMesh as W}from"./collision/collision-shape.js";import{isCollisionMesh as G}from"./collision/collision-shape-import.js";import{initLandscape as J}from"./landscape/landscape.js";import{LandscapeManager as X}from"./landscape/landscape-manager.js";import{SectionGrid as Y,smoothNormalsCrossMeshes as q}from"./landscape/utils.js";import{createGrassMaterial as Z}from"./materials/grass.js";import{createGrassFoliageMaterial as K}from"./materials/grass-foliage.js";import{getMaterialAttribute as Q}from"./materials/utils/material-painting.js";import{createWaterMaterial as ee}from"./materials/water.js";import{SerializedParamType as te}from"./model.js";import{Matrix4 as ae}from"three";import{BaseActor as se}from"../gameplay/actors/actor.js";import{Sampler2DNode as re}from"../shader-nodes/index.js";import{StandardShader as ie}from"../shader/builtin/standard-shader.js";import{LambertShader as ne}from"../shader/builtin/lambert-shader.js";import{ShapeLibrary as oe,ShapeLibraryKeys as ce}from"./objects/shapes.js";import{ambientLightName as le,createSky as he,defaultSkyMaterial as me}from"./sky.js";import{ActorComponent as de,withInjectionContext as pe}from"../gameplay/index.js";import{iterateMaterials as fe}from"../utils/materials.js";import{VfxActor as ue}from"../effects/vfx/vfx-actor.js";import{VisualEffect as ge}from"../effects/vfx/vfx-param.js";import{findFirstVisibleObject as ye}from"../utils/three/traverse";const we={};export const shapeDefaultColor="#aaaaaa";export class SceneMaterializerLoader{constructor(e,t,a){this.dataProvider=e,this.assetsService=t,this.assetManagerService=a}get(e,t){return new SceneMaterializer(e,this.dataProvider,this.assetsService,this.assetManagerService,t,[],[],{create:()=>null,initActor:async()=>{}})}}export class SceneMaterializer{constructor(t,a,s,r,i,n,o,c){this.scene=t,this.dataProvider=a,this.assetsService=s,this.assetManagerService=r,this.renderingView=i,this.shaders=n,this.actorTypes=o,this.actorProvider=c,this.objectMap=new Map,this.sceneObjectMap=new Map,this.components=[],this.landscapeManagers=[],this.materializedActors=new Map,this.inEditor=!0,this.updated$=new e,this.removed$=new e,this.error$=new e,this.editorActorParamSnapshot=new Map,this._canBeInstancedCache=new Map,this._originalMaterials=new Map,this.originalFog=null,a.onUpdate((e=>this.update(e))),a.onRemove((e=>this.remove(e))),this.updateSubscription=s.onUpdate.subscribe((async e=>{"material"==e.type?((await this.assetsService.getAssets()).filter((t=>(t.materialAssignments??[]).some((t=>t.materialId===e.id)))).forEach((e=>{const t=this.findByAssetId(e.id);e.materialAssignments.forEach((e=>{t.forEach((t=>{const a=t.userData.src.materialAssignments;null!=a&&a.some((t=>t.color===e.color))||this.applyMaterial(t,e)}))}))})),R(this.scene,(t=>null!=t.userData.src&&(t.userData.src.materialAssignments??[]).some((t=>t.materialId===e.id))),(e=>null!=e.userData.src)).forEach((async e=>{this.deleteSceneObject(e.userData.src),this.materialize(e.userData.src)}))):"mesh"==e.type?this.findByAssetId(e.id).forEach((t=>{De(t.userData.src.materialAssignments,e.materialAssignments).forEach((e=>{this.applyMaterial(t,e)}))})):"prefab"===e.type&&this.findByAssetId(e.id).forEach((e=>{const t=e.userData.src;this.remove(t),this.materializeAndInitActor(t)}))}))}get actorInstances(){return Array.from(this.materializedActors.values())}async prefetchAssets(){const e=Array.from(new Set(this.dataProvider.getObjects().filter((e=>null!=e.assetId&&"asset_mesh"==e.type)).filter((e=>e.assetId))));await Promise.all(e.map((e=>this.assetsService.getAsset(e.assetId).then((e=>e&&this.assetManagerService.getMesh(e))))))}async init(){this.preInit(),Ae.clear(),await this.prefetchAssets(),await Promise.all(this.dataProvider.getObjects().map((e=>this.materialize(e)))),await this.initActorsPostInit()}initActorsPostInit(e=this.actorInstances){const t=e.map((async e=>{const t=e.object.userData.src;if("vfx"===t.type)return Promise.resolve();const a=await this.assetsService.getAsset(t.assetId),s={...a?.actor?.params??{},...t.actor?.params??{}};for(const a of t.actor.innerParams??[])await this.applyActorComponentParams(e,a.path.slice(),a.params);const r=await Me(s,e.constructor,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders,this.actorProvider);Object.assign(e,r);try{return await this.actorProvider.initActor(e)}catch(e){console.error(`Failed to initiate actor (name="${t.name}", id=${t.id})`,e)}}));return Promise.all(t)}addVfxChildActors(e,t=e){for(const a of Object.keys(t))t[a]instanceof ge?null!=t[a].actor&&(console.log("add actor to world",t[a].actor),e.object.add(t[a].actor.object)):t[a]instanceof de&&this.addVfxChildActors(e,t[a])}removeVfxChildActors(e,t=e){for(const a of Object.keys(t))if(t[a]instanceof ge){if(null!=t[a].actor){t[a].actor.onEndPlay(),console.log("remve actor from world",t[a].actor),e.object.remove(t[a].actor.object)}}else t[a]instanceof de&&this.removeVfxChildActors(e,t[a])}async applyActorComponentParams(e,t,a){const s=t.length,r=t.shift();if(0==s){const t=await Me(a,null,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders);for(const[a,s]of Object.entries(t))null!=s&&(e[a]=s)}else null!=e[r]&&await this.applyActorComponentParams(e[r],t,a)}async canAssetBeInstanced(e){if(!this._canBeInstancedCache.has(e.assetId)){const t=await this.createFromAsset(e);if(null==t)return!1;const a=[];t.traverse((e=>{!G(e)&&e.isMesh&&a.push(e)}));const s=1==a.length&&0==a[0].children.length,r=!0;this._canBeInstancedCache.set(e.assetId,s&&r)}return this._canBeInstancedCache.get(e.assetId)}preInit(){this.renderingView?.onLoop((()=>this.sky?.position.copy(this.renderingView.camera.position)))}async initWithInstancing(){this.preInit();const e=new $;for(const t of this.dataProvider.getObjects())await Pe(t,(async(t,a,s)=>{const r="asset_mesh"==t.type&&await this.canAssetBeInstanced(t)?t.assetId+JSON.stringify(t.materialAssignments??[]):"other";"other"!==r&&a&&a.children?.length>0&&a.children.splice(a.children.findIndex((e=>e.id===t.id)),1),"other"===r&&a||e.push(r,{...t,parentTransform:s})}));for(const[t,a]of e.entries())if("other"!==t&&a.length>0){const e=await this.createFromAsset(a[0]);if(null==e)continue;const t=await this.createInstancedMesh(a,e),s=new U;s.add(t),s.userData.src=a[0],e instanceof U&&(s.collisionShapes=e.collisionShapes),s.castShadow=!1,s.receiveShadow=!1,this.scene.add(s)}else await Promise.all(a.map((e=>this.materialize(e))));await this.initActorsPostInit()}async createInstancedMesh(e,a){const s=ye(a,(e=>!G(e)&&null!=e.geometry)),i=await this.assetsService.getAsset(e[0].assetId);await this.applyMaterials(a,De(e[0].materialAssignments,i.materialAssignments)),s.updateMatrix();const n=s.geometry.clone().applyMatrix4(s.matrix),o=new t.InstancedMesh(n,s.material.clone(),e.length);o.material.side=t.FrontSide;for(let a=0;a<e.length;a++){const s=(new t.Matrix4).compose((new v).fromArray(e[a].position),(new u).setFromEuler((new r).fromArray(e[a].rotation)),(new v).fromArray(e[a].scale)),i=(new ae).copy(e[a].parentTransform).multiply(s);o.setMatrixAt(a,i)}return o.castShadow=i.castShadow??!0,o.receiveShadow=i.receiveShadow??!0,o}remove(e){if(console.log("Remove scene object",e),"global_fog"==e.type)return void(this.scene.fog=this.originalFog);if("actor"==e.type){const t=this.materializedActors.get(e.id);null!=t?(t.disposed.next(!0),t.onEndPlay(),this.removeVfxChildActors(t)):console.warn("Failed to remove actor",e)}const t=this.sceneObjectMap.get(e.id);t?.parent.remove(t),this.sceneObjectMap.delete(e.id),this.components.filter((t=>t.object.userData.src?.id===e.id)).forEach((e=>this.components.splice(this.components.indexOf(e,1)))),this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>{e.clear(),e.stop(),this.landscapeManagers.splice(this.landscapeManagers.indexOf(e,1))})),this.removed$.next({object:t,source:e})}deleteSceneObject(e){const t=this.sceneObjectMap.get(e.id);if(this.scene.remove(t),"landscape"==e.type){const t=this.landscapeManagers.findIndex((t=>t.source.id===e.id));if(t>-1){const e=this.landscapeManagers.splice(t,1)[0];e.clear(),e.stop()}}}findByAssetId(e){return R(this.scene,(t=>t.userData.src?.assetId==e),(e=>null!=e.userData.src))}applyMaterials(e,t){return null==t?Promise.resolve([]):Promise.all(t.filter((e=>"null"!==e.materialId)).map((t=>this.applyMaterial(e,t))))}applyMaterial(e,t){const a=[];return e.traverse((async e=>{if(e instanceof l||e.isMesh)for(const t of fe(e.material))t.hasOwnProperty("color")&&a.push(e)})),Promise.all(a.map((async e=>{if(e.material instanceof Array)for(let a=0;a<e.material.length;a++){const r=e.material[a];if(null==r.color||!(r.color instanceof s))continue;const i="#"+r.color.getHexString(),n=r.name;if(i===t.color&&(r.name===t.name||null==t.name)||e.userData["originalColor_"+a]===t.color&&e.userData["originalMaterialName_"+a]===t.name){const s=await this.assetsService.getAsset(t.materialId),r=e.material[a];s&&(e.material[a]=await materialFromAsset(s,this.renderingView,this.assetsService,this.assetManagerService,this.shaders),e.userData["originalColor_"+a]=e.userData["originalColor_"+a]??i,e.userData["originalMaterialName_"+a]=e.userData["originalMaterialName_"+a]??n,this.inEditor&&this._originalMaterials.set(e.id+"#"+a,r))}}else{const a="#"+e.material.color.getHexString(),s=e.material.name;if(a===t.color&&(e.material.name===t.name||null==t.name)||e.userData.originalColor===t.color&&e.userData.originalName===t.name){const r=await this.assetsService.getAsset(t.materialId),i=e.material;r&&(e.material=await materialFromAsset(r,this.renderingView,this.assetsService,this.assetManagerService,this.shaders),e.userData.originalColor=e.userData.originalColor??a,e.userData.originalMaterialName=e.userData.originalMaterialName??s,this.inEditor&&this._originalMaterials.set(e.id,i))}}})))}unapplyMaterials(e){e.traverse((async e=>{if(e instanceof l)if(e.material instanceof Array)for(let t=0;t<e.material.length;t++)e.material[t]=this._originalMaterials.get(e.id+"#"+t)??e.material[t];else e.material=this._originalMaterials.get(e.id)??e.material}))}updateActors(e){console.log("update actors"),this.actorTypes=e;const t=new Set(Object.values(O));R(this.scene,(e=>e.userData.src?.id&&"actor"===e.userData.src.type&&this.materializedActors.has(e.userData.src?.id)&&!t.has(e.userData.src.actor.type))).forEach((async e=>{this.remove(e.userData.src),await this.materializeAndInitActor(e.userData.src)}))}updateShaders(e){this.shaders=e;for(const[e,t]of Ae.entries())t.userData.customShaderName&&Ae.delete(e);this.landscapeManagers.forEach((t=>t.updateShaders(e))),R(this.scene,(e=>!0)).forEach((e=>{e.traverse((e=>{if(e instanceof l){const t=e.material.userData?.customShaderName;if(null!=t){const t=function(e,t){if(t(e))return e;let a;return e.traverseAncestors((e=>{null==a&&t(e)&&(a=e)})),a}(e,(e=>null!=e.userData.src?.id))?.userData.src;null!=t&&this.update(t)}}}))}))}async update(e){if("sky"===e.type&&null!=this.sky&&null!=this.sky.parent)return void this.updateSky(e);const t=this.sceneObjectMap.get(e.id);if(t){const r=this.findParent(e);if(null!=r&&r.uuid!=t.uuid?r.attach(t):console.error("Parent is wrong"),"prefab"!==e.type){this.unapplyMaterials(t);this.inEditor&&e.hidden&&!1?t.traverse((e=>{e instanceof l&&(e.material.wireframe=!0)})):t.traverse((e=>{e instanceof l&&(e.material.wireframe=!1)}))}if("asset_mesh"===e.type){const a=await this.assetsService.getAsset(e.assetId);De(e.materialAssignments,a.materialAssignments).forEach((e=>this.applyMaterial(t,e)))}else"shape_mesh"===e.type&&this.applyMaterials(t,e.materialAssignments);let o=!1;if(t.traverseAncestors((e=>{"_hology_transform_group"===e.name&&(o=!0)})),o||(t.position.fromArray(e.position),t.scale.fromArray(e.scale),t.rotation.fromArray(e.rotation)),this.applyVertexMaterials(e,t),"light"==e.type)if("point"==e.light.type){const a=t;a.color=new s(e.light.point.color),a.intensity=e.light.point.intensity,a.decay=e.light.point.decay,a.castShadow=e.light.point.castShadow,a.distance=Math.max(e.light.point.distance,0)}else"directional"===e.light.type?this.applyDirectionalLight(e.light.directional):"ambient"===e.light.type&&this.applyDirectionalAmbientLight(t,e.light.ambient);else if("landscape"===e.shape)this.applyHeightMaps(t,e.landscape.heightMaps),this.inEditor&&this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>!0))));else if("global_fog"===e.type){const t=(this.scene.fog instanceof n?"density":"linear")!==e.fog.type;this.scene.fog=je(e.fog),t&&(a=this.scene).traverse((e=>{if(e instanceof l){const t=e.material;t instanceof P&&(a.fog instanceof i?(t.uniforms.fogFar.value=a.fog.far,t.uniforms.fogNear.value=a.fog.near):a.fog instanceof n&&(t.uniforms.density={value:a.fog.density}),t.needsUpdate=!0,t.uniformsNeedUpdate=!0)}})),this.fixFogColor()}else if("actor"===e.type){if(this.materializedActors.has(e.id)){const t=this.editorActorParamSnapshot.get(e.id);null!=t&&t===JSON.stringify(e.actor)||(console.log("Rematerializing actor because parameters changed"),this.remove(e),await this.materializeAndInitActor(e))}}else if("shape_mesh"===e.type){const a=await this.createMeshByShape(e.shape,t.material,e.shapeParams);t instanceof W&&(t.geometry=a.geometry,t.collisionShape=a.collisionShape)}("asset_mesh"===e.type||"shape_mesh"===e.type&&"landscape"!==e.shape)&&ve(t,e.castShadow,e.receiveShadow),e.name&&e.name.length>0&&(t.name=e.name),this.updated$.next({object:t,source:e})}else{const t=await this.materializeAndInitActor(e);this.updated$.next({object:t,source:e})}var a}async materializeAndInitActor(e,t=this.findParent(e)){console.log("materialize actor and init");const a=await this.materialize(e,t);return Pe(e,(async e=>{if("actor"===e.type){const t=this.materializedActors.get(e.id);null!=t?await this.initActorsPostInit([t]):console.error(`Something went wrong when creating actor ${e.id}`)}})),a}findParent(e){const t=this.dataProvider.getObjects().flatMap((t=>t.id===e.id?null:L(t,(t=>t.children?.some((t=>t.id===e.id))),(()=>!0))))[0];return null==t?this.scene:null!=t?R(this.scene,(e=>e.userData?.src?.id===t.id),(e=>null!=e.userData?.src))[0]:void 0}fixFogColor(){!0===this.renderingView.options.enableOutlines&&(this.scene.fog.color=new s(this.scene.fog.color).convertSRGBToLinear())}findMeshWithGeometry(e){let t;return e.traverse((e=>{e instanceof l&&e.geometry&&(t=e)})),t}applyVertexMaterials(e,t){if(null==e.vertexMaterials||0===e.vertexMaterials.length)return;const a=T(e.vertexMaterials,(e=>e.m));t.traverse((e=>{if(e instanceof l){const t=Q(e,!1);if(null!=t){for(let e=0;e<t.array.length;e++)t.setX(e,0);t.needsUpdate=!0}}}));const s=new Set;for(const[e,r]of a.entries()){const a=null!=e?t.getObjectByName(e):this.findMeshWithGeometry(t);let i=!1;if(null==a)return void console.warn(`Failed to apply vertex materials on mesh with name "${e}"`);const n=Q(a,!0);for(let e=0;e<n.array.length;e++)n.setX(e,0);for(const e of r)n.setX(e.i,e.w[0]),n.setY(e.i,e.w[1]),n.setZ(e.i,e.w[2]),i=!0;i&&s.add(e)}this.inEditor&&this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>s.has(e.name)))))}async materialize(e,t,s=!1){let r;switch(e.type){case"asset_mesh":r=await this.createFromAsset(e);break;case"shape_mesh":r=await this.createFromShape(e);break;case"light":r=await this.createLight(e);break;case"particles":r=await this.createParticleSystem(e),e.collisionDetection=!1;break;case"global_fog":this.scene.fog=je(e.fog),this.fixFogColor(),r=new o;break;case"sky":this.sky=he(),this.updateSky(e),r=this.sky;break;case"actor":r=await this.createFromActor(e);break;case"group":r=new o;break;case"prefab":r=await this.createFromPrefabAsset(e);break;case"vfx":r=await this.createFromVfx(e);break;default:if(this.inEditor)throw new Error("unknown type "+e.type);console.warn(`Failed to materialize object. Unknown type '${e.type}'. This might be because the hology/core library is not compatible with the editor version.`)}if(null!=r){if(e.name&&e.name.length>0&&(r.name=e.name),r.position.fromArray(e.position),r.scale.fromArray(e.scale),r.rotation.fromArray(e.rotation),s||(r.userData.src=e),!this.inEditor){const t=e.components??[],a=null!=e.assetId?(await this.assetsService.getAsset(e.assetId))?.components??[]:[];t.push(...a),t.length>0?r.userData.componentRefs=await Promise.all(t.map(((t,a)=>this.createComponent(r,e,t,a)))):"asset_mesh"==e.type&&function(e){e.traverse((e=>{e.matrixAutoUpdate=!1,e.matrixWorldNeedsUpdate=!1}));const t=e.updateMatrixWorld;e.updateMatrixWorld=function(){t.apply(e),e.updateMatrixWorld=function(){}}}(r)}if(this.inEditor){let e=null;r instanceof W&&(e=function(e){if(e instanceof H)return new l(new a(...e.offset.toArray()),Ie);return null}(r.collisionShape)),null!=e&&(e.layers.disable(0),e.layers.enable(18),e.scale.multiplyScalar(1.1),r.add(e))}return this.objectMap.set(r.uuid,e),this.sceneObjectMap.set(e.id,r),null==t?this.scene.add(r):t?.add(r),null!=e.children&&await Promise.all(e.children?.map((e=>this.materialize(e,r,s)))),r}}async updateSky(e){if(null==e?.sky?.materialId)return void(this.sky.material=me);const a=await this.assetsService.getAsset(e.sky.materialId),s=await materialFromAsset(a,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!1);s.side=t.BackSide,null!=this.sky?this.sky.material=s:console.warn("No sky has been created")}async createComponent(e,t,a,s){const r=new we[a.path+"/"+a.className],i=t.id+s;r.id=i,r.object=e;for(const e of a.params)null!=e.value&&(r[e.name]=e.value);return this.components.push(r),i}async createFromActor(e){const t=this.actorTypes.find((t=>t.name===e.actor?.type))?.type??O[e.actor?.type];if(null==t)return null;this.inEditor&&this.editorActorParamSnapshot.set(e.id,JSON.stringify(e.actor));const a=await this.actorProvider.create(t,(new v).fromArray(e.position),(new r).fromArray(e.rotation),!0);return this.materializedActors.set(e.id,a),a?.object}async createFromVfx(e){const t=await this.assetsService.getAsset(e.assetId);null==t&&console.error("Could not find asset",e);const a=await this.actorProvider.create(ue,(new v).fromArray(e.position),(new r).fromArray(e.rotation),!1);return await a.fromAsset(t),a.play(),this.materializedActors.set(e.id,a),a?.object}cleanup(){this.materializedActors.clear()}async createFromShape(e){const t=this.inEditor&&e.hidden;let a;if("landscape"==e.shape)a=this.createLandscape(e);else{let r=new d({name:"Default",color:new s("#aaaaaa"),visible:this.inEditor||!e.hidden,wireframe:!!t});const i=await this.createMeshByShape(e.shape,r,e.shapeParams);i.castShadow=e.castShadow??!0,i.receiveShadow=e.castShadow??!1,e.collisionDetection||(i.collisionShape=null),a=i,this._originalMaterials.set(a.id,i.material),a.traverse((e=>{}))}return t||((e.materialAssignments??[]).filter((e=>null!=e.materialId)).forEach((e=>this.applyMaterial(a,e))),this.applyVertexMaterials(e,a)),a}createLandscape(e){const t=e.landscape?.options;if(null==t)return console.error(`No landscape options exist on scene object ${e.id} ${e.name}`),new o;const a=J(e.landscape.options);this.applyHeightMaps(a,e.landscape.heightMaps,!0);const s=new X(e,this.renderingView,a,this.assetManagerService,this.assetsService,this.shaders,(t=>{(e.materialAssignments??[]).filter((e=>null!=e.materialId)).forEach((e=>this.applyMaterial(t,e)))}));return this.landscapeManagers.push(s),s.refreshGeometry(),a}applyHeightMaps(e,t,a=!1){const s=new Y(e.sections);for(const e of t??[]){const t=s.find(e.x,e.y);if(!t)return;const a=t.geometry.getAttribute("position");for(const t of e.points)a.setY(t.i,t.y);a.needsUpdate=!0}const r=e.sections;r.forEach((e=>{e.geometry.computeBoundsTree(),e.geometry.computeVertexNormals()})),this.inEditor&&!a||setTimeout((()=>q(r)),50)}async createMeshByShape(e,t,a={}){if("landscape"!==e&&ce.includes(e)){const s=await prepareShapeParameters(a??{});return"cylinder"==e&&s.openEnded,new W(oe[e].geometry(s),t,oe[e].collision(s))}if(this.inEditor)throw new Error(`Unsupported shape '${e}'`);console.warn(`Failed to create shape. Unsupported shape '${e}'. This might be because the hology/core library is not compatible with the editor version.`)}async createFromAsset(e){const t=await this.assetsService.getAsset(e.assetId);if(null==t)return void console.warn(`Can not find asset with id ${e.assetId} and name ${e.name}`);let{scene:a}=await this.assetManagerService.getMesh(t);De(e.materialAssignments,t.materialAssignments).forEach((e=>this.applyMaterial(a,e)));const s=e.receiveShadow??!!t.receiveShadow??!0,r=e.castShadow??!!t.castShadow??!1;return a.receiveShadow=s,ve(a,r,s),e.collisionDetection||(a.collisionShapes=[]),this.applyVertexMaterials(e,a),a.traverse((e=>{e instanceof l&&"computeBoundsTree"in e.geometry&&e.geometry.computeBoundsTree()})),a}async createFromPrefabAsset(e){const t=await this.assetsService.getAsset(e.assetId);if(null==t)return void console.warn(`Can not find asset with id ${e.assetId} and name ${e.name}`);const a=new o;return t.prefab.objects.filter((e=>"global_fog"!==e.type)).forEach((e=>this.materialize(e,a,!0))),a}async createParticleSystem(e){const a=await this.assetsService.getAsset(e.assetId),s=new p;return await S.fromJSONAsync(a.particleSystem,t).then((e=>{const a=new b(s,t);e.addRenderer(a),this.renderingView.onLoop((t=>e.update()))})),s}async createLight(e){if("point"===e.light.type){const t=new f(e.light.point.color,e.light.point.intensity,e.light.point.distance,e.light.point.decay);if(t.castShadow=e.light.point.castShadow??!0,this.inEditor){const e=new g(.3,10,10),a=new d({color:new s(16771709)}),r=new l(e,a);t.add(r)}return t}return"directional"===e.light.type?(this.applyDirectionalLight(e.light.directional),new o):"ambient"===e.light.type?(this.applyDirectionalAmbientLight(null,e.light.ambient),new o):void 0}applyDirectionalAmbientLight(e,t){const a=this.scene.children.find((e=>e.name===le));null!=a?(a.intensity=t.intensity,a.color.set(t.color),a.groundColor.set(t.color)):console.warn("Couldn't find ambient light")}applyDirectionalLight(e){for(const t of this.renderingView.csm.lights)t.intensity=e.intensity,t.color.set(e.color),t.castShadow=e.castShadow;this.renderingView.csm.lightDirection.fromArray(e.direction).normalize()}dispose(){this.updateSubscription.unsubscribe(),this.materializedActors.forEach((e=>e.disposed.next(!0)))}}function ve(e,t,a){e.castShadow=t,e.receiveShadow=a,e.traverse((e=>{e.castShadow=t,e.receiveShadow=a}))}const Ae=new Map,Se=new h({color:16711935}),be=new Map;export async function materialFromAsset(e,a,r,i,n,o=!0){const c=JSON.stringify(e.material);if(o&&Ae.has(c))return Ae.get(c);const l={opacity:e.material.params.opacity,map:null,emissive:e.material.params.emissive??null,metalness:e.material.params.metalness??0,flatShading:e.material.params.flatShading??!1,color:new s(e.material.params.color).convertSRGBToLinear(),transparent:null!=e.material.params.opacity&&e.material.params.opacity<1},h={};if(null!=e.material.params.map){const t=e.material.params.map,a=await r.getAsset(t);null!=a&&(l.map=await i.getTexture(a))}let d;switch(e.material.type){case"phong":d=new m({...l,...h});break;case"water":d=ee(l,a);break;case"grassFoliage":d=K({color:l.color,map:l.map},a);break;case"grass":d=Z({...l,colorTwo:new s(e.material.params.colorTwo),colorThree:new s(e.material.params.colorThree)},a);break;case"standard":case"lambert":case"shader":const t={standard:ie,lambert:ne}[e.material.type]??n.find((t=>t.name==e.material.shader))?.type;if(t){const s=new t,o=await Me(e.material?.shaderParams??{},t,r,i,null,a,n);Object.assign(s,o);try{d=s.build()}catch(t){console.log("Shader runtime error: "+t),be.has(e.material.shader)||be.set(e.material.shader,Se.clone()),d=be.get(e.material.shader)}d.userData.customShaderName=e.material.shader}else console.warn("Missing shader implementation with name "+e.material.shader),d=Se;break;default:throw new Error("Unsupported material type"+e.material.type)}return a?.csm.setupMaterial(d),o&&Ae.set(c,d),d.side=e.material.side??d.side??t.FrontSide,d.transparent=(e.material.transparent??l.transparent??!1)||d.transparent,e.material.bloom&&(d.userData.hasBloom=!0),d}async function Me(e,t,a,s,r,i,n,o){const c={};for(const[t,l]of Object.entries(e)){const e=await xe(l,a,s,r,i,n,o);null!=e&&(c[t]=e)}return c}export async function prepareShapeParameters(e){const t={};for(const[a,s]of Object.entries(e)){const e=await xe(s,null,null,null);null!=e&&(t[a]=e)}return t}async function xe(e,t,a,i,n,o,c){if(te.String,null==e||null==e.value||""==e.value)return null;const l=e.value;switch(e.type){case te.Number:case te.FloatNode:let h="string"==typeof l?parseFloat(l):l;return e.type===te.FloatNode?j(h):h;case te.Texture:return await a.getTexture(await t.getAsset(l));case te.Sampler2DNode:return N(await a.getTexture(await t.getAsset(l)));case te.Boolean:return l;case te.BooleanNode:return M(l);case te.Vector2:case te.Vec2Node:if("object"==typeof l){const t=l instanceof Array?(new w).fromArray(l):new w(l.x,l.y);return e.type===te.Vec2Node?F(t):t}return null;case te.Vector3:case te.Vec3Node:if("object"==typeof l){const t=l instanceof Array?(new v).fromArray(l):new v(l.x,l.y,l.z);return e.type===te.Vec3Node?C(t):t}return null;case te.Color:case te.RgbNode:const m=new s(l).convertSRGBToLinear();return e.type===te.RgbNode?D(m):m;case te.String:return l;case te.BaseActor:const d=l;return null==i&&console.warn("Class parameters can not be prepared as actors are not passed in"),i?.get(d);case te.Euler:const p=l;return(new r).fromArray(p);case te.Object3D:return(await a.getMesh(await t.getAsset(l))).scene;case te.Material:return await materialFromAsset(await t.getAsset(l),n,t,a,o);case te.AudioBuffer:return await a.getAudio(await t.getAsset(l));case te.VisualEffect:const f=await t.getAsset(l);if(null==c){console.error("Can not create instance of visual effect because missing actor provider");break}if("vfx"in f)return new ge(c,f);console.error("Using a non-vfx asset for visual effect parameter")}return null}function je(e){return"linear"===e.type?new i(new s(e.color),e.near??100,e.far??1e3):"density"===e.type?new n(e.color,e.density):void console.warn("Invalid fog type",e)}const Ie=new d({color:4229780});async function Pe(e,a,s,i){null==i&&(i=(new ae).identity()),await a(e,s,i);const n=i.clone().multiply(function(e,t){return t.compose((new v).fromArray(e.position),(new u).setFromEuler((new r).fromArray(e.rotation)),(new v).fromArray(e.scale))}(e,new t.Matrix4));return Promise.all((e.children??[]).map((t=>Pe(t,a,e,n))))}export function toSerializedParamType(e){const t=e.constructor.prototype;return t instanceof Number||e===Number?te.Number:t instanceof I||"function"==typeof e.prototype.isFloat?te.FloatNode:t instanceof y||e===y||e.isTexture?te.Texture:t instanceof re||e===V?te.Sampler2DNode:t instanceof Boolean||e===Boolean?te.Boolean:t instanceof x?te.BooleanNode:t instanceof s||e==s?te.Color:t instanceof E||"function"==typeof e.prototype.isRgb?te.RgbNode:t instanceof w||e==w?te.Vector2:t instanceof z||"function"==typeof e.prototype.isVec2?te.Vec2Node:t instanceof v||e==v?te.Vector3:t instanceof k||"function"==typeof e.prototype.isVec3?te.Vec3Node:t instanceof String||e===String?te.String:t instanceof se||e==se||e.prototype instanceof se||e.prototype==se?te.BaseActor:t instanceof r||e==r?te.Euler:t instanceof p||e==p?te.Object3D:t instanceof c||e==c?te.Material:t instanceof AudioBuffer||e==AudioBuffer?te.AudioBuffer:t instanceof ge||e==ge?te.VisualEffect:void console.warn("Failed to map parameter type to serialized version",{type:e})}export function prepareCustomParams(e,t,a={}){return Object.fromEntries(e.map((e=>[e.name,{type:toSerializedParamType(e.type),value:t[e.name]?.value??a[e.name]??customParameterDefaultValueByType.get(toSerializedParamType(e.type))}])))}export function prepareCustomParamsFromType(e,t,a=null){const s=_(e);if(0===s.length)return{};let r;null!=a?pe(a,(()=>{r=a.get(e)})):r=new e;const i={};for(const e of s){const t=r[e.name];if(null!=t){const a=serializeCustomParameter(e.type,t);null!=a&&(i[e.name]=a)}}return prepareCustomParams(s,t,i)}export function serializeCustomParameter(e,t){function a(){console.error("Failed to serialize value",{type:e,value:t})}switch(e){case Number:case Boolean:return t;case w:return t instanceof w?t.toArray():void a();case v:return t instanceof v?t.toArray():void a();case A:return t instanceof A?t.toArray():void a();case s:return t instanceof s?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new s(t).getHexString():void a();case String:return t;case r:return t instanceof r?t.toArray():void a()}}function De(e,t){return function(e,t,a){const s=[],r=new Set;for(const i of[...e??[],...t??[]]){const e=a(i);r.has(e)||(r.add(e),s.push(i))}return s}((e??[]).filter((e=>Ee(e.materialId))),(t??[]).filter((e=>Ee(e.materialId))),(e=>e.color+e.name))}function Ee(e){return"null"!=e&&null!=e}export const customParameterDefaultValueByType=new Map([[te.RgbNode,"#000000"],[te.Color,"#000000"],[te.Vector4,[0,0,0,0]],[te.Vec4Node,[0,0,0,0]],[te.Vector3,[0,0,0]],[te.Vec3Node,[0,0,0]],[te.Vector2,[0,0]],[te.Vec2Node,[0,0]],[te.Euler,[0,0,0,"XYZ"]]]);
1
+ import{Subject as e}from"rxjs";import*as t from"three";import{BoxGeometry as a,Color as s,Euler as r,Fog as i,FogExp2 as n,Group as o,Material as c,Mesh as l,MeshLambertMaterial as h,MeshPhongMaterial as m,MeshStandardMaterial as p,Object3D as d,PointLight as f,Quaternion as u,SphereGeometry as y,Texture as g,Vector2 as w,Vector3 as v,Vector4 as A}from"three";import S,{SpriteRenderer as b}from"three-nebula";import{bool as M,BooleanNode as j,float as x,FloatNode as I,NodeShaderMaterial as P,rgb as D,RgbNode as E,Texture2dLookupNode as V,textureSampler2d as N,vec2 as C,Vec2Node as F,vec3 as k,Vec3Node as z,vec4 as B}from"three-shader-graph";import O from"../gameplay/actors/builtin/index.js";import{extractShaderParameters as _}from"../shader/parameter.js";import{groupBy as T,ArrayMap as $}from"../utils/collections.js";import{filterChildrenShallow as L,filterSceneShallow as R}from"../utils/three/traverse.js";import{AssetMeshInstance as U}from"./asset-resource-loader.js";import{BoxCollisionShape as H,PhysicalShapeMesh as G}from"./collision/collision-shape.js";import{isCollisionMesh as J}from"./collision/collision-shape-import.js";import{initLandscape as X}from"./landscape/landscape.js";import{LandscapeManager as W}from"./landscape/landscape-manager.js";import{SectionGrid as Y,smoothNormalsCrossMeshes as q}from"./landscape/utils.js";import{createGrassMaterial as Z}from"./materials/grass.js";import{createGrassFoliageMaterial as K}from"./materials/grass-foliage.js";import{getMaterialAttribute as Q}from"./materials/utils/material-painting.js";import{createWaterMaterial as ee}from"./materials/water.js";import{SerializedParamType as te}from"./model.js";import{Matrix4 as ae}from"three";import{BaseActor as se}from"../gameplay/actors/actor.js";import{Sampler2DNode as re}from"../shader-nodes/index.js";import{StandardShader as ie}from"../shader/builtin/standard-shader.js";import{LambertShader as ne}from"../shader/builtin/lambert-shader.js";import{ShapeLibrary as oe,ShapeLibraryKeys as ce}from"./objects/shapes.js";import{ambientLightName as le,createSky as he,defaultSkyMaterial as me}from"./sky.js";import{ActorComponent as pe,PhysicsBodyType as de,withInjectionContext as fe}from"../gameplay/index.js";import{iterateMaterials as ue}from"../utils/materials.js";import{VfxActor as ye}from"../effects/vfx/vfx-actor.js";import{VisualEffect as ge}from"../effects/vfx/vfx-param.js";import{findFirstVisibleObject as we}from"../utils/three/traverse.js";const ve={};export const shapeDefaultColor="#aaaaaa";export class SceneMaterializerLoader{constructor(e,t,a){this.dataProvider=e,this.assetsService=t,this.assetManagerService=a}get(e,t){return new SceneMaterializer(e,this.dataProvider,this.assetsService,this.assetManagerService,t,[],[],{create:()=>null,initActor:async()=>{}})}}export class SceneMaterializer{constructor(t,a,s,r,i,n,o,c){this.scene=t,this.dataProvider=a,this.assetsService=s,this.assetManagerService=r,this.renderingView=i,this.shaders=n,this.actorTypes=o,this.actorProvider=c,this.objectMap=new Map,this.sceneObjectMap=new Map,this.components=[],this.landscapeManagers=[],this.materializedActors=new Map,this.inEditor=!0,this.updated$=new e,this.removed$=new e,this.error$=new e,this.editorActorParamSnapshot=new Map,this._canBeInstancedCache=new Map,this._originalMaterials=new Map,this.geometryCache=new Map,this.collisionShapeCache=new Map,this.originalFog=null,a.onUpdate((e=>this.update(e))),a.onRemove((e=>this.remove(e))),this.updateSubscription=s.onUpdate.subscribe((async e=>{"material"==e.type?((await this.assetsService.getAssets()).filter((t=>(t.materialAssignments??[]).some((t=>t.materialId===e.id)))).forEach((e=>{const t=this.findByAssetId(e.id);e.materialAssignments.forEach((e=>{t.forEach((t=>{const a=t.userData.src.materialAssignments;null!=a&&a.some((t=>t.color===e.color))||this.applyMaterial(t,e)}))}))})),R(this.scene,(t=>null!=t.userData.src&&(t.userData.src.materialAssignments??[]).some((t=>t.materialId===e.id))),(e=>null!=e.userData.src)).forEach((async e=>{this.deleteSceneObject(e.userData.src),this.materialize(e.userData.src)}))):"mesh"==e.type?this.findByAssetId(e.id).forEach((t=>{Ee(t.userData.src.materialAssignments,e.materialAssignments).forEach((e=>{this.applyMaterial(t,e)}))})):"prefab"===e.type&&this.findByAssetId(e.id).forEach((e=>{const t=e.userData.src;this.remove(t),this.materializeAndInitActor(t)}))}))}get actorInstances(){return Array.from(this.materializedActors.values())}async prefetchAssets(){const e=Array.from(new Set(this.dataProvider.getObjects().filter((e=>null!=e.assetId&&"asset_mesh"==e.type)).filter((e=>e.assetId))));await Promise.all(e.map((e=>this.assetsService.getAsset(e.assetId).then((e=>e&&this.assetManagerService.getMesh(e))))))}async init(){this.preInit(),Se.clear(),await this.prefetchAssets(),await Promise.all(this.dataProvider.getObjects().map((e=>this.materialize(e)))),await this.initActorsPostInit()}initActorsPostInit(e=this.actorInstances){const t=e.map((async e=>{const t=e.object.userData.src;if("vfx"===t.type)return Promise.resolve();const a=await this.assetsService.getAsset(t.assetId),s={...a?.actor?.params??{},...t.actor?.params??{}};for(const a of t.actor.innerParams??[])await this.applyActorComponentParams(e,a.path.slice(),a.params);const r=await je(s,e.constructor,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders,this.actorProvider);Object.assign(e,r);try{return await this.actorProvider.initActor(e)}catch(e){console.error(`Failed to initiate actor (name="${t.name}", id=${t.id})`,e)}}));return Promise.all(t)}addVfxChildActors(e,t=e){for(const a of Object.keys(t))t[a]instanceof ge?null!=t[a].actor&&(console.log("add actor to world",t[a].actor),e.object.add(t[a].actor.object)):t[a]instanceof pe&&this.addVfxChildActors(e,t[a])}removeVfxChildActors(e,t=e){for(const a of Object.keys(t))if(t[a]instanceof ge){if(null!=t[a].actor){t[a].actor.onEndPlay(),console.log("remve actor from world",t[a].actor),e.object.remove(t[a].actor.object)}}else t[a]instanceof pe&&this.removeVfxChildActors(e,t[a])}async applyActorComponentParams(e,t,a){const s=t.length,r=t.shift();if(0==s){const t=await je(a,null,this.assetsService,this.assetManagerService,this.materializedActors,this.renderingView,this.shaders);for(const[a,s]of Object.entries(t))null!=s&&(e[a]=s)}else null!=e[r]&&await this.applyActorComponentParams(e[r],t,a)}canObjectBeInstanced(e){return e.physics?.type!==de.dynamic}async canAssetBeInstanced(e){if(!this._canBeInstancedCache.has(e.assetId)){const t=await this.createFromAsset(e);if(null==t)return!1;const a=[];t.traverse((e=>{!J(e)&&e.isMesh&&a.push(e)}));const s=1==a.length&&0==a[0].children.length,r=!0;this._canBeInstancedCache.set(e.assetId,s&&r)}return this._canBeInstancedCache.get(e.assetId)}preInit(){this.renderingView?.onLoop((()=>this.sky?.position.copy(this.renderingView.camera.position)))}async initWithInstancing(){this.preInit();const e=new $;for(const t of this.dataProvider.getObjects())await De(t,(async(t,a,s)=>{const r="asset_mesh"==t.type&&this.canObjectBeInstanced(t)&&await this.canAssetBeInstanced(t)?t.assetId+JSON.stringify(t.materialAssignments??[]):"other";"other"!==r&&a&&a.children?.length>0&&a.children.splice(a.children.findIndex((e=>e.id===t.id)),1),"other"===r&&a||e.push(r,{...t,parentTransform:s})}));for(const[t,a]of e.entries())if("other"!==t&&a.length>0){const e=await this.createFromAsset(a[0]);if(null==e)continue;const t=await this.createInstancedMesh(a,e),s=new U;s.add(t),s.userData.src=a[0],e instanceof U&&(s.collisionShapes=e.collisionShapes),s.castShadow=!1,s.receiveShadow=!1,this.scene.add(s)}else await Promise.all(a.map((e=>this.materialize(e))));await this.initActorsPostInit()}async createInstancedMesh(e,a){const s=we(a,(e=>!J(e)&&null!=e.geometry)),i=await this.assetsService.getAsset(e[0].assetId);await this.applyMaterials(a,Ee(e[0].materialAssignments,i.materialAssignments)),s.updateMatrix();const n=s.geometry.clone().applyMatrix4(s.matrix),o=new t.InstancedMesh(n,s.material.clone(),e.length);o.material.side=t.FrontSide;for(let a=0;a<e.length;a++){const s=(new t.Matrix4).compose((new v).fromArray(e[a].position),(new u).setFromEuler((new r).fromArray(e[a].rotation)),(new v).fromArray(e[a].scale)),i=(new ae).copy(e[a].parentTransform).multiply(s);o.setMatrixAt(a,i)}return o.castShadow=i.castShadow??!0,o.receiveShadow=i.receiveShadow??!0,o}remove(e){if(console.log("Remove scene object",e),"global_fog"==e.type)return void(this.scene.fog=this.originalFog);if("actor"==e.type){const t=this.materializedActors.get(e.id);null!=t?(t.disposed.next(!0),t.onEndPlay(),this.removeVfxChildActors(t)):console.warn("Failed to remove actor",e)}const t=this.sceneObjectMap.get(e.id);t?.parent.remove(t),this.sceneObjectMap.delete(e.id),this.components.filter((t=>t.object.userData.src?.id===e.id)).forEach((e=>this.components.splice(this.components.indexOf(e,1)))),this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>{e.clear(),e.stop(),this.landscapeManagers.splice(this.landscapeManagers.indexOf(e,1))})),this.removed$.next({object:t,source:e})}deleteSceneObject(e){const t=this.sceneObjectMap.get(e.id);if(this.scene.remove(t),"landscape"==e.type){const t=this.landscapeManagers.findIndex((t=>t.source.id===e.id));if(t>-1){const e=this.landscapeManagers.splice(t,1)[0];e.clear(),e.stop()}}}findByAssetId(e){return R(this.scene,(t=>t.userData.src?.assetId==e),(e=>null!=e.userData.src))}applyMaterials(e,t){return null==t?Promise.resolve([]):Promise.all(t.filter((e=>"null"!==e.materialId)).map((t=>this.applyMaterial(e,t))))}applyMaterial(e,a){const r=[];return e.traverse((async e=>{if(e instanceof l||e.isMesh||e instanceof t.SkinnedMesh||e.isSkinnedMesh)for(const t of ue(e.material))t.hasOwnProperty("color")&&r.push(e)})),Promise.all(r.map((async e=>{if(e.material instanceof Array)for(let t=0;t<e.material.length;t++){const r=e.material[t];if(null==r.color||!(r.color instanceof s))continue;const i="#"+r.color.getHexString(),n=r.name;if(i===a.color&&(r.name===a.name||null==a.name)||e.userData["originalColor_"+t]===a.color&&e.userData["originalMaterialName_"+t]===a.name){const s=await this.assetsService.getAsset(a.materialId),r=e.material[t];s&&(e.material[t]=await materialFromAsset(s,this.renderingView,this.assetsService,this.assetManagerService,this.shaders),e.userData["originalColor_"+t]=e.userData["originalColor_"+t]??i,e.userData["originalMaterialName_"+t]=e.userData["originalMaterialName_"+t]??n,this.inEditor&&this._originalMaterials.set(e.id+"#"+t,r))}}else{const t="#"+e.material.color.getHexString(),s=e.material.name;if(t===a.color&&(e.material.name===a.name||null==a.name)||e.userData.originalColor===a.color&&e.userData.originalName===a.name){const r=await this.assetsService.getAsset(a.materialId),i=e.material;r&&(e.material=await materialFromAsset(r,this.renderingView,this.assetsService,this.assetManagerService,this.shaders),e.userData.originalColor=e.userData.originalColor??t,e.userData.originalMaterialName=e.userData.originalMaterialName??s,this.inEditor&&this._originalMaterials.set(e.id,i))}}})))}unapplyMaterials(e){e.traverse((async e=>{if(e instanceof l)if(e.material instanceof Array)for(let t=0;t<e.material.length;t++)e.material[t]=this._originalMaterials.get(e.id+"#"+t)??e.material[t];else e.material=this._originalMaterials.get(e.id)??e.material}))}updateActors(e){console.log("update actors"),this.actorTypes=e;const t=new Set(Object.values(O));R(this.scene,(e=>e.userData.src?.id&&"actor"===e.userData.src.type&&this.materializedActors.has(e.userData.src?.id)&&!t.has(e.userData.src.actor.type))).forEach((async e=>{this.remove(e.userData.src),await this.materializeAndInitActor(e.userData.src)}))}updateShaders(e){this.shaders=e;for(const[e,t]of Se.entries())t.userData.customShaderName&&Se.delete(e);this.landscapeManagers.forEach((t=>t.updateShaders(e))),R(this.scene,(e=>!0)).forEach((e=>{e.traverse((e=>{if(e instanceof l){const t=e.material.userData?.customShaderName;if(null!=t){const t=function(e,t){if(t(e))return e;let a;return e.traverseAncestors((e=>{null==a&&t(e)&&(a=e)})),a}(e,(e=>null!=e.userData.src?.id))?.userData.src;null!=t&&this.update(t)}}}))}))}async update(e){if("sky"===e.type&&null!=this.sky&&null!=this.sky.parent)return void this.updateSky(e);const t=this.sceneObjectMap.get(e.id);if(t){let r=!1;if(t.traverseAncestors((e=>{"_hology_transform_group"===e.name&&(r=!0)})),!r){const a=this.findParent(e);null!=a&&a.uuid!=t.uuid?a.attach(t):console.error("Parent is wrong")}if("prefab"!==e.type&&"group"!==e.type){this.unapplyMaterials(t);this.inEditor&&e.hidden&&!1?t.traverse((e=>{e instanceof l&&(e.material.wireframe=!0)})):t.traverse((e=>{e instanceof l&&(e.material.wireframe=!1)}))}if("asset_mesh"===e.type){const a=await this.assetsService.getAsset(e.assetId);Ee(e.materialAssignments,a.materialAssignments).forEach((e=>this.applyMaterial(t,e)))}else"shape_mesh"===e.type&&this.applyMaterials(t,e.materialAssignments);if(r||(null!=e.position&&t.position.fromArray(e.position),null!=e.scale&&t.scale.fromArray(e.scale),null!=e.rotation&&t.rotation.fromArray(e.rotation)),this.applyVertexMaterials(e,t),"light"==e.type)if("point"==e.light.type){const a=t;a.color=new s(e.light.point.color),a.intensity=e.light.point.intensity,a.decay=e.light.point.decay,a.castShadow=e.light.point.castShadow,a.distance=Math.max(e.light.point.distance,0)}else"directional"===e.light.type?this.applyDirectionalLight(e.light.directional):"ambient"===e.light.type&&this.applyDirectionalAmbientLight(t,e.light.ambient);else if("landscape"===e.shape)this.applyHeightMaps(t,e.landscape.heightMaps),this.inEditor&&this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>!0))));else if("global_fog"===e.type){const t=(this.scene.fog instanceof n?"density":"linear")!==e.fog.type;this.scene.fog=Ie(e.fog),t&&(a=this.scene).traverse((e=>{if(e instanceof l){const t=e.material;t instanceof P&&(a.fog instanceof i?(t.uniforms.fogFar.value=a.fog.far,t.uniforms.fogNear.value=a.fog.near):a.fog instanceof n&&(t.uniforms.density={value:a.fog.density}),t.needsUpdate=!0,t.uniformsNeedUpdate=!0)}})),this.fixFogColor()}else if("actor"===e.type){if(this.materializedActors.has(e.id)){const t=this.editorActorParamSnapshot.get(e.id);null!=t&&t===JSON.stringify(e.actor)||(console.log("Rematerializing actor because parameters changed"),this.remove(e),await this.materializeAndInitActor(e))}}else if("shape_mesh"===e.type){const a=await this.createMeshByShape(e.shape,t.material,e.shapeParams);t instanceof G&&(t.geometry=a.geometry,t.collisionShape=a.collisionShape)}("asset_mesh"===e.type||"shape_mesh"===e.type&&"landscape"!==e.shape)&&Ae(t,e.castShadow,e.receiveShadow),e.name&&e.name.length>0&&(t.name=e.name),this.updated$.next({object:t,source:e})}else{const t=await this.materializeAndInitActor(e);this.updated$.next({object:t,source:e})}var a}async materializeAndInitActor(e,t=this.findParent(e)){console.log("materialize actor and init");const a=await this.materialize(e,t);return De(e,(async e=>{if("actor"===e.type){const t=this.materializedActors.get(e.id);null!=t?await this.initActorsPostInit([t]):console.error(`Something went wrong when creating actor ${e.id}`)}})),a}findParent(e){const t=this.dataProvider.getObjects().flatMap((t=>t.id===e.id?null:L(t,(t=>t.children?.some((t=>t.id===e.id))),(()=>!0))))[0];return null==t?this.scene:null!=t?R(this.scene,(e=>e.userData?.src?.id===t.id),(e=>null!=e.userData?.src))[0]:void 0}fixFogColor(){!0===this.renderingView.options.enableOutlines&&(this.scene.fog.color=new s(this.scene.fog.color).convertSRGBToLinear())}findMeshWithGeometry(e){let t;return e.traverse((e=>{e instanceof l&&e.geometry&&(t=e)})),t}applyVertexMaterials(e,t){if(null==e.vertexMaterials||0===e.vertexMaterials.length)return;const a=T(e.vertexMaterials,(e=>e.m));t.traverse((e=>{if(e instanceof l){const t=Q(e,!1);if(null!=t){for(let e=0;e<t.array.length;e++)t.setX(e,0);t.needsUpdate=!0}}}));const s=new Set;for(const[e,r]of a.entries()){const a=null!=e?t.getObjectByName(e):this.findMeshWithGeometry(t);let i=!1;if(null==a)return void console.warn(`Failed to apply vertex materials on mesh with name "${e}"`);const n=Q(a,!0);for(let e=0;e<n.array.length;e++)n.setX(e,0);for(const e of r)n.setX(e.i,e.w[0]),n.setY(e.i,e.w[1]),n.setZ(e.i,e.w[2]),i=!0;i&&s.add(e)}this.inEditor&&this.landscapeManagers.filter((t=>t.source.id===e.id)).forEach((e=>e.queueRefreshScatter(this.renderingView.camera.position,!0,(e=>s.has(e.name)))))}async materialize(e,t,s=!1){let r;switch(e.type){case"asset_mesh":r=await this.createFromAsset(e);break;case"shape_mesh":r=await this.createFromShape(e);break;case"light":r=await this.createLight(e);break;case"particles":r=await this.createParticleSystem(e),e.collisionDetection=!1;break;case"global_fog":this.scene.fog=Ie(e.fog),this.fixFogColor(),r=new o;break;case"sky":this.sky=he(),this.updateSky(e),r=this.sky;break;case"actor":r=await this.createFromActor(e);break;case"group":r=new o;break;case"prefab":r=await this.createFromPrefabAsset(e);break;case"vfx":r=await this.createFromVfx(e);break;default:if(this.inEditor)throw new Error("unknown type "+e.type);console.warn(`Failed to materialize object. Unknown type '${e.type}'. This might be because the hology/core library is not compatible with the editor version.`)}if(null!=r){if(e.name&&e.name.length>0&&(r.name=e.name),null!=e.position&&r.position.fromArray(e.position),null!=e.scale&&r.scale.fromArray(e.scale),null!=e.rotation&&r.rotation.fromArray(e.rotation),s||(r.userData.src=e),this.inEditor,this.inEditor){let e=null;r instanceof G&&(e=function(e){if(e instanceof H)return new l(new a(...e.offset.toArray()),Pe);return null}(r.collisionShape)),null!=e&&(e.layers.disable(0),e.layers.enable(18),e.scale.multiplyScalar(1.1),r.add(e))}return this.objectMap.set(r.uuid,e),this.sceneObjectMap.set(e.id,r),null==t?this.scene.add(r):t?.add(r),null!=e.children&&await Promise.all(e.children?.map((e=>this.materialize(e,r,s)))),r}}async updateSky(e){if(null==e?.sky?.materialId)return void(this.sky.material=me);const a=await this.assetsService.getAsset(e.sky.materialId),s=await materialFromAsset(a,this.renderingView,this.assetsService,this.assetManagerService,this.shaders,!1);s.side=t.BackSide,null!=this.sky?this.sky.material=s:console.warn("No sky has been created")}async createComponent(e,t,a,s){const r=new ve[a.path+"/"+a.className],i=t.id+s;r.id=i,r.object=e;for(const e of a.params)null!=e.value&&(r[e.name]=e.value);return this.components.push(r),i}async createFromActor(e){const t=this.actorTypes.find((t=>t.name===e.actor?.type))?.type??O[e.actor?.type];if(null==t)return null;this.inEditor&&this.editorActorParamSnapshot.set(e.id,JSON.stringify(e.actor));const a=await this.actorProvider.create(t,(new v).fromArray(e.position),(new r).fromArray(e.rotation),!0);return this.materializedActors.set(e.id,a),a?.object}async createFromVfx(e){const t=await this.assetsService.getAsset(e.assetId);null==t&&console.error("Could not find asset",e);const a=await this.actorProvider.create(ye,(new v).fromArray(e.position),(new r).fromArray(e.rotation),!1);return await a.fromAsset(t),a.play(),this.materializedActors.set(e.id,a),a?.object}cleanup(){this.materializedActors.clear()}async createFromShape(e){const t=this.inEditor&&e.hidden;let a;if("landscape"==e.shape)a=this.createLandscape(e);else{let r=new p({name:"Default",color:new s("#aaaaaa"),visible:this.inEditor||!e.hidden,wireframe:!!t});const i=await this.createMeshByShape(e.shape,r,e.shapeParams);i.castShadow=e.castShadow??!0,i.receiveShadow=e.castShadow??!1,e.collisionDetection||(i.collisionShape=null),i.physics=e.physics,a=i,this._originalMaterials.set(a.id,i.material),a.traverse((e=>{}))}return t||((e.materialAssignments??[]).filter((e=>null!=e.materialId)).forEach((e=>this.applyMaterial(a,e))),this.applyVertexMaterials(e,a)),a}createLandscape(e){const t=e.landscape?.options;if(null==t)return console.error(`No landscape options exist on scene object ${e.id} ${e.name}`),new o;const a=X(e.landscape.options);this.applyHeightMaps(a,e.landscape.heightMaps,!0);const s=new W(e,this.renderingView,a,this.assetManagerService,this.assetsService,this.shaders,(t=>{(e.materialAssignments??[]).filter((e=>null!=e.materialId)).forEach((e=>this.applyMaterial(t,e)))}));return this.landscapeManagers.push(s),s.refreshGeometry(),a}applyHeightMaps(e,t,a=!1){const s=new Y(e.sections);for(const e of t??[]){const t=s.find(e.x,e.y);if(!t)return;const a=t.geometry.getAttribute("position");for(const t of e.points)a.setY(t.i,t.y);a.needsUpdate=!0}const r=e.sections;r.forEach((e=>{e.geometry.computeBoundsTree(),e.geometry.computeVertexNormals()})),this.inEditor&&!a||setTimeout((()=>q(r)),50)}async createMeshByShape(e,t,a={}){if("landscape"!==e&&ce.includes(e)){const s=await prepareShapeParameters(a??{}),r=e+JSON.stringify(a);return this.geometryCache.has(r)||this.geometryCache.set(r,oe[e].geometry(s)),this.collisionShapeCache.has(r)||this.collisionShapeCache.set(r,oe[e].collision(s)),new G(this.geometryCache.get(r),t,this.collisionShapeCache.get(r))}if(this.inEditor)throw new Error(`Unsupported shape '${e}'`);console.warn(`Failed to create shape. Unsupported shape '${e}'. This might be because the hology/core library is not compatible with the editor version.`)}async createFromAsset(e){const t=await this.assetsService.getAsset(e.assetId);if(null==t)return void console.warn(`Can not find asset with id ${e.assetId} and name ${e.name}`);let{scene:a}=await this.assetManagerService.getMesh(t);Ee(e.materialAssignments,t.materialAssignments).forEach((e=>this.applyMaterial(a,e)));const s=e.receiveShadow??!!t.receiveShadow??!0,r=e.castShadow??!!t.castShadow??!1;return a.receiveShadow=s,Ae(a,r,s),e.collisionDetection||(a.collisionShapes=[]),null!=e.physics&&!0!==this.inEditor&&(a.physics=e.physics),this.applyVertexMaterials(e,a),a.traverse((e=>{e instanceof l&&"computeBoundsTree"in e.geometry&&e.geometry.computeBoundsTree()})),a}async createFromPrefabAsset(e){const t=await this.assetsService.getAsset(e.assetId);if(null==t)return void console.warn(`Can not find asset with id ${e.assetId} and name ${e.name}`);const a=new o;return t.prefab.objects.filter((e=>"global_fog"!==e.type)).forEach((e=>this.materialize(e,a,!0))),a}async createParticleSystem(e){const a=await this.assetsService.getAsset(e.assetId),s=new d;return await S.fromJSONAsync(a.particleSystem,t).then((e=>{const a=new b(s,t);e.addRenderer(a),this.renderingView.onLoop((t=>e.update()))})),s}async createLight(e){if("point"===e.light.type){const t=new f(e.light.point.color,e.light.point.intensity,e.light.point.distance,e.light.point.decay);if(t.castShadow=e.light.point.castShadow??!0,this.inEditor){const e=new y(.3,10,10),a=new p({color:new s(16771709)}),r=new l(e,a);t.add(r)}return t}return"directional"===e.light.type?(this.applyDirectionalLight(e.light.directional),new o):"ambient"===e.light.type?(this.applyDirectionalAmbientLight(null,e.light.ambient),new o):void 0}applyDirectionalAmbientLight(e,t){const a=this.scene.children.find((e=>e.name===le));null!=a?(a.intensity=t.intensity,a.color.set(t.color),a.groundColor.set(t.color)):console.warn("Couldn't find ambient light")}applyDirectionalLight(e){for(const t of this.renderingView.csm.lights)t.intensity=e.intensity,t.color.set(e.color),t.castShadow=e.castShadow;this.renderingView.csm.lightDirection.fromArray(e.direction).normalize()}dispose(){this.updateSubscription.unsubscribe(),this.materializedActors.forEach((e=>e.disposed.next(!0)))}}function Ae(e,t,a){e.castShadow=t,e.receiveShadow=a,e.traverse((e=>{e.castShadow=t,e.receiveShadow=a}))}const Se=new Map,be=new h({color:16711935}),Me=new Map;export async function materialFromAsset(e,a,r,i,n,o=!0){const c=JSON.stringify(e.material);if(o&&Se.has(c))return Se.get(c);const l={opacity:e.material.params.opacity,map:null,emissive:e.material.params.emissive??null,metalness:e.material.params.metalness??0,flatShading:e.material.params.flatShading??!1,color:new s(e.material.params.color).convertSRGBToLinear(),transparent:null!=e.material.params.opacity&&e.material.params.opacity<1},h={};if(null!=e.material.params.map){const t=e.material.params.map,a=await r.getAsset(t);null!=a&&(l.map=await i.getTexture(a))}let p;switch(e.material.type){case"phong":p=new m({...l,...h});break;case"water":p=ee(l,a);break;case"grassFoliage":p=K({color:l.color,map:l.map},a);break;case"grass":p=Z({...l,colorTwo:new s(e.material.params.colorTwo),colorThree:new s(e.material.params.colorThree)},a);break;case"standard":case"lambert":case"shader":const t={standard:ie,lambert:ne}[e.material.type]??n.find((t=>t.name==e.material.shader))?.type;if(t){const s=new t,o=await je(e.material?.shaderParams??{},t,r,i,null,a,n);Object.assign(s,o);try{p=s.build()}catch(t){console.log("Shader runtime error: "+t),Me.has(e.material.shader)||Me.set(e.material.shader,be.clone()),p=Me.get(e.material.shader)}p.userData.customShaderName=e.material.shader}else console.warn("Missing shader implementation with name "+e.material.shader),p=be;break;default:throw new Error("Unsupported material type"+e.material.type)}return a?.csm.setupMaterial(p),o&&Se.set(c,p),p.side=e.material.side??p.side??t.FrontSide,p.transparent=(e.material.transparent??l.transparent??!1)||p.transparent,e.material.bloom&&(p.userData.hasBloom=!0),p}async function je(e,t,a,s,r,i,n,o){const c={};for(const[t,l]of Object.entries(e)){const e=await xe(l,a,s,r,i,n,o);null!=e&&(c[t]=e)}return c}export async function prepareShapeParameters(e){const t={};for(const[a,s]of Object.entries(e)){const e=await xe(s,null,null,null);null!=e&&(t[a]=e)}return t}async function xe(e,t,a,i,n,o,c){if(te.String,null==e||null==e.value||""==e.value)return null;const l=e.value;switch(e.type){case te.Number:case te.FloatNode:let h="string"==typeof l?parseFloat(l):l;return e.type===te.FloatNode?x(h):h;case te.Texture:return await a.getTexture(await t.getAsset(l));case te.Sampler2DNode:return N(await a.getTexture(await t.getAsset(l)));case te.Boolean:return l;case te.BooleanNode:return M(l);case te.Vector2:case te.Vec2Node:if("object"==typeof l){const t=l instanceof Array?(new w).fromArray(l):new w(l.x,l.y);return e.type===te.Vec2Node?C(t):t}return null;case te.Vector3:case te.Vec3Node:if("object"==typeof l){const t=l instanceof Array?(new v).fromArray(l):new v(l.x,l.y,l.z);return e.type===te.Vec3Node?k(t):t}return null;case te.Color:case te.RgbNode:const m=new s(l).convertSRGBToLinear();return e.type===te.RgbNode?D(m):m;case te.String:return l;case te.BaseActor:const p=l;return null==i&&console.warn("Class parameters can not be prepared as actors are not passed in"),i?.get(p);case te.Euler:const d=l;return(new r).fromArray(d);case te.Object3D:return(await a.getMesh(await t.getAsset(l))).scene;case te.Material:return await materialFromAsset(await t.getAsset(l),n,t,a,o);case te.AudioBuffer:return await a.getAudio(await t.getAsset(l));case te.VisualEffect:const f=await t.getAsset(l);if(null==c){console.error("Can not create instance of visual effect because missing actor provider");break}if("vfx"in f)return new ge(c,f);console.error("Using a non-vfx asset for visual effect parameter")}return null}function Ie(e){return"linear"===e.type?new i(new s(e.color),e.near??100,e.far??1e3):"density"===e.type?new n(e.color,e.density):void console.warn("Invalid fog type",e)}const Pe=new p({color:4229780});async function De(e,a,s,i){null==i&&(i=(new ae).identity()),await a(e,s,i);const n=i.clone().multiply(function(e,t){return t.compose((new v).fromArray(e.position),(new u).setFromEuler((new r).fromArray(e.rotation)),(new v).fromArray(e.scale))}(e,new t.Matrix4));return Promise.all((e.children??[]).map((t=>De(t,a,e,n))))}export function toSerializedParamType(e){const t=e.constructor.prototype;return t instanceof Number||e===Number?te.Number:t instanceof I||"function"==typeof e.prototype.isFloat?te.FloatNode:t instanceof g||e===g||e.isTexture?te.Texture:t instanceof re||e===V?te.Sampler2DNode:t instanceof Boolean||e===Boolean?te.Boolean:t instanceof j?te.BooleanNode:t instanceof s||e==s?te.Color:t instanceof E||"function"==typeof e.prototype.isRgb?te.RgbNode:t instanceof w||e==w?te.Vector2:t instanceof F||"function"==typeof e.prototype.isVec2?te.Vec2Node:t instanceof v||e==v?te.Vector3:t instanceof z||"function"==typeof e.prototype.isVec3?te.Vec3Node:t instanceof String||e===String?te.String:t instanceof se||e==se||e.prototype instanceof se||e.prototype==se?te.BaseActor:t instanceof r||e==r?te.Euler:t instanceof d||e==d?te.Object3D:t instanceof c||e==c?te.Material:t instanceof AudioBuffer||e==AudioBuffer?te.AudioBuffer:t instanceof ge||e==ge?te.VisualEffect:void console.warn("Failed to map parameter type to serialized version",{type:e})}export function prepareCustomParams(e,t,a={}){return Object.fromEntries(e.map((e=>[e.name,{type:toSerializedParamType(e.type),value:t[e.name]?.value??a[e.name]??customParameterDefaultValueByType.get(toSerializedParamType(e.type))}])))}export function prepareCustomParamsFromType(e,t,a=null){const s=_(e);if(0===s.length)return{};let r;null!=a?fe(a,(()=>{r=a.get(e)})):r=new e;const i={};for(const e of s){const t=r[e.name];if(null!=t){const a=serializeCustomParameter(e.type,t);null!=a&&(i[e.name]=a)}}return prepareCustomParams(s,t,i)}export function serializeCustomParameter(e,t){function a(){console.error("Failed to serialize value",{type:e,value:t})}switch(e){case Number:case Boolean:return t;case w:return t instanceof w?t.toArray():void a();case v:return t instanceof v?t.toArray():void a();case A:return t instanceof A?t.toArray():void a();case s:return t instanceof s?"#"+t.getHexString():"string"==typeof t?t:"number"==typeof t?"#"+new s(t).getHexString():void a();case String:return t;case r:return t instanceof r?t.toArray():void a()}}function Ee(e,t){return function(e,t,a){const s=[],r=new Set;for(const i of[...e??[],...t??[]]){const e=a(i);r.has(e)||(r.add(e),s.push(i))}return s}((e??[]).filter((e=>Ve(e.materialId))),(t??[]).filter((e=>Ve(e.materialId))),(e=>e.color+e.name))}function Ve(e){return"null"!=e&&null!=e}export const customParameterDefaultValueByType=new Map([[te.RgbNode,"#000000"],[te.Color,"#000000"],[te.Vector4,[0,0,0,0]],[te.Vec4Node,[0,0,0,0]],[te.Vector3,[0,0,0]],[te.Vec3Node,[0,0,0]],[te.Vector2,[0,0]],[te.Vec2Node,[0,0]],[te.Euler,[0,0,0,"XYZ"]]]);
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -105,7 +105,13 @@ export interface SceneData {
105
105
  name: string;
106
106
  fileKey: string;
107
107
  }
108
- export interface SceneBlob {
108
+ export type SceneBlob = {
109
+ id: string;
110
+ name: string;
111
+ data: SceneObject[];
112
+ sceneId: string;
113
+ } | SceneBlobV0;
114
+ export interface SceneBlobV0 {
109
115
  id: string;
110
116
  name: string;
111
117
  data: string;
@@ -1,3 +1,4 @@
1
+ import { SceneObject } from './materializer.js';
1
2
  import { Asset, SceneData } from './model.js';
2
3
  export declare class RuntimeBackendService {
3
4
  private sceneStorage;
@@ -8,5 +9,5 @@ export declare class RuntimeBackendService {
8
9
  getAsset(id: string): Promise<Asset>;
9
10
  getScenes(): Promise<SceneData[]>;
10
11
  getScene(idOrName: string): Promise<SceneData>;
11
- getSceneData(sceneId: string): Promise<string>;
12
+ getSceneData(sceneId: string): Promise<SceneObject[]>;
12
13
  }
@@ -1,4 +1,4 @@
1
- import{ObjectStorage as e}from"./storage/storage.js";export class RuntimeBackendService{constructor(t){this.sceneStorage=new e("scene"),this.sceneBlobStorage=new e("scene-blob"),this.assetStorage=new e("asset"),this.sceneStorage.setBasePath(t),this.sceneBlobStorage.setBasePath(t),this.assetStorage.setBasePath(t)}getAssets(){return this.assetStorage.getAll()}getAsset(e){return this.assetStorage.get(e)}getScenes(){return this.sceneStorage.getAll()}getScene(e){return this.sceneStorage.get(e)}async getSceneData(e){const t=await this.sceneBlobStorage.get(e);return t?.data}}
1
+ import{ObjectStorage as e}from"./storage/storage.js";export class RuntimeBackendService{constructor(t){this.sceneStorage=new e("scene"),this.sceneBlobStorage=new e("scene-blob"),this.assetStorage=new e("asset"),this.sceneStorage.setBasePath(t),this.sceneBlobStorage.setBasePath(t),this.assetStorage.setBasePath(t)}getAssets(){return this.assetStorage.getAll()}getAsset(e){return this.assetStorage.get(e)}getScenes(){return this.sceneStorage.getAll()}getScene(e){return this.sceneStorage.get(e)}async getSceneData(e){const t=await this.sceneBlobStorage.get(e);return null==t?null:"string"==typeof t.data?JSON.parse(t.data):t.data}}
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -7,7 +7,7 @@ export declare class SceneDataService implements SceneDataProvider {
7
7
  private removeCallbacks;
8
8
  objectChange: BehaviorSubject<SceneObject[]>;
9
9
  constructor();
10
- initiate(data: string): void;
10
+ initiate(data: SceneObject[]): void;
11
11
  private createDefaultObjects;
12
12
  removeOnUpdateCallback(callback: (sceneObject: SceneObject) => void): void;
13
13
  onUpdate(callback: (sceneObject: SceneObject) => void): void;
@@ -1,4 +1,4 @@
1
- import{BehaviorSubject as t}from"rxjs";import{Matrix4 as e,Vector3 as s,Quaternion as i,Euler as o}from"three";export class SceneDataService{constructor(){this.objects=[],this.callbacks=[],this.removeCallbacks=[],this.objectChange=new t([])}initiate(t){this.objects=t?JSON.parse(t)??[]:[],this.objectChange.next(this.objects)}createDefaultObjects(){this.objects.some((t=>"global_fog"===t.type))||this.objects.unshift(createInitialFog());this.objects.some((t=>"sky"===t.type))||this.objects.unshift(createInitialSky())}removeOnUpdateCallback(t){this.callbacks.splice(this.callbacks.indexOf(t),1)}onUpdate(t){this.callbacks.push(t)}onRemove(t){this.removeCallbacks.push(t)}getObjects(){return this.objects}addObject(t){this.objects.push(t),this.callbacks.forEach((e=>e(t))),this.objectChange.next(this.objects)}updateObject(t){const e=this.findObjectById(t.id);e?(Object.assign(e,t),this.callbacks.forEach((e=>e(t)))):this.addObject(t),this.objectChange.next(this.objects)}findObjectById(t){const e=[...this.objects];for(;e.length>0;){const s=e.pop();if(s.id===t)return s;s.children&&e.push(...s.children)}}findAncestorsById(t){const e=this.findParentById(t);return null==e?[]:[e,...this.findAncestorsById(e.id)]}findParentById(t){return this._findParentById(t,this.objects)}_findParentById(t,e,s=null){return e.some((e=>e.id===t))?s:e.filter((t=>null!=t.children)).map((e=>this._findParentById(t,e.children,e))).find((t=>null!=t))}updateParent(t,n){const r=this.findParentById(t.id);{const c=null!=n?this.getMatrixWorld(n).invert():(new e).identity();null!=r&&c.multiply(this.getMatrixWorld(r));const a=this.getLocalMatrix(t),l=c.multiply(a),h=new s,d=new i,b=new s;l.decompose(h,d,b),t.position=h.toArray(),t.rotation=(new o).setFromQuaternion(d).toArray(),t.scale=b.toArray()}this.removeRecursive(t.id,r?.children??this.objects),null!=n?(n.children??=[],n.children.push(t)):this.objects.push(t),this.objectChange.next(this.objects),this.callbacks.forEach((e=>e(t)))}getMatrixWorld(t){const e=this.findAncestorsById(t.id).reverse();e.push(t);const s=this.getLocalMatrix(e.shift());for(const t of e){const e=this.getLocalMatrix(t);s.multiply(e)}return s}getLocalMatrix(t){const n=new e,r=(new s).fromArray(t.position),c=(new i).setFromEuler((new o).fromArray(t.rotation)),a=(new s).fromArray(t.scale);return n.compose(r,c,a),n}removeObject(t){this.removeRecursive(t.id,this.objects),this.removeCallbacks.forEach((e=>e(t))),this.objectChange.next([...this.objects])}removeRecursive(t,e){const s=e.findIndex((e=>e.id===t));if(s>-1)e.splice(s,1);else for(const s of e)this.removeRecursive(t,s.children??[])}save(){}serialize(){return JSON.stringify(this.objects)}}export function createInitialFog(){return{id:"auto-global-fog",name:"Global fog",type:"global_fog",position:[0,0,0],scale:[1,1,1],rotation:[0,0,0],collisionDetection:!1,fog:{type:"density",color:"#b8f8ff",density:.005,near:100,far:1e3}}}export function createInitialSky(){return{id:"auto-sky",name:"Sky",type:"sky",position:[0,0,0],scale:[1,1,1],rotation:[0,0,0],collisionDetection:!1,sky:{materialId:null}}}
1
+ import{BehaviorSubject as t}from"rxjs";import{Matrix4 as e,Vector3 as s,Quaternion as i,Euler as o}from"three";export class SceneDataService{constructor(){this.objects=[],this.callbacks=[],this.removeCallbacks=[],this.objectChange=new t([])}initiate(t){this.objects=t??[],this.objectChange.next(this.objects)}createDefaultObjects(){this.objects.some((t=>"global_fog"===t.type))||this.objects.unshift(createInitialFog());this.objects.some((t=>"sky"===t.type))||this.objects.unshift(createInitialSky())}removeOnUpdateCallback(t){this.callbacks.splice(this.callbacks.indexOf(t),1)}onUpdate(t){this.callbacks.push(t)}onRemove(t){this.removeCallbacks.push(t)}getObjects(){return this.objects}addObject(t){this.objects.push(t),this.callbacks.forEach((e=>e(t))),this.objectChange.next(this.objects)}updateObject(t){const e=this.findObjectById(t.id);e?(Object.assign(e,t),this.callbacks.forEach((e=>e(t)))):this.addObject(t),this.objectChange.next(this.objects)}findObjectById(t){const e=[...this.objects];for(;e.length>0;){const s=e.pop();if(s.id===t)return s;s.children&&e.push(...s.children)}}findAncestorsById(t){const e=this.findParentById(t);return null==e?[]:[e,...this.findAncestorsById(e.id)]}findParentById(t){return this._findParentById(t,this.objects)}_findParentById(t,e,s=null){return e.some((e=>e.id===t))?s:e.filter((t=>null!=t.children)).map((e=>this._findParentById(t,e.children,e))).find((t=>null!=t))}updateParent(t,n){const r=this.findParentById(t.id);{const c=null!=n?this.getMatrixWorld(n).invert():(new e).identity();null!=r&&c.multiply(this.getMatrixWorld(r));const a=this.getLocalMatrix(t),l=c.multiply(a),h=new s,d=new i,b=new s;l.decompose(h,d,b),t.position=h.toArray(),t.rotation=(new o).setFromQuaternion(d).toArray(),t.scale=b.toArray()}this.removeRecursive(t.id,r?.children??this.objects),null!=n?(n.children??=[],n.children.push(t)):this.objects.push(t),this.objectChange.next(this.objects),this.callbacks.forEach((e=>e(t)))}getMatrixWorld(t){const e=this.findAncestorsById(t.id).reverse();e.push(t);const s=this.getLocalMatrix(e.shift());for(const t of e){const e=this.getLocalMatrix(t);s.multiply(e)}return s}getLocalMatrix(t){const n=new e,r=(new s).fromArray(t.position),c=(new i).setFromEuler((new o).fromArray(t.rotation)),a=(new s).fromArray(t.scale);return n.compose(r,c,a),n}removeObject(t){this.removeRecursive(t.id,this.objects),this.removeCallbacks.forEach((e=>e(t))),this.objectChange.next([...this.objects])}removeRecursive(t,e){const s=e.findIndex((e=>e.id===t));if(s>-1)e.splice(s,1);else for(const s of e)this.removeRecursive(t,s.children??[])}save(){}serialize(){return JSON.stringify(this.objects)}}export function createInitialFog(){return{id:"auto-global-fog",name:"Global fog",type:"global_fog",fog:{type:"density",color:"#b8f8ff",density:.005,near:100,far:1e3}}}export function createInitialSky(){return{id:"auto-sky",name:"Sky",type:"sky",sky:{materialId:null}}}
2
2
  /*
3
3
  * Copyright (©) 2023. All rights reserved.
4
4
  * See the LICENSE.md file for details.
@@ -1,6 +1,6 @@
1
1
  import { Object3D, Vector3 } from 'three';
2
2
  type ObjectPredicate<T> = (obj: T) => boolean;
3
- export declare function filterScene(scene: Object3D, predicate: ObjectPredicate<Object3D>): any[];
3
+ export declare function filterScene(scene: Object3D, predicate: ObjectPredicate<Object3D>): Object3D<import("three").Event>[];
4
4
  export declare function findFirstVisibleObject(scene: Object3D, predicate: ObjectPredicate<Object3D>): Object3D;
5
5
  /**
6
6
  * Only continue traverse through children if it has not yet matched.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hology/core",
3
- "version": "0.0.41",
3
+ "version": "0.0.42",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",