@hology/core 0.0.213 → 0.0.215
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/project-config.d.ts +1 -0
- package/dist/effects/sequence/sequence-action.d.ts +4 -0
- package/dist/effects/sequence/sequence-actor.js +1 -1
- package/dist/effects/sequence/sequence-animation-retiming.d.ts +2 -1
- package/dist/effects/sequence/sequence-animation-retiming.js +1 -1
- package/dist/effects/sequence/sequence-data.d.ts +6 -0
- package/dist/effects/sequence/sequence-data.js +1 -1
- package/dist/effects/sequence/sequence-player.d.ts +11 -0
- package/dist/effects/sequence/sequence-player.js +1 -1
- package/dist/effects/vfx/initializsers.d.ts +4 -0
- package/dist/effects/vfx/initializsers.js +1 -1
- package/dist/effects/vfx/vfx-collision-behaviour.js +1 -1
- package/dist/effects/vfx/vfx-materializer.js +1 -1
- package/dist/gameplay/actors/actor.d.ts +6 -0
- package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-movement-like.d.ts +3 -0
- package/dist/gameplay/actors/builtin/components/character/character-movement.d.ts +22 -0
- package/dist/gameplay/actors/builtin/components/character/character-movement.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-slide.d.ts +7 -0
- package/dist/gameplay/actors/builtin/components/character/character-slide.js +4 -0
- package/dist/gameplay/actors/builtin/components/character/modes.d.ts +2 -1
- package/dist/gameplay/actors/builtin/components/character/modes.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.d.ts +3 -1
- package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.js +1 -1
- package/dist/gameplay/actors/builtin/navmesh-actor.js +1 -1
- package/dist/gameplay/actors/camera/third-person-camera-component.d.ts +1 -0
- package/dist/gameplay/actors/camera/third-person-camera-component.js +1 -1
- package/dist/gameplay/actors/component.d.ts +6 -0
- package/dist/gameplay/ai/behavior-tree/move.js +1 -1
- package/dist/gameplay/ai/dynamic-tiled-navmesh.d.ts +20 -2
- package/dist/gameplay/ai/dynamic-tiled-navmesh.js +1 -1
- package/dist/gameplay/animation/animation-action.d.ts +3 -0
- package/dist/gameplay/animation/animation-action.js +4 -0
- package/dist/gameplay/animation/retarget.js +1 -1
- package/dist/gameplay/initiate.js +1 -1
- package/dist/gameplay/services/physics/physics-system.d.ts +56 -3
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/gameplay/services/world.js +1 -1
- package/dist/scene/asset-resource-loader.d.ts +2 -0
- package/dist/scene/asset-resource-loader.js +1 -1
- package/dist/scene/assets-provider.d.ts +1 -0
- package/dist/scene/assets-provider.js +1 -1
- package/dist/scene/collision/collision-shape.d.ts +1 -1
- package/dist/scene/materializer.d.ts +8 -1
- package/dist/scene/materializer.js +1 -1
- package/dist/scene/runtime-asset-service.d.ts +7 -1
- package/dist/scene/runtime-asset-service.js +1 -1
- package/dist/scene/storage/storage.js +1 -1
- package/dist/shader/builtin/standard-shader.js +1 -1
- package/dist/shader/builtin/unlit-shader.js +1 -1
- package/dist/shader/decal-shader.d.ts +2 -2
- package/dist/shader/decal-shader.js +1 -1
- package/dist/shader/shader.d.ts +2 -1
- package/dist/shader/shader.js +1 -1
- package/dist/shader/sprite-shader.d.ts +2 -2
- package/dist/shader/sprite-shader.js +1 -1
- package/dist/shader/trail-shader.d.ts +2 -2
- package/dist/shader/trail-shader.js +1 -1
- package/dist/test/animation-retarget.test.js +1 -1
- package/dist/test/asset-resource-loader-texture-array.test.d.ts +2 -0
- package/dist/test/asset-resource-loader-texture-array.test.js +4 -0
- package/dist/test/character-animation-transition.test.d.ts +2 -0
- package/dist/test/character-animation-transition.test.js +4 -0
- package/dist/test/character-slide.test.d.ts +2 -0
- package/dist/test/character-slide.test.js +4 -0
- package/dist/test/navmesh-worker-pool.test.d.ts +2 -0
- package/dist/test/navmesh-worker-pool.test.js +4 -0
- package/dist/test/net-character-movement.test.js +1 -1
- package/dist/test/prefab-instance-params.test.js +1 -1
- package/dist/test/runtime-asset-service.test.js +1 -1
- package/dist/test/sequence-animation-retiming.test.js +1 -1
- package/dist/test/sequence-root-motion-axis-mask.test.d.ts +2 -0
- package/dist/test/sequence-root-motion-axis-mask.test.js +4 -0
- package/dist/test/vfx-world-space-emitter-rotation.test.d.ts +2 -0
- package/dist/test/vfx-world-space-emitter-rotation.test.js +4 -0
- package/dist/test/world-prefab-spawn.test.js +1 -1
- package/package.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as t,__metadata as e}from"tslib";import*as i from"@dimforge/rapier3d-simd-compat";import{QueryFilterFlags as s}from"@dimforge/rapier3d-simd-compat";import{BehaviorSubject as o,distinctUntilChanged as n,filter as r,map as a,Subject as l,takeUntil as c}from"rxjs";import*as d from"three";import{ArrowHelper as h,BufferAttribute as u,BufferGeometry as p,Group as y,LineSegments as g,Matrix4 as m,Object3D as f,Quaternion as w,Raycaster as x,Scene as b,Vector3 as B}from"three";import*as v from"three/examples/jsm/utils/BufferGeometryUtils.js";import{Service as C}from"typedi";import{ActorComponent as S,Component as A}from"../../../gameplay/actors/component.js";import{inject as R}from"../../../gameplay/inject.js";import{BoxCollisionShape as z,CapsuleCollisionShape as D,ConeCollisionShape as T,ConvexPolyhedronCollisionShape as M,CylinderCollisionShape as E,PhysicalShapeMesh as P,PlaneCollisionShape as _,SphereCollisionShape as F,toInstancedCollisionShape as W,TrimeshCollisionShape as I}from"../../../index.js";import{AssetMeshInstance as j}from"../../../scene/asset-resource-loader.js";import{LandscapeGroup as V}from"../../../scene/landscape/landscape.js";import{calculateEffectiveScale as k}from"../../../utils/three/traverse.js";import{ViewController as N}from"../render.js";import{World as L}from"../world.js";import{AbstractPhysicsSystem as O}from"./abstract-physics-system.js";import{NetRole as G}from"../../net/index.js";export{ActorComponent,attach,Attach,Component}from"../../actors/component.js";export class RayTestResult{constructor(){this.hasHit=!1,this.hitPoint=new B,this.hitNormal=new B}}export class ShapeCastResult{constructor(){this.hasHit=!1,this.hitPoint=new B,this.normal=new B}reset(){this.actor=void 0,this.hasHit=!1,this.distance=0,this.hitPoint.set(0,0,0),this.normal.set(0,0,0)}}ShapeCastResult.shared=new ShapeCastResult;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={}));const K=new B,U=new B,H=new w,q=new w,Q=new w,X=[];let $=class extends O{set showDebug(t){this.shouldRenderDebug=t,this.debugMesh&&(this.debugMesh.visible=t)}get showDebug(){return this.shouldRenderDebug}constructor(){super(),this.staticMeshes=new Map,this.staticBodies=new Map,this.actorBodies=new Map,this.bodyActors=new Map,this.colliders=new Map,this.collisionEvents=new l,this.beforeStep=new l,this.afterStep=new l,this.shouldRenderDebug=!1,this.viewController=R(N),this.shapeCacheBox=new Map,this.shapeCacheBall=new Map,this._raycaster=new x,this._reusableResult=new RayTestResult,this._raytestDiff=new B,this._raytestDirection=new B,this.controlledActors=new Set,this._isStopped=!1,this.ready=this.setup()}getBallShape(t){let e=this.shapeCacheBall.get(t);return null==e&&(e=new this.rapier.Ball(t),this.shapeCacheBall.set(t,e)),e}getBoxShape(t,e,i){const s=t+1e6*e+1e12*i;let o=this.shapeCacheBox.get(s);return null==o&&(o=new this.rapier.Cuboid(t,e,i),this.shapeCacheBox.set(s,o)),o}hasBoxIntersection(t){const e=t.getCenter(K),i=t.getSize(U),s=this.getBoxShape(i.x/2,i.y/2,i.z/2);return null!=this.world.intersectionWithShape(e,H,s)}hasSphereIntersection(t){const e=this.getBallShape(t.radius);return null!=this.world.intersectionWithShape(t.center,H,e)}findActorsInRadius(t,e,i){const s=this.getBallShape(e),o=[];for(const[e,n]of this.bodyActors)if(n instanceof i||null==i)for(let i=0,r=e.numColliders();i<r;i++){e.collider(i).intersectsShape(s,t,H)&&o.push(n)}return o}createDebugMesh(){return new g(new p,new d.LineBasicMaterial({color:255}))}async start(){return await this.ready,this.handleTick(),this.handleCollisionEvents(),this.ready}handleCollisionEvents(){this.collisionSub=this.collisionEvents.subscribe(t=>{const e=this.colliders.get(t.handle1);if(null==e)return;const i=this.world.getCollider(t.handle2);if(null==i||null==i.parent())return;const s=this.bodyActors.get(i.parent());null!=s&&(t.started?e.onBeginOverlapActor.next({actor:s}):e.onEndOverlapActor.next({actor:s}))})}renderDebug(){if(null==this.scene)return;null==this.debugMesh&&(this.debugMesh=this.createDebugMesh(),this.debugMesh.visible=this.shouldRenderDebug,this.debugMesh.raycast=function(){},this.scene?.add(this.debugMesh));const t=this.world.debugRender().vertices,e=this.debugMesh.geometry,i=e.getAttribute("position");null==i||(i.array.length,t.length);{const i=new u(t,3);i.setUsage(d.DynamicDrawUsage),e.setAttribute("position",i)}e.setDrawRange(0,t.length/3)}async setup(){if(null!=this.rapier)throw new Error("Rapier is already estup");this.rapier=await dt(),this.eventQueue=new this.rapier.EventQueue(!0),this.setupWorld()}handleTick(){this.fixedupdateSub=this.viewController.onUpdate().subscribe(t=>{this._isStopped||(t=Math.min(.1,t),this.beforeStep.next(t),this.updatePhysics(t),this.showDebug&&this.renderDebug(),this.world.bodies.forEach(t=>{if(t.isFixed())return;let e,i=this.staticMeshes.get(t);if(null==i&&(e=this.bodyActors.get(t),null!=e)){if(e.netRole===G.simulatedProxy)return;i=e.object}null!=i&&i.parent instanceof b&&(pt(i.position,t.translation()),(t.isDynamic()||t.isKinematic()&&!this.controlledActors.has(this.bodyActors.get(t)?.id))&&yt(i.quaternion,t.rotation()),i.matrixWorldNeedsUpdate=!0)}),this.afterStep.next(t))})}_updateWorld(){this.world.timestep=0,this.world.step()}updatePhysics(t){this._isStopped||(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(rt,this.viewController.getCamera());const s=this._raycaster.ray.origin,o=this._raycaster.ray.direction.multiplyScalar(t).add(s);return this.rayTest(s,o,e,i)}rayTest(t,e,i,s){null==i&&(i=this._reusableResult);const o=this._raytestDiff,n=this._raytestDirection;if(o.subVectors(e,t),n.copy(o).normalize(),0===n.length())return console.warn("Ray test called with to and from being equal"),i;null==bt&&(bt=new this.rapier.Ray(new this.rapier.Vector3(0,0,0),new this.rapier.Vector3(0,1,0))),ht(bt.origin,t),ht(bt.dir,n);const r=o.length(),a=this.world.castRayAndGetNormal(bt,r,!1,void 0,s?.collisionFilter,void 0,null!=s?.excludeActor?this.actorBodies.get(s.excludeActor.id):void 0,s?.excludeTriggers?t=>!t.isSensor():void 0);if(i.hasHit=null!=a,i.hasHit){const e=bt.pointAt(a.timeOfImpact);if(i._internal=a,pt(i.hitNormal,a.normal),pt(i.hitPoint,e),i.distance=mt.subVectors(i.hitPoint,t).length(),!1!==s?.resolveActor){const t=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===a.collider));i.actor=null!=t?this.bodyActors.get(t):null}}if(this.showDebug){let e;X.length>0?(e=X.pop(),e.setDirection(n),e.position.copy(t),e.setLength(r,.2,.1),e.setColor(s?.debugColor??255)):e=new h(n,t,r,s?.debugColor??255),this.scene?.add(e),setTimeout(()=>{this.scene?.remove(e),X.push(e)},s?.debugLifetime??200)}return i}setGravity(t,e,i){this.world.gravity.x=t,this.world.gravity.y=e,this.world.gravity.z=i}getGravity(){return tt.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())gt(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 P&&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 j){const e=!1!==t.userData?.src?.collisionDetection;if(t.children[0]&&(t.children[0].instanceMatrix&&e||t.children[0].isBatchedMesh))this.createForInstancedMesh(t.children[0],t.collisionShapes);else if(e&&t.children.length>0){const e=this.createStaticBody(t,t.collisionShapes,t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}}else t instanceof V?this.addLandscapeGroup(t):(t instanceof y||t instanceof b)&&t.children.forEach(t=>this.addRecursively(t))}createForInstancedMesh(t,e){const i=new m;if(t instanceof d.BatchedMesh){const e=t._instanceInfo??t._drawInfo,s=new Map;for(let o=0;o<e.length;o++){if(null!=t.userData.hasCollision&&!t.userData.hasCollision[o])continue;const e=t.userData.collisionShapes;let n=e?.[o];if(null==n&&null==e&&t.parent instanceof j&&(n=t.parent.collisionShapes),null==n)continue;let r=s.get(n);null==r&&(r=this.instancedShapeReset(n),s.set(n,r));const a=new f;a.matrix.identity(),t.getMatrixAt(o,i),a.applyMatrix4(i);this.createStaticBody(a,r)}}else{const s=this.instancedShapeReset(e);for(let e=0;e<t.count;e++){if(null!=t.userData.hasCollision&&!t.userData.hasCollision[e])continue;const o=new f;o.matrix.identity(),i.fromArray(t.instanceMatrix.array,16*e),o.applyMatrix4(i);this.createStaticBody(o,s)}}}instancedShapeReset(t){return t.filter(t=>null!=t).map(t=>W(t))}getCharacterController(t){return this.world?.createCharacterController(t)}getActorComputedMovement(t,e,i,o=null){const n=this.actorBodies.get(t.id);this.controlledActors.add(t.id);const r=n.collider(0);e.computeColliderMovement(r,i,s.EXCLUDE_SENSORS,o,wt);const a=e.computedMovement();return pt(ft,a),ft}setActorCapsuleCollider(t,e,i,s){const o=this.actorBodies.get(t.id),n=o?.collider(0);if(null==o||null==n)return!1;const r=t.object?.getWorldScale(xt)??it,a=Math.max(0,e*Math.abs(r.y)),l=Math.max(.001,i*Math.max(Math.abs(r.x),Math.abs(r.z)));return n.setHalfHeight(a/2),n.setRadius(l),nt.set(0,s,0).multiply(r),ht(st,nt),n.setTranslationWrtParent(st),o.recomputeMassPropertiesFromColliders(),!0}hasActorCapsuleIntersection(t,e,i,o,n,r=null){const a=this.actorBodies.get(t.id),l=t.object?.getWorldScale(xt)??it,c=Math.max(0,i*Math.abs(l.y)),d=Math.max(.001,o*Math.max(Math.abs(l.x),Math.abs(l.z))),h=new this.rapier.Capsule(c/2,d),u=t.object?.getWorldQuaternion(Q)??H;nt.set(0,n,0).multiply(l).applyQuaternion(u).add(e);return null!=this.world.intersectionWithShape(nt,u,h,s.EXCLUDE_SENSORS,r??void 0,void 0,a,wt)}createCollider(t,e){const i=this.addShape(e?.body,t),s=new PhysicsCollider(i,this.world);return this.colliders.set(i.handle,s),s.disposed.subscribe(()=>{this.colliders.delete(i.handle)}),s}createBody(t=PhysicsBodyType.dynamic,e={}){const i=(()=>{switch(t){case PhysicsBodyType.dynamic:return this.rapier.RigidBodyDesc.dynamic();case PhysicsBodyType.static:return this.rapier.RigidBodyDesc.fixed();case PhysicsBodyType.kinematic:return this.rapier.RigidBodyDesc.kinematicPositionBased();case PhysicsBodyType.kinematicVelocityBased:return this.rapier.RigidBodyDesc.kinematicVelocityBased();default:return this.rapier.RigidBodyDesc.dynamic()}})();e.position&&i.setTranslation(e.position.x,e.position.y,e.position.z),e.rotation&&i.setRotation({x:e.rotation.x,y:e.rotation.y,z:e.rotation.z,w:e.rotation.w}),"boolean"==typeof e.canSleep&&i.setCanSleep(e.canSleep),"boolean"==typeof e.ccdEnabled&&i.setCcdEnabled(e.ccdEnabled),"number"==typeof e.gravityScale&&i.setGravityScale(e.gravityScale),"number"==typeof e.mass&&i.setAdditionalMass(e.mass),void 0!==e.userData&&(i.userData=e.userData);const s=this.world.createRigidBody(i);return new PhysicsBody(s,this.world)}getCharacterComputedMovement(t,e,i,o=null){const n=t.collider;e.computeColliderMovement(n,i,s.EXCLUDE_SENSORS,o,wt);const r=e.computedMovement();return pt(ft,r),ft}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)}setNextKinematicPosition(t,e){this.actorBodies.get(t.id).setNextKinematicTranslation(e)}setNextKinematicRotation(t,e){this.actorBodies.get(t.id).setNextKinematicRotation(e)}setNextKinematicTransform(t){!function(t,e){const i=e.getWorldPosition(Y),s=e.getWorldQuaternion(Z);t.setNextKinematicTranslation(at(i)),t.setNextKinematicRotation(lt(s))}(this.actorBodies.get(t.id),t.object)}setAngularVelocity(t,e){const i=this.actorBodies.get(t.id);st.x=e.x,st.y=e.y,st.z=e.z,i?.setAngvel(st,!0)}setLinearVelocity(t,e){const i=this.actorBodies.get(t.id);st.x=e.x,st.y=e.y,st.z=e.z,i?.setLinvel(st,!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)}getLienarDamping(t){const e=this.actorBodies.get(t.id);return e?.linearDamping()??0}setAngularDamping(t,e){const i=this.actorBodies.get(t.id);i?.setAngularDamping(e)}getAngularDamping(t){const e=this.actorBodies.get(t.id);e?.angularDamping()}setPosition(t,e){const i=this.actorBodies.get(t.id);i?.setTranslation(at(e),!1)}getPosition(t,e=new B){const i=this.actorBodies.get(t.id);i&&pt(e,i.translation())}setRotation(t,e){const i=this.actorBodies.get(t.id);i?.setTranslation(lt(e),!1)}getRotation(t,e=new w){const i=this.actorBodies.get(t.id);i&&yt(e,i.rotation())}lockTranslations(t,e){const i=this.actorBodies.get(t.id);i?.lockTranslations(e,!1)}lockRotations(t,e){const i=this.actorBodies.get(t.id);i?.lockRotations(e,!1)}setEnabledTranslations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledTranslations(e,i,s,!1)}setEnabledRotations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledRotations(e,i,s,!1)}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));var o=n.getWorldPosition(new B);if(e.landscape.holes&&e.landscape.holes.some(t=>t.m===n.name&&0!==t.w[0])){const t=n.geometry.clone(),i=n.scale,s=n.geometry.getAttribute("hole"),r=new Float32Array(t.getAttribute("position").array);for(let t=0;t<r.length;t+=3)r[t]*=i.x,r[t+1]*=i.y,r[t+2]*=i.z;const a=t.index;for(let t=0;t<a.count;t+=3){const e=s.getX(a.getX(t)),i=s.getX(a.getY(t)),o=s.getX(a.getZ(t));(e>.5||i>.5||o>.5)&&(a.setX(t,0),a.setY(t,0),a.setZ(t,0))}const l=this.rapier.ColliderDesc.trimesh(r,new Uint32Array(t.getIndex().array));if(!1!==e.collisionDetection){const t=this.world.createRigidBody(this.rapier.RigidBodyDesc.fixed()),e=new this.rapier.Vector3(0,0,0);ht(e,o),t.setTranslation(e,!1),this.world.createCollider(l,t),this.staticBodies.set(n,t)}continue}const t=e.landscape.options.density+1,r=e.landscape.options.sectionSize,a=new Array(t);for(let e=0;e<t;e++)a[e]=new Array(t).fill(0);const l=s.find(t=>t.x===n.x&&t.y==n.y);if(null!=l)for(const e of l.points){if(null==a[e.i%t])continue;const i=t-1-Math.floor(e.i/t);i in a[e.i%t]?a[e.i%t][i]=e.y/r:console.warn("wrong index",{points:a,point:e,i:e.i%t,k:i,heightMap:l})}const c=e.landscape.options.density,d=a.flatMap(t=>t.reverse()),h=i.ColliderDesc.heightfield(c,c,new Float32Array(d),new this.rapier.Vector3(r,r,r));if(!1!==e.collisionDetection){const t=this.world.createRigidBody(this.rapier.RigidBodyDesc.fixed()),e=new this.rapier.Vector3(0,0,0);ht(e,o),t.setTranslation(e,!1),this.world.createCollider(h,t),this.staticBodies.set(n,t)}}}setEnabled(t,e){const i=this.actorBodies.get(t.id);i?.setEnabled(e)}addActor(t,e,i={}){if(0==e.length)return void console.error("No collision shapes were defined when adding actor to the physics system.");this.removeActor(t);const s=t.object;let o;switch(i.type??PhysicsBodyType.static){case PhysicsBodyType.dynamic:o=this.rapier.RigidBodyDesc.dynamic(),o.mass=i.mass??1;break;case PhysicsBodyType.kinematic:o=this.rapier.RigidBodyDesc.kinematicPositionBased();break;case PhysicsBodyType.kinematicVelocityBased:o=this.rapier.RigidBodyDesc.kinematicVelocityBased();break;default:o=i.isTrigger?this.rapier.RigidBodyDesc.kinematicVelocityBased():this.rapier.RigidBodyDesc.fixed()}const n=this.world.createRigidBody(o);n.enableCcd(1==i.continousCollisionDetection);for(const t of e)this.addShape(n,t,s);return gt(n,t=>{null!=i.isTrigger&&(t.setSensor(i.isTrigger),t.setActiveCollisionTypes(this.rapier.ActiveCollisionTypes.ALL),t.setActiveEvents(this.rapier.ActiveEvents.COLLISION_EVENTS)),null!=i.friction&&t.setFriction(i.friction),null!=i.density&&t.setDensity(i.density),null!=i.mass&&t.setMass(i.mass),null!=i.restitution&&t.setRestitution(i.restitution)}),J(n,s),!0===i.ignoreForNavMesh&&(n.userData={ignoreForNavMesh:!0}),this.actorBodies.set(t.id,n),this.bodyActors.set(n,t),new PhysicsBody(n,this.world)}applyTorque(t,e){const i=this.actorBodies.get(t.id);st.x=e.x,st.y=e.y,st.z=e.z,i?.addTorque(st,!0)}applyTorqueImpulse(t,e){const i=this.actorBodies.get(t.id);st.x=e.x,st.y=e.y,st.z=e.z,i?.applyTorqueImpulse(st,!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);st.x=e.x,st.y=e.y,st.z=e.z,i?.addForce(st,!0)}applyImpulse(t,e){const i=this.actorBodies.get(t.id);st.x=e.x,st.y=e.y,st.z=e.z,i?.applyImpulse(st,!0)}applyLocalForce(t,e,i){const s=this.actorBodies.get(t.id);ht(st,e),null==i?s?.addForce(st,!0):(ht(ot,i),s?.addForceAtPoint(st,ot,!0))}applyLocalImpulse(t,e,i){const s=this.actorBodies.get(t.id);ht(st,e),null==i?s.applyImpulse(st,!0):(ht(ot,i),s.applyImpulseAtPoint(st,ot,!0))}applyRadiusImpulse(t,e,s){this.world.bodies.forEach(o=>{if(o.collider(0)?.isSensor())return;if(o.bodyType()!==i.RigidBodyType.Dynamic)return;const n=nt;pt(n,o.translation());const r=n.clone().sub(t);if(r.length()>e)return;const a=r.clone().normalize().multiplyScalar(s);st.x=a.x,st.y=a.y,st.z=a.z,o.applyImpulse(st,!0)})}removeActor(t){if(null==t)return;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)}removeRemoved(t){if(null==t)return;const e=new Set;t.traverse(t=>{e.add(t.uuid)});for(const[t,i]of this.staticBodies.entries())e.has(t.uuid)&&this.world.getRigidBody(i.handle)&&(this.staticBodies.delete(t),this.world.removeRigidBody(i))}removeSceneObject(t){if(t instanceof V){for(const e of t.sections)this.removeSceneObject(e);return}let e=this.staticBodies.get(t);null!=e&&this.world.getRigidBody(e.handle)&&this.world.removeRigidBody(e),this.staticBodies.delete(t)}activateActorEvents(t){this.actorBodies.get(t.id)}_onCollisionWithActorEvent(t,e,i){return this.activateActorEvents(t),this.collisionEvents.pipe(c(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(c(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(c(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())}onBeginOverlap(t){return this._onCollisionWithActorEvent(t,()=>!0,!0)}onEndOverlap(t){return this._onCollisionWithActorEvent(t,()=>!0,!1)}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&&J(e,t.object)}flushModifiedBodyPositionsToColliders(){this.world.propagateModifiedBodyPositionsToColliders()}setupWorld(){const t=new this.rapier.World({x:0,y:-9.81,z:0});this.world=t}sphereCast(t,e,i,s,o=ShapeCastResult.shared,n){o.reset();const r=this.getBallShape(e);this.shapeCacheBall.get;const a={x:t.x,y:t.y,z:t.z},l={x:i.x,y:i.y,z:i.z},c=n?.excludeActor?this.actorBodies.get(n.excludeActor.id):null,d=this.world.castShape(a,{x:0,y:0,z:0,w:1},l,r,.01,s,!0,null,n?.collisionFilter??void 0,null,c,n?.excludeTriggers?t=>!t.isSensor():void 0);if(null!=d){pt(o.hitPoint,d.witness1),o.normal.set(d.normal1.x,d.normal1.y,d.normal1.z),o.distance=d.time_of_impact,o.hasHit=!0;const t=d.collider.parent();if(t){const e=this.bodyActors.get(t);e&&(o.actor=e)}}return o}castActorShape(t,e,i,s=ShapeCastResult.shared,o=void 0){s.reset();const n=this.actorBodies.get(t.id);if(n&&n.numColliders()>0){for(let t=0;t<n.numColliders();t++){const r=n.collider(t);let a=r.shape,l=r.translation(),c=r.rotation(),d=e,h=i;const u=this.world.castShape(l,c,d,a,.01,h,!0,null,o,null,n,void 0);if(null!=u){u.collider;const t=r;return pt(s.hitPoint,u.witness1),vt(t.rotation(),u.normal1,s.normal,q),s.distance=u.time_of_impact,s.actor=this.bodyActors.get(u.collider.parent()),s.hasHit=!0,s}}return s}return console.warn("Actor is not added to the physics system"),s}stop(){if(!this._isStopped){this._isStopped=!0,this.bodyActors.clear(),this.actorBodies.clear(),this.staticBodies.clear(),this.staticMeshes.clear(),this.colliders.clear(),this.fixedupdateSub?.unsubscribe(),this.collisionSub?.unsubscribe(),this.world?.bodies.forEach(t=>this.world.removeRigidBody(t));try{this.world?.free(),this.world=void 0}catch(t){console.warn("Error while freeing physics world",t)}X.length=0}}createStaticBody(t,e,s){const o=s?.type===PhysicsBodyType.dynamic?i.RigidBodyDesc.dynamic():i.RigidBodyDesc.fixed();o.setSleeping(!0);const n=this.world.createRigidBody(o);let r=0;for(const i of e){if(r>128){console.warn("Too many collision shapes for object",t);break}if(r++,null==i){console.warn("Collision shape is missing for object",t);continue}const o=this.addShape(n,i,t);null!=o&&(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 J(n,t),n.userData=t.uuid,n.sleep(),n}addShape(t=void 0,e,i){const s=i?.getWorldScale(xt)??it,o=this.createShape(e,s);if(null==o)return void console.error("Failed to create physics shape. This can happen if the geometry is degenerate or zero-scaled.",{shapeInfo:e,object:i});this.applyShapeSettings(o,e);const n=e.offset.clone().multiply(s);ht(o.translation,n);const r=(new w).setFromEuler(e.rotation);ut(o.rotation,r),null!=t&&t.numColliders()>128&&console.warn(`Rigid body has many colliders (${t.numColliders()}). Consider using a Trimesh if this is static geometry.`,t);try{return this.world.createCollider(o,t)}catch(t){return void console.error("Failed to create collider",t)}}applyShapeSettings(t,e){null!=e.collisionGroup&&t.setCollisionGroups(e.collisionGroup),t.friction=e.friction??.1,null!=e.restitution&&(t.restitution=e.restitution),null!=e.density&&(t.density=e.density,t.massPropsMode=i.MassPropsMode.Density),null!=e.mass&&(t.mass=e.mass,t.massPropsMode=i.MassPropsMode.Mass)}createShape(t,e){if(t instanceof z)return this.rapier.ColliderDesc.cuboid(t.dimensions.x*e.x/2,t.dimensions.y*e.y/2,t.dimensions.z*e.z/2);if(t instanceof D){return this.rapier.ColliderDesc.capsule(t.length/2*e.y,t.radius*Math.max(e.z,e.x))}if(t instanceof I){const i=null!=t.geometry.getIndex()?t.geometry:v.mergeVertices(t.geometry),s=extractFloat32Array(i.getAttribute("position"));for(let t=0;t<s.length;t+=3)s[t]*=e.x,s[t+1]*=e.y,s[t+2]*=e.z;const o=i.getIndex();return null==o?(console.error("Trimesh collision shape is missing an index buffer.",t),null):this.rapier.ColliderDesc.trimesh(s,new Uint32Array(o.array))}if(t instanceof M){let i,s;t.mesh instanceof d.Mesh?i=t.mesh.geometry:t.mesh instanceof d.BufferGeometry?i=t.mesh:console.log("Unknownd shape",{shapeInfo:t}),t.mesh instanceof d.Mesh&&(s=k(t.mesh));const o=`${i.uuid}|${s?.x??1},${s?.y??1},${s?.z??1}|${e.x},${e.y},${e.z}`,n=et.get(o);if(void 0!==n)return n;const r=extractFloat32Array(i.getAttribute("position"));if(null!=s)for(let t=0;t<r.length;t+=3)r[t]*=s.x,r[t+1]*=s.y,r[t+2]*=s.z;for(let t=0;t<r.length;t+=3)r[t]*=e.x,r[t+1]*=e.y,r[t+2]*=e.z;const a=this.rapier.ColliderDesc.convexHull(r);return null==a&&console.error("Failed to compute convex hull. Points may be coplanar or too few.",{count:r.length/3}),et.set(o,a),a}if(t instanceof F){const i=2*e.x-e.y-e.z;return Math.abs(i)>.01?this.createShape(new M(new d.SphereGeometry(t.radius).scale(e.x,e.y,e.z)),new B(1,1,1)):this.rapier.ColliderDesc.ball(t.radius*Math.max(e.x,e.y,e.z))}return t instanceof E?this.rapier.ColliderDesc.cylinder(t.height/2*e.y,t.radiusTop*Math.max(e.z,e.x)):t instanceof T?this.rapier.ColliderDesc.cone(t.height*e.y,t.radiusBottom/2*Math.max(e.z,e.x)):t instanceof _?this.rapier.ColliderDesc.cuboid(t.width/2*e.x,t.height/2*e.y,.001):(console.error("Unsupported shape",t),this.rapier.ColliderDesc.cuboid(1,1,1))}createCharacterCollision(){return new this.rapier.CharacterCollision}};$=t([C(),e("design:paramtypes",[])],$);export{$ as PhysicsSystem};const Y=new B,Z=new d.Quaternion;function J(t,e){const i=e.getWorldPosition(Y),s=e.getWorldQuaternion(Z);t.setTranslation(at(i),!1),t.setRotation(lt(s),!1)}const tt=new B,et=new Map,it=new B(1,1,1),st=new i.Vector3(0,0,0),ot=new i.Vector3(0,0,0),nt=new B,rt=new d.Vector2;function at(t){return ht(st,t),st}function lt(t){return ut(q,t),q}let ct=null;const dt=async()=>(null==ct&&(ct=(async()=>{let t=await import("@dimforge/rapier3d-simd-compat");return await t.init(),t})()),ct);function ht(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function ut(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}function pt(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function yt(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}function gt(t,e){for(let i=0,s=t.numColliders();i<s;i++){e(t.collider(i))}}const mt=new B,ft=new B,wt=t=>!t.isSensor(),xt=new B;let bt,Bt=class extends S{constructor(){super(...arguments),this._active=!0,this.physics=R($),this.world=R(L)}set active(t){this._active=t,t?(this.world.scene.remove(this.actor.object),this.physics.setEnabled(this.actor,t)):(this.world.scene.add(this.actor.object),this.physics.setEnabled(this.actor,t))}get active(){return this._active}};Bt=t([A()],Bt);export function extractFloat32Array(t){const e=t.itemSize,i=t.count,s=new Float32Array(i*e);for(let o=0;o<i;o++)for(let i=0;i<e;i++)s[o*e+i]=t.getComponent(o,i);return s}function vt(t,e,i,s){return s.set(t.x,t.y,t.z,t.w),i.set(e.x,e.y,e.z),i.applyQuaternion(s),i}export class PhysicsCollider{constructor(t,e){this.collider=t,this.world=e,this.disposed=new l,this.onBeginOverlapActor=new l,this.onEndOverlapActor=new l}dispose(){this.world.removeCollider(this.collider,!1),this.disposed.next(!0),this.disposed.complete(),this.onBeginOverlapActor.complete(),this.onEndOverlapActor.complete()}set mass(t){this.collider.setMass(t)}get mass(){return this.collider.mass()}set friction(t){this.collider.setFriction(t)}get friction(){return this.collider.friction()}set restitution(t){this.collider.setRestitution(t)}get restitution(){return this.collider.restitution()}set density(t){this.collider.setDensity(t)}get density(){return this.collider.density()}set isTrigger(t){this.collider.setSensor(t)}get isTrigger(){return this.collider.isSensor()}set collisionGroups(t){this.collider.setCollisionGroups(t)}get collisionGroups(){return this.collider.collisionGroups()}set enabled(t){this.collider.setEnabled(t)}get enabled(){return this.collider.isEnabled()}}export class PhysicsBody{constructor(t,e){this.body=t,this.world=e}dispose(){this.world.removeRigidBody(this.body)}setEnabled(t){this.body.setEnabled(t)}isEnabled(){return this.body.isEnabled()}getPosition(t){const e=this.body.translation();return t.set(e.x,e.y,e.z),t}setPosition(t){this.body.setTranslation({x:t.x,y:t.y,z:t.z},!0)}getRotation(t){const e=this.body.rotation();return t.set(e.x,e.y,e.z,e.w),t}setRotation(t){this.body.setRotation({x:t.x,y:t.y,z:t.z,w:t.w},!0)}getLinearVelocity(t){const e=this.body.linvel();return t.set(e.x,e.y,e.z),t}setLinearVelocity(t){this.body.setLinvel({x:t.x,y:t.y,z:t.z},!0)}getAngularVelocity(t){const e=this.body.angvel();return t.set(e.x,e.y,e.z),t}setAngularVelocity(t){this.body.setAngvel({x:t.x,y:t.y,z:t.z},!0)}applyImpulse(t,e=!0){this.body.applyImpulse({x:t.x,y:t.y,z:t.z},e)}applyTorqueImpulse(t,e=!0){this.body.applyTorqueImpulse({x:t.x,y:t.y,z:t.z},e)}setNextKinematicPosition(t){this.body.setNextKinematicTranslation(t)}setNextKinematicRotation(t){this.body.setNextKinematicRotation(t)}setType(t){this.body.setBodyType(function(t){switch(t){case PhysicsBodyType.dynamic:return i.RigidBodyType.Dynamic;case PhysicsBodyType.static:return i.RigidBodyType.Fixed;case PhysicsBodyType.kinematic:return i.RigidBodyType.KinematicPositionBased;case PhysicsBodyType.kinematicVelocityBased:return i.RigidBodyType.KinematicVelocityBased}}(t),t!==PhysicsBodyType.static)}setGravityScale(t){this.body.setGravityScale(t,!1)}getGravityScale(){return this.body.gravityScale()}isDynamic(){return this.body.isDynamic()}isKinematic(){return this.body.isKinematic()}isStatic(){return this.body.isFixed()}sleep(){this.body.sleep()}wakeUp(){this.body.wakeUp()}}/*
|
|
1
|
+
import{__decorate as t,__metadata as e}from"tslib";import*as i from"@dimforge/rapier3d-simd-compat";import{QueryFilterFlags as s}from"@dimforge/rapier3d-simd-compat";import{BehaviorSubject as o,distinctUntilChanged as r,filter as n,map as a,Subject as l,takeUntil as c}from"rxjs";import*as d from"three";import{ArrowHelper as h,BufferAttribute as u,BufferGeometry as p,Group as y,LineSegments as g,Matrix4 as m,Object3D as b,Quaternion as f,Raycaster as w,Scene as x,Vector3 as v}from"three";import*as D from"three/examples/jsm/utils/BufferGeometryUtils.js";import{Service as B}from"typedi";import{ActorComponent as S,Component as A}from"../../../gameplay/actors/component.js";import{inject as C}from"../../../gameplay/inject.js";import{BoxCollisionShape as R,CapsuleCollisionShape as M,ConeCollisionShape as E,ConvexPolyhedronCollisionShape as z,CylinderCollisionShape as T,PhysicalShapeMesh as P,PlaneCollisionShape as F,SphereCollisionShape as _,toInstancedCollisionShape as I,TrimeshCollisionShape as j}from"../../../scene/collision/collision-shape.js";import{AssetMeshInstance as W}from"../../../scene/asset-resource-loader.js";import{LandscapeGroup as N}from"../../../scene/landscape/landscape.js";import{calculateEffectiveScale as k}from"../../../utils/three/traverse.js";import{ViewController as V}from"../render.js";import{World as L}from"../world.js";import{AbstractPhysicsSystem as O}from"./abstract-physics-system.js";import{NetRole as U}from"../../net/index.js";export{ActorComponent,attach,Attach,Component}from"../../actors/component.js";export class RayTestResult{constructor(){this.hasHit=!1,this.hitPoint=new v,this.hitNormal=new v}}export class ShapeCastResult{constructor(){this.hasHit=!1,this.hitPoint=new v,this.normal=new v}reset(){this.actor=void 0,this.hasHit=!1,this.distance=0,this.hitPoint.set(0,0,0),this.normal.set(0,0,0)}}ShapeCastResult.shared=new ShapeCastResult;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={}));const G=new v,K=new v,H=new f,X=new f,q=new f;let Q=class extends O{set showDebug(t){this.shouldRenderDebug=t,t||this.clearRayDebugArrows(),this.debugMesh&&(this.debugMesh.visible=t),this.staticDebugMesh&&(this.staticDebugMesh.visible=t)}get showDebug(){return this.shouldRenderDebug}constructor(){super(),this.staticMeshes=new Map,this.staticBodies=new Map,this.actorBodies=new Map,this.bodyActors=new Map,this.colliders=new Map,this.rayDebugArrowPool=[],this.activeRayDebugArrows=[],this.collisionEvents=new l,this.beforeStep=new l,this.afterStep=new l,this.shouldRenderDebug=!1,this.viewController=C(V),this.shapeCacheBox=new Map,this.shapeCacheBall=new Map,this.staticDebugNeedsUpdate=!0,this.invalidateStaticDebug=()=>{this.staticDebugNeedsUpdate=!0},this._raycaster=new w,this._reusableResult=new RayTestResult,this._raytestDiff=new v,this._raytestDirection=new v,this.controlledActors=new Set,this._isStopped=!1,this.ready=this.setup()}getBallShape(t){let e=this.shapeCacheBall.get(t);return null==e&&(e=new this.rapier.Ball(t),this.shapeCacheBall.set(t,e)),e}getBoxShape(t,e,i){const s=t+1e6*e+1e12*i;let o=this.shapeCacheBox.get(s);return null==o&&(o=new this.rapier.Cuboid(t,e,i),this.shapeCacheBox.set(s,o)),o}hasBoxIntersection(t){const e=t.getCenter(G),i=t.getSize(K),s=this.getBoxShape(i.x/2,i.y/2,i.z/2);return null!=this.world.intersectionWithShape(e,H,s)}hasSphereIntersection(t){const e=this.getBallShape(t.radius);return null!=this.world.intersectionWithShape(t.center,H,e)}findActorsInRadius(t,e,i){const s=this.getBallShape(e),o=[];for(const[e,r]of this.bodyActors)if(r instanceof i||null==i)for(let i=0,n=e.numColliders();i<n;i++){e.collider(i).intersectsShape(s,t,H)&&o.push(r)}return o}createDebugMesh(){const t=new g(new p,new d.LineBasicMaterial({color:255}));return t.frustumCulled=!1,t}updateDebugMesh(t,e){const i=t.geometry,s=i.getAttribute("position");if(null==s||s.array.length<e.length){null!=s&&i.dispose();const t=new Float32Array(e.length);t.set(e);const o=new u(t,3);o.setUsage(d.DynamicDrawUsage),i.setAttribute("position",o)}else e.length>0&&(s.array.set(e),s.clearUpdateRanges(),s.addUpdateRange(0,e.length),s.needsUpdate=!0);i.setDrawRange(0,e.length/3)}async start(){return await this.ready,this.handleTick(),this.handleCollisionEvents(),this.ready}handleCollisionEvents(){this.collisionSub=this.collisionEvents.subscribe(t=>{const e=this.colliders.get(t.handle1);if(null==e)return;const i=this.world.getCollider(t.handle2);if(null==i||null==i.parent())return;const s=this.bodyActors.get(i.parent());null!=s&&(t.started?e.onBeginOverlapActor.next({actor:s}):e.onEndOverlapActor.next({actor:s}))})}renderDebug(){if(null==this.scene)return;if(null==this.staticDebugMesh&&(this.staticDebugMesh=this.createDebugMesh(),this.staticDebugMesh.visible=this.shouldRenderDebug,this.staticDebugMesh.raycast=function(){},this.scene.add(this.staticDebugMesh)),null==this.debugMesh&&(this.debugMesh=this.createDebugMesh(),this.debugMesh.visible=this.shouldRenderDebug,this.debugMesh.raycast=function(){},this.scene.add(this.debugMesh)),this.staticDebugNeedsUpdate){const t=this.world.debugRender(s.ONLY_FIXED);this.updateDebugMesh(this.staticDebugMesh,t.vertices),this.staticDebugNeedsUpdate=!1}const t=this.world.debugRender(s.EXCLUDE_FIXED);this.updateDebugMesh(this.debugMesh,t.vertices)}async setup(){if(null!=this.rapier)throw new Error("Rapier is already estup");this.rapier=await ct(),this.eventQueue=new this.rapier.EventQueue(!0),this.setupWorld()}handleTick(){this.fixedupdateSub=this.viewController.onUpdate().subscribe(t=>{this._isStopped||(t=Math.min(.1,t),this.beforeStep.next(t),this.updatePhysics(t),this.showDebug&&this.renderDebug(),this.releaseExpiredRayDebugArrows(),this.world.bodies.forEach(t=>{if(t.isFixed())return;let e,i=this.staticMeshes.get(t);if(null==i&&(e=this.bodyActors.get(t),null!=e)){if(e.netRole===U.simulatedProxy)return;i=e.object}null!=i&&i.parent instanceof x&&(ut(i.position,t.translation()),(t.isDynamic()||t.isKinematic()&&!this.controlledActors.has(this.bodyActors.get(t)?.id))&&pt(i.quaternion,t.rotation()),i.matrixWorldNeedsUpdate=!0)}),this.afterStep.next(t))})}_updateWorld(){this.world.timestep=0,this.world.step()}updatePhysics(t){this._isStopped||(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(rt,this.viewController.getCamera());const s=this._raycaster.ray.origin,o=this._raycaster.ray.direction.multiplyScalar(t).add(s);return this.rayTest(s,o,e,i)}rayTest(t,e,i,s){null==i&&(i=this._reusableResult);const o=this._raytestDiff,r=this._raytestDirection;o.subVectors(e,t);const n=o.length();if(0===n)return console.warn("Ray test called with to and from being equal"),i;r.copy(o).multiplyScalar(1/n),null==ft&&(ft=new this.rapier.Ray(new this.rapier.Vector3(0,0,0),new this.rapier.Vector3(0,1,0))),dt(ft.origin,t),dt(ft.dir,r);const a=this.world.castRayAndGetNormal(ft,n,!1,void 0,s?.collisionFilter,void 0,null!=s?.excludeActor?this.actorBodies.get(s.excludeActor.id):void 0,s?.excludeTriggers?mt:void 0);if(i.hasHit=null!=a,i.actor=void 0,i.hasHit&&(i._internal=a,ut(i.hitNormal,a.normal),i.hitPoint.copy(t).addScaledVector(r,a.timeOfImpact),i.distance=a.timeOfImpact,!1!==s?.resolveActor)){const t=a.collider.parent();i.actor=null!=t?this.bodyActors.get(t):null}return this.showDebug&&!1!==s?.debug&&null!=this.scene&&this.drawRayDebugArrow(r,t,n,s?.debugColor,s?.debugLifetime),i}drawRayDebugArrow(t,e,i,s=255,o=200){let r=this.rayDebugArrowPool.pop();null==r?r=new h(t,e,i,s,.2,.1):(r.setDirection(t),r.position.copy(e),r.setLength(i,.2,.1),r.setColor(s)),r.userData.physicsRayDebugExpiresAt=performance.now()+o,this.activeRayDebugArrows.push(r),this.scene.add(r)}releaseExpiredRayDebugArrows(){if(0===this.activeRayDebugArrows.length)return;const t=performance.now();let e=0;for(let i=0;i<this.activeRayDebugArrows.length;i++){const s=this.activeRayDebugArrows[i];s.userData.physicsRayDebugExpiresAt<=t?(s.removeFromParent(),this.rayDebugArrowPool.push(s)):this.activeRayDebugArrows[e++]=s}this.activeRayDebugArrows.length=e}clearRayDebugArrows(){for(const t of this.activeRayDebugArrows)t.removeFromParent(),this.rayDebugArrowPool.push(t);this.activeRayDebugArrows.length=0}setGravity(t,e,i){this.world.gravity.x=t,this.world.gravity.y=e,this.world.gravity.z=i}getGravity(){return Z.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())yt(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 P&&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 W){const e=!1!==t.userData?.src?.collisionDetection;if(t.children[0]&&(t.children[0].instanceMatrix&&e||t.children[0].isBatchedMesh))this.createForInstancedMesh(t.children[0],t.collisionShapes);else if(e&&t.children.length>0){const e=this.createStaticBody(t,t.collisionShapes,t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}}else t instanceof N?this.addLandscapeGroup(t):(t instanceof y||t instanceof x)&&t.children.forEach(t=>this.addRecursively(t))}createForInstancedMesh(t,e){const i=new m;if(t instanceof d.BatchedMesh){const e=t._instanceInfo??t._drawInfo,s=new Map,o=t.userData.collisionMatrices;for(let r=0;r<e.length;r++){if(null!=t.userData.hasCollision&&!t.userData.hasCollision[r])continue;const e=t.userData.collisionShapes;let n=e?.[r];if(null==n&&null==e&&t.parent instanceof W&&(n=t.parent.collisionShapes),null==n)continue;const a=o?.[r];let l=n;null==a&&(l=s.get(n),null==l&&(l=this.instancedShapeReset(n),s.set(n,l)));const c=new b;c.matrix.identity(),null!=a?i.copy(a):t.getMatrixAt(r,i),c.applyMatrix4(i);this.createStaticBody(c,l)}}else{const s=this.instancedShapeReset(e);for(let e=0;e<t.count;e++){if(null!=t.userData.hasCollision&&!t.userData.hasCollision[e])continue;const o=new b;o.matrix.identity(),i.fromArray(t.instanceMatrix.array,16*e),o.applyMatrix4(i);this.createStaticBody(o,s)}}}instancedShapeReset(t){return t.filter(t=>null!=t).map(t=>I(t))}getCharacterController(t){return this.world?.createCharacterController(t)}getActorComputedMovement(t,e,i,o=null){const r=this.actorBodies.get(t.id);this.controlledActors.add(t.id);const n=r.collider(0);e.computeColliderMovement(n,i,s.EXCLUDE_SENSORS,o,mt);const a=e.computedMovement();return ut(gt,a),gt}setActorCapsuleCollider(t,e,i,s){const o=this.actorBodies.get(t.id),r=o?.collider(0);if(null==o||null==r)return!1;const n=t.object?.getWorldScale(bt)??et,a=Math.max(0,e*Math.abs(n.y)),l=Math.max(.001,i*Math.max(Math.abs(n.x),Math.abs(n.z)));return r.setHalfHeight(a/2),r.setRadius(l),ot.set(0,s,0).multiply(n),dt(it,ot),r.setTranslationWrtParent(it),o.recomputeMassPropertiesFromColliders(),o.isFixed()&&this.invalidateStaticDebug(),!0}hasActorCapsuleIntersection(t,e,i,o,r,n=null){const a=this.actorBodies.get(t.id),l=t.object?.getWorldScale(bt)??et,c=Math.max(0,i*Math.abs(l.y)),d=Math.max(.001,o*Math.max(Math.abs(l.x),Math.abs(l.z))),h=new this.rapier.Capsule(c/2,d),u=t.object?.getWorldQuaternion(q)??H;ot.set(0,r,0).multiply(l).applyQuaternion(u).add(e);return null!=this.world.intersectionWithShape(ot,u,h,s.EXCLUDE_SENSORS,n??void 0,void 0,a,mt)}createCollider(t,e){const i=this.addShape(e?.body,t),s=new PhysicsCollider(i,this.world,this.invalidateStaticDebug);return this.colliders.set(i.handle,s),(null==e||e.body.isFixed())&&this.invalidateStaticDebug(),s.disposed.subscribe(()=>{this.colliders.delete(i.handle)}),s}createBody(t=PhysicsBodyType.dynamic,e={}){const i=(()=>{switch(t){case PhysicsBodyType.dynamic:return this.rapier.RigidBodyDesc.dynamic();case PhysicsBodyType.static:return this.rapier.RigidBodyDesc.fixed();case PhysicsBodyType.kinematic:return this.rapier.RigidBodyDesc.kinematicPositionBased();case PhysicsBodyType.kinematicVelocityBased:return this.rapier.RigidBodyDesc.kinematicVelocityBased();default:return this.rapier.RigidBodyDesc.dynamic()}})();e.position&&i.setTranslation(e.position.x,e.position.y,e.position.z),e.rotation&&i.setRotation({x:e.rotation.x,y:e.rotation.y,z:e.rotation.z,w:e.rotation.w}),"boolean"==typeof e.canSleep&&i.setCanSleep(e.canSleep),"boolean"==typeof e.ccdEnabled&&i.setCcdEnabled(e.ccdEnabled),"number"==typeof e.gravityScale&&i.setGravityScale(e.gravityScale),"number"==typeof e.mass&&i.setAdditionalMass(e.mass),void 0!==e.userData&&(i.userData=e.userData);const s=this.world.createRigidBody(i);return s.isFixed()&&this.invalidateStaticDebug(),new PhysicsBody(s,this.world,this.invalidateStaticDebug)}createJoint(t,e,i){let s,o;switch(i.type){case"fixed":s=this.rapier.JointData.fixed(i.anchor1,i.frame1,i.anchor2,i.frame2);break;case"spherical":s=this.rapier.JointData.spherical(i.anchor1,i.anchor2);break;case"revolute":s=this.rapier.JointData.revolute(i.anchor1,i.anchor2,i.axis),null!=i.limits&&(o=i.limits)}const r=this.world.createImpulseJoint(s,t.body,e.body,!0);if(null!=o){r.setLimits(o[0],o[1])}return r.setContactsEnabled(i.contactsEnabled??!1),new PhysicsJoint(r,this.world)}getCharacterComputedMovement(t,e,i,o=null){const r=t.collider;e.computeColliderMovement(r,i,s.EXCLUDE_SENSORS,o,mt);const n=e.computedMovement();return ut(gt,n),gt}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)}setNextKinematicPosition(t,e){this.actorBodies.get(t.id).setNextKinematicTranslation(e)}setNextKinematicRotation(t,e){this.actorBodies.get(t.id).setNextKinematicRotation(e)}setNextKinematicTransform(t){!function(t,e){const i=e.getWorldPosition(J),s=e.getWorldQuaternion($);t.setNextKinematicTranslation(nt(i)),t.setNextKinematicRotation(at(s))}(this.actorBodies.get(t.id),t.object)}setAngularVelocity(t,e){const i=this.actorBodies.get(t.id);it.x=e.x,it.y=e.y,it.z=e.z,i?.setAngvel(it,!0)}setLinearVelocity(t,e){const i=this.actorBodies.get(t.id);it.x=e.x,it.y=e.y,it.z=e.z,i?.setLinvel(it,!0)}getLinearVelocity(t,e=new v){const i=this.actorBodies.get(t.id);if(null==i)return e.set(0,0,0);const s=i.linvel();return e.x=s.x,e.y=s.y,e.z=s.z,e}getAngularVelocity(t,e=new v){const i=this.actorBodies.get(t.id);if(null==i)return e.set(0,0,0);const s=i.angvel();return e.x=s.x,e.y=s.y,e.z=s.z,e}setLinearDamping(t,e){const i=this.actorBodies.get(t.id);i?.setLinearDamping(e)}getLienarDamping(t){const e=this.actorBodies.get(t.id);return e?.linearDamping()??0}setAngularDamping(t,e){const i=this.actorBodies.get(t.id);i?.setAngularDamping(e)}getAngularDamping(t){const e=this.actorBodies.get(t.id);e?.angularDamping()}setPosition(t,e){const i=this.actorBodies.get(t.id);i?.setTranslation(nt(e),!1)}getPosition(t,e=new v){const i=this.actorBodies.get(t.id);i&&ut(e,i.translation())}setRotation(t,e){const i=this.actorBodies.get(t.id);i?.setTranslation(at(e),!1)}getRotation(t,e=new f){const i=this.actorBodies.get(t.id);i&&pt(e,i.rotation())}lockTranslations(t,e){const i=this.actorBodies.get(t.id);i?.lockTranslations(e,!1)}lockRotations(t,e){const i=this.actorBodies.get(t.id);i?.lockRotations(e,!1)}setEnabledTranslations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledTranslations(e,i,s,!1)}setEnabledRotations(t,e,i,s){const o=this.actorBodies.get(t.id);o?.setEnabledRotations(e,i,s,!1)}addLandscapeGroup(t){this.invalidateStaticDebug();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));var o=r.getWorldPosition(new v);if(e.landscape.holes&&e.landscape.holes.some(t=>t.m===r.name&&0!==t.w[0])){const t=r.geometry.clone(),i=r.scale,s=r.geometry.getAttribute("hole"),n=new Float32Array(t.getAttribute("position").array);for(let t=0;t<n.length;t+=3)n[t]*=i.x,n[t+1]*=i.y,n[t+2]*=i.z;const a=t.index;for(let t=0;t<a.count;t+=3){const e=s.getX(a.getX(t)),i=s.getX(a.getY(t)),o=s.getX(a.getZ(t));(e>.5||i>.5||o>.5)&&(a.setX(t,0),a.setY(t,0),a.setZ(t,0))}const l=this.rapier.ColliderDesc.trimesh(n,new Uint32Array(t.getIndex().array));if(!1!==e.collisionDetection){const t=this.world.createRigidBody(this.rapier.RigidBodyDesc.fixed()),e=new this.rapier.Vector3(0,0,0);dt(e,o),t.setTranslation(e,!1),this.world.createCollider(l,t),this.staticBodies.set(r,t)}continue}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 l=s.find(t=>t.x===r.x&&t.y==r.y);if(null!=l)for(const e of l.points){if(null==a[e.i%t])continue;const i=t-1-Math.floor(e.i/t);i in a[e.i%t]?a[e.i%t][i]=e.y/n:console.warn("wrong index",{points:a,point:e,i:e.i%t,k:i,heightMap:l})}const c=e.landscape.options.density,d=a.flatMap(t=>t.reverse()),h=i.ColliderDesc.heightfield(c,c,new Float32Array(d),new this.rapier.Vector3(n,n,n));if(!1!==e.collisionDetection){const t=this.world.createRigidBody(this.rapier.RigidBodyDesc.fixed()),e=new this.rapier.Vector3(0,0,0);dt(e,o),t.setTranslation(e,!1),this.world.createCollider(h,t),this.staticBodies.set(r,t)}}}setEnabled(t,e){const i=this.actorBodies.get(t.id);i?.setEnabled(e),i?.isFixed()&&this.invalidateStaticDebug()}addActor(t,e,i={}){if(0==e.length)return void console.error("No collision shapes were defined when adding actor to the physics system.");this.removeActor(t);const s=t.object;let o;switch(i.type??PhysicsBodyType.static){case PhysicsBodyType.dynamic:o=this.rapier.RigidBodyDesc.dynamic(),o.mass=i.mass??1;break;case PhysicsBodyType.kinematic:o=this.rapier.RigidBodyDesc.kinematicPositionBased();break;case PhysicsBodyType.kinematicVelocityBased:o=this.rapier.RigidBodyDesc.kinematicVelocityBased();break;default:o=i.isTrigger?this.rapier.RigidBodyDesc.kinematicVelocityBased():this.rapier.RigidBodyDesc.fixed()}const r=this.world.createRigidBody(o);r.enableCcd(1==i.continousCollisionDetection);for(const t of e)this.addShape(r,t,s);return yt(r,t=>{null!=i.isTrigger&&(t.setSensor(i.isTrigger),t.setActiveCollisionTypes(this.rapier.ActiveCollisionTypes.ALL),t.setActiveEvents(this.rapier.ActiveEvents.COLLISION_EVENTS)),null!=i.friction&&t.setFriction(i.friction),null!=i.density&&t.setDensity(i.density),null!=i.mass&&t.setMass(i.mass),null!=i.restitution&&t.setRestitution(i.restitution)}),Y(r,s),!0===i.ignoreForNavMesh&&(r.userData={ignoreForNavMesh:!0}),this.actorBodies.set(t.id,r),this.bodyActors.set(r,t),r.isFixed()&&this.invalidateStaticDebug(),new PhysicsBody(r,this.world,this.invalidateStaticDebug)}applyTorque(t,e){const i=this.actorBodies.get(t.id);it.x=e.x,it.y=e.y,it.z=e.z,i?.addTorque(it,!0)}applyTorqueImpulse(t,e){const i=this.actorBodies.get(t.id);it.x=e.x,it.y=e.y,it.z=e.z,i?.applyTorqueImpulse(it,!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);it.x=e.x,it.y=e.y,it.z=e.z,i?.addForce(it,!0)}applyImpulse(t,e){const i=this.actorBodies.get(t.id);it.x=e.x,it.y=e.y,it.z=e.z,i?.applyImpulse(it,!0)}applyLocalForce(t,e,i){const s=this.actorBodies.get(t.id);dt(it,e),null==i?s?.addForce(it,!0):(dt(st,i),s?.addForceAtPoint(it,st,!0))}applyLocalImpulse(t,e,i){const s=this.actorBodies.get(t.id);dt(it,e),null==i?s.applyImpulse(it,!0):(dt(st,i),s.applyImpulseAtPoint(it,st,!0))}applyRadiusImpulse(t,e,s){this.world.bodies.forEach(o=>{if(o.collider(0)?.isSensor())return;if(o.bodyType()!==i.RigidBodyType.Dynamic)return;const r=ot;ut(r,o.translation());const n=r.clone().sub(t);if(n.length()>e)return;const a=n.clone().normalize().multiplyScalar(s);it.x=a.x,it.y=a.y,it.z=a.z,o.applyImpulse(it,!0)})}removeActor(t){if(null==t)return;this.controlledActors.delete(t.id);const e=this.actorBodies.get(t.id);null!=e&&(e.isFixed()&&this.invalidateStaticDebug(),this.bodyActors.delete(e),this.world.removeRigidBody(e)),this.actorBodies.delete(t.id)}removeRemoved(t){if(null==t)return;const e=new Set;t.traverse(t=>{e.add(t.uuid)});for(const[t,i]of this.staticBodies.entries())e.has(t.uuid)&&this.world.getRigidBody(i.handle)&&(this.invalidateStaticDebug(),this.staticBodies.delete(t),this.world.removeRigidBody(i))}removeSceneObject(t){if(t instanceof N){for(const e of t.sections)this.removeSceneObject(e);return}let e=this.staticBodies.get(t);null!=e&&this.world.getRigidBody(e.handle)&&(this.invalidateStaticDebug(),this.world.removeRigidBody(e)),this.staticBodies.delete(t)}activateActorEvents(t){this.actorBodies.get(t.id)}_onCollisionWithActorEvent(t,e,i){return this.activateActorEvents(t),this.collisionEvents.pipe(c(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(c(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(c(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())}onBeginOverlap(t){return this._onCollisionWithActorEvent(t,()=>!0,!0)}onEndOverlap(t){return this._onCollisionWithActorEvent(t,()=>!0,!1)}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&&(Y(e,t.object),e.isFixed()&&this.invalidateStaticDebug())}flushModifiedBodyPositionsToColliders(){this.world.propagateModifiedBodyPositionsToColliders()}setupWorld(){const t=new this.rapier.World({x:0,y:-9.81,z:0});this.world=t,this.invalidateStaticDebug()}sphereCast(t,e,i,s,o=ShapeCastResult.shared,r){o.reset();const n=this.getBallShape(e);this.shapeCacheBall.get;const a={x:t.x,y:t.y,z:t.z},l={x:i.x,y:i.y,z:i.z},c=r?.excludeActor?this.actorBodies.get(r.excludeActor.id):null,d=this.world.castShape(a,{x:0,y:0,z:0,w:1},l,n,.01,s,!0,null,r?.collisionFilter??void 0,null,c,r?.excludeTriggers?t=>!t.isSensor():void 0);if(null!=d){ut(o.hitPoint,d.witness1),o.normal.set(d.normal1.x,d.normal1.y,d.normal1.z),o.distance=d.time_of_impact,o.hasHit=!0;const t=d.collider.parent();if(t){const e=this.bodyActors.get(t);e&&(o.actor=e)}}return o}castActorShape(t,e,i,s=ShapeCastResult.shared,o=void 0){s.reset();const r=this.actorBodies.get(t.id);if(r&&r.numColliders()>0){for(let t=0;t<r.numColliders();t++){const n=r.collider(t);let a=n.shape,l=n.translation(),c=n.rotation(),d=e,h=i;const u=this.world.castShape(l,c,d,a,.01,h,!0,null,o,null,r,void 0);if(null!=u){u.collider;const t=n;return ut(s.hitPoint,u.witness1),xt(t.rotation(),u.normal1,s.normal,X),s.distance=u.time_of_impact,s.actor=this.bodyActors.get(u.collider.parent()),s.hasHit=!0,s}}return s}return console.warn("Actor is not added to the physics system"),s}stop(){if(!this._isStopped){this._isStopped=!0,this.bodyActors.clear(),this.actorBodies.clear(),this.staticBodies.clear(),this.staticMeshes.clear(),this.colliders.clear(),this.fixedupdateSub?.unsubscribe(),this.collisionSub?.unsubscribe(),this.world?.bodies.forEach(t=>this.world.removeRigidBody(t));try{this.world?.free(),this.world=void 0}catch(t){console.warn("Error while freeing physics world",t)}this.clearRayDebugArrows();for(const t of this.rayDebugArrowPool)t.dispose();this.rayDebugArrowPool.length=0}}createStaticBody(t,e,s){const o=s?.type===PhysicsBodyType.dynamic?i.RigidBodyDesc.dynamic():i.RigidBodyDesc.fixed();o.setSleeping(!0);const r=this.world.createRigidBody(o);let n=0;for(const i of e){if(n>128){console.warn("Too many collision shapes for object",t);break}if(n++,null==i){console.warn("Collision shape is missing for object",t);continue}const o=this.addShape(r,i,t);null!=o&&(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 Y(r,t),r.userData=t.uuid,r.sleep(),r.isFixed()&&this.invalidateStaticDebug(),r}addShape(t=void 0,e,i){const s=i?.getWorldScale(bt)??et,o=this.createShape(e,s);if(null==o)return void console.error("Failed to create physics shape. This can happen if the geometry is degenerate or zero-scaled.",{shapeInfo:e,object:i});this.applyShapeSettings(o,e);const r=e.offset.clone().multiply(s);dt(o.translation,r);const n=(new f).setFromEuler(e.rotation);ht(o.rotation,n),null!=t&&t.numColliders()>128&&console.warn(`Rigid body has many colliders (${t.numColliders()}). Consider using a Trimesh if this is static geometry.`,t);try{return this.world.createCollider(o,t)}catch(t){return void console.error("Failed to create collider",t)}}applyShapeSettings(t,e){null!=e.collisionGroup&&t.setCollisionGroups(e.collisionGroup),t.friction=e.friction??.1,null!=e.restitution&&(t.restitution=e.restitution),null!=e.density&&(t.density=e.density,t.massPropsMode=i.MassPropsMode.Density),null!=e.mass&&(t.mass=e.mass,t.massPropsMode=i.MassPropsMode.Mass)}createShape(t,e){if(t instanceof R)return this.rapier.ColliderDesc.cuboid(t.dimensions.x*e.x/2,t.dimensions.y*e.y/2,t.dimensions.z*e.z/2);if(t instanceof M){return this.rapier.ColliderDesc.capsule(t.length/2*e.y,t.radius*Math.max(e.z,e.x))}if(t instanceof j){const i=null!=t.geometry.getIndex()?t.geometry:D.mergeVertices(t.geometry),s=extractFloat32Array(i.getAttribute("position"));for(let t=0;t<s.length;t+=3)s[t]*=e.x,s[t+1]*=e.y,s[t+2]*=e.z;const o=i.getIndex();return null==o?(console.error("Trimesh collision shape is missing an index buffer.",t),null):this.rapier.ColliderDesc.trimesh(s,new Uint32Array(o.array))}if(t instanceof z){let i,s;t.mesh instanceof d.Mesh?i=t.mesh.geometry:t.mesh instanceof d.BufferGeometry?i=t.mesh:console.log("Unknownd shape",{shapeInfo:t}),t.mesh instanceof d.Mesh&&(s=k(t.mesh));const o=`${i.uuid}|${s?.x??1},${s?.y??1},${s?.z??1}|${e.x},${e.y},${e.z}`,r=tt.get(o);if(void 0!==r)return r;const n=extractFloat32Array(i.getAttribute("position"));if(null!=s)for(let t=0;t<n.length;t+=3)n[t]*=s.x,n[t+1]*=s.y,n[t+2]*=s.z;for(let t=0;t<n.length;t+=3)n[t]*=e.x,n[t+1]*=e.y,n[t+2]*=e.z;const a=this.rapier.ColliderDesc.convexHull(n);return null==a&&console.error("Failed to compute convex hull. Points may be coplanar or too few.",{count:n.length/3}),tt.set(o,a),a}if(t instanceof _){const i=2*e.x-e.y-e.z;return Math.abs(i)>.01?this.createShape(new z(new d.SphereGeometry(t.radius).scale(e.x,e.y,e.z)),new v(1,1,1)):this.rapier.ColliderDesc.ball(t.radius*Math.max(e.x,e.y,e.z))}return t instanceof T?this.rapier.ColliderDesc.cylinder(t.height/2*e.y,t.radiusTop*Math.max(e.z,e.x)):t instanceof E?this.rapier.ColliderDesc.cone(t.height*e.y,t.radiusBottom/2*Math.max(e.z,e.x)):t instanceof F?this.rapier.ColliderDesc.cuboid(t.width/2*e.x,t.height/2*e.y,.001):(console.error("Unsupported shape",t),this.rapier.ColliderDesc.cuboid(1,1,1))}createCharacterCollision(){return new this.rapier.CharacterCollision}};Q=t([B(),e("design:paramtypes",[])],Q);export{Q as PhysicsSystem};const J=new v,$=new d.Quaternion;function Y(t,e){const i=e.getWorldPosition(J),s=e.getWorldQuaternion($);t.setTranslation(nt(i),!1),t.setRotation(at(s),!1)}const Z=new v,tt=new Map,et=new v(1,1,1),it=new i.Vector3(0,0,0),st=new i.Vector3(0,0,0),ot=new v,rt=new d.Vector2;function nt(t){return dt(it,t),it}function at(t){return ht(X,t),X}let lt=null;const ct=async()=>(null==lt&&(lt=(async()=>{let t=await import("@dimforge/rapier3d-simd-compat");return await t.init(),t})()),lt);function dt(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function ht(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}function ut(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function pt(t,e){t.x=e.x,t.y=e.y,t.z=e.z,t.w=e.w}function yt(t,e){for(let i=0,s=t.numColliders();i<s;i++){e(t.collider(i))}}const gt=new v,mt=t=>!t.isSensor(),bt=new v;let ft,wt=class extends S{constructor(){super(...arguments),this._active=!0,this.physics=C(Q),this.world=C(L)}set active(t){this._active=t,t?(this.world.scene.remove(this.actor.object),this.physics.setEnabled(this.actor,t)):(this.world.scene.add(this.actor.object),this.physics.setEnabled(this.actor,t))}get active(){return this._active}};wt=t([A()],wt);export function extractFloat32Array(t){const e=t.itemSize,i=t.count,s=new Float32Array(i*e);for(let o=0;o<i;o++)for(let i=0;i<e;i++)s[o*e+i]=t.getComponent(o,i);return s}function xt(t,e,i,s){return s.set(t.x,t.y,t.z,t.w),i.set(e.x,e.y,e.z),i.applyQuaternion(s),i}export class PhysicsCollider{constructor(t,e,i){this.collider=t,this.world=e,this.invalidateStaticDebug=i,this.disposed=new l,this.onBeginOverlapActor=new l,this.onEndOverlapActor=new l}dispose(){const t=this.collider.parent();(null==t||t.isFixed())&&this.invalidateStaticDebug?.(),this.world.removeCollider(this.collider,!1),this.disposed.next(!0),this.disposed.complete(),this.onBeginOverlapActor.complete(),this.onEndOverlapActor.complete()}set mass(t){this.collider.setMass(t)}get mass(){return this.collider.mass()}set friction(t){this.collider.setFriction(t)}get friction(){return this.collider.friction()}set restitution(t){this.collider.setRestitution(t)}get restitution(){return this.collider.restitution()}set density(t){this.collider.setDensity(t)}get density(){return this.collider.density()}set isTrigger(t){this.collider.setSensor(t)}get isTrigger(){return this.collider.isSensor()}set collisionGroups(t){this.collider.setCollisionGroups(t)}get collisionGroups(){return this.collider.collisionGroups()}set enabled(t){this.collider.setEnabled(t);const e=this.collider.parent();(null==e||e.isFixed())&&this.invalidateStaticDebug?.()}get enabled(){return this.collider.isEnabled()}}export class PhysicsBody{constructor(t,e,i){this.invalidateStaticDebug=i,this.body=t,this.world=e}dispose(){this.body.isFixed()&&this.invalidateStaticDebug?.(),this.world.removeRigidBody(this.body)}setEnabled(t){this.body.setEnabled(t),this.body.isFixed()&&this.invalidateStaticDebug?.()}isEnabled(){return this.body.isEnabled()}getPosition(t){const e=this.body.translation();return t.set(e.x,e.y,e.z),t}setPosition(t){this.body.setTranslation({x:t.x,y:t.y,z:t.z},!0),this.body.isFixed()&&this.invalidateStaticDebug?.()}getRotation(t){const e=this.body.rotation();return t.set(e.x,e.y,e.z,e.w),t}setRotation(t){this.body.setRotation({x:t.x,y:t.y,z:t.z,w:t.w},!0),this.body.isFixed()&&this.invalidateStaticDebug?.()}getLinearVelocity(t){const e=this.body.linvel();return t.set(e.x,e.y,e.z),t}setLinearVelocity(t){this.body.setLinvel({x:t.x,y:t.y,z:t.z},!0)}getAngularVelocity(t){const e=this.body.angvel();return t.set(e.x,e.y,e.z),t}setAngularVelocity(t){this.body.setAngvel({x:t.x,y:t.y,z:t.z},!0)}setLinearDamping(t){this.body.setLinearDamping(t)}setAngularDamping(t){this.body.setAngularDamping(t)}applyImpulse(t,e=!0){this.body.applyImpulse({x:t.x,y:t.y,z:t.z},e)}applyTorqueImpulse(t,e=!0){this.body.applyTorqueImpulse({x:t.x,y:t.y,z:t.z},e)}setNextKinematicPosition(t){this.body.setNextKinematicTranslation(t)}setNextKinematicRotation(t){this.body.setNextKinematicRotation(t)}setType(t){const e=this.body.isFixed();this.body.setBodyType(function(t){switch(t){case PhysicsBodyType.dynamic:return i.RigidBodyType.Dynamic;case PhysicsBodyType.static:return i.RigidBodyType.Fixed;case PhysicsBodyType.kinematic:return i.RigidBodyType.KinematicPositionBased;case PhysicsBodyType.kinematicVelocityBased:return i.RigidBodyType.KinematicVelocityBased}}(t),t!==PhysicsBodyType.static),(e||this.body.isFixed())&&this.invalidateStaticDebug?.()}setGravityScale(t){this.body.setGravityScale(t,!1)}getGravityScale(){return this.body.gravityScale()}isDynamic(){return this.body.isDynamic()}isKinematic(){return this.body.isKinematic()}isStatic(){return this.body.isFixed()}sleep(){this.body.sleep()}wakeUp(){this.body.wakeUp()}}export class PhysicsJoint{constructor(t,e){this.joint=t,this.world=e}dispose(){this.joint.isValid()&&this.world.removeImpulseJoint(this.joint,!0)}setContactsEnabled(t){this.joint.setContactsEnabled(t)}get contactsEnabled(){return this.joint.contactsEnabled()}}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as t}from"tslib";import{Service as e}from"typedi";import{BaseActor as r}from"../actors/actor.js";import{ActorFactory as s}from"../actors/factory.js";import{Group as
|
|
1
|
+
import{__decorate as t}from"tslib";import{Service as e}from"typedi";import{BaseActor as r}from"../actors/actor.js";import{ActorFactory as s}from"../actors/factory.js";import{Group as i,Vector3 as n}from"three";import{ActorComponent as o}from"../../gameplay/actors/component.js";import{Subject as a}from"rxjs";import{RenderingView as c}from"../../rendering.js";import{randomUUID as h}from"../../utils/uuid";import{PrefabInstance as p}from"../../scene/objects/prefab";import{PhysicsSystem as l}from"./physics/physics-system.js";import{inject as d}from"../../gameplay/inject.js";import{isComponentEnabledInEnvironment as m}from"../actors/internal/component-init.js";import{NetRole as v}from"../net/service/net-actor-role.js";import{BasePlayerController as f}from"../actors/controller/actor-controller.js";import{EventGraphInstance as y}from"../event-graph/runtime.js";import{ViewController as w}from"./render.js";import{AssetsProvider as u}from"../../scene/assets-provider.js";import{WorldEventGraphAssetRuntime as b}from"../event-graph/runtime-assets.js";import{hasExecutableEventGraphDocument as E}from"../event-graph/model.js";const A=new n;class g{constructor(t){this.view=t}get direction(){return this.view.csm.lightDirection}set intensity(t){this.view.csm.lightIntensity=t,this.view.csm.lights.forEach(t=>t.intensity=this.view.csm.lightIntensity)}get intensity(){return this.view.csm.lightIntensity}get position(){return 0==this.view.csm.lights.length?A:this.view.csm.lights[0].position}}let G=class{constructor(){this.actorFactory=d(s),this.view=d(c),this.viewController=d(w),this.physics=d(l),this.assetsProvider=d(u),this.eventGraphAssets=new b(this,this.assetsProvider),this.actors=[],this.actorAdded=new a,this.actorRemoved=new a,this.directionalLight=new g(this.view),this.sceneEventGraphs=new Map,this.sceneEventGraphSubscriptions=[]}async spawnActor(t,e,r,s){if(null==t)throw new Error("Cannot spawn actor with null type");if("prefab"in t){const i=t.prefab,n=await this.spawnPrefab(i,e,r),o=n.mainActor;if(null==o)throw new Error(`Prefab has no main actor or there was an error when spwaning it. Prefab: ${JSON.stringify(i)}`);return o.disposed.subscribe(()=>{const t=n.actors.findIndex(t=>t===o);t>=0&&n.actors.splice(t,1),this.removePrefab(n)}),null!=s?.owner&&(o.owner=s.owner),o}const i=await this.actorFactory.create(t,e,r);return null!=s?.owner&&(i.owner=s.owner),this.addActor(i,e,r),i}async spawnActorWithNetInfo(t,e,r,s,i,n){const o=await this.actorFactory.create(t,i,n,!0),a=null!=s&&0!==s?this.actors.find(t=>t.__netid===s):null;return o.__netid=e,o.netRole=r,o.owner=a,o instanceof f&&(o.isLocallyControlled=r===v.autonomousProxy),this.actorFactory.initActor(o),this.addActor(o,i,n),o}async spawnLocalPlayerController(t,e,r){const s=await this.actorFactory.create(t,e,r,!0);return s.isLocallyControlled=!0,this.actorFactory.initActor(s),this.addActor(s,e,r),s}spawnActorSync(t,e,r){if(null==t)throw new Error("Cannot spawn actor with null type");const s=this.actorFactory.createSync(t,e,r);return this.addActor(s,e,r),s}addActor(t,e,r){e&&t.object.position.copy(e),r&&t.object.rotation.copy(r),null==t.object.parent&&this.scene.add(t.object),this.actors.push(t),j(t,t=>t.onBeginPlay(),this.actorFactory.inEditor),this.actorAdded.next(t)}removeActor(t){for(const[e,r]of[...this.sceneEventGraphs])r.binding.mainActor===t&&this.deactivateSceneEventGraph(e);j(t,t=>t.onEndPlay(),this.actorFactory.inEditor);const e=this.actors.indexOf(t);e>=0&&this.actors.splice(e,1),t.object.removeFromParent(),t.disposed.next(!0),this.actorRemoved.next(t),this.physics.removeActor(t)}findActorByType(t,e){return this.actors.find(r=>r instanceof t&&(null==e||r.object.name==e))}findActorsByType(t,e){return this.actors.filter(r=>r instanceof t&&(null==e||r.object.name==e))}resolveSceneActor(t){return this.materializer?.resolveSceneActor(t)}async startSceneEventGraphs(t){this.stopSceneEventGraphs(),this.sceneEventGraphSubscriptions.push(t.prefabEventGraphAdded$.subscribe(t=>{this.activateSceneEventGraph(t).catch(e=>{console.error(`Failed to start scene prefab event graph ${JSON.stringify(t.id)}`,e)})}),t.prefabEventGraphRemoved$.subscribe(t=>{this.deactivateSceneEventGraph(t.id);for(const e of t.actors)this.actors.includes(e)&&this.removeActor(e)}));for(const e of t.prefabEventGraphInstances)await this.activateSceneEventGraph(e)}stopSceneEventGraphs(){for(const t of this.sceneEventGraphSubscriptions)t.unsubscribe();this.sceneEventGraphSubscriptions.length=0;for(const t of[...this.sceneEventGraphs.keys()])this.deactivateSceneEventGraph(t)}async activateSceneEventGraph(t){if(this.sceneEventGraphs.has(t.id))return;for(const e of t.actors)this.actors.includes(e)||this.addActor(e);const e=new y(t.graph,{world:this,actorsById:t.actorsById,mainActor:t.mainActor,updates:this.viewController.onUpdate(),timer:this.viewController,physics:this.physics,assets:this.eventGraphAssets});this.sceneEventGraphs.set(t.id,{binding:t,runtime:e});try{await e.beginPlay()}catch(r){throw this.sceneEventGraphs.delete(t.id),e.endPlay(),r}}deactivateSceneEventGraph(t){const e=this.sceneEventGraphs.get(t);null!=e&&(this.sceneEventGraphs.delete(t),e.runtime.endPlay())}async spawnPrefab(t,e,r){if(null==this.materializer)return console.error("Internal error: Materializer is missing on World"),null;const s=new p,n=new i;null!=e&&n.position.copy(e),null!=r&&n.rotation.copy(r),this.materializer.setScene(this.scene),this.materializer.inEditor=this.actorFactory.inEditor;const o=null!=t.asset.id?await(this.assetsProvider?.getAsset(t.asset.id))??t.asset:t.asset,{object:a,actors:c,actorsById:l,mainActor:d,instanceId:m}=await this.materializer.createFromPrefabAsset(o,{sceneObjectChain:["r-"+h()],runtimeSpawn:!0},n,void 0,!1);s.object=a,s.actors=c,s.mainActor=d,s.__materializerInstanceId=m,this.scene.attach(a),c.forEach(t=>{this.addActor(t)}),this.physics.addFromScene(a);const v=o.prefab?.eventGraph;if(!this.actorFactory.inEditor&&E(v)){s.eventGraph=new y(v,{world:this,actorsById:l,mainActor:d,updates:this.viewController.onUpdate(),timer:this.viewController,physics:this.physics,assets:this.eventGraphAssets});try{await s.eventGraph.beginPlay()}catch(t){throw this.removePrefab(s),t}}return s}removePrefab(t){if(t.destroyed)return;t.destroyed=!0,t.eventGraph?.endPlay(),t.eventGraph=void 0,null!=t.__materializerInstanceId&&(this.materializer.unregisterLivePrefabInstance?.(t.__materializerInstanceId),t.__materializerInstanceId=void 0);t.actors.splice(0).forEach(t=>this.removeActor(t)),t.object?.removeFromParent(),this.physics.removeRemoved(t.object)}};G=t([e()],G);export{G as World};function j(t,e,s=!1,i=new WeakSet){if(!i.has(t))return i.add(t),e(t),t instanceof r&&t.attachedComponents.forEach(t=>{m(t,s)&&j(t,e,s,i)}),Object.entries(t).filter(([t,e])=>e instanceof o&&m(e,s)).forEach(([t,r])=>{j(r,e,s,i)})}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -37,6 +37,7 @@ export declare class AssetResourceLoader {
|
|
|
37
37
|
private getUri;
|
|
38
38
|
private _texturePromises;
|
|
39
39
|
private _arrayTexturesByFileKey;
|
|
40
|
+
private _arrayTexturePromisesByFileKey;
|
|
40
41
|
private _arrayTextureSettingsByFileKey;
|
|
41
42
|
private _animationPromises;
|
|
42
43
|
private _animationCache;
|
|
@@ -51,6 +52,7 @@ export declare class AssetResourceLoader {
|
|
|
51
52
|
texture: Texture | null;
|
|
52
53
|
layerIndex: number | null;
|
|
53
54
|
}>;
|
|
55
|
+
private loadTextureArray;
|
|
54
56
|
private applyTextureArraySettings;
|
|
55
57
|
private _getTextureLoader;
|
|
56
58
|
clearCache(asset: Asset): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AudioLoader as e,BufferGeometry as t,Euler as r,Group as a,LoadingManager as s,Mesh as i,Object3D as n,Texture as o,TextureLoader as l,Vector3 as c}from"three";import{MTLLoader as h,OBJLoader as u,LUTCubeLoader as m}from"three-stdlib";import{cloneMesh as p}from"../utils/mesh.js";import{pathJoin as d}from"../utils/files.js";import{Subject as f,firstValueFrom as y}from"rxjs";import{BoxCollisionShape as g,CapsuleCollisionShape as w,CollisionShapeSource as x,CylinderCollisionShape as M,SphereCollisionShape as A}from"./collision/collision-shape.js";import{importCollisionShapes as b,isCollisionMesh as _}from"./collision/collision-shape-import.js";import*as S from"three";import{iterateMaterials as L}from"../utils/materials.js";import{applyMaterial as T,getConvertedFbxToGlbAssignedMaterialTextureFlipY as v}from"./materializer.js";import{BufferGeometryUtils as C,DRACOLoader as R,EXRLoader as P,FBXLoader as K,GLTFLoader as I,KTX2Loader as k,TGALoader as B,UltraHDRLoader as D}from"three/examples/jsm/Addons.js";import{disposeScene as F}from"../utils/three/cleanup.js";import{resolveAnimationRigBasisRotation as W,setAnimationClipRigId as j}from"../gameplay/animation/retarget.js";(()=>{const e=new Uint8Array([255,0,0,255]),t=new S.DataTexture(e,1,1,S.RGBAFormat);t.needsUpdate=!0})();const U=new R;U.setDecoderConfig({type:"js"}),U.setDecoderPath("/assets/draco/");const E=["glb","gltf","fbx","obj"];export class AssetResourceLoader{onError(e){console.error(e)}constructor(){this.cache=new Map,this.textureCache=new Map,this.loadingManager=new s,this.glbLoader=new I(this.loadingManager).setDRACOLoader(U),this.fbxLoader=new K(this.loadingManager),this.objLoader=new u(this.loadingManager),this.textureLoader=new l(this.loadingManager),this.tgaLoader=new B(this.loadingManager),this.exrLoader=new P(this.loadingManager),this.cubeLoader=new m(this.loadingManager),this.hdrLoader=new D(this.loadingManager),this.ktx2Loader=new k(this.loadingManager),this._textureLoader=new S.ImageBitmapLoader(this.loadingManager),this.audioLoader=new e(this.loadingManager),this.initialisedKtx2=!1,this._retrievedMeshes=[],this._retrievedTextures=[],this.makeReady=new f,this.ready=y(this.makeReady),this._texturePromises=new Map,this._arrayTexturesByFileKey=new Map,this._arrayTextureSettingsByFileKey=new Map,this._animationPromises=new Map,this._animationCache=new Map,this.asyncMeshResults=new Map,this.asyncAudioResults=new Map,this.collisionShapeCache=new Map,this.optimizedMeshes=new Set}initKtx2(e){this.initialisedKtx2=!0;null!=getElectronArg("windowId")||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?this.ktx2Loader.setTranscoderPath("/assets/basis/"):this.ktx2Loader.setTranscoderPath(new URL("../assets/basis/",import.meta.url).href),this.ktx2Loader.detectSupport(e),this.ktx2Loader.setWorkerLimit(6)}setDataDir(e){this.basePath=d(e,"asset-resources"),this.makeReady.next(!0)}getUri(e){const t=function(e){return G.get(e)}(e),r=getElectronArg("windowId");return null!=r||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?d(this.basePath,e)+(null!=r?`?windowId=${r}${null!=t?`&v=${t}`:""}`:""):new URL(d("..",this.basePath,e),import.meta.url).href}async getTexture(e){if(!e||!e.fileKey)return null;if("png"===e.fileFormat||e.fileFormat,this._texturePromises.has(e.id))return this._texturePromises.get(e.id);const t=this._getTexture(e).finally(()=>{this._texturePromises.delete(e.id)});return this._texturePromises.set(e.id,t),t}async _getTexture(e){if(null==e||null==e.fileKey)return null;if(await this.ready,this.textureCache.has(e.id)){const t=this.textureCache.get(e.id);if(null!=e.texture){const r=O(t,e);t.flipY!==r?(t.needsUpdate=!0,t.flipY=r):t.wrapS!==Y(e.texture?.wrapS)?(t.needsUpdate=!0,t.wrapS=Y(e.texture?.wrapS)):t.wrapT!==Y(e.texture?.wrapT)&&(t.wrapT=Y(e.texture?.wrapT),t.needsUpdate=!0)}const r=V(N(e));t.colorSpace!==r&&(t.colorSpace=r,t.needsUpdate=!0)}else try{await this._getTextureLoader(e.fileKey).loadAsync(this.getUri(e.fileKey)).then(t=>(t.texture3D?t=t.texture3D:(t.wrapS=Y(e.texture?.wrapS),t.wrapT=Y(e.texture?.wrapT),t.flipY=O(t,e),t.colorSpace=V(N(e))),this.textureCache.set(e.id,t),this._retrievedTextures.push(t),t))}catch(t){return console.warn("Failed to load texture "+e.name,t),null}const t=this.textureCache.get(e.id);return null!=t&&(t.userData.assetId=e.id),t}async getTextureArray(e){const t=e.texture?.textureArrayFileKey,r=e.texture?.textureArrayLayer;if(!t||null==r)return{texture:null,layerIndex:null};if(this._arrayTexturesByFileKey.has(t))this.applyTextureArraySettings(t,this._arrayTexturesByFileKey.get(t),e);else{const r=this._getTextureLoader(t);let a=await r.loadAsync(this.getUri(t));a instanceof o||(a=a.texture3D),this.applyTextureArraySettings(t,a,e),this._arrayTexturesByFileKey.set(t,a),this._retrievedTextures.push(a)}return{texture:this._arrayTexturesByFileKey.get(t),layerIndex:r}}applyTextureArraySettings(e,t,r){const a=function(e){return{wrapS:Y(e.texture?.wrapS),wrapT:Y(e.texture?.wrapT)}}(r),s=this._arrayTextureSettingsByFileKey.get(e);if(null!=s&&(n=a,(i=s).wrapS!==n.wrapS||i.wrapT!==n.wrapT))return void console.warn(`Texture array ${e} is used with incompatible texture settings. Texture arrays share wrapping; rebuild arrays so incompatible textures are grouped separately.`);var i,n;null==s&&this._arrayTextureSettingsByFileKey.set(e,a);let o=!1;t.wrapS!==a.wrapS&&(t.wrapS=a.wrapS,o=!0),t.wrapT!==a.wrapT&&(t.wrapT=a.wrapT,o=!0),!1!==t.flipY&&(t.flipY=!1,o=!0),o&&(t.needsUpdate=!0)}_getTextureLoader(e){return e?.toLowerCase().endsWith(".tga")?this.tgaLoader:e?.toLowerCase().endsWith(".ktx2")?this.ktx2Loader:e?.toLowerCase().endsWith(".exr")?this.exrLoader:e?.toLowerCase().endsWith(".cube")?this.cubeLoader:this.textureLoader}clearCache(e){this.clearCacheByAsset(e)}clearCacheByAsset(e){null!=e&&(this.clearCacheById(e.id),null!=e.fileKey&&(Array.from(this.cache.keys()).forEach(t=>{t.startsWith(e.fileKey)&&this.cache.delete(t)}),Array.from(this.asyncMeshResults.keys()).forEach(t=>{t.startsWith(e.fileKey)&&this.asyncMeshResults.delete(t)}),Array.from(this._animationCache.keys()).forEach(t=>{t.startsWith(e.fileKey+"|")&&this._animationCache.delete(t)}),Array.from(this._animationPromises.keys()).forEach(t=>{t.startsWith(e.fileKey+"|")&&this._animationPromises.delete(t)}),z(e.fileKey)),null!=e.materialLib&&z(e.materialLib))}clearCacheById(e){const t=Array.from(this.cache.values()).find(t=>t.scene.userData.assetId===e);t&&Array.from(this.cache.keys()).forEach(e=>{this.cache.get(e)===t&&this.cache.delete(e)}),this.textureCache.delete(e),this._texturePromises.delete(e),Array.from(this.collisionShapeCache.keys()).forEach(t=>{t.startsWith(e+"|")&&this.collisionShapeCache.delete(t)})}async getMesh(e,t){if(await this.ready,null==e)return console.error("No asset was provided"),{scene:new a,animations:[]};if(!E.includes(e.fileFormat?.toLowerCase()))return console.error("Unsupported mesh file format "+e.fileFormat,e),{scene:new a,animations:[]};const r=e.fileKey+(!0===t?.mergeGeomtries?"1":"0");if(!this.cache.has(r))try{this.asyncMeshResults.has(r)||this.asyncMeshResults.set(r,this.loadMesh(e).finally(()=>this.asyncMeshResults.delete(r))),this.cache.set(r,await this.asyncMeshResults.get(r))}catch(e){return this.onError(e),{scene:new a,animations:[]}}const s=this.cache.get(r).scene,n=this.computeCollisionShapes(e,s);!0===t?.mergeGeomtries&&this.optimizeDrawGroups(s);const o=p(s),l=this.cache.get(r).animations;o.traverse(e=>{e instanceof i&&e.material instanceof Array&&(e.material=e.material.slice())});const c=new AssetMeshInstance;c.add(o),c.collisionShapes=n,c.animations=l,c.userData.assetId=e.id;const h=e.mesh?.animationRigId??e.anim?.rigId;if(c.userData.animationRigId=h,o.userData.animationRigId=h,null!=h&&null!=this.animationRigProvider){const e=await this.animationRigProvider(h);c.userData.animationRig=e,o.userData.animationRig=e,null!=e&&!1!==t?.applyRigBasis&&c.quaternion.copy(W(e))}const u=e.receiveShadow??!1,m=e.castShadow??!1;if(o.traverse(e=>{e.castShadow=m,e.receiveShadow=u}),!0===t?.rescale&&"number"==typeof e.mesh?.rescale&&c.scale.setScalar(e.mesh?.rescale),!0===t?.applyMaterials){const r=t?.materialResolver??this.materialProvider;if(null!=r)for(const t of e.materialAssignments??[])await T(c,t,r,void 0,{textureFlipY:v(e)});else console.warn(`applyMaterials was set to true for ${e.name} but no material resolver was provided.`)}return{scene:c,animations:l}}async getAudio(e){await this.ready;const t=e.fileKey;if(this.asyncAudioResults.has(t))return await this.asyncAudioResults.get(t);const r=this.audioLoader.loadAsync(this.getUri(e.fileKey)).finally(()=>{setTimeout(()=>{this.asyncAudioResults.delete(t)},1e3)});return this.asyncAudioResults.set(t,r),r}async getAnimationClip(e){if(null==e||null==e.fileKey||null==e.anim?.clip)return console.warn("Asset or animation clip name is not defined",e),null;const t=e.anim.clip,r=e.fileKey+"|"+t;if(this._animationCache.has(r))return this._animationCache.get(r);if(this._animationPromises.has(r))return this._animationPromises.get(r);const a=(async()=>{try{const a=await this.getMesh(e),s=a.animations.find(e=>e.name===t);return null!=s&&(j(s,e.anim?.rigId),this._animationCache.set(r,s)),s}catch(e){return this.onError(e),null}finally{setTimeout(()=>this._animationPromises.delete(r),1e3)}})();return this._animationPromises.set(r,a),a}computeCollisionShapes(e,t){if(!0!==e.collisionDetection)return[];const r=e.id+"|"+(e.mesh?.collisions?.shapeType??"")+"|"+(e.mesh?.rescale??1)+"|"+JSON.stringify(e.mesh?.colliders??[]);if(!this.collisionShapeCache.has(r)){const a=e.mesh?.colliders??[],s=a.length>0?createAuthoredCollisionShapes(a,e.mesh?.rescale):b(t,e);this.collisionShapeCache.set(r,s)}return this.collisionShapeCache.get(r)}async loadMesh(e){return await this.ready,await this.loadByAsset(e).then(r=>(r.scene.traverse(e=>{e instanceof i&&e.material&&function(e){let t=e.material;if(null==t)return;Array.isArray(t)?e.material=t.map(Z):e.material=Z(t)}(e),_(e)?e.visible=!1:e instanceof i&&e.geometry instanceof t&&(e.geometry.hasAttribute("normal")||e.geometry.computeVertexNormals())}),this._retrievedMeshes.push(r.scene),r.scene=function(e,t){let r=!1;if(t.traverseVisible(e=>{J.test(e.name)&&(r=!0)}),!r)return t;const a=[],s=[t];for(;s.length>0;){const e=s.shift(),t=e.name.match(J);if(null!=t){const r=parseInt(t[1]);if(0!==r){console.warn(`Skipping LOD level ${r} for now as LOD is not fully supported`),a.push(e);continue}}s.push(...e.children)}for(const e of a)e.removeFromParent();return t}(0,r.scene),function(e){const t=q;q.length=0,e.traverse(e=>{(e instanceof S.Camera||e instanceof S.Light)&&t.push(e)}),t.forEach(e=>e.removeFromParent())}(r.scene),r.scene.userData.assetId=e.id,r))}optimizeDrawGroups(e){if(this.optimizedMeshes.has(e.uuid))return;this.optimizedMeshes.add(e.uuid),e.updateWorldMatrix(!0,!0);const r=[];e.traverse(e=>{e instanceof i&&!(e instanceof S.SkinnedMesh)&&e.geometry instanceof t&&Array.isArray(e.material)&&!_(e)&&r.push({mesh:e,geometry:e.geometry,materialArray:e.material,parent:e.parent})});for(const{mesh:t,geometry:a,materialArray:s,parent:n}of r){t.removeFromParent();for(let r=0;r<s.length;r++){const o=s[r],l=a.groups.filter(e=>e.materialIndex===r);if(0===l.length)continue;const c=this.extractGeometryGroups(a,l);c.groups.length>1&&C.mergeGroups(c);const h=new i(c,o);h.copy(t,!1),h.geometry=c,h.material=o,n?n.add(h):e.add(h)}a.dispose()}let a=!0,s=0,n=0;if(e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!_(e)){s++;const t=Object.keys(e.geometry.attributes).length;t!==n&&0!==n&&(a=!1),n=t}else(e instanceof S.SkinnedMesh||e instanceof S.Bone)&&(a=!1)}),s>1&&a){const r=new Map;e.traverse(a=>{if(a instanceof i&&a.geometry instanceof t&&!_(a)){if(Array.isArray(a.material))return;a.updateWorldMatrix(!0,!0);const t=a.material?.uuid||"default";r.has(t)||r.set(t,{material:a.material,geometries:[],objects:[]});const s=r.get(t),i=e.matrixWorld.clone().invert().multiply(a.matrixWorld);s.geometries.push(a.geometry.clone().applyMatrix4(i)),s.objects.push(a)}});for(const e of r.values())for(const t of e.objects)t.removeFromParent();for(const t of r.values()){let r;r=1===t.geometries.length?t.geometries[0]:C.mergeGeometries(t.geometries,!0),r.groups.length>1&&C.mergeGroups(r),e.add(new i(r,t.material))}}e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!_(e)){const t=e.geometry;!Array.isArray(e.material)&&t.groups.length>1&&C.mergeGroups(t)}})}extractGeometryGroups(e,r){const a=e.index;if(!a){const a=new t;let s=0;for(const e of r)s+=e.count;if(0===s)return a;for(const t in e.attributes){const i=e.attributes[t],n=i.itemSize,o=i.array,l=new(0,o.constructor)(s*n);let c=0;for(const e of r){const t=e.start*n,r=e.count*n;for(let e=0;e<r;e++)l[c+e]=o[t+e];c+=r}const h=new S.BufferAttribute(l,n,i.normalized);a.setAttribute(t,h)}return a.groups=[{start:0,count:s,materialIndex:0}],a}const s=[];for(const e of r)for(let t=0;t<e.count;t++){const r=a.getX(e.start+t);s.push(r)}if(0===s.length)return new t;const i=new Map,n=[];let o=0;for(const e of s)i.has(e)||(i.set(e,o),o++),n.push(i.get(e));if(0===n.length||0===i.size)return new t;const l=new t;for(const t in e.attributes){const r=e.attributes[t],a=r.itemSize,s=r.array,n=new(0,s.constructor)(i.size*a);for(const[e,t]of i)for(let r=0;r<a;r++)n[t*a+r]=s[e*a+r];const o=new S.BufferAttribute(n,a,r.normalized);l.setAttribute(t,o)}const c=new((n.length>0?Math.max(...n):0)>65535?Uint32Array:Uint16Array)(n.length);for(let e=0;e<n.length;e++)c[e]=n[e];return l.setIndex(new S.BufferAttribute(c,1)),l.groups=[{start:0,count:n.length,materialIndex:0}],l}async loadByAsset(e){this.fbxLoader;const t=this.getUri(e.fileKey);switch(e.fileFormat){case"glb":case"gltf":return this.glbLoader.loadAsync(t).then(e=>({scene:e.scene,animations:e.animations}));case"fbx":return this.fbxLoader.loadAsync(t).then(e=>({scene:e,animations:e.animations}));case"obj":if(null!=e.materialLib){const t=new h;t.materialOptions={normalizeRGB:!1};const r=await t.loadAsync(this.getUri(e.materialLib));this.objLoader.setMaterials(r)}return this.objLoader.loadAsync(t).then(e=>($(e),e)).then(e=>({scene:e,animations:e.animations}))}}disposeAll(){this.cache.clear(),this._retrievedMeshes.forEach(e=>F(e)),this._retrievedTextures.forEach(e=>e.dispose()),this._retrievedMeshes.length=0,this._retrievedTextures.length=0}}const G=new Map;function z(e){G.set(e,(G.get(e)??0)+1)}function $(e){if(e instanceof i)for(const t of L(e.material))t instanceof S.MeshPhongMaterial&&!t.color.isLinear&&(t.color.isLinear=!0);e.children?.forEach($)}export class AssetMeshInstance extends n{}export function createAuthoredCollisionShapes(e,t=1){const a=null!=t&&0!==t?1/t:1;return e.map(e=>{let t;switch(e.type){case"box":t=new g((new c).fromArray(e.size).multiplyScalar(a));break;case"sphere":t=new A(e.radius*a);break;case"capsule":t=new w(e.length*a,e.radius*a);break;case"cylinder":t=new M(e.radius*a,e.radius*a,e.height*a,16,new r)}return t.source=x.custom,t.offset.fromArray(e.position??[0,0,0]).multiplyScalar(a),t.rotation.fromArray(e.rotation??[0,0,0,"XYZ"]),t})}export function getElectronArg(e){const t=`--${e}=`,r=window.process?.argv.find(e=>e.startsWith(t));return r?.substring(t.length)}function Y(e){switch(e){case"clamp":return S.ClampToEdgeWrapping;case"repeat":return S.RepeatWrapping;case"mirror":return S.MirroredRepeatWrapping}return S.RepeatWrapping}function O(e,t){const r=e;return!0!==r.isCompressedTexture&&!0!==r.isCompressedArrayTexture&&(t.texture?.flipY??!0)}function N(e){return e.texture?.colorSpace??function(e){if("exr"===e.fileFormat||e.fileKey?.toLowerCase().endsWith(".exr"))return"linear";const t=`${e.name} ${e.fileKey??""}`.toLowerCase();if(X.some(e=>t.includes(e)))return"linear";return"srgb"}(e)}function V(e){return"linear"===e?S.LinearSRGBColorSpace:S.SRGBColorSpace}const X=["_normal","_nrm","_nor","_norm","_roughness","_rough","_metalness","_metallic","_metal","_ao","_ambient","_occlusion","_mask","_height","_disp","_displacement","_bump","_opacity"];new S.Matrix4;const q=[];const J=/_LOD(\d+)/;function Z(e){let t=e instanceof S.MeshPhysicalMaterial&&0===e.sheen&&0===e.anisotropy;if("MeshLambertMaterial"===e.type||"MeshPhongMaterial"===e.type||t){let t={};(e instanceof S.MeshLambertMaterial||e instanceof S.MeshPhongMaterial||e instanceof S.MeshPhysicalMaterial)&&(t.color=e.color,t.map=e.map,t.bumpMap=e.bumpMap,t.bumpScale=e.bumpScale,t.lightMap=e.lightMap,t.lightMapIntensity=e.lightMapIntensity,t.aoMap=e.aoMap,t.aoMapIntensity=e.aoMapIntensity,t.emissiveMap=e.emissiveMap,t.alphaMap=e.alphaMap,t.envMap=e.envMap,t.envMapRotation=e.envMapRotation,t.wireframe=e.wireframe,t.wireframeLinewidth=e.wireframeLinewidth,t.fog=e.fog,t.opacity=e.opacity,t.transparent=e.transparent,t.side=e.side,t.depthTest=e.depthTest,t.depthWrite=e.depthWrite,t.alphaTest=e.alphaTest,t.displacementMap=e.displacementMap,t.displacementScale=e.displacementScale,t.displacementBias=e.displacementBias);const r=new S.MeshStandardMaterial(t);return r.userData={...e.userData??{}},r.name=e.name,r}return e}/*
|
|
1
|
+
import{AudioLoader as e,BufferGeometry as t,Euler as r,Group as a,LoadingManager as s,Mesh as i,Object3D as n,Texture as o,TextureLoader as l,Vector3 as c}from"three";import{MTLLoader as h,OBJLoader as u,LUTCubeLoader as m}from"three-stdlib";import{cloneMesh as p}from"../utils/mesh.js";import{pathJoin as d}from"../utils/files.js";import{Subject as f,firstValueFrom as y}from"rxjs";import{BoxCollisionShape as g,CapsuleCollisionShape as w,CollisionShapeSource as x,CylinderCollisionShape as M,SphereCollisionShape as A}from"./collision/collision-shape.js";import{importCollisionShapes as b,isCollisionMesh as _}from"./collision/collision-shape-import.js";import*as L from"three";import{iterateMaterials as S}from"../utils/materials.js";import{applyMaterial as T,getConvertedFbxToGlbAssignedMaterialTextureFlipY as v}from"./materializer.js";import{BufferGeometryUtils as C,DRACOLoader as R,EXRLoader as P,FBXLoader as K,GLTFLoader as B,KTX2Loader as I,TGALoader as k,UltraHDRLoader as D}from"three/examples/jsm/Addons.js";import{disposeScene as F}from"../utils/three/cleanup.js";import{resolveAnimationRigBasisRotation as W,setAnimationClipRigId as j}from"../gameplay/animation/retarget.js";(()=>{const e=new Uint8Array([255,0,0,255]),t=new L.DataTexture(e,1,1,L.RGBAFormat);t.needsUpdate=!0})();const U=new R;U.setDecoderConfig({type:"js"}),U.setDecoderPath("/assets/draco/");const E=["glb","gltf","fbx","obj"];export class AssetResourceLoader{onError(e){console.error(e)}constructor(){this.cache=new Map,this.textureCache=new Map,this.loadingManager=new s,this.glbLoader=new B(this.loadingManager).setDRACOLoader(U),this.fbxLoader=new K(this.loadingManager),this.objLoader=new u(this.loadingManager),this.textureLoader=new l(this.loadingManager),this.tgaLoader=new k(this.loadingManager),this.exrLoader=new P(this.loadingManager),this.cubeLoader=new m(this.loadingManager),this.hdrLoader=new D(this.loadingManager),this.ktx2Loader=new I(this.loadingManager),this._textureLoader=new L.ImageBitmapLoader(this.loadingManager),this.audioLoader=new e(this.loadingManager),this.initialisedKtx2=!1,this._retrievedMeshes=[],this._retrievedTextures=[],this.makeReady=new f,this.ready=y(this.makeReady),this._texturePromises=new Map,this._arrayTexturesByFileKey=new Map,this._arrayTexturePromisesByFileKey=new Map,this._arrayTextureSettingsByFileKey=new Map,this._animationPromises=new Map,this._animationCache=new Map,this.asyncMeshResults=new Map,this.asyncAudioResults=new Map,this.collisionShapeCache=new Map,this.optimizedMeshes=new Set}initKtx2(e){this.initialisedKtx2=!0;null!=getElectronArg("windowId")||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?this.ktx2Loader.setTranscoderPath("/assets/basis/"):this.ktx2Loader.setTranscoderPath(new URL("../assets/basis/",import.meta.url).href),this.ktx2Loader.detectSupport(e),this.ktx2Loader.setWorkerLimit(6)}setDataDir(e){this.basePath=d(e,"asset-resources"),this.makeReady.next(!0)}getUri(e){const t=function(e){return G.get(e)}(e),r=getElectronArg("windowId");return null!=r||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?d(this.basePath,e)+(null!=r?`?windowId=${r}${null!=t?`&v=${t}`:""}`:""):new URL(d("..",this.basePath,e),import.meta.url).href}async getTexture(e){if(!e||!e.fileKey)return null;if("png"===e.fileFormat||e.fileFormat,this._texturePromises.has(e.id))return this._texturePromises.get(e.id);const t=this._getTexture(e).finally(()=>{this._texturePromises.delete(e.id)});return this._texturePromises.set(e.id,t),t}async _getTexture(e){if(null==e||null==e.fileKey)return null;if(await this.ready,this.textureCache.has(e.id)){const t=this.textureCache.get(e.id);if(null!=e.texture){const r=O(t,e);t.flipY!==r?(t.needsUpdate=!0,t.flipY=r):t.wrapS!==Y(e.texture?.wrapS)?(t.needsUpdate=!0,t.wrapS=Y(e.texture?.wrapS)):t.wrapT!==Y(e.texture?.wrapT)&&(t.wrapT=Y(e.texture?.wrapT),t.needsUpdate=!0)}const r=V(N(e));t.colorSpace!==r&&(t.colorSpace=r,t.needsUpdate=!0)}else try{await this._getTextureLoader(e.fileKey).loadAsync(this.getUri(e.fileKey)).then(t=>(t.texture3D?t=t.texture3D:(t.wrapS=Y(e.texture?.wrapS),t.wrapT=Y(e.texture?.wrapT),t.flipY=O(t,e),t.colorSpace=V(N(e))),this.textureCache.set(e.id,t),this._retrievedTextures.push(t),t))}catch(t){return console.warn("Failed to load texture "+e.name,t),null}const t=this.textureCache.get(e.id);return null!=t&&(t.userData.assetId=e.id),t}async getTextureArray(e){const t=e.texture?.textureArrayFileKey,r=e.texture?.textureArrayLayer;if(!t||null==r)return{texture:null,layerIndex:null};let a=this._arrayTexturesByFileKey.get(t);if(null==a){let e=this._arrayTexturePromisesByFileKey.get(t);null==e&&(e=this.loadTextureArray(t).finally(()=>{this._arrayTexturePromisesByFileKey.delete(t)}),this._arrayTexturePromisesByFileKey.set(t,e)),a=await e}return this.applyTextureArraySettings(t,a,e),{texture:a,layerIndex:r}}async loadTextureArray(e){const t=this._getTextureLoader(e);let r=await t.loadAsync(this.getUri(e));return r instanceof o||(r=r.texture3D),this._arrayTexturesByFileKey.set(e,r),this._retrievedTextures.push(r),r}applyTextureArraySettings(e,t,r){const a=function(e){return{wrapS:Y(e.texture?.wrapS),wrapT:Y(e.texture?.wrapT)}}(r),s=this._arrayTextureSettingsByFileKey.get(e);if(null!=s&&(n=a,(i=s).wrapS!==n.wrapS||i.wrapT!==n.wrapT))return void console.warn(`Texture array ${e} is used with incompatible texture settings. Texture arrays share wrapping; rebuild arrays so incompatible textures are grouped separately.`);var i,n;null==s&&this._arrayTextureSettingsByFileKey.set(e,a);let o=!1;t.wrapS!==a.wrapS&&(t.wrapS=a.wrapS,o=!0),t.wrapT!==a.wrapT&&(t.wrapT=a.wrapT,o=!0),!1!==t.flipY&&(t.flipY=!1,o=!0),o&&(t.needsUpdate=!0)}_getTextureLoader(e){return e?.toLowerCase().endsWith(".tga")?this.tgaLoader:e?.toLowerCase().endsWith(".ktx2")?this.ktx2Loader:e?.toLowerCase().endsWith(".exr")?this.exrLoader:e?.toLowerCase().endsWith(".cube")?this.cubeLoader:this.textureLoader}clearCache(e){this.clearCacheByAsset(e)}clearCacheByAsset(e){null!=e&&(this.clearCacheById(e.id),null!=e.fileKey&&(Array.from(this.cache.keys()).forEach(t=>{t.startsWith(e.fileKey)&&this.cache.delete(t)}),Array.from(this.asyncMeshResults.keys()).forEach(t=>{t.startsWith(e.fileKey)&&this.asyncMeshResults.delete(t)}),Array.from(this._animationCache.keys()).forEach(t=>{t.startsWith(e.fileKey+"|")&&this._animationCache.delete(t)}),Array.from(this._animationPromises.keys()).forEach(t=>{t.startsWith(e.fileKey+"|")&&this._animationPromises.delete(t)}),z(e.fileKey)),null!=e.materialLib&&z(e.materialLib))}clearCacheById(e){const t=Array.from(this.cache.values()).find(t=>t.scene.userData.assetId===e);t&&Array.from(this.cache.keys()).forEach(e=>{this.cache.get(e)===t&&this.cache.delete(e)}),this.textureCache.delete(e),this._texturePromises.delete(e),Array.from(this.collisionShapeCache.keys()).forEach(t=>{t.startsWith(e+"|")&&this.collisionShapeCache.delete(t)})}async getMesh(e,t){if(await this.ready,null==e)return console.error("No asset was provided"),{scene:new a,animations:[]};if(!E.includes(e.fileFormat?.toLowerCase()))return console.error("Unsupported mesh file format "+e.fileFormat,e),{scene:new a,animations:[]};const r=e.fileKey+(!0===t?.mergeGeomtries?"1":"0");if(!this.cache.has(r))try{this.asyncMeshResults.has(r)||this.asyncMeshResults.set(r,this.loadMesh(e).finally(()=>this.asyncMeshResults.delete(r))),this.cache.set(r,await this.asyncMeshResults.get(r))}catch(e){return this.onError(e),{scene:new a,animations:[]}}const s=this.cache.get(r).scene,n=this.computeCollisionShapes(e,s);!0===t?.mergeGeomtries&&this.optimizeDrawGroups(s);const o=p(s),l=this.cache.get(r).animations;o.traverse(e=>{e instanceof i&&e.material instanceof Array&&(e.material=e.material.slice())});const c=new AssetMeshInstance;c.add(o),c.collisionShapes=n,c.animations=l,c.userData.assetId=e.id;const h=e.mesh?.animationRigId??e.anim?.rigId;if(c.userData.animationRigId=h,o.userData.animationRigId=h,null!=h&&null!=this.animationRigProvider){const e=await this.animationRigProvider(h);c.userData.animationRig=e,o.userData.animationRig=e,null!=e&&!1!==t?.applyRigBasis&&c.quaternion.copy(W(e))}const u=e.receiveShadow??!1,m=e.castShadow??!1;if(o.traverse(e=>{e.castShadow=m,e.receiveShadow=u}),!0===t?.rescale&&"number"==typeof e.mesh?.rescale&&c.scale.setScalar(e.mesh?.rescale),!0===t?.applyMaterials){const r=t?.materialResolver??this.materialProvider;if(null!=r)for(const t of e.materialAssignments??[])await T(c,t,r,void 0,{textureFlipY:v(e)});else console.warn(`applyMaterials was set to true for ${e.name} but no material resolver was provided.`)}return{scene:c,animations:l}}async getAudio(e){await this.ready;const t=e.fileKey;if(this.asyncAudioResults.has(t))return await this.asyncAudioResults.get(t);const r=this.audioLoader.loadAsync(this.getUri(e.fileKey)).finally(()=>{setTimeout(()=>{this.asyncAudioResults.delete(t)},1e3)});return this.asyncAudioResults.set(t,r),r}async getAnimationClip(e){if(null==e||null==e.fileKey||null==e.anim?.clip)return console.warn("Asset or animation clip name is not defined",e),null;const t=e.anim.clip,r=e.fileKey+"|"+t;if(this._animationCache.has(r))return this._animationCache.get(r);if(this._animationPromises.has(r))return this._animationPromises.get(r);const a=(async()=>{try{const a=await this.getMesh(e),s=a.animations.find(e=>e.name===t);return null!=s&&(j(s,e.anim?.rigId),this._animationCache.set(r,s)),s}catch(e){return this.onError(e),null}finally{setTimeout(()=>this._animationPromises.delete(r),1e3)}})();return this._animationPromises.set(r,a),a}computeCollisionShapes(e,t){if(!0!==e.collisionDetection)return[];const r=e.id+"|"+(e.mesh?.collisions?.shapeType??"")+"|"+(e.mesh?.rescale??1)+"|"+JSON.stringify(e.mesh?.colliders??[]);if(!this.collisionShapeCache.has(r)){const a=e.mesh?.colliders??[],s=a.length>0?createAuthoredCollisionShapes(a,e.mesh?.rescale):b(t,e);this.collisionShapeCache.set(r,s)}return this.collisionShapeCache.get(r)}async loadMesh(e){return await this.ready,await this.loadByAsset(e).then(r=>(r.scene.traverse(e=>{e instanceof i&&e.material&&function(e){let t=e.material;if(null==t)return;Array.isArray(t)?e.material=t.map(Z):e.material=Z(t)}(e),_(e)?e.visible=!1:e instanceof i&&e.geometry instanceof t&&(e.geometry.hasAttribute("normal")||e.geometry.computeVertexNormals())}),this._retrievedMeshes.push(r.scene),r.scene=function(e,t){let r=!1;if(t.traverseVisible(e=>{J.test(e.name)&&(r=!0)}),!r)return t;const a=[],s=[t];for(;s.length>0;){const e=s.shift(),t=e.name.match(J);if(null!=t){const r=parseInt(t[1]);if(0!==r){console.warn(`Skipping LOD level ${r} for now as LOD is not fully supported`),a.push(e);continue}}s.push(...e.children)}for(const e of a)e.removeFromParent();return t}(0,r.scene),function(e){const t=q;q.length=0,e.traverse(e=>{(e instanceof L.Camera||e instanceof L.Light)&&t.push(e)}),t.forEach(e=>e.removeFromParent())}(r.scene),r.scene.userData.assetId=e.id,r))}optimizeDrawGroups(e){if(this.optimizedMeshes.has(e.uuid))return;this.optimizedMeshes.add(e.uuid),e.updateWorldMatrix(!0,!0);const r=[];e.traverse(e=>{e instanceof i&&!(e instanceof L.SkinnedMesh)&&e.geometry instanceof t&&Array.isArray(e.material)&&!_(e)&&r.push({mesh:e,geometry:e.geometry,materialArray:e.material,parent:e.parent})});for(const{mesh:t,geometry:a,materialArray:s,parent:n}of r){t.removeFromParent();for(let r=0;r<s.length;r++){const o=s[r],l=a.groups.filter(e=>e.materialIndex===r);if(0===l.length)continue;const c=this.extractGeometryGroups(a,l);c.groups.length>1&&C.mergeGroups(c);const h=new i(c,o);h.copy(t,!1),h.geometry=c,h.material=o,n?n.add(h):e.add(h)}a.dispose()}let a=!0,s=0,n=0;if(e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!_(e)){s++;const t=Object.keys(e.geometry.attributes).length;t!==n&&0!==n&&(a=!1),n=t}else(e instanceof L.SkinnedMesh||e instanceof L.Bone)&&(a=!1)}),s>1&&a){const r=new Map;e.traverse(a=>{if(a instanceof i&&a.geometry instanceof t&&!_(a)){if(Array.isArray(a.material))return;a.updateWorldMatrix(!0,!0);const t=a.material?.uuid||"default";r.has(t)||r.set(t,{material:a.material,geometries:[],objects:[]});const s=r.get(t),i=e.matrixWorld.clone().invert().multiply(a.matrixWorld);s.geometries.push(a.geometry.clone().applyMatrix4(i)),s.objects.push(a)}});for(const e of r.values())for(const t of e.objects)t.removeFromParent();for(const t of r.values()){let r;r=1===t.geometries.length?t.geometries[0]:C.mergeGeometries(t.geometries,!0),r.groups.length>1&&C.mergeGroups(r),e.add(new i(r,t.material))}}e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!_(e)){const t=e.geometry;!Array.isArray(e.material)&&t.groups.length>1&&C.mergeGroups(t)}})}extractGeometryGroups(e,r){const a=e.index;if(!a){const a=new t;let s=0;for(const e of r)s+=e.count;if(0===s)return a;for(const t in e.attributes){const i=e.attributes[t],n=i.itemSize,o=i.array,l=new(0,o.constructor)(s*n);let c=0;for(const e of r){const t=e.start*n,r=e.count*n;for(let e=0;e<r;e++)l[c+e]=o[t+e];c+=r}const h=new L.BufferAttribute(l,n,i.normalized);a.setAttribute(t,h)}return a.groups=[{start:0,count:s,materialIndex:0}],a}const s=[];for(const e of r)for(let t=0;t<e.count;t++){const r=a.getX(e.start+t);s.push(r)}if(0===s.length)return new t;const i=new Map,n=[];let o=0;for(const e of s)i.has(e)||(i.set(e,o),o++),n.push(i.get(e));if(0===n.length||0===i.size)return new t;const l=new t;for(const t in e.attributes){const r=e.attributes[t],a=r.itemSize,s=r.array,n=new(0,s.constructor)(i.size*a);for(const[e,t]of i)for(let r=0;r<a;r++)n[t*a+r]=s[e*a+r];const o=new L.BufferAttribute(n,a,r.normalized);l.setAttribute(t,o)}const c=new((n.length>0?Math.max(...n):0)>65535?Uint32Array:Uint16Array)(n.length);for(let e=0;e<n.length;e++)c[e]=n[e];return l.setIndex(new L.BufferAttribute(c,1)),l.groups=[{start:0,count:n.length,materialIndex:0}],l}async loadByAsset(e){this.fbxLoader;const t=this.getUri(e.fileKey);switch(e.fileFormat){case"glb":case"gltf":return this.glbLoader.loadAsync(t).then(e=>({scene:e.scene,animations:e.animations}));case"fbx":return this.fbxLoader.loadAsync(t).then(e=>({scene:e,animations:e.animations}));case"obj":if(null!=e.materialLib){const t=new h;t.materialOptions={normalizeRGB:!1};const r=await t.loadAsync(this.getUri(e.materialLib));this.objLoader.setMaterials(r)}return this.objLoader.loadAsync(t).then(e=>($(e),e)).then(e=>({scene:e,animations:e.animations}))}}disposeAll(){this.cache.clear(),this._retrievedMeshes.forEach(e=>F(e)),this._retrievedTextures.forEach(e=>e.dispose()),this._retrievedMeshes.length=0,this._retrievedTextures.length=0}}const G=new Map;function z(e){G.set(e,(G.get(e)??0)+1)}function $(e){if(e instanceof i)for(const t of S(e.material))t instanceof L.MeshPhongMaterial&&!t.color.isLinear&&(t.color.isLinear=!0);e.children?.forEach($)}export class AssetMeshInstance extends n{}export function createAuthoredCollisionShapes(e,t=1){const a=null!=t&&0!==t?1/t:1;return e.map(e=>{let t;switch(e.type){case"box":t=new g((new c).fromArray(e.size).multiplyScalar(a));break;case"sphere":t=new A(e.radius*a);break;case"capsule":t=new w(e.length*a,e.radius*a);break;case"cylinder":t=new M(e.radius*a,e.radius*a,e.height*a,16,new r)}return t.source=x.custom,t.offset.fromArray(e.position??[0,0,0]).multiplyScalar(a),t.rotation.fromArray(e.rotation??[0,0,0,"XYZ"]),t})}export function getElectronArg(e){const t=`--${e}=`,r=window.process?.argv.find(e=>e.startsWith(t));return r?.substring(t.length)}function Y(e){switch(e){case"clamp":return L.ClampToEdgeWrapping;case"repeat":return L.RepeatWrapping;case"mirror":return L.MirroredRepeatWrapping}return L.RepeatWrapping}function O(e,t){const r=e;return!0!==r.isCompressedTexture&&!0!==r.isCompressedArrayTexture&&(t.texture?.flipY??!0)}function N(e){return e.texture?.colorSpace??function(e){if("exr"===e.fileFormat||e.fileKey?.toLowerCase().endsWith(".exr"))return"linear";const t=`${e.name} ${e.fileKey??""}`.toLowerCase();if(X.some(e=>t.includes(e)))return"linear";return"srgb"}(e)}function V(e){return"linear"===e?L.LinearSRGBColorSpace:L.SRGBColorSpace}const X=["_normal","_nrm","_nor","_norm","_roughness","_rough","_metalness","_metallic","_metal","_ao","_ambient","_occlusion","_mask","_height","_disp","_displacement","_bump","_opacity"];new L.Matrix4;const q=[];const J=/_LOD(\d+)/;function Z(e){let t=e instanceof L.MeshPhysicalMaterial&&0===e.sheen&&0===e.anisotropy;if("MeshLambertMaterial"===e.type||"MeshPhongMaterial"===e.type||t){let t={};(e instanceof L.MeshLambertMaterial||e instanceof L.MeshPhongMaterial||e instanceof L.MeshPhysicalMaterial)&&(t.color=e.color,t.map=e.map,t.bumpMap=e.bumpMap,t.bumpScale=e.bumpScale,t.lightMap=e.lightMap,t.lightMapIntensity=e.lightMapIntensity,t.aoMap=e.aoMap,t.aoMapIntensity=e.aoMapIntensity,t.emissiveMap=e.emissiveMap,t.alphaMap=e.alphaMap,t.envMap=e.envMap,t.envMapRotation=e.envMapRotation,t.wireframe=e.wireframe,t.wireframeLinewidth=e.wireframeLinewidth,t.fog=e.fog,t.opacity=e.opacity,t.transparent=e.transparent,t.side=e.side,t.depthTest=e.depthTest,t.depthWrite=e.depthWrite,t.alphaTest=e.alphaTest,t.displacementMap=e.displacementMap,t.displacementScale=e.displacementScale,t.displacementBias=e.displacementBias);const r=new L.MeshStandardMaterial(t);return r.userData={...e.userData??{}},r.name=e.name,r}return e}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SceneObjectPhysicsSettings } from "../../scene/materializer.js";
|
|
1
|
+
import type { SceneObjectPhysicsSettings } from "../../scene/materializer.js";
|
|
2
2
|
import { BufferGeometry, Euler, Material, Mesh, Vector3 } from "three";
|
|
3
3
|
export declare enum CollisionShapeSource {
|
|
4
4
|
/**
|
|
@@ -378,6 +378,7 @@ export declare class SceneMaterializer {
|
|
|
378
378
|
get prefabEventGraphInstances(): readonly MaterializedPrefabEventGraph[];
|
|
379
379
|
private editorActorParamSnapshot;
|
|
380
380
|
private editorAttachedActorComponents;
|
|
381
|
+
private readonly livePrefabInstances;
|
|
381
382
|
resolveSceneActor(sceneObjectId: SceneObjectId): BaseActor | undefined;
|
|
382
383
|
private originalFog;
|
|
383
384
|
private assets;
|
|
@@ -466,8 +467,13 @@ export declare class SceneMaterializer {
|
|
|
466
467
|
private update;
|
|
467
468
|
materializeAndInitActor(source: SceneObject, parent?: THREE.Object3D<THREE.Object3DEventMap, Event>): Promise<THREE.Object3D<THREE.Object3DEventMap, Event>>;
|
|
468
469
|
private tryApplyLiveActorParameterUpdate;
|
|
470
|
+
private tryApplyLiveActorSettingsUpdate;
|
|
471
|
+
private applyLiveActorSettingsUpdate;
|
|
472
|
+
private applyLivePrefabParameterUpdate;
|
|
473
|
+
private applyLiveNestedPrefabOverrideUpdates;
|
|
474
|
+
private rememberLivePrefabActorSettings;
|
|
469
475
|
private tryApplyLiveParameterUpdate;
|
|
470
|
-
private
|
|
476
|
+
private applyLiveInnerParameterUpdates;
|
|
471
477
|
private resolveActorComponent;
|
|
472
478
|
private findParent;
|
|
473
479
|
private fixFogColor;
|
|
@@ -544,6 +550,7 @@ export declare class SceneMaterializer {
|
|
|
544
550
|
actors: BaseActor[];
|
|
545
551
|
actorsById: Map<string, BaseActor>;
|
|
546
552
|
mainActor: BaseActor | null;
|
|
553
|
+
instanceId: string;
|
|
547
554
|
}>;
|
|
548
555
|
private createParticleSystem;
|
|
549
556
|
private createLight;
|