@hology/core 0.0.53 → 0.0.55
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE.md +4 -4
- package/dist/effects/vfx/behaviours.d.ts +16 -0
- package/dist/effects/vfx/behaviours.js +1 -1
- package/dist/effects/vfx/index.d.ts +2 -0
- package/dist/effects/vfx/index.js +1 -1
- package/dist/effects/vfx/initializsers.d.ts +7 -0
- package/dist/effects/vfx/initializsers.js +1 -1
- package/dist/effects/vfx/rates.d.ts +6 -0
- package/dist/effects/vfx/rates.js +1 -1
- package/dist/effects/vfx/stretched-sprite.d.ts +4 -0
- package/dist/effects/vfx/stretched-sprite.js +5 -0
- package/dist/effects/vfx/trail-renderer.d.ts +91 -0
- package/dist/effects/vfx/trail-renderer.js +5 -0
- package/dist/effects/vfx/vfx-actor.d.ts +15 -2
- package/dist/effects/vfx/vfx-actor.js +1 -1
- package/dist/effects/vfx/vfx-asset.d.ts +29 -4
- package/dist/effects/vfx/vfx-asset.js +1 -1
- package/dist/effects/vfx/vfx-defs.d.ts +46 -15
- package/dist/effects/vfx/vfx-defs.js +1 -1
- package/dist/effects/vfx/vfx-materializer.d.ts +22 -10
- package/dist/effects/vfx/vfx-materializer.js +1 -1
- package/dist/effects/vfx/vfx-old-materializer.d.ts +11 -0
- package/dist/effects/vfx/vfx-old-materializer.js +5 -0
- package/dist/effects/vfx/vfx-param.d.ts +2 -3
- package/dist/effects/vfx/vfx-param.js +1 -1
- package/dist/effects/vfx/vfx-renderers.d.ts +58 -3
- package/dist/effects/vfx/vfx-renderers.js +1 -1
- package/dist/effects/vfx/vfx-service.d.ts +14 -0
- package/dist/effects/vfx/vfx-service.js +5 -0
- package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
- package/dist/gameplay/actors/builtin/components/mesh-component.d.ts +1 -0
- package/dist/gameplay/actors/builtin/components/mesh-component.js +1 -1
- package/dist/gameplay/index.d.ts +1 -0
- package/dist/gameplay/index.js +1 -1
- package/dist/gameplay/services/physics/physics-system.d.ts +8 -0
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/gameplay/services/world.js +1 -1
- package/dist/rendering.js +1 -1
- package/dist/scene/asset-resource-loader.d.ts +1 -0
- package/dist/scene/asset-resource-loader.js +1 -1
- package/dist/scene/landscape/landscape-manager.d.ts +1 -0
- package/dist/scene/landscape/landscape-manager.js +1 -1
- package/dist/scene/materializer.d.ts +2 -0
- package/dist/scene/materializer.js +1 -1
- package/dist/scene/model.d.ts +1 -0
- package/dist/scene/storage/storage.d.ts +33 -2
- package/dist/scene/storage/storage.js +1 -1
- package/dist/shader/builtin/lambert-shader.d.ts +1 -1
- package/dist/shader/builtin/lambert-shader.js +1 -1
- package/dist/shader/builtin/standard-shader.js +1 -1
- package/dist/utils/math.js +1 -1
- package/dist/utils/three/transform-controls.d.ts +4 -2
- package/dist/utils/three/transform-controls.js +1 -1
- package/package.json +3 -2
- package/tsconfig.tsbuildinfo +1 -1
@@ -1,4 +1,4 @@
|
|
1
|
-
import{Object3D as e}from"three";import*as t from"three";import a,{Behaviour as n,Body as r,BoxZone as o,Emitter as s,Force as i,Life as l,Mass as m,MeshRenderer as c,PointZone as w,Position as d,RadialVelocity as u,Radius as f,Rate as p,Rotate as A,Scale as h,Span as g,Vector3D as y,ease as b}from"three-nebula";import{RotatePosition as M}from"./behaviours.js";import{DelayRate as x,OnceRate as I}from"./rates.js";import{VfxBehaviourLibrary as B,VfxInitializserLibrary as E}from"./vfx-defs.js";import{ThreeBlendingMode as R}from"./vfx-asset.js";import{ShapeLibrary as S}from"../../scene/objects/shapes.js";import{prepareShapeParameters as v}from"../../scene/materializer.js";import{particleEnergyUniformName as j,particleVelcoityUniformName as Q}from"../../shader-nodes/particle.js";import{AttributeVec3Node as V,NodeShaderMaterial as U,RgbNode as k,Vec3ExpressionNode as F,lambertMaterial as H,varyingVec3 as P}from"three-shader-graph";import{DefaultInitializer as J}from"./initializsers.js";import{MultiRenderer as q}from"./vfx-renderers.js";export async function materializeVfx(n,o,i){let l=o;if(!0!==n.vfx.localSpace)for(;null!=l.parent;)l=l.parent;const m=new e;m.name="particle system",l.add(m);const c=new q(m,t),w=new a,d=await Promise.all(n.vfx.emitters.map((async a=>{let n,o;switch(a.rate.type){case"continuous":n=new x(a.rate.delay??0,a.rate.count,a.rate.time);break;case"once":n=new I(a.rate.delay??0,a.rate.count);break;default:console.warn(`Failed to configure r\n ate for emitter: ${JSON.stringify(a)}`),n=new p(0,1/0)}switch(a.output.type){case"sprite":o=new r(await async function(e,a){const n=null!=e.texture?await a.getTexture(e.texture):T;var r=new t.SpriteMaterial({map:n,color:e.color??16777215,blending:R[e.blendingMode]??t.NormalBlending,fog:!0,transparent:!0});const o=new t.Sprite(r);return o}(a.output,i));break;case"shape":o=new r(await async function(a,n){const r=S[a.shape];if(null==r)return console.error(`No shape with type ${a.shape}`),new e;const o=v(a.params??{}),s=r.geometry(o),i=null!=a.material?await n.getMaterial(a.material):function(){const e=P(new F("instanceColor")).rgb(),t=P(new V("particleData")).x();return new U({color:H({color:e}).rgb().rgba(t),transparent:!0})}();return new t.Mesh(s,i)}(a.output,i));break;case"mesh":o=new r(await async function(a,n){if(null==a.assetId)return console.warn("Can't use mesh as particle without asset id"),new e;const r=await n.getMesh(a.assetId),o=await n.getAsset(a.assetId),s=[];if(null!=o.materialAssignments)for(const e of o.materialAssignments)r.traverse((a=>{a instanceof t.Mesh&&a.material instanceof t.Material&&a.material.color instanceof t.Color&&(a.material.name!=e.name&&null!=e.name||"#"+a.material.color.getHexString()!==e.color||s.push(n.getMaterial(e.materialId).then((e=>a.material=e))))}));return await Promise.all(s),r.traverse((e=>{})),r}(a.output,i));break;default:console.error("Failed to create particly system body: "+JSON.stringify(a))}const l=(new s).setRate(n),m=await Promise.all(a.initializers.filter((e=>null!=E[e.type])).map((async e=>{const t=E[e.type],a=await v(e.params??{});return t.build(a)})));m.push(o,new J),l.addInitializers(m);const c=await Promise.all(a.behaviours.filter((e=>null!=B[e.type])).map((async e=>{const t=B[e.type],a=await v(e.params??{});return t.build(a)})));return c.push(new W),l.addBehaviours(c),l.emit()})));return d.forEach((e=>w.addEmitter(e))),w.addRenderer(c).emit({onEnd:()=>{console.log("ended")}}),{system:w,dispose:()=>{m.removeFromParent(),c.dispose()}}}const T=(new t.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=");export function materializeVfxOld(n,x){let B=x;if(!0!==n.vfx.localSpace)for(;null!=B.parent;)B=B.parent;const E=new e;E.name="particle system",B.add(E);const R=new c(E,t),S=new t.Mesh(new t.BoxGeometry(.3,.3,.3),new t.MeshStandardMaterial({color:16777215})),v=new p(new g(3,9),new g(.02,.15)),j=new s,Q=new a;j.setLife(4).setRate(v).addInitializers([new m(1),new f(1),new l(1),new r(S),new d(new o(.5)),new u(10,new y(0,0,1),30)]).addBehaviours([new M(new t.Vector3(0,0,1),4),new i(0,0,.1),new A("random",2.5*-Math.PI,2*Math.PI,1,b.easeOutCubic),new h(1,.2)]).emit();const V=new I(0),U=(new s).setLife(5).addInitializers([new m(1),new f(1),new l(3),new r(S),new d(new w(0,0,0))]).addBehaviours([new h(4,6,void 0,b.easeOutExpo)]).setRate(V).emit();return V.nextTime=0,Q.addEmitter(j).addEmitter(U).addRenderer(R).emit({onEnd:()=>{console.log("ended")}}),{system:Q,rate:v,renderer:R,dispose:()=>E.removeFromParent()}}class W extends n{initialize(e){if(e.body instanceof t.Mesh){const t=e.body.material;t instanceof U&&(null!=t.uniforms[j]||null!=t.uniforms[Q])&&(e.body.material=t.clone())}}mutate(e,a,n){if(e.target instanceof t.Mesh){const t=e.target.material;t instanceof U&&(null!=t.uniforms[j]&&(t.uniforms[j].value=this.energy),null!=t.uniforms[Q]&&(t.uniforms[Q].value=e.velocity))}}}
|
1
|
+
import*as t from"three";import{Object3D as e}from"three";import i,{Behaviour as n,Body as o,Emitter as s,Rate as r}from"three-nebula";import{AttributeFloatNode as a,AttributeVec3Node as l,AttributeVec4Node as c,NodeShaderMaterial as m,RgbNode as u,UniformVec3Node as p,Vec3ExpressionNode as d,Vec4Node as h,attributes as f,float as w,glslFunction as g,lambertMaterial as y,log as A,pow as v,rgba as x,saturate as E,textureSampler2d as b,transformed as P,uniforms as M,varyingAttributes as I,varyingVec3 as R,varyingVec4 as z}from"three-shader-graph";import{prepareShapeParameters as V}from"../../scene/materializer.js";import{ShapeLibrary as B}from"../../scene/objects/shapes.js";import{fragmentLinearEyeDepth as T,linearEyeDepth as S}from"../../shader-nodes/depth.js";import{particleEnergyUniformName as j,particleVelcoityUniformName as k}from"../../shader-nodes/particle.js";import{DefaultInitializer as C}from"./initializsers.js";import{DelayRate as F,OnceRate as Q}from"./rates.js";import{ThreeBlendingMode as U}from"./vfx-asset.js";import{VfxBehaviourLibrary as H,VfxInitializserLibrary as D}from"./vfx-defs.js";import{MultiRenderer as G}from"./vfx-renderers.js";import{StretchedSprite as J}from"./stretched-sprite.js";export async function materializeVfx(n,o,s,r){let a=o;for(;null!=a.parent;)a=a.parent;const l=new e;l.name="particle system local",o.add(l);const c=new e;c.name="particle system world",a.add(c);const m=new G(c,l,t,r),u=new i;return(await Promise.all(n.vfx.emitters.map((async t=>{const e=await q(t,s,u);return e.setParentRecursive(u),e.emit()})))).forEach((t=>u.addEmitter(t))),u.addRenderer(m).emit({onEnd:()=>{console.log("ended")}}),{container:c,system:u,dispose:()=>{c.removeFromParent(),l.removeFromParent(),m.dispose()}}}async function q(i,n,s){const u=function(t){let e;switch(t.rate.type){case"continuous":e=new F(t.rate.delay??0,t.rate.count,t.rate.time);break;case"once":e=new Q(t.rate.delay??0,t.rate.count);break;default:console.warn(`Failed to configure rate for emitter: ${JSON.stringify(t)}`),e=new r(0,1/0)}return e}(i);let j;switch(i.output.type){case"sprite":j=new o(await async function(e,i){const n=null!=e.texture?await i.getTexture(e.texture):W,o=b(n).sample(I.uv),s=new p("color").rgb(),r=(new p("opacity").rgb(),S.subtract(T).divide(S));let a=o.x();if("number"==typeof e.softness&&e.softness>0){const t=v(r,w(e.softness));a=a.multiply(t)}const l=g(h,{position:P.position,modelViewMatrix:M.modelViewMatrix},"\n vec2 center = vec2(0.5, 0.5);\n float rotation = 0.0;\n vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n // Using scale form instance matrix instead of modelMatrix\n vec2 scale;\n scale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n scale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\n // This times 2 on scale seem to make it appear like when using regular sprites. \n // Not sure if this is correct though.\n vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * (scale);\n\n vec2 rotatedPosition;\n rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\n mvPosition.xy += rotatedPosition;\n return projectionMatrix * mvPosition;\n ");var c=new L({color:x(s,a).multiply(o),transparent:!0,position:l,uniforms:{color:{value:new t.Color(e.color)}}});c.blending=U[e.blendingMode]??t.NormalBlending;const m=new t.Mesh(new t.PlaneGeometry(1,1),c);return m.name="sprite",m}(i.output,n));break;case"stretchedSprite":j=new o(await async function(e,i){const n=null!=e.texture?await i.getTexture(e.texture):W,o=b(n).sample(I.uv),s=z(new c("color")),r=s.rgb();let m=s.w();if("number"==typeof e.softness&&e.softness>0){const t=S.subtract(T).divide(A(S)),i=v(t,w(e.softness));m=E(m.multiply(i))}const u=g(h,{position:f.position,offset:new l("offset"),modelViewMatrix:M.modelViewMatrix,velocity:new c("velocity"),size:new l("size"),rotation:new a("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 L({color:x(r,m).multiply(o),transparent:!0,position:u,uniforms:{}});p.blending=U[e.blendingMode]??t.NormalBlending;const d=new J(new t.PlaneGeometry(1,1),p);return d.scaleFactor=e.scale,d}(i.output,n));break;case"shape":j=new o(await async function(i,n){const o=B[i.shape];if(null==o)return console.error(`No shape with type ${i.shape}`),new e;const s=V(i.params??{}),r=o.geometry(s),a=null!=i.material?await n.getMaterial(i.material):function(){const t=R(new d("instanceColor")).rgb(),e=R(new l("particleData")).x();return new m({color:y({color:t}).rgb().rgba(e),transparent:!0})}();return new t.Mesh(r,a)}(i.output,n));break;case"mesh":j=new o(await async function(i,n){if(null==i.assetId)return console.warn("Can't use mesh as particle without asset id"),new e;const o=await n.getMesh(i.assetId),s=await n.getAsset(i.assetId),r=[];if(null!=s.materialAssignments)for(const e of s.materialAssignments)o.traverse((i=>{i instanceof t.Mesh&&i.material instanceof t.Material&&i.material.color instanceof t.Color&&(i.material.name!=e.name&&null!=e.name||"#"+i.material.color.getHexString()!==e.color||r.push(n.getMaterial(e.materialId).then((t=>i.material=t))))}));return await Promise.all(r),o.traverse((t=>{})),o}(i.output,n));break;case"trail":j=new o({type:"trail",taper:i.output.taper,headGeometry:null,dragTexture:!1,color:i.output.color,colorEnd:i.output.colorEnd,length:i.output.length,opacityStart:i.output.opacityStart,opacityEnd:i.output.opacityEnd,bloom:i.output.bloom});break;default:console.error("Failed to create particly system body: "+JSON.stringify(i))}const k=new K;k.parent=s,k.setRate(u),k._space=i.output.space;const G=await Promise.all(i.initializers.filter((t=>null!=D[t.type])).map((async t=>{const e=D[t.type],i=await V(t.params??{});return e.build(i)})));G.push(j,new C),k.addInitializers(G);const O=await Promise.all(i.behaviours.filter((t=>null!=H[t.type])).map((async t=>{const e=H[t.type],i=await V(t.params??{});return e.build(i)})));O.push(new N),k.addBehaviours(O);for(const t of i.children){const e=await q(t,n,s),i=new EmitterPool((()=>{const t=e.clone();return t.onExpired=()=>{const e=k.childEmitters.findIndex((e=>e.id===t.id));-1!=e&&k.childEmitters.splice(e,1),i.release(t)},t})),o=k.eventDispatcher,r=new Map;k.bindEmitterEvent=!0,o.addEventListener("PARTICLE_DEAD",(t=>{const e=r.get(t.id);if(null!=e){const t=k.childEmitters.findIndex((t=>t.id===e.id));null!=t&&e.stopEmit()}})),o.addEventListener("PARTICLE_CREATED",(t=>{const e=i.get();e.age=0,e.totalEmitTimes=-1,e.particles.length=0,e.currentEmitTime=0,e.cID=0,k.childEmitters.push(e),r.set(t.id,e),e.parentParticle=t,e.emit()}))}return k}const W=(new t.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=");class L extends m{get color(){return this.uniforms.color.value}set color(e){this.uniforms.color.value=new t.Color(e)}}class N extends n{initialize(e){if(e.body instanceof t.Mesh){const t=e.body.material;t instanceof m&&(null!=t.uniforms[j]||null!=t.uniforms[k])&&(e.body.material=t.clone())}}mutate(e,i,n){if(this.energize(e,i),e.target instanceof t.Mesh){const t=e.target.material;t instanceof m&&(null!=t.uniforms[j]&&(t.uniforms[j].value=this.energy),null!=t.uniforms[k]&&(t.uniforms[k].value=e.velocity))}}}class K extends s{constructor(){super(...arguments),this.childEmitters=[],this.bindEmitterEvent=!1,this.onExpired=()=>{}}update(t){if(!this.isEmitting&&0===this.particles.length)return;this.age+=t,(this.dead||this.age>=this.life)&&this.destroy(),this.generate(t),this.integrate(t);let e=this.particles.length;for(;e--;){const t=this.particles[e];t.dead&&(this.parent&&this.parent.dispatch("PARTICLE_DEAD",t),this.bindEmitterEvent&&this.dispatch("PARTICLE_DEAD",t),this.parent.pool.expire(t.reset()),this.particles.splice(e,1))}if(this.updateEmitterBehaviours(t),this.isEmitting||0!==this.particles.length)for(const e of this.childEmitters)null!=e.parentParticle?e.position.copy(e.parentParticle.position):e.setPosition(this.position),e.update(t);else this.onExpired()}clone(){const t=new K;return t.setRate(this.rate.clone()),t.behaviours=this.behaviours,t.initializers=this.initializers,t._space=this._space,t.body=this.body,t.parent=this.parent,t}setParentRecursive(t){this.parent=t,this.childEmitters.forEach((e=>e.setParentRecursive(t)))}}export class EmitterPool{constructor(t){this.creator=t,this.instances=[]}get(){0==this.instances.length&&this.instances.push(this.creator());return this.instances.pop()}release(t){this.instances.push(t)}dispose(){this.instances.length=0}}
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { VfxAsset } from 'scene/model';
|
2
|
+
import * as THREE from 'three';
|
3
|
+
import { Object3D } from 'three';
|
4
|
+
import System from 'three-nebula';
|
5
|
+
import { MeshRenderer, Rate } from 'three-nebula';
|
6
|
+
export declare function materializeVfxOld(asset: VfxAsset, target: Object3D): {
|
7
|
+
system: System;
|
8
|
+
rate: Rate;
|
9
|
+
renderer: MeshRenderer;
|
10
|
+
dispose: () => THREE.Object3D<THREE.Object3DEventMap>;
|
11
|
+
};
|
@@ -0,0 +1,5 @@
|
|
1
|
+
import*as e from"three";import{Object3D as n}from"three";import t from"three-nebula";import{Body as r,BoxZone as a,Emitter as o,Force as i,Life as w,Mass as d,MeshRenderer as m,PointZone as s,Position as l,RadialVelocity as f,Radius as p,Rate as c,Rotate as h,Scale as u,Span as v,Vector3D as x,ease as M}from"three-nebula";import{RotatePosition as b}from"./behaviours";import{OnceRate as E}from"./rates";export function materializeVfxOld(I,y){let z=y;if(!0!==I.vfx.localSpace)for(;null!=z.parent;)z=z.parent;const B=new n;B.name="particle system",z.add(B);const O=new m(B,e),P=new e.Mesh(new e.BoxGeometry(.3,.3,.3),new e.MeshStandardMaterial({color:16777215})),R=new c(new v(3,9),new v(.02,.15)),L=new o,S=new t;L.setLife(4).setRate(R).addInitializers([new d(1),new p(1),new w(1),new r(P),new l(new a(.5)),new f(10,new x(0,0,1),30)]).addBehaviours([new b(new e.Vector3(0,0,1),4),new i(0,0,.1),new h("random",2.5*-Math.PI,2*Math.PI,1,M.easeOutCubic),new u(1,.2)]).emit();const V=new E(0),g=(new o).setLife(5).addInitializers([new d(1),new p(1),new w(3),new r(P),new l(new s(0,0,0))]).addBehaviours([new u(4,6,void 0,M.easeOutExpo)]).setRate(V).emit();return V.nextTime=0,S.addEmitter(L).addEmitter(g).addRenderer(O).emit({onEnd:()=>{console.log("ended")}}),{system:S,rate:R,renderer:O,dispose:()=>B.removeFromParent()}}
|
2
|
+
/*
|
3
|
+
* Copyright (©) 2023. All rights reserved.
|
4
|
+
* See the LICENSE.md file for details.
|
5
|
+
*/
|
@@ -20,9 +20,9 @@ export declare class VisualEffect {
|
|
20
20
|
* @param parent The object that the VFX should be parented to to make particles spawn relative to its location.
|
21
21
|
* @returns
|
22
22
|
*/
|
23
|
-
createPool(parent: Object3D | BaseActor):
|
23
|
+
createPool(parent: Object3D | BaseActor): VfxPool<VfxActor>;
|
24
24
|
}
|
25
|
-
declare class
|
25
|
+
export declare class VfxPool<T extends VfxActor = VfxActor> {
|
26
26
|
private creator;
|
27
27
|
instances: T[];
|
28
28
|
constructor(creator: () => Promise<T>);
|
@@ -38,4 +38,3 @@ declare class Pool<T extends VfxActor> {
|
|
38
38
|
release(instance: T): void;
|
39
39
|
dispose(): void;
|
40
40
|
}
|
41
|
-
export {};
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{VfxActor as t}from"./vfx-actor.js";import{BaseActor as s}from"../../gameplay/index.js";export class VisualEffect{constructor(t,s){this.actorProvider=t,this.asset=s}async create(e){const a=await this.actorProvider.create(t);return e instanceof s?e.object.add(a.object):e.add(a.object),await a.fromAsset(this.asset),a}createPool(t){return new
|
1
|
+
import{VfxActor as t}from"./vfx-actor.js";import{BaseActor as s}from"../../gameplay/index.js";export class VisualEffect{constructor(t,s){this.actorProvider=t,this.asset=s}async create(e){const a=await this.actorProvider.create(t);return e instanceof s?e.object.add(a.object):e.add(a.object),await a.fromAsset(this.asset),a}createPool(t){return new VfxPool((()=>this.create(t)))}}export class VfxPool{constructor(t){this.creator=t,this.instances=[]}async get(){0==this.instances.length&&this.instances.push(await this.creator());const t=this.instances.shift();return t.restart(),t}release(t){this.instances.push(t)}dispose(){this.instances.length=0}}
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,11 +1,15 @@
|
|
1
1
|
import * as THREE from 'three';
|
2
2
|
import { Object3D } from 'three';
|
3
3
|
import { CustomRenderer, MeshRenderer, Particle } from 'three-nebula';
|
4
|
+
import { ViewController } from '../../gameplay';
|
4
5
|
export declare class MultiRenderer extends CustomRenderer {
|
5
|
-
private
|
6
|
+
private worldContainer;
|
7
|
+
private localContainer;
|
6
8
|
private three;
|
7
|
-
private
|
8
|
-
|
9
|
+
private view;
|
10
|
+
private localRenderers;
|
11
|
+
private worldRenderers;
|
12
|
+
constructor(worldContainer: Object3D, localContainer: Object3D, three: typeof THREE, view: ViewController);
|
9
13
|
onSystemUpdate(): void;
|
10
14
|
onParticleCreated(particle: Particle): void;
|
11
15
|
onParticleUpdate(particle: Particle): void;
|
@@ -13,6 +17,28 @@ export declare class MultiRenderer extends CustomRenderer {
|
|
13
17
|
private getRenderer;
|
14
18
|
dispose(): void;
|
15
19
|
}
|
20
|
+
export type ParticleTemplate = TrailTemplate;
|
21
|
+
export type TrailTemplate = {
|
22
|
+
type: 'trail';
|
23
|
+
headGeometry?: THREE.BufferGeometry;
|
24
|
+
length: number;
|
25
|
+
material?: THREE.ShaderMaterial;
|
26
|
+
dragTexture?: boolean;
|
27
|
+
taper: boolean;
|
28
|
+
color: string;
|
29
|
+
colorEnd: string;
|
30
|
+
opacityStart: number;
|
31
|
+
opacityEnd: number;
|
32
|
+
bloom: boolean;
|
33
|
+
};
|
34
|
+
export declare class TrailRenderer extends MeshRenderer {
|
35
|
+
private trails;
|
36
|
+
dispose(): void;
|
37
|
+
onSystemUpdate(): void;
|
38
|
+
onParticleCreated(particle: Particle): void;
|
39
|
+
onParticleUpdate(particle: Particle): void;
|
40
|
+
onParticleDead(particle: Particle): void;
|
41
|
+
}
|
16
42
|
export declare class CombinedRenderer extends MeshRenderer {
|
17
43
|
dispose(): void;
|
18
44
|
scale(particle: any): void;
|
@@ -24,8 +50,29 @@ export declare class CombinedRenderer extends MeshRenderer {
|
|
24
50
|
onParticleUpdate(particle: any): void;
|
25
51
|
onParticleDead(particle: any): void;
|
26
52
|
}
|
53
|
+
export declare class StretchedSpriteInstancedRenderer extends MeshRenderer {
|
54
|
+
private view;
|
55
|
+
constructor(container: THREE.Object3D, three: typeof THREE, view: ViewController);
|
56
|
+
dispose(): void;
|
57
|
+
onSystemUpdate(): void;
|
58
|
+
private meshes;
|
59
|
+
onParticleCreated(particle: Particle & {
|
60
|
+
body?: MeshRenderer['_body'];
|
61
|
+
target: any;
|
62
|
+
}): void;
|
63
|
+
onParticleUpdate(particle: any): void;
|
64
|
+
onParticleDead(particle: any): void;
|
65
|
+
}
|
66
|
+
type InstancedMeshInfo = {
|
67
|
+
mesh: THREE.InstancedMesh<THREE.BufferGeometry, THREE.Material>;
|
68
|
+
indices: number[];
|
69
|
+
particles: Particle[];
|
70
|
+
};
|
27
71
|
export declare class InstancedRenderer extends MeshRenderer {
|
72
|
+
private view;
|
73
|
+
constructor(container: THREE.Object3D, three: typeof THREE, view: ViewController);
|
28
74
|
dispose(): void;
|
75
|
+
onSystemUpdate(): void;
|
29
76
|
private meshes;
|
30
77
|
onParticleCreated(particle: Particle & {
|
31
78
|
body?: MeshRenderer['_body'];
|
@@ -34,3 +81,11 @@ export declare class InstancedRenderer extends MeshRenderer {
|
|
34
81
|
onParticleUpdate(particle: any): void;
|
35
82
|
onParticleDead(particle: any): void;
|
36
83
|
}
|
84
|
+
/**
|
85
|
+
* Sorts the instances of an InstancedMesh by their distance from the camera.
|
86
|
+
*
|
87
|
+
* @param instancedMesh - The InstancedMesh to sort.
|
88
|
+
* @param camera - The camera from which to calculate distances.
|
89
|
+
*/
|
90
|
+
declare function sortInstancedMeshByDistance(mesh: InstancedMeshInfo, camera: THREE.Camera): void;
|
91
|
+
export { sortInstancedMeshByDistance };
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import*as e from"three";import{Object3D as t}from"three";import{CustomRenderer as r,MeshRenderer as i,PUID as a}from"three-nebula";import{NodeShaderMaterial as s}from"three-shader-graph";var n;!function(e){e[e.mesh=0]="mesh",e[e.instanced=1]="instanced",e[e.sprite=2]="sprite"}(n||(n={}));export class MultiRenderer extends r{constructor(e,t){super(),this.container=e,this.three=t,this.renderers=[]}onSystemUpdate(){}onParticleCreated(e){this.getRenderer(e)?.onParticleCreated(e)}onParticleUpdate(e){this.getRenderer(e)?.onParticleUpdate(e)}onParticleDead(e){this.getRenderer(e)?.onParticleDead(e)}getRenderer(t){return t._renderer?t._renderer:t.body instanceof e.Sprite?(this.renderers[n.sprite]||(this.renderers[n.sprite]=new CombinedRenderer(this.container,this.three)),t._renderer=this.renderers[n.sprite]):t.body instanceof e.Mesh&&0==t.body.children.length&&t.body.material instanceof s?(this.renderers[n.instanced]||(this.renderers[n.instanced]=new InstancedRenderer(this.container,this.three)),t._renderer=this.renderers[n.instanced]):t.body instanceof e.Object3D?(this.renderers[n.mesh]||(this.renderers[n.mesh]=new CombinedRenderer(this.container,this.three)),t._renderer=this.renderers[n.mesh]):void 0}dispose(){this.renderers.forEach((e=>{e instanceof InstancedRenderer&&e.dispose()}))}}export class CombinedRenderer extends i{dispose(){}scale(t){const r=t.transform.initialScale;t.target instanceof e.Sprite?null!=r?t.target.scale.set(r.x*t.scale*t.radius,r.y*t.scale*t.radius,1):t.target.scale.set(t.scale*t.radius,t.scale*t.radius,1):null!=r?t.target.scale.set(r.x*t.scale,r.y*t.scale,r.z*t.scale):super.scale(t)}rotate(e){e.target.material.rotation=e.rotation.z}onParticleCreated(r){r.target||(r.target=this._targetPool.get(r.body),(r.useAlpha||r.useColor)&&(r.target instanceof e.Mesh||r.target instanceof e.Sprite&&r.target.material instanceof e.Material)&&(r.target.material.__puid=a.id(r.body.material),r.target.material=this._materialPool.get(r.target.material))),r.target&&r.target instanceof t&&(r.target.position.set(r.position.x,r.position.y,r.position.z),this.container.add(r.target))}onParticleUpdate(r){const{target:i,useAlpha:a,useColor:s,rotation:n}=r;if(i){if(i.position.copy(r.position),this.isThreeSprite(r)||i.rotation.set(n.x,n.y,n.z),this.scale(r),r.transform&&r.transform.orientAlongVelocity&&i instanceof t){const e=o.set(r.velocity.x,r.velocity.y,r.velocity.z).normalize(),t=i.getWorldDirection(l);t.applyAxisAngle(d,Math.PI/-2),c.setFromUnitVectors(t,e),i.quaternion.copy(c)}i.material instanceof e.Material&&(a&&(i.material.opacity=r.alpha,i.material.transparent=!0),s&&null!=i.material.color&&i.material.color.copy(r.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)}}const o=new e.Vector3,l=new e.Vector3,c=new e.Quaternion,d=new e.Vector3(1,0,0);export class InstancedRenderer extends i{constructor(){super(...arguments),this.meshes=[]}dispose(){this.meshes.forEach((e=>e.mesh.dispose()))}onParticleCreated(t){if(!(t.body instanceof e.Sprite)){if(null==t.target){const r=t.body;let i=this.meshes.find((e=>e.mesh.geometry.uuid===r.geometry.uuid&&e.mesh.material.uuid===r.material.uuid));if(null==i){const a=t.parent.rate,s=Math.min(Math.ceil(a.numPan.b/Math.min(Math.max(a.timePan.a,.01),1)),1e5);i={mesh:new e.InstancedMesh(r.geometry,r.material,s),indices:new Array(s).fill(null)},i.mesh.setColorAt(0,x.copy(new e.Color(t.color)));const n=new Float32Array(3*s);u.makeScale(0,0,0);for(let e=0;e<s;e++)n[3*e+0]=1,n[3*e+1]=1,i.mesh.setMatrixAt(e,u);i.mesh.instanceMatrix.needsUpdate=!0,i.mesh.geometry.setAttribute("particleData",new e.InstancedBufferAttribute(n,3)),this.meshes.push(i),this.container.add(i.mesh)}let a=i.indices.findIndex((e=>null==e));a<0&&(a=i.indices.indexOf(Math.min(...i.indices))),i.indices[a]=performance.now(),t.target=a}if("number"==typeof t.target){t.transform.initialScale;const e=t.body;let r=this.meshes.find((t=>t.mesh.geometry.uuid===e.geometry.uuid&&t.mesh.material.uuid===e.material.uuid));h(t,r.mesh),t.useAlpha&&(r.mesh.material.transparent=!0)}}}onParticleUpdate(e){const{target:t,useAlpha:r,useColor:i,rotation:a}=e;if(null==t)return;const s=e.body;let n=this.meshes.find((e=>e.mesh.geometry.uuid===s.geometry.uuid&&e.mesh.material.uuid===s.material.uuid));if(h(e,n.mesh),i&&(n.mesh.setColorAt(e.target,x.copy(e.color)),n.mesh.instanceColor.needsUpdate=!0),r){const t=n.mesh.geometry.getAttribute("particleData");t.setX(e.target,e.alpha),t.needsUpdate=!0}}onParticleDead(e){if(null!=e.target){const t=e.body;let r=this.meshes.find((e=>e.mesh.geometry.uuid===t.geometry.uuid&&e.mesh.material.uuid===t.material.uuid));r.indices[e.target]=null,e.scale=0,h(e,r.mesh),r.mesh.instanceMatrix.needsUpdate=!0,e.target=null}}}const m=new t;function h(e,t){if(g.set(e.position.x,e.position.y,e.position.z),e.transform&&e.transform.orientAlongVelocity){const r=o.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,m.matrix);const i=m.getWorldDirection(f);i.applyAxisAngle(d,Math.PI/-2),p.setFromUnitVectors(i,r)}else y.set(e.rotation.x,e.rotation.y,e.rotation.z),p.setFromEuler(y);const r=e.transform.initialScale;null!=r?f.set(r.x*e.scale,r.y*e.scale,r.z*e.scale):f.set(e.scale,e.scale,e.scale),u.compose(g,p,f),t.setMatrixAt(e.target,u),t.instanceMatrix.needsUpdate=!0}const u=new e.Matrix4,p=new e.Quaternion,g=new e.Vector3,f=new e.Vector3,y=new e.Euler,x=new e.Color(0);
|
1
|
+
import*as e from"three";import{InstancedBufferAttribute as t,Object3D as r}from"three";import{CustomRenderer as a,MeshRenderer as s,PUID as i}from"three-nebula";import{NodeShaderMaterial as o}from"three-shader-graph";import{StretchedSprite as n}from"./stretched-sprite.js";import{Trail as l}from"./trail-renderer.js";var c;!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"}(c||(c={}));export class MultiRenderer extends a{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){this.getRenderer(e)?.onParticleCreated(e)}onParticleUpdate(e){this.getRenderer(e)?.onParticleUpdate(e)}onParticleDead(e){this.getRenderer(e)?.onParticleDead(e),e._renderer=null}getRenderer(t){if(t._renderer)return t._renderer;const r=t?.parent._space??"world",a="world"===r?this.worldContainer:this.localContainer,s="world"===r?this.worldRenderers:this.localRenderers;return"trail"===t.body.type?(null==s[c.trail]&&(s[c.trail]=new TrailRenderer(a,this.three)),t._renderer=s[c.trail]):t.body instanceof n?(null==s[c.stretchedBillboard]&&(s[c.stretchedBillboard]=new StretchedSpriteInstancedRenderer(a,this.three,this.view)),t._renderer=s[c.stretchedBillboard]):t.body instanceof e.Sprite||t.body instanceof e.Mesh&&"sprite"===t.body.name?(null==s[c.sprite]&&(s[c.sprite]=new CombinedRenderer(a,this.three)),t._renderer=s[c.sprite]):t.body instanceof e.Mesh&&0==t.body.children.length&&t.body.material instanceof o?(null==s[c.instanced]&&(s[c.instanced]=new InstancedRenderer(a,this.three,this.view)),t._renderer=s[c.instanced]):t.body instanceof e.Object3D?(null==s[c.mesh]&&(s[c.mesh]=new CombinedRenderer(a,this.three)),t._renderer=s[c.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 s{constructor(){super(...arguments),this.trails=[]}dispose(){}onSystemUpdate(){for(const e of this.trails)e.update()}onParticleCreated(t){const a=t.body,s=new l(this.container,!0),i=new r,o=l.createBaseMaterial();o.uniforms.taper.value=a.taper??!1;const n=new e.Color(a.color??0),c=new e.Color(a.colorEnd??0);o.uniforms.headColor.value.set(n.r,n.g,n.b,a.opacityStart??1),o.uniforms.tailColor.value.set(c.r,c.g,c.b,a.opacityEnd??1),a.bloom&&(o.userData.hasBloom=!0),s.initialize(o,Math.round(a.length??10),!1,0,null,i);const d=t.rotation;i.rotation.set(d.x,d.y,d.z);t.scale;s.activate(),this.trails.push(s),t.target=i}onParticleUpdate(e){const t=e.target;t.position.copy(e.position);e.velocity.clone().normalize();const r=this.trails.findIndex((e=>e.targetObject.id===t.id));if(-1!=r){const t=this.trails[r];if(e.useAlpha){t.material.uniforms.headColor.value.setW(e.alpha);t.material.uniforms.tailColor.value.setW(e.alpha)}}}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(),t.removeFromParent(),this.trails.splice(r,1)}}}export class CombinedRenderer extends s{dispose(){}scale(t){const r=t.transform.initialScale;t.target instanceof e.Sprite?null!=r?t.target.scale.set(r.x*t.scale*t.radius,r.y*t.scale*t.radius,1):t.target.scale.set(t.scale*t.radius,t.scale*t.radius,1):null!=r?t.target.scale.set(r.x*t.scale,r.y*t.scale,r.z*t.scale):super.scale(t)}rotate(e){e.target.material.rotation=e.rotation.z}onParticleCreated(t){t.target||(t.target=this._targetPool.get(t.body),(t.useAlpha||t.useColor)&&(t.target instanceof e.Mesh||t.target instanceof e.Sprite&&t.target.material instanceof e.Material)&&(t.target.material.__puid=i.id(t.body.material),t.target.material=this._materialPool.get(t.target.material))),t.target&&t.target instanceof r&&(t.target.position.set(t.position.x,t.position.y,t.position.z),this.container.add(t.target))}onParticleUpdate(t){const{target:a,useAlpha:s,useColor:i,rotation:o}=t;if(a){if(a.position.copy(t.position),this.isThreeSprite(t)||a.rotation.set(o.x,o.y,o.z),this.scale(t),t.transform&&t.transform.orientAlongVelocity&&a instanceof r){const e=d.set(t.velocity.x,t.velocity.y,t.velocity.z).normalize(),r=a.getWorldDirection(m);r.applyAxisAngle(p,Math.PI/-2),h.setFromUnitVectors(r,e),a.quaternion.copy(h)}a.material instanceof e.Material&&(s&&(a.material.opacity=t.alpha,a.material.transparent=!0),i&&null!=a.material.color&&a.material.color.copy(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 s{constructor(e,t,r){super(e,t),this.view=r,this.meshes=[]}dispose(){this.meshes.forEach((e=>e.mesh.geometry.dispose()))}onSystemUpdate(){for(const t of this.meshes){const r=t.mesh.geometry.getAttribute("offset"),a=t.mesh.geometry.getAttribute("size"),s=t.mesh.geometry.getAttribute("velocity"),i=t.mesh.geometry.getAttribute("rotation"),o=t.mesh.geometry.getAttribute("color");let n=0;for(const l of t.particles){if(null==l||l.dead)continue;if(l.useColor||l.color instanceof e.Color){const e=A.copy(l.color).getRGB(U);o.setXYZW(n,e.r,e.g,e.b,1),o.needsUpdate=!0}l.useAlpha&&(o.setW(n,l.alpha),o.needsUpdate=!0),"number"==typeof l.rotation?i.setX(n,l.rotation):i.setX(n,l.rotation.x);const t=l.position;if(r.setXYZ(n,t.x,t.y,t.z),"number"!=typeof l.scale)throw new Error("Particle scale is not a number");a.setXYZ(n,l.scale,l.scale,l.scale);let c=l.body.scaleFactor;0===c&&(c=.001);const d=1,m=l.velocity;s.setXYZW(n,m.x*c,m.y*c,m.z*c,d),n++}n>0&&(r.clearUpdateRanges(),r.addUpdateRange(0,3*n),r.needsUpdate=!0,a.clearUpdateRanges(),a.addUpdateRange(0,3*n),a.needsUpdate=!0,o.clearUpdateRanges(),o.addUpdateRange(0,4*n),o.needsUpdate=!0,s.clearUpdateRanges(),s.addUpdateRange(0,4*n),s.needsUpdate=!0,i.clearUpdateRanges(),i.addUpdateRange(0,n),i.needsUpdate=!0)}}onParticleCreated(r){if(r.body instanceof n&&null==r.target){const a=r.body;let s=this.meshes.find((e=>e.mesh.material.uuid===a.material.uuid));if(null==s){const i=R(r),o=new e.InstancedBufferGeometry;o.setIndex(a.geometry.getIndex()),o.setAttribute("position",a.geometry.getAttribute("position")),a.geometry.hasAttribute("normal")&&o.setAttribute("normal",a.geometry.getAttribute("normal")),o.setAttribute("uv",a.geometry.getAttribute("uv"));const n=new t(new Float32Array(3*i),3);n.setUsage(e.DynamicDrawUsage),o.setAttribute("offset",n);const l=new t(new Float32Array(4*i),4);l.setUsage(e.DynamicDrawUsage),o.setAttribute("color",l);const c=new t(new Float32Array(3*i),3);c.setUsage(e.DynamicDrawUsage),o.setAttribute("size",c);const d=new t(new Float32Array(4*i),4);d.setUsage(e.DynamicDrawUsage),o.setAttribute("velocity",d);const m=new t(new Float32Array(4*i),1);m.setUsage(e.DynamicDrawUsage),o.setAttribute("rotation",m),s={mesh:new e.Mesh(o,a.material),indices:new Float32Array(i),particles:[]},this.meshes.push(s),this.container.add(s.mesh)}let i=s.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}(s.indices)),s.indices[i]=performance.now(),r.target=i,s.particles[i]=r}}onParticleUpdate(e){}onParticleDead(e){const t=e.body;let r=this.meshes.find((e=>e.mesh.material.uuid===t.material.uuid));r&&(r.particles[e.target]=null,r.indices[e.target]=0),e.target=null}}const d=new e.Vector3,m=new e.Vector3,h=new e.Quaternion,p=new e.Vector3(1,0,0);export class InstancedRenderer extends s{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);}onParticleCreated(t){if(!(t.body instanceof e.Sprite)){if(null==t.target){const r=t.body;let a=this.meshes.find((e=>e.mesh.geometry.uuid===r.geometry.uuid&&e.mesh.material.uuid===r.material.uuid));if(null==a){const s=t.parent.rate,i=Math.min(Math.ceil(s.numPan.b/Math.min(Math.max(s.timePan.a,.01),1)),1e5);a={mesh:new e.InstancedMesh(r.geometry,r.material,i),indices:new Array(i).fill(null),particles:[]},a.mesh.setColorAt(0,A.copy(new e.Color(t.color))),a.mesh.instanceColor.needsUpdate=!0;const o=new Float32Array(3*i);f.makeScale(0,0,0);for(let e=0;e<i;e++)o[3*e+0]=1,o[3*e+1]=1,a.mesh.setMatrixAt(e,f);a.mesh.instanceMatrix.needsUpdate=!0,a.mesh.geometry.setAttribute("particleData",new e.InstancedBufferAttribute(o,3)),this.meshes.push(a),this.container.add(a.mesh)}let s=a.indices.findIndex((e=>null==e));s<0&&(s=a.indices.indexOf(Math.min(...a.indices))),a.indices[s]=performance.now(),t.target=s,a.particles[s]=t}if("number"==typeof t.target){t.transform.initialScale;const e=t.body;let r=this.meshes.find((t=>t.mesh.geometry.uuid===e.geometry.uuid&&t.mesh.material.uuid===e.material.uuid));g(t,r.mesh),t.useAlpha&&(r.mesh.material.transparent=!0)}}}onParticleUpdate(e){const{target:t,useAlpha:r,useColor:a,rotation:s}=e;if(null==t)return;const i=e.body;let o=this.meshes.find((e=>e.mesh.geometry.uuid===i.geometry.uuid&&e.mesh.material.uuid===i.material.uuid));if(g(e,o.mesh),a&&(o.mesh.setColorAt(e.target,A.copy(e.color)),o.mesh.instanceColor.needsUpdate=!0),r){const t=o.mesh.geometry.getAttribute("particleData");t.setX(e.target,e.alpha),t.needsUpdate=!0}}onParticleDead(e){if(null!=e.target){const t=e.body;let r=this.meshes.find((e=>e.mesh.geometry.uuid===t.geometry.uuid&&e.mesh.material.uuid===t.material.uuid));r.indices[e.target]=null,e.scale=0,g(e,r.mesh),r.mesh.instanceMatrix.needsUpdate=!0,e.target=null}}}const u=new r;function g(e,t){if(b.set(e.position.x,e.position.y,e.position.z),e.transform&&e.transform.orientAlongVelocity){const r=d.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,u.matrix);const a=u.getWorldDirection(w);a.applyAxisAngle(p,Math.PI/-2),y.setFromUnitVectors(a,r)}else x.set(e.rotation.x,e.rotation.y,e.rotation.z),y.setFromEuler(x);const r=e.transform.initialScale;null!=r?w.set(r.x*e.scale,r.y*e.scale,r.z*e.scale):w.set(e.scale,e.scale,e.scale),f.compose(b,y,w),t.setMatrixAt(e.target,f),t.instanceMatrix.needsUpdate=!0}const f=new e.Matrix4,y=new e.Quaternion,b=new e.Vector3,w=new e.Vector3,x=new e.Euler,A=new e.Color(0),U={r:0,g:0,b:0};function P(t,r){const a=t.mesh,s=a.count,i=[],o=a.geometry.getAttribute("particleData"),n=new e.Vector3;for(let l=0;l<s;l++){const s=new e.Matrix4,c=new e.Color;a.getMatrixAt(l,s),a.getColorAt(l,c);const d=o.getX(l);n.setFromMatrixPosition(s);const m=n.distanceTo(r.position);i.push({index:l,distance:m,matrix:s,particle:t.particles[l],color:c,pdx:d})}i.sort(((e,t)=>t.distance-e.distance));for(let e=0;e<s;e++){const t=i[e].matrix;null==i[e].particle&&t.makeScale(0,0,0),a.setMatrixAt(e,t),a.setColorAt(e,i[e].color),o.setX(e,i[e].pdx)}a.instanceMatrix.needsUpdate=!0}export{P as sortInstancedMeshByDistance};function R(e){const t=null!=e.parent.parentParticle?R(e.parent.parentParticle):1,r=e.parent.rate;return Math.min(Math.ceil(r.numPan.b/Math.min(Math.max(r.timePan.a,.01),1)),1e5)*e.life*t}
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { Object3D } from 'three';
|
2
|
+
import { BaseActor, VfxActor } from '../../gameplay';
|
3
|
+
import { Asset, AssetId } from '../../scene/model';
|
4
|
+
import { VfxPool } from './vfx-param';
|
5
|
+
export declare class VfxService {
|
6
|
+
private pools;
|
7
|
+
private actorFactory;
|
8
|
+
private assetService;
|
9
|
+
private world;
|
10
|
+
createFromAssetId(assetId: AssetId, parent?: Object3D | BaseActor): Promise<VfxActor>;
|
11
|
+
createFromAsset(asset: Asset, parent?: Object3D | BaseActor): Promise<VfxActor>;
|
12
|
+
createPoolFromAssetId(assetId: AssetId, parent?: Object3D | BaseActor): Promise<VfxPool>;
|
13
|
+
createPoolFromAsset(asset: Asset, parent?: Object3D | BaseActor): Promise<VfxPool<VfxActor>>;
|
14
|
+
}
|
@@ -0,0 +1,5 @@
|
|
1
|
+
import{__decorate as t}from"tslib";import{ActorFactory as s,AssetLoader as e,BaseActor as r,inject as o,Service as a,VfxActor as c,World as i}from"../../gameplay";import{VfxPool as n}from"./vfx-param";let h=class{constructor(){this.pools=new Map,this.actorFactory=o(s),this.assetService=o(e),this.world=o(i)}async createFromAssetId(t,s=this.world.scene){const e=await this.assetService.getAsset(t);return this.createFromAsset(e,s)}async createFromAsset(t,s=this.world.scene){const e=await this.actorFactory.create(c);return s instanceof r?s.object.add(e.object):s.add(e.object),await e.fromAsset(t),e}async createPoolFromAssetId(t,s=this.world.scene){const e=await this.assetService.getAsset(t);return this.createPoolFromAsset(e,s)}async createPoolFromAsset(t,s=this.world.scene){let e;return this.pools.has(t.id)||(e=new n((()=>this.createFromAsset(t,s))),this.pools.set(t.id,e)),e}};h=t([a()],h);export{h as VfxService};
|
2
|
+
/*
|
3
|
+
* Copyright (©) 2023. All rights reserved.
|
4
|
+
* See the LICENSE.md file for details.
|
5
|
+
*/
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{__decorate as t}from"tslib";import{ActorComponent as i,Component as e}from"../../../component.js";import{RootMotionClip as s}from"../../../../animation/root-motion.js";import{inject as r}from"../../../../inject.js";import{ViewController as o}from"../../../../services/render.js";import{AnimationMixer as n,Bone as p,LoopOnce as l}from"three";let h=class extends i{constructor(){super(...arguments),this.viewController=r(o),this.stateMachines=[],this.upperStateMachines=[],this.fadeTime=.2,this.movementSpeed=null,this.upperBodyTimer=0,this.upperBodyOverride=!1,this.fullBodyTimer=0,this.currentFullBodyPriority=-1,this.currentUpperBodyPriority=-1,this.getFullBodyClip=a((t=>t.uuid),(t=>u(this.fullBodyMask,t))),this.getUpperBodyClip=a((t=>t.uuid),(t=>u(this.upperBodyMask,t)))}onInit(){this.viewController.onUpdate(this.actor).subscribe((t=>this.updateInternal(t)))}getRootMotionAction(){if(this.fullBodyAction.getClip()instanceof s)return this.fullBodyAction}setup(t,i,e){null!=i&&(this.upperBodyMask=c(i),this.fullBodyMask=function(t,i){const e=new Set(c(i).map((t=>t.uuid))),s=[];return t.traverse((t=>{(t instanceof p||t.isBone)&&!e.has(t.uuid)&&s.push(t)})),s}(function(t){let i;return t.traverse((t=>{(t instanceof p||t.isBone)&&null==i&&(i=t)})),i}(t),i)),null!=this.mixer&&this.mixer.stopAllAction(),this.mixer=new n(t)}updateStateMachines(t){this.stateMachines.forEach((i=>{i.step(t);const e=i.current.clip;null!=e&&this.play(e,{priority:0})})),this.upperStateMachines.forEach((i=>{i.step(t);const e=i.current.clip;null!=e?this.playUpper(e,{priority:0}):this.play(this.fullBodyClip)}))}updateInternal(t){null!=this.mixer&&(this.upperBodyTimer+=t,this.fullBodyTimer+=t,this.upperBodyAction&&this.upperBodyOverride&&this.upperBodyAction.getClip().duration-2*this.fadeTime<this.upperBodyTimer&&(this.upperBodyOverride=!1,null!=this.fullBodyClip&&this.transition(this.upperBodyAction,this.getUpperBodyClip(this.fullBodyClip))),this.fullBodyAction&&this.fullBodyAction.loop===l&&this.fullBodyAction.getClip().duration-2*this.fadeTime<this.fullBodyTimer&&(this.currentFullBodyPriority=-1),this.updateStateMachines(t),this.syncMovementSpeed(this.fullBodyAction),this.upperBodyOverride||this.syncMovementSpeed(this.upperBodyAction),this.mixer.update(t))}syncMovementSpeed(t){if(null!=t){const i=t.getClip();i instanceof s&&i.fixedInPlace&&null!=this.movementSpeed&&(t.timeScale=i.duration/i.displacement*this.movementSpeed)}}playStateMachine(t){this.stateMachines.push(t)}playUpperStateMachine(t){this.upperStateMachines.push(t)}removeStateMachine(t){this.stateMachines.
|
1
|
+
import{__decorate as t}from"tslib";import{ActorComponent as i,Component as e}from"../../../component.js";import{RootMotionClip as s}from"../../../../animation/root-motion.js";import{inject as r}from"../../../../inject.js";import{ViewController as o}from"../../../../services/render.js";import{AnimationMixer as n,Bone as p,LoopOnce as l}from"three";let h=class extends i{constructor(){super(...arguments),this.viewController=r(o),this.stateMachines=[],this.upperStateMachines=[],this.fadeTime=.2,this.movementSpeed=null,this.upperBodyTimer=0,this.upperBodyOverride=!1,this.fullBodyTimer=0,this.currentFullBodyPriority=-1,this.currentUpperBodyPriority=-1,this.getFullBodyClip=a((t=>t.uuid),(t=>u(this.fullBodyMask,t))),this.getUpperBodyClip=a((t=>t.uuid),(t=>u(this.upperBodyMask,t)))}onInit(){this.viewController.onUpdate(this.actor).subscribe((t=>this.updateInternal(t)))}getRootMotionAction(){if(this.fullBodyAction.getClip()instanceof s)return this.fullBodyAction}setup(t,i,e){null!=i&&(this.upperBodyMask=c(i),this.fullBodyMask=function(t,i){const e=new Set(c(i).map((t=>t.uuid))),s=[];return t.traverse((t=>{(t instanceof p||t.isBone)&&!e.has(t.uuid)&&s.push(t)})),s}(function(t){let i;return t.traverse((t=>{(t instanceof p||t.isBone)&&null==i&&(i=t)})),i}(t),i)),null!=this.mixer&&this.mixer.stopAllAction(),this.mixer=new n(t)}updateStateMachines(t){this.stateMachines.forEach((i=>{i.step(t);const e=i.current.clip;null!=e&&this.play(e,{priority:0})})),this.upperStateMachines.forEach((i=>{i.step(t);const e=i.current.clip;null!=e?this.playUpper(e,{priority:0}):this.play(this.fullBodyClip)}))}updateInternal(t){null!=this.mixer&&(this.upperBodyTimer+=t,this.fullBodyTimer+=t,this.upperBodyAction&&this.upperBodyOverride&&this.upperBodyAction.getClip().duration-2*this.fadeTime<this.upperBodyTimer&&(this.upperBodyOverride=!1,null!=this.fullBodyClip&&this.transition(this.upperBodyAction,this.getUpperBodyClip(this.fullBodyClip))),this.fullBodyAction&&this.fullBodyAction.loop===l&&this.fullBodyAction.getClip().duration-2*this.fadeTime<this.fullBodyTimer&&(this.currentFullBodyPriority=-1),this.updateStateMachines(t),this.syncMovementSpeed(this.fullBodyAction),this.upperBodyOverride||this.syncMovementSpeed(this.upperBodyAction),this.mixer.update(t))}syncMovementSpeed(t){if(null!=t){const i=t.getClip();i instanceof s&&i.fixedInPlace&&null!=this.movementSpeed&&(t.timeScale=i.duration/i.displacement*this.movementSpeed)}}playStateMachine(t){this.stateMachines.push(t)}playUpperStateMachine(t){this.upperStateMachines.push(t)}removeStateMachine(t){const i=this.stateMachines.indexOf(t);i>=0&&this.stateMachines.splice(i,1)}removeUpperStateMachine(t){const i=this.upperStateMachines.indexOf(t);i>=0&&this.upperStateMachines.splice(i,1)}playUpper(t,i={}){const e=i?.priority??1;e<this.currentUpperBodyPriority||(this.currentUpperBodyPriority=e,this.upperBodyAction=this.transition(this.upperBodyAction,this.getUpperBodyClip(t),i),this.upperBodyTimer=0,this.upperBodyOverride=!0)}play(t,i={}){!function(t,i){if(!1===t||"function"==typeof t&&!1===t())throw new Error(i)}(null!=this.mixer,"Can't play animation before setup is called");const e=i.priority??1;e<this.currentFullBodyPriority||(this.currentFullBodyPriority=e,this.fullBodyTimer=0,this.upperBodyOverride||(this.upperBodyAction=this.transition(this.upperBodyAction,this.getUpperBodyClip(t),i)),this.fullBodyClip=t,this.fullBodyAction=this.transition(this.fullBodyAction,this.getFullBodyClip(t),i),this.fullBodyAction.getClip().uuid==this.upperBodyAction.getClip().uuid&&this.upperBodyAction.syncWith(this.fullBodyAction))}onActionDone(t){return new Promise((i=>{const e=s=>{s.action===t&&(i(s.action),this.mixer.removeEventListener("finished",e))};this.mixer.addEventListener("finished",e)}))}transition(t,i,e={}){if(null!=t&&t.getClip().uuid===i.uuid)return t;if(t){const e=t,s=t=this.mixer.clipAction(i);s.play(),s.enabled=!0,s.setEffectiveTimeScale(1),s.setEffectiveWeight(1),s.time=0,e.crossFadeTo(s,this.fadeTime,!0)}else t=this.mixer.clipAction(i),t?.fadeIn(.3),t?.play();return!1===e.loop&&(t.setLoop(l,1),t.clampWhenFinished=!0,t.reset()),t}};h=t([e()],h);export{h as CharacterAnimationComponent};function u(t,i){if(null==t)return i;const e=i.clone(),s=new Set(t.map((t=>t.name)));return e.tracks=e.tracks.filter((t=>s.has(t.name.split(".")[0]))),e}function c(t){return t.flatMap((t=>function(t){const i=[];return t.traverse((t=>{i.push(t)})),i}(t))).filter((t=>t instanceof p))}function a(t,i){const e=new Map;return(s,...r)=>{const o=t(s);return e.has(o)||e.set(o,i(s,...r)),e.get(o)}}
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -10,6 +10,7 @@ export declare class MeshComponent<TObj extends Object3D = Object3D> extends Act
|
|
10
10
|
readonly mass: number;
|
11
11
|
readonly friction: number;
|
12
12
|
readonly bodyType: PhysicsBodyType;
|
13
|
+
readonly isTrigger: boolean;
|
13
14
|
readonly continousCollisionDetection: boolean;
|
14
15
|
private currentMesh;
|
15
16
|
constructor(physicsSystem: PhysicsSystem);
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{__decorate as t,__metadata as s}from"tslib";import{PhysicsBodyType as i,PhysicsSystem as e}from"../../../../gameplay/services/physics/physics-system.js";import{AssetMeshInstance as o}from"../../../../scene/asset-resource-loader.js";import{PhysicalShapeMesh as r}from"../../../../index.js";import{Parameter as n}from"../../../../shader/parameter.js";import{Euler as c,Object3D as h,Vector3 as p}from"three";import{ActorComponent as a,Component as l}from"../../component.js";import{firstValueFrom as
|
1
|
+
import{__decorate as t,__metadata as s}from"tslib";import{PhysicsBodyType as i,PhysicsSystem as e}from"../../../../gameplay/services/physics/physics-system.js";import{AssetMeshInstance as o}from"../../../../scene/asset-resource-loader.js";import{PhysicalShapeMesh as r}from"../../../../index.js";import{Parameter as n}from"../../../../shader/parameter.js";import{Euler as c,Object3D as h,Vector3 as p}from"three";import{ActorComponent as a,Component as l}from"../../component.js";import{firstValueFrom as y}from"rxjs";const m={friction:.1,mass:0,bodyType:i.static,continousCollisionDetection:!1};let d=class extends a{constructor(t){super(),this.physicsSystem=t,this.position=new p,this.rotation=new c,this.scale=new p(1,1,1),this.mass=m.mass,this.friction=m.friction,this.bodyType=i.static,this.isTrigger=!1,this.continousCollisionDetection=m.continousCollisionDetection}onInit(){null!=this.object&&(this.currentMesh=this.object,this.updateMesh()),y(this.disposed).then((()=>{this.physicsSystem.removeActor(this.actor)}))}setObject(t){null!=this.currentMesh&&this.actor.object.remove(this.currentMesh),this.object=this.currentMesh=t,this.updateMesh()}updateMesh(){this.currentMesh.position.copy(this.position),this.currentMesh.rotation.copy(this.rotation),this.currentMesh.scale.copy(this.scale);const t=this.getCollisionShapes();t.length>0&&this.physicsSystem.addActor(this.actor,t,{...m,isTrigger:this.isTrigger??!1,mass:this.mass,friction:this.friction,type:this.bodyType,continousCollisionDetection:this.continousCollisionDetection}),this.actor.object.add(this.currentMesh)}getCollisionShapes(){return this.currentMesh instanceof o?this.currentMesh.collisionShapes:this.currentMesh instanceof r?[this.currentMesh.collisionShape]:"collisionShape"in this.currentMesh?(console.error("Could not understand wehre to get collision shapes from. This is likely due to an import issue"),[this.currentMesh.collisionShape]):[]}};t([n({type:h}),s("design:type",Object)],d.prototype,"object",void 0),t([n(),s("design:type",p)],d.prototype,"position",void 0),t([n(),s("design:type",c)],d.prototype,"rotation",void 0),t([n(),s("design:type",p)],d.prototype,"scale",void 0),t([n(),s("design:type",Number)],d.prototype,"mass",void 0),t([n(),s("design:type",Number)],d.prototype,"friction",void 0),t([n({options:[{name:"Static",value:i.static},{name:"Dynamic",value:i.dynamic}]}),s("design:type",Number)],d.prototype,"bodyType",void 0),t([n(),s("design:type",Boolean)],d.prototype,"isTrigger",void 0),d=t([l({inEditor:!0}),s("design:paramtypes",[e])],d);export{d as MeshComponent};
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
package/dist/gameplay/index.d.ts
CHANGED
package/dist/gameplay/index.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import"reflect-metadata";export{Container as DIContainer}from"typedi";export*from"./initiate.js";export*from"./inject.js";export{Service,Inject}from"typedi";export{ActorFactory}from"./actors/factory.js";export{Actor,BaseActor}from"./actors/actor.js";export{Component,ActorComponent,attach,Attach}from"./actors/component.js";export*from"./services/world.js";export*from"./services/render.js";export*from"./services/physics/physics-system.js";export*from"./animation/anim-sm.js";export*from"./animation/root-motion.js";export*from"./services/asset-loader.js";export*from"./services/pointer-events.js";export{VisualEffect}from"../effects/vfx/vfx-param.js";export*from"../shader/parameter.js";export*from"./ai/index.js";
|
1
|
+
import"reflect-metadata";export{Container as DIContainer}from"typedi";export*from"./initiate.js";export*from"./inject.js";export{Service,Inject}from"typedi";export{ActorFactory}from"./actors/factory.js";export{Actor,BaseActor}from"./actors/actor.js";export{Component,ActorComponent,attach,Attach}from"./actors/component.js";export*from"./services/world.js";export*from"./services/render.js";export*from"./services/physics/physics-system.js";export*from"./animation/anim-sm.js";export*from"./animation/root-motion.js";export*from"./services/asset-loader.js";export*from"./services/pointer-events.js";export{VisualEffect}from"../effects/vfx/vfx-param.js";export*from"../shader/parameter.js";export*from"./ai/index.js";export*from"../effects/vfx";
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -104,6 +104,14 @@ export declare class PhysicsSystem {
|
|
104
104
|
applyImpulse(actor: BaseActor, force: Vector3): void;
|
105
105
|
applyLocalForce(actor: BaseActor, force: Vector3, localPoint?: Vector3): void;
|
106
106
|
applyLocalImpulse(actor: BaseActor, force: Vector3, localPoint?: Vector3): void;
|
107
|
+
/**
|
108
|
+
* Apply an impulse on all dynamic physics bodies in the direction away from the given
|
109
|
+
* position.
|
110
|
+
* @param position The center of where the impulse should originate.
|
111
|
+
* @param radius Used to filter which objects should be affected.
|
112
|
+
* @param forceAmount
|
113
|
+
*/
|
114
|
+
private applyRadiusImpulse;
|
107
115
|
removeActor(actor: BaseActor): void;
|
108
116
|
removeSceneObject(object: Object3D): void;
|
109
117
|
private activateActorEvents;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{__decorate as t,__metadata as e}from"tslib";import*as i from"@dimforge/rapier3d-compat";import{QueryFilterFlags as s}from"@dimforge/rapier3d-compat";import{BehaviorSubject as o,distinctUntilChanged as r,filter as n,map as a,Subject as c,takeUntil as l}from"rxjs";import*as d from"three";import{ArrowHelper as h,BufferAttribute as u,BufferGeometry as y,Group as p,LineSegments as g,Matrix4 as m,MeshBasicMaterial as f,Object3D as w,Quaternion as v,Raycaster as x,Scene as B,Vector3 as b}from"three";import{Service as A}from"typedi";import{AssetMeshInstance as C}from"../../../scene/asset-resource-loader.js";import{BoxCollisionShape as D,CapsuleCollisionShape as z,ConeCollisionShape as M,ConvexPolyhedronCollisionShape as T,CylinderCollisionShape as R,PhysicalShapeMesh as S,PlaneCollisionShape as E,SphereCollisionShape as W,TrimeshCollisionShape as F}from"../../../index.js";import{LandscapeGroup as _}from"../../../scene/landscape/landscape.js";import{ViewController as V}from"../render.js";import{World as P}from"../world.js";import*as I from"three/examples/jsm/utils/BufferGeometryUtils.js";import{calculateEffectiveScale as L}from"../../../utils/three/traverse.js";export class RayTestResult{constructor(){this.hasHit=!1,this.hitPoint=new b,this.hitNormal=new b}}export var PhysicsBodyType;!function(t){t[t.dynamic=1]="dynamic",t[t.static=2]="static",t[t.kinematic=4]="kinematic",t[t.kinematicVelocityBased=8]="kinematicVelocityBased"}(PhysicsBodyType||(PhysicsBodyType={}));let k=class{set showDebug(t){this.shouldRenderDebug=t,this.debugMesh&&(this.debugMesh.visible=t)}get showDebug(){return this.shouldRenderDebug}constructor(t,e){this.viewController=t,this.gameWorld=e,this.staticMeshes=new Map,this.staticBodies=new Map,this.actorBodies=new Map,this.bodyActors=new Map,this.collisionEvents=new c,this.beforeStep=new c,this.afterStep=new c,this.shouldRenderDebug=!1,this._raycaster=new x,this._reusableResult=new RayTestResult,this._raytestDiff=new b,this._raytestDirection=new b,this.controlledActors=new Set,this.ready=this.setup()}createDebugMesh(){return new g(new y,new f({color:255}))}async start(){return await this.ready,this.handleTick(),this.ready}renderDebug(){null==this.debugMesh&&(this.debugMesh=this.createDebugMesh(),this.debugMesh.visible=this.shouldRenderDebug,this.debugMesh.raycast=function(){},this.gameWorld.scene.add(this.debugMesh));const t=this.world.debugRender();this.debugMesh.geometry.setAttribute("position",new u(t.vertices,3))}async setup(){if(null!=this.rapier)throw new Error("Rapier is already estup");this.rapier=await U(),this.eventQueue=new i.EventQueue(!0),this.setupWorld()}handleTick(){this.fixedupdateSub=this.viewController.onUpdate().subscribe((t=>{t=Math.min(.1,t),this.beforeStep.next(t),this.updatePhysics(t),this.afterStep.next(t),this.showDebug&&this.renderDebug(),this.world.bodies.forEach((t=>{if(t.isFixed())return;const e=this.staticMeshes.get(t)??this.bodyActors.get(t)?.object;var i,s;null!=e&&(e.parent instanceof B&&(X(e.position,t.translation()),(t.isDynamic()||t.isKinematic()&&!this.controlledActors.has(this.bodyActors.get(t)?.id))&&(i=e.quaternion,s=t.rotation(),i.x=s.x,i.y=s.y,i.z=s.z,i.w=s.w)))}))}))}_updateWorld(){this.world.timestep=0,this.world.step()}updatePhysics(t){this.world.timestep=t,this.world.step(this.eventQueue),this.eventQueue.drainCollisionEvents(((t,e,i)=>{this.collisionEvents.next({handle1:t,handle2:e,started:i}),this.collisionEvents.next({handle1:e,handle2:t,started:i})}))}rayTestFromCamera(t,e,i){this._raycaster.setFromCamera(H,this.viewController.getCamera());const s=this._raycaster.ray.origin,o=this._raycaster.ray.direction.multiplyScalar(t).add(s);return this.rayTest(s,o,e,i)}rayTest(t,e,s,o){null==s&&(s=this._reusableResult);const r=this._raytestDiff,n=this._raytestDirection;if(r.subVectors(e,t),n.copy(r).normalize(),0===n.length())return console.warn("Ray test called with to and from being equal"),s;const a=new i.Ray(t,n),c=r.length(),l=this.world.castRayAndGetNormal(a,c,!1,void 0,void 0,void 0,null!=o?.excludeActor?this.actorBodies.get(o.excludeActor.id):void 0,o?.excludeTriggers?t=>!t.isSensor():void 0);if(s.hasHit=null!=l,s.hasHit){const e=a.pointAt(l.timeOfImpact);s._internal=l,X(s.hitNormal,l.normal),X(s.hitPoint,e),s.distance=Y.subVectors(s.hitPoint,t).length();const i=this.world.bodies.getAll().find((t=>function(t,e){for(let i=0,s=t.numColliders();i<s;i++){const s=t.collider(i);if(e(s))return s}}(t,(t=>t===l.collider))));s.actor=null!=i?this.bodyActors.get(i):null}if(this.showDebug){const e=new h(n,t,c,o?.debugColor??255);this.gameWorld.scene.add(e),setTimeout((()=>this.gameWorld.scene.remove(e)),o?.debugLifetime??200)}return this._reusableResult}setGravity(t,e,i){this.world.gravity.x=t,this.world.gravity.y=e,this.world.gravity.z=i}getGravity(){return q.set(this.world.gravity.x,this.world.gravity.y,this.world.gravity.z)}addFromScene(t){this.addRecursively(t);for(const t of this.staticBodies.values())J(t,(t=>t.setActiveEvents(i.ActiveEvents.COLLISION_EVENTS)))}addRecursively(t){if(this.removeSceneObject(t),!function(t){if(null!=t.userData?.src){const e=t.userData?.src;return"actor"===e.type}return!1}(t))if(t instanceof S&&null!=t.collisionShape){const e=this.createStaticBody(t,[t.collisionShape],t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else if(t instanceof C&&!1!==t.userData?.src?.collisionDetection)if(t.children[0]&&t.children[0].instanceMatrix)this.createForInstancedMesh(t.children[0],t.collisionShapes);else{const e=this.createStaticBody(t,t.collisionShapes,t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else t instanceof _?this.addLandscapeGroup(t):(t instanceof p||t instanceof B)&&t.children.forEach((t=>this.addRecursively(t)))}createForInstancedMesh(t,e){const i=new m;for(let s=0;s<t.count;s++){const o=new w;o.matrix.identity(),i.fromArray(t.instanceMatrix.array,16*s),o.applyMatrix4(i);this.createStaticBody(o,e)}}getCharacterController(t=.01){return this.world?.createCharacterController(t)}getActorComputedMovement(t,e,i){const o=this.actorBodies.get(t.id);this.controlledActors.add(t.id);const r=o.collider(0);e.computeColliderMovement(r,i,s.EXCLUDE_SENSORS,null,$);const n=e.computedMovement();return X(Z,n),Z}setNextKinematicTranslation(t,e){const i=this.actorBodies.get(t.id),s=i.translation();s.x+=e.x,s.y+=e.y,s.z+=e.z,i?.setNextKinematicTranslation(s)}setAngularVelocity(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.setAngvel(G,!0)}setLinearVelocity(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.setLinvel(G,!0)}getLinearVelocity(t,e=new b){const i=this.actorBodies.get(t.id).linvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}getAngularVelocity(t,e=new b){const i=this.actorBodies.get(t.id).angvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}setLinearDamping(t,e){const i=this.actorBodies.get(t.id);i?.setLinearDamping(e)}setAngularDamping(t,e){const i=this.actorBodies.get(t.id);i?.setAngularDamping(e)}createCharacterCollision(){return new i.CharacterCollision}addLandscapeGroup(t){const e=t.userData.src,s=e.landscape.heightMaps;for(const r of t.sections){this.staticBodies.has(r)&&this.world.removeRigidBody(this.staticBodies.get(r));const t=e.landscape.options.density+1,n=e.landscape.options.sectionSize,a=new Array(t);for(let e=0;e<t;e++)a[e]=new Array(t).fill(0);const c=s.find((t=>t.x===r.x&&t.y==r.y));if(null!=c)for(const e of c.points){if(null==a[e.i%t])continue;const i=t-1-Math.floor(e.i/t);i in a[e.i%t]?a[e.i%t][i]=e.y/n:console.warn("wrong index",{points:a,point:e,i:e.i%t,k:i,heightMap:c})}const l=e.landscape.options.density,d=a.flatMap((t=>t.reverse())),h=i.ColliderDesc.heightfield(l,l,new Float32Array(d),new i.Vector3(n,n,n));var o=r.getWorldPosition(new b);if(!1!==e.collisionDetection){const t=this.world.createRigidBody(i.RigidBodyDesc.fixed()),e=new i.Vector3(0,0,0);K(e,o),t.setTranslation(e,!1),this.world.createCollider(h,t),this.staticBodies.set(r,t)}}}addActor(t,e,s={}){if(0==e.length)return void console.error("No collision shapes were defined when adding actor to the physics system.");this.removeActor(t);const o=t.object;let r;switch(s.type??PhysicsBodyType.static){case PhysicsBodyType.dynamic:r=i.RigidBodyDesc.dynamic(),r.mass=s.mass??1;break;case PhysicsBodyType.kinematic:r=i.RigidBodyDesc.kinematicPositionBased();break;case PhysicsBodyType.kinematicVelocityBased:r=i.RigidBodyDesc.kinematicVelocityBased();break;default:r=s.isTrigger?i.RigidBodyDesc.kinematicVelocityBased():i.RigidBodyDesc.fixed()}const n=this.world.createRigidBody(r);n.enableCcd(1==s.continousCollisionDetection);for(const t of e)this.addShape(n,t,o);J(n,(t=>{null!=s.isTrigger&&(t.setSensor(s.isTrigger),t.setActiveCollisionTypes(i.ActiveCollisionTypes.ALL),t.setActiveEvents(i.ActiveEvents.COLLISION_EVENTS)),null!=s.friction&&t.setFriction(s.friction),null!=s.density&&t.setDensity(s.density),null!=s.mass&&t.setMass(s.mass),null!=s.restitution&&t.setRestitution(s.restitution)})),N(n,o),!0===s.ignoreForNavMesh&&(n.userData={ignoreForNavMesh:!0}),this.actorBodies.set(t.id,n),this.bodyActors.set(n,t)}applyTorque(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.addTorque(G,!0)}applyTorqueImpulse(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.applyTorqueImpulse(G,!0)}resetForces(t){const e=this.actorBodies.get(t.id);e?.resetForces(!1)}resetTorques(t){const e=this.actorBodies.get(t.id);e?.resetTorques(!1)}applyForce(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.addForce(G,!0)}applyImpulse(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.applyImpulse(G,!0)}applyLocalForce(t,e,i){const s=this.actorBodies.get(t.id);K(G,e),null==i?s?.addForce(G,!0):(K(Q,i),s?.addForceAtPoint(G,Q,!0))}applyLocalImpulse(t,e,i){const s=this.actorBodies.get(t.id);K(G,e),null==i?s.applyImpulse(G,!0):(K(Q,i),s.applyImpulseAtPoint(G,Q,!0))}removeActor(t){if(null==t)return;this.controlledActors.delete(t.id);const e=this.actorBodies.get(t.id);null!=e&&(this.bodyActors.delete(e),this.world.removeRigidBody(e)),this.actorBodies.delete(t.id)}removeSceneObject(t){let e=this.staticBodies.get(t);null!=e&&this.world.getRigidBody(e.handle)&&this.world.removeRigidBody(e),this.staticBodies.delete(t)}activateActorEvents(t){this.actorBodies.get(t.id)}_onCollisionWithActorEvent(t,e,i){return this.activateActorEvents(t),this.collisionEvents.pipe(l(t.disposed),n((({started:t})=>t===i)),a((({handle1:t,handle2:e,started:i})=>({a1:this.bodyActors.get(this.world.getCollider(t).parent()),a2:this.bodyActors.get(this.world.getCollider(e).parent()),started:i}))),n((({a1:i,a2:s})=>null!=i&&null!=s&&i.id===t.id&&e(i,s))),a((({a2:t})=>t)))}onBeginContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(l(t.disposed),n((t=>t.started)),n((({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e).parent());return null!=i&&i.id===t.id})),a((t=>t.handle2)))}onEndContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(l(t.disposed),n((t=>!t.started)),n((({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e).parent());return null!=i&&i.id===t.id})),a((t=>t.handle2)))}onHasContactChanged(t){const e=new Set,i=new o(!1);return this.onBeginContact(t).subscribe((t=>{e.add(t),i.next(e.size>0)})),this.onEndContact(t).subscribe((t=>{e.delete(t),i.next(e.size>0)})),i.pipe(r())}onBeginOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>i instanceof e),!0)}onEndOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>i instanceof e),!1)}onBeginOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>e.id===i.id),!0)}onEndOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>e.id===i.id),!1)}onCollisionWithActor(t,e){return this.onBeginOverlapWithActor(t,e)}onCollisionWithActorType(t,e){return this.onBeginOverlapWithActorType(t,e)}updateActorTransform(t){const e=this.actorBodies.get(t.id);null!=e?N(e,t.object):console.warn("Actor has not been added to physics world",t)}setupWorld(){const t=new i.World({x:0,y:-9.81,z:0});this.world=t}getActorContacts(t,e){const s=this.actorBodies.get(t.id);if(s&&s.numColliders()>0){const o=s.collider(0);let r=o.shape,n=o.translation(),a=o.rotation(),c=e,l=.3;const d=this.world.castShape(n,a,c,r,.1,l,!0,null,null,null,this.actorBodies.get(t.id),(t=>t.shape.type!=i.ShapeType.HeightField));if(null!=d){const t=new b,e=new b,i=new b;return X(t,d.witness2),X(e,d.witness1),X(i,d.normal1),i.negate(),[{ri:t,rj:e,ni:i}]}return[]}return console.warn("Actor is not added to the physics system"),[]}stop(){this.world?.bodies.forEach((t=>this.world.removeRigidBody(t))),this.world?.free(),this.fixedupdateSub?.unsubscribe()}createStaticBody(t,e,s){const o=s?.type===PhysicsBodyType.dynamic?i.RigidBodyDesc.dynamic():i.RigidBodyDesc.fixed(),r=this.world.createRigidBody(o);for(const i of e){const o=this.addShape(r,i,t);null!=s?.friction&&o.setFriction(s.friction),null!=s?.density&&o.setDensity(s.density),null!=s?.mass&&o.setMass(s.mass/e.length),null!=s?.restitution&&o.setRestitution(s.restitution)}return N(r,t),r}addShape(t,e,i){const s=i.getWorldScale(tt),o=this.createShape(e,s);o.friction=.1;const r=e.offset.clone().multiply(s);var n,a;return K(o.translation,r),n=o.rotation,a=(new v).setFromEuler(e.rotation),n.x=a.x,n.y=a.y,n.z=a.z,n.w=a.w,this.world.createCollider(o,t)}createShape(t,e){if(t instanceof D)return i.ColliderDesc.cuboid(t.dimensions.x*e.x/2,t.dimensions.y*e.y/2,t.dimensions.z*e.z/2);if(t instanceof z){return i.ColliderDesc.capsule(t.length/2*e.y,t.radius*Math.max(e.z,e.x))}if(t instanceof F){const s=null!=t.geometry.getIndex()?t.geometry:I.mergeVertices(t.geometry),o=new Float32Array(s.getAttribute("position").array);for(let t=0;t<o.length;t+=3)o[t]*=e.x,o[t+1]*=e.y,o[t+2]*=e.z;return i.ColliderDesc.trimesh(o,new Uint32Array(s.getIndex().array))}if(t instanceof T){let s;t.mesh instanceof d.Mesh?s=t.mesh.geometry:t.mesh instanceof d.BufferGeometry?s=t.mesh:console.log("Unknownd shape",{shapeInfo:t});const o=new Float32Array(s.getAttribute("position").array);if(t.mesh instanceof d.Mesh){const e=L(t.mesh);for(let t=0;t<o.length;t+=3)o[t]*=e.x,o[t+1]*=e.y,o[t+2]*=e.z}for(let t=0;t<o.length;t+=3)o[t]*=e.x,o[t+1]*=e.y,o[t+2]*=e.z;return i.ColliderDesc.convexHull(o)}return t instanceof W?i.ColliderDesc.ball(t.radius*Math.max(e.x,e.y,e.z)):t instanceof R?i.ColliderDesc.cylinder(t.height/2*e.y,t.radiusTop*Math.max(e.z,e.x)):t instanceof M?i.ColliderDesc.cone(t.height*e.y,t.radiusBottom/2*Math.max(e.z,e.x)):t instanceof E?i.ColliderDesc.cuboid(t.width/2*e.x,t.height/2*e.y,.01):(console.error("Unsupported shape",t),i.ColliderDesc.cuboid(1,1,1))}};k=t([A(),e("design:paramtypes",[V,P])],k);export{k as PhysicsSystem};const j=new b,O=new d.Quaternion;function N(t,e){const s=e.getWorldPosition(j),o=e.getWorldQuaternion(O);t.setTranslation(new i.Vector3(s.x,s.y,s.z),!1),t.setRotation(new i.Quaternion(o.x,o.y,o.z,o.w),!1)}const q=new b,G=new i.Vector3(0,0,0),Q=new i.Vector3(0,0,0),H=(new b,new d.Vector2),U=async()=>{let t=await import("@dimforge/rapier3d-compat");return await t.init(),t};function K(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function X(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function J(t,e){for(let i=0,s=t.numColliders();i<s;i++){e(t.collider(i))}}const Y=new b,Z=new b,$=t=>!t.isSensor(),tt=new b;
|
1
|
+
import{__decorate as t,__metadata as e}from"tslib";import*as i from"@dimforge/rapier3d-compat";import{QueryFilterFlags as s}from"@dimforge/rapier3d-compat";import{BehaviorSubject as o,distinctUntilChanged as n,filter as r,map as a,Subject as c,takeUntil as l}from"rxjs";import*as d from"three";import{ArrowHelper as h,BufferAttribute as u,BufferGeometry as y,Group as p,LineSegments as g,Matrix4 as m,MeshBasicMaterial as f,Object3D as w,Quaternion as v,Raycaster as b,Scene as x,Vector3 as B}from"three";import{Service as A}from"typedi";import{AssetMeshInstance as C}from"../../../scene/asset-resource-loader.js";import{BoxCollisionShape as D,CapsuleCollisionShape as z,ConeCollisionShape as M,ConvexPolyhedronCollisionShape as T,CylinderCollisionShape as R,PhysicalShapeMesh as S,PlaneCollisionShape as E,SphereCollisionShape as W,TrimeshCollisionShape as F}from"../../../index.js";import{LandscapeGroup as _}from"../../../scene/landscape/landscape.js";import{ViewController as V}from"../render.js";import{World as k}from"../world.js";import*as I from"three/examples/jsm/utils/BufferGeometryUtils.js";import{calculateEffectiveScale as P}from"../../../utils/three/traverse.js";export class RayTestResult{constructor(){this.hasHit=!1,this.hitPoint=new B,this.hitNormal=new B}}export var PhysicsBodyType;!function(t){t[t.dynamic=1]="dynamic",t[t.static=2]="static",t[t.kinematic=4]="kinematic",t[t.kinematicVelocityBased=8]="kinematicVelocityBased"}(PhysicsBodyType||(PhysicsBodyType={}));let L=class{set showDebug(t){this.shouldRenderDebug=t,this.debugMesh&&(this.debugMesh.visible=t)}get showDebug(){return this.shouldRenderDebug}constructor(t,e){this.viewController=t,this.gameWorld=e,this.staticMeshes=new Map,this.staticBodies=new Map,this.actorBodies=new Map,this.bodyActors=new Map,this.collisionEvents=new c,this.beforeStep=new c,this.afterStep=new c,this.shouldRenderDebug=!1,this._raycaster=new b,this._reusableResult=new RayTestResult,this._raytestDiff=new B,this._raytestDirection=new B,this.controlledActors=new Set,this.ready=this.setup()}createDebugMesh(){return new g(new y,new f({color:255}))}async start(){return await this.ready,this.handleTick(),this.ready}renderDebug(){null==this.debugMesh&&(this.debugMesh=this.createDebugMesh(),this.debugMesh.visible=this.shouldRenderDebug,this.debugMesh.raycast=function(){},this.gameWorld.scene.add(this.debugMesh));const t=this.world.debugRender();this.debugMesh.geometry.setAttribute("position",new u(t.vertices,3))}async setup(){if(null!=this.rapier)throw new Error("Rapier is already estup");this.rapier=await K(),this.eventQueue=new i.EventQueue(!0),this.setupWorld()}handleTick(){this.fixedupdateSub=this.viewController.onUpdate().subscribe((t=>{t=Math.min(.1,t),this.beforeStep.next(t),this.updatePhysics(t),this.afterStep.next(t),this.showDebug&&this.renderDebug(),this.world.bodies.forEach((t=>{if(t.isFixed())return;const e=this.staticMeshes.get(t)??this.bodyActors.get(t)?.object;var i,s;null!=e&&(e.parent instanceof x&&(J(e.position,t.translation()),(t.isDynamic()||t.isKinematic()&&!this.controlledActors.has(this.bodyActors.get(t)?.id))&&(i=e.quaternion,s=t.rotation(),i.x=s.x,i.y=s.y,i.z=s.z,i.w=s.w)))}))}))}_updateWorld(){this.world.timestep=0,this.world.step()}updatePhysics(t){this.world.timestep=t,this.world.step(this.eventQueue),this.eventQueue.drainCollisionEvents(((t,e,i)=>{this.collisionEvents.next({handle1:t,handle2:e,started:i}),this.collisionEvents.next({handle1:e,handle2:t,started:i})}))}rayTestFromCamera(t,e,i){this._raycaster.setFromCamera(U,this.viewController.getCamera());const s=this._raycaster.ray.origin,o=this._raycaster.ray.direction.multiplyScalar(t).add(s);return this.rayTest(s,o,e,i)}rayTest(t,e,s,o){null==s&&(s=this._reusableResult);const n=this._raytestDiff,r=this._raytestDirection;if(n.subVectors(e,t),r.copy(n).normalize(),0===r.length())return console.warn("Ray test called with to and from being equal"),s;const a=new i.Ray(t,r),c=n.length(),l=this.world.castRayAndGetNormal(a,c,!1,void 0,void 0,void 0,null!=o?.excludeActor?this.actorBodies.get(o.excludeActor.id):void 0,o?.excludeTriggers?t=>!t.isSensor():void 0);if(s.hasHit=null!=l,s.hasHit){const e=a.pointAt(l.timeOfImpact);s._internal=l,J(s.hitNormal,l.normal),J(s.hitPoint,e),s.distance=Z.subVectors(s.hitPoint,t).length();const i=this.world.bodies.getAll().find((t=>function(t,e){for(let i=0,s=t.numColliders();i<s;i++){const s=t.collider(i);if(e(s))return s}}(t,(t=>t===l.collider))));s.actor=null!=i?this.bodyActors.get(i):null}if(this.showDebug){const e=new h(r,t,c,o?.debugColor??255);this.gameWorld.scene.add(e),setTimeout((()=>this.gameWorld.scene.remove(e)),o?.debugLifetime??200)}return this._reusableResult}setGravity(t,e,i){this.world.gravity.x=t,this.world.gravity.y=e,this.world.gravity.z=i}getGravity(){return q.set(this.world.gravity.x,this.world.gravity.y,this.world.gravity.z)}addFromScene(t){this.addRecursively(t);for(const t of this.staticBodies.values())Y(t,(t=>t.setActiveEvents(i.ActiveEvents.COLLISION_EVENTS)))}addRecursively(t){if(this.removeSceneObject(t),!function(t){if(null!=t.userData?.src){const e=t.userData?.src;return"actor"===e.type}return!1}(t))if(t instanceof S&&null!=t.collisionShape){const e=this.createStaticBody(t,[t.collisionShape],t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else if(t instanceof C&&!1!==t.userData?.src?.collisionDetection)if(t.children[0]&&t.children[0].instanceMatrix)this.createForInstancedMesh(t.children[0],t.collisionShapes);else{const e=this.createStaticBody(t,t.collisionShapes,t.physics);this.staticMeshes.set(e,t),this.staticBodies.set(t,e)}else t instanceof _?this.addLandscapeGroup(t):(t instanceof p||t instanceof x)&&t.children.forEach((t=>this.addRecursively(t)))}createForInstancedMesh(t,e){const i=new m;for(let s=0;s<t.count;s++){const o=new w;o.matrix.identity(),i.fromArray(t.instanceMatrix.array,16*s),o.applyMatrix4(i);this.createStaticBody(o,e)}}getCharacterController(t=.01){return this.world?.createCharacterController(t)}getActorComputedMovement(t,e,i){const o=this.actorBodies.get(t.id);this.controlledActors.add(t.id);const n=o.collider(0);e.computeColliderMovement(n,i,s.EXCLUDE_SENSORS,null,tt);const r=e.computedMovement();return J($,r),$}setNextKinematicTranslation(t,e){const i=this.actorBodies.get(t.id),s=i.translation();s.x+=e.x,s.y+=e.y,s.z+=e.z,i?.setNextKinematicTranslation(s)}setAngularVelocity(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.setAngvel(G,!0)}setLinearVelocity(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.setLinvel(G,!0)}getLinearVelocity(t,e=new B){const i=this.actorBodies.get(t.id).linvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}getAngularVelocity(t,e=new B){const i=this.actorBodies.get(t.id).angvel();return e.x=i.x,e.y=i.y,e.z=i.z,e}setLinearDamping(t,e){const i=this.actorBodies.get(t.id);i?.setLinearDamping(e)}setAngularDamping(t,e){const i=this.actorBodies.get(t.id);i?.setAngularDamping(e)}createCharacterCollision(){return new i.CharacterCollision}addLandscapeGroup(t){const e=t.userData.src,s=e.landscape.heightMaps;for(const n of t.sections){this.staticBodies.has(n)&&this.world.removeRigidBody(this.staticBodies.get(n));const t=e.landscape.options.density+1,r=e.landscape.options.sectionSize,a=new Array(t);for(let e=0;e<t;e++)a[e]=new Array(t).fill(0);const c=s.find((t=>t.x===n.x&&t.y==n.y));if(null!=c)for(const e of c.points){if(null==a[e.i%t])continue;const i=t-1-Math.floor(e.i/t);i in a[e.i%t]?a[e.i%t][i]=e.y/r:console.warn("wrong index",{points:a,point:e,i:e.i%t,k:i,heightMap:c})}const l=e.landscape.options.density,d=a.flatMap((t=>t.reverse())),h=i.ColliderDesc.heightfield(l,l,new Float32Array(d),new i.Vector3(r,r,r));var o=n.getWorldPosition(new B);if(!1!==e.collisionDetection){const t=this.world.createRigidBody(i.RigidBodyDesc.fixed()),e=new i.Vector3(0,0,0);X(e,o),t.setTranslation(e,!1),this.world.createCollider(h,t),this.staticBodies.set(n,t)}}}addActor(t,e,s={}){if(0==e.length)return void console.error("No collision shapes were defined when adding actor to the physics system.");this.removeActor(t);const o=t.object;let n;switch(s.type??PhysicsBodyType.static){case PhysicsBodyType.dynamic:n=i.RigidBodyDesc.dynamic(),n.mass=s.mass??1;break;case PhysicsBodyType.kinematic:n=i.RigidBodyDesc.kinematicPositionBased();break;case PhysicsBodyType.kinematicVelocityBased:n=i.RigidBodyDesc.kinematicVelocityBased();break;default:n=s.isTrigger?i.RigidBodyDesc.kinematicVelocityBased():i.RigidBodyDesc.fixed()}const r=this.world.createRigidBody(n);r.enableCcd(1==s.continousCollisionDetection);for(const t of e)this.addShape(r,t,o);Y(r,(t=>{null!=s.isTrigger&&(t.setSensor(s.isTrigger),t.setActiveCollisionTypes(i.ActiveCollisionTypes.ALL),t.setActiveEvents(i.ActiveEvents.COLLISION_EVENTS)),null!=s.friction&&t.setFriction(s.friction),null!=s.density&&t.setDensity(s.density),null!=s.mass&&t.setMass(s.mass),null!=s.restitution&&t.setRestitution(s.restitution)})),N(r,o),!0===s.ignoreForNavMesh&&(r.userData={ignoreForNavMesh:!0}),this.actorBodies.set(t.id,r),this.bodyActors.set(r,t)}applyTorque(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.addTorque(G,!0)}applyTorqueImpulse(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.applyTorqueImpulse(G,!0)}resetForces(t){const e=this.actorBodies.get(t.id);e?.resetForces(!1)}resetTorques(t){const e=this.actorBodies.get(t.id);e?.resetTorques(!1)}applyForce(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.addForce(G,!0)}applyImpulse(t,e){const i=this.actorBodies.get(t.id);G.x=e.x,G.y=e.y,G.z=e.z,i?.applyImpulse(G,!0)}applyLocalForce(t,e,i){const s=this.actorBodies.get(t.id);X(G,e),null==i?s?.addForce(G,!0):(X(Q,i),s?.addForceAtPoint(G,Q,!0))}applyLocalImpulse(t,e,i){const s=this.actorBodies.get(t.id);X(G,e),null==i?s.applyImpulse(G,!0):(X(Q,i),s.applyImpulseAtPoint(G,Q,!0))}applyRadiusImpulse(t,e,s){this.world.bodies.forEach((o=>{if(o.collider(0)?.isSensor())return;if(o.bodyType()!==i.RigidBodyType.Dynamic)return;const n=H;J(n,o.translation());const r=n.clone().sub(t);if(r.length()>e)return;const a=r.clone().normalize().multiplyScalar(s);G.x=a.x,G.y=a.y,G.z=a.z,o.applyImpulse(G,!0)}))}removeActor(t){if(null==t)return;this.controlledActors.delete(t.id);const e=this.actorBodies.get(t.id);null!=e&&(this.bodyActors.delete(e),this.world.removeRigidBody(e)),this.actorBodies.delete(t.id)}removeSceneObject(t){let e=this.staticBodies.get(t);null!=e&&this.world.getRigidBody(e.handle)&&this.world.removeRigidBody(e),this.staticBodies.delete(t)}activateActorEvents(t){this.actorBodies.get(t.id)}_onCollisionWithActorEvent(t,e,i){return this.activateActorEvents(t),this.collisionEvents.pipe(l(t.disposed),r((({started:t})=>t===i)),a((({handle1:t,handle2:e,started:i})=>({a1:this.bodyActors.get(this.world.getCollider(t)?.parent()),a2:this.bodyActors.get(this.world.getCollider(e)?.parent()),started:i}))),r((({a1:i,a2:s})=>null!=i&&null!=s&&i.id===t.id&&e(i,s))),a((({a2:t})=>t)))}onBeginContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(l(t.disposed),r((t=>t.started)),r((({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e)?.parent());return null!=i&&i.id===t.id})),a((t=>t.handle2)))}onEndContact(t){return this.activateActorEvents(t),this.collisionEvents.pipe(l(t.disposed),r((t=>!t.started)),r((({handle1:e})=>{const i=this.bodyActors.get(this.world.getCollider(e)?.parent());return null!=i&&i.id===t.id})),a((t=>t.handle2)))}onHasContactChanged(t){const e=new Set,i=new o(!1);return this.onBeginContact(t).subscribe((t=>{e.add(t),i.next(e.size>0)})),this.onEndContact(t).subscribe((t=>{e.delete(t),i.next(e.size>0)})),i.pipe(n())}onBeginOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>i instanceof e),!0)}onEndOverlapWithActorType(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>i instanceof e),!1)}onBeginOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>e.id===i.id),!0)}onEndOverlapWithActor(t,e){return this._onCollisionWithActorEvent(t,((t,i)=>e.id===i.id),!1)}onCollisionWithActor(t,e){return this.onBeginOverlapWithActor(t,e)}onCollisionWithActorType(t,e){return this.onBeginOverlapWithActorType(t,e)}updateActorTransform(t){const e=this.actorBodies.get(t.id);null!=e?N(e,t.object):console.warn("Actor has not been added to physics world",t)}setupWorld(){const t=new i.World({x:0,y:-9.81,z:0});this.world=t}getActorContacts(t,e){const s=this.actorBodies.get(t.id);if(s&&s.numColliders()>0){const o=s.collider(0);let n=o.shape,r=o.translation(),a=o.rotation(),c=e,l=.3;const d=this.world.castShape(r,a,c,n,.1,l,!0,null,null,null,this.actorBodies.get(t.id),(t=>t.shape.type!=i.ShapeType.HeightField));if(null!=d){const t=new B,e=new B,i=new B;return J(t,d.witness2),J(e,d.witness1),J(i,d.normal1),i.negate(),[{ri:t,rj:e,ni:i}]}return[]}return console.warn("Actor is not added to the physics system"),[]}stop(){this.world?.bodies.forEach((t=>this.world.removeRigidBody(t))),this.world?.free(),this.fixedupdateSub?.unsubscribe()}createStaticBody(t,e,s){const o=s?.type===PhysicsBodyType.dynamic?i.RigidBodyDesc.dynamic():i.RigidBodyDesc.fixed(),n=this.world.createRigidBody(o);for(const i of e){const o=this.addShape(n,i,t);null!=s?.friction&&o.setFriction(s.friction),null!=s?.density&&o.setDensity(s.density),null!=s?.mass&&o.setMass(s.mass/e.length),null!=s?.restitution&&o.setRestitution(s.restitution)}return N(n,t),n}addShape(t,e,i){const s=i.getWorldScale(et),o=this.createShape(e,s);o.friction=.1;const n=e.offset.clone().multiply(s);var r,a;return X(o.translation,n),r=o.rotation,a=(new v).setFromEuler(e.rotation),r.x=a.x,r.y=a.y,r.z=a.z,r.w=a.w,this.world.createCollider(o,t)}createShape(t,e){if(t instanceof D)return i.ColliderDesc.cuboid(t.dimensions.x*e.x/2,t.dimensions.y*e.y/2,t.dimensions.z*e.z/2);if(t instanceof z){return i.ColliderDesc.capsule(t.length/2*e.y,t.radius*Math.max(e.z,e.x))}if(t instanceof F){const s=null!=t.geometry.getIndex()?t.geometry:I.mergeVertices(t.geometry),o=new Float32Array(s.getAttribute("position").array);for(let t=0;t<o.length;t+=3)o[t]*=e.x,o[t+1]*=e.y,o[t+2]*=e.z;return i.ColliderDesc.trimesh(o,new Uint32Array(s.getIndex().array))}if(t instanceof T){let s;t.mesh instanceof d.Mesh?s=t.mesh.geometry:t.mesh instanceof d.BufferGeometry?s=t.mesh:console.log("Unknownd shape",{shapeInfo:t});const o=new Float32Array(s.getAttribute("position").array);if(t.mesh instanceof d.Mesh){const e=P(t.mesh);for(let t=0;t<o.length;t+=3)o[t]*=e.x,o[t+1]*=e.y,o[t+2]*=e.z}for(let t=0;t<o.length;t+=3)o[t]*=e.x,o[t+1]*=e.y,o[t+2]*=e.z;const n=o.length>1e3?function(t,e,i){const s=[],o={},n=i,r=i*i;for(let i=0;i<t.length;i+=3){const a=t[i],c=t[i+1],l=t[i+2],d=it(a,c,l,n);let h=!1;for(const[t,e,i]of ot){const s=it(a+t*n,c+e*n,l+i*n,n);if(o[s])for(let t=0;t<o[s].length;t+=3){if(st(a,c,l,o[s][t],o[s][t+1],o[s][t+2])<r){h=!0;break}}if(h)break}if(h||(s.push(a,c,l),o[d]||(o[d]=[]),o[d].push(a,c,l)),s.length>=3*e)break}return new Float32Array(s)}(o,1e3,.1):o;return i.ColliderDesc.convexHull(n)}return t instanceof W?i.ColliderDesc.ball(t.radius*Math.max(e.x,e.y,e.z)):t instanceof R?i.ColliderDesc.cylinder(t.height/2*e.y,t.radiusTop*Math.max(e.z,e.x)):t instanceof M?i.ColliderDesc.cone(t.height*e.y,t.radiusBottom/2*Math.max(e.z,e.x)):t instanceof E?i.ColliderDesc.cuboid(t.width/2*e.x,t.height/2*e.y,.01):(console.error("Unsupported shape",t),i.ColliderDesc.cuboid(1,1,1))}};L=t([A(),e("design:paramtypes",[V,k])],L);export{L as PhysicsSystem};const j=new B,O=new d.Quaternion;function N(t,e){const s=e.getWorldPosition(j),o=e.getWorldQuaternion(O);t.setTranslation(new i.Vector3(s.x,s.y,s.z),!1),t.setRotation(new i.Quaternion(o.x,o.y,o.z,o.w),!1)}const q=new B,G=new i.Vector3(0,0,0),Q=new i.Vector3(0,0,0),H=new B,U=new d.Vector2,K=async()=>{let t=await import("@dimforge/rapier3d-compat");return await t.init(),t};function X(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function J(t,e){t.x=e.x,t.y=e.y,t.z=e.z}function Y(t,e){for(let i=0,s=t.numColliders();i<s;i++){e(t.collider(i))}}const Z=new B,$=new B,tt=t=>!t.isSensor(),et=new B;function it(t,e,i,s){return 73856093*Math.floor(t/s)^19349663*Math.floor(e/s)^83492791*Math.floor(i/s)}function st(t,e,i,s,o,n){const r=t-s,a=e-o,c=i-n;return r*r+a*a+c*c}const ot=[[0,0,0],[1,0,0],[0,1,0],[0,0,1],[1,1,0],[1,0,1],[0,1,1],[1,1,1]];
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{__decorate as t,__metadata as i}from"tslib";import{Service as e}from"typedi";import{ActorFactory as s}from"../actors/factory.js";import{Vector3 as o}from"three";import{ActorComponent as r}from"../../gameplay/actors/component.js";import{Subject as n}from"rxjs";import{RenderingView as c}from"../../rendering.js";const a=new o;class h{constructor(t){this.view=t}get direction(){return this.view.csm.lightDirection}set intensity(t){this.view.csm.lightIntensity=t,this.view.csm.lights.forEach((t=>t.intensity=this.view.csm.lightIntensity))}get intensity(){return this.view.csm.lightIntensity}get position(){return 0==this.view.csm.lights.length?a:this.view.csm.lights[0].position}}let m=class{constructor(t,i){this.actorFactory=t,this.view=i,this.actors=[],this.actorAdded=new n,this.actorRemoved=new n,this.directionalLight=new h(this.view)}async spawnActor(t,i,e){const s=await this.actorFactory.create(t,i,e);return this.addActor(s,i,e),s}addActor(t,i,e){i&&t.object.position.copy(i),e&&t.object.rotation.copy(e),this.scene.add(t.object),this.actors.push(t),d(t,(t=>t.onBeginPlay())),this.actorAdded.next(t)}removeActor(t){d(t,(t=>t.onEndPlay()))
|
1
|
+
import{__decorate as t,__metadata as i}from"tslib";import{Service as e}from"typedi";import{ActorFactory as s}from"../actors/factory.js";import{Vector3 as o}from"three";import{ActorComponent as r}from"../../gameplay/actors/component.js";import{Subject as n}from"rxjs";import{RenderingView as c}from"../../rendering.js";const a=new o;class h{constructor(t){this.view=t}get direction(){return this.view.csm.lightDirection}set intensity(t){this.view.csm.lightIntensity=t,this.view.csm.lights.forEach((t=>t.intensity=this.view.csm.lightIntensity))}get intensity(){return this.view.csm.lightIntensity}get position(){return 0==this.view.csm.lights.length?a:this.view.csm.lights[0].position}}let m=class{constructor(t,i){this.actorFactory=t,this.view=i,this.actors=[],this.actorAdded=new n,this.actorRemoved=new n,this.directionalLight=new h(this.view)}async spawnActor(t,i,e){const s=await this.actorFactory.create(t,i,e);return this.addActor(s,i,e),s}addActor(t,i,e){i&&t.object.position.copy(i),e&&t.object.rotation.copy(e),this.scene.add(t.object),this.actors.push(t),d(t,(t=>t.onBeginPlay())),this.actorAdded.next(t)}removeActor(t){d(t,(t=>t.onEndPlay()));const i=this.actors.indexOf(t);i>=0&&this.actors.splice(i,1),this.scene.remove(t.object),t.disposed.next(!0),this.actorRemoved.next(t)}findActorByType(t,i){return this.actors.find((e=>e instanceof t&&(null==i||e.object.name==i)))}findActorsByType(t,i){return this.actors.filter((e=>e instanceof t&&(null==i||e.object.name==i)))}};m=t([e(),i("design:paramtypes",[s,c])],m);export{m as World};function d(t,i){return i(t),Object.entries(t).filter((([t,i])=>i instanceof r)).forEach((([t,e])=>{d(e,i)}))}
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
package/dist/rendering.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
var e;import{__decorate as t,__metadata as i}from"tslib";import*as s from"three";import{Mesh as r,Matrix4 as n,ShaderMaterial as a,Color as o,PerspectiveCamera as h,ShaderChunk as l}from"three";import{EffectComposer as d,UnrealBloomPass as c,VRButton as m}from"three-stdlib";import{RenderPass as p}from"three-stdlib";import{ShaderPass as u}from"three-stdlib";import{FXAAShader as g}from"three-stdlib";import{CSMShader as f,CSMUtil as v}from"./csm.js";import{GammaCorrectionShader as w}from"three-stdlib";import{Reflector as x}from"three-stdlib";import{depthUniformName as b,resolutionUniformName as C,supportsDepthTextureExtension as P,nearUniformName as S,farUniformName as R}from"./shader-nodes/depth.js";import{elapsedTimeUniformName as M}from"./shader-nodes/time.js";import{OutlinePass as y}from"./utils/three/outline-pass.js";import T from"./utils/three/stats.js";import{findFirstVisibleObject as W}from"./utils/three/traverse.js";import{DepthPass as L}from"./utils/three/depth-pass.js";import{Service as E}from"typedi";import{CSM as H}from"three/examples/jsm/csm/CSM.js";import{GPUStatsPanel as B}from"three/examples/jsm/utils/GPUStatsPanel.js";(new s.Layers).set(9);const D=new s.MeshBasicMaterial({color:"black"}),F=new s.MeshDepthMaterial;F.depthPacking=s.RGBADepthPacking,F.blending=s.NoBlending,l.lights_pars_begin=f.lights_pars_begin(5);const j=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let z=e=class{setPaused(e){this.paused=e}resizeRender(){this.previousClientWith===this.container.clientWidth&&this.previousClientHeight===this.container.clientHeight||(this.previousClientWith=this.container.clientWidth,this.previousClientHeight=this.container.clientHeight,this.camera instanceof h&&(this.camera.aspect=this.container.clientWidth/this.container.clientHeight,this.camera.updateProjectionMatrix()),this.renderer.setPixelRatio(Math.min(this.maxPixelRatio,window.devicePixelRatio)*this.resolutionScale),this.renderer.setSize(this.container.clientWidth,this.container.clientHeight),this.composer.setSize(this.container.clientWidth*this.resolutionScale,this.container.clientHeight*this.resolutionScale))}constructor(t,i={}){this.container=t,this.options=i,this.windowVisible=!0,this.running=!0,this.paused=!1,this.fpsCap=null,this.resolutionScale=j?.5:1,this.maxPixelRatio=j?1:window.devicePixelRatio,this.onResize=()=>{this.resizeRender(),this.paused||this.render()},this.onVisiblityChane=()=>{this.windowVisible=!document.hidden},this.isDepthTextureExtensionSupported=!1,this.onLoopCallbacks=[],this.stats=T(),this._showStats=!1,this.insetHeight=200,this.insetWidth=this.insetHeight*(16/9),this.insetOffsetY=250,this.insetMargin=10,this.maxInsetCameras=4,this.overlayCameras=new Set,this.prevClearColor=new o,this.hadBloom=!1,this.bloomStoredMaterials={},null!=i.maxPixelRatio&&(this.maxPixelRatio=i.maxPixelRatio),window.renderer=this.renderer=new s.WebGLRenderer({antialias:!0,powerPreference:"high-performance"}),this.scene=new s.Scene,this.renderer.setPixelRatio(Math.min(this.maxPixelRatio,window.devicePixelRatio)*this.resolutionScale),this.renderer.setSize(t.clientWidth,t.clientHeight),this.renderer.xr.enabled=this.options.enableXR??!1,!0===this.options.enableXR&&document.body.appendChild(m.createButton(this.renderer)),this.composer=new d(this.renderer);var r=t.clientWidth/t.clientHeight;const n=new s.PerspectiveCamera(45,r,.5,800);n.layers.enable(19),this.setCamera(n),this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=s.PCFSoftShadowMap,this.renderer.shadowMap.autoUpdate=!1,this.renderer.outputColorSpace=s.SRGBColorSpace,this.renderer.toneMapping=s.NoToneMapping,this.renderer.toneMappingExposure=1,this.renderer.gammaFactor=1.4,v.renderingView=this,v.patchThreeAdd(),this.isDepthTextureExtensionSupported=P(this.renderer),t.replaceChildren(this.renderer.domElement),this.setupEventListeners(),this.depthRenderTarget=e.createDepthRenderTarget(this.renderer,this.container);const a=new p(this.scene,this.camera);this.composer.addPass(a);const h=new c(new s.Vector2(t.clientWidth,t.clientHeight),1.5,.4,.85);h.threshold=0,h.strength=.9,h.radius=1,this.renderer.info.autoReset=!1;const l=new d(this.renderer);l.renderToScreen=!1,l.addPass(a),l.addPass(h),this.bloomComposer=l;const f=new u(new s.ShaderMaterial({uniforms:{baseTexture:{value:null},bloomTexture:{value:l.renderTarget2.texture}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }",fragmentShader:"\n uniform sampler2D baseTexture;\n uniform sampler2D bloomTexture;\n varying vec2 vUv;\n void main() {\n gl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) );\n }",defines:{}}),"baseTexture");if(f.needsSwap=!0,this.composer.addPass(f),this.outlinePass=new y(new s.Vector2(t.clientWidth,t.clientHeight),this.scene,this.camera),!0===i.enableOutlines){this.outlinePass.edgeThickness=0,this.outlinePass.edgeGlow=0,this.outlinePass.edgeThickness=1.5,this.outlinePass.edgeStrength=5,this.outlinePass.clear=!1,this.composer.addPass(this.outlinePass);const e=new u(g);e.uniforms.resolution.value.set(1/t.clientWidth,1/t.clientHeight),this.composer.addPass(e)}var x=new u(w);x.clear=!1,this.composer.addPass(x)}setCamera(e){this.camera=e,this.composer.passes.forEach((t=>{t instanceof p?t.camera=e:t instanceof y?t.renderCamera=e:t instanceof L&&(t.camera=e)})),null==this.csm?this.csm=new H({maxFar:250,lightFar:250,lightMargin:20,cascades:4,shadowMapSize:2048,lightDirection:new s.Vector3(.5,-1,-.6).normalize(),lightIntensity:.5*Math.PI,camera:this.camera,parent:this.scene,mode:"logarithmic"}):(this.csm.camera=this.camera,this.camera instanceof h&&(this.csm.maxFar=this.camera.far)),this.csm.updateFrustums()}setSelectedObjects(e){const t=new Map;for(const i of e)t.set(i.uuid,i);for(const i of e)i.traverse((e=>{e.uuid!==i.uuid&&t.has(e.uuid)&&t.delete(e.uuid)}));this.outlinePass.selectedObjects=Array.from(t.values())}static createDepthRenderTarget(e,t){var i=!!e.extensions.get("WEBGL_depth_texture");const r=new s.WebGLRenderTarget(t.clientWidth*e.getPixelRatio(),t.clientHeight*e.getPixelRatio());return r.texture.minFilter=s.NearestFilter,r.texture.magFilter=s.NearestFilter,r.texture.generateMipmaps=!1,r.stencilBuffer=!1,!0===i&&(r.depthTexture=new s.DepthTexture(128,128),r.depthTexture.type=s.UnsignedShortType,r.depthTexture.minFilter=s.NearestFilter,r.depthTexture.magFilter=s.NearestFilter),r}setupEventListeners(){window.addEventListener("resize",this.onResize),window.addEventListener("orientationchange",this.onResize),document.addEventListener("visibilitychange",this.onVisiblityChane)}stop(){this.running=!1,window.removeEventListener("resize",this.onResize),window.removeEventListener("orientationchange",this.onResize),document.removeEventListener("visibilitychange",this.onVisiblityChane),this.onLoopCallbacks=[],this.renderer.dispose(),this.depthRenderTarget.dispose(),this.csm.dispose(),this.container.replaceChildren()}onLoop(e){this.onLoopCallbacks.push(e)}removeOnLoop(e){const t=this.onLoopCallbacks.find(e);this.onLoopCallbacks.splice(t,1)}set showStats(e){this._showStats=e,this._showStats&&!this.container.contains(this.stats.dom)?this.container.appendChild(this.stats.dom):!this._showStats&&this.container.contains(this.stats.dom)&&this.container.removeChild(this.stats.dom)}get showStats(){return this._showStats}loop(e,t=!1){const i=this.stats,a=i.addPanel(new T.Panel("Calls","#83f","#002"));let o;navigator.userAgent.includes("Chrome")&&navigator.userAgent.includes("HologyEngine")&&(o=new B(this.renderer.getContext()),i.addPanel(o)),i.showPanel(0),this.showStats=t;let h=10;const l=()=>{const e=this.renderer.info.render.calls;e>h&&(h=e,setTimeout((()=>h=10),5e3)),a.update(e,h)};performance.now();s.Ray.prototype.intersectTriangle;let d=0;const c=new n,m=new n,p=t=>{const s=this.renderer.getContext();if(this.paused&&this.running&&s.drawingBufferHeight>1)return void setTimeout((()=>p(t)),500);this.renderer.autoClear=!1,this.renderer.clear(),this.renderer.setViewport(0,0,this.container.clientWidth,this.container.clientHeight),this.camera,i.begin();let n=(t*=.001)-d;if(d=t,c.copy(this.camera.matrixWorld),n>1){let t=n;for(;t>.05;)e(O),t-=O;e(t)}else e(n);this.onLoopCallbacks.forEach((e=>e(n))),this.camera?.updateMatrixWorld(),m.copy(this.camera.matrixWorld),m.equals(c)||(this.renderer.shadowMap.needsUpdate=!0),this.resizeRender();const a=[],h=[];if(this.scene.traverse((e=>{e instanceof r&&e.visible&&(e.material?.userData?.water||e.material?.uniforms&&null!=e.material?.uniforms[b])?(e.visible=!1,a.push(e),this.initDepthUniform(e.material),e.renderOrder=100):e instanceof x&&(e.visible=!1,h.push(e)),e instanceof r&&e.material?.uniforms&&null!=e.material?.uniforms[M]&&(e.material.uniforms[M].value=t)})),a.length>0){if(this.scene.overrideMaterial=F,this.renderer.setRenderTarget(this.depthRenderTarget),!this.paused&&null!=this.camera)try{this.renderer.clear(),this.renderer.render(this.scene,this.camera)}catch(e){console.warn(e)}this.renderer.setRenderTarget(null),this.scene.overrideMaterial=null}a.forEach((e=>e.visible=!0)),h.forEach((e=>e.visible=!0));try{!this.paused&&this.running&&(o?.startQuery(),this.render(n),o?.endQuery(),this.showStats&&l(),this.renderer.info.reset(),this.renderOverlay())}catch(e){console.warn(e)}i.end(),this.csm?.update(),this.running&&!0!==this.options.enableXR&&(this.fpsCap?setTimeout((()=>{requestAnimationFrame(p)}),1e3/this.fpsCap):requestAnimationFrame(p))};!0===this.options.enableXR?this.renderer.setAnimationLoop(p):requestAnimationFrame(p)}renderOverlay(){const e=Array.from(this.overlayCameras.values()).slice(0,this.maxInsetCameras),t=this.container.clientWidth/2,i=e.length*this.insetWidth+(e.length-1)*this.insetMargin;for(let s=0;s<e.length;s++)this.renderer.clearDepth(),this.renderer.setViewport(t-i/2+this.insetWidth*s+this.insetMargin*s,this.insetOffsetY,this.insetWidth,this.insetHeight),this.renderer.render(this.scene,e[s])}addOverlayCamera(e){this.overlayCameras.add(e)}clearOverlayCameras(){this.overlayCameras.clear()}removeOverlayCamera(e){this.overlayCameras.delete(e)}render(e){const t=this.hasBloom();if(t||this.hadBloom){const e=this.scene.fog;this.scene.fog=null;const t=this.renderer.getClearColor(this.prevClearColor);this.renderer.setClearColor(0),this.scene.traverseVisible((e=>this.darkenNonBloomed(e))),this.bloomComposer.render(),this.scene.traverse((e=>this.restoreMaterial(e))),this.renderer.setClearColor(t),this.scene.fog=e}this.hadBloom=t,this.composer.render(e)}hasBloom(){return null!=W(this.scene,(e=>e instanceof r&&!0===e.material?.userData?.hasBloom))}darkenNonBloomed(e){e.isMesh&&e.visible&&!0!==e.material.userData.hasBloom&&(this.bloomStoredMaterials[e.uuid]=e.material,!0!==e.material.transparent?e.material=D:e.visible=!1)}restoreMaterial(e){this.bloomStoredMaterials[e.uuid]&&(e.material=this.bloomStoredMaterials[e.uuid],delete this.bloomStoredMaterials[e.uuid],e.visible=!0)}initDepthUniform(e){e instanceof a&&(e.uniforms[b].value=this.isDepthTextureExtensionSupported?this.depthRenderTarget.depthTexture:this.depthRenderTarget.texture,null!=e.uniforms[C]&&e.uniforms[C].value.set(this.container.clientWidth*this.renderer.getPixelRatio(),this.container.clientHeight*this.renderer.getPixelRatio()),this.camera instanceof h&&(e.uniforms[S].value=this.camera.near,e.uniforms[R].value=this.camera.far))}};z=e=t([E(),i("design:paramtypes",[HTMLElement,Object])],z);export{z as RenderingView};export function setRenderingPaused(e){null!=window.editor?.viewer?.renderingView&&(window.editor.viewer.renderingView.paused=e)}const O=.05;
|
1
|
+
var e;import{__decorate as t,__metadata as i}from"tslib";import*as s from"three";import{Mesh as r,Matrix4 as n,Material as a,ShaderMaterial as o,Color as h,PerspectiveCamera as l,ShaderChunk as d}from"three";import{EffectComposer as c,UnrealBloomPass as m,VRButton as p}from"three-stdlib";import{RenderPass as u}from"three-stdlib";import{ShaderPass as g}from"three-stdlib";import{FXAAShader as f}from"three-stdlib";import{CSMShader as v,CSMUtil as w}from"./csm.js";import{GammaCorrectionShader as x}from"three-stdlib";import{Reflector as b}from"three-stdlib";import{depthUniformName as C,resolutionUniformName as P,supportsDepthTextureExtension as S,nearUniformName as R,farUniformName as M}from"./shader-nodes/depth.js";import{elapsedTimeUniformName as y}from"./shader-nodes/time.js";import{OutlinePass as T}from"./utils/three/outline-pass.js";import W from"./utils/three/stats.js";import{findFirstVisibleObject as L}from"./utils/three/traverse.js";import{DepthPass as E}from"./utils/three/depth-pass.js";import{Service as H}from"typedi";import{CSM as B}from"three/examples/jsm/csm/CSM.js";import{GPUStatsPanel as D}from"three/examples/jsm/utils/GPUStatsPanel.js";(new s.Layers).set(9);const F=new s.MeshBasicMaterial({color:"black"}),j=new s.MeshDepthMaterial;j.depthPacking=s.RGBADepthPacking,j.blending=s.NoBlending,d.lights_pars_begin=v.lights_pars_begin(5);const V=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);let z=e=class{setPaused(e){this.paused=e}resizeRender(){this.previousClientWith===this.container.clientWidth&&this.previousClientHeight===this.container.clientHeight||(this.previousClientWith=this.container.clientWidth,this.previousClientHeight=this.container.clientHeight,this.camera instanceof l&&(this.camera.aspect=this.container.clientWidth/this.container.clientHeight,this.camera.updateProjectionMatrix()),this.renderer.setPixelRatio(Math.min(this.maxPixelRatio,window.devicePixelRatio)*this.resolutionScale),this.renderer.setSize(this.container.clientWidth,this.container.clientHeight),this.composer.setSize(this.container.clientWidth*this.resolutionScale,this.container.clientHeight*this.resolutionScale))}constructor(t,i={}){this.container=t,this.options=i,this.windowVisible=!0,this.running=!0,this.paused=!1,this.fpsCap=null,this.resolutionScale=V?.5:1,this.maxPixelRatio=V?1:window.devicePixelRatio,this.onResize=()=>{this.resizeRender(),this.paused||this.render()},this.onVisiblityChane=()=>{this.windowVisible=!document.hidden},this.isDepthTextureExtensionSupported=!1,this.onLoopCallbacks=[],this.stats=W(),this._showStats=!1,this.insetHeight=200,this.insetWidth=this.insetHeight*(16/9),this.insetOffsetY=250,this.insetMargin=10,this.maxInsetCameras=4,this.overlayCameras=new Set,this.prevClearColor=new h,this.hadBloom=!1,this.bloomStoredMaterials={},null!=i.maxPixelRatio&&(this.maxPixelRatio=i.maxPixelRatio),window.renderer=this.renderer=new s.WebGLRenderer({antialias:!0,powerPreference:"high-performance"}),this.scene=new s.Scene,this.renderer.setPixelRatio(Math.min(this.maxPixelRatio,window.devicePixelRatio)*this.resolutionScale),this.renderer.setSize(t.clientWidth,t.clientHeight),this.renderer.xr.enabled=this.options.enableXR??!1,!0===this.options.enableXR&&document.body.appendChild(p.createButton(this.renderer)),this.composer=new c(this.renderer);var r=t.clientWidth/t.clientHeight;const n=new s.PerspectiveCamera(45,r,.5,800);n.layers.enable(19),this.setCamera(n),this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=s.PCFSoftShadowMap,this.renderer.shadowMap.autoUpdate=!1,this.renderer.outputColorSpace=s.SRGBColorSpace,this.renderer.toneMapping=s.NoToneMapping,this.renderer.toneMappingExposure=1,this.renderer.gammaFactor=1.4,w.renderingView=this,w.patchThreeAdd(),this.isDepthTextureExtensionSupported=S(this.renderer),t.replaceChildren(this.renderer.domElement),this.setupEventListeners(),this.depthRenderTarget=e.createDepthRenderTarget(this.renderer,this.container);const a=new u(this.scene,this.camera);this.composer.addPass(a);const o=new m(new s.Vector2(t.clientWidth,t.clientHeight),1.5,.4,.85);o.threshold=0,o.strength=.9,o.radius=1,this.renderer.info.autoReset=!1;const l=new c(this.renderer);l.renderToScreen=!1,l.addPass(a),l.addPass(o),this.bloomComposer=l;const d=new g(new s.ShaderMaterial({uniforms:{baseTexture:{value:null},bloomTexture:{value:l.renderTarget2.texture}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }",fragmentShader:"\n uniform sampler2D baseTexture;\n uniform sampler2D bloomTexture;\n varying vec2 vUv;\n void main() {\n gl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) );\n }",defines:{}}),"baseTexture");if(d.needsSwap=!0,this.composer.addPass(d),this.outlinePass=new T(new s.Vector2(t.clientWidth,t.clientHeight),this.scene,this.camera),!0===i.enableOutlines){this.outlinePass.edgeThickness=0,this.outlinePass.edgeGlow=0,this.outlinePass.edgeThickness=1.5,this.outlinePass.edgeStrength=5,this.outlinePass.clear=!1,this.composer.addPass(this.outlinePass);const e=new g(f);e.uniforms.resolution.value.set(1/t.clientWidth,1/t.clientHeight),this.composer.addPass(e)}var v=new g(x);v.clear=!1,this.composer.addPass(v)}setCamera(e){this.camera=e,this.composer.passes.forEach((t=>{t instanceof u?t.camera=e:t instanceof T?t.renderCamera=e:t instanceof E&&(t.camera=e)})),null==this.csm?this.csm=new B({maxFar:250,lightFar:250,lightMargin:20,cascades:4,shadowMapSize:2048,lightDirection:new s.Vector3(.5,-1,-.6).normalize(),lightIntensity:.5*Math.PI,camera:this.camera,parent:this.scene,mode:"logarithmic"}):(this.csm.camera=this.camera,this.camera instanceof l&&(this.csm.maxFar=this.camera.far)),this.csm.updateFrustums()}setSelectedObjects(e){const t=new Map;for(const i of e)t.set(i.uuid,i);for(const i of e)i.traverse((e=>{e.uuid!==i.uuid&&t.has(e.uuid)&&t.delete(e.uuid)}));this.outlinePass.selectedObjects=Array.from(t.values())}static createDepthRenderTarget(e,t){var i=!!e.extensions.get("WEBGL_depth_texture");const r=new s.WebGLRenderTarget(t.clientWidth*e.getPixelRatio(),t.clientHeight*e.getPixelRatio());return r.texture.minFilter=s.NearestFilter,r.texture.magFilter=s.NearestFilter,r.texture.generateMipmaps=!1,r.stencilBuffer=!1,!0===i&&(r.depthTexture=new s.DepthTexture(128,128),r.depthTexture.type=s.UnsignedShortType,r.depthTexture.minFilter=s.NearestFilter,r.depthTexture.magFilter=s.NearestFilter),r}setupEventListeners(){window.addEventListener("resize",this.onResize),window.addEventListener("orientationchange",this.onResize),document.addEventListener("visibilitychange",this.onVisiblityChane)}stop(){this.running=!1,window.removeEventListener("resize",this.onResize),window.removeEventListener("orientationchange",this.onResize),document.removeEventListener("visibilitychange",this.onVisiblityChane),this.onLoopCallbacks=[],this.renderer.dispose(),this.depthRenderTarget.dispose(),this.csm.dispose(),this.container.replaceChildren()}onLoop(e){this.onLoopCallbacks.push(e)}removeOnLoop(e){const t=this.onLoopCallbacks.find(e);t>=0&&this.onLoopCallbacks.splice(t,1)}set showStats(e){this._showStats=e,this._showStats&&!this.container.contains(this.stats.dom)?this.container.appendChild(this.stats.dom):!this._showStats&&this.container.contains(this.stats.dom)&&this.container.removeChild(this.stats.dom)}get showStats(){return this._showStats}loop(e,t=!1){const i=this.stats,o=i.addPanel(new W.Panel("Calls","#83f","#002"));let h;navigator.userAgent.includes("Chrome")&&navigator.userAgent.includes("HologyEngine")&&(h=new D(this.renderer.getContext()),i.addPanel(h)),i.showPanel(0),this.showStats=t;let l=10;const d=()=>{const e=this.renderer.info.render.calls;e>l&&(l=e,setTimeout((()=>l=10),5e3)),o.update(e,l)};performance.now();s.Ray.prototype.intersectTriangle;const c=[],m=[];let p=0;const u=new n,g=new n,f=t=>{const n=this.renderer.getContext();if(this.paused&&this.running&&n.drawingBufferHeight>1)return void setTimeout((()=>f(t)),500);this.renderer.autoClear=!1,this.renderer.clear(),this.renderer.setViewport(0,0,this.container.clientWidth,this.container.clientHeight),this.camera,i.begin();let o=(t*=.001)-p;if(p=t,u.copy(this.camera.matrixWorld),o>1){let t=o;for(;t>.05;)e(O),t-=O;e(t)}else e(o);if(this.onLoopCallbacks.forEach((e=>e(o))),this.camera?.updateMatrixWorld(),g.copy(this.camera.matrixWorld),g.equals(u)||(this.renderer.shadowMap.needsUpdate=!0),this.resizeRender(),c.length=0,m.length=0,this.scene.traverseVisible((e=>{(e instanceof r||e instanceof s.Sprite)&&e.visible&&(e.material?.userData?.water||e.material?.uniforms&&null!=e.material?.uniforms[C])?(e.visible=!1,c.push(e),this.initDepthUniform(e.material),e.renderOrder=100):(e instanceof b||(e instanceof r||e instanceof s.Sprite)&&function(e){if(e.material instanceof a)return e.material.transparent||e.material.alphaTest>0;if(Array.isArray(e.material))for(const t of e.material)if(t.transparent||t.alphaTest>0)return!0}(e))&&(e.visible=!1,m.push(e)),e instanceof r&&e.material?.uniforms&&null!=e.material?.uniforms[y]&&(e.material.uniforms[y].value=t)})),c.length>0){if(this.scene.overrideMaterial=j,this.renderer.setRenderTarget(this.depthRenderTarget),!this.paused&&null!=this.camera)try{this.renderer.clear(),this.renderer.render(this.scene,this.camera)}catch(e){console.warn(e)}this.renderer.setRenderTarget(null),this.scene.overrideMaterial=null}c.forEach((e=>e.visible=!0)),m.forEach((e=>e.visible=!0));try{!this.paused&&this.running&&(h?.startQuery(),this.render(o),h?.endQuery(),this.showStats&&d(),this.renderer.info.reset(),this.renderOverlay())}catch(e){console.warn(e)}i.end(),this.csm?.update(),this.running&&!0!==this.options.enableXR&&(this.fpsCap?setTimeout((()=>{requestAnimationFrame(f)}),1e3/this.fpsCap):requestAnimationFrame(f))};!0===this.options.enableXR?this.renderer.setAnimationLoop(f):requestAnimationFrame(f)}renderOverlay(){const e=Array.from(this.overlayCameras.values()).slice(0,this.maxInsetCameras),t=this.container.clientWidth/2,i=e.length*this.insetWidth+(e.length-1)*this.insetMargin;for(let s=0;s<e.length;s++)this.renderer.clearDepth(),this.renderer.setViewport(t-i/2+this.insetWidth*s+this.insetMargin*s,this.insetOffsetY,this.insetWidth,this.insetHeight),this.renderer.render(this.scene,e[s])}addOverlayCamera(e){this.overlayCameras.add(e)}clearOverlayCameras(){this.overlayCameras.clear()}removeOverlayCamera(e){this.overlayCameras.delete(e)}render(e){const t=this.hasBloom();if(t||this.hadBloom){const e=this.scene.fog;this.scene.fog=null;const t=this.renderer.getClearColor(this.prevClearColor);this.renderer.setClearColor(0),this.scene.traverseVisible((e=>this.darkenNonBloomed(e))),this.bloomComposer.render(),this.scene.traverse((e=>this.restoreMaterial(e))),this.renderer.setClearColor(t),this.scene.fog=e}this.hadBloom=t,this.composer.render(e)}hasBloom(){return null!=L(this.scene,(e=>e instanceof r&&!0===e.material?.userData?.hasBloom))}darkenNonBloomed(e){e.isMesh&&e.visible&&!0!==e.material.userData.hasBloom&&(this.bloomStoredMaterials[e.uuid]=e.material,!0!==e.material.transparent?e.material=F:e.visible=!1)}restoreMaterial(e){this.bloomStoredMaterials[e.uuid]&&(e.material=this.bloomStoredMaterials[e.uuid],delete this.bloomStoredMaterials[e.uuid],e.visible=!0)}initDepthUniform(e){e instanceof o&&(e.uniforms[C].value=this.isDepthTextureExtensionSupported?this.depthRenderTarget.depthTexture:this.depthRenderTarget.texture,null!=e.uniforms[P]&&e.uniforms[P].value.set(this.container.clientWidth*this.renderer.getPixelRatio(),this.container.clientHeight*this.renderer.getPixelRatio()),this.camera instanceof l&&(e.uniforms[R].value=this.camera.near,e.uniforms[M].value=this.camera.far))}};z=e=t([H(),i("design:paramtypes",[HTMLElement,Object])],z);export{z as RenderingView};export function setRenderingPaused(e){null!=window.editor?.viewer?.renderingView&&(window.editor.viewer.renderingView.paused=e)}const O=.05;
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import{AudioLoader as e,Group as t,LoadingManager as a,Mesh as s,Object3D as i,TextureLoader as r}from"three";import{GLTFLoader as n,MTLLoader as o,OBJLoader as h}from"three-stdlib";import{FBXLoader as c}from"three-stdlib";import{cloneMesh as l}from"../utils/mesh.js";import{pathJoin as d}from"../utils/files.js";import{Subject as
|
1
|
+
import{AudioLoader as e,Group as t,LoadingManager as a,Mesh as s,Object3D as i,TextureLoader as r}from"three";import{GLTFLoader as n,MTLLoader as o,OBJLoader as h}from"three-stdlib";import{FBXLoader as c}from"three-stdlib";import{cloneMesh as l}from"../utils/mesh.js";import{pathJoin as d}from"../utils/files.js";import{Subject as m,firstValueFrom as p}from"rxjs";import{importCollisionShapes as u}from"./collision/collision-shape-import.js";import*as f from"three";import{iterateMaterials as g}from"../utils/materials.js";const w=["glb","gltf","fbx","obj"];export class AssetResourceLoader{onError(e){console.error(e)}constructor(){this.cache=new Map,this.textureCache=new Map,this.loadingManager=new a,this.glbLoader=new n(this.loadingManager),this.fbxLoader=new c(this.loadingManager),this.objLoader=new h(this.loadingManager),this.textureLoader=new r(this.loadingManager),this._textureLoader=new f.ImageBitmapLoader(this.loadingManager),this.audioLoader=new e(this.loadingManager),this.makeReady=new m,this.ready=p(this.makeReady),this.collisionShapeCache=new Map}setDataDir(e){this.basePath=d(e,"asset-resources"),this.makeReady.next(!0)}getUri(e){return d(this.basePath,e)+`?windowId=${getElectronArg("windowId")}`}async getTexture(e){return null==e?null:(await this.ready,this.textureCache.has(e.id)||await this.textureLoader.loadAsync(this.getUri(e.fileKey)).then((t=>(t.wrapS=L(e.texture?.wrapS),t.wrapT=L(e.texture?.wrapT),t.flipY=e.texture?.flipY??!0,this.textureCache.set(e.id,t),t))),this.textureCache.get(e.id))}async getMesh(e){if(await this.ready,!w.includes(e.fileFormat?.toLowerCase()))return console.error("Unsupported mesh file format "+e.fileFormat,e),{scene:new t,animations:[]};if(!this.cache.has(e.fileKey))try{this.cache.set(e.fileKey,await this.loadMesh(e))}catch(e){return this.onError(e),{scene:new t,animations:[]}}const a=l(this.cache.get(e.fileKey).scene),i=this.cache.get(e.fileKey).animations;a.traverse((e=>{e instanceof s&&e.material instanceof Array&&(e.material=e.material.slice())}));const r=this.computeCollisionShapes(e,a),n=new AssetMeshInstance;n.add(a),n.collisionShapes=r,n.animations=i;const o=!!e.receiveShadow??!0,h=!!e.castShadow??!1;return a.traverse((e=>{e.castShadow=h,e.receiveShadow=o})),{scene:n,animations:i}}async getAudio(e){return await this.ready,this.audioLoader.loadAsync(this.getUri(e.fileKey))}computeCollisionShapes(e,t){const a=e.id+e.mesh?.collisions?.shapeType;return this.collisionShapeCache.has(a)||this.collisionShapeCache.set(a,u(t,e)),this.collisionShapeCache.get(a)}async loadMesh(e){return await this.ready,await this.loadByAsset(e).then((e=>(e.scene=function(e,t){let a=!1;if(t.traverseVisible((e=>{b.test(e.name)&&(a=!0)})),!a)return t;const s=new f.LOD,i=[t];for(;i.length>0;){const e=i.shift(),t=e.name.match(b);if(null!=t){const a=parseInt(t[1]);0===a?s.addLevel(e,0):console.warn(`Skipping LOD level ${a} for now as LOD is not fully supported`)}else i.push(...e.children)}return s}(0,e.scene),e)))}async loadByAsset(e){const t=this.getUri(e.fileKey);switch(e.fileFormat){case"glb":case"gltf":return this.glbLoader.loadAsync(t).then((e=>({scene:e.scene,animations:e.animations})));case"fbx":return this.fbxLoader.loadAsync(t).then((e=>({scene:e,animations:e.animations})));case"obj":if(null!=e.materialLib){const t=new o;t.materialOptions={normalizeRGB:!1};const a=await t.loadAsync(this.getUri(e.materialLib));this.objLoader.setMaterials(a)}return this.objLoader.loadAsync(t).then((e=>(y(e),e))).then((e=>({scene:e,animations:e.animations})))}}}function y(e){if(e instanceof s)for(const t of g(e.material))t instanceof f.MeshPhongMaterial&&!t.color.isLinear&&(t.color.isLinear=!0);e.children?.forEach(y)}export class AssetMeshInstance extends i{}export function getElectronArg(e){const t=`--${e}=`,a=window.process?.argv.find((e=>e.startsWith(t)));return a?.substring(t.length)}function L(e){switch(e){case"clamp":return f.ClampToEdgeWrapping;case"repeat":return f.RepeatWrapping;case"mirror":return f.MirroredRepeatWrapping}return f.RepeatWrapping}const b=/_LOD(\d+)$/;
|
2
2
|
/*
|
3
3
|
* Copyright (©) 2023. All rights reserved.
|
4
4
|
* See the LICENSE.md file for details.
|
@@ -20,6 +20,7 @@ export declare class LandscapeManager {
|
|
20
20
|
private loadedScatterSquares;
|
21
21
|
private refreshRequests;
|
22
22
|
private defaultLandscapeMaterial;
|
23
|
+
private scatterMeshPool;
|
23
24
|
private onLoopHandler;
|
24
25
|
constructor(source: SceneObject, view: RenderingView, landscape: LandscapeGroup, assetManagerService: AssetResourceLoader, assetService: AssetsProvider, shaders: ShaderImpl[], applyMaterial: (object: Mesh) => void);
|
25
26
|
updateShaders(shaders: ShaderImpl[]): void;
|