@hology/core 0.0.227 → 0.0.229
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/effects/vfx/trail-renderer.js +1 -1
- package/dist/effects/vfx/vfx-materializer.js +1 -1
- package/dist/effects/vfx/vfx-renderers.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-movement.js +1 -1
- package/dist/gameplay/initiate.d.ts +5 -1
- package/dist/gameplay/initiate.js +1 -1
- package/dist/gameplay/services/physics/physics-system.d.ts +1 -0
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/gameplay/services/pointer-events.d.ts +2 -0
- package/dist/rendering/environment.d.ts +8 -0
- package/dist/rendering/environment.js +4 -0
- package/dist/rendering/node-material-webgpu-resolver.d.ts +80 -0
- package/dist/rendering/node-material-webgpu-resolver.js +4 -0
- package/dist/rendering/post-process-effect.d.ts +4 -2
- package/dist/rendering/post-process-effect.js +1 -1
- package/dist/rendering/webgpu-experimental-backend.d.ts +109 -0
- package/dist/rendering/webgpu-experimental-backend.js +4 -0
- package/dist/rendering.d.ts +59 -1
- package/dist/rendering.js +1 -1
- package/dist/scene/materializer.d.ts +47 -2
- package/dist/scene/materializer.js +1 -1
- package/dist/scene/objects/shapes.d.ts +1 -2
- package/dist/scene/objects/shapes.js +1 -1
- package/dist/scene/sky.js +1 -1
- package/dist/shader/builtin/lambert-shader.d.ts +7 -6
- package/dist/shader/builtin/lambert-shader.js +1 -1
- package/dist/shader/builtin/landscape-composite-shader.js +1 -1
- package/dist/shader/graph/compiler.d.ts +3 -0
- package/dist/shader/graph/compiler.js +1 -1
- package/dist/shader/sprite-shader.d.ts +5 -2
- package/dist/shader/sprite-shader.js +1 -1
- package/dist/shader-nodes/depth.d.ts +17 -6
- package/dist/shader-nodes/depth.js +1 -1
- package/dist/shader-nodes/dither.js +1 -1
- package/dist/shader-nodes/glsl-node.js +1 -1
- package/dist/shader-nodes/index.d.ts +2 -1
- package/dist/shader-nodes/index.js +1 -1
- package/dist/shader-nodes/particle.d.ts +10 -4
- package/dist/shader-nodes/particle.js +1 -1
- package/dist/shader-nodes/pom.d.ts +3 -2
- package/dist/shader-nodes/pom.js +1 -1
- package/dist/shader-nodes/wgsl-node.d.ts +17 -0
- package/dist/shader-nodes/wgsl-node.js +4 -0
- package/dist/test/node-material-webgpu-resolver.test.d.ts +2 -0
- package/dist/test/node-material-webgpu-resolver.test.js +4 -0
- package/dist/test/post-process-effect.test.js +1 -1
- package/dist/test/shader-graph.test.js +1 -1
- package/dist/test/webgpu-experimental-backend.test.d.ts +2 -0
- package/dist/test/webgpu-experimental-backend.test.js +4 -0
- package/package.json +11 -4
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{timeUniforms as t}from"../../shader-nodes/index.js";import*as e from"three";import{NodeShaderMaterial as i,uniformBool as r,uniformFloat as o,uniformVec2 as s,mix as a,uniformVec4 as n,attributeFloat as h,attributeVec3 as l,select as d,float as u,textureSampler2d as c,attributes as m,uniforms as y,rgba as g,vec4 as p,varying as x,vec2 as f,normalize as v,vec3 as b,cross as T,max as C,length as V}from"three-shader-graph";o("trailLength");const P=o("verticesPerNode"),w=o("minID"),F=o("maxID"),I=(o("dragTexture"),o("maxTrailLength")),D=s("textureTileFactor",new e.Vector2(1,1)),N=n("headColor",new e.Vector4),U=n("tailColor",new e.Vector4),A=r("taper",!1),M=(o("scale",1),h("nodeID")),z=h("nodeVertexID"),B=l("nodeCenter"),H=F.subtract(M).divide(F.subtract(w)),S=d(A,H,u(0)),j=x(u(1).subtract(H).multiplyVec4(N).add(H.multiplyVec4(U))),q=v(y.cameraPosition.subtract(B)),L=v(l("nodeTangent")),G=o("width",1),O=v(T(d(V(L).gt(u(.1)),L,b(1,0,0)),q)).multiplyScalar(z.subtract(u(.5))).multiplyScalar(G),Q=p(u(1).subtract(S).multiplyVec3(O).add(C(S,u(1)).multiplyVec3(B)),1),R=p(u(1).subtract(S).multiplyVec3(m.position).add(S.multiplyVec3(B)),1),W=y.projectionMatrix.multiply(y.viewMatrix).multiplyVec(Q),_=y.projectionMatrix.multiply(y.viewMatrix).multiplyVec(R);export const trailUV=x(f(H.multiply(D.x),z.divide(P).multiply(D.y).multiply(2)));export const trailDragUV=x(f(M.divide(I).multiply(D.x),z.divide(P).multiply(D.y).multiply(2)));const k={position:new e.Vector3,direction:new e.Vector3,offset:new e.Vector3,worldOrientation:new e.Vector3,matrix4:new e.Matrix4,quat1:new e.Quaternion,quat2:new e.Quaternion,quaternion:new e.Quaternion,quaternion2:new e.Quaternion,boundingBox:new e.Box3,localHeadGeometry:Array.from({length:128},()=>new e.Vector3)};export class Trail extends e.Object3D{constructor(t,i){super(),this.historyCount=0,this.historyHeadIndex=-1,this.history=[],this.renderNodeCount=0,this.subdivisions=4,this.currentNodeID=0,this.advance=function(){const t=new e.Matrix4;return function(){this.targetObject.updateMatrixWorld(),t.copy(this.targetObject.matrixWorld),this.advanceWithTransform(t),this.updateUniforms()}}(),this.connectNodes=(()=>{const t={attribute:null,offset:0,count:-1};return(e,i)=>{const r=this.geometry.getIndex();for(let t=0;t<this.localHeadGeometry.length-1;t++){const o=this.VerticesPerNode*e+t,s=this.VerticesPerNode*i+t,a=(e*this.FacesPerNode+t*Trail.FacesPerQuad)*Trail.IndicesPerFace;r.array[a]=o,r.array[a+1]=s,r.array[a+2]=o+1,r.array[a+3]=s,r.array[a+4]=s+1,r.array[a+5]=o+1}return r.needsUpdate=!0,r.clearUpdateRanges(),t.attribute=r,t.offset=e*this.FacesPerNode*Trail.IndicesPerFace,t.count=this.FacesPerNode*Trail.IndicesPerFace,t}})(),this.disconnectNodes=(()=>{const t={attribute:null,offset:0,count:-1};return e=>{const i=this.geometry.getIndex();for(let t=0;t<this.localHeadGeometry.length-1;t++){const r=(e*this.FacesPerNode+t*Trail.FacesPerQuad)*Trail.IndicesPerFace;i.array[r]=0,i.array[r+1]=0,i.array[r+2]=0,i.array[r+3]=0,i.array[r+4]=0,i.array[r+5]=0}return i.needsUpdate=!0,i.clearUpdateRanges(),t.attribute=i,t.offset=e*this.FacesPerNode*Trail.IndicesPerFace,t.count=this.FacesPerNode*Trail.IndicesPerFace,t}})(),this.active=!1,this.orientToMovement=!1,i&&(this.orientToMovement=!0),this.scene=t,this.geometry=null,this.mesh=null,this.historyCount=0,this.historyHeadIndex=-1,this.history=[],this.renderNodeCount=0,this.currentNodeID=0,this.advanceFrequency=60,this.advancePeriod=1/this.advanceFrequency,this.lastAdvanceTime=0,this.paused=!1,this.pauseAdvanceUpdateTimeDiff=0}setAdvanceFrequency(t){this.advanceFrequency=t,this.advancePeriod=1/this.advanceFrequency}initialize(t,i,r,o,s,a,n=!1){this.deactivate(),this.destroyMesh(),this.length=i>0?i+1:0,this.dragTexture=r?1:0,this.targetObject=a,this.billboard=n,this.initializeLocalHeadGeometry(o,s),null!=t.uniforms.width&&(t.uniforms.width.value=o),this.renderNodeCount=this.length*this.subdivisions,this.historyCount=0,this.historyHeadIndex=-1,this.history=[];for(let t=0;t<this.length;t++)this.history.push({position:new e.Vector3,tangent:new e.Vector3(1,0,0),transformMatrix:new e.Matrix4,id:-1});this.setAllNodesToCurrentTargetPosition(),this.material=t,this.initializeGeometry(),this.initializeMesh(),this.material.uniforms.dragTexture&&(this.material.uniforms.trailLength.value=0),this.material.uniforms.minID.value=0,this.material.uniforms.maxID.value=0,this.material.uniforms.dragTexture&&(this.material.uniforms.dragTexture.value=this.dragTexture),this.material.uniforms.maxTrailLength&&(this.material.uniforms.maxTrailLength.value=this.length),this.material.uniforms.verticesPerNode&&(this.material.uniforms.verticesPerNode.value=this.VerticesPerNode),this.material.uniforms.textureTileFactor&&(this.material.uniforms.textureTileFactor.value=new e.Vector2(1,1)),this.material.uniforms.scale&&(this.material.uniforms.scale.value=1),this.reset()}initializeLocalHeadGeometry(t,i){if(this.localHeadGeometry=[],i){this.VerticesPerNode=0;for(let t=0;t<i.length&&t<Trail.MaxHeadVertices;t++){const r=i[t];if(r&&r instanceof e.Vector3){const t=new e.Vector3;t.copy(r),this.localHeadGeometry.push(t),this.VerticesPerNode++}}}else{const i=(t||1)/2;this.localHeadGeometry.push(new e.Vector3(-i,0,0)),this.localHeadGeometry.push(new e.Vector3(i,0,0)),this.VerticesPerNode=2}this.FacesPerNode=2*(this.VerticesPerNode-1),this.FaceIndicesPerNode=3*this.FacesPerNode}initializeGeometry(){this.vertexCount=this.renderNodeCount*this.VerticesPerNode,this.faceCount=this.renderNodeCount*this.FacesPerNode;const t=new e.BufferGeometry,i=new Float32Array(this.vertexCount),r=new Float32Array(this.vertexCount*this.VerticesPerNode),o=new Float32Array(this.vertexCount*Trail.PositionComponentCount),s=new Float32Array(this.vertexCount*Trail.PositionComponentCount),a=new Float32Array(this.vertexCount*Trail.UVComponentCount),n=new Uint32Array(this.faceCount*Trail.IndicesPerFace),h=new Float32Array(3*this.vertexCount),l=new e.BufferAttribute(h,3);l.setUsage(e.DynamicDrawUsage),t.setAttribute("nodeTangent",l);const d=new e.BufferAttribute(i,1);d.setUsage(e.DynamicDrawUsage),t.setAttribute("nodeID",d);const u=new e.BufferAttribute(r,1);u.setUsage(e.DynamicDrawUsage),t.setAttribute("nodeVertexID",u);const c=new e.BufferAttribute(s,Trail.PositionComponentCount);c.setUsage(e.DynamicDrawUsage),t.setAttribute("nodeCenter",c);const m=new e.BufferAttribute(o,Trail.PositionComponentCount);m.setUsage(e.DynamicDrawUsage),t.setAttribute("position",m);const y=new e.BufferAttribute(a,Trail.UVComponentCount);y.setUsage(e.DynamicDrawUsage),t.setAttribute("uv",y);const g=new e.BufferAttribute(n,1);g.setUsage(e.DynamicDrawUsage),t.setIndex(g),this.geometry=t}zeroVertices(){const t=this.geometry.getAttribute("position");for(let e=0;e<this.vertexCount;e++){const i=3*e;t.array[i]=0,t.array[i+1]=0,t.array[i+2]=0}t.needsUpdate=!0}zeroIndices(){if(null==this.geometry)throw"Geometry not initialized";const t=this.geometry.getIndex();for(let e=0;e<this.faceCount;e++){const i=3*e;t.array[i]=0,t.array[i+1]=0,t.array[i+2]=0}t.needsUpdate=!0,t.clearUpdateRanges()}formInitialFaces(){this.zeroIndices();const t=this.geometry.getIndex();for(let t=0;t<this.renderNodeCount-1;t++)this.connectNodes(t,t+1);t.needsUpdate=!0,t.clearUpdateRanges()}initializeMesh(){if(null==this.geometry)throw"Geometry not initialized";this.mesh=new e.Mesh(this.geometry,this.material),this.mesh.matrixAutoUpdate=!1,this.mesh.visible=!1}destroyMesh(){this.mesh&&(this.scene.remove(this.mesh),this.mesh=null)}reset(){this.historyCount=0,this.historyHeadIndex=-1,this.currentNodeID=0,this.formInitialFaces(),this.zeroVertices(),this.geometry.setDrawRange(0,0),this.setAllNodesToCurrentTargetPosition(),this.mesh&&(this.mesh.visible=!0)}setAllNodesToCurrentTargetPosition(){if(!this.targetObject)return;this.targetObject.updateMatrixWorld();const t=this.targetObject.matrixWorld,i=(new e.Vector3).setFromMatrixPosition(t),r=new e.Vector3(1,0,0).applyMatrix4(t).normalize();for(let e=0;e<this.length;e++)this.history[e].position.copy(i),this.history[e].tangent.copy(r),this.history[e].transformMatrix.copy(t),this.history[e].id=-1;this.historyCount=0,this.historyHeadIndex=-1}updateUniforms(){if(0===this.historyCount)return;const t=this.getControlPoint(0).id,e=this.getControlPoint(this.historyCount-1).id;this.material.uniforms.minID.value=t,this.material.uniforms.maxID.value=e,this.material.uniforms.trailLength&&(this.material.uniforms.trailLength.value=this.historyCount),this.material.uniforms.maxTrailLength&&(this.material.uniforms.maxTrailLength.value=this.length),this.material.uniforms.verticesPerNode&&(this.material.uniforms.verticesPerNode.value=this.VerticesPerNode)}advanceWithTransform(t){this.historyCount<this.length&&this.historyCount++,this.historyHeadIndex=(this.historyHeadIndex+1)%this.length;const e=this.history[this.historyHeadIndex];if(e.id=this.currentNodeID++,k.position.set(0,0,0).applyMatrix4(t),e.position.copy(k.position),e.transformMatrix.copy(t),this.billboard){const i=this.getControlPoint(this.historyCount-2);i&&!i.position.equals(k.position)?e.tangent.copy(k.position).sub(i.position).normalize():e.tangent.set(1,0,0).applyMatrix4(t).normalize()}this.rebuildGeometry()}updateHead(){if(0===this.historyCount)return;this.targetObject.updateMatrixWorld();const t=this.targetObject.matrixWorld,e=this.history[this.historyHeadIndex];if(k.position.set(0,0,0).applyMatrix4(t),e.position.copy(k.position),e.transformMatrix.copy(t),this.billboard){const i=this.getControlPoint(this.historyCount-2);i&&!i.position.equals(k.position)?e.tangent.copy(k.position).sub(i.position).normalize():e.tangent.set(1,0,0).applyMatrix4(t).normalize()}this.rebuildGeometry()}getControlPoint(t){if(t<0)return this.history[(this.historyHeadIndex-this.historyCount+1+this.length)%this.length];t>=this.historyCount&&(t=this.historyCount-1);const e=(this.historyHeadIndex-this.historyCount+1+this.length)%this.length;return this.history[(e+t)%this.length]}rebuildGeometry(){if(this.historyCount<2)return this.geometry.setDrawRange(0,0),void(this.mesh&&(this.mesh.visible=!1));const t=this.geometry.getAttribute("position"),i=this.geometry.getAttribute("nodeID"),r=this.geometry.getAttribute("nodeVertexID"),o=this.geometry.getAttribute("nodeCenter"),s=this.geometry.getAttribute("nodeTangent"),a=this.historyCount-1,n=a*this.subdivisions+1;let h=0;k.boundingBox.makeEmpty();for(let e=0;e<a;e++){const n=this.getControlPoint(e-1),l=this.getControlPoint(e),d=this.getControlPoint(e+1),u=this.getControlPoint(e+2),c=e===a-1?this.subdivisions+1:this.subdivisions;for(let e=0;e<c;e++){const a=e/this.subdivisions,c=n.position,m=l.position,y=d.position,g=u.position,p=a*a,x=p*a,f=.5*(y.x-c.x),v=.5*(g.x-m.x),b=(2*(m.x-y.x)+f+v)*x+(-3*(m.x-y.x)-2*f-v)*p+f*a+m.x,T=.5*(y.y-c.y),C=.5*(g.y-m.y),V=(2*(m.y-y.y)+T+C)*x+(-3*(m.y-y.y)-2*T-C)*p+T*a+m.y,P=.5*(y.z-c.z),w=.5*(g.z-m.z),F=(2*(m.z-y.z)+P+w)*x+(-3*(m.z-y.z)-2*P-w)*p+P*a+m.z;k.position.set(b,V,F);const I=l.id+(d.id-l.id)*a,D=k.direction.copy(l.tangent).lerp(d.tangent,a).normalize();k.matrix4.copy(l.transformMatrix),k.quat1.setFromRotationMatrix(l.transformMatrix),k.quat2.setFromRotationMatrix(d.transformMatrix),k.quaternion.copy(k.quat1).slerp(k.quat2,a),k.matrix4.makeRotationFromQuaternion(k.quaternion),k.matrix4.setPosition(k.position);for(let e=0;e<this.VerticesPerNode;e++){const n=h*this.VerticesPerNode+e;i.array[n]=I,r.array[n]=e,o.array[3*n]=k.position.x,o.array[3*n+1]=k.position.y,o.array[3*n+2]=k.position.z;const l=k.localHeadGeometry[e].copy(this.localHeadGeometry[e]);if(this.billboard)s.array[3*n]=D.x,s.array[3*n+1]=D.y,s.array[3*n+2]=D.z,k.boundingBox.expandByPoint(k.position);else{if(l.applyMatrix4(k.matrix4),this.orientToMovement){k.worldOrientation.set(0,0,-1).applyQuaternion(k.quaternion);const t=(3*p-2*a)*(m.x-y.x)+(x-p)*v+(3*p-4*a+1)*f,e=(3*p-2*a)*(m.y-y.y)+(x-p)*C+(3*p-4*a+1)*T,i=(3*p-2*a)*(m.z-y.z)+(x-p)*w+(3*p-4*a+1)*P;k.direction.set(t,e,i).normalize(),k.direction.lengthSq()>1e-4&&(k.quaternion2.setFromUnitVectors(k.worldOrientation,k.direction),l.sub(k.position).applyQuaternion(k.quaternion2).add(k.position))}t.array[3*n]=l.x,t.array[3*n+1]=l.y,t.array[3*n+2]=l.z,k.boundingBox.expandByPoint(l)}}h++}}if(i.needsUpdate=!0,r.needsUpdate=!0,o.needsUpdate=!0,this.billboard){s.needsUpdate=!0,this.mesh.frustumCulled=!1;const t=this.material.uniforms.width?.5*this.material.uniforms.width.value:.5;k.boundingBox.min.subScalar(t),k.boundingBox.max.addScalar(t)}else t.needsUpdate=!0;this.geometry.boundingBox=this.geometry.boundingBox||new e.Box3,this.geometry.boundingBox.copy(k.boundingBox),this.geometry.boundingSphere=this.geometry.boundingSphere||new e.Sphere,this.geometry.boundingBox.getBoundingSphere(this.geometry.boundingSphere),this.mesh.visible=!k.boundingBox.isEmpty(),this.geometry.setDrawRange(0,(n-1)*this.FaceIndicesPerNode)}currentTime(){return performance.now()/1e3}pause(){this.paused||(this.paused=!0,this.pauseAdvanceUpdateTimeDiff=this.currentTime()-this.lastAdvanceTime)}resume(){this.paused&&(this.paused=!1,this.lastAdvanceTime=this.currentTime()-this.pauseAdvanceUpdateTimeDiff)}update(){if(!this.paused){const t=this.currentTime();this.lastAdvanceTime||(this.lastAdvanceTime=t),t-this.lastAdvanceTime>this.advancePeriod?(this.advance(),this.lastAdvanceTime=t):this.updateHead()}}deactivate(){this.active&&(this.scene.remove(this.mesh),this.active=!1)}activate(){this.active||(this.scene.add(this.mesh),this.active=!0)}static getTrailShaderNodes(t){return{position:t?W:_,color:j,fraction:H}}static applyTrailShaderParameters(t){t.transparent=!0,t.alphaTest=.1,t.blending=e.CustomBlending,t.blendSrc=e.SrcAlphaFactor,t.blendDst=e.OneMinusSrcAlphaFactor,t.blendEquation=e.AddEquation,t.depthTest=!0,t.depthWrite=!1,t.side=e.DoubleSide}static createBaseMaterial(e,r,o,s=!1){let{position:n}=Trail.getTrailShaderNodes(s),h=a(N,U,H).rgba,l=h.a;if(null!=e){let i=trailUV;null!=r&&(i=i.add(f(t.elapsed.multiply(-r),0)));const s=c(e).sample(i);switch(o??"red"){case"none":break;case"red":l=l.multiply(s.r);break;case"alpha":l=l.multiply(s.a)}h=g(h.rgb.multiply(s.rgb),l)}const d=new i({position:n,opacity:l,color:h});return Trail.applyTrailShaderParameters(d),d}static get MaxHeadVertices(){return 128}static get LocalOrientationTangent(){return Trail._LocalOrientationTangent}static get LocalHeadOrigin(){return Trail._LocalHeadOrigin}static get PositionComponentCount(){return 3}static get UVComponentCount(){return 2}static get IndicesPerFace(){return 3}static get FacesPerQuad(){return 2}}Trail._LocalOrientationTangent=new e.Vector3(1,0,0),Trail._LocalHeadOrigin=new e.Vector3(0,0,0),Trail.Shader={get BaseVertexVars(){return["attribute float nodeID;","attribute float nodeVertexID;","attribute vec3 nodeCenter;","uniform float minID;","uniform float maxID;","uniform float trailLength;","uniform float maxTrailLength;","uniform float verticesPerNode;","uniform vec2 textureTileFactor;","uniform bool taper;","uniform vec4 headColor;","uniform vec4 tailColor;","varying vec4 vColor;"].join("\n")},get TexturedVertexVars(){return[this.BaseVertexVars,"varying vec2 vUV;","uniform float dragTexture;"].join("\n")},BaseFragmentVars:["varying vec4 vColor;","uniform sampler2D trailTexture;"].join("\n"),get TexturedFragmentVars(){return[this.BaseFragmentVars,"varying vec2 vUV;"].join("\n")},get VertexShaderCore(){return["float fraction = (maxID - nodeID) / (maxID - minID);","float fractionSize = taper ? fraction : 0.0;","vColor = (1.0 - fraction) * headColor + fraction * tailColor;","vec4 realPosition = vec4((1.0 - fractionSize) * position.xyz + fractionSize * nodeCenter.xyz, 1.0); "].join("\n")},get BaseVertexShader(){return[this.BaseVertexVars,"void main() { ",this.VertexShaderCore,"gl_Position = projectionMatrix * viewMatrix * realPosition;","}"].join("\n")},get BaseFragmentShader(){return[this.BaseFragmentVars,"void main() { ","gl_FragColor = vColor;","}"].join("\n")},get TexturedVertexShader(){return[this.TexturedVertexVars,"void main() { ",this.VertexShaderCore,"float s = 0.0;","float t = 0.0;","if (dragTexture == 1.0) { "," s = fraction * textureTileFactor.s; "," t = (nodeVertexID / verticesPerNode) * textureTileFactor.t;","} else { "," s = nodeID / maxTrailLength * textureTileFactor.s;"," t = (nodeVertexID / verticesPerNode) * textureTileFactor.t;","}","vUV = vec2(s, t); ","gl_Position = projectionMatrix * viewMatrix * realPosition;","}"].join("\n")},get TexturedFragmentShader(){return[this.TexturedFragmentVars,"void main() { ","vec4 textureColor = texture2D(trailTexture, vUV);","gl_FragColor = vColor * textureColor;","}"].join("\n")}};/*
|
|
1
|
+
import{timeUniforms as t}from"../../shader-nodes/index.js";import*as e from"three";import{NodeShaderMaterial as i,uniformBool as r,uniformFloat as o,uniformVec2 as s,mix as a,uniformVec4 as n,attributeFloat as h,attributeVec3 as l,select as d,float as u,textureSampler2d as c,attributes as m,uniforms as y,rgba as g,vec4 as p,varying as x,vec2 as f,vec3 as v,cross as b,max as T,length as C}from"three-shader-graph";o("trailLength");const V=o("verticesPerNode"),P=o("minID"),w=o("maxID"),F=(o("dragTexture"),o("maxTrailLength")),I=s("textureTileFactor",new e.Vector2(1,1)),D=n("headColor",new e.Vector4),N=n("tailColor",new e.Vector4),U=r("taper",!1),A=(o("scale",1),h("nodeID")),M=h("nodeVertexID"),z=l("nodeCenter"),B=u(1e-4),S=w.subtract(A).divide(T(w.subtract(P),B)),H=d(U,S,u(0)),j=x(u(1).subtract(S).multiplyVec4(D).add(S.multiplyVec4(N))),q=y.cameraPosition.subtract(z),L=d(C(q).gt(B),q.divideScalar(T(C(q),B)),v(0,0,1)),G=l("nodeTangent"),O=d(C(G).gt(B),G.divideScalar(T(C(G),B)),v(1,0,0)),Q=o("width",1),R=b(O,L),W=b(O,v(0,1,0)),_=d(C(W).gt(B),W,b(O,v(1,0,0))),k=d(C(R).gt(B),R.divideScalar(T(C(R),B)),_.divideScalar(T(C(_),B))).multiplyScalar(M.subtract(u(.5))).multiplyScalar(Q),E=p(u(1).subtract(H).multiplyVec3(k).add(T(H,u(1)).multiplyVec3(z)),1),J=p(u(1).subtract(H).multiplyVec3(m.position).add(H.multiplyVec3(z)),1),K=y.projectionMatrix.multiply(y.viewMatrix).multiplyVec(E),X=y.projectionMatrix.multiply(y.viewMatrix).multiplyVec(J);export const trailUV=x(f(S.multiply(I.x),M.divide(V).multiply(I.y).multiply(2)));export const trailDragUV=x(f(A.divide(F).multiply(I.x),M.divide(V).multiply(I.y).multiply(2)));const Y={position:new e.Vector3,direction:new e.Vector3,offset:new e.Vector3,worldOrientation:new e.Vector3,matrix4:new e.Matrix4,quat1:new e.Quaternion,quat2:new e.Quaternion,quaternion:new e.Quaternion,quaternion2:new e.Quaternion,boundingBox:new e.Box3,localHeadGeometry:Array.from({length:128},()=>new e.Vector3)};export class Trail extends e.Object3D{constructor(t,i){super(),this.historyCount=0,this.historyHeadIndex=-1,this.history=[],this.renderNodeCount=0,this.subdivisions=4,this.currentNodeID=0,this.advance=function(){const t=new e.Matrix4;return function(){this.targetObject.updateMatrixWorld(),t.copy(this.targetObject.matrixWorld),this.advanceWithTransform(t),this.updateUniforms()}}(),this.connectNodes=(()=>{const t={attribute:null,offset:0,count:-1};return(e,i)=>{const r=this.geometry.getIndex();for(let t=0;t<this.localHeadGeometry.length-1;t++){const o=this.VerticesPerNode*e+t,s=this.VerticesPerNode*i+t,a=(e*this.FacesPerNode+t*Trail.FacesPerQuad)*Trail.IndicesPerFace;r.array[a]=o,r.array[a+1]=s,r.array[a+2]=o+1,r.array[a+3]=s,r.array[a+4]=s+1,r.array[a+5]=o+1}return r.needsUpdate=!0,r.clearUpdateRanges(),t.attribute=r,t.offset=e*this.FacesPerNode*Trail.IndicesPerFace,t.count=this.FacesPerNode*Trail.IndicesPerFace,t}})(),this.disconnectNodes=(()=>{const t={attribute:null,offset:0,count:-1};return e=>{const i=this.geometry.getIndex();for(let t=0;t<this.localHeadGeometry.length-1;t++){const r=(e*this.FacesPerNode+t*Trail.FacesPerQuad)*Trail.IndicesPerFace;i.array[r]=0,i.array[r+1]=0,i.array[r+2]=0,i.array[r+3]=0,i.array[r+4]=0,i.array[r+5]=0}return i.needsUpdate=!0,i.clearUpdateRanges(),t.attribute=i,t.offset=e*this.FacesPerNode*Trail.IndicesPerFace,t.count=this.FacesPerNode*Trail.IndicesPerFace,t}})(),this.active=!1,this.orientToMovement=!1,i&&(this.orientToMovement=!0),this.scene=t,this.geometry=null,this.mesh=null,this.historyCount=0,this.historyHeadIndex=-1,this.history=[],this.renderNodeCount=0,this.currentNodeID=0,this.advanceFrequency=60,this.advancePeriod=1/this.advanceFrequency,this.lastAdvanceTime=0,this.paused=!1,this.pauseAdvanceUpdateTimeDiff=0}setAdvanceFrequency(t){this.advanceFrequency=t,this.advancePeriod=1/this.advanceFrequency}initialize(t,i,r,o,s,a,n=!1){this.deactivate(),this.destroyMesh(),this.length=i>0?i+1:0,this.dragTexture=r?1:0,this.targetObject=a,this.billboard=n,this.initializeLocalHeadGeometry(o,s),null!=t.uniforms.width&&(t.uniforms.width.value=o),this.renderNodeCount=this.length*this.subdivisions,this.historyCount=0,this.historyHeadIndex=-1,this.history=[];for(let t=0;t<this.length;t++)this.history.push({position:new e.Vector3,tangent:new e.Vector3(1,0,0),transformMatrix:new e.Matrix4,id:-1});this.setAllNodesToCurrentTargetPosition(),this.material=t,this.initializeGeometry(),this.initializeMesh(),this.material.uniforms.dragTexture&&(this.material.uniforms.trailLength.value=0),this.material.uniforms.minID.value=0,this.material.uniforms.maxID.value=0,this.material.uniforms.dragTexture&&(this.material.uniforms.dragTexture.value=this.dragTexture),this.material.uniforms.maxTrailLength&&(this.material.uniforms.maxTrailLength.value=this.length),this.material.uniforms.verticesPerNode&&(this.material.uniforms.verticesPerNode.value=this.VerticesPerNode),this.material.uniforms.textureTileFactor&&(this.material.uniforms.textureTileFactor.value=new e.Vector2(1,1)),this.material.uniforms.scale&&(this.material.uniforms.scale.value=1),this.reset()}initializeLocalHeadGeometry(t,i){if(this.localHeadGeometry=[],i){this.VerticesPerNode=0;for(let t=0;t<i.length&&t<Trail.MaxHeadVertices;t++){const r=i[t];if(r&&r instanceof e.Vector3){const t=new e.Vector3;t.copy(r),this.localHeadGeometry.push(t),this.VerticesPerNode++}}}else{const i=(t||1)/2;this.localHeadGeometry.push(new e.Vector3(-i,0,0)),this.localHeadGeometry.push(new e.Vector3(i,0,0)),this.VerticesPerNode=2}this.FacesPerNode=2*(this.VerticesPerNode-1),this.FaceIndicesPerNode=3*this.FacesPerNode}initializeGeometry(){this.vertexCount=this.renderNodeCount*this.VerticesPerNode,this.faceCount=this.renderNodeCount*this.FacesPerNode;const t=new e.BufferGeometry,i=new Float32Array(this.vertexCount),r=new Float32Array(this.vertexCount*this.VerticesPerNode),o=new Float32Array(this.vertexCount*Trail.PositionComponentCount),s=new Float32Array(this.vertexCount*Trail.PositionComponentCount),a=new Float32Array(this.vertexCount*Trail.UVComponentCount),n=new Uint32Array(this.faceCount*Trail.IndicesPerFace),h=new Float32Array(3*this.vertexCount),l=new e.BufferAttribute(h,3);l.setUsage(e.DynamicDrawUsage),t.setAttribute("nodeTangent",l);const d=new e.BufferAttribute(i,1);d.setUsage(e.DynamicDrawUsage),t.setAttribute("nodeID",d);const u=new e.BufferAttribute(r,1);u.setUsage(e.DynamicDrawUsage),t.setAttribute("nodeVertexID",u);const c=new e.BufferAttribute(s,Trail.PositionComponentCount);c.setUsage(e.DynamicDrawUsage),t.setAttribute("nodeCenter",c);const m=new e.BufferAttribute(o,Trail.PositionComponentCount);m.setUsage(e.DynamicDrawUsage),t.setAttribute("position",m);const y=new e.BufferAttribute(a,Trail.UVComponentCount);y.setUsage(e.DynamicDrawUsage),t.setAttribute("uv",y);const g=new e.BufferAttribute(n,1);g.setUsage(e.DynamicDrawUsage),t.setIndex(g),this.geometry=t}zeroVertices(){const t=this.geometry.getAttribute("position");for(let e=0;e<this.vertexCount;e++){const i=3*e;t.array[i]=0,t.array[i+1]=0,t.array[i+2]=0}t.needsUpdate=!0}zeroIndices(){if(null==this.geometry)throw"Geometry not initialized";const t=this.geometry.getIndex();for(let e=0;e<this.faceCount;e++){const i=3*e;t.array[i]=0,t.array[i+1]=0,t.array[i+2]=0}t.needsUpdate=!0,t.clearUpdateRanges()}formInitialFaces(){this.zeroIndices();const t=this.geometry.getIndex();for(let t=0;t<this.renderNodeCount-1;t++)this.connectNodes(t,t+1);t.needsUpdate=!0,t.clearUpdateRanges()}initializeMesh(){if(null==this.geometry)throw"Geometry not initialized";this.mesh=new e.Mesh(this.geometry,this.material),this.mesh.matrixAutoUpdate=!1,this.mesh.visible=!1}destroyMesh(){this.mesh&&(this.scene.remove(this.mesh),this.mesh=null)}reset(){this.historyCount=0,this.historyHeadIndex=-1,this.currentNodeID=0,this.formInitialFaces(),this.zeroVertices(),this.geometry.setDrawRange(0,0),this.setAllNodesToCurrentTargetPosition(),this.mesh&&(this.mesh.visible=!0)}setAllNodesToCurrentTargetPosition(){if(!this.targetObject)return;this.targetObject.updateMatrixWorld();const t=this.targetObject.matrixWorld,i=(new e.Vector3).setFromMatrixPosition(t),r=new e.Vector3(1,0,0).transformDirection(t);for(let e=0;e<this.length;e++)this.history[e].position.copy(i),this.history[e].tangent.copy(r),this.history[e].transformMatrix.copy(t),this.history[e].id=-1;this.historyCount=0,this.historyHeadIndex=-1}updateUniforms(){if(0===this.historyCount)return;const t=this.getControlPoint(0).id,e=this.getControlPoint(this.historyCount-1).id;this.material.uniforms.minID.value=t,this.material.uniforms.maxID.value=e,this.material.uniforms.trailLength&&(this.material.uniforms.trailLength.value=this.historyCount),this.material.uniforms.maxTrailLength&&(this.material.uniforms.maxTrailLength.value=this.length),this.material.uniforms.verticesPerNode&&(this.material.uniforms.verticesPerNode.value=this.VerticesPerNode)}advanceWithTransform(t){this.historyCount<this.length&&this.historyCount++,this.historyHeadIndex=(this.historyHeadIndex+1)%this.length;const e=this.history[this.historyHeadIndex];if(e.id=this.currentNodeID++,Y.position.set(0,0,0).applyMatrix4(t),e.position.copy(Y.position),e.transformMatrix.copy(t),this.billboard){const i=this.getControlPoint(this.historyCount-2);i&&!i.position.equals(Y.position)?e.tangent.copy(Y.position).sub(i.position).normalize():e.tangent.set(1,0,0).transformDirection(t)}this.rebuildGeometry()}updateHead(){if(0===this.historyCount)return;this.targetObject.updateMatrixWorld();const t=this.targetObject.matrixWorld,e=this.history[this.historyHeadIndex];if(Y.position.set(0,0,0).applyMatrix4(t),e.position.copy(Y.position),e.transformMatrix.copy(t),this.billboard){const i=this.getControlPoint(this.historyCount-2);i&&!i.position.equals(Y.position)?e.tangent.copy(Y.position).sub(i.position).normalize():e.tangent.set(1,0,0).transformDirection(t)}this.rebuildGeometry()}getControlPoint(t){if(t<0)return this.history[(this.historyHeadIndex-this.historyCount+1+this.length)%this.length];t>=this.historyCount&&(t=this.historyCount-1);const e=(this.historyHeadIndex-this.historyCount+1+this.length)%this.length;return this.history[(e+t)%this.length]}rebuildGeometry(){if(this.historyCount<2)return this.geometry.setDrawRange(0,0),void(this.mesh&&(this.mesh.visible=!1));const t=this.geometry.getAttribute("position"),i=this.geometry.getAttribute("nodeID"),r=this.geometry.getAttribute("nodeVertexID"),o=this.geometry.getAttribute("nodeCenter"),s=this.geometry.getAttribute("nodeTangent"),a=this.historyCount-1,n=a*this.subdivisions+1;let h=0;Y.boundingBox.makeEmpty();for(let e=0;e<a;e++){const n=this.getControlPoint(e-1),l=this.getControlPoint(e),d=this.getControlPoint(e+1),u=this.getControlPoint(e+2),c=e===a-1?this.subdivisions+1:this.subdivisions;for(let e=0;e<c;e++){const a=e/this.subdivisions,c=n.position,m=l.position,y=d.position,g=u.position,p=a*a,x=p*a,f=.5*(y.x-c.x),v=.5*(g.x-m.x),b=(2*(m.x-y.x)+f+v)*x+(-3*(m.x-y.x)-2*f-v)*p+f*a+m.x,T=.5*(y.y-c.y),C=.5*(g.y-m.y),V=(2*(m.y-y.y)+T+C)*x+(-3*(m.y-y.y)-2*T-C)*p+T*a+m.y,P=.5*(y.z-c.z),w=.5*(g.z-m.z),F=(2*(m.z-y.z)+P+w)*x+(-3*(m.z-y.z)-2*P-w)*p+P*a+m.z;Y.position.set(b,V,F);const I=l.id+(d.id-l.id)*a,D=Y.direction.copy(l.tangent).lerp(d.tangent,a).normalize();Y.matrix4.copy(l.transformMatrix),Y.quat1.setFromRotationMatrix(l.transformMatrix),Y.quat2.setFromRotationMatrix(d.transformMatrix),Y.quaternion.copy(Y.quat1).slerp(Y.quat2,a),Y.matrix4.makeRotationFromQuaternion(Y.quaternion),Y.matrix4.setPosition(Y.position);for(let e=0;e<this.VerticesPerNode;e++){const n=h*this.VerticesPerNode+e;i.array[n]=I,r.array[n]=e,o.array[3*n]=Y.position.x,o.array[3*n+1]=Y.position.y,o.array[3*n+2]=Y.position.z;const l=Y.localHeadGeometry[e].copy(this.localHeadGeometry[e]);if(this.billboard)s.array[3*n]=D.x,s.array[3*n+1]=D.y,s.array[3*n+2]=D.z,Y.boundingBox.expandByPoint(Y.position);else{if(l.applyMatrix4(Y.matrix4),this.orientToMovement){Y.worldOrientation.set(0,0,-1).applyQuaternion(Y.quaternion);const t=(3*p-2*a)*(m.x-y.x)+(x-p)*v+(3*p-4*a+1)*f,e=(3*p-2*a)*(m.y-y.y)+(x-p)*C+(3*p-4*a+1)*T,i=(3*p-2*a)*(m.z-y.z)+(x-p)*w+(3*p-4*a+1)*P;Y.direction.set(t,e,i).normalize(),Y.direction.lengthSq()>1e-4&&(Y.quaternion2.setFromUnitVectors(Y.worldOrientation,Y.direction),l.sub(Y.position).applyQuaternion(Y.quaternion2).add(Y.position))}t.array[3*n]=l.x,t.array[3*n+1]=l.y,t.array[3*n+2]=l.z,Y.boundingBox.expandByPoint(l)}}h++}}if(i.needsUpdate=!0,r.needsUpdate=!0,o.needsUpdate=!0,this.billboard){s.needsUpdate=!0,this.mesh.frustumCulled=!1;const t=this.material.uniforms.width?.5*this.material.uniforms.width.value:.5;Y.boundingBox.min.subScalar(t),Y.boundingBox.max.addScalar(t)}else t.needsUpdate=!0;this.geometry.boundingBox=this.geometry.boundingBox||new e.Box3,this.geometry.boundingBox.copy(Y.boundingBox),this.geometry.boundingSphere=this.geometry.boundingSphere||new e.Sphere,this.geometry.boundingBox.getBoundingSphere(this.geometry.boundingSphere),this.mesh.visible=!Y.boundingBox.isEmpty(),this.geometry.setDrawRange(0,(n-1)*this.FaceIndicesPerNode)}currentTime(){return performance.now()/1e3}pause(){this.paused||(this.paused=!0,this.pauseAdvanceUpdateTimeDiff=this.currentTime()-this.lastAdvanceTime)}resume(){this.paused&&(this.paused=!1,this.lastAdvanceTime=this.currentTime()-this.pauseAdvanceUpdateTimeDiff)}update(){if(!this.paused){const t=this.currentTime();this.lastAdvanceTime||(this.lastAdvanceTime=t),t-this.lastAdvanceTime>this.advancePeriod?(this.advance(),this.lastAdvanceTime=t):this.updateHead()}}deactivate(){this.active&&(this.scene.remove(this.mesh),this.active=!1)}activate(){this.active||(this.scene.add(this.mesh),this.active=!0)}static getTrailShaderNodes(t){return{position:t?K:X,color:j,fraction:S}}static applyTrailShaderParameters(t){t.transparent=!0,t.alphaTest=.1,t.blending=e.CustomBlending,t.blendSrc=e.SrcAlphaFactor,t.blendDst=e.OneMinusSrcAlphaFactor,t.blendEquation=e.AddEquation,t.depthTest=!0,t.depthWrite=!1,t.side=e.DoubleSide}static createBaseMaterial(e,r,o,s=!1){let{position:n}=Trail.getTrailShaderNodes(s),h=a(D,N,S).rgba,l=h.a;if(null!=e){let i=trailUV;null!=r&&(i=i.add(f(t.elapsed.multiply(-r),0)));const s=c(e).sample(i);switch(o??"red"){case"none":break;case"red":l=l.multiply(s.r);break;case"alpha":l=l.multiply(s.a)}h=g(h.rgb.multiply(s.rgb),l)}const d=new i({position:n,opacity:l,color:h});return Trail.applyTrailShaderParameters(d),d}static get MaxHeadVertices(){return 128}static get LocalOrientationTangent(){return Trail._LocalOrientationTangent}static get LocalHeadOrigin(){return Trail._LocalHeadOrigin}static get PositionComponentCount(){return 3}static get UVComponentCount(){return 2}static get IndicesPerFace(){return 3}static get FacesPerQuad(){return 2}}Trail._LocalOrientationTangent=new e.Vector3(1,0,0),Trail._LocalHeadOrigin=new e.Vector3(0,0,0),Trail.Shader={get BaseVertexVars(){return["attribute float nodeID;","attribute float nodeVertexID;","attribute vec3 nodeCenter;","uniform float minID;","uniform float maxID;","uniform float trailLength;","uniform float maxTrailLength;","uniform float verticesPerNode;","uniform vec2 textureTileFactor;","uniform bool taper;","uniform vec4 headColor;","uniform vec4 tailColor;","varying vec4 vColor;"].join("\n")},get TexturedVertexVars(){return[this.BaseVertexVars,"varying vec2 vUV;","uniform float dragTexture;"].join("\n")},BaseFragmentVars:["varying vec4 vColor;","uniform sampler2D trailTexture;"].join("\n"),get TexturedFragmentVars(){return[this.BaseFragmentVars,"varying vec2 vUV;"].join("\n")},get VertexShaderCore(){return["float fraction = (maxID - nodeID) / (maxID - minID);","float fractionSize = taper ? fraction : 0.0;","vColor = (1.0 - fraction) * headColor + fraction * tailColor;","vec4 realPosition = vec4((1.0 - fractionSize) * position.xyz + fractionSize * nodeCenter.xyz, 1.0); "].join("\n")},get BaseVertexShader(){return[this.BaseVertexVars,"void main() { ",this.VertexShaderCore,"gl_Position = projectionMatrix * viewMatrix * realPosition;","}"].join("\n")},get BaseFragmentShader(){return[this.BaseFragmentVars,"void main() { ","gl_FragColor = vColor;","}"].join("\n")},get TexturedVertexShader(){return[this.TexturedVertexVars,"void main() { ",this.VertexShaderCore,"float s = 0.0;","float t = 0.0;","if (dragTexture == 1.0) { "," s = fraction * textureTileFactor.s; "," t = (nodeVertexID / verticesPerNode) * textureTileFactor.t;","} else { "," s = nodeID / maxTrailLength * textureTileFactor.s;"," t = (nodeVertexID / verticesPerNode) * textureTileFactor.t;","}","vUV = vec2(s, t); ","gl_Position = projectionMatrix * viewMatrix * realPosition;","}"].join("\n")},get TexturedFragmentShader(){return[this.TexturedFragmentVars,"void main() { ","vec4 textureColor = texture2D(trailTexture, vUV);","gl_FragColor = vColor * textureColor;","}"].join("\n")}};/*
|
|
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 e,{Behaviour as t,Body as a,Emitter as r,Rate as s}from"@hology/nebula";import*as i from"three";import{Object3D as n}from"three";import{AttributeVec3Node as o,AttributeVec4Node as l,NodeShaderMaterial as c,RgbNode as p,UniformFloatNode as u,UniformVec3Node as h,Vec3ExpressionNode as d,Vec4Node as m,attributeFloat as f,attributeVec3 as y,attributeVec4 as w,attributes as g,clamp as b,float as v,glslFunction as E,lambertMaterial as A,log as M,pow as x,rgb as P,rgba as S,smoothstep as I,standardMaterial as T,textureSampler2d as C,uniformFloat as R,uniforms as B,varying as k,varyingAttributes as j,varyingVec3 as D,varyingVec4 as G}from"three-shader-graph";import{prepareClassParameters as V,prepareShaderGraphParameters as F,prepareShapeParameters as z}from"../../scene/materializer.js";import{SerializedParamType as L}from"../../scene/model.js";import{ShapeLibrary as O}from"../../scene/objects/shapes.js";import{fragmentLinearEyeDepth as W,linearEyeDepth as Q}from"../../shader-nodes/depth.js";import{particleEnergyUniformName as H,particleTimeUniformName as U,particleUniforms as q,particleVelcoityUniformName as J}from"../../shader-nodes/particle.js";import{sampleFlipbook as N}from"../../shader-nodes/texture-sequence.js";import{DefaultInitializer as X,WorldSpaceEmitterRotationInitializer as _}from"./initializsers.js";import{DelayRate as K,OnceRate as Y}from"./rates.js";import{StretchedSprite as Z}from"./stretched-sprite.js";import{ThreeBlendingMode as $}from"./vfx-asset.js";import{VfxBehaviourLibrary as ee,VfxInitializserLibrary as te}from"./vfx-defs.js";import{MultiRenderer as ae}from"./vfx-renderers.js";import{WorldCollisionBehaviour as re}from"./vfx-collision-behaviour.js";import{getSpritePosition as se,SpriteNodeShaderMaterial as ie}from"../../shader/sprite-shader.js";import{DecalUnlitShader as ne}from"../../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as oe}from"../../shader/builtin/decal-standard-shader.js";import{createBoundBehaviour as le,createBoundInitializer as ce}from"./vfx-binding-runtime.js";import{buildShaderGraphMaterial as pe}from"../../shader/graph/index.js";export async function materializeVfx(t,a,r,s,o,l,c,p,u){let h=a;for(;null!=h.parent;)h=h.parent;const d=new n;d.name="particle system local",a.add(d);const m=new n;m.name="particle system world";const f=new ae(m,d,i,s),y=new e;return(await Promise.all(t.vfx.emitters.slice().sort((e,t)=>(t.output.renderOrder??0)-(e.output.renderOrder??0)).map(async e=>{const t=await ue(e,r,c,p,y,o,l,u,a);return t.setParentRecursive(y),t.emit()}))).forEach(e=>y.addEmitter(e)),y.addRenderer(f).emit({onEnd:()=>{}}),{container:m,system:y,dispose:()=>{m.removeFromParent(),d.removeFromParent(),f.dispose()}}}async function ue(e,t,r,p,v,x,P,T,D){const V=function(e){let t;switch(e.rate.type){case"continuous":t=new K(e.rate.delay??0,e.rate.count,e.rate.time,e.rate.duration);break;case"once":t=new Y(e.rate.delay??0,e.rate.count);break;default:console.warn(`Failed to configure rate for emitter: ${JSON.stringify(e)}`),t=new s(0,1/0)}return t}(e);let F;switch(e.output.type){case"decal":F=new a(await async function(e,t,a,r,s){if("shaderGraph"===fe(e)){const t=await me(e,"decal",a,r,s);if(null!=t){const a=new i.Mesh(new i.BoxGeometry(1,1,1),t);return we(a,e),a}}const n=!1!==e.unlit?new ne:new oe;n.color=new i.Color(e.color),n instanceof ne?n.intensity=e.intensity??1:n.emissiveIntensity=e.intensity??1;if(e.colorMap){const a=await t.getTexture(e.colorMap);n.colorMap=a}if(e.alphaMap){const a=await t.getTexture(e.alphaMap);n.alphaMap=a}const o=n.build();o.blending=$[e.blendingMode]??i.NormalBlending,o.transparent=!0,o.side=i.BackSide,o.depthTest=!1,null!=o&&!0===e.bloom&&(o.userData.hasBloom=!0);o.defines.IS_PARTICLE="";const l=new i.BoxGeometry(1,1,1),c=new i.Mesh(l,o);return we(c,e),c}(e.output,t,r,p,P));break;case"sprite":F=new a(await async function(e,t,a,r,s){let n=null;const o=fe(e);"shaderGraph"===o&&(n=await me(e,"sprite",a,r,s));null==n&&"shader"===o&&null!=e.shader&&(n=await de(e,t,s));null==n&&(n=await async function(e,t){const a=null!=e.texture?await t.getTexture(e.texture):he,r=C(a);let s=r.sample(j.uv);e.flipbook?.enabled&&(s=N(r,g.uv,e.flipbook.columns,e.flipbook.rows,q.time,e.flipbook.fps,e.flipbook.mode));const n=new u("rotation",0),o=new h("color").rgb,l=R("opacity",1),c=Q.subtract(W).divide(Q);let p=l;switch(e.opacityChannel??"red"){case"none":break;case"red":p=p.multiply(s.r);break;case"alpha":p=p.multiply(s.a)}if("number"==typeof e.softness&&e.softness>0){const t=b(c,0,1e3);p=p.multiply(I(0,.2*e.softness,t))}const d=se(n),m=S(o.multiply(s.rgb).multiplyScalar(e.intensity??1),p);var f=new ie({color:m,emissive:m.rgb.multiplyScalar(p),transparent:!0,position:d,alphaTest:1e-4,uniforms:{color:{value:new i.Color(e.color)}}});f.alphaHash=!0,null!=f&&!0===e.bloom&&(f.userData.hasBloom=!0);return f.blending=$[e.blendingMode]??i.NormalBlending,f}(e,t));ye(n,e);const l=new i.Mesh(new i.PlaneGeometry(1,1),n);return l.name="sprite",we(l,e),l}(e.output,t,r,p,P));break;case"stretchedSprite":F=new a(await async function(e,t){"shaderGraph"===fe(e)&&console.warn("Shader graph materials are not supported for stretched sprite VFX outputs yet. Falling back to the default stretched sprite material.");const a=null!=e.texture?await t.getTexture(e.texture):he,r=C(a).sample(j.uv),s=G(new l("color")),n=s.rgb.multiply(r.rgb);let o=s.w;switch(e.opacityChannel??"red"){case"none":break;case"red":o=o.multiply(r.r);break;case"alpha":o=o.multiply(r.a)}if("number"==typeof e.softness&&e.softness>0){const t=Q.subtract(W).divide(M(Q)),a=b(t,0,1e3);o=o.multiply(I(0,.2*e.softness,a))}const c=E(m,{position:g.position,offset:y("offset"),modelViewMatrix:B.modelViewMatrix,velocity:w("velocity"),size:y("size"),rotation:f("rotation")},"\n float lengthFactor = velocity.w;\n float avgSize = (size.x + size.y) * 0.5;\n\n vec4 mvPosition = modelViewMatrix * vec4( offset , 1.0 );\n vec3 viewVelocity = normalMatrix * velocity.xyz;\n float vlength = length(viewVelocity); \n mvPosition.xyz += position.y * normalize(cross(mvPosition.xyz, viewVelocity)) * avgSize; \n mvPosition.xyz -= (position.x + 0.5) * viewVelocity * (1.0 + lengthFactor / vlength) * avgSize;\n return projectionMatrix * mvPosition;\n ");var p=new ie({color:S(n.multiplyScalar(e.intensity??1),o),alphaTest:.1,transparent:!0,position:c,uniforms:{color:{value:new i.Color(e.color)}}});null!=p&&!0===e.bloom&&(p.userData.hasBloom=!0);p.blending=$[e.blendingMode]??i.NormalBlending;const u=new Z(new i.PlaneGeometry(1,1),p);return u.scaleFactor=e.scale,we(u,e),u}(e.output,t));break;case"shape":F=new a(await async function(e,t,a,r,s){if(null==e.shape)return console.log("Shape is null"),new n;const l=O[e.shape];if(null==l)return console.error(`No shape with type ${e.shape}`),new n;const p=z(e.params??{}),u=l.geometry(p);let h=null;const m=fe(e);"shaderGraph"===m&&(h=await me(e,"surface",a,r,s));null==h&&"shader"===m&&null!=e.shader&&(h=await de(e,t,s));null==h&&(h="material"===m&&null!=e.material?ge(await t.getMaterial(e.material)):function(){const e=k(new d("instanceColor")).rgb,t=k(new o("particleData")).x;return new c({color:A({color:e}).rgb.rgba(t),opacity:t,transparent:!0})}());ye(h,e);const f=new i.Mesh(u,h);return we(f,e),f}(e.output,t,r,p,P));break;case"mesh":F=new a(await async function(e,t,a,r,s){if(null==e.assetId)return console.warn("Can't use mesh as particle without asset id"),new n;const o=await t.getMesh(e.assetId),l=await t.getAsset(e.assetId),c=fe(e);if("shaderGraph"===c||"shader"===c||"material"===c){let n;"shaderGraph"===c?n=await me(e,"surface",a,r,s):"shader"===c&&null!=e.shader?n=await de(e,t,s):"material"===c&&null!=e.material&&(n=ge(await t.getMaterial(e.material))),ye(n,e),o.traverse(e=>{e instanceof i.Mesh&&null!=n&&(e.material=n)})}else{const e=[];if(null!=l.materialAssignments)for(const a of l.materialAssignments)o.traverse(r=>{r instanceof i.Mesh&&r.material instanceof i.Material&&r.material.color instanceof i.Color&&(r.material.name!=a.name&&null!=a.name||"#"+r.material.color.getHexString()!==a.color||e.push(t.getMaterial(a.materialId).then(e=>r.material=e)))});await Promise.all(e)}const p=[];if(o.traverse(e=>{e instanceof i.Mesh&&p.push(e)}),we(o,e),1===p.length){const e=p[0];return e.updateWorldMatrix(!0,!0),e.updateMatrixWorld(),e.matrix.copy(e.matrixWorld),e.matrixWorld.decompose(e.position,e.quaternion,e.scale),e.removeFromParent(),e}return o}(e.output,t,r,p,P));break;case"trail":{const s="shaderGraph"===fe(e.output)?await me(e.output,"trail",r,p,P,{trailBillboard:e.output.billboard??!1}):null;F=new a({type:"trail",taper:e.output.taper,headGeometry:null,material:s instanceof i.ShaderMaterial?s:void 0,dragTexture:!1,texture:null!=e.output.texture?await t.getTexture(e.output.texture):null,opacityChannel:e.output.opacityChannel,color:e.output.color,colorEnd:e.output.colorEnd,intensity:e.output.intensity??1,intensityEnd:e.output.intensityEnd??1,length:e.output.length,opacityStart:e.output.opacityStart,opacityEnd:e.output.opacityEnd,bloom:e.output.bloom,scrollSpeed:e.output.scrollSpeed,width:e.output.width,billboard:e.output.billboard??!1,renderOrder:e.output.renderOrder});break}default:console.error("Failed to create particly system body: "+JSON.stringify(e))}const H=new ve(D);H.parent=v,H.setRate(V),H._space=e.output.space;const U=await Promise.all(e.initializers.filter(e=>!1!==e.enabled).filter(e=>null!=te[e.type]).map(async e=>{const t=te[e.type],a=await z(e.params??{});return ce(t,e.params??{},a,T)}));"world"!==e.output.space||"shape"!==e.output.type&&"mesh"!==e.output.type||U.unshift(new _),U.push(F,new X),H.addInitializers(U);const J=await Promise.all(e.behaviours.filter(e=>!1!==e.enabled).filter(e=>null!=ee[e.type]).map(async e=>{const t=ee[e.type];for(const[a,r]of Object.entries(e.params))t.parameters&&null!=t.parameters[a]&&"curve"===t.parameters[a].type&&r.type!==L.Curve&&(r.type=L.Curve);const a=await z(e.params??{},r,p);return le(t,e.params??{},a,T)}).sort((e,t)=>e instanceof re?1:0));J.push(new be);for(const e of J)e instanceof re&&(e.physics=x);H.addBehaviours(J);for(const a of e.children??[]){const e=await ue(a,t,r,p,v,x,P,T,D),s=new EmitterPool(()=>{const t=e.clone();return t.onExpired=()=>{const e=H.childEmitters.findIndex(e=>e.id===t.id);-1!=e&&H.childEmitters.splice(e,1),null!=t.parentParticle&&(n.delete(t.parentParticle.id),t.parentParticle=null),s.release(t)},t}),i=H.eventDispatcher,n=new Map;H.bindEmitterEvent=!0,i.addEventListener("PARTICLE_DEAD",e=>{const t=n.get(e.id);null!=t&&(H.detachChildEmitterFromParticle(t,e),n.delete(e.id))});let o="PARTICLE_CREATED";if("spawnEvent"in a)switch(a.spawnEvent){case"collision":o="PARTICLE_COLLISION";break;case"start":o="PARTICLE_CREATED"}i.addEventListener(o,e=>{const t=s.get();t.age=0,t.totalEmitTimes=-1,t.particles.length=0,t.currentEmitTime=0,t.cID=0,t.eventDispatcher.removeAllEventListeners(),H.childEmitters.push(t),n.set(e.id,t),t.parentParticle=e,t.system=H.system,t.emit()})}return H}const he=(new i.TextureLoader).load("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJkSURBVHjaxJeJbusgEEW94S1L//83X18M2MSuLd2pbqc4wZGqRLrKBsyZhQHny7Jk73xVL8xpVhWrcmiB5lX+6GJ5YgQ2owbAm8oIwH1VgKZUmGcRqKGGPgtEQQAzGR8hQ59fAmhJHSAagigJ4E7GPWRXOYC6owAd1JM6wDQPADyMWUqZRMqmAojHp1Vn6EQQEgUNMJLnUjMyJsM49wygBkAPw9dVFwXRkncCIIW3GRgoTQUZn6HxCMAFEFd8TwEQ78X4rHbILoAUmeT+RFG4UhQ6MiIAE4W/UsYFjuVjAIa2nIY4q1R0GFtQWG3E84lqw2GO2QOoCKBVu0BAPgDSU0eUDjjQenNkV/AW/pWChhpMTelo1a64AOKM30vk18GzTHXCNtI/Knz3DFBgsUqBGIjTInXRY1yA9xkVoqW5tVq3pDR9A0hfF5BSARmVnh7RMDCaIdcNgbPBkgzn1Bu+SfIEFSpSBmkxyrMicb0fAEuCZrWnN89veA/4XcakrPcjBWzkTuLjlbfTQPOlBhz+HwkqqPXmPQDdrQItxE1moGof1S74j/8txk8EHhTQrAE8qlwfqS5yukm1x/rAJ9Jiaa6nyATqD78aUVBhFo8b1V4DdTXdCW+IxA1zB4JhiOhZMEWO1HqnvdoHZ4FAMIhV9REF8FiUm0jsYPEJx/Fm/N8OhH90HI9YRHesWbXXZwAShU8qThe7H8YAuJmw5yOd989uRINKRTJAhoF8jbqrHKfeCYdIISZfSq26bk/K+yO3YvfKrVgiwQBHnwt8ynPB25+M8hceTt/ybPhnryJ78+tLgAEAuCFyiQgQB30AAAAASUVORK5CYII=");async function de(e,t,a){const r=a.get(e.shader);if(null==r)return console.error("No shader exists with name "+e.shader),new i.Material;const s=new r.type,n=await V(e.shaderParams??{},r.type,t,{getTexture:e=>t.getTexture(e.id),getMaterial:e=>t.getMaterial(e.id),getMesh:e=>t.getMesh(e.id)},void 0,void 0,void 0,void 0,void 0,s);return Object.assign(s,n),s.build()}async function me(e,t,a,r,s,i={}){const n=e.shaderGraph;if("asset"!==n?.source||null==n.assetId)return console.warn(`Missing shader graph asset reference for ${e.type} VFX output`),null;const o=await a.getAsset(n.assetId),l=o?.shaderGraph;if(null==l)return console.warn(`Missing shader graph asset "${n.assetId}" for ${e.type} VFX output`),null;if(l.target!==t)return console.warn(`Shader graph "${o.name}" targets "${l.target}" but ${e.type} VFX output expects "${t}"`),null;try{const t=await F(e.shaderGraphParams??{},l,a,r,void 0,s.shaders),o=pe(l,{parameters:t,trailBillboard:i.trailBillboard});return o.userData.customShaderName=`shaderGraph:${n.assetId}`,ye(o,e),o}catch(e){return console.log("Shader graph VFX runtime error: "+e,e),null}}function fe(e){return null!=e.materialSource?e.materialSource:"asset"===e.shaderGraph?.source?"shaderGraph":"shader"in e&&null!=e.shader?"shader":"mesh"!==e.type&&"shape"!==e.type||null==e.material?"default":"material"}function ye(e,t){null!=e&&("bloom"in t&&!0===t.bloom&&(e.userData.hasBloom=!0),"sprite"===t.type?(e.blending=$[t.blendingMode]??i.NormalBlending,!0===t.lockY&&e instanceof i.ShaderMaterial&&(e.defines??(e.defines={}),e.defines.LOCK_Y_AXIS="")):"decal"===t.type?(e.blending=$[t.blendingMode]??i.NormalBlending,e.transparent=!0,e.side=i.BackSide,e.depthTest=!1,e instanceof i.ShaderMaterial&&(e.defines??(e.defines={}),e.defines.IS_PARTICLE="")):"shape"!==t.type&&"mesh"!==t.type||e instanceof i.ShaderMaterial&&(e.defines??(e.defines={}),e.defines.IS_PARTICLE=""))}function we(e,t){const a=t.renderOrder;null!=a&&e.traverse(e=>e.renderOrder=a)}function ge(e){const t=k(new d("instanceColor")).rgb;let a,r=k(new o("particleData")).x;if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshBasicMaterial){let s=t.multiply(P(e.color));null!=e.map&&(s=s.multiply(C(e.map).sample(j.uv).rgb)),null!=e.alphaMap&&(r=r.multiply(C(e.alphaMap).sample(j.uv).r)),e instanceof i.MeshStandardMaterial?a=new c({color:T({color:s,emissive:P(e.emissive),emissiveIntensity:v(e.emissiveIntensity),roughness:e.roughness,metalness:e.metalness}).rgb.rgba(r),emissive:P(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}):e instanceof i.MeshLambertMaterial?a=new c({color:A({color:s}).rgb.rgba(r),emissive:P(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}):e instanceof i.MeshBasicMaterial&&(a=new c({color:s.rgb.rgba(r),emissive:s.rgb,transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}))}else e instanceof c&&(a=e.clone(),a.defines.IS_PARTICLE="");return null!=a&&(!0===e.userData?.hasBloom&&null!=a&&(a.userData.hasBloom=!0),a.side=e.side,a.transparent=e.transparent),a??e}class be extends t{initialize(e){e.body instanceof i.Object3D&&e.body.traverse(e=>{if(e instanceof i.Mesh){const t=e.material;t instanceof c&&(null!=t.uniforms[H]||null!=t.uniforms[U]||t.uniforms[J])}})}mutate(e,t,a){this.energize(e,t),e.target instanceof n&&e.target.traverse(t=>{if(t instanceof i.Mesh){const a=t.material;a instanceof c&&(null!=a.uniforms[H]&&(a.uniforms[H].value=this.energy),null!=a.uniforms[U]&&(a.uniforms[U].value=e.age),null!=a.uniforms[J]&&(a.uniforms[J].value=e.velocity))}})}}class ve extends r{constructor(e){super(),this.transformRoot=e,this.childEmitters=[],this.bindEmitterEvent=!1,this.onExpired=()=>{}}clearParticlesRecursive(){let e=this.childEmitters.length;for(;e--;){const t=this.childEmitters[e];t.stopEmit(),t.clearParticlesRecursive(),t.onExpired()}this.childEmitters.length=0;let t=this.particles.length;for(;t--;){const e=this.particles[t];this.system?.dispatch("PARTICLE_DEAD",e),this.bindEmitterEvent&&this.dispatch("PARTICLE_DEAD",e),null!=this.system?this.system.pool.expire(e.reset()):e.reset()}this.particles.length=0}detachChildEmitterFromParticle(e,t){this.copyPositionToChildSpace(e,t.position),e.parentParticle=null,e.stopEmit()}update(e){if(!this.isEmitting&&0===this.particles.length&&0===this.childEmitters.length)return;this.age+=e,(this.dead||this.age>=this.life)&&this.destroy(),this.isEmitting&&this.generate(e),this.integrate(e);let t=this.particles.length;for(;t--;){const e=this.particles[t];e.dead&&(this.system&&this.system.dispatch("PARTICLE_DEAD",e),this.bindEmitterEvent&&this.dispatch("PARTICLE_DEAD",e),this.system.pool.expire(e.reset()),this.particles.splice(t,1))}this.updateEmitterBehaviours(e),this.updateChildren(e),this.isEmitting||0!==this.particles.length||0!==this.childEmitters.length||this.onExpired()}updateChildren(e){for(const t of this.childEmitters)null!=t.parentParticle&&this.copyPositionToChildSpace(t,t.parentParticle.position),t.update(e)}copyPositionToChildSpace(e,t){const a=this._space??"world",r=e._space??"world";a!==r&&null!=this.transformRoot?(Ee.copy(t),"local"===a&&"world"===r?Ee.applyMatrix4(this.transformRoot.matrixWorld):"world"===a&&"local"===r&&(Ae.copy(this.transformRoot.matrixWorld).invert(),Ee.applyMatrix4(Ae)),e.position.copy(Ee)):e.position.copy(t)}clone(){const e=new ve(this.transformRoot);return e.setRate(this.rate.clone()),e.behaviours=this.behaviours,e.initializers=this.initializers,e._space=this._space,e.body=this.body,e.parent=this.parent,e.system=this.system,e}setParentRecursive(e){this.system=e,this.childEmitters.forEach(t=>t.setParentRecursive(e))}}const Ee=new i.Vector3,Ae=new i.Matrix4;export class EmitterPool{constructor(e){this.creator=e,this.instances=[]}get(){0==this.instances.length&&this.instances.push(this.creator());return this.instances.pop()}release(e){this.instances.push(e)}dispose(){this.instances.length=0}}/*
|
|
1
|
+
import e,{Behaviour as t,Body as a,Emitter as r,Rate as s}from"@hology/nebula";import*as i from"three";import{Object3D as n}from"three";import{AttributeVec3Node as o,AttributeVec4Node as l,NodeShaderMaterial as c,RgbNode as p,UniformFloatNode as u,UniformVec3Node as d,Vec3ExpressionNode as h,attributeVec3 as m,attributeVec4 as f,attributes as y,clamp as w,cross as g,float as b,lambertMaterial as E,length as A,log as v,normalize as M,pow as x,rgb as I,rgba as S,smoothstep as P,standardMaterial as T,textureSampler2d as C,uniformFloat as R,uniforms as B,varying as k,varyingAttributes as j,varyingVec3 as D,varyingVec4 as G,vec2 as F,vec3 as V,vec4 as L}from"three-shader-graph";import{prepareClassParameters as W,prepareShaderGraphParameters as O,prepareShapeParameters as Q}from"../../scene/materializer.js";import{SerializedParamType as H}from"../../scene/model.js";import{ShapeLibrary as U}from"../../scene/objects/shapes.js";import{fragmentLinearEyeDepth as q,linearEyeDepth as z}from"../../shader-nodes/depth.js";import{particleEnergyUniformName as J,particleTimeUniformName as N,particleUniforms as X,particleVelcoityUniformName as _}from"../../shader-nodes/particle.js";import{sampleFlipbook as K}from"../../shader-nodes/texture-sequence.js";import{DefaultInitializer as Y,WorldSpaceEmitterRotationInitializer as Z}from"./initializsers.js";import{DelayRate as $,OnceRate as ee}from"./rates.js";import{StretchedSprite as te}from"./stretched-sprite.js";import{ThreeBlendingMode as ae}from"./vfx-asset.js";import{VfxBehaviourLibrary as re,VfxInitializserLibrary as se}from"./vfx-defs.js";import{MultiRenderer as ie}from"./vfx-renderers.js";import{WorldCollisionBehaviour as ne}from"./vfx-collision-behaviour.js";import{getSpritePosition as oe,SpriteNodeShaderMaterial as le}from"../../shader/sprite-shader.js";import{DecalUnlitShader as ce}from"../../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as pe}from"../../shader/builtin/decal-standard-shader.js";import{createBoundBehaviour as ue,createBoundInitializer as de}from"./vfx-binding-runtime.js";import{buildShaderGraphMaterial as he}from"../../shader/graph/index.js";export async function materializeVfx(t,a,r,s,o,l,c,p,u){let d=a;for(;null!=d.parent;)d=d.parent;const h=new n;h.name="particle system local",a.add(h);const m=new n;m.name="particle system world";const f=new ie(m,h,i,s),y=new e;return(await Promise.all(t.vfx.emitters.slice().sort((e,t)=>(t.output.renderOrder??0)-(e.output.renderOrder??0)).map(async e=>{const t=await me(e,r,c,p,y,o,l,u,a);return t.setParentRecursive(y),t.emit()}))).forEach(e=>y.addEmitter(e)),y.addRenderer(f).emit({onEnd:()=>{}}),{container:m,system:y,dispose:()=>{m.removeFromParent(),h.removeFromParent(),f.dispose()}}}async function me(e,t,r,p,x,I,T,D,F){const V=function(e){let t;switch(e.rate.type){case"continuous":t=new $(e.rate.delay??0,e.rate.count,e.rate.time,e.rate.duration);break;case"once":t=new ee(e.rate.delay??0,e.rate.count);break;default:console.warn(`Failed to configure rate for emitter: ${JSON.stringify(e)}`),t=new s(0,1/0)}return t}(e);let W;switch(e.output.type){case"decal":W=new a(await async function(e,t,a,r,s){if("shaderGraph"===ge(e)){const t=await we(e,"decal",a,r,s);if(null!=t){const a=new i.Mesh(new i.BoxGeometry(1,1,1),t);return Ee(a,e),a}}const n=!1!==e.unlit?new ce:new pe;n.color=new i.Color(e.color),n instanceof ce?n.intensity=e.intensity??1:n.emissiveIntensity=e.intensity??1;if(e.colorMap){const a=await t.getTexture(e.colorMap);n.colorMap=a}if(e.alphaMap){const a=await t.getTexture(e.alphaMap);n.alphaMap=a}const o=n.build();o.blending=ae[e.blendingMode]??i.NormalBlending,o.transparent=!0,o.side=i.BackSide,o.depthTest=!1,null!=o&&!0===e.bloom&&(o.userData.hasBloom=!0);o.defines.IS_PARTICLE="";const l=new i.BoxGeometry(1,1,1),c=new i.Mesh(l,o);return Ee(c,e),c}(e.output,t,r,p,T));break;case"sprite":W=new a(await async function(e,t,a,r,s){let n=null;const o=ge(e);"shaderGraph"===o&&(n=await we(e,"sprite",a,r,s));null==n&&"shader"===o&&null!=e.shader&&(n=await ye(e,t,s));null==n&&(n=await async function(e,t){const a=null!=e.texture?await t.getTexture(e.texture):fe,r=C(a);let s=r.sample(j.uv);e.flipbook?.enabled&&(s=K(r,y.uv,e.flipbook.columns,e.flipbook.rows,X.time,e.flipbook.fps,e.flipbook.mode));const n=new u("rotation",0),o=new d("color").rgb,l=R("opacity",1),c=z.subtract(q).divide(z);let p=l;switch(e.opacityChannel??"red"){case"none":break;case"red":p=p.multiply(s.r);break;case"alpha":p=p.multiply(s.a)}if("number"==typeof e.softness&&e.softness>0){const t=w(c,0,1e3);p=p.multiply(P(0,.2*e.softness,t))}const h=oe(n),m=S(o.multiply(s.rgb).multiplyScalar(e.intensity??1),p);var f=new le({color:m,emissive:m.rgb.multiplyScalar(p),transparent:!0,position:h,alphaTest:1e-4,uniforms:{color:{value:new i.Color(e.color)}}});f.alphaHash=!0,null!=f&&!0===e.bloom&&(f.userData.hasBloom=!0);return f.blending=ae[e.blendingMode]??i.NormalBlending,f}(e,t));n.depthWrite=!1,be(n,e);const l=new i.Mesh(new i.PlaneGeometry(1,1),n);return l.name="sprite",Ee(l,e),l}(e.output,t,r,p,T));break;case"stretchedSprite":W=new a(await async function(e,t){"shaderGraph"===ge(e)&&console.warn("Shader graph materials are not supported for stretched sprite VFX outputs yet. Falling back to the default stretched sprite material.");const a=null!=e.texture?await t.getTexture(e.texture):fe,r=C(a).sample(j.uv),s=G(new l("particleColor")),n=s.rgb.multiply(r.rgb);let o=s.w;switch(e.opacityChannel??"red"){case"none":break;case"red":o=o.multiply(r.r);break;case"alpha":o=o.multiply(r.a)}if("number"==typeof e.softness&&e.softness>0){const t=z.subtract(q).divide(v(z)),a=w(t,0,1e3);o=o.multiply(P(0,.2*e.softness,a))}const c=m("offset"),p=f("velocity"),u=m("size"),d=p.w,h=u.x.add(u.y).multiply(.5),E=B.modelViewMatrix.multiplyVec(L(c,1)),x=B.normalMatrix.multiplyVec(p.xyz),I=M(g(E.xyz,x)).multiplyScalar(y.position.y.multiply(h)),T=x.multiplyScalar(y.position.x.add(.5).multiply(b(1).add(d.divide(A(x)))).multiply(h)),R=B.projectionMatrix.multiplyVec(L(E.xyz.add(I).subtract(T),E.w));var k=new le({color:S(n.multiplyScalar(e.intensity??1),o),alphaTest:.1,transparent:!0,position:R,uniforms:{color:{value:new i.Color(e.color)}}});null!=k&&!0===e.bloom&&(k.userData.hasBloom=!0);k.blending=ae[e.blendingMode]??i.NormalBlending;const D=new te(new i.PlaneGeometry(1,1),k);return D.scaleFactor=e.scale,Ee(D,e),D}(e.output,t));break;case"shape":W=new a(await async function(e,t,a,r,s){if(null==e.shape)return console.log("Shape is null"),new n;const l=U[e.shape];if(null==l)return console.error(`No shape with type ${e.shape}`),new n;const p=Q(e.params??{}),u=l.geometry(p);let d=null;const m=ge(e);"shaderGraph"===m&&(d=await we(e,"surface",a,r,s));null==d&&"shader"===m&&null!=e.shader&&(d=await ye(e,t,s));null==d&&(d="material"===m&&null!=e.material?Ae(await t.getMaterial(e.material)):function(){const e=k(new h("instanceColor")).rgb,t=k(new o("particleData")).x;return new c({color:E({color:e}).rgb.rgba(t),opacity:t,transparent:!0})}());be(d,e);const f=new i.Mesh(u,d);return Ee(f,e),f}(e.output,t,r,p,T));break;case"mesh":W=new a(await async function(e,t,a,r,s){if(null==e.assetId)return console.warn("Can't use mesh as particle without asset id"),new n;const o=await t.getMesh(e.assetId),l=await t.getAsset(e.assetId),c=ge(e);if("shaderGraph"===c||"shader"===c||"material"===c){let n;"shaderGraph"===c?n=await we(e,"surface",a,r,s):"shader"===c&&null!=e.shader?n=await ye(e,t,s):"material"===c&&null!=e.material&&(n=Ae(await t.getMaterial(e.material))),n.transparent&&(n.depthWrite=!1),be(n,e),o.traverse(e=>{e instanceof i.Mesh&&null!=n&&(e.material=n)})}else{const e=[];if(null!=l.materialAssignments)for(const a of l.materialAssignments)o.traverse(r=>{r instanceof i.Mesh&&r.material instanceof i.Material&&r.material.color instanceof i.Color&&(r.material.name!=a.name&&null!=a.name||"#"+r.material.color.getHexString()!==a.color||e.push(t.getMaterial(a.materialId).then(e=>r.material=e)))});await Promise.all(e)}const p=[];if(o.traverse(e=>{e instanceof i.Mesh&&p.push(e)}),Ee(o,e),1===p.length){const e=p[0];return e.updateWorldMatrix(!0,!0),e.updateMatrixWorld(),e.matrix.copy(e.matrixWorld),e.matrixWorld.decompose(e.position,e.quaternion,e.scale),e.removeFromParent(),e}return o}(e.output,t,r,p,T));break;case"trail":{const s="shaderGraph"===ge(e.output)?await we(e.output,"trail",r,p,T,{trailBillboard:e.output.billboard??!1}):null;W=new a({type:"trail",taper:e.output.taper,headGeometry:null,material:s instanceof i.ShaderMaterial?s:void 0,dragTexture:!1,texture:null!=e.output.texture?await t.getTexture(e.output.texture):null,opacityChannel:e.output.opacityChannel,color:e.output.color,colorEnd:e.output.colorEnd,intensity:e.output.intensity??1,intensityEnd:e.output.intensityEnd??1,length:e.output.length,opacityStart:e.output.opacityStart,opacityEnd:e.output.opacityEnd,bloom:e.output.bloom,scrollSpeed:e.output.scrollSpeed,width:e.output.width,billboard:e.output.billboard??!1,renderOrder:e.output.renderOrder});break}default:console.error("Failed to create particly system body: "+JSON.stringify(e))}const O=new Me(F);O.parent=x,O.setRate(V),O._space=e.output.space;const J=await Promise.all(e.initializers.filter(e=>!1!==e.enabled).filter(e=>null!=se[e.type]).map(async e=>{const t=se[e.type],a=await Q(e.params??{});return de(t,e.params??{},a,D)}));"world"!==e.output.space||"shape"!==e.output.type&&"mesh"!==e.output.type||J.unshift(new Z),J.push(W,new Y),O.addInitializers(J);const N=await Promise.all(e.behaviours.filter(e=>!1!==e.enabled).filter(e=>null!=re[e.type]).map(async e=>{const t=re[e.type];for(const[a,r]of Object.entries(e.params))t.parameters&&null!=t.parameters[a]&&"curve"===t.parameters[a].type&&r.type!==H.Curve&&(r.type=H.Curve);const a=await Q(e.params??{},r,p);return ue(t,e.params??{},a,D)}).sort((e,t)=>e instanceof ne?1:0));N.push(new ve);for(const e of N)e instanceof ne&&(e.physics=I);O.addBehaviours(N);for(const a of e.children??[]){const e=await me(a,t,r,p,x,I,T,D,F),s=new EmitterPool(()=>{const t=e.clone();return t.onExpired=()=>{const e=O.childEmitters.findIndex(e=>e.id===t.id);-1!=e&&O.childEmitters.splice(e,1),null!=t.parentParticle&&(n.delete(t.parentParticle.id),t.parentParticle=null),s.release(t)},t}),i=O.eventDispatcher,n=new Map;O.bindEmitterEvent=!0,i.addEventListener("PARTICLE_DEAD",e=>{const t=n.get(e.id);null!=t&&(O.detachChildEmitterFromParticle(t,e),n.delete(e.id))});let o="PARTICLE_CREATED";if("spawnEvent"in a)switch(a.spawnEvent){case"collision":o="PARTICLE_COLLISION";break;case"start":o="PARTICLE_CREATED"}i.addEventListener(o,e=>{const t=s.get();t.age=0,t.totalEmitTimes=-1,t.particles.length=0,t.currentEmitTime=0,t.cID=0,t.eventDispatcher.removeAllEventListeners(),O.childEmitters.push(t),n.set(e.id,t),t.parentParticle=e,t.system=O.system,t.emit()})}return O}const fe=(new i.TextureLoader).load("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJkSURBVHjaxJeJbusgEEW94S1L//83X18M2MSuLd2pbqc4wZGqRLrKBsyZhQHny7Jk73xVL8xpVhWrcmiB5lX+6GJ5YgQ2owbAm8oIwH1VgKZUmGcRqKGGPgtEQQAzGR8hQ59fAmhJHSAagigJ4E7GPWRXOYC6owAd1JM6wDQPADyMWUqZRMqmAojHp1Vn6EQQEgUNMJLnUjMyJsM49wygBkAPw9dVFwXRkncCIIW3GRgoTQUZn6HxCMAFEFd8TwEQ78X4rHbILoAUmeT+RFG4UhQ6MiIAE4W/UsYFjuVjAIa2nIY4q1R0GFtQWG3E84lqw2GO2QOoCKBVu0BAPgDSU0eUDjjQenNkV/AW/pWChhpMTelo1a64AOKM30vk18GzTHXCNtI/Knz3DFBgsUqBGIjTInXRY1yA9xkVoqW5tVq3pDR9A0hfF5BSARmVnh7RMDCaIdcNgbPBkgzn1Bu+SfIEFSpSBmkxyrMicb0fAEuCZrWnN89veA/4XcakrPcjBWzkTuLjlbfTQPOlBhz+HwkqqPXmPQDdrQItxE1moGof1S74j/8txk8EHhTQrAE8qlwfqS5yukm1x/rAJ9Jiaa6nyATqD78aUVBhFo8b1V4DdTXdCW+IxA1zB4JhiOhZMEWO1HqnvdoHZ4FAMIhV9REF8FiUm0jsYPEJx/Fm/N8OhH90HI9YRHesWbXXZwAShU8qThe7H8YAuJmw5yOd989uRINKRTJAhoF8jbqrHKfeCYdIISZfSq26bk/K+yO3YvfKrVgiwQBHnwt8ynPB25+M8hceTt/ybPhnryJ78+tLgAEAuCFyiQgQB30AAAAASUVORK5CYII=");async function ye(e,t,a){const r=a.get(e.shader);if(null==r)return console.error("No shader exists with name "+e.shader),new i.Material;const s=new r.type,n=await W(e.shaderParams??{},r.type,t,{getTexture:e=>t.getTexture(e.id),getMaterial:e=>t.getMaterial(e.id),getMesh:e=>t.getMesh(e.id)},void 0,void 0,void 0,void 0,void 0,s);return Object.assign(s,n),s.build()}async function we(e,t,a,r,s,i={}){const n=e.shaderGraph;if("asset"!==n?.source||null==n.assetId)return console.warn(`Missing shader graph asset reference for ${e.type} VFX output`),null;const o=await a.getAsset(n.assetId),l=o?.shaderGraph;if(null==l)return console.warn(`Missing shader graph asset "${n.assetId}" for ${e.type} VFX output`),null;if(l.target!==t)return console.warn(`Shader graph "${o.name}" targets "${l.target}" but ${e.type} VFX output expects "${t}"`),null;try{const t=await O(e.shaderGraphParams??{},l,a,r,void 0,s.shaders),o=he(l,{parameters:t,trailBillboard:i.trailBillboard});return o.userData.customShaderName=`shaderGraph:${n.assetId}`,be(o,e),o}catch(e){return console.log("Shader graph VFX runtime error: "+e,e),null}}function ge(e){return null!=e.materialSource?e.materialSource:"asset"===e.shaderGraph?.source?"shaderGraph":"shader"in e&&null!=e.shader?"shader":"mesh"!==e.type&&"shape"!==e.type||null==e.material?"default":"material"}function be(e,t){null!=e&&("bloom"in t&&!0===t.bloom&&(e.userData.hasBloom=!0),"sprite"===t.type?(e.blending=ae[t.blendingMode]??i.NormalBlending,!0===t.lockY&&e instanceof i.ShaderMaterial&&(e.defines??(e.defines={}),e.defines.LOCK_Y_AXIS="")):"decal"===t.type?(e.blending=ae[t.blendingMode]??i.NormalBlending,e.transparent=!0,e.side=i.BackSide,e.depthTest=!1,e instanceof i.ShaderMaterial&&(e.defines??(e.defines={}),e.defines.IS_PARTICLE="")):"shape"!==t.type&&"mesh"!==t.type||e instanceof i.ShaderMaterial&&(e.defines??(e.defines={}),e.defines.IS_PARTICLE=""))}function Ee(e,t){const a=t.renderOrder;null!=a&&e.traverse(e=>e.renderOrder=a)}function Ae(e){const t=k(new h("instanceColor")).rgb;let a,r=k(new o("particleData")).x;if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshBasicMaterial){let s=t.multiply(I(e.color));null!=e.map&&(s=s.multiply(C(e.map).sample(j.uv).rgb)),null!=e.alphaMap&&(r=r.multiply(C(e.alphaMap).sample(j.uv).r)),e instanceof i.MeshStandardMaterial?a=new c({color:T({color:s,emissive:I(e.emissive),emissiveIntensity:b(e.emissiveIntensity),roughness:e.roughness,metalness:e.metalness}).rgb.rgba(r),emissive:I(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}):e instanceof i.MeshLambertMaterial?a=new c({color:E({color:s}).rgb.rgba(r),emissive:I(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}):e instanceof i.MeshBasicMaterial&&(a=new c({color:s.rgb.rgba(r),emissive:s.rgb,transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}))}else e instanceof c&&(a=e.clone(),a.defines.IS_PARTICLE="");return null!=a&&(!0===e.userData?.hasBloom&&null!=a&&(a.userData.hasBloom=!0),a.side=e.side,a.transparent=e.transparent),a??e}class ve extends t{initialize(e){e.body instanceof i.Object3D&&e.body.traverse(e=>{if(e instanceof i.Mesh){const t=e.material;t instanceof c&&(null!=t.uniforms[J]||null!=t.uniforms[N]||t.uniforms[_])}})}mutate(e,t,a){this.energize(e,t),e.target instanceof n&&e.target.traverse(t=>{if(t instanceof i.Mesh){const a=t.material;a instanceof c&&(null!=a.uniforms[J]&&(a.uniforms[J].value=this.energy),null!=a.uniforms[N]&&(a.uniforms[N].value=e.age),null!=a.uniforms[_]&&(a.uniforms[_].value=e.velocity))}})}}class Me extends r{constructor(e){super(),this.transformRoot=e,this.childEmitters=[],this.bindEmitterEvent=!1,this.onExpired=()=>{}}clearParticlesRecursive(){let e=this.childEmitters.length;for(;e--;){const t=this.childEmitters[e];t.stopEmit(),t.clearParticlesRecursive(),t.onExpired()}this.childEmitters.length=0;let t=this.particles.length;for(;t--;){const e=this.particles[t];this.system?.dispatch("PARTICLE_DEAD",e),this.bindEmitterEvent&&this.dispatch("PARTICLE_DEAD",e),null!=this.system?this.system.pool.expire(e.reset()):e.reset()}this.particles.length=0}detachChildEmitterFromParticle(e,t){this.copyPositionToChildSpace(e,t.position),e.parentParticle=null,e.stopEmit()}update(e){if(!this.isEmitting&&0===this.particles.length&&0===this.childEmitters.length)return;this.age+=e,(this.dead||this.age>=this.life)&&this.destroy(),this.isEmitting&&this.generate(e),this.integrate(e);let t=this.particles.length;for(;t--;){const e=this.particles[t];e.dead&&(this.system&&this.system.dispatch("PARTICLE_DEAD",e),this.bindEmitterEvent&&this.dispatch("PARTICLE_DEAD",e),this.system.pool.expire(e.reset()),this.particles.splice(t,1))}this.updateEmitterBehaviours(e),this.updateChildren(e),this.isEmitting||0!==this.particles.length||0!==this.childEmitters.length||this.onExpired()}updateChildren(e){for(const t of this.childEmitters)null!=t.parentParticle&&this.copyPositionToChildSpace(t,t.parentParticle.position),t.update(e)}copyPositionToChildSpace(e,t){const a=this._space??"world",r=e._space??"world";a!==r&&null!=this.transformRoot?(xe.copy(t),"local"===a&&"world"===r?xe.applyMatrix4(this.transformRoot.matrixWorld):"world"===a&&"local"===r&&(Ie.copy(this.transformRoot.matrixWorld).invert(),xe.applyMatrix4(Ie)),e.position.copy(xe)):e.position.copy(t)}clone(){const e=new Me(this.transformRoot);return e.setRate(this.rate.clone()),e.behaviours=this.behaviours,e.initializers=this.initializers,e._space=this._space,e.body=this.body,e.parent=this.parent,e.system=this.system,e}setParentRecursive(e){this.system=e,this.childEmitters.forEach(t=>t.setParentRecursive(e))}}const xe=new i.Vector3,Ie=new i.Matrix4;export class EmitterPool{constructor(e){this.creator=e,this.instances=[]}get(){0==this.instances.length&&this.instances.push(this.creator());return this.instances.pop()}release(e){this.instances.push(e)}dispose(){this.instances.length=0}}/*
|
|
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{CustomRenderer as e,MeshRenderer as t,PUID as r}from"@hology/nebula";import*as a from"three";import{InstancedBufferAttribute as o,Object3D as i}from"three";import{NodeShaderMaterial as n}from"three-shader-graph";import{StretchedSprite as s}from"./stretched-sprite.js";import{Trail as l}from"./trail-renderer.js";import{SpriteNodeShaderMaterial as c}from"../../shader/sprite-shader";import{particleEnergyUniformName as d}from"../../shader-nodes/particle";import{AssetMeshInstance as m}from"../../scene/asset-resource-loader.js";var u;!function(e){e[e.mesh=0]="mesh",e[e.instanced=1]="instanced",e[e.sprite=2]="sprite",e[e.stretchedBillboard=3]="stretchedBillboard",e[e.trail=4]="trail"}(u||(u={}));export class MultiRenderer extends e{constructor(e,t,r,a){super(),this.worldContainer=e,this.localContainer=t,this.three=r,this.view=a,this.localRenderers=[],this.worldRenderers=[]}onSystemUpdate(){for(const e of this.worldRenderers)e?.onSystemUpdate();for(const e of this.localRenderers)e?.onSystemUpdate()}onParticleCreated(e){e.target=null,this.getRenderer(e)?.onParticleCreated(e)}onParticleUpdate(e){this.getRenderer(e)?.onParticleUpdate(e)}onParticleDead(e){this.getRenderer(e)?.onParticleDead(e),e._renderer=null}getRenderer(e){if(e._renderer)return e._renderer;const t=(null!=e?.parent?e?.parent._space:null)??"world",r="world"===t?this.worldContainer:this.localContainer,o="world"===t?this.worldRenderers:this.localRenderers;return"trail"===e.body.type?(null==o[u.trail]&&(o[u.trail]=new TrailRenderer(r,this.three)),e._renderer=o[u.trail]):e.body instanceof s?(null==o[u.stretchedBillboard]&&(o[u.stretchedBillboard]=new StretchedSpriteInstancedRenderer(r,this.three,this.view)),e._renderer=o[u.stretchedBillboard]):e.body instanceof a.Sprite||e.body instanceof a.Mesh&&"sprite"===e.body.name?(null==o[u.sprite]&&(o[u.sprite]=new CombinedRenderer(r,this.three)),e._renderer=o[u.sprite]):e.body instanceof a.Mesh&&0==e.body.children.length&&e.body.material instanceof n?(null==o[u.instanced]&&(o[u.instanced]=new InstancedRenderer(r,this.three,this.view)),e._renderer=o[u.instanced]):e.body instanceof a.Object3D?(null==o[u.mesh]&&(o[u.mesh]=new CombinedRenderer(r,this.three)),e._renderer=o[u.mesh]):void 0}dispose(){this.localRenderers.forEach(e=>{e instanceof InstancedRenderer&&e.dispose()}),this.worldRenderers.forEach(e=>{e instanceof InstancedRenderer&&e.dispose()})}}export class TrailRenderer extends t{constructor(){super(...arguments),this.trails=[]}dispose(){}onSystemUpdate(){for(const e of this.trails)e.update()}onParticleCreated(e){const t=e.body,r=new l(this.container,!1),o=new i;this.container.add(o),o.updateMatrixWorld(),o.updateWorldMatrix(!0,!0);const n=t.material?.clone()??l.createBaseMaterial(t.texture,t.scrollSpeed,t.opacityChannel,t.billboard??!1);n.uniforms.taper&&(n.uniforms.taper.value=t.taper??!1);const s=new a.Color(t.color??0).multiplyScalar(t.intensity),c=new a.Color(t.colorEnd??0).multiplyScalar(t.intensityEnd??t.intensity??1);n.uniforms.headColor&&n.uniforms.tailColor&&(n.uniforms.headColor.value=new a.Vector4(s.r,s.g,s.b,t.opacityStart??1),n.uniforms.tailColor.value=new a.Vector4(c.r,c.g,c.b,t.opacityEnd??1)),n.uniforms.color&&null==n.uniforms.headColor&&(n.uniforms.color.value=s),n.uniforms.opacity&&null==n.uniforms.headColor&&(n.uniforms.opacity.value=t.opacityStart??1),t.bloom&&(n.userData.hasBloom=!0),r.initialize(n,Math.round(t.length??10),!1,t.width,null,o,t.billboard??!1),null!=t.renderOrder&&null!=r.mesh&&(r.mesh.renderOrder=t.renderOrder);const d=e.rotation;o.rotation.set(d.x,d.y,d.z);e.scale;r.activate(),this.trails.push(r),e.target=o}onParticleUpdate(e){const t=e.target;t.position.copy(e.position);const r=e.body;let a=U;e.old&&e.old.position?a.set(e.position.x-e.old.position.x,e.position.y-e.old.position.y,e.position.z-e.old.position.z).normalize():a.copy(e.velocity).normalize();const o=A;o.setFromUnitVectors(a,x),t.rotation.set(0,0,0),t.rotation.set(e.rotation.x,e.rotation.y,e.rotation.z),t.applyQuaternion(o);const i=this.trails.findIndex(e=>e.targetObject.id===t.id);if(-1!=i){const t=this.trails[i];if(e.useAlpha){if(t.material.uniforms.headColor&&t.material.uniforms.tailColor){t.material.uniforms.headColor.value.setW(r.opacityStart*e.alpha);t.material.uniforms.tailColor.value.setW(r.opacityEnd*e.alpha)}null!=t.material.uniforms.opacity&&(t.material.uniforms.opacity.value=e.alpha)}e.useColor&&null!=t.material.uniforms.color&&t.material.uniforms.color.value.copy(e.color),null!=t.material.uniforms[d]&&(t.material.uniforms[d].value=e.energy)}}onParticleDead(e){const t=e.target,r=this.trails.findIndex(e=>e.targetObject.id===t.id);if(-1!=r){const e=this.trails[r];e.removeFromParent(),e.mesh.removeFromParent(),e.targetObject.removeFromParent(),t.removeFromParent(),this.trails.splice(r,1)}}}export class CombinedRenderer extends t{dispose(){}scale(e){const t=e.transform.initialScale;e.target instanceof a.Sprite?null!=t?e.target.scale.set(t.x*e.scale*e.radius,t.y*e.scale*e.radius,1):e.target.scale.set(e.scale*e.radius,e.scale*e.radius,1):null!=t?e.target.scale.set(t.x*e.scale,t.y*e.scale,t.z*e.scale):super.scale(e)}rotate(e){e.target.material.rotation=e.rotation.z}onParticleCreated(e){e.target||(e.target=this._targetPool.get(e.body),(e.useAlpha||e.useColor)&&(e.target instanceof a.Mesh||e.target instanceof a.Sprite&&e.target.material instanceof a.Material)&&(e.target.material.__puid=r.id(e.body.material),e.target.material=this._materialPool.get(e.target.material))),e.target&&e.target instanceof i&&(e.target.position.set(e.position.x,e.position.y,e.position.z),this.container.add(e.target))}onParticleUpdate(e){const{target:t,useAlpha:r,useColor:o,rotation:n}=e;if(t){if(t.position.copy(e.position),this.isThreeSprite(e)||(t instanceof a.Mesh&&t.material instanceof c?e.target.material.rotation=e.rotation.z:t.rotation.set(n.x,n.y,n.z)),this.scale(e),e.transform&&e.transform.orientAlongVelocity&&t instanceof i){const r=p.set(e.velocity.x,e.velocity.y,e.velocity.z).normalize(),a=t.getWorldDirection(h);a.applyAxisAngle(g,Math.PI/-2),f.setFromUnitVectors(a,r),t.quaternion.copy(f)}(r||o)&&this.applyUniforms(t,e)}}applyUniforms(e,t){e instanceof m&&e.traverse(r=>r!==e&&this.applyUniforms(r,t)),e instanceof a.Mesh&&(t.useAlpha&&(e.material instanceof c&&null!=e.material.uniforms.opacity&&(e.material.uniforms.opacity.value=t.alpha),e.material instanceof a.ShaderMaterial&&null!=e.material.uniforms.opacity?e.material.uniforms.opacity.value=t.alpha:e.material.opacity=t.alpha,e.material.transparent=!0),t.useColor&&(null!=e.material.color?e.material.color.copy(t.color):e.material instanceof a.ShaderMaterial&&null!=e.material.uniforms.color&&(e.material.uniforms.color.value=t.color)))}onParticleDead(e){e.target&&(e.target.material&&(e.useAlpha||e.useColor)&&this._materialPool.expire(e.target.material),this._targetPool.expire(e.target),this.container.remove(e.target),e.target=null)}}export class StretchedSpriteInstancedRenderer extends t{constructor(e,t,r){super(e,t),this.view=r,this.meshes=[]}dispose(){this.meshes.forEach(e=>e.mesh.geometry.dispose())}onSystemUpdate(){for(const e of this.meshes){const t=e.mesh.geometry.getAttribute("offset"),r=e.mesh.geometry.getAttribute("size"),o=e.mesh.geometry.getAttribute("velocity"),i=e.mesh.geometry.getAttribute("rotation"),n=e.mesh.geometry.getAttribute("color");let s=0;for(const l of e.particles){if(null==l||l.dead)continue;if(l.useColor||l.color instanceof a.Color){const e=P.copy(l.color).getRGB(v);n.setXYZW(s,e.r,e.g,e.b,1),n.needsUpdate=!0}l.useAlpha&&(n.setW(s,l.alpha),n.needsUpdate=!0),"number"==typeof l.rotation?i.setX(s,l.rotation):i.setX(s,l.rotation.x);const e=l.position;if(t.setXYZ(s,e.x,e.y,e.z),"number"!=typeof l.scale)throw new Error("Particle scale is not a number");r.setXYZ(s,l.scale,l.scale,l.scale);let c=l.body.scaleFactor;0===c&&(c=.001);const d=1,m=l.velocity;o.setXYZW(s,m.x*c,m.y*c,m.z*c,d),s++}s>0&&(t.clearUpdateRanges(),t.addUpdateRange(0,3*s),t.needsUpdate=!0,r.clearUpdateRanges(),r.addUpdateRange(0,3*s),r.needsUpdate=!0,n.clearUpdateRanges(),n.addUpdateRange(0,4*s),n.needsUpdate=!0,o.clearUpdateRanges(),o.addUpdateRange(0,4*s),o.needsUpdate=!0,i.clearUpdateRanges(),i.addUpdateRange(0,s),i.needsUpdate=!0)}}calcMaxCount(e){if(null==e)return 1;const t=e.parent.rate,r=t.timePan.a;if(!Number.isFinite(r)||r<=0)return t.numPan.b*this.calcMaxCount(e.parent.parentParticle);return Math.min(t.numPan.b*Math.ceil(e.life/Math.min(Math.max(t.timePan.a,.01),1)),1e5)*this.calcMaxCount(e.parent.parentParticle)}onParticleCreated(e){if(e.body instanceof s&&null==e.target){const t=e.body;let r=this.meshes.find(e=>e.mesh.material.uuid===t.material.uuid);if(null==r){const i=this.calcMaxCount(e),n=new a.InstancedBufferGeometry;n.setIndex(t.geometry.getIndex()),n.setAttribute("position",t.geometry.getAttribute("position")),t.geometry.hasAttribute("normal")&&n.setAttribute("normal",t.geometry.getAttribute("normal")),n.setAttribute("uv",t.geometry.getAttribute("uv"));const s=new o(new Float32Array(3*i),3);s.setUsage(a.DynamicDrawUsage),n.setAttribute("offset",s);const l=new o(new Float32Array(4*i),4);if(l.setUsage(a.DynamicDrawUsage),n.setAttribute("color",l),t.material instanceof c){const e=new a.Color(t.material.color);for(let t=0;t<l.count;t++)l.setXYZW(t,e.r,e.g,e.b,1)}const d=new o(new Float32Array(3*i),3);d.setUsage(a.DynamicDrawUsage),n.setAttribute("size",d);const m=new o(new Float32Array(4*i),4);m.setUsage(a.DynamicDrawUsage),n.setAttribute("velocity",m);const u=new o(new Float32Array(4*i),1);u.setUsage(a.DynamicDrawUsage),n.setAttribute("rotation",u),r={mesh:new a.Mesh(n,t.material),indices:new Float32Array(i),particles:[]},r.mesh.renderOrder=t.renderOrder,this.meshes.push(r),this.container.add(r.mesh)}let i=r.indices.findIndex(e=>0===e);i<0&&(i=function(e){let t=e[0],r=0;for(let a=1;a<e.length;a++)e[a]<t&&(t=e[a],r=a);return r}(r.indices)),r.indices[i]=performance.now(),e.target=i,r.particles[i]=e}}onParticleUpdate(e){}onParticleDead(e){const t=e.body;let r=this.meshes.find(e=>e.mesh.material.uuid===t.material.uuid);if(r){const t=r.mesh.geometry.getAttribute("size");t.setXYZ(e.target,0,0,0),t.needsUpdate=!0,r.particles[e.target]=null,r.indices[e.target]=0}e.target=null}}const p=new a.Vector3,h=new a.Vector3,f=new a.Quaternion,g=new a.Vector3(1,0,0);export class InstancedRenderer extends t{constructor(e,t,r){super(e,t),this.view=r,this.meshes=[]}dispose(){this.meshes.forEach(e=>e.mesh.dispose())}onSystemUpdate(){for(const e of this.meshes);}calcMaxCount(e){if(null==e)return 1;const t=e.parent.rate,r=t.timePan.a;if(!Number.isFinite(r)||r<=0)return t.numPan.b*this.calcMaxCount(e.parent.parentParticle);return Math.min(t.numPan.b*Math.ceil(e.life/Math.min(Math.max(t.timePan.a,.01),1)),1e5)*this.calcMaxCount(e.parent.parentParticle)}onParticleCreated(e){if(e.body instanceof a.Sprite)return;const t=e.body;let r=this.meshes.find(e=>e.mesh.geometry.uuid===t.geometry.uuid&&e.mesh.material.uuid===t.material.uuid);if(null==r){const o=this.calcMaxCount(e);r={mesh:new a.InstancedMesh(t.geometry,t.material,o),indices:new Array(o).fill(null),particles:[]},r.mesh.renderOrder=t.renderOrder,r.mesh.setColorAt(0,P.setScalar(1)),r.mesh.instanceColor.needsUpdate=!0,r.mesh.material.defines.USE_INSTANCING="";const i=new Float32Array(3*o);w.makeScale(0,0,0);for(let e=0;e<o;e++)i[3*e+0]=1,i[3*e+1]=1,r.mesh.setMatrixAt(e,w);r.mesh.instanceMatrix.needsUpdate=!0,r.mesh.geometry.setAttribute("particleData",new a.InstancedBufferAttribute(i,3)),this.meshes.push(r),this.container.add(r.mesh)}let o=r.indices.findIndex(e=>null==e);if(o<0&&(o=r.indices.indexOf(Math.min(...r.indices))),r.indices[o]=performance.now(),e.target=o,r.particles[o]=e,"number"==typeof e.target){e.transform.initialScale;const t=e.body;let r=this.meshes.find(e=>e.mesh.geometry.uuid===t.geometry.uuid&&e.mesh.material.uuid===t.material.uuid);b(e,r.mesh),e.useAlpha&&(r.mesh.material.transparent=!0)}}onParticleUpdate(e){const{target:t,useAlpha:r,useColor:a,rotation:o}=e;if(null==t)return;const i=e.body,n=this.meshes.find(e=>e.mesh.geometry.uuid===i.geometry.uuid&&e.mesh.material.uuid===i.material.uuid);if(null==n)return;n.mesh.frustumCulled=!1,b(e,n.mesh),a&&(n.mesh.setColorAt(e.target,P.copy(e.color)),n.mesh.instanceColor.needsUpdate=!0);const s=n.mesh.geometry.getAttribute("particleData");r&&s.setX(e.target,e.alpha),s.setY(e.target,e.energy),s.needsUpdate=!0}onParticleDead(e){if(null!=e.target){const t=e.body,r=this.meshes.find(e=>e.mesh.geometry.uuid===t.geometry.uuid&&e.mesh.material.uuid===t.material.uuid);if(null==r)return;r.indices[e.target]=null,e.scale=0,b(e,r.mesh),r.mesh.instanceMatrix.needsUpdate=!0,e.target=null}}}const y=new i;function b(e,t){if(U.set(e.position.x,e.position.y,e.position.z),e.transform&&e.transform.orientAlongVelocity){const r=p.set(e.position.x-e.old.position.x,e.position.y-e.old.position.y,e.position.z-e.old.position.z).normalize();t.getMatrixAt(e.target,y.matrix);const a=y.getWorldDirection(C);a.applyAxisAngle(g,Math.PI/-2),A.setFromUnitVectors(a,r)}else M.set(e.rotation.x,e.rotation.y,e.rotation.z),A.setFromEuler(M);const r=e.transform.initialScale;null!=r?C.set(r.x*e.scale,r.y*e.scale,r.z*e.scale):C.set(e.scale,e.scale,e.scale),w.compose(U,A,C),t.setMatrixAt(e.target,w),t.instanceMatrix.needsUpdate=!0}const x=new a.Vector3(0,0,-1),w=new a.Matrix4,A=new a.Quaternion,U=new a.Vector3,C=new a.Vector3,M=new a.Euler,P=new a.Color(0),v={r:0,g:0,b:0};function R(e,t){const r=e.mesh,o=r.count,i=[],n=r.geometry.getAttribute("particleData"),s=new a.Vector3;for(let l=0;l<o;l++){const o=new a.Matrix4,c=new a.Color;r.getMatrixAt(l,o),r.getColorAt(l,c);const d=n.getX(l);s.setFromMatrixPosition(o);const m=s.distanceTo(t.position);i.push({index:l,distance:m,matrix:o,particle:e.particles[l],color:c,pdx:d})}i.sort((e,t)=>t.distance-e.distance);for(let e=0;e<o;e++){const t=i[e].matrix;null==i[e].particle&&t.makeScale(0,0,0),r.setMatrixAt(e,t),r.setColorAt(e,i[e].color),n.setX(e,i[e].pdx)}r.instanceMatrix.needsUpdate=!0}export{R as sortInstancedMeshByDistance};/*
|
|
1
|
+
import{CustomRenderer as e,MeshRenderer as t,PUID as r}from"@hology/nebula";import*as a from"three";import{InstancedBufferAttribute as i,Object3D as o}from"three";import{NodeShaderMaterial as n}from"three-shader-graph";import{StretchedSprite as s}from"./stretched-sprite.js";import{Trail as l}from"./trail-renderer.js";import{SpriteNodeShaderMaterial as c}from"../../shader/sprite-shader";import{particleEnergyUniformName as d}from"../../shader-nodes/particle";import{AssetMeshInstance as m}from"../../scene/asset-resource-loader.js";var u;!function(e){e[e.mesh=0]="mesh",e[e.instanced=1]="instanced",e[e.sprite=2]="sprite",e[e.stretchedBillboard=3]="stretchedBillboard",e[e.trail=4]="trail"}(u||(u={}));export class MultiRenderer extends e{constructor(e,t,r,a){super(),this.worldContainer=e,this.localContainer=t,this.three=r,this.view=a,this.localRenderers=[],this.worldRenderers=[]}onSystemUpdate(){for(const e of this.worldRenderers)e?.onSystemUpdate();for(const e of this.localRenderers)e?.onSystemUpdate()}onParticleCreated(e){e.target=null,this.getRenderer(e)?.onParticleCreated(e)}onParticleUpdate(e){this.getRenderer(e)?.onParticleUpdate(e)}onParticleDead(e){this.getRenderer(e)?.onParticleDead(e),e._renderer=null}getRenderer(e){if(e._renderer)return e._renderer;const t=(null!=e?.parent?e?.parent._space:null)??"world",r="world"===t?this.worldContainer:this.localContainer,i="world"===t?this.worldRenderers:this.localRenderers;return"trail"===e.body.type?(null==i[u.trail]&&(i[u.trail]=new TrailRenderer(r,this.three)),e._renderer=i[u.trail]):e.body instanceof s?(null==i[u.stretchedBillboard]&&(i[u.stretchedBillboard]=new StretchedSpriteInstancedRenderer(r,this.three,this.view)),e._renderer=i[u.stretchedBillboard]):e.body instanceof a.Sprite||e.body instanceof a.Mesh&&"sprite"===e.body.name?(null==i[u.sprite]&&(i[u.sprite]=new CombinedRenderer(r,this.three)),e._renderer=i[u.sprite]):e.body instanceof a.Mesh&&0==e.body.children.length&&e.body.material instanceof n?(null==i[u.instanced]&&(i[u.instanced]=new InstancedRenderer(r,this.three,this.view)),e._renderer=i[u.instanced]):e.body instanceof a.Object3D?(null==i[u.mesh]&&(i[u.mesh]=new CombinedRenderer(r,this.three)),e._renderer=i[u.mesh]):void 0}dispose(){this.localRenderers.forEach(e=>{e instanceof InstancedRenderer&&e.dispose()}),this.worldRenderers.forEach(e=>{e instanceof InstancedRenderer&&e.dispose()})}}export class TrailRenderer extends t{constructor(){super(...arguments),this.trails=[]}dispose(){}onSystemUpdate(){for(const e of this.trails)e.update()}onParticleCreated(e){const t=e.body,r=new l(this.container,!1),i=new o;this.container.add(i),i.updateMatrixWorld(),i.updateWorldMatrix(!0,!0);const n=t.material?.clone()??l.createBaseMaterial(t.texture,t.scrollSpeed,t.opacityChannel,t.billboard??!1);n.uniforms.taper&&(n.uniforms.taper.value=t.taper??!1);const s=new a.Color(t.color??0).multiplyScalar(t.intensity??1),c=new a.Color(t.colorEnd??0).multiplyScalar(t.intensityEnd??t.intensity??1);n.uniforms.headColor&&n.uniforms.tailColor&&(n.uniforms.headColor.value=new a.Vector4(s.r,s.g,s.b,t.opacityStart??1),n.uniforms.tailColor.value=new a.Vector4(c.r,c.g,c.b,t.opacityEnd??1)),n.uniforms.color&&null==n.uniforms.headColor&&(n.uniforms.color.value=s),n.uniforms.opacity&&null==n.uniforms.headColor&&(n.uniforms.opacity.value=t.opacityStart??1),t.bloom&&(n.userData.hasBloom=!0),r.initialize(n,Math.round(t.length??10),!1,t.width,null,i,t.billboard??!1),null!=t.renderOrder&&null!=r.mesh&&(r.mesh.renderOrder=t.renderOrder);const d=e.rotation;i.rotation.set(d.x,d.y,d.z);e.scale;r.activate(),this.trails.push(r),e.target=i}onParticleUpdate(e){const t=e.target;t.position.copy(e.position);const r=e.body;let a=U;e.old&&e.old.position?a.set(e.position.x-e.old.position.x,e.position.y-e.old.position.y,e.position.z-e.old.position.z):a.copy(e.velocity),a.lengthSq()>1e-8?a.normalize():a.copy(w);const i=C;i.setFromUnitVectors(a,w),t.rotation.set(0,0,0),t.rotation.set(e.rotation.x,e.rotation.y,e.rotation.z),t.applyQuaternion(i);const o=this.trails.findIndex(e=>e.targetObject.id===t.id);if(-1!=o){const t=this.trails[o];if(e.useAlpha){if(t.material.uniforms.headColor&&t.material.uniforms.tailColor){t.material.uniforms.headColor.value.setW((r.opacityStart??1)*e.alpha);t.material.uniforms.tailColor.value.setW((r.opacityEnd??1)*e.alpha)}null!=t.material.uniforms.opacity&&(t.material.uniforms.opacity.value=e.alpha)}e.useColor&&null!=t.material.uniforms.color&&t.material.uniforms.color.value.copy(e.color),null!=t.material.uniforms[d]&&(t.material.uniforms[d].value=e.energy)}}onParticleDead(e){const t=e.target,r=this.trails.findIndex(e=>e.targetObject.id===t.id);if(-1!=r){const e=this.trails[r];e.removeFromParent(),e.mesh.removeFromParent(),e.targetObject.removeFromParent(),t.removeFromParent(),this.trails.splice(r,1)}}}export class CombinedRenderer extends t{dispose(){}scale(e){const t=e.transform.initialScale;e.target instanceof a.Sprite?null!=t?e.target.scale.set(t.x*e.scale*e.radius,t.y*e.scale*e.radius,1):e.target.scale.set(e.scale*e.radius,e.scale*e.radius,1):null!=t?e.target.scale.set(t.x*e.scale,t.y*e.scale,t.z*e.scale):super.scale(e)}rotate(e){e.target.material.rotation=e.rotation.z}onParticleCreated(e){e.target||(e.target=this._targetPool.get(e.body),(e.useAlpha||e.useColor)&&(e.target instanceof a.Mesh||e.target instanceof a.Sprite&&e.target.material instanceof a.Material)&&(e.target.material.__puid=r.id(e.body.material),e.target.material=this._materialPool.get(e.target.material))),e.target&&e.target instanceof o&&(e.target.position.set(e.position.x,e.position.y,e.position.z),this.container.add(e.target))}onParticleUpdate(e){const{target:t,useAlpha:r,useColor:i,rotation:n}=e;if(t){if(t.position.copy(e.position),this.isThreeSprite(e)||(t instanceof a.Mesh&&t.material instanceof c?e.target.material.rotation=e.rotation.z:t.rotation.set(n.x,n.y,n.z)),this.scale(e),e.transform&&e.transform.orientAlongVelocity&&t instanceof o){const r=h.set(e.velocity.x,e.velocity.y,e.velocity.z).normalize(),a=t.getWorldDirection(p);a.applyAxisAngle(g,Math.PI/-2),f.setFromUnitVectors(a,r),t.quaternion.copy(f)}(r||i)&&this.applyUniforms(t,e)}}applyUniforms(e,t){e instanceof m&&e.traverse(r=>r!==e&&this.applyUniforms(r,t)),e instanceof a.Mesh&&(t.useAlpha&&(e.material instanceof c&&null!=e.material.uniforms.opacity&&(e.material.uniforms.opacity.value=t.alpha),e.material instanceof a.ShaderMaterial&&null!=e.material.uniforms.opacity?e.material.uniforms.opacity.value=t.alpha:e.material.opacity=t.alpha,e.material.transparent=!0),t.useColor&&(null!=e.material.color?e.material.color.copy(t.color):e.material instanceof a.ShaderMaterial&&null!=e.material.uniforms.color&&(e.material.uniforms.color.value=t.color)))}onParticleDead(e){e.target&&(e.target.material&&(e.useAlpha||e.useColor)&&this._materialPool.expire(e.target.material),this._targetPool.expire(e.target),this.container.remove(e.target),e.target=null)}}export class StretchedSpriteInstancedRenderer extends t{constructor(e,t,r){super(e,t),this.view=r,this.meshes=[]}dispose(){this.meshes.forEach(e=>e.mesh.geometry.dispose())}onSystemUpdate(){for(const e of this.meshes){const t=e.mesh.geometry.getAttribute("offset"),r=e.mesh.geometry.getAttribute("size"),i=e.mesh.geometry.getAttribute("velocity"),o=e.mesh.geometry.getAttribute("rotation"),n=e.mesh.geometry.getAttribute("particleColor");let s=0;for(const l of e.particles){if(null==l||l.dead)continue;if(l.useColor||l.color instanceof a.Color){const e=P.copy(l.color).getRGB(v);n.setXYZW(s,e.r,e.g,e.b,1),n.needsUpdate=!0}l.useAlpha&&(n.setW(s,l.alpha),n.needsUpdate=!0),"number"==typeof l.rotation?o.setX(s,l.rotation):o.setX(s,l.rotation.x);const e=l.position;if(t.setXYZ(s,e.x,e.y,e.z),"number"!=typeof l.scale)throw new Error("Particle scale is not a number");r.setXYZ(s,l.scale,l.scale,l.scale);let c=l.body.scaleFactor;0===c&&(c=.001);const d=1,m=l.velocity;i.setXYZW(s,m.x*c,m.y*c,m.z*c,d),s++}s>0&&(t.clearUpdateRanges(),t.addUpdateRange(0,3*s),t.needsUpdate=!0,r.clearUpdateRanges(),r.addUpdateRange(0,3*s),r.needsUpdate=!0,n.clearUpdateRanges(),n.addUpdateRange(0,4*s),n.needsUpdate=!0,i.clearUpdateRanges(),i.addUpdateRange(0,4*s),i.needsUpdate=!0,o.clearUpdateRanges(),o.addUpdateRange(0,s),o.needsUpdate=!0)}}calcMaxCount(e){if(null==e)return 1;const t=e.parent.rate,r=t.timePan.a;if(!Number.isFinite(r)||r<=0)return t.numPan.b*this.calcMaxCount(e.parent.parentParticle);return Math.min(t.numPan.b*Math.ceil(e.life/Math.min(Math.max(t.timePan.a,.01),1)),1e5)*this.calcMaxCount(e.parent.parentParticle)}onParticleCreated(e){if(e.body instanceof s&&null==e.target){const t=e.body;let r=this.meshes.find(e=>e.mesh.material.uuid===t.material.uuid);if(null==r){const o=this.calcMaxCount(e),n=new a.InstancedBufferGeometry;n.setIndex(t.geometry.getIndex()),n.setAttribute("position",t.geometry.getAttribute("position")),t.geometry.hasAttribute("normal")&&n.setAttribute("normal",t.geometry.getAttribute("normal")),n.setAttribute("uv",t.geometry.getAttribute("uv"));const s=new i(new Float32Array(3*o),3);s.setUsage(a.DynamicDrawUsage),n.setAttribute("offset",s);const l=new i(new Float32Array(4*o),4);if(l.setUsage(a.DynamicDrawUsage),n.setAttribute("particleColor",l),t.material instanceof c){const e=new a.Color(t.material.color);for(let t=0;t<l.count;t++)l.setXYZW(t,e.r,e.g,e.b,1)}const d=new i(new Float32Array(3*o),3);d.setUsage(a.DynamicDrawUsage),n.setAttribute("size",d);const m=new i(new Float32Array(4*o),4);m.setUsage(a.DynamicDrawUsage),n.setAttribute("velocity",m);const u=new i(new Float32Array(4*o),1);u.setUsage(a.DynamicDrawUsage),n.setAttribute("rotation",u),r={mesh:new a.Mesh(n,t.material),indices:new Float32Array(o),particles:[]},r.mesh.renderOrder=t.renderOrder,this.meshes.push(r),this.container.add(r.mesh)}let o=r.indices.findIndex(e=>0===e);o<0&&(o=function(e){let t=e[0],r=0;for(let a=1;a<e.length;a++)e[a]<t&&(t=e[a],r=a);return r}(r.indices)),r.indices[o]=performance.now(),e.target=o,r.particles[o]=e}}onParticleUpdate(e){}onParticleDead(e){const t=e.body;let r=this.meshes.find(e=>e.mesh.material.uuid===t.material.uuid);if(r){const t=r.mesh.geometry.getAttribute("size");t.setXYZ(e.target,0,0,0),t.needsUpdate=!0,r.particles[e.target]=null,r.indices[e.target]=0}e.target=null}}const h=new a.Vector3,p=new a.Vector3,f=new a.Quaternion,g=new a.Vector3(1,0,0);export class InstancedRenderer extends t{constructor(e,t,r){super(e,t),this.view=r,this.meshes=[]}dispose(){this.meshes.forEach(e=>e.mesh.dispose())}onSystemUpdate(){for(const e of this.meshes);}calcMaxCount(e){if(null==e)return 1;const t=e.parent.rate,r=t.timePan.a;if(!Number.isFinite(r)||r<=0)return t.numPan.b*this.calcMaxCount(e.parent.parentParticle);return Math.min(t.numPan.b*Math.ceil(e.life/Math.min(Math.max(t.timePan.a,.01),1)),1e5)*this.calcMaxCount(e.parent.parentParticle)}onParticleCreated(e){if(e.body instanceof a.Sprite)return;const t=e.body;let r=this.meshes.find(e=>e.mesh.geometry.uuid===t.geometry.uuid&&e.mesh.material.uuid===t.material.uuid);if(null==r){const i=this.calcMaxCount(e);r={mesh:new a.InstancedMesh(t.geometry,t.material,i),indices:new Array(i).fill(null),particles:[]},r.mesh.renderOrder=t.renderOrder,r.mesh.userData.webGpuCacheMaterial=!0;const o=new Float32Array(4*i);o.fill(1),r.mesh.instanceColor=new a.InstancedBufferAttribute(o,4),r.mesh.setColorAt(0,P.setScalar(1)),r.mesh.instanceColor.needsUpdate=!0,r.mesh.material.defines.USE_INSTANCING="",r.mesh.material.needsUpdate=!0;const n=new Float32Array(3*i);x.makeScale(0,0,0);for(let e=0;e<i;e++)n[3*e+0]=1,n[3*e+1]=1,n[3*e+2]=1,r.mesh.instanceMatrix.array.set(x.elements,16*e);r.mesh.instanceMatrix.needsUpdate=!0,r.mesh.geometry.setAttribute("particleData",new a.InstancedBufferAttribute(n,3)),this.meshes.push(r),this.container.add(r.mesh)}let i=r.indices.findIndex(e=>null==e);if(i<0&&(i=r.indices.indexOf(Math.min(...r.indices))),r.indices[i]=performance.now(),e.target=i,r.particles[i]=e,"number"==typeof e.target){e.transform.initialScale;const t=e.body;let r=this.meshes.find(e=>e.mesh.geometry.uuid===t.geometry.uuid&&e.mesh.material.uuid===t.material.uuid);b(e,r.mesh),e.useAlpha&&(r.mesh.material.transparent||(r.mesh.material.transparent=!0,r.mesh.material.needsUpdate=!0))}}onParticleUpdate(e){const{target:t,useAlpha:r,useColor:a,rotation:i}=e;if(null==t)return;const o=e.body,n=this.meshes.find(e=>e.mesh.geometry.uuid===o.geometry.uuid&&e.mesh.material.uuid===o.material.uuid);if(null==n)return;if(n.mesh.frustumCulled=!1,b(e,n.mesh),a){P.copy(e.color);const t=n.mesh.instanceColor.array,r=e.target*n.mesh.instanceColor.itemSize;t[r+0]=P.r,t[r+1]=P.g,t[r+2]=P.b,n.mesh.instanceColor.itemSize>=4&&(t[r+3]=1),n.mesh.instanceColor.needsUpdate=!0}const s=n.mesh.geometry.getAttribute("particleData");r&&s.setX(e.target,e.alpha),s.setY(e.target,e.energy),s.needsUpdate=!0}onParticleDead(e){if(null!=e.target){const t=e.body,r=this.meshes.find(e=>e.mesh.geometry.uuid===t.geometry.uuid&&e.mesh.material.uuid===t.material.uuid);if(null==r)return;r.indices[e.target]=null,e.scale=0,b(e,r.mesh),r.mesh.instanceMatrix.needsUpdate=!0,e.target=null}}}const y=new o;function b(e,t){if(U.set(e.position.x,e.position.y,e.position.z),e.transform&&e.transform.orientAlongVelocity){const r=h.set(e.position.x-e.old.position.x,e.position.y-e.old.position.y,e.position.z-e.old.position.z).normalize();t.getMatrixAt(e.target,y.matrix);const a=y.getWorldDirection(A);a.applyAxisAngle(g,Math.PI/-2),C.setFromUnitVectors(a,r)}else M.set(e.rotation.x,e.rotation.y,e.rotation.z),C.setFromEuler(M);const r=e.transform.initialScale;null!=r?A.set(r.x*e.scale,r.y*e.scale,r.z*e.scale):A.set(e.scale,e.scale,e.scale),x.compose(U,C,A),t.instanceMatrix.array.set(x.elements,16*e.target),t.instanceMatrix.needsUpdate=!0}const w=new a.Vector3(0,0,-1),x=new a.Matrix4,C=new a.Quaternion,U=new a.Vector3,A=new a.Vector3,M=new a.Euler,P=new a.Color(0),v={r:0,g:0,b:0};function R(e,t){const r=e.mesh,i=r.count,o=[],n=r.geometry.getAttribute("particleData"),s=new a.Vector3;for(let l=0;l<i;l++){const i=new a.Matrix4,c=new a.Color;r.getMatrixAt(l,i),r.getColorAt(l,c);const d=n.getX(l);s.setFromMatrixPosition(i);const m=s.distanceTo(t.position);o.push({index:l,distance:m,matrix:i,particle:e.particles[l],color:c,pdx:d})}o.sort((e,t)=>t.distance-e.distance);for(let e=0;e<i;e++){const t=o[e].matrix;null==o[e].particle&&t.makeScale(0,0,0),r.setMatrixAt(e,t),r.setColorAt(e,o[e].color),n.setX(e,o[e].pdx)}r.instanceMatrix.needsUpdate=!0}export{R as sortInstancedMeshByDistance};/*
|
|
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,__metadata as e}from"tslib";import i from"@dimforge/rapier3d-simd-compat";import{takeUntil as o}from"rxjs";import*as s from"three";import{ArrowHelper as n,MathUtils as r,Quaternion as a,Vector3 as h}from"three";import{RootMotionClip as l}from"../../../../animation/root-motion.js";import{inject as c}from"../../../../inject.js";import{ActionInput as u,AxisInput as d,RotationInput as p}from"../../../../input/index.js";import{NetRole as m}from"../../../../net/service/net-actor-role.js";import{RunOnClient as v,RunOnNotOwner as y,RunOnServer as S}from"../../../../net/service/rpc-decorator.js";import{NetService as g}from"../../../../net/service/net-service.js";import{PhysicsSystem as M,RayTestResult as f}from"../../../../services/physics/physics-system.js";import{CapsuleCollisionShape as x}from"../../../../../scene/collision/collision-shape.js";import{Parameter as T}from"../../../../../shader/parameter.js";import{PhysicsBodyType as C}from"../../../../services/physics/physics-system.js";import{ActorComponent as R,Component as w}from"../../../component.js";import{CharacterMovementMode as A}from"./modes.js";import{DEFAULT_MAX_CLIENT_TIME_AHEAD as q,DEFAULT_LARGE_CORRECTION_THRESHOLD as D,DEFAULT_MAX_COMBINED_MOVE_DELTA_TIME as b,DEFAULT_MAX_MOVE_DELTA_TIME as k,DEFAULT_MAX_MOVES_PER_PACKET as I,DEFAULT_MAX_REPLAYED_MOVES as z,DEFAULT_MAX_SERVER_MOVES_PER_TICK as P,DEFAULT_MAX_SAVED_MOVES as O,DEFAULT_MAX_SERVER_MOVE_DELTA_TIME_SCALAR as j,DEFAULT_MAX_SERVER_MOVE_TIME_BUDGET as G,DEFAULT_MAX_SUBSTEP_DELTA_TIME as Y,DEFAULT_MOVE_SEND_INTERVAL as F,DEFAULT_SIMULATED_INTERPOLATION_DELAY as N,DEFAULT_SIMULATED_STATE_INTERVAL as V,DEFAULT_SMALL_CORRECTION_TOLERANCE as U,DEFAULT_TELEPORT_SNAP_THRESHOLD as X,MOVE_FLAG_CROUCH as E,MOVE_FLAG_JUMP as L,MOVE_FLAG_ROOT_MOTION as B,MOVE_FLAG_SLIDE_START as H,MOVE_FLAG_SPRINT as Z,MOVE_FLAG_SPRINT_START as W,SNAPSHOT_FLAG_CROUCH_SUPPRESSED as $,SNAPSHOT_FLAG_CROUCHING as Q,NetCharacterProxySmoother as J,NetCharacterSavedMoveBuffer as K,accrueNetCharacterServerMoveTime as _,createNetCharacterMovementSnapshot as tt,createNetCharacterServerMoveTimingState as et,consumeNetCharacterServerMoveTime as it,decodeNetCharacterMoveBatch as ot,decodeNetCharacterOwnerAck as st,decodeNetCharacterOwnerCorrection as nt,decodeNetCharacterSimulatedState as rt,encodeNetCharacterMoveBatch as at,encodeNetCharacterOwnerAck as ht,encodeNetCharacterOwnerCorrection as lt,encodeNetCharacterSimulatedState as ct,validateNetCharacterMove as ut}from"./net-character-movement-protocol.js";import{NetMode as dt}from"../../../../net/net-session.js";import{setSlideJumpVelocity as pt,shouldContinueSlide as mt,shouldStartSlide as vt,updateSlideVelocity as yt,updateSlideVelocityFromDisplacement as St}from"./character-slide.js";export*from"./net-character-movement-protocol.js";const gt=131070,Mt=new h(0,1,0),ft=new h,xt=new h,Tt=new h,Ct=new h,Rt=new h,wt=new h,At=new h,qt=new h,Dt=new h,bt=new h,kt=new h,It=new h,zt=new h,Pt=new h,Ot=new h(0,1,0),jt=new h(0,-.05,0),Gt=new h,Yt=new a,Ft=new s.Euler,Nt=new h,Vt=new h,Ut=new h,Xt=new h,Et=new i.CharacterCollision;let Lt=class extends R{get autoStepMinWidth(){return this.cc.autostepMinWidth()}set autoStepMinWidth(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),t,this.cc.autostepIncludesDynamicBodies())}get autoStepDynamicObjects(){return this.cc.autostepIncludesDynamicBodies()}set autoStepDynamicObjects(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),this.cc.autostepMinWidth(),t)}get autoStepMaxHeight(){return this.cc.autostepMaxHeight()}set autoStepMaxHeight(t){this.cc.enableAutostep(t,this.cc.autostepMinWidth(),this.cc.autostepIncludesDynamicBodies())}get snapToGround(){return this.cc.snapToGroundDistance()}set snapToGround(t){this.cc.enableSnapToGround(t)}set offset(t){this.cc.setOffset(t)}get offset(){return this.cc.offset()}set normalNudgeFactor(t){this.cc.setNormalNudgeFactor(t)}get normalNudgeFactor(){return this.cc.normalNudgeFactor()}constructor(){super(),this.isDefaultCharacterMovementComponent=!0,this.directionInput=new d,this.jumpInput=new u,this.sprintInput=new u,this.crouchInput=new u,this.rotationInput=new p,this.horizontalSpeed=0,this.maxSpeed=8,this.maxSpeedBackwards=8,this.maxSpeedSprint=12,this.maxSpeedCrouch=4,this.slideEnabled=!1,this.slideMinStartSpeed=8,this.slideMinExitSpeed=4,this.slideDeceleration=3,this.slideGravityScale=1,this.slideSteeringRate=2,this.sprintStartBoostSpeed=0,this.sprintStartBoostDamping=6,this.jumpVelocity=7,this.fallingMovementControl=.5,this.fallingReorientation=!1,this.groundAccelerationRate=4,this.gravityOverride=null,this.colliderHeight=2,this.colliderRadius=.5,this.crouchColliderHeight=1,this.crouchColliderRadius=null,this.jumpInAir=!1,this.mass=50,this.allowSliding=!0,this.minSlopeSlideAngle=r.degToRad(70),this.maxSlopeClimbAngle=r.degToRad(70),this.applyImpulsesToDynamicBodies=!0,this.normalizedDirection=!0,this.characterCollision=!1,this.allowRootMotionJumpCancel=!1,this.enabled=!0,this.rotateToMovementDirection=!1,this.smoothRotation=!0,this.rotationSpeed=40,this.maxRotationSpeed=100,this.impulseDamping=2,this.moveSendInterval=F,this.simulatedStateInterval=V,this.maxSavedMoves=O,this.maxReplayedMoves=z,this.maxServerMovesPerTick=P,this.maxMovesPerPacket=I,this.maxMoveDeltaTime=k,this.maxCombinedMoveDeltaTime=b,this.maxServerMoveDeltaTimeScalar=j,this.maxClientTimeAhead=q,this.maxServerMoveTimeBudget=G,this.maxSubstepDeltaTime=Y,this.fallGraceTime=.1,this.correctionToleranceSq=U*U,this.largeCorrectionThreshold=D,this.teleportSnapThreshold=X,this.listenServerSmoothing=!0,this.listenServerSmoothLocationTime=.04,this.listenServerMaxSmoothUpdateDistance=1,this.listenServerNoSmoothUpdateDistance=2.5,this.debugCorrections=!0,this.suppressUncrouchLift=!1,this.velocity=new h,this.visualSmoothingOffset=new h,this.slideDirection=new h,this.slideSurfaceNormal=new h(0,1,0),this.mode=A.walking,this.isSprinting=!1,this.isCrouching=!1,this.isSliding=!1,this.pressedJump=!1,this.rayTestResult=new f,this.groundRayTestOptions={debug:!1,excludeTriggers:!0,excludeActor:void 0},this.physicsSystem=c(M),this.netService=c(g),this.state={sequence:0,position:new h,velocity:new h,yaw:0,lookYaw:0,mode:A.walking,grounded:!1,currentSpeed:0,fallGraceTime:0,prevInputDirection:new h,prevRotateToMovementDirection:!1},this.movementModes=new Map,this.savedMoves=new K(O),this.serverMoveTiming=et(),this.serverMoveQueue=[],this.inputMoveScratch={sequence:0,clientTime:0,dt:0,inputX:0,inputY:0,yaw:0,flags:0,clientX:0,clientY:0,clientZ:0,rootMotionX:0,rootMotionY:0,rootMotionZ:0},this.authoritativeMoveScratch={sequence:0,clientTime:0,dt:0,inputX:0,inputY:0,yaw:0,flags:0,clientX:0,clientY:0,clientZ:0,rootMotionX:0,rootMotionY:0,rootMotionZ:0},this.movementModeContext={component:this,state:this.state,move:this.inputMoveScratch,deltaTime:0,rotatedDirection:xt,platformVelocity:Ct,outVelocity:Tt,rootMotionActive:!1,startedSprinting:!1},this.proxySmoother=new J(N,X),this.proxySample=tt(),this.pendingSnapshot=tt(),this.impulse=new h,this.prevRootMotionPos=new h,this.rootMotionOptions={},this.resetRootMotion=!1,this.nextMoveSequence=0,this.clientMoveTime=0,this.lastSentClientMoveTime=0,this.moveSendAccumulator=0,this.simulatedStateAccumulator=0,this.proxyTime=0,this.lastServerProcessedSequence=0,this.lastServerReceivedSequence=0,this.lastAutonomousMoveFlags=0,this.previousSprintInput=!1,this.previousCrouchInput=!1,this.crouchSuppressedUntilRelease=!1,this.slideOnLandingRequested=!1,this.initialized=!1,this.cc=this.physicsSystem.getCharacterController(.1),this.cc.enableSnapToGround(.1),this.cc.enableAutostep(0,.1,!1),this.registerMovementMode(Bt),this.registerMovementMode(Ht),this.registerMovementMode({mode:A.sliding,update:t=>this.updateSlidingMode(t)})}onInit(){this.groundRayTestOptions.excludeActor=this.actor,this.configureCharacterController(),this.physicsSystem.addActor(this.actor,[this.createCollisionShape()],{mass:0,type:C.kinematic,continousCollisionDetection:!1,friction:0,restitution:.5,ignoreForNavMesh:!0}),this.rotationInput.rotation.copy(this.actor.rotation),this.initializeStateFromActor(),this.initialized=!0,this.physicsSystem.beforeStep.pipe(o(this.disposed)).subscribe(t=>this.tick(t))}onLateUpdate(t){this.updateVisualSmoothing(t)}registerMovementMode(t){this.movementModes.set(t.mode,t)}applyImpulse(t){this.impulse.add(t)}getEffectiveGravity(){return this.gravityOverride??this.physicsSystem.getGravity().y}get isGrounded(){return this.rayTestResult.hasHit||this.cc.computedGrounded()}setRootMotionAction(t,e={}){const i=t?.getClip();if(i instanceof l){this.rootMotionAction=t,this.rootMotionOptions=e,this.resetRootMotion=!0;const o=[];this.rootMotionInterpolant=i.motionTrack.InterpolantFactoryMethodSmooth(o);const n=s.PropertyBinding.parseTrackName(i.motionTrack.name);this.rootMotionRootBone=this.actor.object.getObjectByName(n.nodeName)}}serverMove(t){const e=ot(t);if(e.ok)for(const t of e.value.moves)ut(t,this.lastServerReceivedSequence,this.maxMoveDeltaTime)&&(this.lastServerReceivedSequence=t.sequence,this.serverMoveQueue.push(t))}clientMoveAck(t){const e=st(t);e.ok&&this.actor.netRole===m.autonomousProxy&&(this.savedMoves.ack(e.value.sequence),this.sprintPolicy?.ack?.(e.value.sequence,!1))}clientMoveCorrection(t){const e=nt(t);e.ok&&this.actor.netRole===m.autonomousProxy&&(this.debugCorrections&&(null==this.correctionDebug&&(this.correctionDebug=new Qt(Kt(this.actor.object))),this.correctionDebug.update(this.state.position,e.value.snapshot)),this.applyCorrection(e.value.snapshot))}simulatedState(t){const e=rt(t);e.ok&&this.actor.netRole===m.simulatedProxy&&this.proxySmoother.push(e.value,this.proxyTime)}tick(t){if(!this.initialized)return;t=Math.min(.1,t);const e=this.actor.netRole,i=this.netService.mode;e!==m.simulatedProxy?this.enabled&&(e!==m.autonomousProxy?this.isRemoteControlledAuthority(i,e)?this.tickRemoteAuthority(t):this.tickAuthority(t,i):this.tickAutonomousProxy(t)):this.tickSimulatedProxy(t)}tickAutonomousProxy(t){const e=this.state.mode,i=this.lastAutonomousMoveFlags,o=this.createMoveFromInput(t,++this.nextMoveSequence,{quantizeClientTime:!0});this.performMove(o,_t),this.resetToggleCrouchAfterSlide(e);const s=this.state.mode!==e||o.flags!==i;this.lastAutonomousMoveFlags=o.flags,this.savedMoves.capacity=this.maxSavedMoves,this.savedMoves.maxCombinedDeltaTime=Math.min(this.maxCombinedMoveDeltaTime,this.maxMoveDeltaTime),this.savedMoves.push(o),this.sendSavedMoves(t,s)}tickAuthority(t,e){const i=this.state.mode,o=this.createMoveFromInput(t,++this.nextMoveSequence);this.performMove(o,_t),this.resetToggleCrouchAfterSlide(i),e!==dt.none&&this.sendSimulatedState(t,!1)}resetToggleCrouchAfterSlide(t){t===A.sliding&&this.state.mode!==A.sliding&&"toggle"===this.crouchInput.mode&&this.crouchInput.activated&&this.crouchInput.setActivated(!1)}tickRemoteAuthority(t){_(this.serverMoveTiming,t,this.maxServerMoveTimeBudget);let e=!1;const i=Number.isFinite(this.maxServerMovesPerTick)?Math.max(1,Math.floor(this.maxServerMovesPerTick)):this.serverMoveQueue.length,o=Math.min(this.serverMoveQueue.length,i),s=Ut.copy(this.actor.position);let n=!1;for(let t=0;t<o;t++){const t=this.serverMoveQueue.shift();if(null==t)break;if(!ut(t,this.lastServerProcessedSequence,this.maxMoveDeltaTime)){console.log("Net: Invalid move",t),this.sendOwnerCorrection(!0),e=!0;continue}const i=it(this.serverMoveTiming,t,{maxMoveDeltaTime:this.maxMoveDeltaTime,maxServerMoveDeltaTimeScalar:this.maxServerMoveDeltaTimeScalar,maxClientTimeAhead:this.maxClientTimeAhead});if(i<0){this.sendOwnerCorrection(!0),e=!0;continue}const o=Wt(t,this.authoritativeMoveScratch);o.dt=i,o.rootMotionX=0,o.rootMotionY=0,o.rootMotionZ=0,o.flags&=~B,this.performMove(o,{immediate:!0,savedRootMotion:!1}),n=!0,this.lastServerProcessedSequence=o.sequence;const s=$t(this.state,t);if(s>this.correctionToleranceSq){console.log(`Net server: Correction error: ${Math.sqrt(s)}`);const o=this.state.position.x-t.clientX,n=this.state.position.y-t.clientY,r=this.state.position.z-t.clientZ;console.log(`diff x: ${o}, y: ${n}, z: ${r}`),console.log({sequence:t.sequence,moveDt:t.dt,serverMoveDeltaTime:i,flags:t.flags,mode:this.state.mode,grounded:this.state.grounded,fallGraceTime:this.state.fallGraceTime}),this.sendOwnerCorrection(s>this.largeCorrectionThreshold*this.largeCorrectionThreshold),e=!0}}0===this.lastServerProcessedSequence||e||(this.sprintPolicy?.ack?.(this.lastServerProcessedSequence,!1),this.clientMoveAck(ht(this.lastServerProcessedSequence))),n&&this.accumulateListenServerVisualSmoothing(s,this.actor.position),this.sendSimulatedState(t,!1)}tickSimulatedProxy(t){this.proxyTime+=t,this.proxySmoother.sample(this.proxyTime,this.proxySample)&&this.applySnapshot(this.proxySample,!0)}accumulateListenServerVisualSmoothing(t,e){if(!this.shouldSmoothListenServerRemoteAuthority())return void this.visualSmoothingOffset.set(0,0,0);Xt.subVectors(t,e);const i=Xt.lengthSq();i>1e-8&&(i>this.listenServerNoSmoothUpdateDistance*this.listenServerNoSmoothUpdateDistance?this.visualSmoothingOffset.set(0,0,0):(i>this.listenServerMaxSmoothUpdateDistance*this.listenServerMaxSmoothUpdateDistance&&Xt.setLength(this.listenServerMaxSmoothUpdateDistance),this.visualSmoothingOffset.add(Xt)))}updateVisualSmoothing(t){if(this.visualSmoothingOffset.lengthSq()<=1e-8)return void this.visualSmoothingOffset.set(0,0,0);if(!this.shouldSmoothListenServerRemoteAuthority())return void this.visualSmoothingOffset.set(0,0,0);const e=Math.max(.001,this.listenServerSmoothLocationTime);t<e?this.visualSmoothingOffset.multiplyScalar(1-t/e):this.visualSmoothingOffset.set(0,0,0),this.visualSmoothingOffset.lengthSq()<=1e-4&&this.visualSmoothingOffset.set(0,0,0)}shouldSmoothListenServerRemoteAuthority(){return this.listenServerSmoothing&&this.actor.netRole===m.authority&&this.netService.isServer&&!this.netService.isDedicatedServer&&this.isRemoteControlledAuthority()}createMoveFromInput(t,e,i={}){const o=r.clamp(t,.001,this.maxMoveDeltaTime);this.clientMoveTime+=o;let s=this.clientMoveTime,n=o;!0===i.quantizeClientTime&&(s=Math.max(this.lastSentClientMoveTime+.001,Math.round(1e3*this.clientMoveTime)/1e3),n=r.clamp(s-this.lastSentClientMoveTime,.001,this.maxMoveDeltaTime),this.lastSentClientMoveTime=s),this.sampleRootMotion(At);const a=this.crouchInput.activated,h=a&&!this.previousCrouchInput;this.previousCrouchInput=a;const l=!a&&this.sprintInput.activated,c=l&&!this.previousSprintInput;this.previousSprintInput=l;const u=(this.jumpInput.activated?L:0)|(l?Z:0)|(a?E:0)|(h&&this.slideEnabled?H:0)|(c?W:0)|(At.lengthSq()>0?B:0),d=function(t,e){e.set(t.x,0,t.y),e.lengthSq()>1&&e.normalize();return e}(this.directionInput.vector,Nt),p=this.inputMoveScratch;return p.sequence=e>>>0,p.clientTime=s,p.dt=n,p.inputX=d.x,p.inputY=d.z,p.yaw=this.rotationInput.rotation.y,p.flags=u,p.clientX=this.state.position.x,p.clientY=this.state.position.y,p.clientZ=this.state.position.z,p.rootMotionX=At.x,p.rootMotionY=At.y,p.rootMotionZ=At.z,p}performMove(t,e){const i=r.clamp(t.dt,.001,this.maxMoveDeltaTime),o=Math.max(1,Math.ceil(i/this.maxSubstepDeltaTime)),s=0!==(t.flags&Z)&&0===(t.flags&E);this.sprintPolicy?.update?.(i,t.sequence,s),It.set(e.savedRootMotion?t.rootMotionX:0,e.savedRootMotion?t.rootMotionY:0,e.savedRootMotion?t.rootMotionZ:0),e.savedRootMotion||this.sampleRootMotion(It);let n=i;const a=i/o;for(let s=0;s<o;s++){const o=i>0?a/i:1;this.performSubstep(t,Math.min(a,n),It,o,e.immediate,0===s),n-=a}t.clientX=this.state.position.x,t.clientY=this.state.position.y,t.clientZ=this.state.position.z,t.flags=It.lengthSq()>0?t.flags|B:t.flags&~B,this.state.sequence=t.sequence,this.syncPublicState()}performSubstep(t,e,i,o,s,n){if(e<.001)return;this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded;const r=null!=this.rootMotionAction&&this.rootMotionAction.enabled,a=i.lengthSq()>0,h=!r&&0!==(t.flags&L),l=r||a;this.updateCrouchState(t,n,l,h),this.pressedJump=h,this.isSprinting=!1,this.updateRotation(t,e,r,a),this.resolvePlatformVelocity(Ct);const c=this.movementModeContext,u=this.movementModes.get(this.state.mode);if(null!=u){c.move=t,c.deltaTime=e,c.rootMotionActive=l,c.startedSprinting=n&&!l&&0===(t.flags&E)&&0!==(t.flags&W);const i=u.update(c);"number"==typeof i&&(this.state.mode=i)}else Tt.set(0,0,0);if(a){qt.copy(i).multiplyScalar(o).applyQuaternion(this.actor.quaternion),Dt.copy(qt).divideScalar(e),this.state.mode===A.walking?(Tt.x=Dt.x+Ct.x,Tt.z=Dt.z+Ct.z):(Tt.x=Dt.x,Tt.z=Dt.z);const t=Math.sqrt(Dt.x*Dt.x+Dt.z*Dt.z);t>.4&&(this.state.currentSpeed=t)}if(this.applyImpulseToVelocity(Tt,e),h&&this.isSprinting){const t=Math.max(0,this.maxSpeedSprint),e=Zt(Tt);if(e>t){const i=t/e;Tt.x*=i,Tt.z*=i,this.state.velocity.x*=i,this.state.velocity.z*=i}}this.state.mode===A.walking&&this.state.velocity.copy(Tt),this.applyMovement(Tt,e,s),this.state.mode===A.sliding&&(St(this.state.velocity,wt,Ct,this.slideSurfaceNormal,e),this.state.currentSpeed=Zt(this.state.velocity)),this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded,this.updateModeAfterMove(Tt,e),this.state.mode===A.sliding&&this.state.velocity.length()<Math.max(0,this.slideMinExitSpeed)&&(this.state.mode=A.walking)}updateRotation(t,e,i,o){ft.set(-t.inputX,0,t.inputY),ft.lengthSq()>1&&ft.normalize();const s=this.state.prevRotateToMovementDirection!==this.rotateToMovementDirection;let n=r.euclideanModulo(t.yaw-this.state.lookYaw+Math.PI,2*Math.PI)-Math.PI;if(s&&(this.actor.object.quaternion.setFromEuler(Ft.set(0,t.yaw,0)),this.state.prevRotateToMovementDirection||(n=0,this.state.lookYaw=t.yaw),this.state.prevRotateToMovementDirection=this.rotateToMovementDirection),xt.set(0,0,0),i)this.state.lookYaw=t.yaw;else if(this.rotateToMovementDirection){if(ft.lengthSq()>0&&this.state.mode!==A.falling){const i=Ft.setFromQuaternion(this.actor.object.quaternion,"YXZ").y,o=Math.atan2(ft.x,ft.z),s=.99*t.yaw+o;if(this.smoothRotation){const t=r.euclideanModulo(s-i+Math.PI,2*Math.PI)-Math.PI;let o=r.clamp(t*this.rotationSpeed*e,-this.maxRotationSpeed*e,this.maxRotationSpeed*e);Math.abs(o)>Math.abs(t)&&(o=t),this.actor.object.quaternion.setFromEuler(Ft.set(0,i+o,0))}else this.actor.object.quaternion.setFromEuler(Ft.set(0,s,0));this.state.prevInputDirection.lerp(ft,e*this.rotationSpeed),this.state.lookYaw+=n,xt.copy(this.actor.object.getWorldDirection(Nt).normalize())}}else o||(this.state.lookYaw+=n,this.actor.object.quaternion.multiply(Yt.setFromEuler(Ft.set(0,n,0))),ft.lengthSq()>0&&xt.copy(ft).applyQuaternion(this.actor.object.quaternion).normalize())}applyMovement(t,e,i){if(t.lengthSq()>0||!this.state.grounded){if(Rt.copy(t).multiplyScalar(e),this.state.grounded&&((o=this.state.mode)===A.walking||o===A.sliding)&&(this.state.mode===A.walking&&this.rayTestResult.distance<=this.cc.offset()&&(Rt.y=Math.max(0,Ct.y*e)),this.physicsSystem.getActorComputedMovement(this.actor,this.cc,Rt,this.getCollisionGroup()),this.cc.computedCollision(0,Et),null!=Et.normal1)){const t=Nt.copy(Et.normal1);Math.acos(r.clamp(t.dot(Mt),-1,1))>this.cc.maxSlopeClimbAngle()&&(Rt.y=.016*this.getEffectiveGravity()*.5)}wt.copy(this.physicsSystem.getActorComputedMovement(this.actor,this.cc,Rt,this.getCollisionGroup()))}else wt.set(0,0,0);var o;this.suppressUncrouchLift&&(this.suppressUncrouchLift=!1,this.state.grounded&&this.state.mode===A.walking&&Rt.y<=1e-6&&wt.y>0&&(wt.y=0)),this.state.position.add(wt),i?(this.actor.position.copy(this.state.position),this.physicsSystem.updateActorTransform(this.actor),this.physicsSystem.flushModifiedBodyPositionsToColliders()):this.physicsSystem.setNextKinematicPosition(this.actor,this.state.position)}updateModeAfterMove(t,e){const i=function(t){if(0===t.numComputedCollisions())return!1;const e=t.computedCollision(0);Gt.set(e.normal2.x,e.normal2.y,e.normal2.z);const i=Gt.angleTo(Mt);Gt.set(e.normal1.x,e.normal1.y,e.normal1.z);const o=Gt.angleTo(Mt);if(i<100)return!1;return o>t.minSlopeSlideAngle()}(this.cc);!this.state.grounded||i?this.state.mode!==A.falling&&(this.state.fallGraceTime+=e,this.state.fallGraceTime>this.fallGraceTime+1e-6&&(this.state.mode=A.falling,this.state.velocity.copy(t))):this.state.velocity.y<=0&&(this.state.mode===A.falling&&(this.state.mode=A.walking),this.state.mode!==A.sliding&&(this.state.velocity.y=0),this.state.fallGraceTime=0)}applyImpulseToVelocity(t,e){if(this.impulse.lengthSq()<=.1)return void this.impulse.set(0,0,0);const i=Math.min(1,this.impulse.length()/5);t.x=r.lerp(t.x,this.impulse.x,i),t.z=r.lerp(t.z,this.impulse.z,i),t.y+=this.impulse.y;const o=Math.exp(-this.impulseDamping*e);this.impulse.x*=o,this.impulse.y>0?this.impulse.y+=e*this.getEffectiveGravity():this.impulse.y*=o,this.impulse.z*=o}sendSavedMoves(t,e=!1){if(this.moveSendAccumulator+=t,!e&&this.moveSendAccumulator<this.moveSendInterval)return;this.moveSendAccumulator=0;const i=this.savedMoves.getMovesForSend(this.maxMovesPerPacket);0!==i.length&&this.serverMove(at(i))}sendOwnerCorrection(t){const e=this.toSnapshot(this.pendingSnapshot);t&&(e.horizontalSpeed=this.horizontalSpeed),this.sprintPolicy?.ack?.(e.sequence,!0),this.clientMoveCorrection(lt(e))}sendSimulatedState(t,e){this.simulatedStateAccumulator+=t,!e&&this.simulatedStateAccumulator<this.simulatedStateInterval||(this.simulatedStateAccumulator=0,this.simulatedState(ct(this.toSnapshot(this.pendingSnapshot))))}applyCorrection(t){this.sprintPolicy?.restore?.(t.sequence),this.savedMoves.ack(t.sequence),this.sprintPolicy?.ack?.(t.sequence,!0),this.applySnapshot(t,!0),this.savedMoves.replayAfter(t.sequence,t=>(this.performMove(t,{immediate:!0,savedRootMotion:!0}),null),this.maxReplayedMoves)}applySnapshot(t,e){this.state.sequence=t.sequence,this.state.position.set(t.x,t.y,t.z),this.state.velocity.set(t.velocityX,t.velocityY,t.velocityZ),this.state.yaw=t.yaw,this.state.lookYaw=t.yaw,this.state.mode=t.mode,this.state.currentSpeed=t.horizontalSpeed,this.state.fallGraceTime=0,this.actor.position.copy(this.state.position),this.actor.object.quaternion.setFromEuler(Ft.set(0,t.yaw,0)),this.crouchSuppressedUntilRelease=0!==(t.flags&$),this.setCrouching(0!==(t.flags&Q)||t.mode===A.sliding),e&&(this.physicsSystem.updateActorTransform(this.actor),this.physicsSystem.flushModifiedBodyPositionsToColliders()),this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded,this.syncPublicState()}toSnapshot(t){return t.sequence=this.state.sequence,t.x=this.state.position.x,t.y=this.state.position.y,t.z=this.state.position.z,t.velocityX=this.state.velocity.x,t.velocityY=this.state.velocity.y,t.velocityZ=this.state.velocity.z,t.yaw=Ft.setFromQuaternion(this.actor.object.quaternion,"YXZ").y,t.mode=this.state.mode,t.flags=(this.isCrouching?Q:0)|(this.crouchSuppressedUntilRelease?$:0),t.horizontalSpeed=this.state.currentSpeed,t}syncPublicState(){this.velocity.copy(this.state.velocity),this.mode=this.state.mode,this.horizontalSpeed=this.state.currentSpeed,this.isSliding=this.state.mode===A.sliding,this.isSliding?(this.resolveGroundNormal(this.slideSurfaceNormal),this.slideDirection.copy(this.state.velocity).projectOnPlane(this.slideSurfaceNormal),this.slideDirection.lengthSq()>1e-8?this.slideDirection.normalize():this.slideDirection.set(0,0,0)):(this.slideDirection.set(0,0,0),this.slideSurfaceNormal.copy(Mt))}sampleRootMotion(t){if(t.set(0,0,0),null==this.rootMotionAction||this.rootMotionAction.isRunning()||this.clearRootMotionAction(this.rootMotionAction),null!=this.rootMotionAction&&this.rootMotionOptions.cancelWithJump&&this.jumpInput.activated&&(this.isGrounded||this.jumpInAir)){const e=this.rootMotionAction,i=this.rootMotionOptions.onJumpCancel;return this.clearRootMotionAction(e),e.stop(),i?.(),t}if(null==this.rootMotionAction)return t;if(!(this.rootMotionAction.getClip()instanceof l))return t;const e=this.rootMotionInterpolant;this.resetRootMotion&&(this.prevRootMotionPos.fromArray(e.evaluate(0)),this.resetRootMotion=!1),kt.fromArray(e.evaluate(this.rootMotionAction.time)),t.subVectors(kt,this.prevRootMotionPos),this.prevRootMotionPos.copy(kt);return(this.rootMotionRootBone??this.rootMotionAction.getRoot()).getWorldScale(bt),t.multiply(bt),t}clearRootMotionAction(t){null!=t&&this.rootMotionAction!==t||(this.rootMotionAction=null,this.rootMotionOptions={},this.resetRootMotion=!1)}isRemoteControlledAuthority(t=this.netService.mode,e=this.actor.netRole){if(t===dt.none||e!==m.authority||t>=dt.client)return!1;return null!=this.netService.resolveActorConnection(this.actor)&&!this.netService.isLocalOwner(this.actor)}configureCharacterController(){const t=this.cc;t.setApplyImpulsesToDynamicBodies(this.applyImpulsesToDynamicBodies),t.setMinSlopeSlideAngle(this.minSlopeSlideAngle),t.setMaxSlopeClimbAngle(this.maxSlopeClimbAngle),t.setCharacterMass(this.mass),t.setSlideEnabled(this.allowSliding)}initializeStateFromActor(){this.state.position.copy(this.actor.position),this.state.velocity.set(0,0,0),this.state.yaw=this.actor.rotation.y,this.state.lookYaw=this.rotationInput.rotation.y,this.state.mode=this.mode,this.state.currentSpeed=this.horizontalSpeed,this.state.prevRotateToMovementDirection=this.rotateToMovementDirection}createCollisionShape(){const t=this.getColliderHeight(!1),e=this.getColliderRadius(!1),i=new x(t,e);return i.offset.y=this.getCapsuleOffsetY(t,e),i.collisionGroup=gt,i}updateCrouchState(t,e,i,o){if(!(0!==(t.flags&E)))return this.crouchSuppressedUntilRelease=!1,this.slideOnLandingRequested=!1,this.state.mode===A.sliding&&(this.state.mode=A.walking),void this.tryUncrouch();if(this.state.mode===A.sliding&&(!this.slideEnabled||i))return this.slideOnLandingRequested=!1,this.state.mode=A.walking,void(this.crouchSuppressedUntilRelease||this.setCrouching(!0));if(this.state.mode===A.sliding&&o)return this.crouchSuppressedUntilRelease=!0,this.slideOnLandingRequested=!1,void this.tryUncrouch();if(this.crouchSuppressedUntilRelease)return void(this.slideOnLandingRequested=!1);if(this.setCrouching(!0),!this.slideEnabled||i)return void(this.slideOnLandingRequested=!1);if(this.state.mode===A.falling)return void(this.slideOnLandingRequested=!0);this.resolveGroundNormal(Vt);const s=this.slideOnLandingRequested&&this.state.mode===A.walking&&this.state.grounded,n=e&&0!==(t.flags&H)||s;s&&(this.slideOnLandingRequested=!1);const r=Zt(this.state.velocity);this.state.mode===A.walking&&vt(this.slideEnabled,n,this.state.grounded,this.isWalkableSlideSurface(Vt),i,r,this.slideMinStartSpeed)&&(this.state.mode=A.sliding,this.slideSurfaceNormal.copy(Vt),this.state.velocity.projectOnPlane(this.slideSurfaceNormal),this.state.currentSpeed=Zt(this.state.velocity))}updateSlidingMode(t){const e=t.state,i=t.move;this.resolveGroundNormal(this.slideSurfaceNormal);const o=this.isWalkableSlideSurface(this.slideSurfaceNormal),s=e.velocity.length();if(!e.grounded||!o)return e.mode=A.falling,Ht.update(t),A.falling;if(this.slideEnabled&&0!==(i.flags&E)&&!t.rootMotionActive&&0!==(i.flags&L))return pt(t.outVelocity,e.velocity,this.jumpVelocity),e.velocity.copy(t.outVelocity),e.currentSpeed=Zt(e.velocity),A.falling;if(!mt(this.slideEnabled,0!==(i.flags&E),e.grounded,o,t.rootMotionActive,s,this.slideMinExitSpeed))return e.mode=A.walking,Bt.update(t),A.walking;const n=yt(e.velocity,e.velocity,this.slideSurfaceNormal,t.rotatedDirection,this.getEffectiveGravity(),t.deltaTime,this.slideDeceleration,this.slideGravityScale,this.slideSteeringRate);if(e.currentSpeed=Zt(e.velocity),n<Math.max(0,this.slideMinExitSpeed))return e.mode=A.walking,Bt.update(t),A.walking;t.outVelocity.copy(e.velocity).add(t.platformVelocity)}tryUncrouch(){this.isCrouching&&this.canUncrouch()&&this.setCrouching(!1)&&(this.suppressUncrouchLift=!0,this.state.fallGraceTime=0)}resolveGroundNormal(t){return!this.rayTestResult.hasHit||this.rayTestResult.hitNormal.lengthSq()<=1e-8?t.copy(Mt):(t.copy(this.rayTestResult.hitNormal).normalize(),t.dot(Mt)<0&&t.multiplyScalar(-1),t)}isWalkableSlideSurface(t){return t.dot(Mt)>=Math.cos(this.cc.maxSlopeClimbAngle())}setCrouching(t){return this.isCrouching!==t&&(this.isCrouching=t,this.syncColliderShape(),!0)}canUncrouch(){const t=this.getColliderHeight(!1),e=this.getColliderRadius(!1);return!this.physicsSystem.hasActorCapsuleIntersection(this.actor,this.state.position,t,e,this.getCapsuleOffsetY(t,e),this.getCollisionGroup())}syncColliderShape(){const t=this.getColliderHeight(this.isCrouching),e=this.getColliderRadius(this.isCrouching);this.physicsSystem.setActorCapsuleCollider(this.actor,t,e,this.getCapsuleOffsetY(t,e))}getColliderHeight(t){const e=Number.isFinite(this.colliderHeight)?Math.max(0,this.colliderHeight):0;if(!t)return e;const i=Number.isFinite(this.crouchColliderHeight)?this.crouchColliderHeight:e;return r.clamp(i,0,e)}getColliderRadius(t){const e=Number.isFinite(this.colliderRadius)?Math.max(.001,this.colliderRadius):.001;if(!t)return e;const i=this.crouchColliderRadius??e,o=Number.isFinite(i)?i:e;return r.clamp(o,.001,e)}getCapsuleOffsetY(t,e){return e+t/2+this.offset}checkGrounded(t){jt.y=-Math.max(.05,this.cc.snapToGroundDistance()),this.physicsSystem.rayTest(zt.addVectors(t,Ot.set(0,this.offset,0)),Pt.addVectors(t,jt),this.rayTestResult,this.groundRayTestOptions)}resolvePlatformVelocity(t){return t.set(0,0,0),this.rayTestResult.hasHit&&null!=this.rayTestResult.actor&&this.physicsSystem.getLinearVelocity(this.rayTestResult.actor,t),t}getCollisionGroup(){return this.characterCollision?null:gt}};t([T(),e("design:type",Object)],Lt.prototype,"colliderHeight",void 0),t([T(),e("design:type",Object)],Lt.prototype,"colliderRadius",void 0),t([T(),e("design:type",Object)],Lt.prototype,"crouchColliderHeight",void 0),t([T(),e("design:type",Number)],Lt.prototype,"crouchColliderRadius",void 0),t([S(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"serverMove",null),t([v(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"clientMoveAck",null),t([v(!0),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"clientMoveCorrection",null),t([y(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"simulatedState",null),Lt=t([w({inEditor:!1}),e("design:paramtypes",[])],Lt);export{Lt as CharacterMovementComponent};const Bt={mode:A.walking,update(t){const e=t.component,i=t.move,o=t.state,s=t.rotatedDirection,n=Math.min(1,Math.sqrt(i.inputX*i.inputX+i.inputY*i.inputY)),r=!e.rotateToMovementDirection&&i.inputY<0,a=e.isCrouching,h=!t.rootMotionActive&&!a&&0===(i.flags&E)&&0!==(i.flags&Z)&&!r&&0!==s.lengthSq()&&(e.sprintPolicy?.canSprint()??!0),l=(a?e.maxSpeedCrouch:r?e.maxSpeedBackwards:h?e.maxSpeedSprint:e.maxSpeed)*(e.normalizedDirection?1:n);if(0!==s.lengthSq()){e.isSprinting=h,h&&e.sprintPolicy?.commitSprint(t.deltaTime,i.sequence);let a=Math.min(l,o.currentSpeed),c=e.groundAccelerationRate;if(h&&t.startedSprinting&&e.sprintStartBoostSpeed>0){const t=e.normalizedDirection?1:n;a=Math.max(a,l+e.sprintStartBoostSpeed*t),c=e.sprintStartBoostDamping}else h&&!r&&e.sprintStartBoostSpeed>0&&o.currentSpeed>l&&(a=o.currentSpeed,c=e.sprintStartBoostDamping);o.currentSpeed=function(t,e,i,o){return e+(t-e)*Math.exp(-i*o)}(a,l,c,t.deltaTime),t.outVelocity.copy(s).multiplyScalar(function(t,e,i,o){const s=i*o;if(s<=1e-6)return t;return e+(t-e)*(1-Math.exp(-s))/s}(a,l,c,t.deltaTime))}else o.currentSpeed=0,t.outVelocity.set(0,0,0);if(0!==(i.flags&L))return o.mode=A.falling,o.velocity.copy(t.outVelocity),o.velocity.y=e.jumpVelocity,A.falling;t.outVelocity.y=t.deltaTime*e.getEffectiveGravity(),t.outVelocity.add(t.platformVelocity)}},Ht={mode:A.falling,update(t){const e=t.component,i=t.state,o=t.move;0!==(o.flags&L)&&e.jumpInAir&&(i.velocity.copy(t.outVelocity),i.velocity.y=e.jumpVelocity),i.velocity.y+=t.deltaTime*e.getEffectiveGravity(),t.outVelocity.copy(i.velocity),t.outVelocity.addScaledVector(t.rotatedDirection,e.fallingMovementControl),e.fallingReorientation&&t.outVelocity.applyAxisAngle(Mt,r.euclideanModulo(o.yaw-i.lookYaw+Math.PI,2*Math.PI)-Math.PI)}};function Zt(t){return Math.sqrt(t.x*t.x+t.z*t.z)}function Wt(t,e){return e.sequence=t.sequence,e.clientTime=t.clientTime,e.dt=t.dt,e.inputX=t.inputX,e.inputY=t.inputY,e.yaw=t.yaw,e.flags=t.flags,e.clientX=t.clientX,e.clientY=t.clientY,e.clientZ=t.clientZ,e.rootMotionX=t.rootMotionX,e.rootMotionY=t.rootMotionY,e.rootMotionZ=t.rootMotionZ,e}function $t(t,e){const i=t.position.x-e.clientX,o=t.position.y-e.clientY,s=t.position.z-e.clientZ;return i*i+o*o+s*s}class Qt{constructor(t){this.scene=t,this.serverPosition=new h,this.direction=new h}update(t,e){const i=this.serverPosition.set(e.x,e.y,e.z),o=i.distanceTo(t);o>.1&&console.log(`Correction applied. Error: ${o.toFixed(3)}. Server position: (${i.x.toFixed(2)}, ${i.y.toFixed(2)}, ${i.z.toFixed(2)}), Client position: (${t.x.toFixed(2)}, ${t.y.toFixed(2)}, ${t.z.toFixed(2)})`);const s=this.direction.copy(i).sub(t).normalize();Jt.position.copy(t),Jt.setDirection(s),Jt.setLength(o);const n=Kt(this.scene);n.add(Jt),setTimeout(()=>{n.remove(Jt)},1e3)}}const Jt=new n(new h(0,1,0),new h,1,16711680);function Kt(t){return null==t.parent?t:Kt(t.parent)}const _t={immediate:!1,savedRootMotion:!0};/*
|
|
1
|
+
import{__decorate as t,__metadata as e}from"tslib";import i from"@dimforge/rapier3d-simd-compat";import{takeUntil as o}from"rxjs";import*as s from"three";import{ArrowHelper as n,MathUtils as r,Quaternion as a,Vector3 as h}from"three";import{RootMotionClip as l}from"../../../../animation/root-motion.js";import{inject as c}from"../../../../inject.js";import{ActionInput as u,AxisInput as d,RotationInput as p}from"../../../../input/index.js";import{NetRole as m}from"../../../../net/service/net-actor-role.js";import{RunOnClient as v,RunOnNotOwner as y,RunOnServer as S}from"../../../../net/service/rpc-decorator.js";import{NetService as g}from"../../../../net/service/net-service.js";import{PhysicsSystem as M,RayTestResult as f}from"../../../../services/physics/physics-system.js";import{CapsuleCollisionShape as x}from"../../../../../scene/collision/collision-shape.js";import{Parameter as T}from"../../../../../shader/parameter.js";import{PhysicsBodyType as C}from"../../../../services/physics/physics-system.js";import{ActorComponent as R,Component as w}from"../../../component.js";import{CharacterMovementMode as A}from"./modes.js";import{DEFAULT_MAX_CLIENT_TIME_AHEAD as q,DEFAULT_LARGE_CORRECTION_THRESHOLD as D,DEFAULT_MAX_COMBINED_MOVE_DELTA_TIME as b,DEFAULT_MAX_MOVE_DELTA_TIME as k,DEFAULT_MAX_MOVES_PER_PACKET as I,DEFAULT_MAX_REPLAYED_MOVES as z,DEFAULT_MAX_SERVER_MOVES_PER_TICK as P,DEFAULT_MAX_SAVED_MOVES as O,DEFAULT_MAX_SERVER_MOVE_DELTA_TIME_SCALAR as j,DEFAULT_MAX_SERVER_MOVE_TIME_BUDGET as G,DEFAULT_MAX_SUBSTEP_DELTA_TIME as Y,DEFAULT_MOVE_SEND_INTERVAL as F,DEFAULT_SIMULATED_INTERPOLATION_DELAY as N,DEFAULT_SIMULATED_STATE_INTERVAL as V,DEFAULT_SMALL_CORRECTION_TOLERANCE as U,DEFAULT_TELEPORT_SNAP_THRESHOLD as X,MOVE_FLAG_CROUCH as E,MOVE_FLAG_JUMP as L,MOVE_FLAG_ROOT_MOTION as B,MOVE_FLAG_SLIDE_START as H,MOVE_FLAG_SPRINT as Z,MOVE_FLAG_SPRINT_START as W,SNAPSHOT_FLAG_CROUCH_SUPPRESSED as $,SNAPSHOT_FLAG_CROUCHING as Q,NetCharacterProxySmoother as J,NetCharacterSavedMoveBuffer as K,accrueNetCharacterServerMoveTime as _,createNetCharacterMovementSnapshot as tt,createNetCharacterServerMoveTimingState as et,consumeNetCharacterServerMoveTime as it,decodeNetCharacterMoveBatch as ot,decodeNetCharacterOwnerAck as st,decodeNetCharacterOwnerCorrection as nt,decodeNetCharacterSimulatedState as rt,encodeNetCharacterMoveBatch as at,encodeNetCharacterOwnerAck as ht,encodeNetCharacterOwnerCorrection as lt,encodeNetCharacterSimulatedState as ct,validateNetCharacterMove as ut}from"./net-character-movement-protocol.js";import{NetMode as dt}from"../../../../net/net-session.js";import{setSlideJumpVelocity as pt,shouldContinueSlide as mt,shouldStartSlide as vt,updateSlideVelocity as yt,updateSlideVelocityFromDisplacement as St}from"./character-slide.js";export*from"./net-character-movement-protocol.js";const gt=131070,Mt=new h(0,1,0),ft=new h,xt=new h,Tt=new h,Ct=new h,Rt=new h,wt=new h,At=new h,qt=new h,Dt=new h,bt=new h,kt=new h,It=new h,zt=new h,Pt=new h,Ot=new h(0,1,0),jt=new h(0,-.05,0),Gt=new h,Yt=new a,Ft=new s.Euler,Nt=new h,Vt=new h,Ut=new h,Xt=new h,Et=new i.CharacterCollision;let Lt=class extends R{get autoStepMinWidth(){return this.cc.autostepMinWidth()}set autoStepMinWidth(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),t,this.cc.autostepIncludesDynamicBodies())}get autoStepDynamicObjects(){return this.cc.autostepIncludesDynamicBodies()}set autoStepDynamicObjects(t){this.cc.enableAutostep(this.cc.autostepMaxHeight(),this.cc.autostepMinWidth(),t)}get autoStepMaxHeight(){return this.cc.autostepMaxHeight()}set autoStepMaxHeight(t){this.cc.enableAutostep(t,this.cc.autostepMinWidth(),this.cc.autostepIncludesDynamicBodies())}get snapToGround(){return this.cc.snapToGroundDistance()}set snapToGround(t){this.cc.enableSnapToGround(t)}set offset(t){this.cc.setOffset(t)}get offset(){return this.cc.offset()}set normalNudgeFactor(t){this.cc.setNormalNudgeFactor(t)}get normalNudgeFactor(){return this.cc.normalNudgeFactor()}constructor(){super(),this.isDefaultCharacterMovementComponent=!0,this.directionInput=new d,this.jumpInput=new u,this.sprintInput=new u,this.crouchInput=new u,this.rotationInput=new p,this.horizontalSpeed=0,this.maxSpeed=8,this.maxSpeedBackwards=8,this.maxSpeedSprint=12,this.maxSpeedCrouch=4,this.slideEnabled=!1,this.slideMinStartSpeed=8,this.slideMinExitSpeed=4,this.slideDeceleration=3,this.slideGravityScale=1,this.slideSteeringRate=2,this.sprintStartBoostSpeed=0,this.sprintStartBoostDamping=6,this.jumpVelocity=7,this.fallingMovementControl=.5,this.fallingReorientation=!1,this.groundAccelerationRate=4,this.gravityOverride=null,this.colliderHeight=2,this.colliderRadius=.5,this.crouchColliderHeight=1,this.crouchColliderRadius=null,this.jumpInAir=!1,this.mass=50,this.allowSliding=!0,this.minSlopeSlideAngle=r.degToRad(70),this.maxSlopeClimbAngle=r.degToRad(70),this.applyImpulsesToDynamicBodies=!0,this.normalizedDirection=!0,this.characterCollision=!1,this.allowRootMotionJumpCancel=!1,this.enabled=!0,this.rotateToMovementDirection=!1,this.smoothRotation=!0,this.rotationSpeed=40,this.maxRotationSpeed=100,this.impulseDamping=2,this.moveSendInterval=F,this.simulatedStateInterval=V,this.maxSavedMoves=O,this.maxReplayedMoves=z,this.maxServerMovesPerTick=P,this.maxMovesPerPacket=I,this.maxMoveDeltaTime=k,this.maxCombinedMoveDeltaTime=b,this.maxServerMoveDeltaTimeScalar=j,this.maxClientTimeAhead=q,this.maxServerMoveTimeBudget=G,this.maxSubstepDeltaTime=Y,this.fallGraceTime=.1,this.correctionToleranceSq=U*U,this.largeCorrectionThreshold=D,this.teleportSnapThreshold=X,this.listenServerSmoothing=!0,this.listenServerSmoothLocationTime=.04,this.listenServerMaxSmoothUpdateDistance=1,this.listenServerNoSmoothUpdateDistance=2.5,this.debugCorrections=!0,this.suppressUncrouchLift=!1,this.velocity=new h,this.visualSmoothingOffset=new h,this.slideDirection=new h,this.slideSurfaceNormal=new h(0,1,0),this.mode=A.walking,this.isSprinting=!1,this.isCrouching=!1,this.isSliding=!1,this.pressedJump=!1,this.rayTestResult=new f,this.groundRayTestOptions={debug:!1,excludeTriggers:!0,excludeActor:void 0,resolveActor:!1},this.physicsSystem=c(M),this.netService=c(g),this.state={sequence:0,position:new h,velocity:new h,yaw:0,lookYaw:0,mode:A.walking,grounded:!1,currentSpeed:0,fallGraceTime:0,prevInputDirection:new h,prevRotateToMovementDirection:!1},this.movementModes=new Map,this.savedMoves=new K(O),this.serverMoveTiming=et(),this.serverMoveQueue=[],this.inputMoveScratch={sequence:0,clientTime:0,dt:0,inputX:0,inputY:0,yaw:0,flags:0,clientX:0,clientY:0,clientZ:0,rootMotionX:0,rootMotionY:0,rootMotionZ:0},this.authoritativeMoveScratch={sequence:0,clientTime:0,dt:0,inputX:0,inputY:0,yaw:0,flags:0,clientX:0,clientY:0,clientZ:0,rootMotionX:0,rootMotionY:0,rootMotionZ:0},this.movementModeContext={component:this,state:this.state,move:this.inputMoveScratch,deltaTime:0,rotatedDirection:xt,platformVelocity:Ct,outVelocity:Tt,rootMotionActive:!1,startedSprinting:!1},this.proxySmoother=new J(N,X),this.proxySample=tt(),this.pendingSnapshot=tt(),this.impulse=new h,this.prevRootMotionPos=new h,this.rootMotionOptions={},this.resetRootMotion=!1,this.nextMoveSequence=0,this.clientMoveTime=0,this.lastSentClientMoveTime=0,this.moveSendAccumulator=0,this.simulatedStateAccumulator=0,this.proxyTime=0,this.lastServerProcessedSequence=0,this.lastServerReceivedSequence=0,this.lastAutonomousMoveFlags=0,this.previousSprintInput=!1,this.previousCrouchInput=!1,this.crouchSuppressedUntilRelease=!1,this.slideOnLandingRequested=!1,this.initialized=!1,this.cc=this.physicsSystem.getCharacterController(.1),this.cc.enableSnapToGround(.1),this.cc.enableAutostep(0,.1,!1),this.registerMovementMode(Bt),this.registerMovementMode(Ht),this.registerMovementMode({mode:A.sliding,update:t=>this.updateSlidingMode(t)})}onInit(){this.groundRayTestOptions.excludeActor=this.actor,this.configureCharacterController(),this.physicsSystem.addActor(this.actor,[this.createCollisionShape()],{mass:0,type:C.kinematic,continousCollisionDetection:!1,friction:0,restitution:.5,ignoreForNavMesh:!0}),this.rotationInput.rotation.copy(this.actor.rotation),this.initializeStateFromActor(),this.initialized=!0,this.physicsSystem.beforeStep.pipe(o(this.disposed)).subscribe(t=>this.tick(t))}onLateUpdate(t){this.updateVisualSmoothing(t)}registerMovementMode(t){this.movementModes.set(t.mode,t)}applyImpulse(t){this.impulse.add(t)}getEffectiveGravity(){return this.gravityOverride??this.physicsSystem.getGravity().y}get isGrounded(){return this.rayTestResult.hasHit||this.cc.computedGrounded()}setRootMotionAction(t,e={}){const i=t?.getClip();if(i instanceof l){this.rootMotionAction=t,this.rootMotionOptions=e,this.resetRootMotion=!0;const o=[];this.rootMotionInterpolant=i.motionTrack.InterpolantFactoryMethodSmooth(o);const n=s.PropertyBinding.parseTrackName(i.motionTrack.name);this.rootMotionRootBone=this.actor.object.getObjectByName(n.nodeName)}}serverMove(t){const e=ot(t);if(e.ok)for(const t of e.value.moves)ut(t,this.lastServerReceivedSequence,this.maxMoveDeltaTime)&&(this.lastServerReceivedSequence=t.sequence,this.serverMoveQueue.push(t))}clientMoveAck(t){const e=st(t);e.ok&&this.actor.netRole===m.autonomousProxy&&(this.savedMoves.ack(e.value.sequence),this.sprintPolicy?.ack?.(e.value.sequence,!1))}clientMoveCorrection(t){const e=nt(t);e.ok&&this.actor.netRole===m.autonomousProxy&&(this.debugCorrections&&(null==this.correctionDebug&&(this.correctionDebug=new Qt(Kt(this.actor.object))),this.correctionDebug.update(this.state.position,e.value.snapshot)),this.applyCorrection(e.value.snapshot))}simulatedState(t){const e=rt(t);e.ok&&this.actor.netRole===m.simulatedProxy&&this.proxySmoother.push(e.value,this.proxyTime)}tick(t){if(!this.initialized)return;t=Math.min(.1,t);const e=this.actor.netRole,i=this.netService.mode;e!==m.simulatedProxy?this.enabled&&(e!==m.autonomousProxy?this.isRemoteControlledAuthority(i,e)?this.tickRemoteAuthority(t):this.tickAuthority(t,i):this.tickAutonomousProxy(t)):this.tickSimulatedProxy(t)}tickAutonomousProxy(t){const e=this.state.mode,i=this.lastAutonomousMoveFlags,o=this.createMoveFromInput(t,++this.nextMoveSequence,{quantizeClientTime:!0});this.performMove(o,_t),this.resetToggleCrouchAfterSlide(e);const s=this.state.mode!==e||o.flags!==i;this.lastAutonomousMoveFlags=o.flags,this.savedMoves.capacity=this.maxSavedMoves,this.savedMoves.maxCombinedDeltaTime=Math.min(this.maxCombinedMoveDeltaTime,this.maxMoveDeltaTime),this.savedMoves.push(o),this.sendSavedMoves(t,s)}tickAuthority(t,e){const i=this.state.mode,o=this.createMoveFromInput(t,++this.nextMoveSequence);this.performMove(o,_t),this.resetToggleCrouchAfterSlide(i),e!==dt.none&&this.sendSimulatedState(t,!1)}resetToggleCrouchAfterSlide(t){t===A.sliding&&this.state.mode!==A.sliding&&"toggle"===this.crouchInput.mode&&this.crouchInput.activated&&this.crouchInput.setActivated(!1)}tickRemoteAuthority(t){_(this.serverMoveTiming,t,this.maxServerMoveTimeBudget);let e=!1;const i=Number.isFinite(this.maxServerMovesPerTick)?Math.max(1,Math.floor(this.maxServerMovesPerTick)):this.serverMoveQueue.length,o=Math.min(this.serverMoveQueue.length,i),s=Ut.copy(this.actor.position);let n=!1;for(let t=0;t<o;t++){const t=this.serverMoveQueue.shift();if(null==t)break;if(!ut(t,this.lastServerProcessedSequence,this.maxMoveDeltaTime)){console.log("Net: Invalid move",t),this.sendOwnerCorrection(!0),e=!0;continue}const i=it(this.serverMoveTiming,t,{maxMoveDeltaTime:this.maxMoveDeltaTime,maxServerMoveDeltaTimeScalar:this.maxServerMoveDeltaTimeScalar,maxClientTimeAhead:this.maxClientTimeAhead});if(i<0){this.sendOwnerCorrection(!0),e=!0;continue}const o=Wt(t,this.authoritativeMoveScratch);o.dt=i,o.rootMotionX=0,o.rootMotionY=0,o.rootMotionZ=0,o.flags&=~B,this.performMove(o,{immediate:!0,savedRootMotion:!1}),n=!0,this.lastServerProcessedSequence=o.sequence;const s=$t(this.state,t);if(s>this.correctionToleranceSq){console.log(`Net server: Correction error: ${Math.sqrt(s)}`);const o=this.state.position.x-t.clientX,n=this.state.position.y-t.clientY,r=this.state.position.z-t.clientZ;console.log(`diff x: ${o}, y: ${n}, z: ${r}`),console.log({sequence:t.sequence,moveDt:t.dt,serverMoveDeltaTime:i,flags:t.flags,mode:this.state.mode,grounded:this.state.grounded,fallGraceTime:this.state.fallGraceTime}),this.sendOwnerCorrection(s>this.largeCorrectionThreshold*this.largeCorrectionThreshold),e=!0}}0===this.lastServerProcessedSequence||e||(this.sprintPolicy?.ack?.(this.lastServerProcessedSequence,!1),this.clientMoveAck(ht(this.lastServerProcessedSequence))),n&&this.accumulateListenServerVisualSmoothing(s,this.actor.position),this.sendSimulatedState(t,!1)}tickSimulatedProxy(t){this.proxyTime+=t,this.proxySmoother.sample(this.proxyTime,this.proxySample)&&this.applySnapshot(this.proxySample,!0)}accumulateListenServerVisualSmoothing(t,e){if(!this.shouldSmoothListenServerRemoteAuthority())return void this.visualSmoothingOffset.set(0,0,0);Xt.subVectors(t,e);const i=Xt.lengthSq();i>1e-8&&(i>this.listenServerNoSmoothUpdateDistance*this.listenServerNoSmoothUpdateDistance?this.visualSmoothingOffset.set(0,0,0):(i>this.listenServerMaxSmoothUpdateDistance*this.listenServerMaxSmoothUpdateDistance&&Xt.setLength(this.listenServerMaxSmoothUpdateDistance),this.visualSmoothingOffset.add(Xt)))}updateVisualSmoothing(t){if(this.visualSmoothingOffset.lengthSq()<=1e-8)return void this.visualSmoothingOffset.set(0,0,0);if(!this.shouldSmoothListenServerRemoteAuthority())return void this.visualSmoothingOffset.set(0,0,0);const e=Math.max(.001,this.listenServerSmoothLocationTime);t<e?this.visualSmoothingOffset.multiplyScalar(1-t/e):this.visualSmoothingOffset.set(0,0,0),this.visualSmoothingOffset.lengthSq()<=1e-4&&this.visualSmoothingOffset.set(0,0,0)}shouldSmoothListenServerRemoteAuthority(){return this.listenServerSmoothing&&this.actor.netRole===m.authority&&this.netService.isServer&&!this.netService.isDedicatedServer&&this.isRemoteControlledAuthority()}createMoveFromInput(t,e,i={}){const o=r.clamp(t,.001,this.maxMoveDeltaTime);this.clientMoveTime+=o;let s=this.clientMoveTime,n=o;!0===i.quantizeClientTime&&(s=Math.max(this.lastSentClientMoveTime+.001,Math.round(1e3*this.clientMoveTime)/1e3),n=r.clamp(s-this.lastSentClientMoveTime,.001,this.maxMoveDeltaTime),this.lastSentClientMoveTime=s),this.sampleRootMotion(At);const a=this.crouchInput.activated,h=a&&!this.previousCrouchInput;this.previousCrouchInput=a;const l=!a&&this.sprintInput.activated,c=l&&!this.previousSprintInput;this.previousSprintInput=l;const u=(this.jumpInput.activated?L:0)|(l?Z:0)|(a?E:0)|(h&&this.slideEnabled?H:0)|(c?W:0)|(At.lengthSq()>0?B:0),d=function(t,e){e.set(t.x,0,t.y),e.lengthSq()>1&&e.normalize();return e}(this.directionInput.vector,Nt),p=this.inputMoveScratch;return p.sequence=e>>>0,p.clientTime=s,p.dt=n,p.inputX=d.x,p.inputY=d.z,p.yaw=this.rotationInput.rotation.y,p.flags=u,p.clientX=this.state.position.x,p.clientY=this.state.position.y,p.clientZ=this.state.position.z,p.rootMotionX=At.x,p.rootMotionY=At.y,p.rootMotionZ=At.z,p}performMove(t,e){const i=r.clamp(t.dt,.001,this.maxMoveDeltaTime),o=Math.max(1,Math.ceil(i/this.maxSubstepDeltaTime)),s=0!==(t.flags&Z)&&0===(t.flags&E);this.sprintPolicy?.update?.(i,t.sequence,s),It.set(e.savedRootMotion?t.rootMotionX:0,e.savedRootMotion?t.rootMotionY:0,e.savedRootMotion?t.rootMotionZ:0),e.savedRootMotion||this.sampleRootMotion(It);let n=i;const a=i/o;for(let s=0;s<o;s++){const o=i>0?a/i:1;this.performSubstep(t,Math.min(a,n),It,o,e.immediate,0===s),n-=a}t.clientX=this.state.position.x,t.clientY=this.state.position.y,t.clientZ=this.state.position.z,t.flags=It.lengthSq()>0?t.flags|B:t.flags&~B,this.state.sequence=t.sequence,this.syncPublicState()}performSubstep(t,e,i,o,s,n){if(e<.001)return;this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded;const r=null!=this.rootMotionAction&&this.rootMotionAction.enabled,a=i.lengthSq()>0,h=!r&&0!==(t.flags&L),l=r||a;this.updateCrouchState(t,n,l,h),this.pressedJump=h,this.isSprinting=!1,this.updateRotation(t,e,r,a),this.resolvePlatformVelocity(Ct);const c=this.movementModeContext,u=this.movementModes.get(this.state.mode);if(null!=u){c.move=t,c.deltaTime=e,c.rootMotionActive=l,c.startedSprinting=n&&!l&&0===(t.flags&E)&&0!==(t.flags&W);const i=u.update(c);"number"==typeof i&&(this.state.mode=i)}else Tt.set(0,0,0);if(a){qt.copy(i).multiplyScalar(o).applyQuaternion(this.actor.quaternion),Dt.copy(qt).divideScalar(e),this.state.mode===A.walking?(Tt.x=Dt.x+Ct.x,Tt.z=Dt.z+Ct.z):(Tt.x=Dt.x,Tt.z=Dt.z);const t=Math.sqrt(Dt.x*Dt.x+Dt.z*Dt.z);t>.4&&(this.state.currentSpeed=t)}if(this.applyImpulseToVelocity(Tt,e),h&&this.isSprinting){const t=Math.max(0,this.maxSpeedSprint),e=Zt(Tt);if(e>t){const i=t/e;Tt.x*=i,Tt.z*=i,this.state.velocity.x*=i,this.state.velocity.z*=i}}this.state.mode===A.walking&&this.state.velocity.copy(Tt),this.applyMovement(Tt,e,s),this.state.mode===A.sliding&&(St(this.state.velocity,wt,Ct,this.slideSurfaceNormal,e),this.state.currentSpeed=Zt(this.state.velocity)),this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded,this.updateModeAfterMove(Tt,e),this.state.mode===A.sliding&&this.state.velocity.length()<Math.max(0,this.slideMinExitSpeed)&&(this.state.mode=A.walking)}updateRotation(t,e,i,o){ft.set(-t.inputX,0,t.inputY),ft.lengthSq()>1&&ft.normalize();const s=this.state.prevRotateToMovementDirection!==this.rotateToMovementDirection;let n=r.euclideanModulo(t.yaw-this.state.lookYaw+Math.PI,2*Math.PI)-Math.PI;if(s&&(this.actor.object.quaternion.setFromEuler(Ft.set(0,t.yaw,0)),this.state.prevRotateToMovementDirection||(n=0,this.state.lookYaw=t.yaw),this.state.prevRotateToMovementDirection=this.rotateToMovementDirection),xt.set(0,0,0),i)this.state.lookYaw=t.yaw;else if(this.rotateToMovementDirection){if(ft.lengthSq()>0&&this.state.mode!==A.falling){const i=Ft.setFromQuaternion(this.actor.object.quaternion,"YXZ").y,o=Math.atan2(ft.x,ft.z),s=.99*t.yaw+o;if(this.smoothRotation){const t=r.euclideanModulo(s-i+Math.PI,2*Math.PI)-Math.PI;let o=r.clamp(t*this.rotationSpeed*e,-this.maxRotationSpeed*e,this.maxRotationSpeed*e);Math.abs(o)>Math.abs(t)&&(o=t),this.actor.object.quaternion.setFromEuler(Ft.set(0,i+o,0))}else this.actor.object.quaternion.setFromEuler(Ft.set(0,s,0));this.state.prevInputDirection.lerp(ft,e*this.rotationSpeed),this.state.lookYaw+=n,xt.copy(this.actor.object.getWorldDirection(Nt).normalize())}}else o||(this.state.lookYaw+=n,this.actor.object.quaternion.multiply(Yt.setFromEuler(Ft.set(0,n,0))),ft.lengthSq()>0&&xt.copy(ft).applyQuaternion(this.actor.object.quaternion).normalize())}applyMovement(t,e,i){if(t.lengthSq()>0||!this.state.grounded){if(Rt.copy(t).multiplyScalar(e),this.state.grounded&&((o=this.state.mode)===A.walking||o===A.sliding)&&(this.state.mode===A.walking&&this.rayTestResult.distance<=this.cc.offset()&&(Rt.y=Math.max(0,Ct.y*e)),this.physicsSystem.getActorComputedMovement(this.actor,this.cc,Rt,this.getCollisionGroup()),this.cc.computedCollision(0,Et),null!=Et.normal1)){const t=Nt.copy(Et.normal1);Math.acos(r.clamp(t.dot(Mt),-1,1))>this.cc.maxSlopeClimbAngle()&&(Rt.y=.016*this.getEffectiveGravity()*.5)}wt.copy(this.physicsSystem.getActorComputedMovement(this.actor,this.cc,Rt,this.getCollisionGroup()))}else wt.set(0,0,0);var o;this.suppressUncrouchLift&&(this.suppressUncrouchLift=!1,this.state.grounded&&this.state.mode===A.walking&&Rt.y<=1e-6&&wt.y>0&&(wt.y=0)),this.state.position.add(wt),i?(this.actor.position.copy(this.state.position),this.physicsSystem.updateActorTransform(this.actor),this.physicsSystem.flushModifiedBodyPositionsToColliders()):this.physicsSystem.setNextKinematicPosition(this.actor,this.state.position)}updateModeAfterMove(t,e){const i=function(t){if(0===t.numComputedCollisions())return!1;const e=t.computedCollision(0);Gt.set(e.normal2.x,e.normal2.y,e.normal2.z);const i=Gt.angleTo(Mt);Gt.set(e.normal1.x,e.normal1.y,e.normal1.z);const o=Gt.angleTo(Mt);if(i<100)return!1;return o>t.minSlopeSlideAngle()}(this.cc);!this.state.grounded||i?this.state.mode!==A.falling&&(this.state.fallGraceTime+=e,this.state.fallGraceTime>this.fallGraceTime+1e-6&&(this.state.mode=A.falling,this.state.velocity.copy(t))):this.state.velocity.y<=0&&(this.state.mode===A.falling&&(this.state.mode=A.walking),this.state.mode!==A.sliding&&(this.state.velocity.y=0),this.state.fallGraceTime=0)}applyImpulseToVelocity(t,e){if(this.impulse.lengthSq()<=.1)return void this.impulse.set(0,0,0);const i=Math.min(1,this.impulse.length()/5);t.x=r.lerp(t.x,this.impulse.x,i),t.z=r.lerp(t.z,this.impulse.z,i),t.y+=this.impulse.y;const o=Math.exp(-this.impulseDamping*e);this.impulse.x*=o,this.impulse.y>0?this.impulse.y+=e*this.getEffectiveGravity():this.impulse.y*=o,this.impulse.z*=o}sendSavedMoves(t,e=!1){if(this.moveSendAccumulator+=t,!e&&this.moveSendAccumulator<this.moveSendInterval)return;this.moveSendAccumulator=0;const i=this.savedMoves.getMovesForSend(this.maxMovesPerPacket);0!==i.length&&this.serverMove(at(i))}sendOwnerCorrection(t){const e=this.toSnapshot(this.pendingSnapshot);t&&(e.horizontalSpeed=this.horizontalSpeed),this.sprintPolicy?.ack?.(e.sequence,!0),this.clientMoveCorrection(lt(e))}sendSimulatedState(t,e){this.simulatedStateAccumulator+=t,!e&&this.simulatedStateAccumulator<this.simulatedStateInterval||(this.simulatedStateAccumulator=0,this.simulatedState(ct(this.toSnapshot(this.pendingSnapshot))))}applyCorrection(t){this.sprintPolicy?.restore?.(t.sequence),this.savedMoves.ack(t.sequence),this.sprintPolicy?.ack?.(t.sequence,!0),this.applySnapshot(t,!0),this.savedMoves.replayAfter(t.sequence,t=>(this.performMove(t,{immediate:!0,savedRootMotion:!0}),null),this.maxReplayedMoves)}applySnapshot(t,e){this.state.sequence=t.sequence,this.state.position.set(t.x,t.y,t.z),this.state.velocity.set(t.velocityX,t.velocityY,t.velocityZ),this.state.yaw=t.yaw,this.state.lookYaw=t.yaw,this.state.mode=t.mode,this.state.currentSpeed=t.horizontalSpeed,this.state.fallGraceTime=0,this.actor.position.copy(this.state.position),this.actor.object.quaternion.setFromEuler(Ft.set(0,t.yaw,0)),this.crouchSuppressedUntilRelease=0!==(t.flags&$),this.setCrouching(0!==(t.flags&Q)||t.mode===A.sliding),e&&(this.physicsSystem.updateActorTransform(this.actor),this.physicsSystem.flushModifiedBodyPositionsToColliders()),this.checkGrounded(this.state.position),this.state.grounded=this.isGrounded,this.syncPublicState()}toSnapshot(t){return t.sequence=this.state.sequence,t.x=this.state.position.x,t.y=this.state.position.y,t.z=this.state.position.z,t.velocityX=this.state.velocity.x,t.velocityY=this.state.velocity.y,t.velocityZ=this.state.velocity.z,t.yaw=Ft.setFromQuaternion(this.actor.object.quaternion,"YXZ").y,t.mode=this.state.mode,t.flags=(this.isCrouching?Q:0)|(this.crouchSuppressedUntilRelease?$:0),t.horizontalSpeed=this.state.currentSpeed,t}syncPublicState(){this.velocity.copy(this.state.velocity),this.mode=this.state.mode,this.horizontalSpeed=this.state.currentSpeed,this.isSliding=this.state.mode===A.sliding,this.isSliding?(this.resolveGroundNormal(this.slideSurfaceNormal),this.slideDirection.copy(this.state.velocity).projectOnPlane(this.slideSurfaceNormal),this.slideDirection.lengthSq()>1e-8?this.slideDirection.normalize():this.slideDirection.set(0,0,0)):(this.slideDirection.set(0,0,0),this.slideSurfaceNormal.copy(Mt))}sampleRootMotion(t){if(t.set(0,0,0),null==this.rootMotionAction||this.rootMotionAction.isRunning()||this.clearRootMotionAction(this.rootMotionAction),null!=this.rootMotionAction&&this.rootMotionOptions.cancelWithJump&&this.jumpInput.activated&&(this.isGrounded||this.jumpInAir)){const e=this.rootMotionAction,i=this.rootMotionOptions.onJumpCancel;return this.clearRootMotionAction(e),e.stop(),i?.(),t}if(null==this.rootMotionAction)return t;if(!(this.rootMotionAction.getClip()instanceof l))return t;const e=this.rootMotionInterpolant;this.resetRootMotion&&(this.prevRootMotionPos.fromArray(e.evaluate(0)),this.resetRootMotion=!1),kt.fromArray(e.evaluate(this.rootMotionAction.time)),t.subVectors(kt,this.prevRootMotionPos),this.prevRootMotionPos.copy(kt);return(this.rootMotionRootBone??this.rootMotionAction.getRoot()).getWorldScale(bt),t.multiply(bt),t}clearRootMotionAction(t){null!=t&&this.rootMotionAction!==t||(this.rootMotionAction=null,this.rootMotionOptions={},this.resetRootMotion=!1)}isRemoteControlledAuthority(t=this.netService.mode,e=this.actor.netRole){if(t===dt.none||e!==m.authority||t>=dt.client)return!1;return null!=this.netService.resolveActorConnection(this.actor)&&!this.netService.isLocalOwner(this.actor)}configureCharacterController(){const t=this.cc;t.setApplyImpulsesToDynamicBodies(this.applyImpulsesToDynamicBodies),t.setMinSlopeSlideAngle(this.minSlopeSlideAngle),t.setMaxSlopeClimbAngle(this.maxSlopeClimbAngle),t.setCharacterMass(this.mass),t.setSlideEnabled(this.allowSliding)}initializeStateFromActor(){this.state.position.copy(this.actor.position),this.state.velocity.set(0,0,0),this.state.yaw=this.actor.rotation.y,this.state.lookYaw=this.rotationInput.rotation.y,this.state.mode=this.mode,this.state.currentSpeed=this.horizontalSpeed,this.state.prevRotateToMovementDirection=this.rotateToMovementDirection}createCollisionShape(){const t=this.getColliderHeight(!1),e=this.getColliderRadius(!1),i=new x(t,e);return i.offset.y=this.getCapsuleOffsetY(t,e),i.collisionGroup=gt,i}updateCrouchState(t,e,i,o){if(!(0!==(t.flags&E)))return this.crouchSuppressedUntilRelease=!1,this.slideOnLandingRequested=!1,this.state.mode===A.sliding&&(this.state.mode=A.walking),void this.tryUncrouch();if(this.state.mode===A.sliding&&(!this.slideEnabled||i))return this.slideOnLandingRequested=!1,this.state.mode=A.walking,void(this.crouchSuppressedUntilRelease||this.setCrouching(!0));if(this.state.mode===A.sliding&&o)return this.crouchSuppressedUntilRelease=!0,this.slideOnLandingRequested=!1,void this.tryUncrouch();if(this.crouchSuppressedUntilRelease)return void(this.slideOnLandingRequested=!1);if(this.setCrouching(!0),!this.slideEnabled||i)return void(this.slideOnLandingRequested=!1);if(this.state.mode===A.falling)return void(this.slideOnLandingRequested=!0);this.resolveGroundNormal(Vt);const s=this.slideOnLandingRequested&&this.state.mode===A.walking&&this.state.grounded,n=e&&0!==(t.flags&H)||s;s&&(this.slideOnLandingRequested=!1);const r=Zt(this.state.velocity);this.state.mode===A.walking&&vt(this.slideEnabled,n,this.state.grounded,this.isWalkableSlideSurface(Vt),i,r,this.slideMinStartSpeed)&&(this.state.mode=A.sliding,this.slideSurfaceNormal.copy(Vt),this.state.velocity.projectOnPlane(this.slideSurfaceNormal),this.state.currentSpeed=Zt(this.state.velocity))}updateSlidingMode(t){const e=t.state,i=t.move;this.resolveGroundNormal(this.slideSurfaceNormal);const o=this.isWalkableSlideSurface(this.slideSurfaceNormal),s=e.velocity.length();if(!e.grounded||!o)return e.mode=A.falling,Ht.update(t),A.falling;if(this.slideEnabled&&0!==(i.flags&E)&&!t.rootMotionActive&&0!==(i.flags&L))return pt(t.outVelocity,e.velocity,this.jumpVelocity),e.velocity.copy(t.outVelocity),e.currentSpeed=Zt(e.velocity),A.falling;if(!mt(this.slideEnabled,0!==(i.flags&E),e.grounded,o,t.rootMotionActive,s,this.slideMinExitSpeed))return e.mode=A.walking,Bt.update(t),A.walking;const n=yt(e.velocity,e.velocity,this.slideSurfaceNormal,t.rotatedDirection,this.getEffectiveGravity(),t.deltaTime,this.slideDeceleration,this.slideGravityScale,this.slideSteeringRate);if(e.currentSpeed=Zt(e.velocity),n<Math.max(0,this.slideMinExitSpeed))return e.mode=A.walking,Bt.update(t),A.walking;t.outVelocity.copy(e.velocity).add(t.platformVelocity)}tryUncrouch(){this.isCrouching&&this.canUncrouch()&&this.setCrouching(!1)&&(this.suppressUncrouchLift=!0,this.state.fallGraceTime=0)}resolveGroundNormal(t){return!this.rayTestResult.hasHit||this.rayTestResult.hitNormal.lengthSq()<=1e-8?t.copy(Mt):(t.copy(this.rayTestResult.hitNormal).normalize(),t.dot(Mt)<0&&t.multiplyScalar(-1),t)}isWalkableSlideSurface(t){return t.dot(Mt)>=Math.cos(this.cc.maxSlopeClimbAngle())}setCrouching(t){return this.isCrouching!==t&&(this.isCrouching=t,this.syncColliderShape(),!0)}canUncrouch(){const t=this.getColliderHeight(!1),e=this.getColliderRadius(!1);return!this.physicsSystem.hasActorCapsuleIntersection(this.actor,this.state.position,t,e,this.getCapsuleOffsetY(t,e),this.getCollisionGroup())}syncColliderShape(){const t=this.getColliderHeight(this.isCrouching),e=this.getColliderRadius(this.isCrouching);this.physicsSystem.setActorCapsuleCollider(this.actor,t,e,this.getCapsuleOffsetY(t,e))}getColliderHeight(t){const e=Number.isFinite(this.colliderHeight)?Math.max(0,this.colliderHeight):0;if(!t)return e;const i=Number.isFinite(this.crouchColliderHeight)?this.crouchColliderHeight:e;return r.clamp(i,0,e)}getColliderRadius(t){const e=Number.isFinite(this.colliderRadius)?Math.max(.001,this.colliderRadius):.001;if(!t)return e;const i=this.crouchColliderRadius??e,o=Number.isFinite(i)?i:e;return r.clamp(o,.001,e)}getCapsuleOffsetY(t,e){return e+t/2+this.offset}checkGrounded(t){jt.y=-Math.max(.05,this.cc.snapToGroundDistance()),this.physicsSystem.rayTest(zt.addVectors(t,Ot.set(0,this.offset,0)),Pt.addVectors(t,jt),this.rayTestResult,this.groundRayTestOptions)}resolvePlatformVelocity(t){return t.set(0,0,0),this.rayTestResult.hasHit&&null!=this.rayTestResult.actor&&this.physicsSystem.getLinearVelocity(this.rayTestResult.actor,t),t}getCollisionGroup(){return this.characterCollision?null:gt}};t([T(),e("design:type",Object)],Lt.prototype,"colliderHeight",void 0),t([T(),e("design:type",Object)],Lt.prototype,"colliderRadius",void 0),t([T(),e("design:type",Object)],Lt.prototype,"crouchColliderHeight",void 0),t([T(),e("design:type",Number)],Lt.prototype,"crouchColliderRadius",void 0),t([S(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"serverMove",null),t([v(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"clientMoveAck",null),t([v(!0),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"clientMoveCorrection",null),t([y(!1),e("design:type",Function),e("design:paramtypes",[Uint8Array]),e("design:returntype",void 0)],Lt.prototype,"simulatedState",null),Lt=t([w({inEditor:!1}),e("design:paramtypes",[])],Lt);export{Lt as CharacterMovementComponent};const Bt={mode:A.walking,update(t){const e=t.component,i=t.move,o=t.state,s=t.rotatedDirection,n=Math.min(1,Math.sqrt(i.inputX*i.inputX+i.inputY*i.inputY)),r=!e.rotateToMovementDirection&&i.inputY<0,a=e.isCrouching,h=!t.rootMotionActive&&!a&&0===(i.flags&E)&&0!==(i.flags&Z)&&!r&&0!==s.lengthSq()&&(e.sprintPolicy?.canSprint()??!0),l=(a?e.maxSpeedCrouch:r?e.maxSpeedBackwards:h?e.maxSpeedSprint:e.maxSpeed)*(e.normalizedDirection?1:n);if(0!==s.lengthSq()){e.isSprinting=h,h&&e.sprintPolicy?.commitSprint(t.deltaTime,i.sequence);let a=Math.min(l,o.currentSpeed),c=e.groundAccelerationRate;if(h&&t.startedSprinting&&e.sprintStartBoostSpeed>0){const t=e.normalizedDirection?1:n;a=Math.max(a,l+e.sprintStartBoostSpeed*t),c=e.sprintStartBoostDamping}else h&&!r&&e.sprintStartBoostSpeed>0&&o.currentSpeed>l&&(a=o.currentSpeed,c=e.sprintStartBoostDamping);o.currentSpeed=function(t,e,i,o){return e+(t-e)*Math.exp(-i*o)}(a,l,c,t.deltaTime),t.outVelocity.copy(s).multiplyScalar(function(t,e,i,o){const s=i*o;if(s<=1e-6)return t;return e+(t-e)*(1-Math.exp(-s))/s}(a,l,c,t.deltaTime))}else o.currentSpeed=0,t.outVelocity.set(0,0,0);if(0!==(i.flags&L))return o.mode=A.falling,o.velocity.copy(t.outVelocity),o.velocity.y=e.jumpVelocity,A.falling;t.outVelocity.y=t.deltaTime*e.getEffectiveGravity(),t.outVelocity.add(t.platformVelocity)}},Ht={mode:A.falling,update(t){const e=t.component,i=t.state,o=t.move;0!==(o.flags&L)&&e.jumpInAir&&(i.velocity.copy(t.outVelocity),i.velocity.y=e.jumpVelocity),i.velocity.y+=t.deltaTime*e.getEffectiveGravity(),t.outVelocity.copy(i.velocity),t.outVelocity.addScaledVector(t.rotatedDirection,e.fallingMovementControl),e.fallingReorientation&&t.outVelocity.applyAxisAngle(Mt,r.euclideanModulo(o.yaw-i.lookYaw+Math.PI,2*Math.PI)-Math.PI)}};function Zt(t){return Math.sqrt(t.x*t.x+t.z*t.z)}function Wt(t,e){return e.sequence=t.sequence,e.clientTime=t.clientTime,e.dt=t.dt,e.inputX=t.inputX,e.inputY=t.inputY,e.yaw=t.yaw,e.flags=t.flags,e.clientX=t.clientX,e.clientY=t.clientY,e.clientZ=t.clientZ,e.rootMotionX=t.rootMotionX,e.rootMotionY=t.rootMotionY,e.rootMotionZ=t.rootMotionZ,e}function $t(t,e){const i=t.position.x-e.clientX,o=t.position.y-e.clientY,s=t.position.z-e.clientZ;return i*i+o*o+s*s}class Qt{constructor(t){this.scene=t,this.serverPosition=new h,this.direction=new h}update(t,e){const i=this.serverPosition.set(e.x,e.y,e.z),o=i.distanceTo(t);o>.1&&console.log(`Correction applied. Error: ${o.toFixed(3)}. Server position: (${i.x.toFixed(2)}, ${i.y.toFixed(2)}, ${i.z.toFixed(2)}), Client position: (${t.x.toFixed(2)}, ${t.y.toFixed(2)}, ${t.z.toFixed(2)})`);const s=this.direction.copy(i).sub(t).normalize();Jt.position.copy(t),Jt.setDirection(s),Jt.setLength(o);const n=Kt(this.scene);n.add(Jt),setTimeout(()=>{n.remove(Jt)},1e3)}}const Jt=new n(new h(0,1,0),new h,1,16711680);function Kt(t){return null==t.parent?t:Kt(t.parent)}const _t={immediate:!1,savedRootMotion:!0};/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Constructable, ContainerInstance } from "typedi";
|
|
2
2
|
import { ShaderType, ActorType, ActorComponentType } from '../shader/shader.js';
|
|
3
3
|
import { World } from './services/world.js';
|
|
4
|
-
import { type DynamicResolutionOptions, type UpscalingOptions } from '../rendering.js';
|
|
4
|
+
import { type DynamicResolutionOptions, type ExperimentalWebGpuPostProcessingOptions, type RenderingBackend, type UpscalingOptions } from '../rendering.js';
|
|
5
5
|
import { Observable } from 'rxjs';
|
|
6
6
|
import { DetailTier } from "../scene/model.js";
|
|
7
7
|
import { NetSession } from "./net/net-session.js";
|
|
@@ -32,10 +32,12 @@ export type InitiateGameConfig = {
|
|
|
32
32
|
*/
|
|
33
33
|
detailTier?: DetailTier;
|
|
34
34
|
rendering?: Partial<{
|
|
35
|
+
backend: RenderingBackend;
|
|
35
36
|
resolutionScale: number;
|
|
36
37
|
maxPixelRatio: number;
|
|
37
38
|
dynamicResolution: DynamicResolutionOptions;
|
|
38
39
|
upscaling: UpscalingOptions;
|
|
40
|
+
webgpuPostProcessing: ExperimentalWebGpuPostProcessingOptions;
|
|
39
41
|
msaa: number;
|
|
40
42
|
fpsCap: number | null;
|
|
41
43
|
depthPrepass: {
|
|
@@ -61,6 +63,8 @@ export type InitiateGameConfig = {
|
|
|
61
63
|
};
|
|
62
64
|
export declare function initiateGame<T_Game>(gameClass: GameClass<T_Game>, config: InitiateGameConfig): HologyRuntime<T_Game>;
|
|
63
65
|
export declare abstract class GameInstance {
|
|
66
|
+
/** Add gameplay objects and preload render resources before the final scene compile. */
|
|
67
|
+
onPreload(): void | Promise<void>;
|
|
64
68
|
onStart(): void | Promise<void>;
|
|
65
69
|
onShutdown(): void | Promise<void>;
|
|
66
70
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import e from"typedi";import{loadScene as t}from"../scene/bootstrap.js";import{ActorFactory as
|
|
1
|
+
import e from"typedi";import{loadScene as t}from"../scene/bootstrap.js";import{ActorFactory as n}from"./actors/factory.js";import{World as s}from"./services/world.js";import{SceneMaterializer as o}from"../scene/materializer.js";import{ViewController as r}from"./services/render.js";import{RenderingView as i}from"../rendering.js";import{PhysicsSystem as a}from"./services/physics/physics-system.js";import{MeshComponent as c}from"./actors/builtin/components/mesh-component.js";import{builtInComponents as d}from"./actors/builtin/components/index.js";import{activeContainerInstance as m}from"./actors/internal/container-map.js";import{InputService as l}from"./input/index.js";import{RuntimeAssetsService as p}from"../scene/runtime-asset-service.js";import{AssetResourceLoader as h}from"../scene/asset-resource-loader.js";import{AssetLoader as u}from"./services/asset-loader.js";import{polyfillClient as g}from"./polyfill.js";import{Subject as f}from"rxjs";import{PointerEvents as w}from"./services/pointer-events.js";import{RuntimeBundledBackendService as b}from"../scene/runtime-bundled-backend-service.js";import{Scene as v}from"three";import{ShaderProvider as j}from"./services/shader-provider.js";import{SceneDataService as S}from"../scene/scene-data-service.js";import{NetMode as x}from"./net/net-session.js";import{AssetsProvider as y}from"../scene/assets-provider.js";export function initiateGame(f,w){if(g(),0!=w.element.childNodes.length)return console.error("Can not initialize the game with a non-empty html element"),null;e.has(r);const I=e.of("default"),P=new HologyRuntime(I),G=new n(I,{inEditor:!1});var E;G.classes=w.actors,e.set(n,G),E=w.element,Object.assign(E.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",overflow:"hidden"});const R=new i(w.element,{backend:w.rendering?.backend??"webgpu-experimental",enableXR:!0===w.xr?.enabled,maxPixelRatio:w.rendering?.maxPixelRatio,resolutionScale:w.rendering?.resolutionScale,dynamicResolution:w.rendering?.dynamicResolution,upscaling:w.rendering?.upscaling,webgpuPostProcessing:w.rendering?.webgpuPostProcessing,msaa:w.rendering?.msaa,fpsCap:w.rendering?.fpsCap,depthPrepass:{enabled:!0===w.rendering?.depthPrepass?.enabled},bloom:{enabled:!1!==w?.rendering?.bloom?.enabled},reflection:{enabled:!1!==w?.rendering?.reflection?.enabled},occlusionCulling:{enabled:!1!==w?.rendering?.occlusionCulling?.enabled},shadows:{cascadeUpdateIntervals:[22,40,60,120]}});R.renderer.shadowMap.enabled=w.rendering?.shadows?.enabled??!0,R.renderer.shadowMap.autoUpdate=w.rendering?.shadows?.autoUpdate??!0,R.renderer.debug.checkShaderErrors=!1,e.set(i,R);const k=new r(R);e.set(r,k);const C=new b,D=new p(C),M=new h;M.setDataDir(w.dataDir),M.initKtx2(R.renderer);const z=Object.entries(w.shaders).map(([e,t])=>({name:e,type:t})),A=Object.entries(w.actors).map(([e,t])=>({name:e,type:t})),O={...d,...w.components??{}},U=Object.entries(O).map(([e,t])=>({name:e,type:t})),F=new j(z);e.set(j,F);const H=new u(M,D,z);e.set(y,D),e.set(h,M),e.set(u,H);const N=new v,T=new o(N,new S,D,M,R,z,A,G,U);T.inEditor=!1,T.netMode=w.multi?.session?.mode??x.none,e.set(o,T);const W=e.get(s);return e.set(s,W),W.materializer=T,(async()=>{const n=e.get(a);if(await n.start(),P.isShutdown)return;if(await C.preloadData(),P.isShutdown)return;if(W.scene=N,null!=w.multi?.session){const{NetService:e}=await import("./net/service/net-service.js"),t=I.get(e);t.session=w.multi.session,t.start(),P.shutdownStarted.subscribe(()=>t.stop())}const{scene:s,actors:o,materializer:r}=await t(R,w.sceneName,w.dataDir,w.shaders,w.actors,O,G,C,D,M,{detailTier:w.detailTier,nodeMode:w.multi?.session?.mode??x.none});W.scene=s,n.scene=W.scene;for(const e of N.children)W.scene.add(e);if(P.isShutdown)return void R.stop();e.import([c]);for(const e of o)W.addActor(e);n.addFromScene(s),await W.startSceneEventGraphs(r),m.value=I,I.remove(f),I.set({id:f,type:f});const i=I.get(f);if(m.value=null,P.gameInstance=i,i instanceof GameInstance&&await i.onPreload(),P.isShutdown)return void R.stop();console.log("Start compile shaders"),console.time("compile shaders"),await R.compileAsync(),console.timeEnd("compile shaders"),"webgpu-experimental"===R.activeBackend?console.log("Finished compiling the experimental WebGPU scene."):console.log("Finished compile shaders. Programs: ",R.renderer.info.programs?.length??0),console.log("Start init scene textures"),console.time("init scene textures"),R.initTextures(),console.timeEnd("init scene textures");const d=I.get(l);R.loop(e=>{d.update(e)}),P.status=5,P.shutdownStarted.subscribe(()=>{M.disposeAll()}),i instanceof GameInstance&&await i.onStart(),P._resolver(!0)})(),P}export class GameInstance{onPreload(){}onStart(){}onShutdown(){}}export function createHologyScene(){}export class HologyRuntime{constructor(e){this.containerInstance=e,this.status=0,this.isShutdown=!1,this.shutdownStarted=new f,this.ready=new Promise(e=>{this._resolver=e})}getWorld(){return this.containerInstance.get(s)}getService(e){return this.containerInstance.get(e)}shutdown(){this.isShutdown=!0;const e=this.shutdownStarted;e.next(),e.complete(),this.gameInstance instanceof GameInstance&&this.gameInstance.onShutdown(),this.containerInstance.get(l).stop();const t=this.containerInstance.get(i);t?.stop();const n=this.getWorld();n.stopSceneEventGraphs();const s=this.containerInstance.get(r);s.setMuted(!0),s.dispose();for(const e of[...n.actors])n.removeActor(e);this.containerInstance.get(a).stop(),this.containerInstance.get(o).dispose();const c=this.containerInstance.get(y);c instanceof p&&c.dispose(),this.containerInstance.get(w).stop(),this.containerInstance.reset(),this.shutdownStarted.complete()}}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -116,6 +116,7 @@ export declare class PhysicsSystem extends AbstractPhysicsSystem {
|
|
|
116
116
|
private collisionSub;
|
|
117
117
|
private rayDebugArrowPool;
|
|
118
118
|
private activeRayDebugArrows;
|
|
119
|
+
private nonFixedBodies;
|
|
119
120
|
private readonly collisionEvents;
|
|
120
121
|
readonly beforeStep: Subject<number>;
|
|
121
122
|
readonly afterStep: Subject<number>;
|